style: soften settings page borders

This commit is contained in:
Haitao Pan 2026-03-30 15:33:13 +08:00
parent 9bcc4b1fac
commit 2b836c5c6e
5 changed files with 87 additions and 47 deletions

View File

@ -12,6 +12,8 @@ import '../../models/app_models.dart';
import '../../runtime/gateway_runtime.dart';
import '../../runtime/runtime_controllers.dart';
import '../../runtime/runtime_models.dart';
import '../../theme/app_palette.dart';
import '../../theme/app_theme.dart';
import 'codex_integration_card.dart';
import 'skill_directory_authorization_card.dart';
import '../../widgets/settings_page_shell.dart';
@ -207,6 +209,8 @@ class SettingsPageStateInternal extends State<SettingsPage> {
return AnimatedBuilder(
animation: controller,
builder: (context, _) {
final theme = Theme.of(context);
final palette = context.palette;
final featurePlatform = resolveUiFeaturePlatformFromContext(context);
final uiFeatures = controller.featuresFor(featurePlatform);
tabInternal = uiFeatures.sanitizeSettingsTab(controller.settingsTab);
@ -220,53 +224,80 @@ class SettingsPageStateInternal extends State<SettingsPage> {
(tabInternal != SettingsTab.gateway ||
integrationSubTabInternal ==
GatewayIntegrationSubTabInternal.acp);
return SettingsPageBodyShell(
padding: const EdgeInsets.fromLTRB(32, 32, 32, 8),
breadcrumbs: buildSettingsBreadcrumbs(
controller,
tab: tabInternal,
detail: detailInternal,
navigationContext: navigationContextInternal,
),
title: appText('设置', 'Settings'),
subtitle: showingDetail
? appText(
'当前正在编辑详细设置参数,保存后会回写到对应状态页。',
'You are editing detailed settings. Saved values flow back to the related status page.',
)
: appText(
'配置 $kProductBrandName 工作区、网关默认项、界面与诊断选项',
'Configure workspace, gateway defaults, appearance, and diagnostics for $kProductBrandName.',
return Theme(
data: theme.copyWith(
inputDecorationTheme: theme.inputDecorationTheme.copyWith(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(AppRadius.input),
borderSide: BorderSide(
color: palette.strokeSoft,
width: settingsHairlineBorderWidthInternal,
),
trailing: SizedBox(
width: showingDetail ? 168 : 220,
child: showingDetail
? OutlinedButton.icon(
onPressed: () {
controller.closeSettingsDetail();
setState(() {
detailInternal = null;
navigationContextInternal = null;
});
},
icon: const Icon(Icons.arrow_back_rounded),
label: Text(appText('返回概览', 'Back to overview')),
)
: TextField(
decoration: InputDecoration(
hintText: appText('搜索设置', 'Search settings'),
prefixIcon: Icon(Icons.search_rounded),
),
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(AppRadius.input),
borderSide: BorderSide(
color: palette.strokeSoft,
width: settingsHairlineBorderWidthInternal,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(AppRadius.input),
borderSide: BorderSide(
color: palette.accent.withValues(alpha: 0.32),
width: settingsHairlineBorderWidthInternal,
),
),
),
),
globalApplyBar: showGlobalApplyBar
? buildGlobalApplyBarInternal(context, controller)
: null,
bodyChildren: buildContentForCurrentStateInternal(
context,
controller,
settings,
uiFeatures,
child: SettingsPageBodyShell(
padding: const EdgeInsets.fromLTRB(32, 32, 32, 8),
breadcrumbs: buildSettingsBreadcrumbs(
controller,
tab: tabInternal,
detail: detailInternal,
navigationContext: navigationContextInternal,
),
title: appText('设置', 'Settings'),
subtitle: showingDetail
? appText(
'当前正在编辑详细设置参数,保存后会回写到对应状态页。',
'You are editing detailed settings. Saved values flow back to the related status page.',
)
: appText(
'配置 $kProductBrandName 工作区、网关默认项、界面与诊断选项',
'Configure workspace, gateway defaults, appearance, and diagnostics for $kProductBrandName.',
),
trailing: SizedBox(
width: showingDetail ? 168 : 220,
child: showingDetail
? OutlinedButton.icon(
onPressed: () {
controller.closeSettingsDetail();
setState(() {
detailInternal = null;
navigationContextInternal = null;
});
},
icon: const Icon(Icons.arrow_back_rounded),
label: Text(appText('返回概览', 'Back to overview')),
)
: TextField(
decoration: InputDecoration(
hintText: appText('搜索设置', 'Search settings'),
prefixIcon: Icon(Icons.search_rounded),
),
),
),
globalApplyBar: showGlobalApplyBar
? buildGlobalApplyBarInternal(context, controller)
: null,
bodyChildren: buildContentForCurrentStateInternal(
context,
controller,
settings,
uiFeatures,
),
),
);
},

View File

@ -118,6 +118,7 @@ extension SettingsPageGatewayMixinInternal on SettingsPageStateInternal {
)
else
SurfaceCard(
borderWidth: settingsHairlineBorderWidthInternal,
child: Text(
appText(
'当前发布配置未开放 Vault Server 参数。',
@ -195,6 +196,7 @@ extension SettingsPageGatewayMixinInternal on SettingsPageStateInternal {
)
else
SurfaceCard(
borderWidth: settingsHairlineBorderWidthInternal,
child: Text(
appText(
'当前发布配置未开放 Vault Server 参数。',
@ -650,6 +652,7 @@ extension SettingsPageGatewayMixinInternal on SettingsPageStateInternal {
}) {
final theme = Theme.of(context);
return SurfaceCard(
borderWidth: settingsHairlineBorderWidthInternal,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [

View File

@ -35,6 +35,7 @@ extension SettingsPageGatewayConnectionMixinInternal
SettingsSnapshot settings,
) {
return SurfaceCard(
borderWidth: settingsHairlineBorderWidthInternal,
child: buildOpenClawGatewayCardBodyInternal(
context,
controller,
@ -352,6 +353,7 @@ extension SettingsPageGatewayConnectionMixinInternal
SettingsSnapshot settings,
) {
return SurfaceCard(
borderWidth: settingsHairlineBorderWidthInternal,
child: buildVaultProviderCardBodyInternal(context, controller, settings),
);
}

View File

@ -27,6 +27,8 @@ import 'settings_page_multi_agent.dart';
import 'settings_page_support.dart';
import 'settings_page_device.dart';
const double settingsHairlineBorderWidthInternal = 0.55;
class EditableFieldInternal extends StatefulWidget {
const EditableFieldInternal({
super.key,

View File

@ -12,6 +12,7 @@ class SurfaceCard extends StatefulWidget {
this.padding = const EdgeInsets.all(AppSpacing.md),
this.onTap,
this.borderRadius = AppRadius.card,
this.borderWidth = 1,
this.color,
this.tone = SurfaceCardTone.standard,
});
@ -20,6 +21,7 @@ class SurfaceCard extends StatefulWidget {
final EdgeInsetsGeometry padding;
final VoidCallback? onTap;
final double borderRadius;
final double borderWidth;
final Color? color;
final SurfaceCardTone tone;
@ -49,7 +51,7 @@ class _SurfaceCardState extends State<SurfaceCard> {
SurfaceCardTone.standard => BoxDecoration(
color: (_hovered && widget.onTap != null ? hoveredColor : baseColor)
.withValues(alpha: 0.98),
border: Border.all(color: borderColor),
border: Border.all(color: borderColor, width: widget.borderWidth),
borderRadius: BorderRadius.circular(widget.borderRadius),
boxShadow: widget.onTap != null && _hovered
? [palette.chromeShadowAmbient]
@ -58,7 +60,7 @@ class _SurfaceCardState extends State<SurfaceCard> {
SurfaceCardTone.chrome => BoxDecoration(
color: (_hovered && widget.onTap != null ? hoveredColor : baseColor)
.withValues(alpha: 0.98),
border: Border.all(color: borderColor),
border: Border.all(color: borderColor, width: widget.borderWidth),
borderRadius: BorderRadius.circular(widget.borderRadius),
boxShadow: [
if (_hovered && widget.onTap != null) palette.chromeShadowAmbient,