@fayz-ai/ui 0.33.0 → 0.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-PL5CUWNE.js → chunk-33A7SN2N.js} +583 -119
- package/dist/chunk-33A7SN2N.js.map +1 -0
- package/dist/{chunk-UFT3MA5H.js → chunk-6GWXDVCO.js} +203 -15
- package/dist/chunk-6GWXDVCO.js.map +1 -0
- package/dist/{chunk-NXSDQ7HO.js → chunk-Q2B5RPH5.js} +13 -16
- package/dist/chunk-Q2B5RPH5.js.map +1 -0
- package/dist/{chunk-3XKDGBP4.js → chunk-UNEEY5XG.js} +3 -3
- package/dist/{chunk-3XKDGBP4.js.map → chunk-UNEEY5XG.js.map} +1 -1
- package/dist/dashboard/DashboardGrid.d.ts +8 -1
- package/dist/dashboard/DashboardGrid.d.ts.map +1 -1
- package/dist/dashboard/KpiCard.d.ts.map +1 -1
- package/dist/dashboard/index.js +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -8
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/ModulePage.d.ts +47 -1
- package/dist/layout/ModulePage.d.ts.map +1 -1
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/index.d.ts +1 -1
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +1 -1
- package/dist/layout/rail-flyout.d.ts.map +1 -1
- package/dist/primitives/collapsible-column.d.ts +38 -0
- package/dist/primitives/collapsible-column.d.ts.map +1 -0
- package/dist/primitives/coming-soon.d.ts +31 -0
- package/dist/primitives/coming-soon.d.ts.map +1 -0
- package/dist/primitives/filter-panel.d.ts +85 -0
- package/dist/primitives/filter-panel.d.ts.map +1 -0
- package/dist/primitives/filter-rail.d.ts +10 -7
- package/dist/primitives/filter-rail.d.ts.map +1 -1
- package/dist/primitives/header-tabs.d.ts +9 -35
- package/dist/primitives/header-tabs.d.ts.map +1 -1
- package/dist/primitives/index.d.ts +2 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +3 -3
- package/dist/primitives/nav-connector.d.ts +23 -0
- package/dist/primitives/nav-connector.d.ts.map +1 -0
- package/dist/primitives/search-select.d.ts.map +1 -1
- package/dist/stores/index.d.ts +1 -1
- package/dist/stores/index.d.ts.map +1 -1
- package/dist/stores/page-header.store.d.ts +17 -0
- package/dist/stores/page-header.store.d.ts.map +1 -1
- package/dist/styles.css +58 -0
- package/package.json +1 -1
- package/dist/chunk-NXSDQ7HO.js.map +0 -1
- package/dist/chunk-PL5CUWNE.js.map +0 -1
- package/dist/chunk-UFT3MA5H.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from './chunk-OKZ6WQB3.js';
|
|
2
2
|
import { ICON_MAP } from './chunk-ATDIWKBD.js';
|
|
3
3
|
import * as React11 from 'react';
|
|
4
|
-
import { Loader2, ChevronLeft, ArrowLeft, X, Bell, PanelLeft, PanelLeftClose, Search, CornerDownLeft, Menu, Crown, ChevronDown, ChevronRight, Info, ExternalLink, CreditCard, Sparkles, Home, ChevronUp, Plus, Settings, UserCog, LogOut } from 'lucide-react';
|
|
4
|
+
import { Loader2, ChevronLeft, ArrowLeft, X, Bell, PanelLeft, PanelLeftClose, Search, CornerDownLeft, Menu, Crown, ChevronsRight, ChevronsLeft, ChevronDown, ChevronRight, Info, ExternalLink, CreditCard, Sparkles, Home, ChevronUp, Plus, Settings, UserCog, LogOut } from 'lucide-react';
|
|
5
5
|
import { useTranslation, useNavReferrer, routeModule, navHistoryBack, recordNavigation } from '@fayz-ai/core';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
@@ -215,6 +215,8 @@ var TooltipContent = React11.forwardRef(({ className, sideOffset = 4, ...props }
|
|
|
215
215
|
));
|
|
216
216
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
217
217
|
var usePageHeaderStore = create((set, get) => ({
|
|
218
|
+
moduleViewLabel: null,
|
|
219
|
+
setModuleViewLabel: (moduleViewLabel) => set((state) => state.moduleViewLabel === moduleViewLabel ? state : { moduleViewLabel }),
|
|
218
220
|
shellSlot: null,
|
|
219
221
|
setShellSlot: (element) => set({ shellSlot: element }),
|
|
220
222
|
outletSlot: null,
|
|
@@ -317,6 +319,16 @@ function usePageHeader(active, options) {
|
|
|
317
319
|
function useHasPageHeaderBack() {
|
|
318
320
|
return usePageHeaderStore((s) => s.hasBack);
|
|
319
321
|
}
|
|
322
|
+
function useModuleViewLabel() {
|
|
323
|
+
return usePageHeaderStore((s) => s.moduleViewLabel);
|
|
324
|
+
}
|
|
325
|
+
function usePublishModuleViewLabel(label) {
|
|
326
|
+
const setLabel = usePageHeaderStore((s) => s.setModuleViewLabel);
|
|
327
|
+
React11.useEffect(() => {
|
|
328
|
+
setLabel(label ?? null);
|
|
329
|
+
return () => setLabel(null);
|
|
330
|
+
}, [label, setLabel]);
|
|
331
|
+
}
|
|
320
332
|
function PageTitlePortal({ children }) {
|
|
321
333
|
const slot = usePageTitleSlot();
|
|
322
334
|
if (!slot) return React11.createElement(React11.Fragment, null, children);
|
|
@@ -555,6 +567,7 @@ function useRailFlyout({
|
|
|
555
567
|
"div",
|
|
556
568
|
{
|
|
557
569
|
ref: panelRef,
|
|
570
|
+
style: { borderTopLeftRadius: 2, borderBottomLeftRadius: 2 },
|
|
558
571
|
className: cn(
|
|
559
572
|
// Sidebar tone, sidebar border: the panel is the menu leaning out,
|
|
560
573
|
// not a popover from the page underneath it.
|
|
@@ -635,6 +648,51 @@ function FlyoutBody({
|
|
|
635
648
|
] })
|
|
636
649
|
] });
|
|
637
650
|
}
|
|
651
|
+
function NavChildConnector({ onPath, active }) {
|
|
652
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
653
|
+
onPath && /* @__PURE__ */ jsx(
|
|
654
|
+
"span",
|
|
655
|
+
{
|
|
656
|
+
"aria-hidden": true,
|
|
657
|
+
className: "pointer-events-none absolute bottom-0 left-[13px] top-0 w-[1.5px] bg-current"
|
|
658
|
+
}
|
|
659
|
+
),
|
|
660
|
+
active && /* @__PURE__ */ jsxs(
|
|
661
|
+
"svg",
|
|
662
|
+
{
|
|
663
|
+
"aria-hidden": true,
|
|
664
|
+
className: "pointer-events-none absolute left-1 top-0",
|
|
665
|
+
width: "21",
|
|
666
|
+
height: "32",
|
|
667
|
+
viewBox: "0 0 21 32",
|
|
668
|
+
fill: "none",
|
|
669
|
+
children: [
|
|
670
|
+
/* @__PURE__ */ jsx(
|
|
671
|
+
"path",
|
|
672
|
+
{
|
|
673
|
+
d: "M9.75 0 V11 Q9.75 16 14.75 16 H20",
|
|
674
|
+
stroke: "currentColor",
|
|
675
|
+
strokeWidth: "1.5",
|
|
676
|
+
strokeLinecap: "round",
|
|
677
|
+
fill: "none"
|
|
678
|
+
}
|
|
679
|
+
),
|
|
680
|
+
/* @__PURE__ */ jsx(
|
|
681
|
+
"path",
|
|
682
|
+
{
|
|
683
|
+
d: "M17 13 L20 16 L17 19",
|
|
684
|
+
stroke: "currentColor",
|
|
685
|
+
strokeWidth: "1.5",
|
|
686
|
+
strokeLinecap: "round",
|
|
687
|
+
strokeLinejoin: "round",
|
|
688
|
+
fill: "none"
|
|
689
|
+
}
|
|
690
|
+
)
|
|
691
|
+
]
|
|
692
|
+
}
|
|
693
|
+
)
|
|
694
|
+
] });
|
|
695
|
+
}
|
|
638
696
|
var RAIL_PUSH_MS = 260;
|
|
639
697
|
var useIsomorphicLayoutEffect2 = typeof window !== "undefined" ? React11.useLayoutEffect : React11.useEffect;
|
|
640
698
|
function getIcon(name) {
|
|
@@ -861,47 +919,7 @@ function NavGroup({
|
|
|
861
919
|
// to /70 when inactive, and a line fading along with the label it
|
|
862
920
|
// points AT was nearly invisible on a dark rail.
|
|
863
921
|
/* @__PURE__ */ jsxs("div", { className: "relative h-8 text-sidebar-foreground/45", children: [
|
|
864
|
-
|
|
865
|
-
"span",
|
|
866
|
-
{
|
|
867
|
-
"aria-hidden": true,
|
|
868
|
-
className: "pointer-events-none absolute bottom-0 left-[13px] top-0 w-[1.5px] bg-current"
|
|
869
|
-
}
|
|
870
|
-
),
|
|
871
|
-
isActive && /* @__PURE__ */ jsxs(
|
|
872
|
-
"svg",
|
|
873
|
-
{
|
|
874
|
-
"aria-hidden": true,
|
|
875
|
-
className: "pointer-events-none absolute left-1 top-0",
|
|
876
|
-
width: "21",
|
|
877
|
-
height: "32",
|
|
878
|
-
viewBox: "0 0 21 32",
|
|
879
|
-
fill: "none",
|
|
880
|
-
children: [
|
|
881
|
-
/* @__PURE__ */ jsx(
|
|
882
|
-
"path",
|
|
883
|
-
{
|
|
884
|
-
d: "M9.75 0 V11 Q9.75 16 14.75 16 H20",
|
|
885
|
-
stroke: "currentColor",
|
|
886
|
-
strokeWidth: "1.5",
|
|
887
|
-
strokeLinecap: "round",
|
|
888
|
-
fill: "none"
|
|
889
|
-
}
|
|
890
|
-
),
|
|
891
|
-
/* @__PURE__ */ jsx(
|
|
892
|
-
"path",
|
|
893
|
-
{
|
|
894
|
-
d: "M17 13 L20 16 L17 19",
|
|
895
|
-
stroke: "currentColor",
|
|
896
|
-
strokeWidth: "1.5",
|
|
897
|
-
strokeLinecap: "round",
|
|
898
|
-
strokeLinejoin: "round",
|
|
899
|
-
fill: "none"
|
|
900
|
-
}
|
|
901
|
-
)
|
|
902
|
-
]
|
|
903
|
-
}
|
|
904
|
-
),
|
|
922
|
+
/* @__PURE__ */ jsx(NavChildConnector, { onPath, active: isActive }),
|
|
905
923
|
row
|
|
906
924
|
] }, child.id)
|
|
907
925
|
);
|
|
@@ -2076,16 +2094,43 @@ function SidebarLayout({
|
|
|
2076
2094
|
frame && (railOpen ? "md:rounded-r-none md:border-r-0" : "md:mr-2"),
|
|
2077
2095
|
immersive && "md:overflow-hidden"
|
|
2078
2096
|
), children: [
|
|
2079
|
-
/* @__PURE__ */ jsxs(
|
|
2080
|
-
"
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2097
|
+
/* @__PURE__ */ jsxs(
|
|
2098
|
+
"div",
|
|
2099
|
+
{
|
|
2100
|
+
style: {
|
|
2101
|
+
// A RÉGUA NÃO ATRAVESSA A COLUNA DO MÓDULO.
|
|
2102
|
+
//
|
|
2103
|
+
// Ela fecha o cabeçalho, e o cabeçalho termina onde a coluna começa:
|
|
2104
|
+
// sobre a coluna, a mesma linha separava duas coisas que são uma só —
|
|
2105
|
+
// o nome da tela e o menu que pende dele. Tapar o pedaço com um pixel
|
|
2106
|
+
// da cor do papel funcionava num tema e falhava no outro, porque o
|
|
2107
|
+
// papel do cartão e o `--page-surface` nem sempre são a mesma tinta.
|
|
2108
|
+
//
|
|
2109
|
+
// Então ela NASCE depois: a régua é um degradê de 1px que só começa
|
|
2110
|
+
// em `--page-rail-seam` — a largura da coluna mais o raio da curva,
|
|
2111
|
+
// publicado por quem a desenha (ver RailColumn). Sem coluna, a
|
|
2112
|
+
// variável não existe e a régua começa em zero, como sempre.
|
|
2113
|
+
backgroundImage: "linear-gradient(to right, transparent 0 var(--page-rail-seam, 0px), hsl(var(--border)) var(--page-rail-seam, 0px) 100%)",
|
|
2114
|
+
backgroundSize: "100% 1px",
|
|
2115
|
+
backgroundRepeat: "no-repeat",
|
|
2116
|
+
backgroundPosition: "left bottom"
|
|
2117
|
+
},
|
|
2118
|
+
className: cn(
|
|
2119
|
+
// O MESMO vidro da coluna do módulo logo abaixo — uma classe só,
|
|
2120
|
+
// senão as duas superfícies encostadas saem em tons diferentes e
|
|
2121
|
+
// a emenda que acabamos de apagar volta como degrau de cor.
|
|
2122
|
+
"fz-liquid-glass relative z-20 flex min-h-12 shrink-0 items-center justify-between gap-3 px-3 md:px-6",
|
|
2123
|
+
menuOpen && "invisible md:visible"
|
|
2124
|
+
),
|
|
2125
|
+
children: [
|
|
2126
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
|
|
2127
|
+
!pageHeaderClaimed && /* @__PURE__ */ jsx(ShellPageTitle, { title: pageTitle, back: pageBack, primary: pagePrimary }),
|
|
2128
|
+
/* @__PURE__ */ jsx("div", { ref: setTitleSlot, className: "flex min-w-0 items-center empty:hidden" })
|
|
2129
|
+
] }),
|
|
2130
|
+
/* @__PURE__ */ jsx("div", { ref: setActionsSlot, className: "flex shrink-0 items-center gap-2" })
|
|
2131
|
+
]
|
|
2132
|
+
}
|
|
2133
|
+
),
|
|
2089
2134
|
/* @__PURE__ */ jsxs("div", { className: "relative flex min-w-0 min-h-0 flex-1 overflow-hidden", children: [
|
|
2090
2135
|
/* @__PURE__ */ jsx("div", { ref: setPageRailSlot, className: "flex shrink-0 empty:hidden" }),
|
|
2091
2136
|
/* @__PURE__ */ jsxs("div", { className: "relative flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden", children: [
|
|
@@ -2223,10 +2268,16 @@ function TopbarLayout({
|
|
|
2223
2268
|
(pageHeaderClaimed || pageBack || hasPageActions || barOwnsNav) && /* @__PURE__ */ jsxs(
|
|
2224
2269
|
"div",
|
|
2225
2270
|
{
|
|
2271
|
+
style: {
|
|
2272
|
+
backgroundImage: "linear-gradient(to right, transparent 0 var(--page-rail-seam, 0px), hsl(var(--border)) var(--page-rail-seam, 0px) 100%)",
|
|
2273
|
+
backgroundSize: "100% 1px",
|
|
2274
|
+
backgroundRepeat: "no-repeat",
|
|
2275
|
+
backgroundPosition: "left bottom"
|
|
2276
|
+
},
|
|
2226
2277
|
className: cn(
|
|
2227
2278
|
// `relative` + glass for the same reason as the sidebar
|
|
2228
2279
|
// layout's band: on a phone this IS the navigation bar.
|
|
2229
|
-
"relative flex min-h-[44px] md:min-h-12 shrink-0 items-center justify-between gap-3
|
|
2280
|
+
"relative flex min-h-[44px] md:min-h-12 shrink-0 items-center justify-between gap-3 px-4 py-2",
|
|
2230
2281
|
menuOpen && "invisible md:visible",
|
|
2231
2282
|
"fayz-glass-topbar",
|
|
2232
2283
|
!(pageHeaderClaimed || pageBack || hasPageActions) && "md:hidden"
|
|
@@ -3371,6 +3422,14 @@ function HeaderTabs({
|
|
|
3371
3422
|
}
|
|
3372
3423
|
);
|
|
3373
3424
|
}
|
|
3425
|
+
var PAGE_BAND_CLASS = "sticky top-0 z-20 -mx-3 -mt-3 mb-4 flex flex-nowrap items-end justify-between gap-3 border-b border-border px-3 pt-2 md:-mx-6 md:-mt-4 md:px-6 md:min-h-[2.5rem]";
|
|
3426
|
+
var PAGE_BAND_SURFACE = { background: "var(--page-surface, hsl(var(--background)))" };
|
|
3427
|
+
function PageBand({ children, actions, className }) {
|
|
3428
|
+
return /* @__PURE__ */ jsxs("div", { style: PAGE_BAND_SURFACE, className: cn(PAGE_BAND_CLASS, "items-center", className), children: [
|
|
3429
|
+
/* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 items-center gap-3", children }),
|
|
3430
|
+
actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2 empty:hidden", children: actions })
|
|
3431
|
+
] });
|
|
3432
|
+
}
|
|
3374
3433
|
function PageTabs({ actions, className, ...props }) {
|
|
3375
3434
|
return /* @__PURE__ */ jsxs(
|
|
3376
3435
|
"div",
|
|
@@ -3473,15 +3532,15 @@ function navigateToCrumb(crumb) {
|
|
|
3473
3532
|
else window.location.hash = crumb.href;
|
|
3474
3533
|
}
|
|
3475
3534
|
function useCurrentRouteHref() {
|
|
3476
|
-
const
|
|
3535
|
+
const read2 = () => {
|
|
3477
3536
|
if (typeof window === "undefined") return "";
|
|
3478
3537
|
const hash = window.location.hash.replace(/^#/, "");
|
|
3479
3538
|
const clean = hash.split("?")[0];
|
|
3480
3539
|
return clean.startsWith("/") ? clean : `/${clean}`;
|
|
3481
3540
|
};
|
|
3482
|
-
const [href, setHref] = React11.useState(
|
|
3541
|
+
const [href, setHref] = React11.useState(read2);
|
|
3483
3542
|
React11.useEffect(() => {
|
|
3484
|
-
const handler = () => setHref(
|
|
3543
|
+
const handler = () => setHref(read2());
|
|
3485
3544
|
window.addEventListener("hashchange", handler);
|
|
3486
3545
|
handler();
|
|
3487
3546
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -3496,6 +3555,241 @@ function useTrailBack(href) {
|
|
|
3496
3555
|
[parent]
|
|
3497
3556
|
);
|
|
3498
3557
|
}
|
|
3558
|
+
var COLUMN_WIDTH = 224;
|
|
3559
|
+
var COLUMN_COLLAPSED_WIDTH = 64;
|
|
3560
|
+
function read(key) {
|
|
3561
|
+
try {
|
|
3562
|
+
return localStorage.getItem(key) === "1";
|
|
3563
|
+
} catch {
|
|
3564
|
+
return false;
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3567
|
+
function CollapsibleColumn({
|
|
3568
|
+
children,
|
|
3569
|
+
storageKey,
|
|
3570
|
+
footer,
|
|
3571
|
+
squeezed,
|
|
3572
|
+
autoCollapseKey,
|
|
3573
|
+
autoCollapseMs = 1800,
|
|
3574
|
+
onWidth,
|
|
3575
|
+
className,
|
|
3576
|
+
seamTop = 12,
|
|
3577
|
+
"aria-label": ariaLabel
|
|
3578
|
+
}) {
|
|
3579
|
+
const pinnedKey = `${storageKey}.pinned`;
|
|
3580
|
+
const [collapsed, setCollapsed] = React11.useState(() => read(storageKey));
|
|
3581
|
+
const [pinned, setPinned] = React11.useState(() => read(pinnedKey));
|
|
3582
|
+
const [hovering, setHovering] = React11.useState(false);
|
|
3583
|
+
const hoveringRef = React11.useRef(false);
|
|
3584
|
+
const collapsedRef = React11.useRef(collapsed);
|
|
3585
|
+
collapsedRef.current = collapsed;
|
|
3586
|
+
const autoRef = React11.useRef(false);
|
|
3587
|
+
const open = !collapsed || hovering;
|
|
3588
|
+
const width = open ? COLUMN_WIDTH : COLUMN_COLLAPSED_WIDTH;
|
|
3589
|
+
const setHover = (on) => {
|
|
3590
|
+
hoveringRef.current = on;
|
|
3591
|
+
setHovering(on);
|
|
3592
|
+
};
|
|
3593
|
+
React11.useEffect(() => {
|
|
3594
|
+
onWidth?.(width);
|
|
3595
|
+
}, [width, onWidth]);
|
|
3596
|
+
const setOpenState = React11.useCallback((nextCollapsed) => {
|
|
3597
|
+
setCollapsed(nextCollapsed);
|
|
3598
|
+
setPinned(!nextCollapsed);
|
|
3599
|
+
autoRef.current = false;
|
|
3600
|
+
try {
|
|
3601
|
+
localStorage.setItem(storageKey, nextCollapsed ? "1" : "0");
|
|
3602
|
+
localStorage.setItem(pinnedKey, nextCollapsed ? "0" : "1");
|
|
3603
|
+
} catch {
|
|
3604
|
+
}
|
|
3605
|
+
if (nextCollapsed) setHover(false);
|
|
3606
|
+
}, [storageKey, pinnedKey]);
|
|
3607
|
+
React11.useEffect(() => {
|
|
3608
|
+
if (squeezed === void 0) return;
|
|
3609
|
+
if (squeezed) {
|
|
3610
|
+
if (!collapsedRef.current) {
|
|
3611
|
+
autoRef.current = true;
|
|
3612
|
+
setCollapsed(true);
|
|
3613
|
+
}
|
|
3614
|
+
} else if (autoRef.current) {
|
|
3615
|
+
autoRef.current = false;
|
|
3616
|
+
setCollapsed(false);
|
|
3617
|
+
}
|
|
3618
|
+
}, [squeezed]);
|
|
3619
|
+
const seen = React11.useRef(null);
|
|
3620
|
+
React11.useEffect(() => {
|
|
3621
|
+
if (autoCollapseKey === void 0) return;
|
|
3622
|
+
if (seen.current === null) {
|
|
3623
|
+
seen.current = autoCollapseKey;
|
|
3624
|
+
return;
|
|
3625
|
+
}
|
|
3626
|
+
if (seen.current === autoCollapseKey) return;
|
|
3627
|
+
seen.current = autoCollapseKey;
|
|
3628
|
+
if (collapsed || pinned) return;
|
|
3629
|
+
const t = setTimeout(() => {
|
|
3630
|
+
if (!hoveringRef.current) setCollapsed(true);
|
|
3631
|
+
}, autoCollapseMs);
|
|
3632
|
+
return () => clearTimeout(t);
|
|
3633
|
+
}, [autoCollapseKey, collapsed, pinned, autoCollapseMs]);
|
|
3634
|
+
const scrollRef = React11.useRef(null);
|
|
3635
|
+
const [hasMore, setHasMore] = React11.useState(false);
|
|
3636
|
+
const onScroll = React11.useCallback(() => {
|
|
3637
|
+
const el = scrollRef.current;
|
|
3638
|
+
if (!el) return;
|
|
3639
|
+
setHasMore(el.scrollHeight - el.scrollTop - el.clientHeight > 4);
|
|
3640
|
+
}, []);
|
|
3641
|
+
React11.useEffect(() => {
|
|
3642
|
+
onScroll();
|
|
3643
|
+
const el = scrollRef.current;
|
|
3644
|
+
if (!el) return;
|
|
3645
|
+
const ro = new ResizeObserver(onScroll);
|
|
3646
|
+
ro.observe(el);
|
|
3647
|
+
return () => {
|
|
3648
|
+
ro.disconnect();
|
|
3649
|
+
};
|
|
3650
|
+
}, [onScroll, open, children]);
|
|
3651
|
+
const boxRef = React11.useRef(null);
|
|
3652
|
+
const panelRef = React11.useRef(null);
|
|
3653
|
+
const [seamed, setSeamed] = React11.useState(false);
|
|
3654
|
+
const armedRef = React11.useRef(false);
|
|
3655
|
+
const publish = React11.useCallback(() => {
|
|
3656
|
+
if (!seamTop) return;
|
|
3657
|
+
const el = panelRef.current;
|
|
3658
|
+
const card = el?.closest(".fz-page-surface");
|
|
3659
|
+
const band = card?.firstElementChild;
|
|
3660
|
+
if (!el || !card || !band) return;
|
|
3661
|
+
const root = document.documentElement;
|
|
3662
|
+
const flush = Math.abs(el.getBoundingClientRect().top - band.getBoundingClientRect().bottom) <= 2;
|
|
3663
|
+
setSeamed(flush);
|
|
3664
|
+
if (!flush) {
|
|
3665
|
+
root.style.removeProperty("--page-rail-seam");
|
|
3666
|
+
return;
|
|
3667
|
+
}
|
|
3668
|
+
const x = el.getBoundingClientRect().right - card.getBoundingClientRect().left;
|
|
3669
|
+
if (!armedRef.current) root.style.transition = "none";
|
|
3670
|
+
root.style.setProperty("--page-rail-seam", `${x + seamTop}px`);
|
|
3671
|
+
if (!armedRef.current) {
|
|
3672
|
+
armedRef.current = true;
|
|
3673
|
+
requestAnimationFrame(() => {
|
|
3674
|
+
root.style.transition = "--page-rail-seam 200ms";
|
|
3675
|
+
});
|
|
3676
|
+
}
|
|
3677
|
+
}, [seamTop]);
|
|
3678
|
+
React11.useEffect(() => {
|
|
3679
|
+
publish();
|
|
3680
|
+
}, [publish, width]);
|
|
3681
|
+
React11.useEffect(() => {
|
|
3682
|
+
if (!seamTop) return;
|
|
3683
|
+
const el = panelRef.current;
|
|
3684
|
+
const card = el?.closest(".fz-page-surface");
|
|
3685
|
+
if (!el || !card) return;
|
|
3686
|
+
const root = document.documentElement;
|
|
3687
|
+
const ro = new ResizeObserver(publish);
|
|
3688
|
+
ro.observe(el);
|
|
3689
|
+
ro.observe(card);
|
|
3690
|
+
return () => {
|
|
3691
|
+
ro.disconnect();
|
|
3692
|
+
armedRef.current = false;
|
|
3693
|
+
root.style.transition = "none";
|
|
3694
|
+
root.style.removeProperty("--page-rail-seam");
|
|
3695
|
+
requestAnimationFrame(() => {
|
|
3696
|
+
root.style.removeProperty("transition");
|
|
3697
|
+
});
|
|
3698
|
+
};
|
|
3699
|
+
}, [publish, seamTop]);
|
|
3700
|
+
return (
|
|
3701
|
+
// A caixa RESERVA a largura; a coluna mora dentro dela, posicionada. Sem
|
|
3702
|
+
// isso, reabrir no hover empurraria o conteúdo a cada passada do ponteiro.
|
|
3703
|
+
/* @__PURE__ */ jsxs(
|
|
3704
|
+
"div",
|
|
3705
|
+
{
|
|
3706
|
+
ref: boxRef,
|
|
3707
|
+
className: cn("relative hidden shrink-0 no-print transition-[width] duration-200 md:block", className),
|
|
3708
|
+
style: { width: collapsed ? COLUMN_COLLAPSED_WIDTH : COLUMN_WIDTH },
|
|
3709
|
+
children: [
|
|
3710
|
+
/* @__PURE__ */ jsxs(
|
|
3711
|
+
"nav",
|
|
3712
|
+
{
|
|
3713
|
+
ref: panelRef,
|
|
3714
|
+
"aria-label": ariaLabel,
|
|
3715
|
+
onMouseEnter: () => setHover(true),
|
|
3716
|
+
onMouseLeave: () => setHover(false),
|
|
3717
|
+
onDoubleClick: () => {
|
|
3718
|
+
if (collapsed) setOpenState(false);
|
|
3719
|
+
},
|
|
3720
|
+
style: { width },
|
|
3721
|
+
className: cn(
|
|
3722
|
+
// O vidro é uma classe compartilhada com a faixa do cabeçalho.
|
|
3723
|
+
"fz-liquid-glass absolute inset-y-0 left-0 flex flex-col overflow-hidden p-3 transition-[width] duration-200",
|
|
3724
|
+
collapsed && hovering && "z-30 shadow-xl"
|
|
3725
|
+
),
|
|
3726
|
+
children: [
|
|
3727
|
+
/* @__PURE__ */ jsx(
|
|
3728
|
+
"span",
|
|
3729
|
+
{
|
|
3730
|
+
"aria-hidden": true,
|
|
3731
|
+
className: "pointer-events-none absolute right-0 w-px",
|
|
3732
|
+
style: { top: seamTop, bottom: 0, background: "hsl(var(--border))" }
|
|
3733
|
+
}
|
|
3734
|
+
),
|
|
3735
|
+
/* @__PURE__ */ jsxs("div", { className: "relative min-h-0 flex-1", children: [
|
|
3736
|
+
/* @__PURE__ */ jsx("div", { ref: scrollRef, onScroll, className: "scrollbar-none h-full overflow-y-auto overflow-x-hidden", children: children({ collapsed: !open }) }),
|
|
3737
|
+
/* @__PURE__ */ jsx(
|
|
3738
|
+
"div",
|
|
3739
|
+
{
|
|
3740
|
+
"aria-hidden": true,
|
|
3741
|
+
className: cn(
|
|
3742
|
+
"pointer-events-none absolute inset-x-0 bottom-0 h-8 transition-opacity duration-200",
|
|
3743
|
+
hasMore ? "opacity-100" : "opacity-0"
|
|
3744
|
+
),
|
|
3745
|
+
style: { backgroundImage: "linear-gradient(to top, var(--page-surface, hsl(var(--background))), transparent)" }
|
|
3746
|
+
}
|
|
3747
|
+
)
|
|
3748
|
+
] }),
|
|
3749
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-2 flex shrink-0 items-center gap-2 border-t border-border pt-2", children: [
|
|
3750
|
+
open && footer && /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: footer }),
|
|
3751
|
+
/* @__PURE__ */ jsx(
|
|
3752
|
+
"button",
|
|
3753
|
+
{
|
|
3754
|
+
type: "button",
|
|
3755
|
+
onClick: () => setOpenState(!collapsed),
|
|
3756
|
+
"aria-label": collapsed ? "Expandir menu" : "Recolher menu",
|
|
3757
|
+
title: collapsed ? "Expandir menu" : "Recolher menu",
|
|
3758
|
+
"aria-expanded": !collapsed,
|
|
3759
|
+
className: "flex h-8 w-full items-center justify-end rounded-button bg-transparent px-2.5 text-muted-foreground transition-colors hover:bg-muted/60 hover:text-foreground",
|
|
3760
|
+
children: collapsed ? /* @__PURE__ */ jsx(ChevronsRight, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronsLeft, { className: "h-4 w-4" })
|
|
3761
|
+
}
|
|
3762
|
+
)
|
|
3763
|
+
] })
|
|
3764
|
+
]
|
|
3765
|
+
}
|
|
3766
|
+
),
|
|
3767
|
+
seamed && /* @__PURE__ */ jsx(
|
|
3768
|
+
"svg",
|
|
3769
|
+
{
|
|
3770
|
+
"aria-hidden": true,
|
|
3771
|
+
className: "pointer-events-none absolute top-0",
|
|
3772
|
+
style: { left: `${width - 1}px`, marginTop: "-1px", zIndex: 25, transition: "left 200ms" },
|
|
3773
|
+
width: seamTop,
|
|
3774
|
+
height: seamTop,
|
|
3775
|
+
viewBox: `0 0 ${seamTop} ${seamTop}`,
|
|
3776
|
+
fill: "none",
|
|
3777
|
+
children: /* @__PURE__ */ jsx(
|
|
3778
|
+
"path",
|
|
3779
|
+
{
|
|
3780
|
+
d: `M ${seamTop} 0.5 Q 0.5 0.5 0.5 ${seamTop}`,
|
|
3781
|
+
stroke: "hsl(var(--border))",
|
|
3782
|
+
strokeWidth: "1",
|
|
3783
|
+
fill: "none"
|
|
3784
|
+
}
|
|
3785
|
+
)
|
|
3786
|
+
}
|
|
3787
|
+
)
|
|
3788
|
+
]
|
|
3789
|
+
}
|
|
3790
|
+
)
|
|
3791
|
+
);
|
|
3792
|
+
}
|
|
3499
3793
|
function PageRail({ children }) {
|
|
3500
3794
|
const slot = usePageRailSlot();
|
|
3501
3795
|
if (slot) return createPortal(children, slot);
|
|
@@ -3539,6 +3833,159 @@ function PageViewBar({ children }) {
|
|
|
3539
3833
|
if (slot) return createPortal(children, slot);
|
|
3540
3834
|
return /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center justify-end gap-2", children });
|
|
3541
3835
|
}
|
|
3836
|
+
var SUB_NAV_STYLE = "nested";
|
|
3837
|
+
function RailSections({ sections, search, collapsed }) {
|
|
3838
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3839
|
+
search && !collapsed && /* @__PURE__ */ jsxs("div", { className: "relative mb-2", children: [
|
|
3840
|
+
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-1 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }),
|
|
3841
|
+
/* @__PURE__ */ jsx(
|
|
3842
|
+
"input",
|
|
3843
|
+
{
|
|
3844
|
+
type: "search",
|
|
3845
|
+
value: search.value,
|
|
3846
|
+
onChange: (e) => search.onChange(e.target.value),
|
|
3847
|
+
placeholder: search.placeholder,
|
|
3848
|
+
"aria-label": search.placeholder,
|
|
3849
|
+
className: "h-8 w-full border-0 bg-transparent pl-7 pr-2 text-[13px] outline-none placeholder:text-muted-foreground focus:ring-0"
|
|
3850
|
+
}
|
|
3851
|
+
)
|
|
3852
|
+
] }),
|
|
3853
|
+
sections.map((section, i) => /* @__PURE__ */ jsxs("div", { className: i > 0 ? "mt-3 border-t border-border pt-3" : void 0, children: [
|
|
3854
|
+
section.heading && !collapsed && /* @__PURE__ */ jsx("p", { className: "px-3 pb-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: section.heading }),
|
|
3855
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: section.items.map((item) => /* @__PURE__ */ jsx(RailNavItem, { item, collapsed }, item.id)) })
|
|
3856
|
+
] }, section.key ?? i))
|
|
3857
|
+
] });
|
|
3858
|
+
}
|
|
3859
|
+
var RAIL_COLLAPSED_KEY = "fayz.subnav.collapsed";
|
|
3860
|
+
function RailColumn({ className, "aria-label": ariaLabel, sections, search, footer }) {
|
|
3861
|
+
const boxRef = React11.useRef(null);
|
|
3862
|
+
const [squeezed, setSqueezed] = React11.useState(void 0);
|
|
3863
|
+
React11.useEffect(() => {
|
|
3864
|
+
if (typeof window === "undefined") return;
|
|
3865
|
+
const row = boxRef.current?.parentElement?.parentElement;
|
|
3866
|
+
if (!row) return;
|
|
3867
|
+
const COLLAPSE_BELOW = 560;
|
|
3868
|
+
const RESTORE_ABOVE = 820;
|
|
3869
|
+
let timer;
|
|
3870
|
+
const decide = () => {
|
|
3871
|
+
const content = row.clientWidth - COLUMN_WIDTH;
|
|
3872
|
+
if (content < COLLAPSE_BELOW) setSqueezed(true);
|
|
3873
|
+
else if (content > RESTORE_ABOVE) setSqueezed(false);
|
|
3874
|
+
};
|
|
3875
|
+
const apply = () => {
|
|
3876
|
+
if (timer) clearTimeout(timer);
|
|
3877
|
+
timer = setTimeout(decide, 180);
|
|
3878
|
+
};
|
|
3879
|
+
apply();
|
|
3880
|
+
const ro = new ResizeObserver(apply);
|
|
3881
|
+
ro.observe(row);
|
|
3882
|
+
window.addEventListener("resize", apply);
|
|
3883
|
+
return () => {
|
|
3884
|
+
if (timer) clearTimeout(timer);
|
|
3885
|
+
ro.disconnect();
|
|
3886
|
+
window.removeEventListener("resize", apply);
|
|
3887
|
+
};
|
|
3888
|
+
}, []);
|
|
3889
|
+
const activeKey = sections.flatMap((sec) => sec.items).filter((i) => i.active).map((i) => i.id).join("|");
|
|
3890
|
+
return /* @__PURE__ */ jsx("div", { ref: boxRef, className: "contents", children: /* @__PURE__ */ jsx(
|
|
3891
|
+
CollapsibleColumn,
|
|
3892
|
+
{
|
|
3893
|
+
"aria-label": ariaLabel,
|
|
3894
|
+
storageKey: RAIL_COLLAPSED_KEY,
|
|
3895
|
+
className,
|
|
3896
|
+
footer,
|
|
3897
|
+
squeezed,
|
|
3898
|
+
autoCollapseKey: activeKey,
|
|
3899
|
+
children: ({ collapsed }) => /* @__PURE__ */ jsx(RailSections, { sections, search, collapsed })
|
|
3900
|
+
}
|
|
3901
|
+
) });
|
|
3902
|
+
}
|
|
3903
|
+
var published = [];
|
|
3904
|
+
var subNavHosts = 0;
|
|
3905
|
+
var subNavListeners = /* @__PURE__ */ new Set();
|
|
3906
|
+
var subNavNotify = () => subNavListeners.forEach((l) => l());
|
|
3907
|
+
var subNavSubscribe = (l) => {
|
|
3908
|
+
subNavListeners.add(l);
|
|
3909
|
+
return () => {
|
|
3910
|
+
subNavListeners.delete(l);
|
|
3911
|
+
};
|
|
3912
|
+
};
|
|
3913
|
+
function publishSubNav(entry) {
|
|
3914
|
+
const i = published.findIndex((p) => p.id === entry.id);
|
|
3915
|
+
published = i < 0 ? [...published, entry] : published.map((p, n) => n === i ? entry : p);
|
|
3916
|
+
subNavNotify();
|
|
3917
|
+
}
|
|
3918
|
+
function unpublishSubNav(id) {
|
|
3919
|
+
published = published.filter((p) => p.id !== id);
|
|
3920
|
+
subNavNotify();
|
|
3921
|
+
}
|
|
3922
|
+
function useSubNavPublished() {
|
|
3923
|
+
return React11.useSyncExternalStore(subNavSubscribe, () => published, () => published);
|
|
3924
|
+
}
|
|
3925
|
+
function useSubNavHost() {
|
|
3926
|
+
React11.useEffect(() => {
|
|
3927
|
+
subNavHosts++;
|
|
3928
|
+
subNavNotify();
|
|
3929
|
+
return () => {
|
|
3930
|
+
subNavHosts--;
|
|
3931
|
+
subNavNotify();
|
|
3932
|
+
};
|
|
3933
|
+
}, []);
|
|
3934
|
+
}
|
|
3935
|
+
function useHasSubNavHost() {
|
|
3936
|
+
return React11.useSyncExternalStore(subNavSubscribe, () => subNavHosts > 0, () => false);
|
|
3937
|
+
}
|
|
3938
|
+
function SubNavBand({ sections, "aria-label": ariaLabel, className }) {
|
|
3939
|
+
const items = sections.flatMap((s) => s.items);
|
|
3940
|
+
const value = items.find((i) => i.active)?.id ?? items[0]?.id;
|
|
3941
|
+
if (!value) return null;
|
|
3942
|
+
return /* @__PURE__ */ jsx(
|
|
3943
|
+
ViewTabs,
|
|
3944
|
+
{
|
|
3945
|
+
className,
|
|
3946
|
+
"aria-label": ariaLabel,
|
|
3947
|
+
options: items.map((i) => ({ value: i.id, label: i.label })),
|
|
3948
|
+
value,
|
|
3949
|
+
onChange: (id) => items.find((i) => i.id === id)?.onClick?.()
|
|
3950
|
+
}
|
|
3951
|
+
);
|
|
3952
|
+
}
|
|
3953
|
+
function SubNavBandHost({ leading, label }) {
|
|
3954
|
+
useSubNavHost();
|
|
3955
|
+
const pubs = useSubNavPublished();
|
|
3956
|
+
const sections = leading ?? pubs.flatMap((p) => p.sections);
|
|
3957
|
+
if (sections.length === 0) return null;
|
|
3958
|
+
return /* @__PURE__ */ jsx(
|
|
3959
|
+
"div",
|
|
3960
|
+
{
|
|
3961
|
+
style: { marginTop: "0.5rem" },
|
|
3962
|
+
className: "flex min-w-0 items-center gap-3",
|
|
3963
|
+
children: /* @__PURE__ */ jsx(SubNavBand, { sections, "aria-label": leading ? label : pubs[0]?.label })
|
|
3964
|
+
}
|
|
3965
|
+
);
|
|
3966
|
+
}
|
|
3967
|
+
function PageSubNav({ items, sections, search, footer, style, "aria-label": ariaLabel }) {
|
|
3968
|
+
const id = React11.useId();
|
|
3969
|
+
const hasHost = useHasSubNavHost();
|
|
3970
|
+
const resolved = sections ?? (items ? [{ items }] : []);
|
|
3971
|
+
const ref = React11.useRef(resolved);
|
|
3972
|
+
ref.current = resolved;
|
|
3973
|
+
const signature = JSON.stringify(resolved.map((s) => [s.key, s.heading, s.items.map((i) => [i.id, i.label, i.icon, !!i.active, !!i.premium])]));
|
|
3974
|
+
React11.useEffect(() => {
|
|
3975
|
+
publishSubNav({ id, label: ariaLabel, sections: ref.current });
|
|
3976
|
+
return () => unpublishSubNav(id);
|
|
3977
|
+
}, [id, ariaLabel, signature]);
|
|
3978
|
+
if (resolved.every((s) => s.items.length === 0)) return null;
|
|
3979
|
+
if (hasHost) return null;
|
|
3980
|
+
const asRail = (style ?? SUB_NAV_STYLE) === "nested";
|
|
3981
|
+
if (!asRail) {
|
|
3982
|
+
return /* @__PURE__ */ jsx("div", { className: "mb-4 flex min-w-0 items-center gap-3", children: /* @__PURE__ */ jsx(SubNavBand, { sections: resolved, "aria-label": ariaLabel }) });
|
|
3983
|
+
}
|
|
3984
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3985
|
+
/* @__PURE__ */ jsx(PageRail, { children: /* @__PURE__ */ jsx(RailColumn, { sections: resolved, search, footer, "aria-label": ariaLabel }) }),
|
|
3986
|
+
/* @__PURE__ */ jsx("div", { className: "mb-4 flex min-w-0 items-center gap-3 md:hidden", children: /* @__PURE__ */ jsx(SubNavBand, { sections: resolved, "aria-label": ariaLabel }) })
|
|
3987
|
+
] });
|
|
3988
|
+
}
|
|
3542
3989
|
function PageHeaderActions({ children }) {
|
|
3543
3990
|
const outlet = usePageActionsOutletSlot();
|
|
3544
3991
|
const shellSlot = useModuleHeaderActionsSlot();
|
|
@@ -3559,8 +4006,11 @@ function ModuleLayoutProvider({ variant, children }) {
|
|
|
3559
4006
|
function useModuleLayout() {
|
|
3560
4007
|
return React11.useContext(ModuleLayoutContext);
|
|
3561
4008
|
}
|
|
3562
|
-
function RailNavItem({ item }) {
|
|
3563
|
-
const [expanded, setExpanded] = React11.useState(
|
|
4009
|
+
function RailNavItem({ item, collapsed }) {
|
|
4010
|
+
const [expanded, setExpanded] = React11.useState(false);
|
|
4011
|
+
React11.useEffect(() => {
|
|
4012
|
+
if (collapsed) setExpanded(false);
|
|
4013
|
+
}, [collapsed]);
|
|
3564
4014
|
const Icon = item.icon ? ICON_MAP[item.icon] ?? null : null;
|
|
3565
4015
|
const hasChildren = item.children && item.children.length > 0;
|
|
3566
4016
|
const hasActiveChild = hasChildren && item.children.some((c) => c.active);
|
|
@@ -3571,36 +4021,53 @@ function RailNavItem({ item }) {
|
|
|
3571
4021
|
{
|
|
3572
4022
|
type: "button",
|
|
3573
4023
|
"data-tour": `modnav.${item.id}`,
|
|
3574
|
-
onClick: () => hasChildren ? setExpanded(!expanded) : item.onClick?.(),
|
|
4024
|
+
onClick: () => hasChildren && !collapsed ? setExpanded(!expanded) : item.onClick?.(),
|
|
4025
|
+
title: collapsed ? item.label : void 0,
|
|
3575
4026
|
className: cn(
|
|
3576
|
-
|
|
4027
|
+
// `px-2.5` NOS DOIS estados: centralizado, o ícone da tira ficava 2px
|
|
4028
|
+
// à direita do mesmo ícone com a coluna aberta, e todos eles davam um
|
|
4029
|
+
// pulinho lateral quando o ponteiro chegava. O recuo é o mesmo; o que
|
|
4030
|
+
// muda é só o rótulo aparecer.
|
|
4031
|
+
// ALTURA FIXA. Com `py-1.5` a linha media o que tinha dentro: 32px com
|
|
4032
|
+
// rótulo (a entrelinha do texto) e 28px só com o ícone — então cada
|
|
4033
|
+
// linha da tira caía num y diferente do da coluna aberta, e a lista
|
|
4034
|
+
// inteira escorregava quando o ponteiro chegava. `h-8` nos dois.
|
|
4035
|
+
"flex h-8 w-full items-center gap-2 rounded-md px-2.5 text-sm transition-colors",
|
|
3577
4036
|
isActive ? "bg-primary/10 text-primary font-medium" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
|
|
3578
4037
|
),
|
|
3579
4038
|
children: [
|
|
3580
4039
|
Icon && /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
3581
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left
|
|
3582
|
-
item.premium && /* @__PURE__ */ jsx(PremiumBadge, { className: "ml-1" }),
|
|
3583
|
-
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" }))
|
|
4040
|
+
!collapsed && /* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-left", children: item.label }),
|
|
4041
|
+
!collapsed && item.premium && /* @__PURE__ */ jsx(PremiumBadge, { className: "ml-1" }),
|
|
4042
|
+
!collapsed && 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" }))
|
|
3584
4043
|
]
|
|
3585
4044
|
}
|
|
3586
4045
|
),
|
|
3587
|
-
hasChildren && expanded && /* @__PURE__ */ jsx("div", { className: "
|
|
3588
|
-
|
|
3589
|
-
{
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
4046
|
+
hasChildren && expanded && !collapsed && /* @__PURE__ */ jsx("div", { className: "relative mt-0.5 text-muted-foreground/45", children: item.children.map((child, i) => {
|
|
4047
|
+
const activeIndex = item.children.findIndex((c) => c.active);
|
|
4048
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative h-8", children: [
|
|
4049
|
+
/* @__PURE__ */ jsx(NavChildConnector, { onPath: activeIndex >= 0 && i < activeIndex, active: !!child.active }),
|
|
4050
|
+
/* @__PURE__ */ jsxs(
|
|
4051
|
+
"button",
|
|
4052
|
+
{
|
|
4053
|
+
type: "button",
|
|
4054
|
+
"data-tour": `modnav.${child.id}`,
|
|
4055
|
+
onClick: child.onClick,
|
|
4056
|
+
className: cn(
|
|
4057
|
+
// `pl-11` passa da ponta da seta (~24px) com folga, para as
|
|
4058
|
+
// filhas lerem como UMA coluna indentada em vez de apertarem
|
|
4059
|
+
// a linha que aponta para elas.
|
|
4060
|
+
"flex h-8 w-full items-center rounded-button pl-11 pr-1 text-sm transition-colors",
|
|
4061
|
+
child.active ? "font-medium text-primary" : "text-muted-foreground hover:text-foreground"
|
|
4062
|
+
),
|
|
4063
|
+
children: [
|
|
4064
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-left", children: child.label }),
|
|
4065
|
+
child.premium && /* @__PURE__ */ jsx(PremiumBadge, { className: "ml-1" })
|
|
4066
|
+
]
|
|
4067
|
+
}
|
|
4068
|
+
)
|
|
4069
|
+
] }, child.id);
|
|
4070
|
+
}) })
|
|
3604
4071
|
] });
|
|
3605
4072
|
}
|
|
3606
4073
|
function defaultChildOf(item) {
|
|
@@ -3796,11 +4263,18 @@ function ShellSubpageHeader({
|
|
|
3796
4263
|
/* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsx("div", { className: "no-print flex shrink-0 items-center gap-2", children: actions }) })
|
|
3797
4264
|
] });
|
|
3798
4265
|
}
|
|
4266
|
+
function ModuleSubBand({ nav }) {
|
|
4267
|
+
useSubNavHost();
|
|
4268
|
+
const pubs = useSubNavPublished();
|
|
4269
|
+
const activeItem = nav.find((item) => item.active || item.children?.some((c) => c.active));
|
|
4270
|
+
const kids = (activeItem?.children ?? []).filter((c) => c.kind !== "action");
|
|
4271
|
+
kids.find((c) => c.active)?.id ?? kids[0]?.id;
|
|
4272
|
+
const own = [];
|
|
4273
|
+
const sections = own.length ? own : pubs.flatMap((p) => p.sections);
|
|
4274
|
+
if (sections.every((sec) => sec.items.length === 0)) return null;
|
|
4275
|
+
return /* @__PURE__ */ jsx(PageBand, { actions: /* @__PURE__ */ jsx(ViewBarHost, {}), children: /* @__PURE__ */ jsx(SubNavBand, { sections, "aria-label": own.length ? activeItem?.label : pubs[0]?.label }) });
|
|
4276
|
+
}
|
|
3799
4277
|
function ModuleHeader({ nav }) {
|
|
3800
|
-
function defaultChild(item) {
|
|
3801
|
-
const kids2 = (item.children ?? []).filter((c) => c.kind !== "action");
|
|
3802
|
-
return kids2.find((c) => /list/i.test(c.id) || /^list$/i.test(c.label)) ?? kids2[kids2.length - 1];
|
|
3803
|
-
}
|
|
3804
4278
|
const activeItem = nav.find((item) => item.active || item.children?.some((c) => c.active));
|
|
3805
4279
|
const tabs = nav.map((item) => ({
|
|
3806
4280
|
value: item.id,
|
|
@@ -3814,23 +4288,12 @@ function ModuleHeader({ nav }) {
|
|
|
3814
4288
|
const item = nav.find((n) => n.id === id);
|
|
3815
4289
|
if (!item) return;
|
|
3816
4290
|
const hasChildren = item.children && item.children.length > 0;
|
|
3817
|
-
if (hasChildren)
|
|
4291
|
+
if (hasChildren) defaultChildOf(item)?.onClick?.();
|
|
3818
4292
|
else item.onClick?.();
|
|
3819
4293
|
};
|
|
3820
4294
|
const kids = (activeItem?.children ?? []).filter((c) => c.kind !== "action");
|
|
3821
4295
|
const activeKid = kids.find((c) => c.active)?.id ?? kids[0]?.id;
|
|
3822
|
-
const
|
|
3823
|
-
/* @__PURE__ */ jsx(
|
|
3824
|
-
ViewTabs,
|
|
3825
|
-
{
|
|
3826
|
-
"aria-label": activeItem?.label,
|
|
3827
|
-
options: kids.map((c) => ({ value: c.id, label: c.label })),
|
|
3828
|
-
value: activeKid,
|
|
3829
|
-
onChange: (id) => kids.find((c) => c.id === id)?.onClick?.()
|
|
3830
|
-
}
|
|
3831
|
-
),
|
|
3832
|
-
/* @__PURE__ */ jsx("span", {})
|
|
3833
|
-
] }) : void 0;
|
|
4296
|
+
const childNav = kids.length > 1 && activeKid ? [{ items: kids.map((c) => ({ id: c.id, label: c.label, icon: c.icon, premium: c.premium, active: c.id === activeKid, onClick: c.onClick })) }] : void 0;
|
|
3834
4297
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3835
4298
|
/* @__PURE__ */ jsx(
|
|
3836
4299
|
PageTabs,
|
|
@@ -3842,7 +4305,7 @@ function ModuleHeader({ nav }) {
|
|
|
3842
4305
|
actions: /* @__PURE__ */ jsx(ViewBarHost, {})
|
|
3843
4306
|
}
|
|
3844
4307
|
),
|
|
3845
|
-
|
|
4308
|
+
/* @__PURE__ */ jsx(SubNavBandHost, { leading: childNav, label: activeItem?.label })
|
|
3846
4309
|
] });
|
|
3847
4310
|
}
|
|
3848
4311
|
function ModulePage({ title: _title, subtitle, nav, children, className, headerAction, showHeader = true, sidebarFooter, navVariant, viewKey, direction, navFilterPlaceholder }) {
|
|
@@ -3861,6 +4324,16 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
|
|
|
3861
4324
|
}, [nav, navQuery]);
|
|
3862
4325
|
const transitionKey = viewKey ?? "view";
|
|
3863
4326
|
const onSubpage = useHasPageHeaderBack();
|
|
4327
|
+
const activeLabel = React11.useMemo(() => {
|
|
4328
|
+
if (onSubpage) return null;
|
|
4329
|
+
for (const item of nav) {
|
|
4330
|
+
const kid = item.children?.find((c) => c.active);
|
|
4331
|
+
if (kid) return kid.label === item.label ? item.label : `${item.label} \u203A ${kid.label}`;
|
|
4332
|
+
if (item.active) return item.label;
|
|
4333
|
+
}
|
|
4334
|
+
return null;
|
|
4335
|
+
}, [nav, onSubpage]);
|
|
4336
|
+
usePublishModuleViewLabel(activeLabel);
|
|
3864
4337
|
if (variant === "sidebar") {
|
|
3865
4338
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3866
4339
|
showHeader && headerAction && /* @__PURE__ */ jsx(PageHeaderActions, { children: headerAction }),
|
|
@@ -3875,32 +4348,23 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
|
|
|
3875
4348
|
] });
|
|
3876
4349
|
}
|
|
3877
4350
|
return /* @__PURE__ */ jsxs("div", { className: cn("min-w-0", className), children: [
|
|
3878
|
-
/* @__PURE__ */ jsx(PageRail, { children: /* @__PURE__ */
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
onChange: (e) => setNavQuery(e.target.value),
|
|
3887
|
-
placeholder: navFilterPlaceholder,
|
|
3888
|
-
"aria-label": navFilterPlaceholder,
|
|
3889
|
-
className: "h-8 w-full border-0 bg-transparent pl-7 pr-2 text-[13px] outline-none placeholder:text-muted-foreground focus:ring-0"
|
|
3890
|
-
}
|
|
3891
|
-
)
|
|
3892
|
-
] }),
|
|
3893
|
-
/* @__PURE__ */ jsx("nav", { className: "space-y-0.5", children: filteredNav.map((item) => /* @__PURE__ */ jsx(RailNavItem, { item }, item.id)) }),
|
|
3894
|
-
sidebarFooter && /* @__PURE__ */ jsx("div", { className: "mt-auto pt-3", children: sidebarFooter })
|
|
3895
|
-
] }) }),
|
|
4351
|
+
/* @__PURE__ */ jsx(PageRail, { children: /* @__PURE__ */ jsx(
|
|
4352
|
+
RailColumn,
|
|
4353
|
+
{
|
|
4354
|
+
sections: [{ items: filteredNav }],
|
|
4355
|
+
search: navFilterPlaceholder ? { value: navQuery, onChange: setNavQuery, placeholder: navFilterPlaceholder } : void 0,
|
|
4356
|
+
footer: sidebarFooter
|
|
4357
|
+
}
|
|
4358
|
+
) }),
|
|
3896
4359
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
3897
4360
|
showHeader && headerAction && /* @__PURE__ */ jsx(PageHeaderActions, { children: headerAction }),
|
|
3898
4361
|
!onSubpage && /* @__PURE__ */ jsx(MobileTabs, { nav }),
|
|
4362
|
+
!onSubpage && /* @__PURE__ */ jsx(ModuleSubBand, { nav }),
|
|
3899
4363
|
/* @__PURE__ */ jsx(PageTransition, { transitionKey, direction, children })
|
|
3900
4364
|
] })
|
|
3901
4365
|
] });
|
|
3902
4366
|
}
|
|
3903
4367
|
|
|
3904
|
-
export { AppShell, BackStyleProvider, BottomSheet, HeaderTabs, Hint, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageHeader, PageHeaderActions, PageHeaderCrumb, PageHeaderOutlet, PageRail, PageTabs, PageTitlePortal, PageTrail, PageTransition, PageViewBar, RailNavItem, SaveBar, SaveBarProvider, SheetCard, SheetRow, ShellSearch, Sidebar, SubpageHeader, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Topbar, ViewTabs, bottomNavReachesAll, isCreateRoute, navigateToCrumb, useBackHandler, useBackStyle, useCrossModuleBack, useCurrentRouteHref, useHasPageActions, useHasPageHeaderBack, useHasPageHeaderHost, useHasPageHeaderOutlet, useLayoutStore, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useNavTransition, usePageHeader, usePageHeaderClaimed, usePageHeaderHost, usePageTrail, usePageTrailParent, useRailRow, useRegisterPageActions, useSaveBar, useSaveBarVisible, useSheetClose, useSheetDrag, useTrailBack };
|
|
3905
|
-
//# sourceMappingURL=chunk-
|
|
3906
|
-
//# sourceMappingURL=chunk-
|
|
4368
|
+
export { AppShell, BackStyleProvider, BottomSheet, COLUMN_WIDTH, CollapsibleColumn, HeaderTabs, Hint, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageHeader, PageHeaderActions, PageHeaderCrumb, PageHeaderOutlet, PageRail, PageSubNav, PageTabs, PageTitlePortal, PageTrail, PageTransition, PageViewBar, RailColumn, RailNavItem, SUB_NAV_STYLE, SaveBar, SaveBarProvider, SheetCard, SheetRow, ShellSearch, Sidebar, SubpageHeader, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Topbar, ViewTabs, bottomNavReachesAll, isCreateRoute, navigateToCrumb, useBackHandler, useBackStyle, useCrossModuleBack, useCurrentRouteHref, useHasPageActions, useHasPageHeaderBack, useHasPageHeaderHost, useHasPageHeaderOutlet, useLayoutStore, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useModuleViewLabel, useNavTransition, usePageHeader, usePageHeaderClaimed, usePageHeaderHost, usePageTrail, usePageTrailParent, usePublishModuleViewLabel, useRailRow, useRegisterPageActions, useSaveBar, useSaveBarVisible, useSheetClose, useSheetDrag, useTrailBack };
|
|
4369
|
+
//# sourceMappingURL=chunk-33A7SN2N.js.map
|
|
4370
|
+
//# sourceMappingURL=chunk-33A7SN2N.js.map
|