Files
English/kouyu_english/lib/widgets/app_widgets.dart
T

164 lines
3.7 KiB
Dart

import 'package:flutter/material.dart';
import '../core/app_theme.dart';
class AppPage extends StatelessWidget {
const AppPage({
super.key,
required this.child,
this.appBar,
this.bottomNavigationBar,
});
final Widget child;
final PreferredSizeWidget? appBar;
final Widget? bottomNavigationBar;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: appBar,
bottomNavigationBar: bottomNavigationBar,
body: SafeArea(
top: appBar == null,
child: SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(16, 20, 16, 24),
child: child,
),
),
);
}
}
class SectionCard extends StatelessWidget {
const SectionCard({
super.key,
required this.child,
this.tint,
this.onTap,
this.padding = const EdgeInsets.all(14),
});
final Widget child;
final Color? tint;
final VoidCallback? onTap;
final EdgeInsets padding;
@override
Widget build(BuildContext context) {
final content = Padding(padding: padding, child: child);
return Material(
color: tint ?? AppColors.surface,
borderRadius: BorderRadius.circular(16),
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(16),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: AppColors.line),
borderRadius: BorderRadius.circular(16),
),
child: content,
),
),
);
}
}
class PrimaryButton extends StatelessWidget {
const PrimaryButton({
super.key,
required this.label,
required this.onPressed,
this.icon,
});
final String label;
final VoidCallback? onPressed;
final IconData? icon;
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 50,
child: FilledButton.icon(
onPressed: onPressed,
icon: icon == null ? const SizedBox.shrink() : Icon(icon),
label: Text(label),
style: FilledButton.styleFrom(
backgroundColor: AppColors.green,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
),
),
),
);
}
}
class SecondaryButton extends StatelessWidget {
const SecondaryButton({
super.key,
required this.label,
required this.onPressed,
});
final String label;
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 48,
child: OutlinedButton(
onPressed: onPressed,
style: OutlinedButton.styleFrom(
foregroundColor: AppColors.ink,
side: const BorderSide(color: AppColors.line),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
),
),
child: Text(label),
),
);
}
}
class Eyebrow extends StatelessWidget {
const Eyebrow(this.text, {super.key});
final String text;
@override
Widget build(BuildContext context) => Text(
text,
style: const TextStyle(
color: AppColors.green,
fontWeight: FontWeight.w600,
fontSize: 13,
),
);
}
class SpacedColumn extends StatelessWidget {
const SpacedColumn({super.key, required this.children, this.spacing = 12});
final List<Widget> children;
final double spacing;
@override
Widget build(BuildContext context) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (var index = 0; index < children.length; index++) ...[
children[index],
if (index < children.length - 1) SizedBox(height: spacing),
],
],
);
}