@fayz-ai/ui 0.8.2 → 0.8.3
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/dist/{chunk-J3IUFUNR.js → chunk-2GDQUARM.js} +3 -3
- package/dist/{chunk-J3IUFUNR.js.map → chunk-2GDQUARM.js.map} +1 -1
- package/dist/{chunk-W5O2X277.js → chunk-A7O7KGNL.js} +8 -4
- package/dist/chunk-A7O7KGNL.js.map +1 -0
- package/dist/{chunk-FY7OZNKU.js → chunk-BVF2KPTT.js} +7 -7
- package/dist/{chunk-FY7OZNKU.js.map → chunk-BVF2KPTT.js.map} +1 -1
- package/dist/{chunk-MZZMZYSE.js → chunk-ID2HQK2Q.js} +328 -51
- package/dist/chunk-ID2HQK2Q.js.map +1 -0
- package/dist/{chunk-ODY3GZ3Y.cjs → chunk-MI6FOB4O.cjs} +7 -7
- package/dist/{chunk-ODY3GZ3Y.cjs.map → chunk-MI6FOB4O.cjs.map} +1 -1
- package/dist/{chunk-IEYCOJTY.cjs → chunk-SVVKUMSL.cjs} +6 -6
- package/dist/{chunk-IEYCOJTY.cjs.map → chunk-SVVKUMSL.cjs.map} +1 -1
- package/dist/{chunk-NWPMNPGR.cjs → chunk-WF3STNDX.cjs} +38 -34
- package/dist/chunk-WF3STNDX.cjs.map +1 -0
- package/dist/{chunk-XAOGMWLC.cjs → chunk-XIRJGVDK.cjs} +325 -48
- package/dist/chunk-XIRJGVDK.cjs.map +1 -0
- package/dist/dashboard/OnboardingWidget.d.ts.map +1 -1
- package/dist/dashboard/index.cjs +26 -26
- package/dist/dashboard/index.js +2 -2
- package/dist/index.cjs +122 -122
- package/dist/index.js +4 -4
- package/dist/layout/AppShell.d.ts +41 -1
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/ModulePage.d.ts +9 -6
- package/dist/layout/ModulePage.d.ts.map +1 -1
- package/dist/layout/Sidebar.d.ts +20 -1
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Topbar.d.ts +13 -1
- package/dist/layout/Topbar.d.ts.map +1 -1
- package/dist/layout/index.cjs +19 -19
- package/dist/layout/index.js +1 -1
- package/dist/primitives/data-table.d.ts.map +1 -1
- package/dist/primitives/index.cjs +77 -77
- package/dist/primitives/index.js +2 -2
- package/package.json +3 -3
- package/src/dashboard/OnboardingWidget.tsx +10 -1
- package/src/layout/AppShell.tsx +255 -7
- package/src/layout/ModulePage.tsx +32 -3
- package/src/layout/Sidebar.tsx +132 -35
- package/src/layout/Topbar.tsx +51 -4
- package/src/primitives/data-table.tsx +10 -1
- package/src/styles.css +34 -0
- package/dist/chunk-MZZMZYSE.js.map +0 -1
- package/dist/chunk-NWPMNPGR.cjs.map +0 -1
- package/dist/chunk-W5O2X277.js.map +0 -1
- package/dist/chunk-XAOGMWLC.cjs.map +0 -1
|
@@ -128,8 +128,17 @@ var ICON_MAP = {
|
|
|
128
128
|
Workflow: lucideReact.Workflow,
|
|
129
129
|
Boxes: lucideReact.Boxes,
|
|
130
130
|
Clock3: lucideReact.Clock3,
|
|
131
|
-
FileCheck2: lucideReact.FileCheck2
|
|
131
|
+
FileCheck2: lucideReact.FileCheck2,
|
|
132
|
+
GraduationCap: lucideReact.GraduationCap,
|
|
133
|
+
Repeat: lucideReact.Repeat,
|
|
134
|
+
User: lucideReact.User,
|
|
135
|
+
Palette: lucideReact.Palette,
|
|
136
|
+
ShieldCheck: lucideReact.ShieldCheck,
|
|
137
|
+
SlidersHorizontal: lucideReact.SlidersHorizontal,
|
|
138
|
+
Puzzle: lucideReact.Puzzle
|
|
132
139
|
};
|
|
140
|
+
var RAIL_PUSH_MS = 260;
|
|
141
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React3__namespace.useLayoutEffect : React3__namespace.useEffect;
|
|
133
142
|
function getIcon(name) {
|
|
134
143
|
return ICON_MAP[name] ?? lucideReact.Home;
|
|
135
144
|
}
|
|
@@ -154,6 +163,7 @@ function NavItem({
|
|
|
154
163
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
155
164
|
!collapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
156
165
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate text-left", children: item.label }),
|
|
166
|
+
item.premium && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Crown, { className: "ml-auto h-3.5 w-3.5 shrink-0 text-amber-500", "aria-hidden": true }),
|
|
157
167
|
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto rounded-full bg-primary px-2 py-0.5 text-xs font-semibold text-primary-foreground", children: item.badge })
|
|
158
168
|
] })
|
|
159
169
|
]
|
|
@@ -170,6 +180,7 @@ function NavItem({
|
|
|
170
180
|
className: "fayz-glass-surface z-50 rounded-md bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md",
|
|
171
181
|
children: [
|
|
172
182
|
item.label,
|
|
183
|
+
item.premium && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Crown, { className: "ml-1.5 inline h-3 w-3 text-amber-500", "aria-hidden": true }),
|
|
173
184
|
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 rounded-full bg-primary px-1.5 py-0.5 text-xs text-primary-foreground", children: item.badge }),
|
|
174
185
|
/* @__PURE__ */ jsxRuntime.jsx(Tooltip__namespace.Arrow, { className: "fill-popover" })
|
|
175
186
|
]
|
|
@@ -282,7 +293,10 @@ function Sidebar({
|
|
|
282
293
|
borderless,
|
|
283
294
|
userMenuSlot,
|
|
284
295
|
notificationSlot,
|
|
285
|
-
unreadCount = 0
|
|
296
|
+
unreadCount = 0,
|
|
297
|
+
sectionLabels,
|
|
298
|
+
navKey,
|
|
299
|
+
navDirection = "forward"
|
|
286
300
|
}) {
|
|
287
301
|
const currentPath = currentPathProp;
|
|
288
302
|
const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
|
|
@@ -293,6 +307,47 @@ function Sidebar({
|
|
|
293
307
|
const handleNavigate = (route) => {
|
|
294
308
|
onNavigate?.(route);
|
|
295
309
|
};
|
|
310
|
+
const sectionHeading = (label) => label && !collapsed ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "px-2.5 pb-1 pt-1 text-[10px] font-semibold uppercase tracking-wider text-sidebar-muted", children: label }) : null;
|
|
311
|
+
const renderItem = (item) => item.children && item.children.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(NavGroup, { item, collapsed, activeRoute, onNavigate: handleNavigate }, item.id) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
312
|
+
NavItem,
|
|
313
|
+
{
|
|
314
|
+
item,
|
|
315
|
+
collapsed,
|
|
316
|
+
isActive: item.route === activeRoute,
|
|
317
|
+
onNavigate: handleNavigate
|
|
318
|
+
},
|
|
319
|
+
item.id
|
|
320
|
+
);
|
|
321
|
+
const navBody = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
322
|
+
topContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 space-y-2", children: topContent }),
|
|
323
|
+
mainItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
324
|
+
sectionHeading(sectionLabels?.main),
|
|
325
|
+
mainItems.map(renderItem)
|
|
326
|
+
] }),
|
|
327
|
+
secondaryItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 space-y-1", children: [
|
|
328
|
+
sectionHeading(sectionLabels?.secondary),
|
|
329
|
+
secondaryItems.map(renderItem)
|
|
330
|
+
] })
|
|
331
|
+
] });
|
|
332
|
+
const [outgoing, setOutgoing] = React3__namespace.useState(null);
|
|
333
|
+
const lastBodyRef = React3__namespace.useRef(null);
|
|
334
|
+
const lastKeyRef = React3__namespace.useRef(navKey);
|
|
335
|
+
const timerRef = React3__namespace.useRef(null);
|
|
336
|
+
useIsomorphicLayoutEffect(() => {
|
|
337
|
+
if (lastKeyRef.current !== navKey) {
|
|
338
|
+
const previousBody = lastBodyRef.current;
|
|
339
|
+
lastKeyRef.current = navKey;
|
|
340
|
+
if (previousBody) {
|
|
341
|
+
setOutgoing({ body: previousBody, direction: navDirection });
|
|
342
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
343
|
+
timerRef.current = setTimeout(() => setOutgoing(null), RAIL_PUSH_MS);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
lastBodyRef.current = navBody;
|
|
347
|
+
});
|
|
348
|
+
React3__namespace.useEffect(() => () => {
|
|
349
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
350
|
+
}, []);
|
|
296
351
|
return /* @__PURE__ */ jsxRuntime.jsx(Tooltip__namespace.Provider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
297
352
|
"aside",
|
|
298
353
|
{
|
|
@@ -336,33 +391,39 @@ function Sidebar({
|
|
|
336
391
|
]
|
|
337
392
|
}
|
|
338
393
|
),
|
|
339
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
394
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
395
|
+
"nav",
|
|
396
|
+
{
|
|
397
|
+
className: chunkH6OULCHF_cjs.cn(
|
|
398
|
+
"relative flex-1 p-2",
|
|
399
|
+
outgoing ? "overflow-hidden" : "overflow-y-auto"
|
|
400
|
+
),
|
|
401
|
+
children: [
|
|
402
|
+
outgoing && /* @__PURE__ */ jsxRuntime.jsx(
|
|
403
|
+
"div",
|
|
404
|
+
{
|
|
405
|
+
"aria-hidden": true,
|
|
406
|
+
className: chunkH6OULCHF_cjs.cn(
|
|
407
|
+
"pointer-events-none absolute inset-x-2 top-2 space-y-1",
|
|
408
|
+
outgoing.direction === "back" ? "saas-rail-out-back" : "saas-rail-out-forward"
|
|
409
|
+
),
|
|
410
|
+
children: outgoing.body
|
|
411
|
+
}
|
|
412
|
+
),
|
|
413
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
414
|
+
"div",
|
|
415
|
+
{
|
|
416
|
+
className: chunkH6OULCHF_cjs.cn(
|
|
417
|
+
"space-y-1",
|
|
418
|
+
outgoing && (outgoing.direction === "back" ? "saas-rail-in-back" : "saas-rail-in-forward")
|
|
419
|
+
),
|
|
420
|
+
children: navBody
|
|
421
|
+
},
|
|
422
|
+
navKey
|
|
423
|
+
)
|
|
424
|
+
]
|
|
425
|
+
}
|
|
426
|
+
),
|
|
366
427
|
settingsItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("p-2 space-y-1", !borderless && "border-t border-sidebar-border"), children: settingsItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
367
428
|
NavItem,
|
|
368
429
|
{
|
|
@@ -408,6 +469,8 @@ function Sidebar({
|
|
|
408
469
|
}
|
|
409
470
|
function TopbarUserMenu({
|
|
410
471
|
user,
|
|
472
|
+
userPlan,
|
|
473
|
+
billingLabel = "Subscription",
|
|
411
474
|
onSignOut,
|
|
412
475
|
onProfile,
|
|
413
476
|
onSettings,
|
|
@@ -458,11 +521,35 @@ function TopbarUserMenu({
|
|
|
458
521
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 space-y-0.5", children: [
|
|
459
522
|
item("Perfil", onProfile, lucideReact.UserCog),
|
|
460
523
|
item("Configura\xE7\xF5es", onSettings, lucideReact.Settings),
|
|
461
|
-
|
|
524
|
+
onBilling && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
525
|
+
"button",
|
|
526
|
+
{
|
|
527
|
+
onClick: () => {
|
|
528
|
+
setOpen(false);
|
|
529
|
+
onBilling();
|
|
530
|
+
},
|
|
531
|
+
className: "flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-sm text-popover-foreground transition-colors hover:bg-muted/70",
|
|
532
|
+
children: [
|
|
533
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCard, { className: "h-4 w-4 text-muted-foreground" }),
|
|
534
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-left", children: billingLabel }),
|
|
535
|
+
userPlan && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
536
|
+
"span",
|
|
537
|
+
{
|
|
538
|
+
className: userPlan.paid ? "inline-flex items-center gap-1 rounded-full border border-amber-400/40 bg-amber-400/15 px-2 py-0.5 text-[10px] font-semibold text-amber-600 dark:text-amber-300" : "inline-flex items-center gap-1 rounded-full border border-border bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground",
|
|
539
|
+
children: [
|
|
540
|
+
userPlan.paid ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Crown, { className: "h-3 w-3" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3 w-3" }),
|
|
541
|
+
userPlan.label
|
|
542
|
+
]
|
|
543
|
+
}
|
|
544
|
+
)
|
|
545
|
+
]
|
|
546
|
+
},
|
|
547
|
+
"billing"
|
|
548
|
+
),
|
|
462
549
|
userMenuExtras?.map((e) => item(e.label, e.onClick)),
|
|
463
550
|
onSignOut && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
464
551
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-1 border-t border-border" }),
|
|
465
|
-
item("Sair", onSignOut)
|
|
552
|
+
item("Sair", onSignOut, lucideReact.LogOut)
|
|
466
553
|
] })
|
|
467
554
|
] })
|
|
468
555
|
]
|
|
@@ -570,7 +657,9 @@ var ICON_MAP2 = {
|
|
|
570
657
|
Star: lucideReact.Star,
|
|
571
658
|
Zap: lucideReact.Zap,
|
|
572
659
|
Clapperboard: lucideReact.Clapperboard,
|
|
573
|
-
Newspaper: lucideReact.Newspaper
|
|
660
|
+
Newspaper: lucideReact.Newspaper,
|
|
661
|
+
GraduationCap: lucideReact.GraduationCap,
|
|
662
|
+
Repeat: lucideReact.Repeat
|
|
574
663
|
};
|
|
575
664
|
function getIcon2(name) {
|
|
576
665
|
return ICON_MAP2[name] ?? lucideReact.Home;
|
|
@@ -634,6 +723,7 @@ function Topbar({
|
|
|
634
723
|
logo,
|
|
635
724
|
user,
|
|
636
725
|
onMenuClick,
|
|
726
|
+
orgSwitcher,
|
|
637
727
|
leftContent,
|
|
638
728
|
rightContent,
|
|
639
729
|
currentPath = "/",
|
|
@@ -643,6 +733,8 @@ function Topbar({
|
|
|
643
733
|
onProfile,
|
|
644
734
|
onSettings,
|
|
645
735
|
onBilling,
|
|
736
|
+
userPlan,
|
|
737
|
+
billingLabel,
|
|
646
738
|
userMenuExtras
|
|
647
739
|
}) {
|
|
648
740
|
const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
|
|
@@ -664,7 +756,8 @@ function Topbar({
|
|
|
664
756
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "h-5 w-5" })
|
|
665
757
|
}
|
|
666
758
|
),
|
|
667
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden shrink-0 items-center md:flex", children: logo ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-bold", children: "App" }) })
|
|
759
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden shrink-0 items-center md:flex", children: logo ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-bold", children: "App" }) }),
|
|
760
|
+
orgSwitcher && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden min-w-0 items-center md:flex", children: orgSwitcher })
|
|
668
761
|
] }),
|
|
669
762
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-8 hidden max-w-sm flex-1 md:flex", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
670
763
|
"button",
|
|
@@ -685,6 +778,8 @@ function Topbar({
|
|
|
685
778
|
TopbarUserMenu,
|
|
686
779
|
{
|
|
687
780
|
user,
|
|
781
|
+
userPlan,
|
|
782
|
+
billingLabel,
|
|
688
783
|
onSignOut,
|
|
689
784
|
onProfile,
|
|
690
785
|
onSettings,
|
|
@@ -727,6 +822,7 @@ function Topbar({
|
|
|
727
822
|
children: [
|
|
728
823
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4" }),
|
|
729
824
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label }),
|
|
825
|
+
item.premium && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Crown, { className: "h-3 w-3 text-amber-500", "aria-hidden": true }),
|
|
730
826
|
item.badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-primary px-1.5 py-0.5 text-[10px] font-semibold text-primary-foreground", children: item.badge })
|
|
731
827
|
]
|
|
732
828
|
},
|
|
@@ -766,7 +862,10 @@ function SidebarLayout({
|
|
|
766
862
|
notificationSlot,
|
|
767
863
|
unreadCount = 0,
|
|
768
864
|
hasBottomNav = false,
|
|
769
|
-
mobileHeader = "minimal"
|
|
865
|
+
mobileHeader = "minimal",
|
|
866
|
+
sidebarSectionLabels,
|
|
867
|
+
sidebarNavKey,
|
|
868
|
+
sidebarNavDirection
|
|
770
869
|
}) {
|
|
771
870
|
const sidebarCollapsed = useLayoutStore((s) => s.sidebarCollapsed);
|
|
772
871
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
@@ -800,7 +899,10 @@ function SidebarLayout({
|
|
|
800
899
|
borderless: false,
|
|
801
900
|
userMenuSlot,
|
|
802
901
|
notificationSlot,
|
|
803
|
-
unreadCount
|
|
902
|
+
unreadCount,
|
|
903
|
+
sectionLabels: sidebarSectionLabels,
|
|
904
|
+
navKey: sidebarNavKey,
|
|
905
|
+
navDirection: sidebarNavDirection
|
|
804
906
|
}
|
|
805
907
|
) }),
|
|
806
908
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn(
|
|
@@ -830,7 +932,7 @@ function SidebarLayout({
|
|
|
830
932
|
topbarEnd
|
|
831
933
|
] })
|
|
832
934
|
] }),
|
|
833
|
-
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children }),
|
|
935
|
+
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "min-w-0 flex-1 overflow-y-auto pb-16 md:pb-0", children }),
|
|
834
936
|
/* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.SaveBar, {})
|
|
835
937
|
] }),
|
|
836
938
|
mobileMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -866,11 +968,15 @@ function TopbarLayout({
|
|
|
866
968
|
onProfile,
|
|
867
969
|
onSettings,
|
|
868
970
|
onBilling,
|
|
971
|
+
userPlan,
|
|
972
|
+
billingLabel,
|
|
869
973
|
userMenuExtras,
|
|
974
|
+
orgSwitcher,
|
|
870
975
|
frame,
|
|
871
976
|
currentPath,
|
|
872
977
|
topbarStart,
|
|
873
978
|
topbarEnd,
|
|
979
|
+
notificationSlot,
|
|
874
980
|
hasBottomNav = false
|
|
875
981
|
}) {
|
|
876
982
|
const [mobileMenuOpen, setMobileMenuOpen] = React3__namespace.useState(false);
|
|
@@ -887,13 +993,19 @@ function TopbarLayout({
|
|
|
887
993
|
onProfile,
|
|
888
994
|
onSettings,
|
|
889
995
|
onBilling,
|
|
996
|
+
userPlan,
|
|
997
|
+
billingLabel,
|
|
890
998
|
userMenuExtras,
|
|
999
|
+
orgSwitcher,
|
|
891
1000
|
leftContent: topbarStart,
|
|
892
|
-
rightContent: topbarEnd,
|
|
1001
|
+
rightContent: topbarEnd || notificationSlot ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1002
|
+
topbarEnd,
|
|
1003
|
+
notificationSlot
|
|
1004
|
+
] }) : void 0,
|
|
893
1005
|
onMenuClick: hasBottomNav ? void 0 : () => setMobileMenuOpen(true)
|
|
894
1006
|
}
|
|
895
1007
|
),
|
|
896
|
-
/* @__PURE__ */ jsxRuntime.jsx("main", { className: chunkH6OULCHF_cjs.cn("flex-
|
|
1008
|
+
/* @__PURE__ */ jsxRuntime.jsx("main", { className: chunkH6OULCHF_cjs.cn("flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden", frame && "md:bg-sidebar md:p-2"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkH6OULCHF_cjs.cn("flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden", frame && "md:rounded-xl md:border md:border-border md:bg-card"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 flex-1 overflow-y-auto pb-16 md:pb-0", children }) }) }),
|
|
897
1009
|
/* @__PURE__ */ jsxRuntime.jsx(chunkOW73RZOU_cjs.SaveBar, {}),
|
|
898
1010
|
mobileMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
899
1011
|
MobileOverlay,
|
|
@@ -907,6 +1019,7 @@ function TopbarLayout({
|
|
|
907
1019
|
onProfile,
|
|
908
1020
|
onSettings,
|
|
909
1021
|
onBilling,
|
|
1022
|
+
orgSwitcher,
|
|
910
1023
|
userMenuSlot: user ? /* @__PURE__ */ jsxRuntime.jsx(DrawerUserRow, { user }) : void 0,
|
|
911
1024
|
onClose: () => setMobileMenuOpen(false)
|
|
912
1025
|
}
|
|
@@ -931,7 +1044,7 @@ function MinimalLayout({
|
|
|
931
1044
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: logo ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-bold", children: "App" }) }),
|
|
932
1045
|
headerEnd && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: headerEnd })
|
|
933
1046
|
] }),
|
|
934
|
-
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children })
|
|
1047
|
+
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "min-w-0 flex-1 overflow-y-auto pb-16 md:pb-0", children })
|
|
935
1048
|
] });
|
|
936
1049
|
}
|
|
937
1050
|
function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
|
|
@@ -1081,6 +1194,8 @@ function AppShell({
|
|
|
1081
1194
|
onProfile,
|
|
1082
1195
|
onSettings,
|
|
1083
1196
|
onBilling,
|
|
1197
|
+
userPlan,
|
|
1198
|
+
billingLabel,
|
|
1084
1199
|
pageTitle,
|
|
1085
1200
|
currentPath,
|
|
1086
1201
|
userMenuExtras,
|
|
@@ -1094,7 +1209,17 @@ function AppShell({
|
|
|
1094
1209
|
mobileHeader = "minimal",
|
|
1095
1210
|
userMenuSlot,
|
|
1096
1211
|
notificationSlot,
|
|
1097
|
-
unreadCount = 0
|
|
1212
|
+
unreadCount = 0,
|
|
1213
|
+
sidebarSectionLabels,
|
|
1214
|
+
sidebarNavKey,
|
|
1215
|
+
sidebarNavDirection,
|
|
1216
|
+
rightRail,
|
|
1217
|
+
rightRailOpen = true,
|
|
1218
|
+
defaultRightRailWidth,
|
|
1219
|
+
onRightRailWidthChange,
|
|
1220
|
+
rightRailMinWidth,
|
|
1221
|
+
rightRailMaxWidth,
|
|
1222
|
+
rightRailResizeLabel
|
|
1098
1223
|
}) {
|
|
1099
1224
|
const hasBottomNav = !!bottomNav?.length;
|
|
1100
1225
|
const bottomBar = hasBottomNav ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1135,6 +1260,9 @@ function AppShell({
|
|
|
1135
1260
|
unreadCount,
|
|
1136
1261
|
hasBottomNav,
|
|
1137
1262
|
mobileHeader,
|
|
1263
|
+
sidebarSectionLabels,
|
|
1264
|
+
sidebarNavKey,
|
|
1265
|
+
sidebarNavDirection,
|
|
1138
1266
|
children
|
|
1139
1267
|
}
|
|
1140
1268
|
);
|
|
@@ -1151,11 +1279,15 @@ function AppShell({
|
|
|
1151
1279
|
onProfile,
|
|
1152
1280
|
onSettings,
|
|
1153
1281
|
onBilling,
|
|
1282
|
+
userPlan,
|
|
1283
|
+
billingLabel,
|
|
1154
1284
|
userMenuExtras,
|
|
1285
|
+
orgSwitcher,
|
|
1155
1286
|
frame: contentFrame,
|
|
1156
1287
|
currentPath,
|
|
1157
1288
|
topbarStart,
|
|
1158
1289
|
topbarEnd,
|
|
1290
|
+
notificationSlot,
|
|
1159
1291
|
hasBottomNav,
|
|
1160
1292
|
children
|
|
1161
1293
|
}
|
|
@@ -1169,11 +1301,142 @@ function AppShell({
|
|
|
1169
1301
|
}
|
|
1170
1302
|
}
|
|
1171
1303
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1172
|
-
|
|
1304
|
+
rightRail ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1305
|
+
SplitWithRightRail,
|
|
1306
|
+
{
|
|
1307
|
+
rail: rightRail,
|
|
1308
|
+
open: rightRailOpen,
|
|
1309
|
+
frame: contentFrame,
|
|
1310
|
+
defaultWidth: defaultRightRailWidth,
|
|
1311
|
+
onWidthChange: onRightRailWidthChange,
|
|
1312
|
+
minWidth: rightRailMinWidth,
|
|
1313
|
+
maxWidth: rightRailMaxWidth,
|
|
1314
|
+
resizeLabel: rightRailResizeLabel,
|
|
1315
|
+
children: layoutElement
|
|
1316
|
+
}
|
|
1317
|
+
) : layoutElement,
|
|
1173
1318
|
floatingAvatar,
|
|
1174
1319
|
bottomBar
|
|
1175
1320
|
] });
|
|
1176
1321
|
}
|
|
1322
|
+
function SplitWithRightRail({
|
|
1323
|
+
children,
|
|
1324
|
+
rail,
|
|
1325
|
+
open,
|
|
1326
|
+
frame,
|
|
1327
|
+
defaultWidth = 380,
|
|
1328
|
+
onWidthChange,
|
|
1329
|
+
minWidth = 300,
|
|
1330
|
+
maxWidth = 720,
|
|
1331
|
+
resizeLabel = "Resize panel"
|
|
1332
|
+
}) {
|
|
1333
|
+
const [width, setWidth] = React3__namespace.useState(defaultWidth);
|
|
1334
|
+
const [dragging, setDragging] = React3__namespace.useState(false);
|
|
1335
|
+
const clamp = React3__namespace.useCallback(
|
|
1336
|
+
(value) => Math.min(maxWidth, Math.max(minWidth, value)),
|
|
1337
|
+
[minWidth, maxWidth]
|
|
1338
|
+
);
|
|
1339
|
+
React3__namespace.useEffect(() => {
|
|
1340
|
+
if (!dragging) return;
|
|
1341
|
+
const onMove = (event) => {
|
|
1342
|
+
event.preventDefault();
|
|
1343
|
+
setWidth(clamp(window.innerWidth - event.clientX));
|
|
1344
|
+
};
|
|
1345
|
+
const stop = () => setDragging(false);
|
|
1346
|
+
window.addEventListener("pointermove", onMove);
|
|
1347
|
+
window.addEventListener("pointerup", stop);
|
|
1348
|
+
window.addEventListener("pointercancel", stop);
|
|
1349
|
+
const previousSelect = document.body.style.userSelect;
|
|
1350
|
+
const previousCursor = document.body.style.cursor;
|
|
1351
|
+
document.body.style.userSelect = "none";
|
|
1352
|
+
document.body.style.cursor = "col-resize";
|
|
1353
|
+
return () => {
|
|
1354
|
+
window.removeEventListener("pointermove", onMove);
|
|
1355
|
+
window.removeEventListener("pointerup", stop);
|
|
1356
|
+
window.removeEventListener("pointercancel", stop);
|
|
1357
|
+
document.body.style.userSelect = previousSelect;
|
|
1358
|
+
document.body.style.cursor = previousCursor;
|
|
1359
|
+
};
|
|
1360
|
+
}, [dragging, clamp]);
|
|
1361
|
+
React3__namespace.useEffect(() => {
|
|
1362
|
+
if (dragging) return;
|
|
1363
|
+
onWidthChange?.(width);
|
|
1364
|
+
}, [dragging]);
|
|
1365
|
+
const nudge = (delta) => setWidth((current) => clamp(current + delta));
|
|
1366
|
+
return (
|
|
1367
|
+
// Sidebar tone always: the gutter and the divider sit in the shell's
|
|
1368
|
+
// chrome, next to the menu — painting them page-white put a bright strip
|
|
1369
|
+
// between the dark chrome and the rail, which read as a seam rather than
|
|
1370
|
+
// as space.
|
|
1371
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkH6OULCHF_cjs.cn("flex h-screen w-full overflow-hidden bg-sidebar", !frame && "md:bg-background"), children: [
|
|
1372
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children }),
|
|
1373
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1374
|
+
"div",
|
|
1375
|
+
{
|
|
1376
|
+
role: "separator",
|
|
1377
|
+
"aria-orientation": "vertical",
|
|
1378
|
+
"aria-label": resizeLabel,
|
|
1379
|
+
"aria-valuenow": width,
|
|
1380
|
+
"aria-valuemin": minWidth,
|
|
1381
|
+
"aria-valuemax": maxWidth,
|
|
1382
|
+
tabIndex: 0,
|
|
1383
|
+
onPointerDown: (event) => {
|
|
1384
|
+
event.preventDefault();
|
|
1385
|
+
setDragging(true);
|
|
1386
|
+
},
|
|
1387
|
+
onDoubleClick: () => setWidth(clamp(defaultWidth)),
|
|
1388
|
+
onKeyDown: (event) => {
|
|
1389
|
+
if (event.key === "ArrowLeft") {
|
|
1390
|
+
event.preventDefault();
|
|
1391
|
+
nudge(24);
|
|
1392
|
+
} else if (event.key === "ArrowRight") {
|
|
1393
|
+
event.preventDefault();
|
|
1394
|
+
nudge(-24);
|
|
1395
|
+
} else if (event.key === "Home") {
|
|
1396
|
+
event.preventDefault();
|
|
1397
|
+
setWidth(maxWidth);
|
|
1398
|
+
} else if (event.key === "End") {
|
|
1399
|
+
event.preventDefault();
|
|
1400
|
+
setWidth(minWidth);
|
|
1401
|
+
}
|
|
1402
|
+
},
|
|
1403
|
+
className: chunkH6OULCHF_cjs.cn(
|
|
1404
|
+
"group relative hidden w-1 shrink-0 cursor-col-resize focus-visible:outline-none",
|
|
1405
|
+
open && "md:block"
|
|
1406
|
+
),
|
|
1407
|
+
children: [
|
|
1408
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1409
|
+
"span",
|
|
1410
|
+
{
|
|
1411
|
+
className: chunkH6OULCHF_cjs.cn(
|
|
1412
|
+
"absolute inset-y-6 left-1/2 w-px -translate-x-1/2 rounded-full bg-transparent transition-colors",
|
|
1413
|
+
"group-hover:bg-primary/60 group-focus-visible:bg-primary",
|
|
1414
|
+
dragging && "bg-primary"
|
|
1415
|
+
)
|
|
1416
|
+
}
|
|
1417
|
+
),
|
|
1418
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-y-0 -left-1.5 -right-1.5" })
|
|
1419
|
+
]
|
|
1420
|
+
}
|
|
1421
|
+
),
|
|
1422
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1423
|
+
"aside",
|
|
1424
|
+
{
|
|
1425
|
+
style: { ["--fayz-rail-w"]: `${width}px` },
|
|
1426
|
+
className: chunkH6OULCHF_cjs.cn(
|
|
1427
|
+
"w-0 shrink-0 overflow-hidden",
|
|
1428
|
+
// Animating WIDTH is what makes the app glide back instead of
|
|
1429
|
+
// snapping; skipped mid-drag so the divider stays glued to the cursor.
|
|
1430
|
+
!dragging && "motion-safe:transition-[width] motion-safe:duration-200 motion-safe:ease-out",
|
|
1431
|
+
open && "md:w-[var(--fayz-rail-w)]",
|
|
1432
|
+
frame && "md:py-2 md:pr-2"
|
|
1433
|
+
),
|
|
1434
|
+
children: rail
|
|
1435
|
+
}
|
|
1436
|
+
)
|
|
1437
|
+
] })
|
|
1438
|
+
);
|
|
1439
|
+
}
|
|
1177
1440
|
var NavTransitionContext = React3__namespace.createContext("slide");
|
|
1178
1441
|
function NavTransitionProvider({ value, children }) {
|
|
1179
1442
|
return /* @__PURE__ */ jsxRuntime.jsx(NavTransitionContext.Provider, { value, children });
|
|
@@ -1203,6 +1466,11 @@ function PageHeaderActions({ children }) {
|
|
|
1203
1466
|
if (slot) return reactDom.createPortal(children, slot);
|
|
1204
1467
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 flex items-center justify-end gap-2", children });
|
|
1205
1468
|
}
|
|
1469
|
+
function PremiumBadge({ className }) {
|
|
1470
|
+
const t = core.useTranslation();
|
|
1471
|
+
const tip = t("upgrade.badgeTooltip");
|
|
1472
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { title: tip, "aria-label": tip, className: chunkH6OULCHF_cjs.cn("inline-flex shrink-0", className), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Crown, { className: "h-3.5 w-3.5 text-amber-500", "aria-hidden": true }) });
|
|
1473
|
+
}
|
|
1206
1474
|
var ModuleLayoutContext = React3__namespace.createContext("rail");
|
|
1207
1475
|
function ModuleLayoutProvider({ variant, children }) {
|
|
1208
1476
|
return /* @__PURE__ */ jsxRuntime.jsx(ModuleLayoutContext.Provider, { value: variant, children });
|
|
@@ -1229,11 +1497,12 @@ function NavItem2({ item }) {
|
|
|
1229
1497
|
children: [
|
|
1230
1498
|
Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
1231
1499
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-left truncate", children: item.label }),
|
|
1500
|
+
item.premium && /* @__PURE__ */ jsxRuntime.jsx(PremiumBadge, { className: "ml-1" }),
|
|
1232
1501
|
hasChildren && (expanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3.5 w-3.5 shrink-0 opacity-50" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-3.5 w-3.5 shrink-0 opacity-50" }))
|
|
1233
1502
|
]
|
|
1234
1503
|
}
|
|
1235
1504
|
),
|
|
1236
|
-
hasChildren && expanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-4 mt-0.5 space-y-0.5 border-l pl-2", children: item.children.map((child) => /* @__PURE__ */ jsxRuntime.
|
|
1505
|
+
hasChildren && expanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-4 mt-0.5 space-y-0.5 border-l pl-2", children: item.children.map((child) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1237
1506
|
"button",
|
|
1238
1507
|
{
|
|
1239
1508
|
type: "button",
|
|
@@ -1242,7 +1511,10 @@ function NavItem2({ item }) {
|
|
|
1242
1511
|
"flex items-center w-full rounded-md px-2.5 py-1 text-xs transition-colors",
|
|
1243
1512
|
child.active ? "text-primary font-medium bg-primary/5" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
|
|
1244
1513
|
),
|
|
1245
|
-
children:
|
|
1514
|
+
children: [
|
|
1515
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-left truncate", children: child.label }),
|
|
1516
|
+
child.premium && /* @__PURE__ */ jsxRuntime.jsx(PremiumBadge, { className: "ml-1" })
|
|
1517
|
+
]
|
|
1246
1518
|
},
|
|
1247
1519
|
child.id
|
|
1248
1520
|
)) })
|
|
@@ -1286,6 +1558,7 @@ function MobileTabs({ nav }) {
|
|
|
1286
1558
|
children: [
|
|
1287
1559
|
Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-3 w-3" }),
|
|
1288
1560
|
item.label,
|
|
1561
|
+
item.premium && /* @__PURE__ */ jsxRuntime.jsx(PremiumBadge, {}),
|
|
1289
1562
|
hasChildren && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: chunkH6OULCHF_cjs.cn("h-2.5 w-2.5 transition-transform", isExpanded && "rotate-180") })
|
|
1290
1563
|
]
|
|
1291
1564
|
},
|
|
@@ -1295,7 +1568,7 @@ function MobileTabs({ nav }) {
|
|
|
1295
1568
|
expandedId && (() => {
|
|
1296
1569
|
const item = nav.find((n) => n.id === expandedId);
|
|
1297
1570
|
if (!item?.children) return null;
|
|
1298
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1 px-2 pb-2 animate-in fade-in-0 slide-in-from-top-1", children: item.children.map((child) => /* @__PURE__ */ jsxRuntime.
|
|
1571
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1 px-2 pb-2 animate-in fade-in-0 slide-in-from-top-1", children: item.children.map((child) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1299
1572
|
"button",
|
|
1300
1573
|
{
|
|
1301
1574
|
type: "button",
|
|
@@ -1307,7 +1580,10 @@ function MobileTabs({ nav }) {
|
|
|
1307
1580
|
"whitespace-nowrap rounded-full px-2.5 py-1 text-[11px] font-medium transition-colors shrink-0",
|
|
1308
1581
|
child.active ? "bg-foreground/10 text-foreground" : "text-muted-foreground hover:text-foreground"
|
|
1309
1582
|
),
|
|
1310
|
-
children:
|
|
1583
|
+
children: [
|
|
1584
|
+
child.label,
|
|
1585
|
+
child.premium && /* @__PURE__ */ jsxRuntime.jsx(PremiumBadge, {})
|
|
1586
|
+
]
|
|
1311
1587
|
},
|
|
1312
1588
|
child.id
|
|
1313
1589
|
)) });
|
|
@@ -1399,7 +1675,8 @@ function ModuleHeader({ nav }) {
|
|
|
1399
1675
|
),
|
|
1400
1676
|
children: [
|
|
1401
1677
|
Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4" }),
|
|
1402
|
-
item.label
|
|
1678
|
+
item.label,
|
|
1679
|
+
item.premium && /* @__PURE__ */ jsxRuntime.jsx(PremiumBadge, {})
|
|
1403
1680
|
]
|
|
1404
1681
|
},
|
|
1405
1682
|
item.id
|
|
@@ -1545,5 +1822,5 @@ exports.useModuleHeaderActionsSlot = useModuleHeaderActionsSlot;
|
|
|
1545
1822
|
exports.useModuleHeaderSlot = useModuleHeaderSlot;
|
|
1546
1823
|
exports.useModuleLayout = useModuleLayout;
|
|
1547
1824
|
exports.useNavTransition = useNavTransition;
|
|
1548
|
-
//# sourceMappingURL=chunk-
|
|
1549
|
-
//# sourceMappingURL=chunk-
|
|
1825
|
+
//# sourceMappingURL=chunk-XIRJGVDK.cjs.map
|
|
1826
|
+
//# sourceMappingURL=chunk-XIRJGVDK.cjs.map
|