@fayz-ai/ui 0.8.1 → 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-OTUH4K4B.js → chunk-2GDQUARM.js} +214 -4
- package/dist/chunk-2GDQUARM.js.map +1 -0
- 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-7PTRAWHO.cjs → chunk-SVVKUMSL.cjs} +217 -6
- package/dist/chunk-SVVKUMSL.cjs.map +1 -0
- 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 +125 -121
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- 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/SearchCombobox.d.ts +38 -0
- package/dist/primitives/SearchCombobox.d.ts.map +1 -0
- package/dist/primitives/data-table.d.ts.map +1 -1
- package/dist/primitives/index.cjs +80 -76
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +2 -2
- package/package.json +3 -3
- package/src/dashboard/OnboardingWidget.tsx +10 -1
- package/src/index.ts +2 -0
- 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/SearchCombobox.tsx +216 -0
- package/src/primitives/data-table.tsx +10 -1
- package/src/primitives/index.ts +1 -0
- package/src/styles.css +34 -0
- package/dist/chunk-7PTRAWHO.cjs.map +0 -1
- package/dist/chunk-MZZMZYSE.js.map +0 -1
- package/dist/chunk-NWPMNPGR.cjs.map +0 -1
- package/dist/chunk-OTUH4K4B.js.map +0 -1
- package/dist/chunk-W5O2X277.js.map +0 -1
- package/dist/chunk-XAOGMWLC.cjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useCrossModuleBack, useBackHandler, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SaveBarProvider, SaveBar } from './chunk-75EFDLST.js';
|
|
2
2
|
import { cn, Button } from './chunk-YRVE4FOD.js';
|
|
3
3
|
import * as React3 from 'react';
|
|
4
|
-
import { FileCheck2, Clock3, Boxes, Workflow, UserX, UserPlus, UserCheck, TrendingUp, Star, Inbox, MessageSquare, LayoutDashboard, Award, Zap, Mic, UsersRound, Disc3, ListMusic, Eye, Music, Layers, CircleDollarSign, Landmark, Banknote, BadgeDollarSign, CalendarX, CalendarCheck2, CalendarDays, Radio, PartyPopper, Wheat, Egg, Apple, LeafyGreen, LayoutTemplate, FolderOpen, Heart, PawPrint, Cat, Dog, Clock, Ban, Shield, Search, ListPlus, List, Plus, Filter, Building2, Contact, Handshake, Map, MapPin, UtensilsCrossed, Camera, Tags, Tag, Percent, Globe, MessageCircle, BookOpenCheck, BookOpen, UserCog, Briefcase, ListChecks, ClipboardList, ShoppingBag, Receipt, Wrench, Target, ShoppingCart, Megaphone, DollarSign, Mail, FileText, BarChart3, Activity, Package, CalendarClock, Calendar, Bell, CreditCard, Settings, Users, Home, PanelLeftClose, PanelLeft, Menu, ChevronRight, ChevronLeft, PanelRightOpen, PanelRightClose, PanelRight, Newspaper, Clapperboard, Box, TreePalm, ArrowDownRight, ArrowUpRight, Ruler, Warehouse, Wallet, Sparkles, AlertTriangle, TableProperties,
|
|
4
|
+
import { Puzzle, SlidersHorizontal, ShieldCheck, Palette, User, Repeat, GraduationCap, FileCheck2, Clock3, Boxes, Workflow, UserX, UserPlus, UserCheck, TrendingUp, Star, Inbox, MessageSquare, LayoutDashboard, Award, Zap, Mic, UsersRound, Disc3, ListMusic, Eye, Music, Layers, CircleDollarSign, Landmark, Banknote, BadgeDollarSign, CalendarX, CalendarCheck2, CalendarDays, Radio, PartyPopper, Wheat, Egg, Apple, LeafyGreen, LayoutTemplate, FolderOpen, Heart, PawPrint, Cat, Dog, Clock, Ban, Shield, Search, ListPlus, List, Plus, Filter, Building2, Contact, Handshake, Map, MapPin, UtensilsCrossed, Camera, Tags, Tag, Percent, Globe, MessageCircle, BookOpenCheck, BookOpen, UserCog, Briefcase, ListChecks, ClipboardList, ShoppingBag, Receipt, Wrench, Target, ShoppingCart, Megaphone, DollarSign, Mail, FileText, BarChart3, Activity, Package, CalendarClock, Calendar, Bell, CreditCard, Settings, Users, Home, PanelLeftClose, PanelLeft, Menu, Crown, ChevronRight, ChevronLeft, PanelRightOpen, PanelRightClose, PanelRight, Newspaper, Clapperboard, Box, TreePalm, ArrowDownRight, ArrowUpRight, Ruler, Warehouse, Wallet, Sparkles, AlertTriangle, TableProperties, Plug, ArrowLeftRight, ArrowUpCircle, ArrowDownCircle, ChevronDown, ClipboardCheck, PiggyBank, LogOut } from 'lucide-react';
|
|
5
5
|
import * as Tooltip from '@radix-ui/react-tooltip';
|
|
6
6
|
import { create } from 'zustand';
|
|
7
|
-
import {
|
|
7
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
8
8
|
import * as Popover from '@radix-ui/react-popover';
|
|
9
9
|
import { createPortal } from 'react-dom';
|
|
10
10
|
import { useTranslation } from '@fayz-ai/core';
|
|
@@ -104,8 +104,17 @@ var ICON_MAP = {
|
|
|
104
104
|
Workflow,
|
|
105
105
|
Boxes,
|
|
106
106
|
Clock3,
|
|
107
|
-
FileCheck2
|
|
107
|
+
FileCheck2,
|
|
108
|
+
GraduationCap,
|
|
109
|
+
Repeat,
|
|
110
|
+
User,
|
|
111
|
+
Palette,
|
|
112
|
+
ShieldCheck,
|
|
113
|
+
SlidersHorizontal,
|
|
114
|
+
Puzzle
|
|
108
115
|
};
|
|
116
|
+
var RAIL_PUSH_MS = 260;
|
|
117
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React3.useLayoutEffect : React3.useEffect;
|
|
109
118
|
function getIcon(name) {
|
|
110
119
|
return ICON_MAP[name] ?? Home;
|
|
111
120
|
}
|
|
@@ -130,6 +139,7 @@ function NavItem({
|
|
|
130
139
|
/* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
131
140
|
!collapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
132
141
|
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-left", children: item.label }),
|
|
142
|
+
item.premium && /* @__PURE__ */ jsx(Crown, { className: "ml-auto h-3.5 w-3.5 shrink-0 text-amber-500", "aria-hidden": true }),
|
|
133
143
|
item.badge !== void 0 && /* @__PURE__ */ jsx("span", { className: "ml-auto rounded-full bg-primary px-2 py-0.5 text-xs font-semibold text-primary-foreground", children: item.badge })
|
|
134
144
|
] })
|
|
135
145
|
]
|
|
@@ -146,6 +156,7 @@ function NavItem({
|
|
|
146
156
|
className: "fayz-glass-surface z-50 rounded-md bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md",
|
|
147
157
|
children: [
|
|
148
158
|
item.label,
|
|
159
|
+
item.premium && /* @__PURE__ */ jsx(Crown, { className: "ml-1.5 inline h-3 w-3 text-amber-500", "aria-hidden": true }),
|
|
149
160
|
item.badge !== void 0 && /* @__PURE__ */ jsx("span", { className: "ml-2 rounded-full bg-primary px-1.5 py-0.5 text-xs text-primary-foreground", children: item.badge }),
|
|
150
161
|
/* @__PURE__ */ jsx(Tooltip.Arrow, { className: "fill-popover" })
|
|
151
162
|
]
|
|
@@ -258,7 +269,10 @@ function Sidebar({
|
|
|
258
269
|
borderless,
|
|
259
270
|
userMenuSlot,
|
|
260
271
|
notificationSlot,
|
|
261
|
-
unreadCount = 0
|
|
272
|
+
unreadCount = 0,
|
|
273
|
+
sectionLabels,
|
|
274
|
+
navKey,
|
|
275
|
+
navDirection = "forward"
|
|
262
276
|
}) {
|
|
263
277
|
const currentPath = currentPathProp;
|
|
264
278
|
const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
|
|
@@ -269,6 +283,47 @@ function Sidebar({
|
|
|
269
283
|
const handleNavigate = (route) => {
|
|
270
284
|
onNavigate?.(route);
|
|
271
285
|
};
|
|
286
|
+
const sectionHeading = (label) => label && !collapsed ? /* @__PURE__ */ jsx("p", { className: "px-2.5 pb-1 pt-1 text-[10px] font-semibold uppercase tracking-wider text-sidebar-muted", children: label }) : null;
|
|
287
|
+
const renderItem = (item) => item.children && item.children.length > 0 ? /* @__PURE__ */ jsx(NavGroup, { item, collapsed, activeRoute, onNavigate: handleNavigate }, item.id) : /* @__PURE__ */ jsx(
|
|
288
|
+
NavItem,
|
|
289
|
+
{
|
|
290
|
+
item,
|
|
291
|
+
collapsed,
|
|
292
|
+
isActive: item.route === activeRoute,
|
|
293
|
+
onNavigate: handleNavigate
|
|
294
|
+
},
|
|
295
|
+
item.id
|
|
296
|
+
);
|
|
297
|
+
const navBody = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
298
|
+
topContent && /* @__PURE__ */ jsx("div", { className: "mb-4 space-y-2", children: topContent }),
|
|
299
|
+
mainItems.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
300
|
+
sectionHeading(sectionLabels?.main),
|
|
301
|
+
mainItems.map(renderItem)
|
|
302
|
+
] }),
|
|
303
|
+
secondaryItems.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-6 space-y-1", children: [
|
|
304
|
+
sectionHeading(sectionLabels?.secondary),
|
|
305
|
+
secondaryItems.map(renderItem)
|
|
306
|
+
] })
|
|
307
|
+
] });
|
|
308
|
+
const [outgoing, setOutgoing] = React3.useState(null);
|
|
309
|
+
const lastBodyRef = React3.useRef(null);
|
|
310
|
+
const lastKeyRef = React3.useRef(navKey);
|
|
311
|
+
const timerRef = React3.useRef(null);
|
|
312
|
+
useIsomorphicLayoutEffect(() => {
|
|
313
|
+
if (lastKeyRef.current !== navKey) {
|
|
314
|
+
const previousBody = lastBodyRef.current;
|
|
315
|
+
lastKeyRef.current = navKey;
|
|
316
|
+
if (previousBody) {
|
|
317
|
+
setOutgoing({ body: previousBody, direction: navDirection });
|
|
318
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
319
|
+
timerRef.current = setTimeout(() => setOutgoing(null), RAIL_PUSH_MS);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
lastBodyRef.current = navBody;
|
|
323
|
+
});
|
|
324
|
+
React3.useEffect(() => () => {
|
|
325
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
326
|
+
}, []);
|
|
272
327
|
return /* @__PURE__ */ jsx(Tooltip.Provider, { children: /* @__PURE__ */ jsxs(
|
|
273
328
|
"aside",
|
|
274
329
|
{
|
|
@@ -312,33 +367,39 @@ function Sidebar({
|
|
|
312
367
|
]
|
|
313
368
|
}
|
|
314
369
|
),
|
|
315
|
-
/* @__PURE__ */ jsxs(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
370
|
+
/* @__PURE__ */ jsxs(
|
|
371
|
+
"nav",
|
|
372
|
+
{
|
|
373
|
+
className: cn(
|
|
374
|
+
"relative flex-1 p-2",
|
|
375
|
+
outgoing ? "overflow-hidden" : "overflow-y-auto"
|
|
376
|
+
),
|
|
377
|
+
children: [
|
|
378
|
+
outgoing && /* @__PURE__ */ jsx(
|
|
379
|
+
"div",
|
|
380
|
+
{
|
|
381
|
+
"aria-hidden": true,
|
|
382
|
+
className: cn(
|
|
383
|
+
"pointer-events-none absolute inset-x-2 top-2 space-y-1",
|
|
384
|
+
outgoing.direction === "back" ? "saas-rail-out-back" : "saas-rail-out-forward"
|
|
385
|
+
),
|
|
386
|
+
children: outgoing.body
|
|
387
|
+
}
|
|
388
|
+
),
|
|
389
|
+
/* @__PURE__ */ jsx(
|
|
390
|
+
"div",
|
|
391
|
+
{
|
|
392
|
+
className: cn(
|
|
393
|
+
"space-y-1",
|
|
394
|
+
outgoing && (outgoing.direction === "back" ? "saas-rail-in-back" : "saas-rail-in-forward")
|
|
395
|
+
),
|
|
396
|
+
children: navBody
|
|
397
|
+
},
|
|
398
|
+
navKey
|
|
399
|
+
)
|
|
400
|
+
]
|
|
401
|
+
}
|
|
402
|
+
),
|
|
342
403
|
settingsItems.length > 0 && /* @__PURE__ */ jsx("div", { className: cn("p-2 space-y-1", !borderless && "border-t border-sidebar-border"), children: settingsItems.map((item) => /* @__PURE__ */ jsx(
|
|
343
404
|
NavItem,
|
|
344
405
|
{
|
|
@@ -384,6 +445,8 @@ function Sidebar({
|
|
|
384
445
|
}
|
|
385
446
|
function TopbarUserMenu({
|
|
386
447
|
user,
|
|
448
|
+
userPlan,
|
|
449
|
+
billingLabel = "Subscription",
|
|
387
450
|
onSignOut,
|
|
388
451
|
onProfile,
|
|
389
452
|
onSettings,
|
|
@@ -434,11 +497,35 @@ function TopbarUserMenu({
|
|
|
434
497
|
/* @__PURE__ */ jsxs("div", { className: "mt-1 space-y-0.5", children: [
|
|
435
498
|
item("Perfil", onProfile, UserCog),
|
|
436
499
|
item("Configura\xE7\xF5es", onSettings, Settings),
|
|
437
|
-
|
|
500
|
+
onBilling && /* @__PURE__ */ jsxs(
|
|
501
|
+
"button",
|
|
502
|
+
{
|
|
503
|
+
onClick: () => {
|
|
504
|
+
setOpen(false);
|
|
505
|
+
onBilling();
|
|
506
|
+
},
|
|
507
|
+
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",
|
|
508
|
+
children: [
|
|
509
|
+
/* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4 text-muted-foreground" }),
|
|
510
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: billingLabel }),
|
|
511
|
+
userPlan && /* @__PURE__ */ jsxs(
|
|
512
|
+
"span",
|
|
513
|
+
{
|
|
514
|
+
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",
|
|
515
|
+
children: [
|
|
516
|
+
userPlan.paid ? /* @__PURE__ */ jsx(Crown, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(Sparkles, { className: "h-3 w-3" }),
|
|
517
|
+
userPlan.label
|
|
518
|
+
]
|
|
519
|
+
}
|
|
520
|
+
)
|
|
521
|
+
]
|
|
522
|
+
},
|
|
523
|
+
"billing"
|
|
524
|
+
),
|
|
438
525
|
userMenuExtras?.map((e) => item(e.label, e.onClick)),
|
|
439
526
|
onSignOut && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
440
527
|
/* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border" }),
|
|
441
|
-
item("Sair", onSignOut)
|
|
528
|
+
item("Sair", onSignOut, LogOut)
|
|
442
529
|
] })
|
|
443
530
|
] })
|
|
444
531
|
]
|
|
@@ -503,7 +590,7 @@ var ICON_MAP2 = {
|
|
|
503
590
|
ArrowUpCircle,
|
|
504
591
|
ArrowLeftRight,
|
|
505
592
|
Plug,
|
|
506
|
-
SlidersHorizontal,
|
|
593
|
+
SlidersHorizontal: SlidersHorizontal,
|
|
507
594
|
TableProperties,
|
|
508
595
|
Landmark: Landmark,
|
|
509
596
|
Receipt: Receipt,
|
|
@@ -546,7 +633,9 @@ var ICON_MAP2 = {
|
|
|
546
633
|
Star: Star,
|
|
547
634
|
Zap: Zap,
|
|
548
635
|
Clapperboard,
|
|
549
|
-
Newspaper
|
|
636
|
+
Newspaper,
|
|
637
|
+
GraduationCap: GraduationCap,
|
|
638
|
+
Repeat: Repeat
|
|
550
639
|
};
|
|
551
640
|
function getIcon2(name) {
|
|
552
641
|
return ICON_MAP2[name] ?? Home;
|
|
@@ -610,6 +699,7 @@ function Topbar({
|
|
|
610
699
|
logo,
|
|
611
700
|
user,
|
|
612
701
|
onMenuClick,
|
|
702
|
+
orgSwitcher,
|
|
613
703
|
leftContent,
|
|
614
704
|
rightContent,
|
|
615
705
|
currentPath = "/",
|
|
@@ -619,6 +709,8 @@ function Topbar({
|
|
|
619
709
|
onProfile,
|
|
620
710
|
onSettings,
|
|
621
711
|
onBilling,
|
|
712
|
+
userPlan,
|
|
713
|
+
billingLabel,
|
|
622
714
|
userMenuExtras
|
|
623
715
|
}) {
|
|
624
716
|
const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
|
|
@@ -640,7 +732,8 @@ function Topbar({
|
|
|
640
732
|
children: /* @__PURE__ */ jsx(Menu, { className: "h-5 w-5" })
|
|
641
733
|
}
|
|
642
734
|
),
|
|
643
|
-
/* @__PURE__ */ jsx("div", { className: "hidden shrink-0 items-center md:flex", children: logo ?? /* @__PURE__ */ jsx("span", { className: "text-lg font-bold", children: "App" }) })
|
|
735
|
+
/* @__PURE__ */ jsx("div", { className: "hidden shrink-0 items-center md:flex", children: logo ?? /* @__PURE__ */ jsx("span", { className: "text-lg font-bold", children: "App" }) }),
|
|
736
|
+
orgSwitcher && /* @__PURE__ */ jsx("div", { className: "hidden min-w-0 items-center md:flex", children: orgSwitcher })
|
|
644
737
|
] }),
|
|
645
738
|
/* @__PURE__ */ jsx("div", { className: "mx-8 hidden max-w-sm flex-1 md:flex", children: /* @__PURE__ */ jsxs(
|
|
646
739
|
"button",
|
|
@@ -661,6 +754,8 @@ function Topbar({
|
|
|
661
754
|
TopbarUserMenu,
|
|
662
755
|
{
|
|
663
756
|
user,
|
|
757
|
+
userPlan,
|
|
758
|
+
billingLabel,
|
|
664
759
|
onSignOut,
|
|
665
760
|
onProfile,
|
|
666
761
|
onSettings,
|
|
@@ -703,6 +798,7 @@ function Topbar({
|
|
|
703
798
|
children: [
|
|
704
799
|
/* @__PURE__ */ jsx(Icon, { className: "h-4 w-4" }),
|
|
705
800
|
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
801
|
+
item.premium && /* @__PURE__ */ jsx(Crown, { className: "h-3 w-3 text-amber-500", "aria-hidden": true }),
|
|
706
802
|
item.badge !== void 0 && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-primary px-1.5 py-0.5 text-[10px] font-semibold text-primary-foreground", children: item.badge })
|
|
707
803
|
]
|
|
708
804
|
},
|
|
@@ -742,7 +838,10 @@ function SidebarLayout({
|
|
|
742
838
|
notificationSlot,
|
|
743
839
|
unreadCount = 0,
|
|
744
840
|
hasBottomNav = false,
|
|
745
|
-
mobileHeader = "minimal"
|
|
841
|
+
mobileHeader = "minimal",
|
|
842
|
+
sidebarSectionLabels,
|
|
843
|
+
sidebarNavKey,
|
|
844
|
+
sidebarNavDirection
|
|
746
845
|
}) {
|
|
747
846
|
const sidebarCollapsed = useLayoutStore((s) => s.sidebarCollapsed);
|
|
748
847
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
@@ -776,7 +875,10 @@ function SidebarLayout({
|
|
|
776
875
|
borderless: false,
|
|
777
876
|
userMenuSlot,
|
|
778
877
|
notificationSlot,
|
|
779
|
-
unreadCount
|
|
878
|
+
unreadCount,
|
|
879
|
+
sectionLabels: sidebarSectionLabels,
|
|
880
|
+
navKey: sidebarNavKey,
|
|
881
|
+
navDirection: sidebarNavDirection
|
|
780
882
|
}
|
|
781
883
|
) }),
|
|
782
884
|
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
@@ -806,7 +908,7 @@ function SidebarLayout({
|
|
|
806
908
|
topbarEnd
|
|
807
909
|
] })
|
|
808
910
|
] }),
|
|
809
|
-
/* @__PURE__ */ jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children }),
|
|
911
|
+
/* @__PURE__ */ jsx("main", { className: "min-w-0 flex-1 overflow-y-auto pb-16 md:pb-0", children }),
|
|
810
912
|
/* @__PURE__ */ jsx(SaveBar, {})
|
|
811
913
|
] }),
|
|
812
914
|
mobileMenuOpen && /* @__PURE__ */ jsx(
|
|
@@ -842,11 +944,15 @@ function TopbarLayout({
|
|
|
842
944
|
onProfile,
|
|
843
945
|
onSettings,
|
|
844
946
|
onBilling,
|
|
947
|
+
userPlan,
|
|
948
|
+
billingLabel,
|
|
845
949
|
userMenuExtras,
|
|
950
|
+
orgSwitcher,
|
|
846
951
|
frame,
|
|
847
952
|
currentPath,
|
|
848
953
|
topbarStart,
|
|
849
954
|
topbarEnd,
|
|
955
|
+
notificationSlot,
|
|
850
956
|
hasBottomNav = false
|
|
851
957
|
}) {
|
|
852
958
|
const [mobileMenuOpen, setMobileMenuOpen] = React3.useState(false);
|
|
@@ -863,13 +969,19 @@ function TopbarLayout({
|
|
|
863
969
|
onProfile,
|
|
864
970
|
onSettings,
|
|
865
971
|
onBilling,
|
|
972
|
+
userPlan,
|
|
973
|
+
billingLabel,
|
|
866
974
|
userMenuExtras,
|
|
975
|
+
orgSwitcher,
|
|
867
976
|
leftContent: topbarStart,
|
|
868
|
-
rightContent: topbarEnd,
|
|
977
|
+
rightContent: topbarEnd || notificationSlot ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
978
|
+
topbarEnd,
|
|
979
|
+
notificationSlot
|
|
980
|
+
] }) : void 0,
|
|
869
981
|
onMenuClick: hasBottomNav ? void 0 : () => setMobileMenuOpen(true)
|
|
870
982
|
}
|
|
871
983
|
),
|
|
872
|
-
/* @__PURE__ */ jsx("main", { className: cn("flex-
|
|
984
|
+
/* @__PURE__ */ jsx("main", { className: cn("flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden", frame && "md:bg-sidebar md:p-2"), children: /* @__PURE__ */ jsx("div", { className: 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__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto pb-16 md:pb-0", children }) }) }),
|
|
873
985
|
/* @__PURE__ */ jsx(SaveBar, {}),
|
|
874
986
|
mobileMenuOpen && /* @__PURE__ */ jsx(
|
|
875
987
|
MobileOverlay,
|
|
@@ -883,6 +995,7 @@ function TopbarLayout({
|
|
|
883
995
|
onProfile,
|
|
884
996
|
onSettings,
|
|
885
997
|
onBilling,
|
|
998
|
+
orgSwitcher,
|
|
886
999
|
userMenuSlot: user ? /* @__PURE__ */ jsx(DrawerUserRow, { user }) : void 0,
|
|
887
1000
|
onClose: () => setMobileMenuOpen(false)
|
|
888
1001
|
}
|
|
@@ -907,7 +1020,7 @@ function MinimalLayout({
|
|
|
907
1020
|
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: logo ?? /* @__PURE__ */ jsx("span", { className: "text-lg font-bold", children: "App" }) }),
|
|
908
1021
|
headerEnd && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: headerEnd })
|
|
909
1022
|
] }),
|
|
910
|
-
/* @__PURE__ */ jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children })
|
|
1023
|
+
/* @__PURE__ */ jsx("main", { className: "min-w-0 flex-1 overflow-y-auto pb-16 md:pb-0", children })
|
|
911
1024
|
] });
|
|
912
1025
|
}
|
|
913
1026
|
function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
|
|
@@ -1057,6 +1170,8 @@ function AppShell({
|
|
|
1057
1170
|
onProfile,
|
|
1058
1171
|
onSettings,
|
|
1059
1172
|
onBilling,
|
|
1173
|
+
userPlan,
|
|
1174
|
+
billingLabel,
|
|
1060
1175
|
pageTitle,
|
|
1061
1176
|
currentPath,
|
|
1062
1177
|
userMenuExtras,
|
|
@@ -1070,7 +1185,17 @@ function AppShell({
|
|
|
1070
1185
|
mobileHeader = "minimal",
|
|
1071
1186
|
userMenuSlot,
|
|
1072
1187
|
notificationSlot,
|
|
1073
|
-
unreadCount = 0
|
|
1188
|
+
unreadCount = 0,
|
|
1189
|
+
sidebarSectionLabels,
|
|
1190
|
+
sidebarNavKey,
|
|
1191
|
+
sidebarNavDirection,
|
|
1192
|
+
rightRail,
|
|
1193
|
+
rightRailOpen = true,
|
|
1194
|
+
defaultRightRailWidth,
|
|
1195
|
+
onRightRailWidthChange,
|
|
1196
|
+
rightRailMinWidth,
|
|
1197
|
+
rightRailMaxWidth,
|
|
1198
|
+
rightRailResizeLabel
|
|
1074
1199
|
}) {
|
|
1075
1200
|
const hasBottomNav = !!bottomNav?.length;
|
|
1076
1201
|
const bottomBar = hasBottomNav ? /* @__PURE__ */ jsx(
|
|
@@ -1111,6 +1236,9 @@ function AppShell({
|
|
|
1111
1236
|
unreadCount,
|
|
1112
1237
|
hasBottomNav,
|
|
1113
1238
|
mobileHeader,
|
|
1239
|
+
sidebarSectionLabels,
|
|
1240
|
+
sidebarNavKey,
|
|
1241
|
+
sidebarNavDirection,
|
|
1114
1242
|
children
|
|
1115
1243
|
}
|
|
1116
1244
|
);
|
|
@@ -1127,11 +1255,15 @@ function AppShell({
|
|
|
1127
1255
|
onProfile,
|
|
1128
1256
|
onSettings,
|
|
1129
1257
|
onBilling,
|
|
1258
|
+
userPlan,
|
|
1259
|
+
billingLabel,
|
|
1130
1260
|
userMenuExtras,
|
|
1261
|
+
orgSwitcher,
|
|
1131
1262
|
frame: contentFrame,
|
|
1132
1263
|
currentPath,
|
|
1133
1264
|
topbarStart,
|
|
1134
1265
|
topbarEnd,
|
|
1266
|
+
notificationSlot,
|
|
1135
1267
|
hasBottomNav,
|
|
1136
1268
|
children
|
|
1137
1269
|
}
|
|
@@ -1145,11 +1277,142 @@ function AppShell({
|
|
|
1145
1277
|
}
|
|
1146
1278
|
}
|
|
1147
1279
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1148
|
-
|
|
1280
|
+
rightRail ? /* @__PURE__ */ jsx(
|
|
1281
|
+
SplitWithRightRail,
|
|
1282
|
+
{
|
|
1283
|
+
rail: rightRail,
|
|
1284
|
+
open: rightRailOpen,
|
|
1285
|
+
frame: contentFrame,
|
|
1286
|
+
defaultWidth: defaultRightRailWidth,
|
|
1287
|
+
onWidthChange: onRightRailWidthChange,
|
|
1288
|
+
minWidth: rightRailMinWidth,
|
|
1289
|
+
maxWidth: rightRailMaxWidth,
|
|
1290
|
+
resizeLabel: rightRailResizeLabel,
|
|
1291
|
+
children: layoutElement
|
|
1292
|
+
}
|
|
1293
|
+
) : layoutElement,
|
|
1149
1294
|
floatingAvatar,
|
|
1150
1295
|
bottomBar
|
|
1151
1296
|
] });
|
|
1152
1297
|
}
|
|
1298
|
+
function SplitWithRightRail({
|
|
1299
|
+
children,
|
|
1300
|
+
rail,
|
|
1301
|
+
open,
|
|
1302
|
+
frame,
|
|
1303
|
+
defaultWidth = 380,
|
|
1304
|
+
onWidthChange,
|
|
1305
|
+
minWidth = 300,
|
|
1306
|
+
maxWidth = 720,
|
|
1307
|
+
resizeLabel = "Resize panel"
|
|
1308
|
+
}) {
|
|
1309
|
+
const [width, setWidth] = React3.useState(defaultWidth);
|
|
1310
|
+
const [dragging, setDragging] = React3.useState(false);
|
|
1311
|
+
const clamp = React3.useCallback(
|
|
1312
|
+
(value) => Math.min(maxWidth, Math.max(minWidth, value)),
|
|
1313
|
+
[minWidth, maxWidth]
|
|
1314
|
+
);
|
|
1315
|
+
React3.useEffect(() => {
|
|
1316
|
+
if (!dragging) return;
|
|
1317
|
+
const onMove = (event) => {
|
|
1318
|
+
event.preventDefault();
|
|
1319
|
+
setWidth(clamp(window.innerWidth - event.clientX));
|
|
1320
|
+
};
|
|
1321
|
+
const stop = () => setDragging(false);
|
|
1322
|
+
window.addEventListener("pointermove", onMove);
|
|
1323
|
+
window.addEventListener("pointerup", stop);
|
|
1324
|
+
window.addEventListener("pointercancel", stop);
|
|
1325
|
+
const previousSelect = document.body.style.userSelect;
|
|
1326
|
+
const previousCursor = document.body.style.cursor;
|
|
1327
|
+
document.body.style.userSelect = "none";
|
|
1328
|
+
document.body.style.cursor = "col-resize";
|
|
1329
|
+
return () => {
|
|
1330
|
+
window.removeEventListener("pointermove", onMove);
|
|
1331
|
+
window.removeEventListener("pointerup", stop);
|
|
1332
|
+
window.removeEventListener("pointercancel", stop);
|
|
1333
|
+
document.body.style.userSelect = previousSelect;
|
|
1334
|
+
document.body.style.cursor = previousCursor;
|
|
1335
|
+
};
|
|
1336
|
+
}, [dragging, clamp]);
|
|
1337
|
+
React3.useEffect(() => {
|
|
1338
|
+
if (dragging) return;
|
|
1339
|
+
onWidthChange?.(width);
|
|
1340
|
+
}, [dragging]);
|
|
1341
|
+
const nudge = (delta) => setWidth((current) => clamp(current + delta));
|
|
1342
|
+
return (
|
|
1343
|
+
// Sidebar tone always: the gutter and the divider sit in the shell's
|
|
1344
|
+
// chrome, next to the menu — painting them page-white put a bright strip
|
|
1345
|
+
// between the dark chrome and the rail, which read as a seam rather than
|
|
1346
|
+
// as space.
|
|
1347
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex h-screen w-full overflow-hidden bg-sidebar", !frame && "md:bg-background"), children: [
|
|
1348
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children }),
|
|
1349
|
+
/* @__PURE__ */ jsxs(
|
|
1350
|
+
"div",
|
|
1351
|
+
{
|
|
1352
|
+
role: "separator",
|
|
1353
|
+
"aria-orientation": "vertical",
|
|
1354
|
+
"aria-label": resizeLabel,
|
|
1355
|
+
"aria-valuenow": width,
|
|
1356
|
+
"aria-valuemin": minWidth,
|
|
1357
|
+
"aria-valuemax": maxWidth,
|
|
1358
|
+
tabIndex: 0,
|
|
1359
|
+
onPointerDown: (event) => {
|
|
1360
|
+
event.preventDefault();
|
|
1361
|
+
setDragging(true);
|
|
1362
|
+
},
|
|
1363
|
+
onDoubleClick: () => setWidth(clamp(defaultWidth)),
|
|
1364
|
+
onKeyDown: (event) => {
|
|
1365
|
+
if (event.key === "ArrowLeft") {
|
|
1366
|
+
event.preventDefault();
|
|
1367
|
+
nudge(24);
|
|
1368
|
+
} else if (event.key === "ArrowRight") {
|
|
1369
|
+
event.preventDefault();
|
|
1370
|
+
nudge(-24);
|
|
1371
|
+
} else if (event.key === "Home") {
|
|
1372
|
+
event.preventDefault();
|
|
1373
|
+
setWidth(maxWidth);
|
|
1374
|
+
} else if (event.key === "End") {
|
|
1375
|
+
event.preventDefault();
|
|
1376
|
+
setWidth(minWidth);
|
|
1377
|
+
}
|
|
1378
|
+
},
|
|
1379
|
+
className: cn(
|
|
1380
|
+
"group relative hidden w-1 shrink-0 cursor-col-resize focus-visible:outline-none",
|
|
1381
|
+
open && "md:block"
|
|
1382
|
+
),
|
|
1383
|
+
children: [
|
|
1384
|
+
/* @__PURE__ */ jsx(
|
|
1385
|
+
"span",
|
|
1386
|
+
{
|
|
1387
|
+
className: cn(
|
|
1388
|
+
"absolute inset-y-6 left-1/2 w-px -translate-x-1/2 rounded-full bg-transparent transition-colors",
|
|
1389
|
+
"group-hover:bg-primary/60 group-focus-visible:bg-primary",
|
|
1390
|
+
dragging && "bg-primary"
|
|
1391
|
+
)
|
|
1392
|
+
}
|
|
1393
|
+
),
|
|
1394
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inset-y-0 -left-1.5 -right-1.5" })
|
|
1395
|
+
]
|
|
1396
|
+
}
|
|
1397
|
+
),
|
|
1398
|
+
/* @__PURE__ */ jsx(
|
|
1399
|
+
"aside",
|
|
1400
|
+
{
|
|
1401
|
+
style: { ["--fayz-rail-w"]: `${width}px` },
|
|
1402
|
+
className: cn(
|
|
1403
|
+
"w-0 shrink-0 overflow-hidden",
|
|
1404
|
+
// Animating WIDTH is what makes the app glide back instead of
|
|
1405
|
+
// snapping; skipped mid-drag so the divider stays glued to the cursor.
|
|
1406
|
+
!dragging && "motion-safe:transition-[width] motion-safe:duration-200 motion-safe:ease-out",
|
|
1407
|
+
open && "md:w-[var(--fayz-rail-w)]",
|
|
1408
|
+
frame && "md:py-2 md:pr-2"
|
|
1409
|
+
),
|
|
1410
|
+
children: rail
|
|
1411
|
+
}
|
|
1412
|
+
)
|
|
1413
|
+
] })
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1153
1416
|
var NavTransitionContext = React3.createContext("slide");
|
|
1154
1417
|
function NavTransitionProvider({ value, children }) {
|
|
1155
1418
|
return /* @__PURE__ */ jsx(NavTransitionContext.Provider, { value, children });
|
|
@@ -1179,6 +1442,11 @@ function PageHeaderActions({ children }) {
|
|
|
1179
1442
|
if (slot) return createPortal(children, slot);
|
|
1180
1443
|
return /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center justify-end gap-2", children });
|
|
1181
1444
|
}
|
|
1445
|
+
function PremiumBadge({ className }) {
|
|
1446
|
+
const t = useTranslation();
|
|
1447
|
+
const tip = t("upgrade.badgeTooltip");
|
|
1448
|
+
return /* @__PURE__ */ jsx("span", { title: tip, "aria-label": tip, className: cn("inline-flex shrink-0", className), children: /* @__PURE__ */ jsx(Crown, { className: "h-3.5 w-3.5 text-amber-500", "aria-hidden": true }) });
|
|
1449
|
+
}
|
|
1182
1450
|
var ModuleLayoutContext = React3.createContext("rail");
|
|
1183
1451
|
function ModuleLayoutProvider({ variant, children }) {
|
|
1184
1452
|
return /* @__PURE__ */ jsx(ModuleLayoutContext.Provider, { value: variant, children });
|
|
@@ -1205,11 +1473,12 @@ function NavItem2({ item }) {
|
|
|
1205
1473
|
children: [
|
|
1206
1474
|
Icon && /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
1207
1475
|
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left truncate", children: item.label }),
|
|
1476
|
+
item.premium && /* @__PURE__ */ jsx(PremiumBadge, { className: "ml-1" }),
|
|
1208
1477
|
hasChildren && (expanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 shrink-0 opacity-50" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5 shrink-0 opacity-50" }))
|
|
1209
1478
|
]
|
|
1210
1479
|
}
|
|
1211
1480
|
),
|
|
1212
|
-
hasChildren && expanded && /* @__PURE__ */ jsx("div", { className: "ml-4 mt-0.5 space-y-0.5 border-l pl-2", children: item.children.map((child) => /* @__PURE__ */
|
|
1481
|
+
hasChildren && expanded && /* @__PURE__ */ jsx("div", { className: "ml-4 mt-0.5 space-y-0.5 border-l pl-2", children: item.children.map((child) => /* @__PURE__ */ jsxs(
|
|
1213
1482
|
"button",
|
|
1214
1483
|
{
|
|
1215
1484
|
type: "button",
|
|
@@ -1218,7 +1487,10 @@ function NavItem2({ item }) {
|
|
|
1218
1487
|
"flex items-center w-full rounded-md px-2.5 py-1 text-xs transition-colors",
|
|
1219
1488
|
child.active ? "text-primary font-medium bg-primary/5" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
|
|
1220
1489
|
),
|
|
1221
|
-
children:
|
|
1490
|
+
children: [
|
|
1491
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left truncate", children: child.label }),
|
|
1492
|
+
child.premium && /* @__PURE__ */ jsx(PremiumBadge, { className: "ml-1" })
|
|
1493
|
+
]
|
|
1222
1494
|
},
|
|
1223
1495
|
child.id
|
|
1224
1496
|
)) })
|
|
@@ -1262,6 +1534,7 @@ function MobileTabs({ nav }) {
|
|
|
1262
1534
|
children: [
|
|
1263
1535
|
Icon && /* @__PURE__ */ jsx(Icon, { className: "h-3 w-3" }),
|
|
1264
1536
|
item.label,
|
|
1537
|
+
item.premium && /* @__PURE__ */ jsx(PremiumBadge, {}),
|
|
1265
1538
|
hasChildren && /* @__PURE__ */ jsx(ChevronDown, { className: cn("h-2.5 w-2.5 transition-transform", isExpanded && "rotate-180") })
|
|
1266
1539
|
]
|
|
1267
1540
|
},
|
|
@@ -1271,7 +1544,7 @@ function MobileTabs({ nav }) {
|
|
|
1271
1544
|
expandedId && (() => {
|
|
1272
1545
|
const item = nav.find((n) => n.id === expandedId);
|
|
1273
1546
|
if (!item?.children) return null;
|
|
1274
|
-
return /* @__PURE__ */ 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__ */
|
|
1547
|
+
return /* @__PURE__ */ 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__ */ jsxs(
|
|
1275
1548
|
"button",
|
|
1276
1549
|
{
|
|
1277
1550
|
type: "button",
|
|
@@ -1283,7 +1556,10 @@ function MobileTabs({ nav }) {
|
|
|
1283
1556
|
"whitespace-nowrap rounded-full px-2.5 py-1 text-[11px] font-medium transition-colors shrink-0",
|
|
1284
1557
|
child.active ? "bg-foreground/10 text-foreground" : "text-muted-foreground hover:text-foreground"
|
|
1285
1558
|
),
|
|
1286
|
-
children:
|
|
1559
|
+
children: [
|
|
1560
|
+
child.label,
|
|
1561
|
+
child.premium && /* @__PURE__ */ jsx(PremiumBadge, {})
|
|
1562
|
+
]
|
|
1287
1563
|
},
|
|
1288
1564
|
child.id
|
|
1289
1565
|
)) });
|
|
@@ -1375,7 +1651,8 @@ function ModuleHeader({ nav }) {
|
|
|
1375
1651
|
),
|
|
1376
1652
|
children: [
|
|
1377
1653
|
Icon && /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4" }),
|
|
1378
|
-
item.label
|
|
1654
|
+
item.label,
|
|
1655
|
+
item.premium && /* @__PURE__ */ jsx(PremiumBadge, {})
|
|
1379
1656
|
]
|
|
1380
1657
|
},
|
|
1381
1658
|
item.id
|
|
@@ -1503,5 +1780,5 @@ function ContentSplitTrigger({ label, iconOnly, className }) {
|
|
|
1503
1780
|
}
|
|
1504
1781
|
|
|
1505
1782
|
export { AppShell, BackStyleProvider, ContentSplit, ContentSplitTrigger, ICON_MAP, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageHeaderActions, PageTransition, Sidebar, SubpageHeader, Topbar, useBackStyle, useLayoutStore, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useNavTransition };
|
|
1506
|
-
//# sourceMappingURL=chunk-
|
|
1507
|
-
//# sourceMappingURL=chunk-
|
|
1783
|
+
//# sourceMappingURL=chunk-ID2HQK2Q.js.map
|
|
1784
|
+
//# sourceMappingURL=chunk-ID2HQK2Q.js.map
|