fix:导航栏交互和UI

This commit is contained in:
jingyun
2026-06-05 16:05:32 +08:00
parent c5288f397d
commit 33d04a5545
10 changed files with 267 additions and 147 deletions
+41 -35
View File
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import '../theme/yanting_text.dart';
import '../theme/yanting_tokens.dart';
class AppButton extends StatelessWidget {
@@ -10,6 +11,7 @@ class AppButton extends StatelessWidget {
this.icon,
this.kind = AppButtonKind.primary,
this.expand = false,
this.compact = false,
super.key,
});
@@ -18,45 +20,49 @@ class AppButton extends StatelessWidget {
final IconData? icon;
final AppButtonKind kind;
final bool expand;
final bool compact;
@override
Widget build(BuildContext context) {
final leading = icon == null ? null : Icon(icon, size: 16);
final width = expand ? double.infinity : null;
final child = Text(label);
return switch (kind) {
AppButtonKind.primary => ShadButton(
width: width,
onPressed: onPressed,
leading: leading,
child: child,
),
AppButtonKind.dark => ShadButton(
width: width,
onPressed: onPressed,
leading: leading,
backgroundColor: YantingColors.foreground,
foregroundColor: YantingColors.background,
hoverBackgroundColor: YantingColors.foreground.withValues(alpha: 0.9),
child: child,
),
AppButtonKind.accent => ShadButton.secondary(
width: width,
onPressed: onPressed,
leading: leading,
backgroundColor: YantingColors.brandSoft,
foregroundColor: YantingColors.primaryForeground,
hoverBackgroundColor: YantingColors.brandSoftBorder,
child: child,
),
AppButtonKind.ghost => ShadButton.outline(
width: width,
onPressed: onPressed,
leading: leading,
child: child,
),
final variant = switch (kind) {
AppButtonKind.primary => ShadButtonVariant.primary,
AppButtonKind.dark => ShadButtonVariant.primary,
AppButtonKind.accent => ShadButtonVariant.secondary,
AppButtonKind.ghost => ShadButtonVariant.outline,
};
final colors = switch (kind) {
AppButtonKind.primary => (null, null, null),
AppButtonKind.dark => (
YantingColors.foreground,
YantingColors.background,
YantingColors.foreground.withValues(alpha: 0.9),
),
AppButtonKind.accent => (
YantingColors.brandSoft,
YantingColors.primaryForeground,
YantingColors.brandSoftBorder,
),
AppButtonKind.ghost => (null, null, null),
};
final button = ShadButton.raw(
variant: variant,
enabled: onPressed != null,
onPressed: onPressed,
width: expand ? double.infinity : null,
height: compact ? 36 : 44,
padding: EdgeInsets.symmetric(horizontal: compact ? 16 : 20),
backgroundColor: colors.$1,
foregroundColor: colors.$2,
hoverBackgroundColor: colors.$3,
leading: icon == null ? null : Icon(icon, size: compact ? 15 : 16),
gap: compact ? 5 : 7,
textStyle: (compact ? YantingText.badge : YantingText.body).copyWith(
color: colors.$2,
fontWeight: FontWeight.w600,
),
child: Text(label),
);
return expand ? SizedBox(width: double.infinity, child: button) : button;
}
}
+18 -17
View File
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import '../theme/yanting_tokens.dart';
@@ -21,29 +20,31 @@ class AppCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = ShadTheme.of(context);
final radius = BorderRadius.circular(YantingRadius.xl);
final content = ShadCard(
padding: padding,
backgroundColor: color,
radius: radius,
border: ShadBorder.all(color: borderColor),
shadows: const [],
child: child,
final decoration = BoxDecoration(
color: color,
borderRadius: radius,
border: Border.all(color: borderColor),
);
if (onTap == null) return content;
if (onTap == null) {
return DecoratedBox(
decoration: decoration,
child: Padding(padding: padding, child: child),
);
}
return Material(
color: Colors.transparent,
borderRadius: radius,
child: InkWell(
borderRadius: radius,
splashColor: theme.colorScheme.mutedForeground.withValues(alpha: 0.08),
highlightColor: theme.colorScheme.mutedForeground.withValues(
alpha: 0.04,
child: Ink(
decoration: decoration,
child: InkWell(
borderRadius: radius,
splashColor: YantingColors.mutedForeground.withValues(alpha: 0.08),
highlightColor: YantingColors.mutedForeground.withValues(alpha: 0.04),
onTap: onTap,
child: Padding(padding: padding, child: child),
),
onTap: onTap,
child: content,
),
);
}
+8 -8
View File
@@ -23,14 +23,14 @@ class InstitutionCard extends StatelessWidget {
: institution.nameCn.characters.take(2).toString();
return AppCard(
onTap: onTap,
padding: const EdgeInsets.all(16),
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
InstitutionLogo(
logoUrl: institution.logoUrl,
initials: initials,
size: 52,
size: 48,
),
const SizedBox(width: 14),
Expanded(
@@ -54,10 +54,10 @@ class InstitutionCard extends StatelessWidget {
style: YantingText.meta,
),
],
const SizedBox(height: 11),
const SizedBox(height: 8),
Wrap(
spacing: 8,
runSpacing: 8,
spacing: 7,
runSpacing: 7,
children: [
if (institution.institutionType.isNotEmpty)
AppBadge(
@@ -71,14 +71,14 @@ class InstitutionCard extends StatelessWidget {
],
),
),
const SizedBox(width: 8),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'${institution.reportCount}',
style: YantingText.sectionTitle.copyWith(
fontSize: 21,
fontSize: 20,
fontFeatures: YantingTypographyFeatures.tabularNums,
),
),