kasy-cli 1.35.0 → 1.36.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.
@@ -1,4 +1,13 @@
1
1
  {
2
+ "1.36.0": {
3
+ "modules": {
4
+ "components": {
5
+ "pt": "Sidebar melhorada: nova linha de busca opcional acima do rodapé (showSearch), variante de gaveta (isDrawer) e modo de demonstração (showcase) pra mais flexibilidade de navegação. As abas internas agora usam o componente compartilhado KasyTabs, deixando o visual mais consistente e o código mais enxuto.",
6
+ "en": "Improved sidebar: new optional search row above the footer (showSearch), a drawer variant (isDrawer) and a showcase mode for more navigation flexibility. The internal tabs now use the shared KasyTabs component, making the look more consistent and the code leaner.",
7
+ "es": "Sidebar mejorada: nueva fila de búsqueda opcional sobre el pie (showSearch), variante de cajón (isDrawer) y modo de demostración (showcase) para más flexibilidad de navegación. Las pestañas internas ahora usan el componente compartido KasyTabs, dejando el aspecto más consistente y el código más limpio."
8
+ }
9
+ }
10
+ },
2
11
  "1.35.0": {
3
12
  "modules": {
4
13
  "core": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kasy-cli",
3
- "version": "1.35.0",
3
+ "version": "1.36.0",
4
4
  "description": "CLI for scaffolding production-ready Flutter SaaS apps with Firebase, Supabase, or API REST backends.",
5
5
  "bin": {
6
6
  "kasy": "./bin/kasy.js"
@@ -58,16 +58,16 @@ assets/assets/icons/google_play_games.png,1772398653083,533c1d87d7be8690ab173ef4
58
58
  assets/assets/icons/google.png,1772398653083,f423e7e7be1e06008d45617d07f095f04da7fdcab9a56523f9e0633828e464e0
59
59
  assets/assets/icons/facebook.png,1772398653083,79ac67e449c1db63319d43329ca91f682b4e0bc6a0883b0dfb2a849e13ae6eb6
60
60
  assets/assets/icons/apple.png,1772398653083,2a737d8801ca81452b2978bb2e1ac72136acf1a4c338f2de2f77b65e9f6de1fa
61
- version.json,1781382132245,b028f2bf7b54dc78541295a1ddf03306ac20a052662bde5b6b1aefe80d613249
62
- index.html,1781382083192,bb8142eb84e9e44049957c3edf86006e1ae5f194c397a8326ce505b68fdf58f4
63
- flutter_service_worker.js,1781382132717,baeeaf9f4b8e6f40d3b0549429ceb70ca01f120db6a7ef2f60d5809233dc2205
64
- assets/FontManifest.json,1781382132345,4d84ab517c27984d36f9a3c8be6f2a72788c0c3985c1d5874297fef0a53407ca
65
- assets/AssetManifest.bin.json,1781382132345,50a11b51c3fc4cbed1b5ec3a4f466c6a6b75c481d08d4782c8191f99bdbdba9c
66
- assets/AssetManifest.bin,1781382132345,78bccb08a36307a400711a1d7e6868bd5f89a24e63439fb5b6747660323e4475
67
- assets/shaders/stretch_effect.frag,1781382132431,1a7d4ac2be40cf0a459dfb390ef08bcd740f37913ffdee8de3c2ea836a18410e
68
- assets/shaders/ink_sparkle.frag,1781382132431,1c8e222328206d1e06754f76fb53947aad38d62180aafad5298a3c6f510b173d
69
- flutter_bootstrap.js,1781382083178,9a838d82fafadf6910ccbc6cdf4df03972abfe7749620e382c8ced856120bd8d
70
- main.dart.js_3.part.js,1781382118356,80b75e3c9ff59756ea8a58318c7886e7a74787b7ed07fad6f7f4b4347d5bdbab
71
- main.dart.js_1.part.js,1781382118351,a6dfa901d3a791b48e70499f583405215d20a4fe2491acd8d670fe0eac71cdaf
72
- assets/NOTICES,1781382132345,a18efc42c5ed99b56481537d0f229ddd3add671c548a893aaf8766f30c854158
73
- main.dart.js,1781382118819,5e7b0cab78a6e7cd653637824e33318f75554c9b5cce4b1ab26299da255247e1
61
+ version.json,1781383075783,1c93a56a819f36903677817066dbda0bae5785563a39d3a0a486246cf67107ac
62
+ flutter_service_worker.js,1781383076286,baeeaf9f4b8e6f40d3b0549429ceb70ca01f120db6a7ef2f60d5809233dc2205
63
+ assets/FontManifest.json,1781383075907,4d84ab517c27984d36f9a3c8be6f2a72788c0c3985c1d5874297fef0a53407ca
64
+ assets/AssetManifest.bin.json,1781383075907,50a11b51c3fc4cbed1b5ec3a4f466c6a6b75c481d08d4782c8191f99bdbdba9c
65
+ assets/AssetManifest.bin,1781383075907,78bccb08a36307a400711a1d7e6868bd5f89a24e63439fb5b6747660323e4475
66
+ assets/shaders/ink_sparkle.frag,1781383075976,1c8e222328206d1e06754f76fb53947aad38d62180aafad5298a3c6f510b173d
67
+ assets/shaders/stretch_effect.frag,1781383075975,1a7d4ac2be40cf0a459dfb390ef08bcd740f37913ffdee8de3c2ea836a18410e
68
+ index.html,1781383002256,bb8142eb84e9e44049957c3edf86006e1ae5f194c397a8326ce505b68fdf58f4
69
+ flutter_bootstrap.js,1781383002244,fb98f6d7235b26ff8bcd0abce3ccbc26619afbc1956fd2bdceeaa847c25f8a4b
70
+ main.dart.js_1.part.js,1781383058280,3d9563d7203157ebfa135f83b8cd2677443bf89b850e8a5adcffe56621b4fc16
71
+ main.dart.js_3.part.js,1781383058289,133184cfaa83a56797dcb74c0b7fce45102298ea9e74f51f4a54ef6beca152c9
72
+ assets/NOTICES,1781383075907,a18efc42c5ed99b56481537d0f229ddd3add671c548a893aaf8766f30c854158
73
+ main.dart.js,1781383059126,b4cd4c8740826a7c4257dc5f49c9a402e5c6338f31eb39de8dd82762fa47be16
@@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
6
6
  import 'package:kasy_kit/components/kasy_app_bar.dart';
7
7
  import 'package:kasy_kit/components/kasy_avatar.dart';
8
8
  import 'package:kasy_kit/components/kasy_avatar_presets.dart';
9
+ import 'package:kasy_kit/components/kasy_tabs.dart';
9
10
  import 'package:kasy_kit/core/theme/theme.dart';
10
11
  import 'package:kasy_kit/core/widgets/kasy_hover.dart';
11
12
  import 'package:kasy_kit/i18n/translations.g.dart';
@@ -60,7 +61,6 @@ class _SidebarColors {
60
61
  required this.border,
61
62
  required this.divider,
62
63
  required this.activeBg,
63
- required this.segmentThumb,
64
64
  required this.textMuted,
65
65
  required this.textActive,
66
66
  required this.logout,
@@ -69,9 +69,9 @@ class _SidebarColors {
69
69
 
70
70
  /// Maps the HeroUI Figma tokens onto the global [KasyColors]:
71
71
  /// `surface → surface`, `foreground → onSurface`, `foreground/muted → muted`,
72
- /// `border → border`, `separator → separator`, `default → surfaceNeutralSoft`
73
- /// (hover/active fill + tabs track), and the selected-tab thumb to the
74
- /// dedicated `segment` token.
72
+ /// `border → border`, `separator → separator`, and `default →
73
+ /// surfaceNeutralSoft` (hover/active fill). The segmented control is the
74
+ /// shared [KasyTabs] component, which owns its own selected-thumb token.
75
75
  factory _SidebarColors.fromContext(BuildContext context) {
76
76
  final c = context.colors;
77
77
  final bool dark = context.isDark;
@@ -83,8 +83,6 @@ class _SidebarColors {
83
83
  divider: c.border,
84
84
  // Hover / active item fill + tabs track + kbd chip (default/default).
85
85
  activeBg: c.surfaceNeutralSoft,
86
- // Selected segment thumb (HeroUI `segment`): lifts off the track.
87
- segmentThumb: c.segment,
88
86
  textMuted: c.muted,
89
87
  textActive: c.onSurface,
90
88
  logout: c.error,
@@ -96,7 +94,6 @@ class _SidebarColors {
96
94
  final Color border;
97
95
  final Color divider;
98
96
  final Color activeBg;
99
- final Color segmentThumb;
100
97
  final Color textMuted;
101
98
  final Color textActive;
102
99
  final Color logout;
@@ -208,6 +205,7 @@ class KasySidebar extends StatefulWidget {
208
205
  this.onLogout,
209
206
  this.initiallyCollapsed = false,
210
207
  this.isDrawer = false,
208
+ this.showSearch = false,
211
209
  this.side = KasySidebarSide.left,
212
210
  this.routes,
213
211
  this.onTapItem,
@@ -260,6 +258,11 @@ class KasySidebar extends StatefulWidget {
260
258
  /// opening the sidebar from an app-bar menu button on a phone.
261
259
  final bool isDrawer;
262
260
 
261
+ /// Whether to pin a ⌘K search row above the footer in connected mode. Opt-in
262
+ /// (off by default) so the live app navigation stays lean; flip it on when the
263
+ /// sidebar should double as a command/search entry point.
264
+ final bool showSearch;
265
+
263
266
  /// The screen edge this sidebar is anchored to.
264
267
  final KasySidebarSide side;
265
268
 
@@ -577,6 +580,15 @@ class _KasySidebarState extends State<KasySidebar> {
577
580
  child: Column(
578
581
  crossAxisAlignment: CrossAxisAlignment.start,
579
582
  children: [
583
+ if (widget.showSearch)
584
+ _buildItemRow(
585
+ c,
586
+ icon: KasyIcons.search,
587
+ label: 'Search',
588
+ isActive: false,
589
+ onTap: () {},
590
+ trailing: [_buildKbd(c)],
591
+ ),
580
592
  _buildNavItem(context, _kHelpItem, c),
581
593
  _buildItemRow(
582
594
  c,
@@ -700,59 +712,15 @@ class _KasySidebarState extends State<KasySidebar> {
700
712
 
701
713
  // ── Segmented tabs (Layers / Assets) ────────────────────────────────────────
702
714
 
715
+ /// The showcase segment is the shared [KasyTabs] component (primary pill,
716
+ /// fill mode) so the sidebar demos the real design-system control rather than
717
+ /// a bespoke copy.
703
718
  Widget _buildTabs(_SidebarColors c) {
704
- return Container(
705
- width: double.infinity,
706
- padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
707
- decoration: BoxDecoration(
708
- color: c.activeBg,
709
- borderRadius: BorderRadius.circular(24),
710
- ),
711
- child: Row(
712
- children: [
713
- _buildTab(c, 'Layers', 0),
714
- const SizedBox(width: 2),
715
- _buildTab(c, 'Assets', 1),
716
- ],
717
- ),
718
- );
719
- }
720
-
721
- Widget _buildTab(_SidebarColors c, String label, int index) {
722
- final bool selected = _showcaseTab == index;
723
- return Expanded(
724
- child: MouseRegion(
725
- cursor: SystemMouseCursors.click,
726
- child: GestureDetector(
727
- behavior: HitTestBehavior.opaque,
728
- onTap: () => setState(() => _showcaseTab = index),
729
- child: AnimatedContainer(
730
- duration: const Duration(milliseconds: 180),
731
- curve: Curves.easeOut,
732
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
733
- alignment: Alignment.center,
734
- decoration: BoxDecoration(
735
- color: selected ? c.segmentThumb : Colors.transparent,
736
- borderRadius: BorderRadius.circular(24),
737
- boxShadow: selected
738
- ? const [
739
- BoxShadow(
740
- color: Color(0x0F000000),
741
- blurRadius: 8,
742
- offset: Offset(0, 2),
743
- ),
744
- ]
745
- : null,
746
- ),
747
- child: Text(
748
- label,
749
- style: context.kasyTextTheme.rowTitle.copyWith(
750
- color: selected ? c.textActive : c.textMuted,
751
- ),
752
- ),
753
- ),
754
- ),
755
- ),
719
+ return KasyTabs(
720
+ tabs: const ['Layers', 'Assets'],
721
+ selectedIndex: _showcaseTab,
722
+ onTabSelected: (index) => setState(() => _showcaseTab = index),
723
+ mode: KasyTabsMode.fill,
756
724
  );
757
725
  }
758
726
 
@@ -555,16 +555,24 @@ ComponentPreviewDefinition? getComponentPreviewDefinition(
555
555
  title: 'Sidebar',
556
556
  variants: [
557
557
  ComponentPreviewVariant(
558
- label: 'Expanded',
559
- builder: _buildSidebarExpanded,
558
+ label: 'App navigation',
559
+ builder: _buildSidebarAppNav,
560
560
  ),
561
561
  ComponentPreviewVariant(
562
- label: 'Collapsed',
562
+ label: 'With search',
563
+ builder: _buildSidebarWithSearch,
564
+ ),
565
+ ComponentPreviewVariant(
566
+ label: 'Collapsed rail',
563
567
  builder: _buildSidebarCollapsed,
564
568
  ),
565
569
  ComponentPreviewVariant(
566
- label: 'Without profile',
567
- builder: _buildSidebarNoProfile,
570
+ label: 'Mobile drawer',
571
+ builder: _buildSidebarMobileDrawer,
572
+ ),
573
+ ComponentPreviewVariant(
574
+ label: 'Workspace showcase',
575
+ builder: _buildSidebarShowcase,
568
576
  ),
569
577
  ],
570
578
  );
@@ -621,63 +629,67 @@ ComponentPreviewDefinition? getComponentPreviewDefinition(
621
629
  // Sidebar — interactive preview
622
630
  // ─────────────────────────────────────────────────────────────────────────────
623
631
 
624
- Widget _buildSidebarExpanded(BuildContext context) =>
625
- const _SidebarPreview(initiallyCollapsed: false);
632
+ // The live Home configuration (real pages, highlight-only nav). The default
633
+ // preview — what actually ships in the app.
634
+ Widget _buildSidebarAppNav(BuildContext context) => const _SidebarPreview();
635
+
636
+ // Same Home config plus the opt-in ⌘K search row pinned above the footer.
637
+ Widget _buildSidebarWithSearch(BuildContext context) =>
638
+ const _SidebarPreview(showSearch: true);
626
639
 
640
+ // Home config starting as the narrow icon rail (tooltips on hover).
627
641
  Widget _buildSidebarCollapsed(BuildContext context) =>
628
642
  const _SidebarPreview(initiallyCollapsed: true);
629
643
 
630
- Widget _buildSidebarNoProfile(BuildContext context) =>
631
- const _SidebarPreview(initiallyCollapsed: false, showProfile: false);
644
+ // The mobile pattern: always wide, collapse toggle hidden (isDrawer).
645
+ Widget _buildSidebarMobileDrawer(BuildContext context) =>
646
+ const _SidebarPreview(isDrawer: true);
647
+
648
+ // The rich SaaS showcase (workspace selector, KasyTabs segment, layers list).
649
+ Widget _buildSidebarShowcase(BuildContext context) =>
650
+ const _SidebarPreview(showcase: true);
632
651
 
652
+ /// Launches a [KasySidebar] as a full-height drawer (left + right buttons) so
653
+ /// the full-bleed chrome can be inspected without crushing the preview card.
654
+ /// Connected variants mirror the live Home; [showcase] swaps to the HeroUI
655
+ /// workspace demo.
633
656
  class _SidebarPreview extends StatelessWidget {
634
657
  const _SidebarPreview({
635
- required this.initiallyCollapsed,
636
- this.showProfile = true,
658
+ this.showcase = false,
659
+ this.initiallyCollapsed = false,
660
+ this.isDrawer = false,
661
+ this.showSearch = false,
637
662
  });
638
663
 
664
+ final bool showcase;
639
665
  final bool initiallyCollapsed;
640
- final bool showProfile;
641
-
642
- void _open(BuildContext context, {required bool fromEnd}) {
643
- showGeneralDialog<void>(
644
- context: context,
645
- barrierDismissible: true,
646
- barrierLabel: 'Dismiss',
647
- barrierColor: Colors.black.withValues(alpha: 0.42),
648
- transitionDuration: const Duration(milliseconds: 290),
649
- pageBuilder: (ctx, anim, secAnim) => Align(
650
- alignment: fromEnd ? Alignment.centerRight : Alignment.centerLeft,
651
- child: SizedBox(
652
- height: double.infinity,
653
- child: KasySidebar(
654
- initiallyCollapsed: initiallyCollapsed,
655
- showProfile: showProfile,
656
- side: fromEnd
657
- ? KasySidebarSide.right
658
- : KasySidebarSide.left,
659
- ),
660
- ),
661
- ),
662
- transitionBuilder: (ctx, anim, secAnim, child) {
663
- final curved = CurvedAnimation(
664
- parent: anim,
665
- curve: Curves.easeOutCubic,
666
- );
667
- return SlideTransition(
668
- position: Tween<Offset>(
669
- begin: Offset(fromEnd ? 1.0 : -1.0, 0),
670
- end: Offset.zero,
671
- ).animate(curved),
672
- child: FadeTransition(
673
- opacity: Tween<double>(begin: 0.85, end: 1.0).animate(curved),
674
- child: child,
675
- ),
676
- );
677
- },
666
+ final bool isDrawer;
667
+ final bool showSearch;
668
+
669
+ Widget _sidebar({required bool fromEnd}) {
670
+ final KasySidebarSide side =
671
+ fromEnd ? KasySidebarSide.right : KasySidebarSide.left;
672
+ if (showcase) {
673
+ return KasySidebar(
674
+ initiallyCollapsed: initiallyCollapsed,
675
+ side: side,
676
+ );
677
+ }
678
+ return _DemoSidebar(
679
+ isDrawer: isDrawer,
680
+ initiallyCollapsed: initiallyCollapsed,
681
+ showSearch: showSearch,
682
+ side: side,
678
683
  );
679
684
  }
680
685
 
686
+ void _open(BuildContext context, {required bool fromEnd}) =>
687
+ _openSidebarDrawer(
688
+ context,
689
+ fromEnd: fromEnd,
690
+ child: _sidebar(fromEnd: fromEnd),
691
+ );
692
+
681
693
  @override
682
694
  Widget build(BuildContext context) {
683
695
  return Column(
@@ -714,9 +726,17 @@ class _SidebarPreview extends StatelessWidget {
714
726
  /// highlight-only navigation, so the showcase mirrors the actual app. Shared by
715
727
  /// the sidebar previews and the app-bar drawer demo.
716
728
  class _DemoSidebar extends StatefulWidget {
717
- const _DemoSidebar({this.isDrawer = false});
729
+ const _DemoSidebar({
730
+ this.isDrawer = false,
731
+ this.initiallyCollapsed = false,
732
+ this.showSearch = false,
733
+ this.side = KasySidebarSide.left,
734
+ });
718
735
 
719
736
  final bool isDrawer;
737
+ final bool initiallyCollapsed;
738
+ final bool showSearch;
739
+ final KasySidebarSide side;
720
740
 
721
741
  @override
722
742
  State<_DemoSidebar> createState() => _DemoSidebarState();
@@ -763,6 +783,9 @@ class _DemoSidebarState extends State<_DemoSidebar> {
763
783
  currentItem: _current,
764
784
  onTapItem: (i) => _current.value = i, // highlight only
765
785
  isDrawer: widget.isDrawer,
786
+ initiallyCollapsed: widget.initiallyCollapsed,
787
+ showSearch: widget.showSearch,
788
+ side: widget.side,
766
789
  );
767
790
  }
768
791
  }