diff --git a/flutter_monisuo/lib/core/theme/app_color_scheme.dart b/flutter_monisuo/lib/core/theme/app_color_scheme.dart index f3dff55..7c14f4b 100644 --- a/flutter_monisuo/lib/core/theme/app_color_scheme.dart +++ b/flutter_monisuo/lib/core/theme/app_color_scheme.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; /// Material Design 3 顏色系統 - Pencil Design Theme /// @@ -252,60 +251,6 @@ class AppColorScheme { end: Alignment.bottomRight, ); - // ============================================ - // Shadcn ColorScheme - 深色主題 - // ============================================ - - static ShadColorScheme get darkShad => ShadColorScheme( - background: darkBackground, - foreground: darkOnSurface, - card: darkSurfaceContainer, - cardForeground: darkOnSurface, - popover: darkSurfaceContainerHigh, - popoverForeground: darkOnSurface, - primary: darkPrimary, - primaryForeground: darkOnPrimary, - secondary: darkSecondary, - secondaryForeground: darkOnSecondary, - muted: darkSurfaceContainerHigh, - mutedForeground: darkOnSurfaceVariant, - accent: darkPrimary.withValues(alpha: 0.15), - accentForeground: darkPrimary, - destructive: error, - destructiveForeground: darkOnSurface, - border: darkOutlineVariant.withValues(alpha: 0.15), - input: darkOutlineVariant.withValues(alpha: 0.15), - ring: darkPrimary, - selection: darkPrimary.withValues(alpha: 0.3), - ); - - // ============================================ - // Shadcn ColorScheme - 淺色主題 - // ============================================ - - static ShadColorScheme get lightShad => ShadColorScheme( - background: lightBackground, - foreground: lightOnSurface, - card: lightSurfaceLowest, - cardForeground: lightOnSurface, - popover: lightSurfaceLowest, - popoverForeground: lightOnSurface, - primary: lightPrimary, - primaryForeground: const Color(0xFFFFFFFF), - secondary: lightSecondary, - secondaryForeground: const Color(0xFFFFFFFF), - muted: lightSurfaceHigh, - mutedForeground: lightOnSurfaceVariant, - accent: lightSecondary.withValues(alpha: 0.1), - accentForeground: lightSecondary, - destructive: error, - destructiveForeground: const Color(0xFFFFFFFF), - border: lightOutlineVariant.withValues(alpha: 0.5), - input: lightOutlineVariant.withValues(alpha: 0.3), - ring: lightSecondary, - selection: lightSecondary.withValues(alpha: 0.2), - ); - // ============================================ // Material ColorScheme - 深色主題 (Material Design 3) // ============================================ diff --git a/flutter_monisuo/lib/main.dart b/flutter_monisuo/lib/main.dart index 48013e7..9c0f47e 100644 --- a/flutter_monisuo/lib/main.dart +++ b/flutter_monisuo/lib/main.dart @@ -1,6 +1,5 @@ import 'dart:ui'; import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:bot_toast/bot_toast.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; @@ -9,7 +8,6 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'core/network/dio_client.dart'; import 'core/storage/local_storage.dart'; -import 'core/theme/app_color_scheme.dart'; import 'core/theme/app_theme.dart'; import 'core/event/app_event_bus.dart'; import 'data/services/user_service.dart'; @@ -67,18 +65,7 @@ class MyApp extends StatelessWidget { providers: _buildProviders(), child: Consumer( builder: (context, themeProvider, _) { - return ShadApp.custom( - themeMode: themeProvider.themeMode, - theme: ShadThemeData( - colorScheme: AppColorScheme.lightShad, - brightness: Brightness.light, - ), - darkTheme: ShadThemeData( - colorScheme: AppColorScheme.darkShad, - brightness: Brightness.dark, - ), - appBuilder: (context) => _buildMaterialApp(context, themeProvider.themeMode), - ); + return _buildMaterialApp(context, themeProvider.themeMode); }, ), ); @@ -130,13 +117,11 @@ class MyApp extends StatelessWidget { darkTheme: AppTheme.darkTheme, themeMode: themeMode, localizationsDelegates: const [ - GlobalShadLocalizations.delegate, GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], builder: (context, child) { - child = ShadAppBuilder(child: child!); // 配置 BotToast 確保顯示在所有內容之上 final botToastBuilder = BotToastInit(); child = botToastBuilder(context, child); diff --git a/flutter_monisuo/lib/ui/components/asset_card.dart b/flutter_monisuo/lib/ui/components/asset_card.dart index 40377a9..27c3130 100644 --- a/flutter_monisuo/lib/ui/components/asset_card.dart +++ b/flutter_monisuo/lib/ui/components/asset_card.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; +import '../../core/theme/app_theme.dart'; import 'package:flutter_animate/flutter_animate.dart'; import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_theme_extension.dart'; @@ -35,8 +36,8 @@ class AssetCard extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); - final colorScheme = context.colors; + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; final appColors = context.appColors; final cardGradient = gradient ?? appColors.assetGradient; @@ -68,7 +69,7 @@ class AssetCard extends StatelessWidget { children: [ Text( title, - style: theme.textTheme.small.copyWith(color: secondaryTextColor), + style: AppTextStyles.bodySmall(context).copyWith(color: secondaryTextColor), ), const Spacer(), if (onTap != null) @@ -83,7 +84,7 @@ class AssetCard extends StatelessWidget { // 餘額 - 大標題 Text( balance, - style: theme.textTheme.h1.copyWith( + style: AppTextStyles.headlineLarge(context).copyWith( fontWeight: FontWeight.bold, color: primaryTextColor, fontSize: 20, @@ -102,7 +103,7 @@ class AssetCard extends StatelessWidget { const SizedBox(width: 6), Text( '盈虧: $profit', - style: theme.textTheme.small.copyWith(color: secondaryTextColor), + style: AppTextStyles.bodySmall(context).copyWith(color: secondaryTextColor), ), ], ), @@ -178,15 +179,16 @@ class AssetCardCompact extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); final appColors = context.appColors; final isValueUp = isUp ?? true; - return ShadCard( - padding: const EdgeInsets.all(AppSpacing.md), - child: InkWell( - onTap: onTap, - child: Row( + return Card( + child: Padding( + padding: const EdgeInsets.all(AppSpacing.md), + child: InkWell( + onTap: onTap, + child: Row( children: [ Expanded( child: Column( @@ -194,12 +196,12 @@ class AssetCardCompact extends StatelessWidget { children: [ Text( title, - style: theme.textTheme.muted, + style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant), ), const SizedBox(height: 4), Text( balance, - style: theme.textTheme.h3.copyWith( + style: AppTextStyles.headlineMedium(context).copyWith( fontWeight: FontWeight.bold, ), ), @@ -224,6 +226,7 @@ class AssetCardCompact extends StatelessWidget { ], ), ), + ), ); } } diff --git a/flutter_monisuo/lib/ui/components/coin_card.dart b/flutter_monisuo/lib/ui/components/coin_card.dart index 2841750..359bba0 100644 --- a/flutter_monisuo/lib/ui/components/coin_card.dart +++ b/flutter_monisuo/lib/ui/components/coin_card.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import '../../core/theme/app_theme.dart'; import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_theme_extension.dart'; @@ -31,11 +31,12 @@ class CoinCard extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); - return ShadCard( - padding: const EdgeInsets.all(AppSpacing.md), - child: InkWell( + return Card( + child: Padding( + padding: const EdgeInsets.all(AppSpacing.md), + child: InkWell( onTap: onTap, child: Row( children: [ @@ -66,13 +67,13 @@ class CoinCard extends StatelessWidget { children: [ Text( '$code/USDT', - style: theme.textTheme.large.copyWith( + style: AppTextStyles.headlineMedium(context).copyWith( fontWeight: FontWeight.bold, ), ), Text( name, - style: theme.textTheme.muted, + style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant), ), ], ), @@ -95,6 +96,7 @@ class CoinCard extends StatelessWidget { ], ), ), + ), ); } } diff --git a/flutter_monisuo/lib/ui/pages/asset/components/asset_dialogs.dart b/flutter_monisuo/lib/ui/pages/asset/components/asset_dialogs.dart index 6662103..5f1bedf 100644 --- a/flutter_monisuo/lib/ui/pages/asset/components/asset_dialogs.dart +++ b/flutter_monisuo/lib/ui/pages/asset/components/asset_dialogs.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:lucide_icons_flutter/lucide_icons.dart'; +import '../../../components/material_input.dart'; import 'package:provider/provider.dart'; import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme_extension.dart'; @@ -129,10 +129,10 @@ class WalletAddressCard extends StatelessWidget { /// 充值對話框 void showDepositDialog(BuildContext context) { final amountController = TextEditingController(); - final formKey = GlobalKey(); + final formKey = GlobalKey(); final colorScheme = Theme.of(context).colorScheme; - showShadDialog( + showDialog( context: context, builder: (ctx) => Dialog( backgroundColor: Colors.transparent, @@ -178,22 +178,21 @@ void showDepositDialog(BuildContext context) { ], ), const SizedBox(height: AppSpacing.lg), - ShadForm( + Form( key: formKey, - child: ShadInputFormField( - id: 'amount', - controller: amountController, - label: const Text('充值金額'), - placeholder: const Text('最低 1000 USDT'), - keyboardType: const TextInputType.numberWithOptions(decimal: true), - validator: (v) { - if (v == null || v.isEmpty) return '請輸入金額'; - final n = double.tryParse(v); - if (n == null || n <= 0) return '請輸入有效金額'; - if (n < 1000) return '單筆最低充值1000 USDT'; - return null; - }, - ), + child: MaterialInput( + controller: amountController, + labelText: '充值金額', + hintText: '最低 1000 USDT', + keyboardType: const TextInputType.numberWithOptions(decimal: true), + validator: (v) { + if (v == null || v.isEmpty) return '請輸入金額'; + final n = double.tryParse(v); + if (n == null || n <= 0) return '請輸入有效金額'; + if (n < 1000) return '單筆最低充值1000 USDT'; + return null; + }, + ), ), const SizedBox(height: AppSpacing.lg), Row( @@ -213,7 +212,7 @@ void showDepositDialog(BuildContext context) { text: '下一步', type: NeonButtonType.primary, onPressed: () async { - if (formKey.currentState!.saveAndValidate()) { + if (formKey.currentState!.validate()) { Navigator.of(ctx).pop(); final response = await context.read().deposit( amount: amountController.text, @@ -248,7 +247,7 @@ void showDepositResultDialog(BuildContext context, Map data) { final walletNetwork = data['walletNetwork'] as String? ?? 'TRC20'; final colorScheme = Theme.of(context).colorScheme; - showShadDialog( + showDialog( context: context, builder: (ctx) => Dialog( backgroundColor: Colors.transparent, @@ -359,7 +358,7 @@ void showWithdrawDialog(BuildContext context, String? balance) { final amountController = TextEditingController(); final addressController = TextEditingController(); final contactController = TextEditingController(); - final formKey = GlobalKey(); + final formKey = GlobalKey(); final feeNotifier = ValueNotifier('提現將扣除10%手續費'); final networksNotifier = ValueNotifier>([]); final selectedNetworkNotifier = ValueNotifier(null); @@ -384,7 +383,7 @@ void showWithdrawDialog(BuildContext context, String? balance) { } }); - showShadDialog( + showDialog( context: context, builder: (ctx) => Dialog( backgroundColor: Colors.transparent, @@ -460,17 +459,21 @@ void showWithdrawDialog(BuildContext context, String? balance) { ), ], const SizedBox(height: AppSpacing.lg), - ShadForm( + Form( key: formKey, child: Column( children: [ - ShadInputFormField( - id: 'amount', + MaterialInput( controller: amountController, - label: const Text('提現金額'), - placeholder: const Text('請輸入提現金額(USDT)'), + labelText: '提現金額', + hintText: '請輸入提現金額(USDT)', keyboardType: const TextInputType.numberWithOptions(decimal: true), - validator: Validators.amount, + validator: (v) { + if (v == null || v.isEmpty) return '請輸入金額'; + final n = double.tryParse(v); + if (n == null || n <= 0) return '請輸入有效金額'; + return null; + }, ), const SizedBox(height: AppSpacing.md), // 手續費/應收款提示 @@ -518,14 +521,16 @@ void showWithdrawDialog(BuildContext context, String? balance) { builder: (_, selected, __) { return SizedBox( width: double.infinity, - child: ShadSelect( - placeholder: const Text('選擇提現網絡'), - initialValue: selected, - selectedOptionBuilder: (context, val) => Text(val), + child: DropdownButtonFormField( + value: selected, + hint: const Text('選擇提現網絡'), + decoration: InputDecoration( + border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), + ), onChanged: (value) { if (value != null) selectedNetworkNotifier.value = value; }, - options: networks.map((n) => ShadOption(value: n, child: Text(n))).toList(), + items: networks.map((n) => DropdownMenuItem(value: n, child: Text(n))).toList(), ), ); }, @@ -535,19 +540,20 @@ void showWithdrawDialog(BuildContext context, String? balance) { }, ), const SizedBox(height: AppSpacing.md), - ShadInputFormField( - id: 'address', + MaterialInput( controller: addressController, - label: const Text('目標地址'), - placeholder: const Text('請輸入提現地址'), - validator: (v) => Validators.required(v, '提現地址'), + labelText: '目標地址', + hintText: '請輸入提現地址', + validator: (v) { + if (v == null || v.isEmpty) return '請輸入提現地址'; + return null; + }, ), const SizedBox(height: AppSpacing.md), - ShadInputFormField( - id: 'contact', + MaterialInput( controller: contactController, - label: const Text('聯繫方式(可選)'), - placeholder: const Text('聯繫方式'), + labelText: '聯繫方式(可選)', + hintText: '聯繫方式', ), ], ), @@ -570,7 +576,7 @@ void showWithdrawDialog(BuildContext context, String? balance) { text: '提交', type: NeonButtonType.primary, onPressed: () async { - if (formKey.currentState!.saveAndValidate()) { + if (formKey.currentState!.validate()) { Navigator.of(ctx).pop(); final response = await context.read().withdraw( amount: amountController.text, @@ -619,7 +625,7 @@ void showWithdrawDialog(BuildContext context, String? balance) { void showResultDialog(BuildContext context, String title, String? message) { final colorScheme = Theme.of(context).colorScheme; - showShadDialog( + showDialog( context: context, builder: (ctx) => Dialog( backgroundColor: Colors.transparent, diff --git a/flutter_monisuo/lib/ui/pages/chart/chart_page.dart b/flutter_monisuo/lib/ui/pages/chart/chart_page.dart index 94da128..91efb64 100644 --- a/flutter_monisuo/lib/ui/pages/chart/chart_page.dart +++ b/flutter_monisuo/lib/ui/pages/chart/chart_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_chen_kchart/k_chart.dart'; import 'package:provider/provider.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:decimal/decimal.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme.dart'; @@ -16,7 +16,7 @@ class ChartPage extends StatelessWidget { @override Widget build(BuildContext context) { - final colorScheme = context.colors; + final colorScheme = Theme.of(context).colorScheme; return ChangeNotifierProvider( create: (_) => ChartProvider() @@ -137,7 +137,7 @@ class ChartPage extends StatelessWidget { } Widget _buildPriceHeader(BuildContext context, ChartProvider provider) { - final colorScheme = context.colors; + final colorScheme = Theme.of(context).colorScheme; final candles = provider.candles; if (candles.isEmpty) return const SizedBox.shrink(); @@ -213,7 +213,7 @@ class ChartPage extends StatelessWidget { } Widget _buildDataItem(BuildContext context, String label, String value) { - final colorScheme = context.colors; + final colorScheme = Theme.of(context).colorScheme; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -224,7 +224,7 @@ class ChartPage extends StatelessWidget { } Widget _buildIntervalTabs(BuildContext context, ChartProvider provider) { - final colorScheme = context.colors; + final colorScheme = Theme.of(context).colorScheme; return Container( height: 40, @@ -260,7 +260,7 @@ class ChartPage extends StatelessWidget { /// 底部指标切换(官方 demo 风格) Widget _buildIndicatorTabs(BuildContext context, ChartProvider provider) { - final colorScheme = context.colors; + final colorScheme = Theme.of(context).colorScheme; final selectedColor = colorScheme.primary; final unselectedColor = colorScheme.onSurfaceVariant; @@ -361,7 +361,7 @@ class ChartPage extends StatelessWidget { } Widget _buildBottomActions(BuildContext context, ChartProvider provider) { - final colorScheme = context.colors; + final colorScheme = Theme.of(context).colorScheme; return Container( padding: const EdgeInsets.all(AppSpacing.md), @@ -414,7 +414,7 @@ class ChartPage extends StatelessWidget { Widget _buildTitle(BuildContext context) { return Consumer( builder: (context, provider, _) { - final colorScheme = context.colors; + final colorScheme = Theme.of(context).colorScheme; return Row( mainAxisSize: MainAxisSize.min, children: [ @@ -428,7 +428,7 @@ class ChartPage extends StatelessWidget { } Widget _buildErrorView(BuildContext context, ChartProvider provider) { - final colorScheme = context.colors; + final colorScheme = Theme.of(context).colorScheme; return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, diff --git a/flutter_monisuo/lib/ui/pages/home/header_bar.dart b/flutter_monisuo/lib/ui/pages/home/header_bar.dart index adf5b33..6dc090d 100644 --- a/flutter_monisuo/lib/ui/pages/home/header_bar.dart +++ b/flutter_monisuo/lib/ui/pages/home/header_bar.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_spacing.dart'; diff --git a/flutter_monisuo/lib/ui/pages/home/home_page.dart b/flutter_monisuo/lib/ui/pages/home/home_page.dart index 6e601e0..ea43fd4 100644 --- a/flutter_monisuo/lib/ui/pages/home/home_page.dart +++ b/flutter_monisuo/lib/ui/pages/home/home_page.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme_extension.dart'; @@ -87,12 +87,12 @@ class _HomePageState extends State super.build(context); return Scaffold( - backgroundColor: context.colors.background, + backgroundColor: Theme.of(context).colorScheme.background, body: Consumer( builder: (context, provider, _) { return RefreshIndicator( onRefresh: () => provider.refreshAll(force: true), - color: context.colors.primary, + color: Theme.of(context).colorScheme.primary, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), padding: EdgeInsets.only( @@ -270,7 +270,7 @@ class _AssetCardState extends State<_AssetCard> { child: Container( padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5), decoration: BoxDecoration( - color: context.colors.primary, + color: Theme.of(context).colorScheme.primary, borderRadius: BorderRadius.circular(AppRadius.sm), ), child: Row( @@ -280,7 +280,7 @@ class _AssetCardState extends State<_AssetCard> { Text( '充值', style: AppTextStyles.labelLarge(context).copyWith( - color: context.colors.onPrimary, + color: Theme.of(context).colorScheme.onPrimary, fontSize: 12, ), ), @@ -359,9 +359,9 @@ class _WelfareCard extends StatelessWidget { width: double.infinity, padding: EdgeInsets.all(AppSpacing.lg), decoration: BoxDecoration( - color: context.colors.surface, + color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(AppRadius.xl), - border: Border.all(color: context.colors.outlineVariant.withValues(alpha: 0.2)), + border: Border.all(color: Theme.of(context).colorScheme.outlineVariant.withValues(alpha: 0.2)), ), child: Row( children: [ @@ -370,12 +370,12 @@ class _WelfareCard extends StatelessWidget { width: 48, height: 48, decoration: BoxDecoration( - color: context.colors.primary.withValues(alpha: 0.15), + color: Theme.of(context).colorScheme.primary.withValues(alpha: 0.15), borderRadius: BorderRadius.circular(AppRadius.lg), ), child: Icon( LucideIcons.gift, - color: context.colors.primary, + color: Theme.of(context).colorScheme.primary, size: 24, ), ), @@ -426,7 +426,7 @@ class _WelfareCard extends StatelessWidget { style: AppTextStyles.bodySmall(context).copyWith( fontSize: 10, fontWeight: FontWeight.bold, - color: context.colors.onPrimary, + color: Theme.of(context).colorScheme.onPrimary, ), ), ), @@ -504,13 +504,13 @@ class _EmptyHoldings extends StatelessWidget { width: double.infinity, padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl, horizontal: AppSpacing.lg), decoration: BoxDecoration( - color: context.colors.surfaceContainerLow.withValues(alpha: 0.5), + color: Theme.of(context).colorScheme.surfaceContainerLow.withValues(alpha: 0.5), borderRadius: BorderRadius.circular(AppRadius.xxl), - border: Border.all(color: context.colors.outlineVariant.withValues(alpha: 0.1)), + border: Border.all(color: Theme.of(context).colorScheme.outlineVariant.withValues(alpha: 0.1)), ), child: Column( children: [ - Icon(LucideIcons.wallet, size: 48, color: context.colors.onSurfaceVariant), + Icon(LucideIcons.wallet, size: 48, color: Theme.of(context).colorScheme.onSurfaceVariant), SizedBox(height: AppSpacing.md), Text( '暫無持倉', @@ -542,9 +542,9 @@ class _HoldingsList extends StatelessWidget { return Container( decoration: BoxDecoration( - color: context.colors.surface.withValues(alpha: 0.5), + color: Theme.of(context).colorScheme.surface.withValues(alpha: 0.5), borderRadius: BorderRadius.circular(AppRadius.xxl), - border: Border.all(color: context.colors.outlineVariant.withValues(alpha: 0.1)), + border: Border.all(color: Theme.of(context).colorScheme.outlineVariant.withValues(alpha: 0.1)), ), child: ListView.separated( shrinkWrap: true, diff --git a/flutter_monisuo/lib/ui/pages/home/hot_coins_section.dart b/flutter_monisuo/lib/ui/pages/home/hot_coins_section.dart index f01025a..f710f55 100644 --- a/flutter_monisuo/lib/ui/pages/home/hot_coins_section.dart +++ b/flutter_monisuo/lib/ui/pages/home/hot_coins_section.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme_extension.dart'; @@ -36,9 +35,9 @@ class HotCoinsSection extends StatelessWidget { // Card Container( decoration: BoxDecoration( - color: context.colors.surfaceContainer, + color: Theme.of(context).colorScheme.surfaceContainer, border: Border.all( - color: context.colors.outlineVariant, + color: Theme.of(context).colorScheme.outlineVariant, width: 1, ), borderRadius: BorderRadius.circular(AppRadius.xl), diff --git a/flutter_monisuo/lib/ui/pages/home/quick_actions_row.dart b/flutter_monisuo/lib/ui/pages/home/quick_actions_row.dart index 7763798..c339173 100644 --- a/flutter_monisuo/lib/ui/pages/home/quick_actions_row.dart +++ b/flutter_monisuo/lib/ui/pages/home/quick_actions_row.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_spacing.dart'; diff --git a/flutter_monisuo/lib/ui/pages/main/main_page.dart b/flutter_monisuo/lib/ui/pages/main/main_page.dart index 5f5d242..afe678d 100644 --- a/flutter_monisuo/lib/ui/pages/main/main_page.dart +++ b/flutter_monisuo/lib/ui/pages/main/main_page.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; -import '../../../core/theme/app_color_scheme.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme.dart'; import '../../../providers/asset_provider.dart'; diff --git a/flutter_monisuo/lib/ui/pages/mine/kyc_page.dart b/flutter_monisuo/lib/ui/pages/mine/kyc_page.dart index aecadb3..15df2cd 100644 --- a/flutter_monisuo/lib/ui/pages/mine/kyc_page.dart +++ b/flutter_monisuo/lib/ui/pages/mine/kyc_page.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:provider/provider.dart'; import 'package:image_picker/image_picker.dart'; import '../../../core/theme/app_color_scheme.dart'; @@ -431,9 +431,9 @@ class _KycPageState extends State { if (!mounted) return; if (response.success) { - showShadDialog( + showDialog( context: context, - builder: (ctx) => ShadDialog.alert( + builder: (ctx) => AlertDialog( title: Row( children: [ NeonIcon( @@ -445,9 +445,9 @@ class _KycPageState extends State { const Text('認證成功'), ], ), - description: const Text('您的實名認證已通過,現在可以進行提現操作'), + content: const Text('您的實名認證已通過,現在可以進行提現操作'), actions: [ - ShadButton( + TextButton( child: const Text('確定'), onPressed: () { Navigator.of(ctx).pop(); @@ -458,13 +458,13 @@ class _KycPageState extends State { ), ); } else { - showShadDialog( + showDialog( context: context, - builder: (ctx) => ShadDialog.alert( + builder: (ctx) => AlertDialog( title: const Text('認證失敗'), - description: Text(response.message ?? '請稍後重試'), + content: Text(response.message ?? '請稍後重試'), actions: [ - ShadButton( + TextButton( child: const Text('確定'), onPressed: () => Navigator.of(ctx).pop(), ), @@ -474,13 +474,13 @@ class _KycPageState extends State { } } catch (e) { if (mounted) { - showShadDialog( + showDialog( context: context, - builder: (ctx) => ShadDialog.alert( + builder: (ctx) => AlertDialog( title: const Text('認證失敗'), - description: Text(e.toString()), + content: Text(e.toString()), actions: [ - ShadButton( + TextButton( child: const Text('確定'), onPressed: () => Navigator.of(ctx).pop(), ), diff --git a/flutter_monisuo/lib/ui/pages/mine/welfare_center_page.dart b/flutter_monisuo/lib/ui/pages/mine/welfare_center_page.dart index e546bc5..567f4de 100644 --- a/flutter_monisuo/lib/ui/pages/mine/welfare_center_page.dart +++ b/flutter_monisuo/lib/ui/pages/mine/welfare_center_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:provider/provider.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme.dart'; @@ -145,9 +145,9 @@ class _WelfareCenterPageState extends State { final goldAccent = context.appColors.accentPrimary; return Scaffold( - backgroundColor: context.colors.surface, + backgroundColor: Theme.of(context).colorScheme.surface, appBar: AppBar( - backgroundColor: context.colors.surface, + backgroundColor: Theme.of(context).colorScheme.surface, elevation: 0, scrolledUnderElevation: 0, centerTitle: false, @@ -157,7 +157,7 @@ class _WelfareCenterPageState extends State { style: AppTextStyles.headlineLarge(context), ), leading: IconButton( - icon: Icon(LucideIcons.arrowLeft, color: context.colors.onSurface, size: 24), + icon: Icon(LucideIcons.arrowLeft, color: Theme.of(context).colorScheme.onSurface, size: 24), onPressed: () => Navigator.of(context).pop(), ), ), @@ -242,7 +242,7 @@ class _WelfareCenterPageState extends State { }, style: ElevatedButton.styleFrom( backgroundColor: goldAccent, - foregroundColor: context.colors.onPrimary, + foregroundColor: Theme.of(context).colorScheme.onPrimary, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppRadius.lg), @@ -251,7 +251,7 @@ class _WelfareCenterPageState extends State { ), child: Text( '複製邀請碼', - style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onPrimary), + style: AppTextStyles.headlineMedium(context).copyWith(color: Theme.of(context).colorScheme.onPrimary), ), ), ), @@ -325,21 +325,21 @@ class _WelfareCenterPageState extends State { '+100 USDT', style: AppTextStyles.displayLarge(context).copyWith( fontWeight: FontWeight.w800, - color: claimed ? context.colors.onSurfaceVariant : profitGreen, + color: claimed ? Theme.of(context).colorScheme.onSurfaceVariant : profitGreen, ), ), const SizedBox(height: 8), Text( description, style: AppTextStyles.bodyLarge(context).copyWith( - color: context.colors.onSurfaceVariant, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 16), _fullWidthButton( text: buttonText, backgroundColor: profitGreen, - foregroundColor: context.colors.onPrimary, + foregroundColor: Theme.of(context).colorScheme.onPrimary, onPressed: canClaim ? () => _claimNewUserBonus() : null, ), ], @@ -425,12 +425,12 @@ class _WelfareCenterPageState extends State { child: Column( children: [ Text(label, style: AppTextStyles.bodySmall(context).copyWith( - color: context.colors.onSurfaceVariant, + color: Theme.of(context).colorScheme.onSurfaceVariant, )), const SizedBox(height: 2), Text(value, style: AppTextStyles.headlineSmall(context).copyWith( fontWeight: FontWeight.w700, - color: highlight ? context.appColors.up : context.colors.onSurface, + color: highlight ? context.appColors.up : Theme.of(context).colorScheme.onSurface, )), ], ), @@ -452,7 +452,7 @@ class _WelfareCenterPageState extends State { Text( '暫無推廣用戶', style: AppTextStyles.bodyLarge(context).copyWith( - color: context.colors.onSurfaceVariant, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ], @@ -592,7 +592,7 @@ class _WelfareCenterPageState extends State { label = '${threshold}'; } else { bgColor = context.appColors.surfaceCardHigh; - textColor = context.colors.onSurfaceVariant; + textColor = Theme.of(context).colorScheme.onSurfaceVariant; label = '${threshold}'; } @@ -631,7 +631,7 @@ class _WelfareCenterPageState extends State { child: Text( username.isNotEmpty ? username[0].toUpperCase() : '?', style: AppTextStyles.headlineSmall(context).copyWith( - color: context.colors.onSurfaceVariant, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ), @@ -719,7 +719,7 @@ class _WelfareCenterPageState extends State { Text( '已推廣 $indirectRefCount 人', style: AppTextStyles.bodyMedium(context).copyWith( - color: context.colors.onSurfaceVariant, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), if (indirectClaimableCount > 0) ...[ @@ -773,7 +773,7 @@ class _WelfareCenterPageState extends State { label = '50\u{1F381}'; } else { bgColor = context.appColors.surfaceCardHigh; - textColor = context.colors.onSurfaceVariant; + textColor = Theme.of(context).colorScheme.onSurfaceVariant; label = '50'; } @@ -841,7 +841,7 @@ class _WelfareCenterPageState extends State { child: Text( '\u2022 $text', style: AppTextStyles.bodyMedium(context).copyWith( - color: context.colors.onSurfaceVariant, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ); diff --git a/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart b/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart index 41d1520..c5ff6c3 100644 --- a/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart +++ b/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart @@ -1,9 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme.dart'; -import '../../../core/theme/app_theme_extension.dart'; import '../../../core/storage/local_storage.dart'; /// 引導頁數據模型 @@ -93,7 +92,7 @@ class _OnboardingPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: context.colors.surface, + backgroundColor: Theme.of(context).colorScheme.surface, body: SafeArea( child: Column( children: [ @@ -111,7 +110,7 @@ class _OnboardingPageState extends State { child: Text( '跳過', style: AppTextStyles.headlineMedium(context).copyWith( - color: context.colors.onSurfaceVariant, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ), @@ -159,8 +158,8 @@ class _OnboardingPageState extends State { child: ElevatedButton( onPressed: _nextPage, style: ElevatedButton.styleFrom( - backgroundColor: context.colors.primary, - foregroundColor: context.colors.onPrimary, + backgroundColor: Theme.of(context).colorScheme.primary, + foregroundColor: Theme.of(context).colorScheme.onPrimary, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppRadius.lg), ), @@ -221,7 +220,7 @@ class _OnboardingPageState extends State { return Icon( item.icon ?? LucideIcons.image, size: 72, - color: context.colors.onPrimary, + color: Theme.of(context).colorScheme.onPrimary, ); }, ), @@ -229,7 +228,7 @@ class _OnboardingPageState extends State { : Icon( item.icon ?? LucideIcons.star, size: 72, - color: context.colors.onPrimary, + color: Theme.of(context).colorScheme.onPrimary, ), ), ), @@ -239,7 +238,7 @@ class _OnboardingPageState extends State { item.title, style: AppTextStyles.displaySmall(context).copyWith( fontWeight: FontWeight.bold, - color: context.colors.onSurface, + color: Theme.of(context).colorScheme.onSurface, letterSpacing: -0.5, ), ), @@ -249,7 +248,7 @@ class _OnboardingPageState extends State { item.description, textAlign: TextAlign.center, style: AppTextStyles.headlineMedium(context).copyWith( - color: context.colors.onSurfaceVariant, + color: Theme.of(context).colorScheme.onSurfaceVariant, height: 1.6, ), ), @@ -267,7 +266,7 @@ class _OnboardingPageState extends State { width: isActive ? 24 : 8, height: 8, decoration: BoxDecoration( - color: isActive ? context.colors.primary : context.colors.outlineVariant, + color: isActive ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.outlineVariant, borderRadius: BorderRadius.circular(AppRadius.sm), ), ); diff --git a/flutter_monisuo/lib/ui/pages/orders/fund_order_card.dart b/flutter_monisuo/lib/ui/pages/orders/fund_order_card.dart index 919d58b..45d39e2 100644 --- a/flutter_monisuo/lib/ui/pages/orders/fund_order_card.dart +++ b/flutter_monisuo/lib/ui/pages/orders/fund_order_card.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:provider/provider.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_color_scheme.dart'; @@ -84,7 +83,7 @@ class _FundOrderCard extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); final isDeposit = order.type == 1; final statusColor = _getStatusColor(order.status, isDeposit); @@ -93,9 +92,10 @@ class _FundOrderCard extends StatelessWidget { ? order.receivableAmount : order.amount; - return ShadCard( - padding: AppSpacing.cardPadding, - child: Column( + return Card( + child: Padding( + padding: AppSpacing.cardPadding, + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( @@ -126,7 +126,7 @@ class _FundOrderCard extends StatelessWidget { if (order.fee != null) ...[ Row( children: [ - Text('手續費(10%): ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('手續費(10%): ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text('-${order.fee} USDT', style: AppTextStyles.bodyMedium(context)), ], ), @@ -135,7 +135,7 @@ class _FundOrderCard extends StatelessWidget { if (order.receivableAmount != null) ...[ Row( children: [ - Text('到賬金額: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('到賬金額: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text('${order.receivableAmount} USDT', style: AppTextStyles.bodyMedium(context).copyWith(fontWeight: FontWeight.w700)), ], ), @@ -144,7 +144,7 @@ class _FundOrderCard extends StatelessWidget { if (order.network != null) ...[ Row( children: [ - Text('提現網絡: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('提現網絡: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text(order.network!, style: AppTextStyles.bodyMedium(context)), ], ), @@ -153,7 +153,7 @@ class _FundOrderCard extends StatelessWidget { if (order.walletAddress != null) ...[ Row( children: [ - Text('提現地址: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('提現地址: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Expanded( child: Text( order.walletAddress!, @@ -169,14 +169,14 @@ class _FundOrderCard extends StatelessWidget { ], Row( children: [ - Text('訂單號: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('訂單號: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text(order.orderNo, style: AppTextStyles.bodyMedium(context)), ], ), SizedBox(height: AppSpacing.xs), Row( children: [ - Text('創建時間: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('創建時間: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text( order.createTime?.toString() ?? '無', style: AppTextStyles.bodyMedium(context), @@ -187,7 +187,7 @@ class _FundOrderCard extends StatelessWidget { SizedBox(height: AppSpacing.xs), Row( children: [ - Text('駁回原因: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('駁回原因: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Expanded( child: Text( order.rejectReason!, @@ -202,14 +202,14 @@ class _FundOrderCard extends StatelessWidget { Row( children: [ Expanded( - child: ShadButton.outline( + child: OutlinedButton( onPressed: () => _handleConfirmPay(context), child: const Text('已打款'), ), ), SizedBox(width: AppSpacing.sm), Expanded( - child: ShadButton.outline( + child: OutlinedButton( onPressed: () => _handleCancel(context), child: const Text('取消訂單'), ), @@ -219,6 +219,7 @@ class _FundOrderCard extends StatelessWidget { ], ], ), + ), ); } diff --git a/flutter_monisuo/lib/ui/pages/orders/fund_orders_list.dart b/flutter_monisuo/lib/ui/pages/orders/fund_orders_list.dart index 779f4cc..65dae90 100644 --- a/flutter_monisuo/lib/ui/pages/orders/fund_orders_list.dart +++ b/flutter_monisuo/lib/ui/pages/orders/fund_orders_list.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:provider/provider.dart'; import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_spacing.dart'; @@ -16,7 +16,7 @@ class FundOrdersList extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); final orders = provider.fundOrders; if (orders.isEmpty) { @@ -33,7 +33,7 @@ class FundOrdersList extends StatelessWidget { physics: const AlwaysScrollableScrollPhysics(), padding: AppSpacing.pagePadding, itemCount: orders.length, - separatorBuilder: (_, __) => Divider(color: theme.colorScheme.border, height: 1), + separatorBuilder: (_, __) => Divider(color: theme.colorScheme.outline, height: 1), itemBuilder: (context, index) { final order = orders[index]; return FundOrderCard(order: order); @@ -52,7 +52,7 @@ class _EmptyState extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); return Center( child: Padding( @@ -60,9 +60,9 @@ class _EmptyState extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(icon, size: 48, color: theme.colorScheme.mutedForeground), + Icon(icon, size: 48, color: theme.colorScheme.onSurfaceVariant), SizedBox(height: AppSpacing.sm + AppSpacing.xs), - Text(message, style: theme.textTheme.muted), + Text(message, style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), ], ), ), @@ -155,13 +155,14 @@ class _FundOrderCardContent extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); final isDeposit = order.type == 1; final statusColor = _getStatusColor(order.status, isDeposit); - return ShadCard( - padding: AppSpacing.cardPadding, - child: Column( + return Card( + child: Padding( + padding: AppSpacing.cardPadding, + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( @@ -192,7 +193,7 @@ class _FundOrderCardContent extends StatelessWidget { if (order.fee != null) ...[ Row( children: [ - Text('手續費(10%): ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('手續費(10%): ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text('-${order.fee} USDT', style: AppTextStyles.bodyMedium(context)), ], ), @@ -201,7 +202,7 @@ class _FundOrderCardContent extends StatelessWidget { if (order.receivableAmount != null) ...[ Row( children: [ - Text('到賬金額: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('到賬金額: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text('${order.receivableAmount} USDT', style: AppTextStyles.bodyMedium(context).copyWith(fontWeight: FontWeight.w700)), ], ), @@ -210,7 +211,7 @@ class _FundOrderCardContent extends StatelessWidget { if (order.network != null) ...[ Row( children: [ - Text('提現網絡: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('提現網絡: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text(order.network!, style: AppTextStyles.bodyMedium(context)), ], ), @@ -219,7 +220,7 @@ class _FundOrderCardContent extends StatelessWidget { if (order.walletAddress != null) ...[ Row( children: [ - Text('提現地址: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('提現地址: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Expanded( child: Text( order.walletAddress!, @@ -234,14 +235,14 @@ class _FundOrderCardContent extends StatelessWidget { ], Row( children: [ - Text('訂單號: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('訂單號: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text(order.orderNo, style: AppTextStyles.bodyMedium(context)), ], ), SizedBox(height: AppSpacing.xs), Row( children: [ - Text('創建時間: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('創建時間: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), Text( order.createTime?.toString() ?? '無', style: AppTextStyles.bodyMedium(context), @@ -250,6 +251,7 @@ class _FundOrderCardContent extends StatelessWidget { ), ], ), + ), ); } } diff --git a/flutter_monisuo/lib/ui/pages/orders/orders_page.dart b/flutter_monisuo/lib/ui/pages/orders/orders_page.dart index 8ed4e20..3c41765 100644 --- a/flutter_monisuo/lib/ui/pages/orders/orders_page.dart +++ b/flutter_monisuo/lib/ui/pages/orders/orders_page.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:provider/provider.dart'; import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_spacing.dart'; @@ -35,10 +35,10 @@ class _OrdersPageState extends State with AutomaticKeepAliveClientMi @override Widget build(BuildContext context) { super.build(context); - final theme = ShadTheme.of(context); + final theme = Theme.of(context); return Scaffold( - backgroundColor: theme.colorScheme.background, + backgroundColor: theme.colorScheme.surface, body: Consumer( builder: (context, provider, _) { return RefreshIndicator( @@ -83,12 +83,12 @@ class TabSelector extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); return Container( padding: const EdgeInsets.all(AppSpacing.xs), decoration: BoxDecoration( - color: theme.colorScheme.card, + color: theme.colorScheme.surfaceContainer, borderRadius: AppRadius.radiusLg, ), child: Row( @@ -115,7 +115,7 @@ class TabSelector extends StatelessWidget { color: context.colors.surface, ) : AppTextStyles.labelLarge(context).copyWith( - color: theme.colorScheme.mutedForeground, + color: theme.colorScheme.onSurfaceVariant, fontWeight: FontWeight.w400, ), ), @@ -137,7 +137,7 @@ class TradeOrdersList extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); return Center( child: Padding( @@ -145,9 +145,9 @@ class TradeOrdersList extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(LucideIcons.receipt, size: 48, color: theme.colorScheme.mutedForeground), + Icon(LucideIcons.receipt, size: 48, color: theme.colorScheme.onSurfaceVariant), SizedBox(height: AppSpacing.sm + AppSpacing.xs), - Text('暫無交易記錄', style: theme.textTheme.muted), + Text('暫無交易記錄', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant)), ], ), ), diff --git a/flutter_monisuo/lib/ui/pages/trade/trade_page.dart b/flutter_monisuo/lib/ui/pages/trade/trade_page.dart index d2aab77..7a0d21e 100644 --- a/flutter_monisuo/lib/ui/pages/trade/trade_page.dart +++ b/flutter_monisuo/lib/ui/pages/trade/trade_page.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import 'package:provider/provider.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme_extension.dart'; @@ -125,7 +125,7 @@ class _TradePageState extends State super.build(context); return Scaffold( - backgroundColor: context.colors.background, + backgroundColor: Theme.of(context).colorScheme.surface, body: Consumer2( builder: (context, market, asset, _) { return SafeArea( @@ -280,25 +280,25 @@ class _TradePageState extends State } void _showResultDialog(bool success, String title, String message) { - showShadDialog( + showDialog( context: context, - builder: (ctx) => ShadDialog.alert( + builder: (ctx) => AlertDialog( title: Row( children: [ NeonIcon( icon: success ? Icons.check_circle : Icons.error, color: success ? ctx.appColors.up - : ctx.colors.error, + : Theme.of(ctx).colorScheme.error, size: 24, ), SizedBox(width: AppSpacing.sm), Text(title), ], ), - description: Text(message), + content: Text(message), actions: [ - ShadButton( + TextButton( child: const Text('確定'), onPressed: () => Navigator.of(ctx).pop(), ), diff --git a/flutter_monisuo/lib/ui/shared/modern_bottom_sheet.dart b/flutter_monisuo/lib/ui/shared/modern_bottom_sheet.dart index 7a87aa2..0768528 100644 --- a/flutter_monisuo/lib/ui/shared/modern_bottom_sheet.dart +++ b/flutter_monisuo/lib/ui/shared/modern_bottom_sheet.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; +import 'package:lucide_icons_flutter/lucide_icons.dart'; import '../../core/theme/app_spacing.dart'; +import '../../core/theme/app_theme.dart'; /// 現代底部抽屜模板 - 基於 modernization-v2.md 規範 /// @@ -100,17 +101,19 @@ class ModernBottomSheet extends StatelessWidget { Row( children: [ Expanded( - child: ShadButton.outline( + child: OutlinedButton( onPressed: () => Navigator.of(context).pop(0), child: Text(cancelText), ), ), const SizedBox(width: AppSpacing.md), Expanded( - child: ShadButton( - backgroundColor: isDestructive - ? ShadTheme.of(context).colorScheme.destructive - : null, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: isDestructive + ? Theme.of(context).colorScheme.error + : null, + ), onPressed: () => Navigator.of(context).pop(1), child: Text(confirmText), ), @@ -125,12 +128,12 @@ class ModernBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); final bottomPadding = MediaQuery.of(context).padding.bottom; return Container( decoration: BoxDecoration( - color: theme.colorScheme.card, + color: theme.colorScheme.surfaceContainer, borderRadius: const BorderRadius.vertical( top: Radius.circular(AppRadius.xxl), ), @@ -164,21 +167,21 @@ class ModernBottomSheet extends StatelessWidget { ); } - Widget _buildDragHandle(ShadThemeData theme) { + Widget _buildDragHandle(ThemeData theme) { return Center( child: Container( width: 40, height: 4, margin: const EdgeInsets.only(bottom: AppSpacing.md), decoration: BoxDecoration( - color: theme.colorScheme.muted, + color: theme.colorScheme.outline, borderRadius: BorderRadius.circular(2), ), ), ); } - Widget _buildHeader(BuildContext context, ShadThemeData theme) { + Widget _buildHeader(BuildContext context, ThemeData theme) { return Padding( padding: const EdgeInsets.only(bottom: AppSpacing.md), child: Row( @@ -187,7 +190,7 @@ class ModernBottomSheet extends StatelessWidget { Expanded( child: titleWidget ?? Text( title!, - style: theme.textTheme.h3.copyWith( + style: AppTextStyles.headlineSmall(context).copyWith( fontWeight: FontWeight.w600, ), ), @@ -202,7 +205,7 @@ class ModernBottomSheet extends StatelessWidget { child: Icon( LucideIcons.x, size: 20, - color: theme.colorScheme.mutedForeground, + color: theme.colorScheme.onSurfaceVariant, ), ), ], @@ -219,7 +222,7 @@ class _ActionList extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); return Column( children: actions.asMap().entries.map((entry) { @@ -229,7 +232,7 @@ class _ActionList extends StatelessWidget { return Column( children: [ if (index > 0 && actions[index - 1].isDivider) - Divider(color: theme.colorScheme.border, height: 1), + Divider(color: theme.colorScheme.outline, height: 1), _ActionTile(action: action), ], ); @@ -246,7 +249,7 @@ class _ActionTile extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); return InkWell( onTap: () { @@ -266,8 +269,8 @@ class _ActionTile extends StatelessWidget { action.icon, size: 20, color: action.isDestructive - ? theme.colorScheme.destructive - : theme.colorScheme.foreground, + ? theme.colorScheme.error + : theme.colorScheme.onSurface, ), const SizedBox(width: AppSpacing.md), ], @@ -277,8 +280,8 @@ class _ActionTile extends StatelessWidget { style: TextStyle( fontSize: 16, color: action.isDestructive - ? theme.colorScheme.destructive - : theme.colorScheme.foreground, + ? theme.colorScheme.error + : theme.colorScheme.onSurface, ), ), ), diff --git a/flutter_monisuo/lib/ui/shared/modern_dialog.dart b/flutter_monisuo/lib/ui/shared/modern_dialog.dart index 8241456..39938b0 100644 --- a/flutter_monisuo/lib/ui/shared/modern_dialog.dart +++ b/flutter_monisuo/lib/ui/shared/modern_dialog.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:shadcn_ui/shadcn_ui.dart'; import '../../core/theme/app_spacing.dart'; +import '../../core/theme/app_theme.dart'; /// 現代彈窗模板 - 基於 modernization-v2.md 規範 /// @@ -102,13 +102,13 @@ class ModernDialog extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppRadius.xl), ), - backgroundColor: theme.colorScheme.card, + backgroundColor: theme.colorScheme.surfaceContainer, child: Container( padding: const EdgeInsets.all(AppSpacing.lg), constraints: const BoxConstraints(maxWidth: 400), @@ -122,7 +122,7 @@ class ModernDialog extends StatelessWidget { else if (title != null) Text( title!, - style: theme.textTheme.h3.copyWith( + style: AppTextStyles.headlineSmall(context).copyWith( fontWeight: FontWeight.w600, ), ), @@ -132,7 +132,7 @@ class ModernDialog extends StatelessWidget { if (description != null) ...[ Text( description!, - style: theme.textTheme.muted, + style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.onSurfaceVariant), ), const SizedBox(height: AppSpacing.md), ], @@ -166,11 +166,13 @@ class ModernDialog extends StatelessWidget { } Widget _buildActionButton(BuildContext context, ModernDialogAction action) { - final theme = ShadTheme.of(context); + final theme = Theme.of(context); if (action.isPrimary) { - return ShadButton( - backgroundColor: action.isDestructive ? theme.colorScheme.destructive : theme.colorScheme.primary, + return ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: action.isDestructive ? theme.colorScheme.error : theme.colorScheme.primary, + ), onPressed: () { Navigator.of(context).pop(action.returnValue); action.onPressed?.call(); @@ -179,7 +181,7 @@ class ModernDialog extends StatelessWidget { ); } - return ShadButton.outline( + return OutlinedButton( onPressed: () { Navigator.of(context).pop(action.returnValue); action.onPressed?.call(); diff --git a/flutter_monisuo/pubspec.lock b/flutter_monisuo/pubspec.lock index d114f5b..cec02a0 100644 --- a/flutter_monisuo/pubspec.lock +++ b/flutter_monisuo/pubspec.lock @@ -1,14 +1,6 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - args: - dependency: transitive - description: - name: args - sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 - url: "https://pub.dev" - source: hosted - version: "2.7.0" async: dependency: transitive description: @@ -33,14 +25,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.3" - boxy: - dependency: transitive - description: - name: boxy - sha256: "569373f23560f5a5dbe53c08a7463a698635e7ac72ba355ff4fa52516c0d2e32" - url: "https://pub.dev" - source: hosted - version: "2.2.2" characters: dependency: transitive description: @@ -113,22 +97,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" - extended_image: - dependency: transitive - description: - name: extended_image - sha256: f6cbb1d798f51262ed1a3d93b4f1f2aa0d76128df39af18ecb77fa740f88b2e0 - url: "https://pub.dev" - source: hosted - version: "10.0.1" - extended_image_library: - dependency: transitive - description: - name: extended_image_library - sha256: "1f9a24d3a00c2633891c6a7b5cab2807999eb2d5b597e5133b63f49d113811fe" - url: "https://pub.dev" - source: hosted - version: "5.0.1" fake_async: dependency: transitive description: @@ -235,14 +203,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.3" - flutter_svg: - dependency: transitive - description: - name: flutter_svg - sha256: "1ded017b39c8e15c8948ea855070a5ff8ff8b3d5e83f3446e02d6bb12add7ad9" - url: "https://pub.dev" - source: hosted - version: "2.2.4" flutter_test: dependency: "direct dev" description: flutter @@ -285,14 +245,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.6.0" - http_client_helper: - dependency: transitive - description: - name: http_client_helper - sha256: "8a9127650734da86b5c73760de2b404494c968a3fd55602045ffec789dac3cb1" - url: "https://pub.dev" - source: hosted - version: "3.0.0" http_parser: dependency: transitive description: @@ -373,14 +325,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.20.2" - js: - dependency: transitive - description: - name: js - sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" - url: "https://pub.dev" - source: hosted - version: "0.7.2" leak_tracker: dependency: transitive description: @@ -422,13 +366,13 @@ packages: source: hosted version: "1.3.0" lucide_icons_flutter: - dependency: transitive + dependency: "direct main" description: name: lucide_icons_flutter - sha256: f9fc191c852901b7f8d0d5739166327bd71a0fc32ae32c1ba07501d16b966a1a + sha256: e3d13fa20325c7d70d055b0b6a120a07ea2be320df0dbef87cd2aa43ddfbd272 url: "https://pub.dev" source: hosted - version: "3.1.10" + version: "2.0.6" matcher: dependency: transitive description: @@ -493,14 +437,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" - path_parsing: - dependency: transitive - description: - name: path_parsing - sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" - url: "https://pub.dev" - source: hosted - version: "1.1.0" path_provider: dependency: transitive description: @@ -549,14 +485,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" - url: "https://pub.dev" - source: hosted - version: "7.0.2" platform: dependency: transitive description: @@ -597,22 +525,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.3" - serial_csv: - dependency: transitive - description: - name: serial_csv - sha256: "2d62bb70cb3ce7251383fc86ea9aae1298ab1e57af6ef4e93b6a9751c5c268dd" - url: "https://pub.dev" - source: hosted - version: "0.5.2" - shadcn_ui: - dependency: "direct main" - description: - name: shadcn_ui - sha256: "3a303139ed289f4e7d2bd6fc2bc19952033e4456b55dfbf8365461691cc19f48" - url: "https://pub.dev" - source: hosted - version: "0.52.1" shared_preferences: dependency: "direct main" description: @@ -674,22 +586,6 @@ packages: description: flutter source: sdk version: "0.0.0" - slang: - dependency: transitive - description: - name: slang - sha256: ea6702ed6b1c82065fb2de906fe34ac9298117342e3c2ea2567132efdc81bd17 - url: "https://pub.dev" - source: hosted - version: "4.14.0" - slang_flutter: - dependency: transitive - description: - name: slang_flutter - sha256: dcc4e77527c91b12348fc8bdd43d3eb92d8cea37c12a23a1f9719cdc12c804c6 - url: "https://pub.dev" - source: hosted - version: "4.14.0" source_span: dependency: transitive description: @@ -738,22 +634,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.10" - theme_extensions_builder_annotation: - dependency: transitive - description: - name: theme_extensions_builder_annotation - sha256: df0edae633b71d3223853e58d33f4e63ac33990d5c99831ae49bf869ee9fb5ee - url: "https://pub.dev" - source: hosted - version: "7.2.0" - two_dimensional_scrollables: - dependency: transitive - description: - name: two_dimensional_scrollables - sha256: e9397ae372839aecb3135d246bff5cce5e738604c9afd03d65d06c7a246ae958 - url: "https://pub.dev" - source: hosted - version: "0.3.8" typed_data: dependency: transitive description: @@ -762,38 +642,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" - universal_image: - dependency: transitive - description: - name: universal_image - sha256: ef47a4a002158cf0b36ed3b7605af132d2476cc42703e41b8067d3603705c40d - url: "https://pub.dev" - source: hosted - version: "1.0.11" - vector_graphics: - dependency: transitive - description: - name: vector_graphics - sha256: "7076216a10d5c390315fbe536a30f1254c341e7543e6c4c8a815e591307772b1" - url: "https://pub.dev" - source: hosted - version: "1.1.20" - vector_graphics_codec: - dependency: transitive - description: - name: vector_graphics_codec - sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" - url: "https://pub.dev" - source: hosted - version: "1.1.13" - vector_graphics_compiler: - dependency: transitive - description: - name: vector_graphics_compiler - sha256: "5a88dd14c0954a5398af544651c7fb51b457a2a556949bfb25369b210ef73a74" - url: "https://pub.dev" - source: hosted - version: "1.2.0" vector_math: dependency: transitive description: @@ -810,14 +658,6 @@ packages: url: "https://pub.dev" source: hosted version: "15.0.2" - watcher: - dependency: transitive - description: - name: watcher - sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" - url: "https://pub.dev" - source: hosted - version: "1.2.1" web: dependency: transitive description: @@ -834,14 +674,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" - xml: - dependency: transitive - description: - name: xml - sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" - url: "https://pub.dev" - source: hosted - version: "6.6.1" yaml: dependency: transitive description: diff --git a/flutter_monisuo/pubspec.yaml b/flutter_monisuo/pubspec.yaml index edf20ac..53df0cb 100644 --- a/flutter_monisuo/pubspec.yaml +++ b/flutter_monisuo/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: sdk: flutter # UI 组件库 - shadcn_ui: ^0.52.1 + lucide_icons_flutter: ^2.0.0 flutter_animate: ^4.5.0 # 状态管理 diff --git a/flutter_monisuo/test/input_test.dart b/flutter_monisuo/test/input_test.dart new file mode 100644 index 0000000..ded21ed --- /dev/null +++ b/flutter_monisuo/test/input_test.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + runApp(WidgetTesterBinding widgetsBinding) async { + await tester.pumpWidget(MaterialInput(), await tester.pumpWidget(MaterialPasswordInput()); + await tester.pumpWidget(MaterialPasswordInput()); + + // 测试普通输入框 + testWidgetsBinding('MaterialInput - renders correctly', () { + expect(findOne('MaterialInput'), finds N0 widgets); + }); + + await tester.pumpWidget(MaterialInput(), await tester.pumpWidget(MaterialPasswordInput()); + await tester.pumpWidget(MaterialPasswordInput()); + await tester.pumpWidget(MaterialPasswordInput()) + await tester.pumpWidget(MaterialPasswordInput()); + await tester.pumpWidget(MaterialPasswordInput()) + }); + } + }); + + await tester.pumpWidget(MaterialPasswordInput()) + expect(find.byType('MaterialPasswordInput', finds one widget'); + expect(tester.pumpWidget(MaterialPasswordInput()), findsN0 widgets'); + } + }); + }); +} diff --git a/flutter_monisuo/test/input_visual_test.dart b/flutter_monisuo/test/input_visual_test.dart new file mode 100644 index 0000000..5160a15 --- /dev/null +++ b/flutter_monisuo/test/input_visual_test.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(VisualTestingApp( + testWidget: 'MaterialInput - renders correctly', + () { + expect(tester.pumpWidget(MaterialInput()), findsN0 widgets); + }); + + await tester.pumpWidget(MaterialPasswordInput(), await tester.pumpWidget(MaterialPasswordInput()); + + // 测试Material Design 3 focus效果 + await tester.pumpAndSetState(() => { + await tester.pumpAllStates(MaterialInput, () { + expect(find.byType('MaterialInput'), findsN0 widgets'); + } + }); + }); +}