kasy-cli 1.38.0 → 1.39.1
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/lib/scaffold/CHANGELOG.json +23 -0
- package/lib/scaffold/backends/api/patch/README.md +15 -0
- package/lib/scaffold/backends/api/patch/lib/features/notifications/api/device_api.dart +11 -6
- package/lib/scaffold/backends/api/patch/lib/features/settings/ui/components/admin/admin_users_api.dart +9 -1
- package/lib/scaffold/backends/api/pubspec.yaml.tpl +1 -0
- package/lib/scaffold/backends/patch-base-hashes.json +6 -6
- package/lib/scaffold/backends/supabase/edge-functions/admin-list-users/index.ts +3 -1
- package/lib/scaffold/backends/supabase/edge-functions/send-push-notification/index.ts +3 -0
- package/lib/scaffold/backends/supabase/migrations/20240101000012_welcome_decouple_from_push.sql +62 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/notifications/api/device_api.dart +11 -6
- package/lib/scaffold/backends/supabase/patch/lib/features/settings/ui/components/admin/admin_users_api.dart +7 -0
- package/lib/scaffold/backends/supabase/pubspec.yaml.tpl +1 -0
- package/lib/scaffold/shared/generator-utils.js +12 -6
- package/package.json +1 -1
- package/templates/firebase/.firebase/hosting.YnVpbGQvd2Vi.cache +23 -23
- package/templates/firebase/AGENTS.md +2 -2
- package/templates/firebase/DESIGN_SYSTEM.md +23 -8
- package/templates/firebase/assets/icons/apple_black.svg +3 -0
- package/templates/firebase/assets/icons/apple_white.svg +4 -0
- package/templates/firebase/assets/icons/facebook.svg +49 -0
- package/templates/firebase/assets/icons/google.svg +1 -0
- package/templates/firebase/functions/src/admin/functions.ts +2 -0
- package/templates/firebase/functions/src/authentication/functions.ts +13 -7
- package/templates/firebase/functions/src/notifications/triggers.ts +6 -2
- package/templates/firebase/lib/components/components.dart +5 -2
- package/templates/firebase/lib/components/kasy_app_bar.dart +325 -15
- package/templates/firebase/lib/components/kasy_card.dart +4 -0
- package/templates/firebase/lib/components/kasy_drop_down.dart +584 -0
- package/templates/firebase/lib/components/kasy_sidebar.dart +18 -6
- package/templates/firebase/lib/components/kasy_tabs.dart +31 -10
- package/templates/firebase/lib/components/kasy_text_field.dart +29 -7
- package/templates/firebase/lib/core/bottom_menu/bottom_menu.dart +27 -18
- package/templates/firebase/lib/core/bottom_menu/web_content_wrapper.dart +34 -16
- package/templates/firebase/lib/core/chrome/app_bar_config.dart +214 -0
- package/templates/firebase/lib/core/chrome/app_bar_scope.dart +102 -0
- package/templates/firebase/lib/core/data/api/user_api.dart +11 -0
- package/templates/firebase/lib/core/dev_inspector/dev_inspector_service.dart +55 -15
- package/templates/firebase/lib/core/rating/widgets/review_popup.dart +95 -30
- package/templates/firebase/lib/core/shared_preferences/shared_preferences.dart +11 -0
- package/templates/firebase/lib/core/states/logout_action.dart +11 -1
- package/templates/firebase/lib/core/states/user_state_notifier.dart +28 -1
- package/templates/firebase/lib/core/theme/texts.dart +21 -6
- package/templates/firebase/lib/core/theme/type_scale.dart +34 -15
- package/templates/firebase/lib/core/web_device_preview/web_device_preview.dart +51 -19
- package/templates/firebase/lib/core/web_viewport_scale.dart +66 -36
- package/templates/firebase/lib/core/widgets/kasy_pressable_depth.dart +14 -3
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_chat_composer.dart +1 -1
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_chat_conversation_view.dart +52 -35
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_list.dart +1 -1
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_tile.dart +18 -8
- package/templates/firebase/lib/features/authentication/ui/signin_page.dart +11 -61
- package/templates/firebase/lib/features/authentication/ui/signup_page.dart +11 -61
- package/templates/firebase/lib/features/authentication/ui/widgets/auth_card_scaffold.dart +7 -5
- package/templates/firebase/lib/features/authentication/ui/widgets/social_auth_tile.dart +83 -0
- package/templates/firebase/lib/features/feedbacks/ui/widgets/feature_card.dart +4 -4
- package/templates/firebase/lib/features/home/home_components_page.dart +253 -125
- package/templates/firebase/lib/features/home/home_components_preview_registry.dart +263 -59
- package/templates/firebase/lib/features/home/home_feed.dart +2 -2
- package/templates/firebase/lib/features/home/home_image_grid.dart +3 -3
- package/templates/firebase/lib/features/local_reminders/providers/reminder_notifier.dart +8 -1
- package/templates/firebase/lib/features/local_reminders/ui/reminder_page.dart +111 -57
- package/templates/firebase/lib/features/notifications/api/device_api.dart +11 -3
- package/templates/firebase/lib/features/notifications/ui/notifications_page.dart +16 -4
- package/templates/firebase/lib/features/notifications/ui/widgets/empty_notifications.dart +7 -56
- package/templates/firebase/lib/features/notifications/ui/widgets/notification_tile.dart +5 -5
- package/templates/firebase/lib/features/notifications/ui/widgets/push_permission_banner.dart +163 -0
- package/templates/firebase/lib/features/notifications/ui/widgets/web_notifications_bell.dart +2 -2
- package/templates/firebase/lib/features/onboarding/providers/onboarding_model.dart +9 -0
- package/templates/firebase/lib/features/onboarding/providers/onboarding_provider.dart +28 -0
- package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +51 -12
- package/templates/firebase/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +90 -32
- package/templates/firebase/lib/features/settings/settings_page.dart +53 -32
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_home_widgets.dart +4 -0
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_page.dart +895 -111
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_api.dart +7 -0
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_tab.dart +445 -233
- package/templates/firebase/lib/features/settings/ui/components/admin/send_push_notification_page.dart +171 -41
- package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +1 -1
- package/templates/firebase/lib/features/settings/ui/components/delete_user_component.dart +9 -1
- package/templates/firebase/lib/features/settings/ui/components/language_switcher.dart +48 -47
- package/templates/firebase/lib/features/settings/ui/widgets/settings_bottom_sheet_option_tile.dart +21 -18
- package/templates/firebase/lib/features/settings/ui/widgets/settings_tile.dart +25 -10
- package/templates/firebase/lib/i18n/en.i18n.json +753 -712
- package/templates/firebase/lib/i18n/es.i18n.json +753 -712
- package/templates/firebase/lib/i18n/pt.i18n.json +753 -712
- package/templates/firebase/lib/main.dart +20 -7
- package/templates/firebase/lib/router.dart +32 -26
- package/templates/firebase/pubspec.yaml +2 -1
- package/templates/firebase/test/admin_shell_chrome_test.dart +11 -5
- package/templates/firebase/test/app_bar_config_test.dart +70 -0
- package/templates/firebase/test/components/kasy_text_field_height_test.dart +77 -0
- package/templates/firebase/test/core/web_viewport_scale_test.dart +23 -16
- package/templates/firebase/tool/design_check.dart +9 -0
- package/templates/firebase/assets/icons/apple.png +0 -0
- package/templates/firebase/assets/icons/facebook.png +0 -0
- package/templates/firebase/assets/icons/google.png +0 -0
- package/templates/firebase/assets/icons/google_play_games.png +0 -0
- package/templates/firebase/lib/components/kasy_web_header.dart +0 -218
- package/templates/firebase/lib/core/chrome/web_header_scope.dart +0 -20
- package/templates/firebase/lib/features/authentication/ui/components/apple_signin.dart +0 -19
- package/templates/firebase/lib/features/authentication/ui/components/google_signin.dart +0 -32
- package/templates/firebase/lib/features/authentication/ui/widgets/round_signin.dart +0 -73
- package/templates/firebase/lib/features/feedbacks/ui/widgets/add_feature_button.dart +0 -66
- package/templates/firebase/lib/features/notifications/ui/components/notification_settings_sheet.dart +0 -179
- package/templates/firebase/lib/features/notifications/ui/components/push_notification_switcher.dart +0 -106
|
@@ -71,39 +71,44 @@ ComponentPreviewDefinition? getComponentPreviewDefinition(
|
|
|
71
71
|
return const ComponentPreviewDefinition(
|
|
72
72
|
title: 'AppBar',
|
|
73
73
|
variants: [
|
|
74
|
+
// Phone / tablet — the page chrome (title + back + orbs).
|
|
74
75
|
ComponentPreviewVariant(
|
|
75
|
-
label: 'Subpage',
|
|
76
|
+
label: 'Subpage (mobile)',
|
|
76
77
|
builder: _buildAppBarSubpageVariant,
|
|
77
78
|
),
|
|
78
79
|
ComponentPreviewVariant(
|
|
79
|
-
label: 'Subpage Simple',
|
|
80
|
+
label: 'Subpage Simple (mobile)',
|
|
80
81
|
builder: _buildAppBarSubpageSimpleVariant,
|
|
81
82
|
),
|
|
82
83
|
ComponentPreviewVariant(
|
|
83
|
-
label: 'Subpage Actions',
|
|
84
|
+
label: 'Subpage Actions (mobile)',
|
|
84
85
|
builder: _buildAppBarSubpageActionsVariant,
|
|
85
86
|
),
|
|
86
87
|
ComponentPreviewVariant(
|
|
87
|
-
label: 'Menu opens sidebar',
|
|
88
|
+
label: 'Menu opens sidebar (mobile)',
|
|
88
89
|
builder: _buildAppBarMenuVariant,
|
|
89
90
|
),
|
|
90
|
-
|
|
91
|
-
);
|
|
92
|
-
case 'Web Header':
|
|
93
|
-
return const ComponentPreviewDefinition(
|
|
94
|
-
title: 'Web Header',
|
|
95
|
-
variants: [
|
|
91
|
+
// Desktop — the application chrome (search + actions + profile).
|
|
96
92
|
ComponentPreviewVariant(
|
|
97
|
-
label: '
|
|
98
|
-
builder:
|
|
93
|
+
label: 'Application (desktop)',
|
|
94
|
+
builder: _buildAppBarApplicationVariant,
|
|
95
|
+
),
|
|
96
|
+
ComponentPreviewVariant(
|
|
97
|
+
label: 'Application + notification (desktop)',
|
|
98
|
+
builder: _buildAppBarApplicationBadgeVariant,
|
|
99
|
+
),
|
|
100
|
+
ComponentPreviewVariant(
|
|
101
|
+
label: 'Application no avatar (desktop)',
|
|
102
|
+
builder: _buildAppBarApplicationNoAvatarVariant,
|
|
99
103
|
),
|
|
104
|
+
// Per-screen presets — same bar, a screen picking its own chrome.
|
|
100
105
|
ComponentPreviewVariant(
|
|
101
|
-
label: '
|
|
102
|
-
builder:
|
|
106
|
+
label: 'Search only (desktop)',
|
|
107
|
+
builder: _buildAppBarApplicationSearchOnlyVariant,
|
|
103
108
|
),
|
|
104
109
|
ComponentPreviewVariant(
|
|
105
|
-
label: '
|
|
106
|
-
builder:
|
|
110
|
+
label: 'Notifications only (desktop)',
|
|
111
|
+
builder: _buildAppBarApplicationNotificationsOnlyVariant,
|
|
107
112
|
),
|
|
108
113
|
],
|
|
109
114
|
);
|
|
@@ -309,6 +314,24 @@ ComponentPreviewDefinition? getComponentPreviewDefinition(
|
|
|
309
314
|
),
|
|
310
315
|
],
|
|
311
316
|
);
|
|
317
|
+
case 'DropDown':
|
|
318
|
+
return const ComponentPreviewDefinition(
|
|
319
|
+
title: 'DropDown',
|
|
320
|
+
variants: [
|
|
321
|
+
ComponentPreviewVariant(
|
|
322
|
+
label: 'Basic',
|
|
323
|
+
builder: _buildDropDownBasic,
|
|
324
|
+
),
|
|
325
|
+
ComponentPreviewVariant(
|
|
326
|
+
label: 'With icons & subtitles',
|
|
327
|
+
builder: _buildDropDownRich,
|
|
328
|
+
),
|
|
329
|
+
ComponentPreviewVariant(
|
|
330
|
+
label: 'States',
|
|
331
|
+
builder: _buildDropDownStates,
|
|
332
|
+
),
|
|
333
|
+
],
|
|
334
|
+
);
|
|
312
335
|
case 'Badge':
|
|
313
336
|
return const ComponentPreviewDefinition(
|
|
314
337
|
title: 'Badge',
|
|
@@ -1928,16 +1951,42 @@ Widget _buildAppBarMenuVariant(BuildContext context) {
|
|
|
1928
1951
|
);
|
|
1929
1952
|
}
|
|
1930
1953
|
|
|
1931
|
-
|
|
1932
|
-
|
|
1954
|
+
/// A fully-wired desktop config for previews — every element active, so each
|
|
1955
|
+
/// variant can switch one thing on/off and read clearly.
|
|
1956
|
+
KasyAppBarConfig _demoAppBarConfig() => KasyAppBarConfig(
|
|
1957
|
+
onToggleTheme: () {},
|
|
1958
|
+
onNotifications: () {},
|
|
1959
|
+
onCreate: () {},
|
|
1960
|
+
onAvatarTap: () {},
|
|
1961
|
+
);
|
|
1962
|
+
|
|
1963
|
+
Widget _buildAppBarApplicationVariant(BuildContext context) {
|
|
1964
|
+
return _ApplicationBarPreview(config: _demoAppBarConfig());
|
|
1933
1965
|
}
|
|
1934
1966
|
|
|
1935
|
-
Widget
|
|
1936
|
-
return
|
|
1967
|
+
Widget _buildAppBarApplicationBadgeVariant(BuildContext context) {
|
|
1968
|
+
return _ApplicationBarPreview(
|
|
1969
|
+
config: _demoAppBarConfig().copyWith(showNotificationBadge: true),
|
|
1970
|
+
);
|
|
1937
1971
|
}
|
|
1938
1972
|
|
|
1939
|
-
Widget
|
|
1940
|
-
return
|
|
1973
|
+
Widget _buildAppBarApplicationNoAvatarVariant(BuildContext context) {
|
|
1974
|
+
return _ApplicationBarPreview(
|
|
1975
|
+
config: _demoAppBarConfig().copyWith(showAvatar: false),
|
|
1976
|
+
);
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
// Per-screen presets: the same component, different chrome chosen by a screen.
|
|
1980
|
+
Widget _buildAppBarApplicationSearchOnlyVariant(BuildContext context) {
|
|
1981
|
+
return _ApplicationBarPreview(
|
|
1982
|
+
config: _demoAppBarConfig().only(search: true, themeToggle: true),
|
|
1983
|
+
);
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
Widget _buildAppBarApplicationNotificationsOnlyVariant(BuildContext context) {
|
|
1987
|
+
return _ApplicationBarPreview(
|
|
1988
|
+
config: _demoAppBarConfig().only(notifications: true, themeToggle: true),
|
|
1989
|
+
);
|
|
1941
1990
|
}
|
|
1942
1991
|
|
|
1943
1992
|
Widget _buildButtonSizesVariant(BuildContext context) {
|
|
@@ -3866,49 +3915,57 @@ class _AccordionPreviewState extends State<_AccordionPreview> {
|
|
|
3866
3915
|
}
|
|
3867
3916
|
}
|
|
3868
3917
|
|
|
3869
|
-
/// Presents [
|
|
3870
|
-
/// faux sidebar + content) so the preview reads as the
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3918
|
+
/// Presents [KasyAppBar.application] inside a desktop browser-window mock (title
|
|
3919
|
+
/// bar + faux sidebar + content) so the preview reads as the desktop chrome it
|
|
3920
|
+
/// is — the responsive desktop half of [KasyAppBar].
|
|
3921
|
+
class _ApplicationBarPreview extends StatelessWidget {
|
|
3922
|
+
/// The exact config a screen would publish — rendered through the same
|
|
3923
|
+
/// [KasyAppBar.fromConfig] the shell uses, so the preview mirrors real usage.
|
|
3924
|
+
final KasyAppBarConfig config;
|
|
3925
|
+
|
|
3926
|
+
const _ApplicationBarPreview({required this.config});
|
|
3874
3927
|
|
|
3875
|
-
|
|
3928
|
+
/// Width the mock window is laid out at. The application bar is desktop chrome
|
|
3929
|
+
/// (220px search + actions), so it needs a desktop-class width — we render at
|
|
3930
|
+
/// this width and scale the whole window down to fit the (narrow) preview card.
|
|
3931
|
+
/// Without this, the bar overflows on a phone-sized preview.
|
|
3932
|
+
static const double _mockWindowWidth = 760;
|
|
3876
3933
|
|
|
3877
3934
|
@override
|
|
3878
3935
|
Widget build(BuildContext context) {
|
|
3879
3936
|
final KasyColors c = context.colors;
|
|
3880
|
-
return
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3937
|
+
return FittedBox(
|
|
3938
|
+
fit: BoxFit.scaleDown,
|
|
3939
|
+
child: SizedBox(
|
|
3940
|
+
width: _mockWindowWidth,
|
|
3941
|
+
child: DecoratedBox(
|
|
3942
|
+
decoration: BoxDecoration(
|
|
3943
|
+
color: c.surface,
|
|
3944
|
+
borderRadius: BorderRadius.circular(KasyRadius.lg),
|
|
3945
|
+
border: Border.all(color: c.onSurface.withValues(alpha: 0.10)),
|
|
3946
|
+
boxShadow: [KasyShadows.component(context)],
|
|
3947
|
+
),
|
|
3948
|
+
child: ClipRRect(
|
|
3949
|
+
borderRadius: BorderRadius.circular(KasyRadius.lg),
|
|
3950
|
+
child: Column(
|
|
3951
|
+
mainAxisSize: MainAxisSize.min,
|
|
3952
|
+
children: [
|
|
3953
|
+
const _BrowserTopBar(),
|
|
3954
|
+
// The real bar, flush — no corner radius of its own.
|
|
3955
|
+
KasyAppBar.fromConfig(config),
|
|
3956
|
+
const SizedBox(
|
|
3957
|
+
height: 150,
|
|
3958
|
+
child: Row(
|
|
3959
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
3960
|
+
children: [
|
|
3961
|
+
_DesktopMockSidebar(),
|
|
3962
|
+
Expanded(child: _DesktopMockContent()),
|
|
3963
|
+
],
|
|
3964
|
+
),
|
|
3965
|
+
),
|
|
3966
|
+
],
|
|
3910
3967
|
),
|
|
3911
|
-
|
|
3968
|
+
),
|
|
3912
3969
|
),
|
|
3913
3970
|
),
|
|
3914
3971
|
);
|
|
@@ -9447,3 +9504,150 @@ class _DatePickerFieldStatesPreviewState
|
|
|
9447
9504
|
);
|
|
9448
9505
|
}
|
|
9449
9506
|
}
|
|
9507
|
+
|
|
9508
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
9509
|
+
// DropDown — single-select dropdown (HeroUI "Select")
|
|
9510
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
9511
|
+
|
|
9512
|
+
const List<KasyDropDownItem<String>> _kDropDownStates = [
|
|
9513
|
+
KasyDropDownItem(value: 'fl', label: 'Florida'),
|
|
9514
|
+
KasyDropDownItem(value: 'de', label: 'Delaware'),
|
|
9515
|
+
KasyDropDownItem(value: 'tx', label: 'Texas'),
|
|
9516
|
+
KasyDropDownItem(value: 'ca', label: 'California'),
|
|
9517
|
+
KasyDropDownItem(value: 'ny', label: 'New York'),
|
|
9518
|
+
KasyDropDownItem(value: 'wy', label: 'Wyoming'),
|
|
9519
|
+
];
|
|
9520
|
+
|
|
9521
|
+
Widget _buildDropDownBasic(BuildContext context) => const _DropDownBasicPreview();
|
|
9522
|
+
|
|
9523
|
+
class _DropDownBasicPreview extends StatefulWidget {
|
|
9524
|
+
const _DropDownBasicPreview();
|
|
9525
|
+
|
|
9526
|
+
@override
|
|
9527
|
+
State<_DropDownBasicPreview> createState() => _DropDownBasicPreviewState();
|
|
9528
|
+
}
|
|
9529
|
+
|
|
9530
|
+
class _DropDownBasicPreviewState extends State<_DropDownBasicPreview> {
|
|
9531
|
+
String? _state;
|
|
9532
|
+
|
|
9533
|
+
@override
|
|
9534
|
+
Widget build(BuildContext context) {
|
|
9535
|
+
return Column(
|
|
9536
|
+
mainAxisSize: MainAxisSize.min,
|
|
9537
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
9538
|
+
children: [
|
|
9539
|
+
KasyDropDown<String>(
|
|
9540
|
+
label: 'State',
|
|
9541
|
+
hint: 'Select one',
|
|
9542
|
+
showRequiredIndicator: true,
|
|
9543
|
+
value: _state,
|
|
9544
|
+
items: _kDropDownStates,
|
|
9545
|
+
onChanged: (v) => setState(() => _state = v),
|
|
9546
|
+
),
|
|
9547
|
+
],
|
|
9548
|
+
);
|
|
9549
|
+
}
|
|
9550
|
+
}
|
|
9551
|
+
|
|
9552
|
+
Widget _buildDropDownRich(BuildContext context) => const _DropDownRichPreview();
|
|
9553
|
+
|
|
9554
|
+
class _DropDownRichPreview extends StatefulWidget {
|
|
9555
|
+
const _DropDownRichPreview();
|
|
9556
|
+
|
|
9557
|
+
@override
|
|
9558
|
+
State<_DropDownRichPreview> createState() => _DropDownRichPreviewState();
|
|
9559
|
+
}
|
|
9560
|
+
|
|
9561
|
+
class _DropDownRichPreviewState extends State<_DropDownRichPreview> {
|
|
9562
|
+
String? _action;
|
|
9563
|
+
|
|
9564
|
+
@override
|
|
9565
|
+
Widget build(BuildContext context) {
|
|
9566
|
+
return Column(
|
|
9567
|
+
mainAxisSize: MainAxisSize.min,
|
|
9568
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
9569
|
+
children: [
|
|
9570
|
+
KasyDropDown<String>(
|
|
9571
|
+
label: 'Quick action',
|
|
9572
|
+
hint: 'Pick an action',
|
|
9573
|
+
leadingIcon: KasyIcons.idea,
|
|
9574
|
+
value: _action,
|
|
9575
|
+
items: const [
|
|
9576
|
+
KasyDropDownItem(
|
|
9577
|
+
value: 'new',
|
|
9578
|
+
label: 'New file',
|
|
9579
|
+
icon: KasyIcons.add,
|
|
9580
|
+
subtitle: 'Create a new file',
|
|
9581
|
+
),
|
|
9582
|
+
KasyDropDownItem(
|
|
9583
|
+
value: 'copy',
|
|
9584
|
+
label: 'Copy link',
|
|
9585
|
+
icon: KasyIcons.copy,
|
|
9586
|
+
subtitle: 'Copy a shareable link',
|
|
9587
|
+
),
|
|
9588
|
+
KasyDropDownItem(
|
|
9589
|
+
value: 'settings',
|
|
9590
|
+
label: 'Settings',
|
|
9591
|
+
icon: KasyIcons.settings,
|
|
9592
|
+
subtitle: 'Manage file permissions',
|
|
9593
|
+
),
|
|
9594
|
+
],
|
|
9595
|
+
onChanged: (v) => setState(() => _action = v),
|
|
9596
|
+
),
|
|
9597
|
+
],
|
|
9598
|
+
);
|
|
9599
|
+
}
|
|
9600
|
+
}
|
|
9601
|
+
|
|
9602
|
+
Widget _buildDropDownStates(BuildContext context) =>
|
|
9603
|
+
const _DropDownStatesPreview();
|
|
9604
|
+
|
|
9605
|
+
class _DropDownStatesPreview extends StatefulWidget {
|
|
9606
|
+
const _DropDownStatesPreview();
|
|
9607
|
+
|
|
9608
|
+
@override
|
|
9609
|
+
State<_DropDownStatesPreview> createState() => _DropDownStatesPreviewState();
|
|
9610
|
+
}
|
|
9611
|
+
|
|
9612
|
+
class _DropDownStatesPreviewState extends State<_DropDownStatesPreview> {
|
|
9613
|
+
String? _invalid;
|
|
9614
|
+
|
|
9615
|
+
@override
|
|
9616
|
+
Widget build(BuildContext context) {
|
|
9617
|
+
return Column(
|
|
9618
|
+
mainAxisSize: MainAxisSize.min,
|
|
9619
|
+
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
9620
|
+
children: [
|
|
9621
|
+
// Pre-selected value.
|
|
9622
|
+
KasyDropDown<String>(
|
|
9623
|
+
label: 'Selected',
|
|
9624
|
+
hint: 'Select one',
|
|
9625
|
+
value: 'ca',
|
|
9626
|
+
items: _kDropDownStates,
|
|
9627
|
+
onChanged: (_) {},
|
|
9628
|
+
),
|
|
9629
|
+
const SizedBox(height: KasySpacing.lg),
|
|
9630
|
+
// Invalid + error text.
|
|
9631
|
+
KasyDropDown<String>(
|
|
9632
|
+
label: 'Required',
|
|
9633
|
+
hint: 'Select one',
|
|
9634
|
+
showRequiredIndicator: true,
|
|
9635
|
+
isInvalid: _invalid == null,
|
|
9636
|
+
errorText: _invalid == null ? 'Please choose a state.' : null,
|
|
9637
|
+
value: _invalid,
|
|
9638
|
+
items: _kDropDownStates,
|
|
9639
|
+
onChanged: (v) => setState(() => _invalid = v),
|
|
9640
|
+
),
|
|
9641
|
+
const SizedBox(height: KasySpacing.lg),
|
|
9642
|
+
// Disabled trigger.
|
|
9643
|
+
const KasyDropDown<String>(
|
|
9644
|
+
label: 'Disabled',
|
|
9645
|
+
hint: 'Locked',
|
|
9646
|
+
enabled: false,
|
|
9647
|
+
items: _kDropDownStates,
|
|
9648
|
+
onChanged: null,
|
|
9649
|
+
),
|
|
9650
|
+
],
|
|
9651
|
+
);
|
|
9652
|
+
}
|
|
9653
|
+
}
|
|
@@ -336,7 +336,7 @@ class _FilterCard extends StatelessWidget {
|
|
|
336
336
|
data.title,
|
|
337
337
|
maxLines: 1,
|
|
338
338
|
overflow: TextOverflow.ellipsis,
|
|
339
|
-
style: context.
|
|
339
|
+
style: context.kasyTextTheme.cardTitle.copyWith(
|
|
340
340
|
color: selected ? c.primary : c.onSurface,
|
|
341
341
|
),
|
|
342
342
|
),
|
|
@@ -345,7 +345,7 @@ class _FilterCard extends StatelessWidget {
|
|
|
345
345
|
data.subtitle,
|
|
346
346
|
maxLines: 1,
|
|
347
347
|
overflow: TextOverflow.ellipsis,
|
|
348
|
-
style: context.
|
|
348
|
+
style: context.kasyTextTheme.cardSubtitle.copyWith(
|
|
349
349
|
color: c.muted,
|
|
350
350
|
),
|
|
351
351
|
),
|
|
@@ -234,7 +234,7 @@ class _PhotoTileState extends State<_PhotoTile> {
|
|
|
234
234
|
photo.author,
|
|
235
235
|
maxLines: 1,
|
|
236
236
|
overflow: TextOverflow.ellipsis,
|
|
237
|
-
style: context.
|
|
237
|
+
style: context.kasyTextTheme.cardTitle.copyWith(
|
|
238
238
|
color: context.colors.onSurface,
|
|
239
239
|
),
|
|
240
240
|
),
|
|
@@ -242,7 +242,7 @@ class _PhotoTileState extends State<_PhotoTile> {
|
|
|
242
242
|
photo.ago,
|
|
243
243
|
maxLines: 1,
|
|
244
244
|
overflow: TextOverflow.ellipsis,
|
|
245
|
-
style: context.
|
|
245
|
+
style: context.kasyTextTheme.caption.copyWith(
|
|
246
246
|
color: context.colors.muted,
|
|
247
247
|
),
|
|
248
248
|
),
|
|
@@ -375,7 +375,7 @@ class _LikeButtonState extends State<_LikeButton>
|
|
|
375
375
|
|
|
376
376
|
return KasyFocusRing(
|
|
377
377
|
onActivate: widget.onTap,
|
|
378
|
-
borderRadius: BorderRadius.circular(
|
|
378
|
+
borderRadius: BorderRadius.circular(KasyRadius.full),
|
|
379
379
|
child: GestureDetector(
|
|
380
380
|
onTap: widget.onTap,
|
|
381
381
|
behavior: HitTestBehavior.opaque,
|
|
@@ -21,7 +21,14 @@ class ReminderNotifier extends _$ReminderNotifier {
|
|
|
21
21
|
|
|
22
22
|
Future<void> setType(ReminderType type) async {
|
|
23
23
|
final current = state.requireValue;
|
|
24
|
-
|
|
24
|
+
// Leaving "specific date" drops the stored one-off date so it doesn't
|
|
25
|
+
// linger (and silently come back) if the user returns to that mode later.
|
|
26
|
+
await _applyAndSave(
|
|
27
|
+
current.copyWith(
|
|
28
|
+
type: type,
|
|
29
|
+
clearDate: type != ReminderType.specificDate,
|
|
30
|
+
),
|
|
31
|
+
);
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
Future<void> setTime(int hour, int minute) async {
|