// widgets/theme_sheet.dart — 主题外观选择 sheet(镜像原型 mobile-shell openThemeSheet)。 // m-opt 行式三主题(A 经典蓝 / B 琥珀 / C 酒窖)+ 四色 swatch 预览,选中出勾。 // 写入 themeControllerProvider(持久化),与桌面 ThemePickerPill 同源。 import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart'; import '../core/theme/app_dims.g.dart'; import '../core/theme/app_tokens.g.dart'; import '../core/theme/context_tokens.dart'; import '../core/theme/theme_controller.dart'; import 'ds/m_sheet.dart'; // (key, 名称, 说明)——与桌面 _PrefPanel._themes / 原型 THEMES 同文案。 const _themes = [ ('a', 'A · 经典蓝', '浅色 · 默认'), ('b', 'B · 琥珀', '深色'), ('c', 'C · 酒窖', '暖浅色'), ]; /// 打开主题外观选择 sheet。 Future showThemeSheet(BuildContext context) { return showMSheet( context, title: '主题外观', builder: (ctx) => Consumer(builder: (ctx, ref, _) { final t = ctx.tokens; final current = ref.watch(themeControllerProvider); return Column(children: [ for (var i = 0; i < _themes.length; i++) ...[ Builder(builder: (_) { final (key, name, desc) = _themes[i]; final sel = key == current; final preview = appTokensOf(key); return InkWell( onTap: () { ref.read(themeControllerProvider.notifier).set(key); Navigator.of(ctx).pop(); }, child: Container( padding: const EdgeInsets.symmetric(vertical: 13), decoration: BoxDecoration( border: i == _themes.length - 1 ? null : Border(bottom: BorderSide(color: t.borderSubtle)), ), child: Row(children: [ // 四色 swatch(primary/primary-dark/page/accent,与桌面 tcard 同序) ClipRRect( borderRadius: BorderRadius.circular(AppDims.rSm), child: SizedBox( width: 56, height: 24, child: Row(children: [ Expanded(child: Container(color: preview.primary)), Expanded(child: Container(color: preview.primaryDark)), Expanded(child: Container(color: preview.page)), Expanded(child: Container(color: preview.accent)), ]), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(name, style: TextStyle( fontSize: AppDims.fsBody, fontWeight: sel ? FontWeight.w600 : FontWeight.w500, color: sel ? t.primary : t.text)), Text(desc, style: TextStyle( fontSize: AppDims.fsXs, color: t.muted)), ], ), ), if (sel) Icon(LucideIcons.check, size: 18, color: t.primary), ]), ), ); }), ], ]); }), ); }