kasy-cli 1.32.0 → 1.35.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/README.md +1 -1
- package/bin/kasy.js +66 -2
- package/docs/cli-reference.md +7 -7
- package/lib/commands/apple-web.js +222 -0
- package/lib/commands/configure.js +3 -91
- package/lib/commands/doctor.js +20 -0
- package/lib/commands/facebook.js +189 -0
- package/lib/commands/new.js +61 -11
- package/lib/commands/release-version.js +234 -0
- package/lib/commands/update.js +27 -0
- package/lib/scaffold/CHANGELOG.json +27 -0
- package/lib/scaffold/backends/api/patch/lib/features/authentication/api/authentication_api.dart +24 -0
- package/lib/scaffold/backends/api/patch/lib/features/authentication/api/authentication_api_interface.dart +15 -0
- package/lib/scaffold/backends/api/patch/lib/features/authentication/repositories/authentication_repository.dart +27 -0
- package/lib/scaffold/backends/api/patch/lib/features/subscriptions/api/entities/subscription_entity.dart +1 -0
- package/lib/scaffold/backends/firebase/setup-from-scratch.js +199 -21
- package/lib/scaffold/backends/patch-base-hashes.json +66 -0
- package/lib/scaffold/backends/supabase/deploy.js +92 -0
- package/lib/scaffold/backends/supabase/edge-functions/stripe-webhook/index.ts +2 -0
- package/lib/scaffold/backends/supabase/migrations/20240101000007_welcome_notification.sql +36 -23
- package/lib/scaffold/backends/supabase/migrations/20240101000014_subscription_trial_end.sql +6 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/authentication/api/authentication_api.dart +92 -3
- package/lib/scaffold/backends/supabase/patch/lib/features/authentication/repositories/authentication_repository.dart +36 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/subscriptions/api/entities/subscription_entity.dart +1 -0
- package/lib/scaffold/generate.js +53 -4
- package/lib/scaffold/shared/generator-utils.js +18 -6
- package/lib/utils/apple-web.js +147 -0
- package/lib/utils/facebook.js +162 -0
- package/lib/utils/i18n/messages-en.js +85 -0
- package/lib/utils/i18n/messages-es.js +85 -0
- package/lib/utils/i18n/messages-pt.js +85 -0
- package/package.json +5 -2
- package/templates/firebase/.firebase/hosting.YnVpbGQvd2Vi.cache +73 -0
- package/templates/firebase/AGENTS.md +170 -0
- package/templates/firebase/CLAUDE.md +16 -0
- package/templates/firebase/DESIGN_SYSTEM.md +269 -0
- package/templates/firebase/docs/auth-setup.en.md +4 -2
- package/templates/firebase/docs/auth-setup.es.md +4 -2
- package/templates/firebase/docs/auth-setup.pt.md +4 -2
- package/templates/firebase/firebase.json +56 -1
- package/templates/firebase/functions/src/authentication/triggers.ts +10 -6
- package/templates/firebase/functions/src/core/data/entities/subscription_entity.ts +5 -0
- package/templates/firebase/functions/src/core/data/entities/user_entity.ts +9 -1
- package/templates/firebase/functions/src/core/data/repositories/user_repository.ts +27 -0
- package/templates/firebase/functions/src/subscriptions/models/subscriptions.ts +3 -0
- package/templates/firebase/functions/src/subscriptions/stripe_functions.ts +4 -0
- package/templates/firebase/lib/components/components.dart +1 -0
- package/templates/firebase/lib/components/kasy_alert.dart +0 -1
- package/templates/firebase/lib/components/kasy_app_bar.dart +35 -17
- package/templates/firebase/lib/components/kasy_bottom_sheet.dart +0 -1
- package/templates/firebase/lib/components/kasy_date_picker.dart +0 -5
- package/templates/firebase/lib/components/kasy_dialog.dart +0 -1
- package/templates/firebase/lib/components/kasy_otp_verification_bottom_sheet.dart +1 -1
- package/templates/firebase/lib/components/kasy_screen.dart +114 -0
- package/templates/firebase/lib/components/kasy_sidebar.dart +189 -120
- package/templates/firebase/lib/components/kasy_text_area.dart +0 -1
- package/templates/firebase/lib/components/kasy_text_field.dart +0 -1
- package/templates/firebase/lib/components/kasy_text_field_otp.dart +0 -1
- package/templates/firebase/lib/components/kasy_toast.dart +108 -73
- package/templates/firebase/lib/core/app_update/app_update_repository.dart +54 -0
- package/templates/firebase/lib/core/app_update/app_update_status.dart +14 -0
- package/templates/firebase/lib/core/app_update/update_available_sheet.dart +70 -0
- package/templates/firebase/lib/core/bottom_menu/active_tab_notifier.dart +40 -3
- package/templates/firebase/lib/core/bottom_menu/bottom_menu.dart +82 -34
- package/templates/firebase/lib/core/bottom_menu/web_content_wrapper.dart +6 -6
- package/templates/firebase/lib/core/bottom_menu/web_url.dart +20 -0
- package/templates/firebase/lib/core/chrome/chrome_visibility.dart +22 -0
- package/templates/firebase/lib/core/config/features.dart +5 -0
- package/templates/firebase/lib/core/data/api/remote_config_api.dart +38 -1
- package/templates/firebase/lib/core/guards/guard.dart +16 -2
- package/templates/firebase/lib/core/icons/kasy_icons.dart +3 -0
- package/templates/firebase/lib/core/rating/widgets/rate_banner.dart +2 -5
- package/templates/firebase/lib/core/rating/widgets/review_popup.dart +48 -124
- package/templates/firebase/lib/core/shared_preferences/shared_preferences.dart +14 -0
- package/templates/firebase/lib/core/states/components/maybe_show_update_available.dart +32 -0
- package/templates/firebase/lib/core/states/logout_action.dart +5 -1
- package/templates/firebase/lib/core/states/user_state_notifier.dart +85 -14
- package/templates/firebase/lib/core/theme/responsive_text_theme.dart +69 -0
- package/templates/firebase/lib/core/theme/texts.dart +90 -57
- package/templates/firebase/lib/core/theme/type_scale.dart +77 -0
- package/templates/firebase/lib/core/theme/web_background_sync_web.dart +20 -6
- package/templates/firebase/lib/core/utils/image_bytes_loader.dart +12 -0
- package/templates/firebase/lib/core/utils/image_bytes_loader_io.dart +28 -0
- package/templates/firebase/lib/core/utils/image_bytes_loader_web.dart +56 -0
- package/templates/firebase/lib/core/web_screen_width.dart +15 -0
- package/templates/firebase/lib/core/web_screen_width_io.dart +3 -0
- package/templates/firebase/lib/core/web_screen_width_web.dart +10 -0
- package/templates/firebase/lib/core/web_viewport_scale.dart +61 -25
- package/templates/firebase/lib/core/widgets/focus_visibility.dart +89 -0
- package/templates/firebase/lib/core/widgets/update_bottom_sheet.dart +29 -126
- package/templates/firebase/lib/features/ai_chat/ai_chat_page.dart +11 -8
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_chat_composer.dart +21 -0
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_chat_conversation_view.dart +1 -2
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_list.dart +2 -3
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_tile.dart +1 -2
- package/templates/firebase/lib/features/authentication/api/auth_web_support.dart +12 -0
- package/templates/firebase/lib/features/authentication/api/auth_web_support_web.dart +25 -0
- package/templates/firebase/lib/features/authentication/api/authentication_api.dart +266 -0
- package/templates/firebase/lib/features/authentication/api/authentication_api_interface.dart +22 -0
- package/templates/firebase/lib/features/authentication/navigation/post_login_navigation.dart +32 -0
- package/templates/firebase/lib/features/authentication/providers/phone_auth_notifier.dart +7 -7
- package/templates/firebase/lib/features/authentication/providers/signin_state_provider.dart +34 -10
- package/templates/firebase/lib/features/authentication/providers/signup_state_provider.dart +2 -2
- package/templates/firebase/lib/features/authentication/repositories/authentication_repository.dart +37 -0
- package/templates/firebase/lib/features/authentication/repositories/exceptions/authentication_exceptions.dart +8 -0
- package/templates/firebase/lib/features/authentication/ui/components/otp_verification.dart +2 -2
- package/templates/firebase/lib/features/authentication/ui/components/phone_input.dart +2 -2
- package/templates/firebase/lib/features/authentication/ui/signin_page.dart +80 -15
- package/templates/firebase/lib/features/authentication/ui/signup_page.dart +20 -14
- package/templates/firebase/lib/features/authentication/ui/widgets/auth_card_scaffold.dart +2 -2
- package/templates/firebase/lib/features/authentication/ui/widgets/recover_password_result.dart +2 -2
- package/templates/firebase/lib/features/feedbacks/ui/widgets/add_feature_button.dart +0 -1
- package/templates/firebase/lib/features/feedbacks/ui/widgets/feature_card.dart +1 -2
- package/templates/firebase/lib/features/home/design_system_page.dart +134 -67
- package/templates/firebase/lib/features/home/home_components_page.dart +8 -1
- package/templates/firebase/lib/features/home/home_components_preview_page.dart +1 -3
- package/templates/firebase/lib/features/home/home_components_preview_registry.dart +186 -56
- package/templates/firebase/lib/features/home/home_page.dart +4 -0
- package/templates/firebase/lib/features/local_reminders/ui/reminder_page.dart +169 -208
- package/templates/firebase/lib/features/notifications/providers/notifications_provider.dart +10 -0
- package/templates/firebase/lib/features/notifications/ui/components/notification_settings_sheet.dart +2 -2
- package/templates/firebase/lib/features/notifications/ui/components/notification_tile.dart +21 -8
- package/templates/firebase/lib/features/notifications/ui/components/push_notification_switcher.dart +2 -2
- package/templates/firebase/lib/features/notifications/ui/notifications_page.dart +3 -4
- package/templates/firebase/lib/features/notifications/ui/widgets/notification_tile.dart +84 -128
- package/templates/firebase/lib/features/onboarding/providers/onboarding_model.dart +11 -0
- package/templates/firebase/lib/features/onboarding/providers/onboarding_provider.dart +30 -3
- package/templates/firebase/lib/features/onboarding/ui/components/onboarding_loader.dart +13 -4
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +3 -4
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +2 -4
- package/templates/firebase/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +2 -1
- package/templates/firebase/lib/features/settings/settings_page.dart +152 -11
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_page.dart +58 -21
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_tab.dart +12 -12
- package/templates/firebase/lib/features/settings/ui/components/admin/send_push_notification_page.dart +1 -4
- package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +2 -2
- package/templates/firebase/lib/features/settings/ui/components/create_password_sheet.dart +141 -0
- package/templates/firebase/lib/features/settings/ui/components/language_switcher.dart +0 -1
- package/templates/firebase/lib/features/settings/ui/widgets/admin_card.dart +42 -38
- package/templates/firebase/lib/features/settings/ui/widgets/settings_tile.dart +17 -2
- package/templates/firebase/lib/features/subscriptions/api/entities/subscription_entity.dart +3 -0
- package/templates/firebase/lib/features/subscriptions/api/stripe_product.dart +12 -11
- package/templates/firebase/lib/features/subscriptions/repositories/subscription_repository.dart +25 -2
- package/templates/firebase/lib/features/subscriptions/ui/component/active_premium_content.dart +319 -143
- package/templates/firebase/lib/features/subscriptions/ui/component/paywall_minimal.dart +1 -5
- package/templates/firebase/lib/features/subscriptions/ui/component/paywall_row.dart +1 -5
- package/templates/firebase/lib/features/subscriptions/ui/component/paywall_with_switch.dart +2 -5
- package/templates/firebase/lib/features/subscriptions/ui/component/premium_content.dart +1 -4
- package/templates/firebase/lib/features/subscriptions/ui/widgets/feature_line.dart +1 -2
- package/templates/firebase/lib/features/subscriptions/ui/widgets/premium_banner.dart +2 -7
- package/templates/firebase/lib/features/subscriptions/ui/widgets/premium_feature.dart +2 -4
- package/templates/firebase/lib/features/subscriptions/ui/widgets/selectable_col.dart +1 -4
- package/templates/firebase/lib/features/subscriptions/ui/widgets/selectable_row.dart +0 -3
- package/templates/firebase/lib/i18n/en.i18n.json +54 -7
- package/templates/firebase/lib/i18n/es.i18n.json +54 -7
- package/templates/firebase/lib/i18n/pt.i18n.json +54 -7
- package/templates/firebase/lib/main.dart +11 -2
- package/templates/firebase/lib/router.dart +94 -13
- package/templates/firebase/pubspec.yaml +1 -1
- package/templates/firebase/test/core/data/api/fake_remote_config_api.dart +14 -0
- package/templates/firebase/test/core/states/user_state_notifier_test.dart +47 -3
- package/templates/firebase/test/core/web_viewport_scale_test.dart +68 -0
- package/templates/firebase/test/features/authentication/data/api/auth_api_fake.dart +15 -0
- package/templates/firebase/tool/design_check.dart +152 -0
- package/templates/firebase/web/index.html +162 -14
- package/templates/firebase/assets/images/review.png +0 -0
- package/templates/firebase/assets/images/update.png +0 -0
- package/templates/firebase/lib/core/guards/user_info_guard.dart +0 -61
- package/templates/firebase/lib/features/notifications/ui/components/notifications_header.dart +0 -32
|
@@ -3,6 +3,7 @@ import 'dart:async';
|
|
|
3
3
|
import 'package:bart/bart/bart_model.dart';
|
|
4
4
|
import 'package:bart/bart/widgets/side_bar/custom_sidebar.dart';
|
|
5
5
|
import 'package:flutter/material.dart';
|
|
6
|
+
import 'package:kasy_kit/components/kasy_app_bar.dart';
|
|
6
7
|
import 'package:kasy_kit/components/kasy_avatar.dart';
|
|
7
8
|
import 'package:kasy_kit/components/kasy_avatar_presets.dart';
|
|
8
9
|
import 'package:kasy_kit/core/theme/theme.dart';
|
|
@@ -15,8 +16,11 @@ import 'package:kasy_kit/i18n/translations.g.dart';
|
|
|
15
16
|
|
|
16
17
|
// Figma sidebar is 223 wide; we run a touch wider for breathing room.
|
|
17
18
|
const double _kWidthOpen = 248.0;
|
|
18
|
-
const double _kWidthCollapsed =
|
|
19
|
+
const double _kWidthCollapsed = 64.0;
|
|
19
20
|
const double _kPadH = 16.0; // px-4
|
|
21
|
+
// Tighter horizontal gutter for the narrow collapsed rail, so a 64px rail keeps
|
|
22
|
+
// the 20px icons (44px active pill) centered without clipping.
|
|
23
|
+
const double _kCollapsedPadH = 10.0;
|
|
20
24
|
const double _kPadBottom = 16.0; // pb-4
|
|
21
25
|
// Top band that holds the logo. Equals the web header height (kasyWebHeaderHeight
|
|
22
26
|
// = 68) so the sidebar's first divider lines up with the header's bottom border.
|
|
@@ -203,6 +207,7 @@ class KasySidebar extends StatefulWidget {
|
|
|
203
207
|
this.onSettingsTap,
|
|
204
208
|
this.onLogout,
|
|
205
209
|
this.initiallyCollapsed = false,
|
|
210
|
+
this.isDrawer = false,
|
|
206
211
|
this.side = KasySidebarSide.left,
|
|
207
212
|
this.routes,
|
|
208
213
|
this.onTapItem,
|
|
@@ -250,6 +255,11 @@ class KasySidebar extends StatefulWidget {
|
|
|
250
255
|
/// Whether the sidebar starts in the narrow (icon-only) mode.
|
|
251
256
|
final bool initiallyCollapsed;
|
|
252
257
|
|
|
258
|
+
/// Present the rail as a slide-in drawer (the mobile pattern): it always opens
|
|
259
|
+
/// wide and hides the collapse toggle, regardless of viewport width. Use when
|
|
260
|
+
/// opening the sidebar from an app-bar menu button on a phone.
|
|
261
|
+
final bool isDrawer;
|
|
262
|
+
|
|
253
263
|
/// The screen edge this sidebar is anchored to.
|
|
254
264
|
final KasySidebarSide side;
|
|
255
265
|
|
|
@@ -269,11 +279,14 @@ class KasySidebar extends StatefulWidget {
|
|
|
269
279
|
}
|
|
270
280
|
|
|
271
281
|
class _KasySidebarState extends State<KasySidebar> {
|
|
272
|
-
// User's explicit open/close preference
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
//
|
|
276
|
-
|
|
282
|
+
// User's explicit open/close preference, set by tapping the toggle button.
|
|
283
|
+
// Null until they touch it, so the rail follows the viewport (auto-collapse on
|
|
284
|
+
// narrow). Once set, the explicit choice wins over the viewport — which is
|
|
285
|
+
// what lets a narrow-viewport rail be reopened by tapping the toggle.
|
|
286
|
+
bool? _collapsePreference;
|
|
287
|
+
|
|
288
|
+
// Computed at the start of build() — the user's explicit preference when set,
|
|
289
|
+
// otherwise the viewport auto-collapse. All submethods read this field.
|
|
277
290
|
bool _collapsed = false;
|
|
278
291
|
|
|
279
292
|
bool _incomeExpanded = false;
|
|
@@ -286,6 +299,19 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
286
299
|
/// Viewport width below which the sidebar auto-collapses (tablet breakpoint).
|
|
287
300
|
static const double _kBreakpoint = 1024.0;
|
|
288
301
|
|
|
302
|
+
/// Below this (mobile), the rail is meant to be a wide drawer: it always opens
|
|
303
|
+
/// full width and hides the collapse toggle (thinning makes no sense on a
|
|
304
|
+
/// phone-width sheet). The collapse affordance only exists from tablet up.
|
|
305
|
+
static const double _kMobileBreakpoint = 768.0;
|
|
306
|
+
|
|
307
|
+
bool _isMobile(BuildContext context) =>
|
|
308
|
+
MediaQuery.sizeOf(context).width < _kMobileBreakpoint;
|
|
309
|
+
|
|
310
|
+
/// Drawer presentation — always wide, no collapse toggle. True on a phone-
|
|
311
|
+
/// width viewport or when explicitly opened as a drawer ([isDrawer]).
|
|
312
|
+
bool _wideDrawer(BuildContext context) =>
|
|
313
|
+
widget.isDrawer || _isMobile(context);
|
|
314
|
+
|
|
289
315
|
/// True when wired to Bart's navigation (real, tappable screens).
|
|
290
316
|
bool get _connected =>
|
|
291
317
|
widget.routes != null &&
|
|
@@ -296,7 +322,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
296
322
|
@override
|
|
297
323
|
void initState() {
|
|
298
324
|
super.initState();
|
|
299
|
-
|
|
325
|
+
_collapsePreference = widget.initiallyCollapsed ? true : null;
|
|
300
326
|
// Connected mode follows Bart's currentItem (empty highlight here); the
|
|
301
327
|
// showcase defaults to the active layer from the Figma reference.
|
|
302
328
|
_activeItemId = _connected ? '' : 'object2';
|
|
@@ -305,13 +331,19 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
305
331
|
bool _isViewportNarrow(BuildContext context) =>
|
|
306
332
|
MediaQuery.sizeOf(context).width < _kBreakpoint;
|
|
307
333
|
|
|
334
|
+
/// Horizontal gutter for the rail content — tighter when collapsed so the
|
|
335
|
+
/// icon rail stays narrow while keeping the icons centered.
|
|
336
|
+
double get _railPadH => _collapsed ? _kCollapsedPadH : _kPadH;
|
|
337
|
+
|
|
308
338
|
_SidebarColors get _colors => _SidebarColors.fromContext(context);
|
|
309
339
|
|
|
310
340
|
// ── Actions ───────────────────────────────────────────────────────────────
|
|
311
341
|
|
|
312
|
-
//
|
|
342
|
+
// Flip the currently visible state and pin it as the explicit preference, so
|
|
343
|
+
// it overrides the viewport auto-collapse — this is what lets a narrow-
|
|
344
|
+
// viewport rail be expanded back open from the toggle.
|
|
313
345
|
void _toggleCollapse() =>
|
|
314
|
-
setState(() =>
|
|
346
|
+
setState(() => _collapsePreference = !_collapsed);
|
|
315
347
|
|
|
316
348
|
/// Navigates to a real route via Bart and clears any static-item highlight.
|
|
317
349
|
/// Moving to another screen also collapses an open submenu (e.g. Income) and
|
|
@@ -347,7 +379,10 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
347
379
|
|
|
348
380
|
@override
|
|
349
381
|
Widget build(BuildContext context) {
|
|
350
|
-
|
|
382
|
+
// A drawer / phone-width rail always opens wide; otherwise honour the user's
|
|
383
|
+
// explicit choice, falling back to the tablet auto-collapse.
|
|
384
|
+
_collapsed = !_wideDrawer(context) &&
|
|
385
|
+
(_collapsePreference ?? _isViewportNarrow(context));
|
|
351
386
|
|
|
352
387
|
final c = _colors;
|
|
353
388
|
final bool anchoredLeft = widget.side == KasySidebarSide.left;
|
|
@@ -409,11 +444,15 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
409
444
|
// Nav: workspace selector + segmented tabs + the layers list.
|
|
410
445
|
Expanded(
|
|
411
446
|
child: Padding(
|
|
412
|
-
padding:
|
|
447
|
+
padding: EdgeInsets.symmetric(horizontal: _railPadH),
|
|
413
448
|
child: SingleChildScrollView(
|
|
414
449
|
child: Column(
|
|
415
450
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
416
451
|
children: [
|
|
452
|
+
// Top gap lives INSIDE the scroll view so the list scrolls
|
|
453
|
+
// flush under the top divider (symmetric with the bottom),
|
|
454
|
+
// instead of clipping a gap below it.
|
|
455
|
+
const SizedBox(height: _kDividerGap),
|
|
417
456
|
if (!_collapsed) ...[
|
|
418
457
|
_buildWorkspaceSelector(c),
|
|
419
458
|
const SizedBox(height: _kHeaderGap),
|
|
@@ -430,10 +469,10 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
430
469
|
// Pinned ⌘K search row + profile block.
|
|
431
470
|
_buildDivider(c),
|
|
432
471
|
Padding(
|
|
433
|
-
padding:
|
|
434
|
-
|
|
472
|
+
padding: EdgeInsets.fromLTRB(
|
|
473
|
+
_railPadH,
|
|
435
474
|
_kFooterGap,
|
|
436
|
-
|
|
475
|
+
_railPadH,
|
|
437
476
|
_kPadBottom,
|
|
438
477
|
),
|
|
439
478
|
child: Column(
|
|
@@ -481,11 +520,15 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
481
520
|
_buildDivider(c),
|
|
482
521
|
Expanded(
|
|
483
522
|
child: Padding(
|
|
484
|
-
padding:
|
|
523
|
+
padding: EdgeInsets.symmetric(horizontal: _railPadH),
|
|
485
524
|
child: SingleChildScrollView(
|
|
486
525
|
child: Column(
|
|
487
526
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
488
527
|
children: [
|
|
528
|
+
// Top gap lives INSIDE the scroll view so the list scrolls
|
|
529
|
+
// flush under the top divider (symmetric with the bottom),
|
|
530
|
+
// instead of clipping a gap below it.
|
|
531
|
+
const SizedBox(height: _kDividerGap),
|
|
489
532
|
if (!_collapsed) ...[
|
|
490
533
|
_buildSectionLabel('MAIN', c),
|
|
491
534
|
const SizedBox(height: _kItemGap),
|
|
@@ -530,7 +573,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
530
573
|
_buildDivider(c),
|
|
531
574
|
const SizedBox(height: _kFooterGap),
|
|
532
575
|
Padding(
|
|
533
|
-
padding:
|
|
576
|
+
padding: EdgeInsets.fromLTRB(_railPadH, 0, _railPadH, _kPadBottom),
|
|
534
577
|
child: Column(
|
|
535
578
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
536
579
|
children: [
|
|
@@ -559,25 +602,40 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
559
602
|
/// header height) so the divider underneath lines up with the header's bottom
|
|
560
603
|
/// border. Content is vertically centred, mirroring the header's toolbar row.
|
|
561
604
|
Widget _buildTopBand(_SidebarColors c) {
|
|
605
|
+
// Keep the first divider on the same line as the content chrome's bottom
|
|
606
|
+
// border: the web header (68) on desktop, but the shorter KasyAppBar on
|
|
607
|
+
// tablet (medium), where the page keeps its own app bar instead of the
|
|
608
|
+
// header. Without this the line breaks between the rail and the app bar.
|
|
609
|
+
final double bandHeight =
|
|
610
|
+
MediaQuery.sizeOf(context).width >= _kBreakpoint
|
|
611
|
+
? _kTopBandHeight
|
|
612
|
+
: kasyAppBarBodyTopOverlap(context);
|
|
613
|
+
// No collapse toggle on the mobile / drawer rail (it always opens wide).
|
|
614
|
+
final bool showToggle = !_wideDrawer(context);
|
|
615
|
+
final bool anchoredLeft = widget.side == KasySidebarSide.left;
|
|
616
|
+
// Brand wordmark — same artwork as the splash screen.
|
|
617
|
+
final Widget logo = Image.asset(
|
|
618
|
+
c.isDark
|
|
619
|
+
? 'assets/images/logo_wordmark_dark.png'
|
|
620
|
+
: 'assets/images/logo_wordmark_light.png',
|
|
621
|
+
height: 32,
|
|
622
|
+
fit: BoxFit.contain,
|
|
623
|
+
);
|
|
624
|
+
// Left rail: wordmark then toggle (toggle hugs the content edge). The right
|
|
625
|
+
// rail mirrors it so the toggle still hugs the content edge (now the left).
|
|
626
|
+
final List<Widget> rowChildren = <Widget>[
|
|
627
|
+
logo,
|
|
628
|
+
if (showToggle) ...[const Spacer(), _buildToggleButton(c)],
|
|
629
|
+
];
|
|
562
630
|
return Padding(
|
|
563
|
-
padding:
|
|
631
|
+
padding: EdgeInsets.symmetric(horizontal: _railPadH),
|
|
564
632
|
child: SizedBox(
|
|
565
|
-
height:
|
|
633
|
+
height: bandHeight,
|
|
566
634
|
child: _collapsed
|
|
567
635
|
? Center(child: _buildToggleButton(c))
|
|
568
636
|
: Row(
|
|
569
|
-
children:
|
|
570
|
-
|
|
571
|
-
Image.asset(
|
|
572
|
-
c.isDark
|
|
573
|
-
? 'assets/images/logo_wordmark_dark.png'
|
|
574
|
-
: 'assets/images/logo_wordmark_light.png',
|
|
575
|
-
height: 32,
|
|
576
|
-
fit: BoxFit.contain,
|
|
577
|
-
),
|
|
578
|
-
const Spacer(),
|
|
579
|
-
_buildToggleButton(c),
|
|
580
|
-
],
|
|
637
|
+
children:
|
|
638
|
+
anchoredLeft ? rowChildren : rowChildren.reversed.toList(),
|
|
581
639
|
),
|
|
582
640
|
),
|
|
583
641
|
);
|
|
@@ -618,10 +676,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
618
676
|
'3D Dog Character',
|
|
619
677
|
maxLines: 1,
|
|
620
678
|
overflow: TextOverflow.ellipsis,
|
|
621
|
-
style:
|
|
622
|
-
fontSize: 14,
|
|
623
|
-
height: 20 / 14,
|
|
624
|
-
fontWeight: FontWeight.w500,
|
|
679
|
+
style: context.kasyTextTheme.rowTitle.copyWith(
|
|
625
680
|
color: c.textActive,
|
|
626
681
|
),
|
|
627
682
|
),
|
|
@@ -635,10 +690,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
635
690
|
'3D Design Project',
|
|
636
691
|
maxLines: 1,
|
|
637
692
|
overflow: TextOverflow.ellipsis,
|
|
638
|
-
style:
|
|
639
|
-
fontSize: 12,
|
|
640
|
-
height: 16 / 12,
|
|
641
|
-
fontWeight: FontWeight.w400,
|
|
693
|
+
style: context.kasyTextTheme.cardSubtitle.copyWith(
|
|
642
694
|
color: c.textMuted,
|
|
643
695
|
),
|
|
644
696
|
),
|
|
@@ -694,10 +746,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
694
746
|
),
|
|
695
747
|
child: Text(
|
|
696
748
|
label,
|
|
697
|
-
style:
|
|
698
|
-
fontSize: 14,
|
|
699
|
-
height: 20 / 14,
|
|
700
|
-
fontWeight: FontWeight.w500,
|
|
749
|
+
style: context.kasyTextTheme.rowTitle.copyWith(
|
|
701
750
|
color: selected ? c.textActive : c.textMuted,
|
|
702
751
|
),
|
|
703
752
|
),
|
|
@@ -710,10 +759,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
710
759
|
// ── ⌘K keyboard chip ─────────────────────────────────────────────────────────
|
|
711
760
|
|
|
712
761
|
Widget _buildKbd(_SidebarColors c) {
|
|
713
|
-
final TextStyle style =
|
|
714
|
-
fontSize: 14,
|
|
715
|
-
height: 20 / 14,
|
|
716
|
-
fontWeight: FontWeight.w500,
|
|
762
|
+
final TextStyle style = context.kasyTextTheme.rowTitle.copyWith(
|
|
717
763
|
color: c.textMuted,
|
|
718
764
|
);
|
|
719
765
|
return Container(
|
|
@@ -774,10 +820,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
774
820
|
widget.profileName,
|
|
775
821
|
maxLines: 1,
|
|
776
822
|
overflow: TextOverflow.ellipsis,
|
|
777
|
-
style:
|
|
778
|
-
fontSize: 14,
|
|
779
|
-
height: 20 / 14,
|
|
780
|
-
fontWeight: FontWeight.w500,
|
|
823
|
+
style: context.kasyTextTheme.rowTitle.copyWith(
|
|
781
824
|
color: c.textActive,
|
|
782
825
|
),
|
|
783
826
|
),
|
|
@@ -785,10 +828,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
785
828
|
widget.profileEmail,
|
|
786
829
|
maxLines: 1,
|
|
787
830
|
overflow: TextOverflow.ellipsis,
|
|
788
|
-
style:
|
|
789
|
-
fontSize: 12,
|
|
790
|
-
height: 16 / 12,
|
|
791
|
-
fontWeight: FontWeight.w500,
|
|
831
|
+
style: context.textTheme.labelMedium?.copyWith(
|
|
792
832
|
color: c.textMuted,
|
|
793
833
|
),
|
|
794
834
|
),
|
|
@@ -816,11 +856,8 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
816
856
|
padding: const EdgeInsets.only(left: _kItemHPad),
|
|
817
857
|
child: Text(
|
|
818
858
|
label,
|
|
819
|
-
style:
|
|
820
|
-
fontSize: 11,
|
|
821
|
-
fontWeight: FontWeight.w600,
|
|
859
|
+
style: context.kasyTextTheme.sectionLabel.copyWith(
|
|
822
860
|
color: c.textMuted,
|
|
823
|
-
letterSpacing: 0.6,
|
|
824
861
|
),
|
|
825
862
|
),
|
|
826
863
|
);
|
|
@@ -913,6 +950,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
913
950
|
iconColor: iconColor,
|
|
914
951
|
activeBg: c.activeBg,
|
|
915
952
|
colors: c,
|
|
953
|
+
anchoredLeft: widget.side == KasySidebarSide.left,
|
|
916
954
|
onTap: onTap,
|
|
917
955
|
),
|
|
918
956
|
),
|
|
@@ -952,10 +990,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
952
990
|
label,
|
|
953
991
|
maxLines: 1,
|
|
954
992
|
overflow: TextOverflow.ellipsis,
|
|
955
|
-
style:
|
|
956
|
-
fontSize: 14,
|
|
957
|
-
height: 20 / 14,
|
|
958
|
-
fontWeight: FontWeight.w500,
|
|
993
|
+
style: context.kasyTextTheme.rowTitle.copyWith(
|
|
959
994
|
color: labelColor,
|
|
960
995
|
),
|
|
961
996
|
),
|
|
@@ -989,6 +1024,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
989
1024
|
subItems: item.subItems,
|
|
990
1025
|
activeSubItem: _activeSubItem,
|
|
991
1026
|
colors: c,
|
|
1027
|
+
anchoredLeft: widget.side == KasySidebarSide.left,
|
|
992
1028
|
onSubItemTap: _activateSubItem,
|
|
993
1029
|
),
|
|
994
1030
|
);
|
|
@@ -1021,10 +1057,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
1021
1057
|
Expanded(
|
|
1022
1058
|
child: Text(
|
|
1023
1059
|
item.label,
|
|
1024
|
-
style:
|
|
1025
|
-
fontSize: 14,
|
|
1026
|
-
height: 20 / 14,
|
|
1027
|
-
fontWeight: FontWeight.w500,
|
|
1060
|
+
style: context.kasyTextTheme.rowTitle.copyWith(
|
|
1028
1061
|
color: c.textActive,
|
|
1029
1062
|
),
|
|
1030
1063
|
),
|
|
@@ -1141,8 +1174,7 @@ class _KasySidebarState extends State<KasySidebar> {
|
|
|
1141
1174
|
alignment: Alignment.centerLeft,
|
|
1142
1175
|
child: Text(
|
|
1143
1176
|
label,
|
|
1144
|
-
style:
|
|
1145
|
-
fontSize: 12,
|
|
1177
|
+
style: context.textTheme.labelMedium?.copyWith(
|
|
1146
1178
|
fontWeight: isActive ? FontWeight.w600 : FontWeight.w500,
|
|
1147
1179
|
color: textColor,
|
|
1148
1180
|
letterSpacing: -0.24,
|
|
@@ -1169,6 +1201,7 @@ class _ProHoverPopupIcon extends StatefulWidget {
|
|
|
1169
1201
|
required this.subItems,
|
|
1170
1202
|
required this.activeSubItem,
|
|
1171
1203
|
required this.colors,
|
|
1204
|
+
required this.anchoredLeft,
|
|
1172
1205
|
required this.onSubItemTap,
|
|
1173
1206
|
});
|
|
1174
1207
|
|
|
@@ -1178,6 +1211,12 @@ class _ProHoverPopupIcon extends StatefulWidget {
|
|
|
1178
1211
|
final List<String> subItems;
|
|
1179
1212
|
final String activeSubItem;
|
|
1180
1213
|
final _SidebarColors colors;
|
|
1214
|
+
|
|
1215
|
+
/// Whether the rail is on the left. The popup opens toward the content side
|
|
1216
|
+
/// (right of the icon on a left rail, left of the icon on a right rail) so it
|
|
1217
|
+
/// never spills off the screen edge.
|
|
1218
|
+
final bool anchoredLeft;
|
|
1219
|
+
|
|
1181
1220
|
final ValueChanged<String> onSubItemTap;
|
|
1182
1221
|
|
|
1183
1222
|
@override
|
|
@@ -1236,14 +1275,15 @@ class _ProHoverPopupIconState extends State<_ProHoverPopupIcon> {
|
|
|
1236
1275
|
}
|
|
1237
1276
|
|
|
1238
1277
|
Widget _buildPopup(BuildContext context) {
|
|
1278
|
+
final bool left = widget.anchoredLeft;
|
|
1239
1279
|
return CompositedTransformFollower(
|
|
1240
1280
|
link: _layerLink,
|
|
1241
1281
|
showWhenUnlinked: false,
|
|
1242
|
-
targetAnchor: Alignment.centerRight,
|
|
1243
|
-
followerAnchor: Alignment.centerLeft,
|
|
1244
|
-
offset:
|
|
1282
|
+
targetAnchor: left ? Alignment.centerRight : Alignment.centerLeft,
|
|
1283
|
+
followerAnchor: left ? Alignment.centerLeft : Alignment.centerRight,
|
|
1284
|
+
offset: Offset(left ? 12 : -12, 0),
|
|
1245
1285
|
child: Align(
|
|
1246
|
-
alignment: Alignment.centerLeft,
|
|
1286
|
+
alignment: left ? Alignment.centerLeft : Alignment.centerRight,
|
|
1247
1287
|
child: MouseRegion(
|
|
1248
1288
|
onEnter: (_) => setState(() => _onPopup = true),
|
|
1249
1289
|
onExit: (_) {
|
|
@@ -1292,8 +1332,7 @@ class _ProHoverPopupIconState extends State<_ProHoverPopupIcon> {
|
|
|
1292
1332
|
),
|
|
1293
1333
|
child: Text(
|
|
1294
1334
|
label,
|
|
1295
|
-
style:
|
|
1296
|
-
fontSize: 12,
|
|
1335
|
+
style: context.textTheme.labelMedium?.copyWith(
|
|
1297
1336
|
fontWeight: isActive ? FontWeight.w600 : FontWeight.w500,
|
|
1298
1337
|
color: textColor,
|
|
1299
1338
|
letterSpacing: -0.24,
|
|
@@ -1320,6 +1359,7 @@ class _ProTooltipIcon extends StatefulWidget {
|
|
|
1320
1359
|
required this.iconColor,
|
|
1321
1360
|
required this.activeBg,
|
|
1322
1361
|
required this.colors,
|
|
1362
|
+
required this.anchoredLeft,
|
|
1323
1363
|
required this.onTap,
|
|
1324
1364
|
});
|
|
1325
1365
|
|
|
@@ -1329,6 +1369,12 @@ class _ProTooltipIcon extends StatefulWidget {
|
|
|
1329
1369
|
final Color iconColor;
|
|
1330
1370
|
final Color activeBg;
|
|
1331
1371
|
final _SidebarColors colors;
|
|
1372
|
+
|
|
1373
|
+
/// Whether the rail is on the left. The tooltip opens toward the content side
|
|
1374
|
+
/// (and its arrow points back at the icon) so it never spills off the screen
|
|
1375
|
+
/// edge on a right-anchored rail.
|
|
1376
|
+
final bool anchoredLeft;
|
|
1377
|
+
|
|
1332
1378
|
final VoidCallback onTap;
|
|
1333
1379
|
|
|
1334
1380
|
@override
|
|
@@ -1374,15 +1420,20 @@ class _ProTooltipIconState extends State<_ProTooltipIcon> {
|
|
|
1374
1420
|
}
|
|
1375
1421
|
|
|
1376
1422
|
Widget _buildTooltip(BuildContext context) {
|
|
1423
|
+
final bool left = widget.anchoredLeft;
|
|
1377
1424
|
return CompositedTransformFollower(
|
|
1378
1425
|
link: _layerLink,
|
|
1379
1426
|
showWhenUnlinked: false,
|
|
1380
|
-
targetAnchor: Alignment.centerRight,
|
|
1381
|
-
followerAnchor: Alignment.centerLeft,
|
|
1382
|
-
offset:
|
|
1427
|
+
targetAnchor: left ? Alignment.centerRight : Alignment.centerLeft,
|
|
1428
|
+
followerAnchor: left ? Alignment.centerLeft : Alignment.centerRight,
|
|
1429
|
+
offset: Offset(left ? 4 : -4, 0),
|
|
1383
1430
|
child: Align(
|
|
1384
|
-
alignment: Alignment.centerLeft,
|
|
1385
|
-
child: _TooltipCard(
|
|
1431
|
+
alignment: left ? Alignment.centerLeft : Alignment.centerRight,
|
|
1432
|
+
child: _TooltipCard(
|
|
1433
|
+
label: widget.label,
|
|
1434
|
+
colors: widget.colors,
|
|
1435
|
+
pointsLeft: left,
|
|
1436
|
+
),
|
|
1386
1437
|
),
|
|
1387
1438
|
);
|
|
1388
1439
|
}
|
|
@@ -1393,11 +1444,19 @@ class _ProTooltipIconState extends State<_ProTooltipIcon> {
|
|
|
1393
1444
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1394
1445
|
|
|
1395
1446
|
class _TooltipCard extends StatelessWidget {
|
|
1396
|
-
const _TooltipCard({
|
|
1447
|
+
const _TooltipCard({
|
|
1448
|
+
required this.label,
|
|
1449
|
+
required this.colors,
|
|
1450
|
+
this.pointsLeft = true,
|
|
1451
|
+
});
|
|
1397
1452
|
|
|
1398
1453
|
final String label;
|
|
1399
1454
|
final _SidebarColors colors;
|
|
1400
1455
|
|
|
1456
|
+
/// Arrow points back at the icon: left when the rail is on the left (tooltip
|
|
1457
|
+
/// sits to the icon's right), right when the rail is on the right.
|
|
1458
|
+
final bool pointsLeft;
|
|
1459
|
+
|
|
1401
1460
|
static const double _arrowW = 13.0;
|
|
1402
1461
|
static const double _arrowH = 26.0;
|
|
1403
1462
|
static const double _arrowOverlap = 8.0;
|
|
@@ -1411,43 +1470,44 @@ class _TooltipCard extends StatelessWidget {
|
|
|
1411
1470
|
final Color bg = colors.isDark ? colors.divider : colors.textActive;
|
|
1412
1471
|
final Color textColor = colors.isDark ? colors.textActive : colors.bg;
|
|
1413
1472
|
|
|
1473
|
+
final Widget arrow = SizedBox(
|
|
1474
|
+
width: _arrowW,
|
|
1475
|
+
height: _arrowH,
|
|
1476
|
+
child: CustomPaint(
|
|
1477
|
+
painter: _TooltipArrowPainter(color: bg, pointsLeft: pointsLeft),
|
|
1478
|
+
),
|
|
1479
|
+
);
|
|
1480
|
+
// Pull the card over the arrow's base so they read as one shape; the
|
|
1481
|
+
// direction of the overlap flips with the arrow side.
|
|
1482
|
+
final Widget card = Transform.translate(
|
|
1483
|
+
offset: Offset(pointsLeft ? -_arrowOverlap : _arrowOverlap, 0),
|
|
1484
|
+
child: Container(
|
|
1485
|
+
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
|
1486
|
+
decoration: BoxDecoration(
|
|
1487
|
+
color: bg,
|
|
1488
|
+
borderRadius: BorderRadius.circular(4),
|
|
1489
|
+
boxShadow: const [
|
|
1490
|
+
BoxShadow(
|
|
1491
|
+
color: Color(0x40000000),
|
|
1492
|
+
blurRadius: 5,
|
|
1493
|
+
offset: Offset(0, 5),
|
|
1494
|
+
),
|
|
1495
|
+
],
|
|
1496
|
+
),
|
|
1497
|
+
child: Text(
|
|
1498
|
+
label,
|
|
1499
|
+
style: context.textTheme.bodyMedium?.copyWith(
|
|
1500
|
+
color: textColor,
|
|
1501
|
+
),
|
|
1502
|
+
),
|
|
1503
|
+
),
|
|
1504
|
+
);
|
|
1505
|
+
|
|
1414
1506
|
return Material(
|
|
1415
1507
|
color: Colors.transparent,
|
|
1416
1508
|
child: Row(
|
|
1417
1509
|
mainAxisSize: MainAxisSize.min,
|
|
1418
|
-
children: [
|
|
1419
|
-
SizedBox(
|
|
1420
|
-
width: _arrowW,
|
|
1421
|
-
height: _arrowH,
|
|
1422
|
-
child: CustomPaint(painter: _TooltipArrowPainter(color: bg)),
|
|
1423
|
-
),
|
|
1424
|
-
Transform.translate(
|
|
1425
|
-
offset: const Offset(-_arrowOverlap, 0),
|
|
1426
|
-
child: Container(
|
|
1427
|
-
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
|
1428
|
-
decoration: BoxDecoration(
|
|
1429
|
-
color: bg,
|
|
1430
|
-
borderRadius: BorderRadius.circular(4),
|
|
1431
|
-
boxShadow: const [
|
|
1432
|
-
BoxShadow(
|
|
1433
|
-
color: Color(0x40000000),
|
|
1434
|
-
blurRadius: 5,
|
|
1435
|
-
offset: Offset(0, 5),
|
|
1436
|
-
),
|
|
1437
|
-
],
|
|
1438
|
-
),
|
|
1439
|
-
child: Text(
|
|
1440
|
-
label,
|
|
1441
|
-
style: TextStyle(
|
|
1442
|
-
fontSize: 14,
|
|
1443
|
-
fontWeight: FontWeight.w400,
|
|
1444
|
-
color: textColor,
|
|
1445
|
-
height: 20 / 14,
|
|
1446
|
-
),
|
|
1447
|
-
),
|
|
1448
|
-
),
|
|
1449
|
-
),
|
|
1450
|
-
],
|
|
1510
|
+
children: pointsLeft ? <Widget>[arrow, card] : <Widget>[card, arrow],
|
|
1451
1511
|
),
|
|
1452
1512
|
);
|
|
1453
1513
|
}
|
|
@@ -1458,22 +1518,31 @@ class _TooltipCard extends StatelessWidget {
|
|
|
1458
1518
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1459
1519
|
|
|
1460
1520
|
class _TooltipArrowPainter extends CustomPainter {
|
|
1461
|
-
const _TooltipArrowPainter({required this.color});
|
|
1521
|
+
const _TooltipArrowPainter({required this.color, this.pointsLeft = true});
|
|
1462
1522
|
final Color color;
|
|
1523
|
+
final bool pointsLeft;
|
|
1463
1524
|
|
|
1464
1525
|
@override
|
|
1465
1526
|
void paint(Canvas canvas, Size size) {
|
|
1466
1527
|
final paint = Paint()
|
|
1467
1528
|
..color = color
|
|
1468
1529
|
..style = PaintingStyle.fill;
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1530
|
+
// Apex on the side it points to; base on the opposite (card) side.
|
|
1531
|
+
final path = pointsLeft
|
|
1532
|
+
? (Path()
|
|
1533
|
+
..moveTo(size.width, 0)
|
|
1534
|
+
..lineTo(0, size.height / 2)
|
|
1535
|
+
..lineTo(size.width, size.height)
|
|
1536
|
+
..close())
|
|
1537
|
+
: (Path()
|
|
1538
|
+
..moveTo(0, 0)
|
|
1539
|
+
..lineTo(size.width, size.height / 2)
|
|
1540
|
+
..lineTo(0, size.height)
|
|
1541
|
+
..close());
|
|
1474
1542
|
canvas.drawPath(path, paint);
|
|
1475
1543
|
}
|
|
1476
1544
|
|
|
1477
1545
|
@override
|
|
1478
|
-
bool shouldRepaint(_TooltipArrowPainter old) =>
|
|
1546
|
+
bool shouldRepaint(_TooltipArrowPainter old) =>
|
|
1547
|
+
old.color != color || old.pointsLeft != pointsLeft;
|
|
1479
1548
|
}
|
|
@@ -489,7 +489,6 @@ class _KasyTextFieldState extends State<KasyTextField> {
|
|
|
489
489
|
final TextStyle fieldTextStyle =
|
|
490
490
|
context.textTheme.bodyLarge?.copyWith(
|
|
491
491
|
color: fieldTextColor,
|
|
492
|
-
fontWeight: FontWeight.w400,
|
|
493
492
|
fontSize: 15,
|
|
494
493
|
) ??
|
|
495
494
|
TextStyle(fontSize: 15, color: fieldTextColor);
|
|
@@ -436,7 +436,6 @@ class _OTPCell extends StatelessWidget {
|
|
|
436
436
|
color: enabled
|
|
437
437
|
? context.colors.muted.withValues(alpha: 0.64)
|
|
438
438
|
: context.colors.muted.withValues(alpha: 0.58),
|
|
439
|
-
fontWeight: FontWeight.w700,
|
|
440
439
|
);
|
|
441
440
|
final String? visiblePlaceholder = digit.isEmpty && placeholder != null
|
|
442
441
|
? placeholder
|