kasy-cli 1.16.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/kasy.js +16 -2
- package/lib/commands/add.js +52 -19
- package/lib/commands/configure.js +548 -0
- package/lib/commands/deploy.js +4 -4
- package/lib/commands/doctor.js +54 -6
- package/lib/commands/favicon.js +4 -4
- package/lib/commands/icon.js +5 -5
- package/lib/commands/new.js +404 -213
- package/lib/commands/remove.js +14 -3
- package/lib/commands/run.js +208 -6
- package/lib/commands/splash.js +5 -5
- package/lib/commands/update.js +9 -9
- package/lib/scaffold/CHANGELOG.json +23 -0
- package/lib/scaffold/backends/api/patch/README.md +3 -2
- package/lib/scaffold/backends/firebase/enable-auth-via-cli.js +108 -0
- package/lib/scaffold/backends/firebase/setup-from-scratch.js +44 -5
- package/lib/scaffold/backends/supabase/patch/README.md +3 -2
- package/lib/scaffold/generate.js +24 -8
- package/lib/scaffold/shared/generator-utils.js +52 -8
- package/lib/scaffold/shared/post-build.js +113 -31
- package/lib/scaffold/shared/template-strings.js +6 -0
- package/lib/utils/brand.js +16 -12
- package/lib/utils/flutter-run.js +139 -11
- package/lib/utils/i18n/messages-en.js +85 -7
- package/lib/utils/i18n/messages-es.js +85 -7
- package/lib/utils/i18n/messages-pt.js +86 -8
- package/lib/utils/ui.js +79 -4
- package/package.json +1 -1
- package/templates/firebase/README.en.md +18 -8
- package/templates/firebase/README.es.md +18 -8
- package/templates/firebase/README.md +18 -8
- package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/MyWidget.kt +68 -45
- package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/MyWidgetReceiver.kt +37 -0
- package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/OpenAppAction.kt +26 -0
- package/templates/firebase/android/app/src/main/res/drawable/widget_add_button.xml +2 -2
- package/templates/firebase/android/app/src/main/res/drawable/widget_gradient_bg.xml +7 -2
- package/templates/firebase/android/app/src/main/res/drawable/widget_gradient_inner.xml +6 -6
- package/templates/firebase/android/app/src/main/res/drawable/widget_plan_pill_bg.xml +1 -1
- package/templates/firebase/android/app/src/main/res/drawable/widget_preview_image.xml +2 -2
- package/templates/firebase/android/app/src/main/res/drawable/widget_pro_pill_bg.xml +1 -1
- package/templates/firebase/android/app/src/main/res/drawable-hdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-hdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-mdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-mdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/android12splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/splash.png +0 -0
- package/templates/firebase/android/app/src/main/res/layout/widget_preview.xml +3 -3
- package/templates/firebase/android/app/src/main/res/values/colors.xml +32 -0
- package/templates/firebase/assets/images/splash_logo_dark.png +0 -0
- package/templates/firebase/assets/images/splash_logo_dark_android12.png +0 -0
- package/templates/firebase/assets/images/splash_logo_light.png +0 -0
- package/templates/firebase/assets/images/splash_logo_light_android12.png +0 -0
- package/templates/firebase/docs/revenuecat-setup.es.md +28 -8
- package/templates/firebase/docs/revenuecat-setup.pt.md +28 -8
- package/templates/firebase/ios/HomeWidgetExtension/MyWidget.swift +75 -29
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png +0 -0
- package/templates/firebase/ios/Runner/Base.lproj/LaunchScreen.storyboard +1 -1
- package/templates/firebase/lib/components/components.dart +1 -0
- package/templates/firebase/lib/components/kasy_avatar.dart +65 -17
- package/templates/firebase/lib/components/kasy_avatar_presets.dart +121 -97
- package/templates/firebase/lib/components/kasy_button.dart +8 -8
- package/templates/firebase/lib/components/kasy_date_picker.dart +834 -0
- package/templates/firebase/lib/components/kasy_tabs.dart +145 -61
- package/templates/firebase/lib/core/home_widgets/home_widget_mywidget_service.dart +45 -53
- package/templates/firebase/lib/features/home/home_components_preview_registry.dart +565 -77
- package/templates/firebase/lib/features/settings/ui/components/language_switcher.dart +10 -5
- package/templates/firebase/lib/i18n/en.i18n.json +2 -1
- package/templates/firebase/lib/i18n/es.i18n.json +2 -1
- package/templates/firebase/lib/i18n/pt.i18n.json +2 -1
- package/templates/firebase/lib/router.dart +15 -1
- package/templates/firebase/pubspec.yaml +1 -1
- package/templates/firebase/web/index.html +9 -0
- package/templates/firebase/web/splash/img/dark-1x.png +0 -0
- package/templates/firebase/web/splash/img/dark-2x.png +0 -0
- package/templates/firebase/web/splash/img/dark-3x.png +0 -0
- package/templates/firebase/web/splash/img/dark-4x.png +0 -0
- package/templates/firebase/web/splash/img/light-1x.png +0 -0
- package/templates/firebase/web/splash/img/light-2x.png +0 -0
- package/templates/firebase/web/splash/img/light-3x.png +0 -0
- package/templates/firebase/web/splash/img/light-4x.png +0 -0
|
@@ -231,6 +231,28 @@ ComponentPreviewDefinition? getComponentPreviewDefinition(
|
|
|
231
231
|
),
|
|
232
232
|
],
|
|
233
233
|
);
|
|
234
|
+
case 'DatePicker':
|
|
235
|
+
return const ComponentPreviewDefinition(
|
|
236
|
+
title: 'DatePicker',
|
|
237
|
+
variants: [
|
|
238
|
+
ComponentPreviewVariant(
|
|
239
|
+
label: 'Without label',
|
|
240
|
+
builder: _buildDatePickerBasic,
|
|
241
|
+
),
|
|
242
|
+
ComponentPreviewVariant(
|
|
243
|
+
label: 'With label',
|
|
244
|
+
builder: _buildDatePickerWithLabel,
|
|
245
|
+
),
|
|
246
|
+
ComponentPreviewVariant(
|
|
247
|
+
label: 'With min & max',
|
|
248
|
+
builder: _buildDatePickerMinMax,
|
|
249
|
+
),
|
|
250
|
+
ComponentPreviewVariant(
|
|
251
|
+
label: 'Disabled',
|
|
252
|
+
builder: _buildDatePickerDisabled,
|
|
253
|
+
),
|
|
254
|
+
],
|
|
255
|
+
);
|
|
234
256
|
case 'Dialog':
|
|
235
257
|
return const ComponentPreviewDefinition(
|
|
236
258
|
title: 'Dialog',
|
|
@@ -654,6 +676,72 @@ class _SidebarPreviewState extends State<_SidebarPreview> {
|
|
|
654
676
|
}
|
|
655
677
|
|
|
656
678
|
|
|
679
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
680
|
+
// DatePicker — interactive demos
|
|
681
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
682
|
+
|
|
683
|
+
Widget _buildDatePickerBasic(BuildContext context) =>
|
|
684
|
+
const _DatePickerPreview(variant: _DatePickerVariant.basic);
|
|
685
|
+
|
|
686
|
+
Widget _buildDatePickerWithLabel(BuildContext context) =>
|
|
687
|
+
const _DatePickerPreview(variant: _DatePickerVariant.withLabel);
|
|
688
|
+
|
|
689
|
+
Widget _buildDatePickerMinMax(BuildContext context) =>
|
|
690
|
+
const _DatePickerPreview(variant: _DatePickerVariant.minMax);
|
|
691
|
+
|
|
692
|
+
Widget _buildDatePickerDisabled(BuildContext context) =>
|
|
693
|
+
const _DatePickerPreview(variant: _DatePickerVariant.disabled);
|
|
694
|
+
|
|
695
|
+
enum _DatePickerVariant { basic, withLabel, minMax, disabled }
|
|
696
|
+
|
|
697
|
+
class _DatePickerPreview extends StatefulWidget {
|
|
698
|
+
const _DatePickerPreview({required this.variant});
|
|
699
|
+
|
|
700
|
+
final _DatePickerVariant variant;
|
|
701
|
+
|
|
702
|
+
@override
|
|
703
|
+
State<_DatePickerPreview> createState() => _DatePickerPreviewState();
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
class _DatePickerPreviewState extends State<_DatePickerPreview> {
|
|
707
|
+
DateTime? _date;
|
|
708
|
+
|
|
709
|
+
@override
|
|
710
|
+
Widget build(BuildContext context) {
|
|
711
|
+
final DateTime today = DateTime.now();
|
|
712
|
+
final DateTime minDate = today.subtract(const Duration(days: 30));
|
|
713
|
+
final DateTime maxDate = today.add(const Duration(days: 60));
|
|
714
|
+
|
|
715
|
+
return Padding(
|
|
716
|
+
padding: const EdgeInsets.all(KasySpacing.md),
|
|
717
|
+
child: switch (widget.variant) {
|
|
718
|
+
_DatePickerVariant.basic => KasyDatePicker(
|
|
719
|
+
value: _date,
|
|
720
|
+
onChanged: (d) => setState(() => _date = d),
|
|
721
|
+
),
|
|
722
|
+
_DatePickerVariant.withLabel => KasyDatePicker(
|
|
723
|
+
label: 'Date of birth',
|
|
724
|
+
value: _date,
|
|
725
|
+
onChanged: (d) => setState(() => _date = d),
|
|
726
|
+
),
|
|
727
|
+
_DatePickerVariant.minMax => KasyDatePicker(
|
|
728
|
+
label: 'Appointment date',
|
|
729
|
+
value: _date,
|
|
730
|
+
minDate: minDate,
|
|
731
|
+
maxDate: maxDate,
|
|
732
|
+
onChanged: (d) => setState(() => _date = d),
|
|
733
|
+
),
|
|
734
|
+
_DatePickerVariant.disabled => KasyDatePicker(
|
|
735
|
+
label: 'Locked date',
|
|
736
|
+
value: today,
|
|
737
|
+
enabled: false,
|
|
738
|
+
onChanged: (d) => setState(() => _date = d),
|
|
739
|
+
),
|
|
740
|
+
},
|
|
741
|
+
);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
657
745
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
658
746
|
// Tabs — interactive demos
|
|
659
747
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -667,6 +755,83 @@ Widget _buildTabsSecondaryVariant(BuildContext context) =>
|
|
|
667
755
|
Widget _buildTabsFillModeVariant(BuildContext context) =>
|
|
668
756
|
const _TabsFillModePreview();
|
|
669
757
|
|
|
758
|
+
// ── Shared tab content helpers ────────────────────────────────────────────
|
|
759
|
+
|
|
760
|
+
/// Fades [child] in when [tabIndex] == [currentIndex], out otherwise.
|
|
761
|
+
///
|
|
762
|
+
/// Used inside an [IndexedStack] so the content area never changes height —
|
|
763
|
+
/// the stack always sizes to the tallest child and only the active one is
|
|
764
|
+
/// visible.
|
|
765
|
+
Widget _tabFade(int tabIndex, int currentIndex, Widget child) {
|
|
766
|
+
return AnimatedOpacity(
|
|
767
|
+
opacity: tabIndex == currentIndex ? 1.0 : 0.0,
|
|
768
|
+
duration: const Duration(milliseconds: 180),
|
|
769
|
+
curve: Curves.easeInOut,
|
|
770
|
+
child: child,
|
|
771
|
+
);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// ── Card container helper ─────────────────────────────────────────────────
|
|
775
|
+
|
|
776
|
+
Widget _tabsCard(BuildContext context, Widget child) {
|
|
777
|
+
return DecoratedBox(
|
|
778
|
+
decoration: BoxDecoration(
|
|
779
|
+
color: context.colors.surface,
|
|
780
|
+
borderRadius: KasyRadius.lgBorderRadius,
|
|
781
|
+
border: Border.all(
|
|
782
|
+
color: context.colors.outline.withValues(alpha: 0.4),
|
|
783
|
+
),
|
|
784
|
+
),
|
|
785
|
+
child: child,
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// ── Divider helper ────────────────────────────────────────────────────────
|
|
790
|
+
|
|
791
|
+
Widget _tabsDivider(BuildContext context) => Divider(
|
|
792
|
+
height: 1,
|
|
793
|
+
thickness: 1,
|
|
794
|
+
indent: KasySpacing.md,
|
|
795
|
+
endIndent: KasySpacing.md,
|
|
796
|
+
color: context.colors.outline.withValues(alpha: 0.33),
|
|
797
|
+
);
|
|
798
|
+
|
|
799
|
+
// ── Radio-style option row ────────────────────────────────────────────────
|
|
800
|
+
|
|
801
|
+
/// Single-select option row that looks like a radio button using KasyCheckbox.
|
|
802
|
+
class _RadioOptionTile extends StatelessWidget {
|
|
803
|
+
const _RadioOptionTile({
|
|
804
|
+
required this.label,
|
|
805
|
+
required this.description,
|
|
806
|
+
required this.selected,
|
|
807
|
+
required this.onTap,
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
final String label;
|
|
811
|
+
final String description;
|
|
812
|
+
final bool selected;
|
|
813
|
+
final VoidCallback onTap;
|
|
814
|
+
|
|
815
|
+
@override
|
|
816
|
+
Widget build(BuildContext context) {
|
|
817
|
+
return Padding(
|
|
818
|
+
padding: const EdgeInsets.symmetric(
|
|
819
|
+
horizontal: KasySpacing.md,
|
|
820
|
+
vertical: KasySpacing.smd,
|
|
821
|
+
),
|
|
822
|
+
child: KasyCheckbox(
|
|
823
|
+
value: selected,
|
|
824
|
+
onChanged: (_) => onTap(),
|
|
825
|
+
label: label,
|
|
826
|
+
description: description,
|
|
827
|
+
style: const KasyCheckboxStyle(
|
|
828
|
+
shape: KasyCheckboxShape.circle,
|
|
829
|
+
),
|
|
830
|
+
),
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
670
835
|
// ── Primary variant ────────────────────────────────────────────────────────
|
|
671
836
|
|
|
672
837
|
class _TabsPrimaryPreview extends StatefulWidget {
|
|
@@ -679,40 +844,239 @@ class _TabsPrimaryPreview extends StatefulWidget {
|
|
|
679
844
|
class _TabsPrimaryPreviewState extends State<_TabsPrimaryPreview> {
|
|
680
845
|
int _index = 0;
|
|
681
846
|
|
|
682
|
-
|
|
847
|
+
// General tab
|
|
848
|
+
final TextEditingController _urlController = TextEditingController();
|
|
849
|
+
bool _analytics = true;
|
|
850
|
+
bool _errorReports = false;
|
|
683
851
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
852
|
+
// Appearance tab
|
|
853
|
+
int _theme = 0; // 0=Auto 1=Light 2=Dark
|
|
854
|
+
int _fontSize = 1; // 0=Small 1=Medium 2=Large
|
|
855
|
+
|
|
856
|
+
// Notifications tab
|
|
857
|
+
bool _pushEnabled = true;
|
|
858
|
+
bool _emailEnabled = true;
|
|
859
|
+
bool _mentions = true;
|
|
860
|
+
bool _weeklyDigest = false;
|
|
861
|
+
|
|
862
|
+
// Profile tab
|
|
863
|
+
final TextEditingController _nameController =
|
|
864
|
+
TextEditingController(text: 'Paulo Morales');
|
|
865
|
+
final TextEditingController _usernameController =
|
|
866
|
+
TextEditingController(text: 'paulomorales');
|
|
689
867
|
|
|
690
868
|
@override
|
|
691
|
-
|
|
692
|
-
|
|
869
|
+
void dispose() {
|
|
870
|
+
_urlController.dispose();
|
|
871
|
+
_nameController.dispose();
|
|
872
|
+
_usernameController.dispose();
|
|
873
|
+
super.dispose();
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
Widget _generalTab(BuildContext context) {
|
|
877
|
+
return Column(
|
|
878
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
879
|
+
mainAxisSize: MainAxisSize.min,
|
|
880
|
+
children: [
|
|
881
|
+
Padding(
|
|
882
|
+
padding: const EdgeInsets.all(KasySpacing.md),
|
|
883
|
+
child: KasyTextField(
|
|
884
|
+
controller: _urlController,
|
|
885
|
+
variant: KasyTextFieldVariant.secondary,
|
|
886
|
+
label: 'Homepage URL',
|
|
887
|
+
hint: 'https://yoursite.com',
|
|
888
|
+
),
|
|
889
|
+
),
|
|
890
|
+
_tabsDivider(context),
|
|
891
|
+
KasyCheckboxTile(
|
|
892
|
+
value: _analytics,
|
|
893
|
+
onChanged: (v) => setState(() => _analytics = v),
|
|
894
|
+
label: 'Enable analytics',
|
|
895
|
+
description: 'Collect anonymous usage data to improve the app',
|
|
896
|
+
),
|
|
897
|
+
_tabsDivider(context),
|
|
898
|
+
KasyCheckboxTile(
|
|
899
|
+
value: _errorReports,
|
|
900
|
+
onChanged: (v) => setState(() => _errorReports = v),
|
|
901
|
+
label: 'Send error reports',
|
|
902
|
+
description: 'Automatically share crash reports with the team',
|
|
903
|
+
),
|
|
904
|
+
],
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
Widget _appearanceTab(BuildContext context) {
|
|
909
|
+
return Column(
|
|
910
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
911
|
+
mainAxisSize: MainAxisSize.min,
|
|
912
|
+
children: [
|
|
913
|
+
Padding(
|
|
914
|
+
padding: const EdgeInsets.fromLTRB(
|
|
915
|
+
KasySpacing.md,
|
|
916
|
+
KasySpacing.md,
|
|
917
|
+
KasySpacing.md,
|
|
918
|
+
KasySpacing.sm,
|
|
919
|
+
),
|
|
920
|
+
child: Text(
|
|
921
|
+
'Theme',
|
|
922
|
+
style: context.textTheme.labelMedium?.copyWith(
|
|
923
|
+
color: context.colors.onSurface,
|
|
924
|
+
fontWeight: FontWeight.w600,
|
|
925
|
+
),
|
|
926
|
+
),
|
|
927
|
+
),
|
|
928
|
+
_RadioOptionTile(
|
|
929
|
+
label: 'Auto',
|
|
930
|
+
description: 'Follows your system appearance',
|
|
931
|
+
selected: _theme == 0,
|
|
932
|
+
onTap: () => setState(() => _theme = 0),
|
|
933
|
+
),
|
|
934
|
+
_tabsDivider(context),
|
|
935
|
+
_RadioOptionTile(
|
|
936
|
+
label: 'Light',
|
|
937
|
+
description: 'Always use the light theme',
|
|
938
|
+
selected: _theme == 1,
|
|
939
|
+
onTap: () => setState(() => _theme = 1),
|
|
940
|
+
),
|
|
941
|
+
_tabsDivider(context),
|
|
942
|
+
_RadioOptionTile(
|
|
943
|
+
label: 'Dark',
|
|
944
|
+
description: 'Always use the dark theme',
|
|
945
|
+
selected: _theme == 2,
|
|
946
|
+
onTap: () => setState(() => _theme = 2),
|
|
947
|
+
),
|
|
948
|
+
_tabsDivider(context),
|
|
949
|
+
Padding(
|
|
950
|
+
padding: const EdgeInsets.fromLTRB(
|
|
951
|
+
KasySpacing.md,
|
|
952
|
+
KasySpacing.md,
|
|
953
|
+
KasySpacing.md,
|
|
954
|
+
KasySpacing.sm,
|
|
955
|
+
),
|
|
956
|
+
child: Text(
|
|
957
|
+
'Font size',
|
|
958
|
+
style: context.textTheme.labelMedium?.copyWith(
|
|
959
|
+
color: context.colors.onSurface,
|
|
960
|
+
fontWeight: FontWeight.w600,
|
|
961
|
+
),
|
|
962
|
+
),
|
|
963
|
+
),
|
|
964
|
+
_RadioOptionTile(
|
|
965
|
+
label: 'Small',
|
|
966
|
+
description: 'Compact text for more content on screen',
|
|
967
|
+
selected: _fontSize == 0,
|
|
968
|
+
onTap: () => setState(() => _fontSize = 0),
|
|
969
|
+
),
|
|
970
|
+
_tabsDivider(context),
|
|
971
|
+
_RadioOptionTile(
|
|
972
|
+
label: 'Medium',
|
|
973
|
+
description: 'Balanced size for most displays',
|
|
974
|
+
selected: _fontSize == 1,
|
|
975
|
+
onTap: () => setState(() => _fontSize = 1),
|
|
976
|
+
),
|
|
977
|
+
_tabsDivider(context),
|
|
978
|
+
_RadioOptionTile(
|
|
979
|
+
label: 'Large',
|
|
980
|
+
description: 'Larger text for better readability',
|
|
981
|
+
selected: _fontSize == 2,
|
|
982
|
+
onTap: () => setState(() => _fontSize = 2),
|
|
983
|
+
),
|
|
984
|
+
],
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
Widget _notificationsTab(BuildContext context) {
|
|
989
|
+
return Column(
|
|
990
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
991
|
+
mainAxisSize: MainAxisSize.min,
|
|
992
|
+
children: [
|
|
993
|
+
KasyCheckboxTile(
|
|
994
|
+
value: _pushEnabled,
|
|
995
|
+
onChanged: (v) => setState(() => _pushEnabled = v),
|
|
996
|
+
label: 'Push notifications',
|
|
997
|
+
description: 'Receive alerts directly on your device',
|
|
998
|
+
),
|
|
999
|
+
_tabsDivider(context),
|
|
1000
|
+
KasyCheckboxTile(
|
|
1001
|
+
value: _emailEnabled,
|
|
1002
|
+
onChanged: (v) => setState(() => _emailEnabled = v),
|
|
1003
|
+
label: 'Email notifications',
|
|
1004
|
+
description: 'Get updates delivered to your inbox',
|
|
1005
|
+
),
|
|
1006
|
+
_tabsDivider(context),
|
|
1007
|
+
KasyCheckboxTile(
|
|
1008
|
+
value: _mentions,
|
|
1009
|
+
onChanged: (v) => setState(() => _mentions = v),
|
|
1010
|
+
label: 'Mentions and replies',
|
|
1011
|
+
description: 'Notify when someone mentions or replies to you',
|
|
1012
|
+
),
|
|
1013
|
+
_tabsDivider(context),
|
|
1014
|
+
KasyCheckboxTile(
|
|
1015
|
+
value: _weeklyDigest,
|
|
1016
|
+
onChanged: (v) => setState(() => _weeklyDigest = v),
|
|
1017
|
+
label: 'Weekly digest',
|
|
1018
|
+
description: 'A summary of activity sent every Monday',
|
|
1019
|
+
),
|
|
1020
|
+
],
|
|
1021
|
+
);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
Widget _profileTab(BuildContext context) {
|
|
1025
|
+
return Padding(
|
|
1026
|
+
padding: const EdgeInsets.all(KasySpacing.md),
|
|
1027
|
+
child: Column(
|
|
1028
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
1029
|
+
mainAxisSize: MainAxisSize.min,
|
|
1030
|
+
children: [
|
|
1031
|
+
KasyTextField(
|
|
1032
|
+
controller: _nameController,
|
|
1033
|
+
variant: KasyTextFieldVariant.secondary,
|
|
1034
|
+
label: 'Name',
|
|
1035
|
+
hint: 'Your full name',
|
|
1036
|
+
textInputAction: TextInputAction.next,
|
|
1037
|
+
),
|
|
1038
|
+
const SizedBox(height: KasySpacing.md),
|
|
1039
|
+
KasyTextField(
|
|
1040
|
+
controller: _usernameController,
|
|
1041
|
+
variant: KasyTextFieldVariant.secondary,
|
|
1042
|
+
label: 'Username',
|
|
1043
|
+
hint: 'yourhandle',
|
|
1044
|
+
textInputAction: TextInputAction.done,
|
|
1045
|
+
),
|
|
1046
|
+
const SizedBox(height: KasySpacing.md),
|
|
1047
|
+
KasyButton(
|
|
1048
|
+
label: 'Update profile',
|
|
1049
|
+
onPressed: () {},
|
|
1050
|
+
),
|
|
1051
|
+
],
|
|
1052
|
+
),
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
693
1055
|
|
|
1056
|
+
@override
|
|
1057
|
+
Widget build(BuildContext context) {
|
|
694
1058
|
return Column(
|
|
695
1059
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
696
1060
|
mainAxisSize: MainAxisSize.min,
|
|
697
1061
|
children: [
|
|
698
1062
|
KasyTabs(
|
|
699
|
-
tabs:
|
|
1063
|
+
tabs: const ['General', 'Appearance', 'Notifications', 'Profile'],
|
|
700
1064
|
selectedIndex: _index,
|
|
701
1065
|
onTabSelected: (i) => setState(() => _index = i),
|
|
702
1066
|
),
|
|
703
1067
|
const SizedBox(height: KasySpacing.md),
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
),
|
|
715
|
-
|
|
1068
|
+
// IndexedStack keeps height fixed at the tallest child (Appearance).
|
|
1069
|
+
// AnimatedOpacity on each child provides the smooth crossfade.
|
|
1070
|
+
_tabsCard(
|
|
1071
|
+
context,
|
|
1072
|
+
IndexedStack(
|
|
1073
|
+
index: _index,
|
|
1074
|
+
children: [
|
|
1075
|
+
_tabFade(0, _index, _generalTab(context)),
|
|
1076
|
+
_tabFade(1, _index, _appearanceTab(context)),
|
|
1077
|
+
_tabFade(2, _index, _notificationsTab(context)),
|
|
1078
|
+
_tabFade(3, _index, _profileTab(context)),
|
|
1079
|
+
],
|
|
716
1080
|
),
|
|
717
1081
|
),
|
|
718
1082
|
const SizedBox(height: KasySpacing.lg),
|
|
@@ -720,7 +1084,7 @@ class _TabsPrimaryPreviewState extends State<_TabsPrimaryPreview> {
|
|
|
720
1084
|
Text(
|
|
721
1085
|
'WITH DISABLED TAB',
|
|
722
1086
|
style: context.textTheme.labelSmall?.copyWith(
|
|
723
|
-
color:
|
|
1087
|
+
color: context.colors.muted,
|
|
724
1088
|
letterSpacing: 1.2,
|
|
725
1089
|
fontWeight: FontWeight.w700,
|
|
726
1090
|
),
|
|
@@ -752,41 +1116,146 @@ class _TabsSecondaryPreview extends StatefulWidget {
|
|
|
752
1116
|
class _TabsSecondaryPreviewState extends State<_TabsSecondaryPreview> {
|
|
753
1117
|
int _index = 0;
|
|
754
1118
|
|
|
755
|
-
|
|
1119
|
+
// General tab
|
|
1120
|
+
final TextEditingController _siteController = TextEditingController();
|
|
1121
|
+
bool _cacheEnabled = true;
|
|
1122
|
+
bool _debugMode = false;
|
|
756
1123
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
1124
|
+
// Notifications tab
|
|
1125
|
+
bool _pushEnabled = true;
|
|
1126
|
+
bool _emailEnabled = false;
|
|
1127
|
+
bool _weeklyDigest = true;
|
|
1128
|
+
|
|
1129
|
+
// Profile tab
|
|
1130
|
+
final TextEditingController _nameController =
|
|
1131
|
+
TextEditingController(text: 'Paulo Morales');
|
|
1132
|
+
final TextEditingController _emailController =
|
|
1133
|
+
TextEditingController(text: 'paulo@kasy.dev');
|
|
762
1134
|
|
|
763
1135
|
@override
|
|
764
|
-
|
|
765
|
-
|
|
1136
|
+
void dispose() {
|
|
1137
|
+
_siteController.dispose();
|
|
1138
|
+
_nameController.dispose();
|
|
1139
|
+
_emailController.dispose();
|
|
1140
|
+
super.dispose();
|
|
1141
|
+
}
|
|
766
1142
|
|
|
1143
|
+
Widget _generalTab(BuildContext context) {
|
|
1144
|
+
return Column(
|
|
1145
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
1146
|
+
mainAxisSize: MainAxisSize.min,
|
|
1147
|
+
children: [
|
|
1148
|
+
Padding(
|
|
1149
|
+
padding: const EdgeInsets.all(KasySpacing.md),
|
|
1150
|
+
child: KasyTextField(
|
|
1151
|
+
controller: _siteController,
|
|
1152
|
+
variant: KasyTextFieldVariant.secondary,
|
|
1153
|
+
label: 'Site URL',
|
|
1154
|
+
hint: 'https://yoursite.com',
|
|
1155
|
+
),
|
|
1156
|
+
),
|
|
1157
|
+
_tabsDivider(context),
|
|
1158
|
+
KasyCheckboxTile(
|
|
1159
|
+
value: _cacheEnabled,
|
|
1160
|
+
onChanged: (v) => setState(() => _cacheEnabled = v),
|
|
1161
|
+
label: 'Enable caching',
|
|
1162
|
+
description: 'Speed up page loads with local cache',
|
|
1163
|
+
),
|
|
1164
|
+
_tabsDivider(context),
|
|
1165
|
+
KasyCheckboxTile(
|
|
1166
|
+
value: _debugMode,
|
|
1167
|
+
onChanged: (v) => setState(() => _debugMode = v),
|
|
1168
|
+
label: 'Debug mode',
|
|
1169
|
+
description: 'Show detailed logs and error messages',
|
|
1170
|
+
),
|
|
1171
|
+
],
|
|
1172
|
+
);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
Widget _notificationsTab(BuildContext context) {
|
|
1176
|
+
return Column(
|
|
1177
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
1178
|
+
mainAxisSize: MainAxisSize.min,
|
|
1179
|
+
children: [
|
|
1180
|
+
KasyCheckboxTile(
|
|
1181
|
+
value: _pushEnabled,
|
|
1182
|
+
onChanged: (v) => setState(() => _pushEnabled = v),
|
|
1183
|
+
label: 'Push notifications',
|
|
1184
|
+
description: 'Receive alerts directly on your device',
|
|
1185
|
+
),
|
|
1186
|
+
_tabsDivider(context),
|
|
1187
|
+
KasyCheckboxTile(
|
|
1188
|
+
value: _emailEnabled,
|
|
1189
|
+
onChanged: (v) => setState(() => _emailEnabled = v),
|
|
1190
|
+
label: 'Email notifications',
|
|
1191
|
+
description: 'Get updates delivered to your inbox',
|
|
1192
|
+
),
|
|
1193
|
+
_tabsDivider(context),
|
|
1194
|
+
KasyCheckboxTile(
|
|
1195
|
+
value: _weeklyDigest,
|
|
1196
|
+
onChanged: (v) => setState(() => _weeklyDigest = v),
|
|
1197
|
+
label: 'Weekly digest',
|
|
1198
|
+
description: 'A summary of activity sent every Monday',
|
|
1199
|
+
),
|
|
1200
|
+
],
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
Widget _profileTab(BuildContext context) {
|
|
1205
|
+
return Padding(
|
|
1206
|
+
padding: const EdgeInsets.all(KasySpacing.md),
|
|
1207
|
+
child: Column(
|
|
1208
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
1209
|
+
mainAxisSize: MainAxisSize.min,
|
|
1210
|
+
children: [
|
|
1211
|
+
KasyTextField(
|
|
1212
|
+
controller: _nameController,
|
|
1213
|
+
variant: KasyTextFieldVariant.secondary,
|
|
1214
|
+
label: 'Name',
|
|
1215
|
+
hint: 'Your full name',
|
|
1216
|
+
textInputAction: TextInputAction.next,
|
|
1217
|
+
),
|
|
1218
|
+
const SizedBox(height: KasySpacing.md),
|
|
1219
|
+
KasyTextField(
|
|
1220
|
+
controller: _emailController,
|
|
1221
|
+
variant: KasyTextFieldVariant.secondary,
|
|
1222
|
+
label: 'Email',
|
|
1223
|
+
hint: 'email@example.com',
|
|
1224
|
+
contentType: KasyTextFieldContentType.email,
|
|
1225
|
+
textInputAction: TextInputAction.done,
|
|
1226
|
+
),
|
|
1227
|
+
const SizedBox(height: KasySpacing.md),
|
|
1228
|
+
KasyButton(
|
|
1229
|
+
label: 'Save changes',
|
|
1230
|
+
onPressed: () {},
|
|
1231
|
+
),
|
|
1232
|
+
],
|
|
1233
|
+
),
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
@override
|
|
1238
|
+
Widget build(BuildContext context) {
|
|
767
1239
|
return Column(
|
|
768
1240
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
769
1241
|
mainAxisSize: MainAxisSize.min,
|
|
770
1242
|
children: [
|
|
771
1243
|
KasyTabs(
|
|
772
|
-
tabs:
|
|
1244
|
+
tabs: const ['General', 'Notifications', 'Profile'],
|
|
773
1245
|
selectedIndex: _index,
|
|
774
1246
|
onTabSelected: (i) => setState(() => _index = i),
|
|
775
1247
|
variant: KasyTabsVariant.secondary,
|
|
776
1248
|
),
|
|
777
1249
|
const SizedBox(height: KasySpacing.md),
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
height: 1.5,
|
|
788
|
-
),
|
|
789
|
-
),
|
|
1250
|
+
_tabsCard(
|
|
1251
|
+
context,
|
|
1252
|
+
IndexedStack(
|
|
1253
|
+
index: _index,
|
|
1254
|
+
children: [
|
|
1255
|
+
_tabFade(0, _index, _generalTab(context)),
|
|
1256
|
+
_tabFade(1, _index, _notificationsTab(context)),
|
|
1257
|
+
_tabFade(2, _index, _profileTab(context)),
|
|
1258
|
+
],
|
|
790
1259
|
),
|
|
791
1260
|
),
|
|
792
1261
|
const SizedBox(height: KasySpacing.lg),
|
|
@@ -794,7 +1263,7 @@ class _TabsSecondaryPreviewState extends State<_TabsSecondaryPreview> {
|
|
|
794
1263
|
Text(
|
|
795
1264
|
'WITH ICONS',
|
|
796
1265
|
style: context.textTheme.labelSmall?.copyWith(
|
|
797
|
-
color:
|
|
1266
|
+
color: context.colors.muted,
|
|
798
1267
|
letterSpacing: 1.2,
|
|
799
1268
|
fontWeight: FontWeight.w700,
|
|
800
1269
|
),
|
|
@@ -826,14 +1295,19 @@ class _TabsFillModePreview extends StatefulWidget {
|
|
|
826
1295
|
|
|
827
1296
|
class _TabsFillModePreviewState extends State<_TabsFillModePreview> {
|
|
828
1297
|
int _primaryIndex = 0;
|
|
829
|
-
int
|
|
1298
|
+
int _iconIndex = 0;
|
|
1299
|
+
|
|
1300
|
+
static const List<String> _primaryContent = [
|
|
1301
|
+
'Overview — see a high-level summary of your project status and recent activity.',
|
|
1302
|
+
'Analytics — track metrics like sessions, retention, and conversion rates over time.',
|
|
1303
|
+
'Settings — manage project configuration, integrations, and team access.',
|
|
1304
|
+
];
|
|
830
1305
|
|
|
831
1306
|
@override
|
|
832
1307
|
Widget build(BuildContext context) {
|
|
833
|
-
final
|
|
834
|
-
final TextStyle labelStyle =
|
|
1308
|
+
final TextStyle sectionLabel =
|
|
835
1309
|
context.textTheme.labelSmall?.copyWith(
|
|
836
|
-
color:
|
|
1310
|
+
color: context.colors.muted,
|
|
837
1311
|
letterSpacing: 1.2,
|
|
838
1312
|
fontWeight: FontWeight.w700,
|
|
839
1313
|
) ??
|
|
@@ -843,38 +1317,52 @@ class _TabsFillModePreviewState extends State<_TabsFillModePreview> {
|
|
|
843
1317
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
844
1318
|
mainAxisSize: MainAxisSize.min,
|
|
845
1319
|
children: [
|
|
846
|
-
Text('PRIMARY
|
|
1320
|
+
Text('PRIMARY FILL', style: sectionLabel),
|
|
847
1321
|
const SizedBox(height: KasySpacing.sm),
|
|
848
1322
|
KasyTabs(
|
|
849
|
-
tabs: const ['
|
|
1323
|
+
tabs: const ['Overview', 'Analytics', 'Settings'],
|
|
850
1324
|
selectedIndex: _primaryIndex,
|
|
851
1325
|
onTabSelected: (i) => setState(() => _primaryIndex = i),
|
|
852
1326
|
mode: KasyTabsMode.fill,
|
|
853
1327
|
),
|
|
854
|
-
const SizedBox(height: KasySpacing.lg),
|
|
855
|
-
Text('SECONDARY + FILL', style: labelStyle),
|
|
856
|
-
const SizedBox(height: KasySpacing.sm),
|
|
857
|
-
KasyTabs(
|
|
858
|
-
tabs: const ['Tab 1', 'Tab 2', 'Tab 3'],
|
|
859
|
-
selectedIndex: _secondaryIndex,
|
|
860
|
-
onTabSelected: (i) => setState(() => _secondaryIndex = i),
|
|
861
|
-
variant: KasyTabsVariant.secondary,
|
|
862
|
-
mode: KasyTabsMode.fill,
|
|
863
|
-
),
|
|
864
1328
|
const SizedBox(height: KasySpacing.md),
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
key: ValueKey('fill_$_secondaryIndex'),
|
|
1329
|
+
_tabsCard(
|
|
1330
|
+
context,
|
|
1331
|
+
Padding(
|
|
869
1332
|
padding: const EdgeInsets.all(KasySpacing.md),
|
|
870
|
-
child:
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
1333
|
+
child: IndexedStack(
|
|
1334
|
+
index: _primaryIndex,
|
|
1335
|
+
children: List.generate(
|
|
1336
|
+
_primaryContent.length,
|
|
1337
|
+
(i) => _tabFade(
|
|
1338
|
+
i,
|
|
1339
|
+
_primaryIndex,
|
|
1340
|
+
Text(
|
|
1341
|
+
_primaryContent[i],
|
|
1342
|
+
style: context.textTheme.bodyMedium?.copyWith(
|
|
1343
|
+
color: context.colors.onSurface.withValues(alpha: 0.75),
|
|
1344
|
+
height: 1.5,
|
|
1345
|
+
),
|
|
1346
|
+
),
|
|
1347
|
+
),
|
|
874
1348
|
),
|
|
875
1349
|
),
|
|
876
1350
|
),
|
|
877
1351
|
),
|
|
1352
|
+
const SizedBox(height: KasySpacing.lg),
|
|
1353
|
+
Text('SECONDARY FILL + ICONS', style: sectionLabel),
|
|
1354
|
+
const SizedBox(height: KasySpacing.sm),
|
|
1355
|
+
KasyTabs.items(
|
|
1356
|
+
items: const [
|
|
1357
|
+
KasyTabItem(label: 'Home', icon: KasyIcons.home),
|
|
1358
|
+
KasyTabItem(label: 'Profile', icon: KasyIcons.person),
|
|
1359
|
+
KasyTabItem(label: 'Settings', icon: KasyIcons.settings),
|
|
1360
|
+
],
|
|
1361
|
+
selectedIndex: _iconIndex,
|
|
1362
|
+
onTabSelected: (i) => setState(() => _iconIndex = i),
|
|
1363
|
+
variant: KasyTabsVariant.secondary,
|
|
1364
|
+
mode: KasyTabsMode.fill,
|
|
1365
|
+
),
|
|
878
1366
|
],
|
|
879
1367
|
);
|
|
880
1368
|
}
|
|
@@ -1199,7 +1687,7 @@ Widget _buildAvatarGroupVariant(BuildContext context) {
|
|
|
1199
1687
|
// Shared gradient avatars list
|
|
1200
1688
|
final List<Widget> gradients = [
|
|
1201
1689
|
KasyAvatar.gradientFill(size: KasyAvatarSize.small, diameter: d, showShadow: false, gradient: KasyAvatarGradients.blue),
|
|
1202
|
-
KasyAvatar.gradientFill(size: KasyAvatarSize.small, diameter: d, showShadow: false, gradient: KasyAvatarGradients.
|
|
1690
|
+
KasyAvatar.gradientFill(size: KasyAvatarSize.small, diameter: d, showShadow: false, gradient: KasyAvatarGradients.sky),
|
|
1203
1691
|
KasyAvatar.gradientFill(size: KasyAvatarSize.small, diameter: d, showShadow: false, gradient: KasyAvatarGradients.orange),
|
|
1204
1692
|
KasyAvatar.gradientFill(size: KasyAvatarSize.small, diameter: d, showShadow: false, gradient: KasyAvatarGradients.red),
|
|
1205
1693
|
KasyAvatar.gradientFill(size: KasyAvatarSize.small, diameter: d, showShadow: false, gradient: KasyAvatarGradients.silver),
|
|
@@ -2096,7 +2584,7 @@ Widget _buildBadgeDefault(BuildContext context) {
|
|
|
2096
2584
|
child: KasyAvatar.gradientFill(
|
|
2097
2585
|
size: KasyAvatarSize.medium,
|
|
2098
2586
|
showShadow: false,
|
|
2099
|
-
gradient: KasyAvatarGradients.
|
|
2587
|
+
gradient: KasyAvatarGradients.sky,
|
|
2100
2588
|
),
|
|
2101
2589
|
),
|
|
2102
2590
|
const SizedBox(height: KasySpacing.sm),
|
|
@@ -4028,9 +4516,9 @@ class _BadgeColorsPreview extends StatelessWidget {
|
|
|
4028
4516
|
KasyBadgeTone.warning,
|
|
4029
4517
|
KasyBadgeTone.danger,
|
|
4030
4518
|
];
|
|
4031
|
-
final List<
|
|
4519
|
+
final List<KasyAvatarGradientData> gradients = [
|
|
4032
4520
|
KasyAvatarGradients.blue,
|
|
4033
|
-
KasyAvatarGradients.
|
|
4521
|
+
KasyAvatarGradients.sky,
|
|
4034
4522
|
KasyAvatarGradients.purple,
|
|
4035
4523
|
KasyAvatarGradients.orange,
|
|
4036
4524
|
KasyAvatarGradients.red,
|
|
@@ -4153,9 +4641,9 @@ class _BadgePlacementsPreview extends StatelessWidget {
|
|
|
4153
4641
|
class _BadgeDotPreview extends StatelessWidget {
|
|
4154
4642
|
const _BadgeDotPreview();
|
|
4155
4643
|
|
|
4156
|
-
static const List<(KasyBadgeTone,
|
|
4644
|
+
static const List<(KasyBadgeTone, KasyAvatarGradientData)> _items = [
|
|
4157
4645
|
(KasyBadgeTone.neutral, KasyAvatarGradients.blue),
|
|
4158
|
-
(KasyBadgeTone.primary, KasyAvatarGradients.
|
|
4646
|
+
(KasyBadgeTone.primary, KasyAvatarGradients.sky),
|
|
4159
4647
|
(KasyBadgeTone.success, KasyAvatarGradients.purple),
|
|
4160
4648
|
(KasyBadgeTone.warning, KasyAvatarGradients.red),
|
|
4161
4649
|
(KasyBadgeTone.danger, KasyAvatarGradients.orange),
|
|
@@ -4197,9 +4685,9 @@ class _BadgeVariantsPreview extends StatelessWidget {
|
|
|
4197
4685
|
KasyBadgeTone.danger,
|
|
4198
4686
|
];
|
|
4199
4687
|
|
|
4200
|
-
static const List<
|
|
4688
|
+
static const List<KasyAvatarGradientData> _gradients = [
|
|
4201
4689
|
KasyAvatarGradients.blue,
|
|
4202
|
-
KasyAvatarGradients.
|
|
4690
|
+
KasyAvatarGradients.sky,
|
|
4203
4691
|
KasyAvatarGradients.purple,
|
|
4204
4692
|
KasyAvatarGradients.red,
|
|
4205
4693
|
KasyAvatarGradients.orange,
|
|
@@ -4332,7 +4820,7 @@ class _BadgeWithContentPreview extends StatelessWidget {
|
|
|
4332
4820
|
class _BadgeContentItem extends StatelessWidget {
|
|
4333
4821
|
final String label;
|
|
4334
4822
|
final KasyBadge badge;
|
|
4335
|
-
final
|
|
4823
|
+
final KasyAvatarGradientData gradient;
|
|
4336
4824
|
|
|
4337
4825
|
const _BadgeContentItem({
|
|
4338
4826
|
required this.label,
|