fix:按照shadcn_ui对着demo_shadcn对齐
This commit is contained in:
+70
-24
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
|
||||
import '../theme/wise_tokens.dart';
|
||||
import '../theme/yanting_tokens.dart';
|
||||
import 'app_buttons.dart';
|
||||
import 'app_card.dart';
|
||||
|
||||
@@ -12,9 +13,10 @@ class LoadingState extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView.separated(
|
||||
padding: const EdgeInsets.all(WiseSpacing.x4),
|
||||
padding: const EdgeInsets.all(YantingSpacing.screenX),
|
||||
itemCount: 4,
|
||||
separatorBuilder: (_, _) => const SizedBox(height: WiseSpacing.x3),
|
||||
separatorBuilder: (_, _) =>
|
||||
const SizedBox(height: YantingSpacing.cardGap),
|
||||
itemBuilder: (context, index) => const SkeletonCard(),
|
||||
);
|
||||
}
|
||||
@@ -30,11 +32,11 @@ class SkeletonCard extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: const [
|
||||
SkeletonLine(width: 96),
|
||||
SizedBox(height: WiseSpacing.x3),
|
||||
SizedBox(height: YantingSpacing.cardGap),
|
||||
SkeletonLine(width: double.infinity, height: 18),
|
||||
SizedBox(height: WiseSpacing.x2),
|
||||
SizedBox(height: YantingSpacing.x2),
|
||||
SkeletonLine(width: 240),
|
||||
SizedBox(height: WiseSpacing.x3),
|
||||
SizedBox(height: YantingSpacing.cardGap),
|
||||
SkeletonLine(width: 160),
|
||||
],
|
||||
),
|
||||
@@ -50,12 +52,58 @@ class SkeletonLine extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
final theme = ShadTheme.of(context);
|
||||
return _PulsingSkeleton(
|
||||
width: width,
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: WiseColors.border,
|
||||
borderRadius: BorderRadius.circular(WiseRadius.pill),
|
||||
color: theme.colorScheme.muted,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PulsingSkeleton extends StatefulWidget {
|
||||
const _PulsingSkeleton({
|
||||
required this.color,
|
||||
required this.width,
|
||||
required this.height,
|
||||
});
|
||||
|
||||
final Color color;
|
||||
final double width;
|
||||
final double height;
|
||||
|
||||
@override
|
||||
State<_PulsingSkeleton> createState() => _PulsingSkeletonState();
|
||||
}
|
||||
|
||||
class _PulsingSkeletonState extends State<_PulsingSkeleton>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late final AnimationController _controller = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 1500),
|
||||
)..repeat(reverse: true);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = ShadTheme.of(context);
|
||||
return FadeTransition(
|
||||
opacity: Tween<double>(
|
||||
begin: 0.4,
|
||||
end: 1,
|
||||
).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut)),
|
||||
child: Container(
|
||||
width: widget.width,
|
||||
height: widget.height,
|
||||
decoration: BoxDecoration(
|
||||
color: widget.color,
|
||||
borderRadius: theme.radius,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -79,24 +127,29 @@ class EmptyState extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = ShadTheme.of(context);
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(WiseSpacing.x6),
|
||||
padding: const EdgeInsets.all(YantingSpacing.x6),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, size: 42, color: WiseColors.primary),
|
||||
const SizedBox(height: WiseSpacing.x3),
|
||||
Icon(icon, size: 42, color: theme.colorScheme.foreground),
|
||||
const SizedBox(height: YantingSpacing.cardGap),
|
||||
Text(title, style: Theme.of(context).textTheme.titleMedium),
|
||||
const SizedBox(height: WiseSpacing.x2),
|
||||
const SizedBox(height: YantingSpacing.x2),
|
||||
Text(
|
||||
message,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
if (actionLabel != null) ...[
|
||||
const SizedBox(height: WiseSpacing.x4),
|
||||
AppButton(label: actionLabel!, onPressed: onAction, kind: AppButtonKind.ghost),
|
||||
const SizedBox(height: YantingSpacing.x4),
|
||||
AppButton(
|
||||
label: actionLabel!,
|
||||
onPressed: onAction,
|
||||
kind: AppButtonKind.ghost,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
@@ -124,12 +177,5 @@ class ErrorState extends StatelessWidget {
|
||||
}
|
||||
|
||||
void showAppToast(BuildContext context, String message) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
backgroundColor: WiseColors.primary,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(WiseRadius.md)),
|
||||
),
|
||||
);
|
||||
ShadToaster.of(context).show(ShadToast(title: Text(message)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user