@fayz-ai/ui 0.31.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-VBYFN5ZL.js → chunk-33A7SN2N.js} +693 -173
- package/dist/chunk-33A7SN2N.js.map +1 -0
- package/dist/{chunk-ABY2HXG4.js → chunk-6GWXDVCO.js} +223 -27
- package/dist/chunk-6GWXDVCO.js.map +1 -0
- package/dist/{chunk-VDAYIQX4.js → chunk-C6PW5C5Q.js} +3 -3
- package/dist/chunk-C6PW5C5Q.js.map +1 -0
- package/dist/{chunk-NTPQRDJF.js → chunk-Q2B5RPH5.js} +13 -16
- package/dist/chunk-Q2B5RPH5.js.map +1 -0
- package/dist/{chunk-UDY4KJRX.js → chunk-UNEEY5XG.js} +7 -5
- package/dist/chunk-UNEEY5XG.js.map +1 -0
- 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 +9 -9
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/ModulePage.d.ts +55 -2
- package/dist/layout/ModulePage.d.ts.map +1 -1
- package/dist/layout/Sidebar.d.ts +6 -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/data-table.d.ts +10 -1
- package/dist/primitives/data-table.d.ts.map +1 -1
- package/dist/primitives/date-picker.d.ts +6 -1
- package/dist/primitives/date-picker.d.ts.map +1 -1
- 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/input.d.ts.map +1 -1
- package/dist/primitives/list-view.d.ts +3 -1
- package/dist/primitives/list-view.d.ts.map +1 -1
- package/dist/primitives/nav-connector.d.ts +23 -0
- package/dist/primitives/nav-connector.d.ts.map +1 -0
- package/dist/primitives/phone-field.d.ts.map +1 -1
- 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 +35 -1
- package/dist/stores/page-header.store.d.ts.map +1 -1
- package/dist/styles.css +66 -1
- package/dist/theme/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-ABY2HXG4.js.map +0 -1
- package/dist/chunk-NTPQRDJF.js.map +0 -1
- package/dist/chunk-UDY4KJRX.js.map +0 -1
- package/dist/chunk-VBYFN5ZL.js.map +0 -1
- package/dist/chunk-VDAYIQX4.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,10 +215,14 @@ 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,
|
|
221
223
|
setOutletSlot: (element) => set({ outletSlot: element }),
|
|
224
|
+
outletActionsSlot: null,
|
|
225
|
+
setOutletActionsSlot: (element) => set({ outletActionsSlot: element }),
|
|
222
226
|
claimed: false,
|
|
223
227
|
owner: null,
|
|
224
228
|
hasBack: false,
|
|
@@ -253,6 +257,9 @@ function usePageHeaderClaimed() {
|
|
|
253
257
|
function usePageTitleSlot() {
|
|
254
258
|
return usePageHeaderStore((s) => s.outletSlot ?? s.shellSlot);
|
|
255
259
|
}
|
|
260
|
+
function usePageActionsOutletSlot() {
|
|
261
|
+
return usePageHeaderStore((s) => s.outletActionsSlot);
|
|
262
|
+
}
|
|
256
263
|
function usePageTitleSlotHost() {
|
|
257
264
|
return usePageHeaderStore((s) => s.setShellSlot);
|
|
258
265
|
}
|
|
@@ -270,19 +277,30 @@ function useHasPageHeaderHost() {
|
|
|
270
277
|
function useHasPageHeaderOutlet() {
|
|
271
278
|
return usePageHeaderStore((s) => s.outlets > 0);
|
|
272
279
|
}
|
|
273
|
-
function PageHeaderOutlet({ className }) {
|
|
280
|
+
function PageHeaderOutlet({ className, active = true }) {
|
|
274
281
|
const setOutletSlot = usePageHeaderStore((s) => s.setOutletSlot);
|
|
282
|
+
const setOutletActionsSlot = usePageHeaderStore((s) => s.setOutletActionsSlot);
|
|
275
283
|
const claimed = usePageHeaderStore((s) => s.claimed);
|
|
284
|
+
const hasActions = usePageHeaderStore((s) => s.actions > 0);
|
|
276
285
|
const addOutlet = usePageHeaderStore((s) => s.addOutlet);
|
|
277
286
|
const removeOutlet = usePageHeaderStore((s) => s.removeOutlet);
|
|
278
287
|
React11.useEffect(() => {
|
|
288
|
+
if (!active) return;
|
|
279
289
|
addOutlet();
|
|
280
290
|
return removeOutlet;
|
|
281
|
-
}, [addOutlet, removeOutlet]);
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
291
|
+
}, [active, addOutlet, removeOutlet]);
|
|
292
|
+
React11.useEffect(() => {
|
|
293
|
+
if (active) return;
|
|
294
|
+
setOutletSlot(null);
|
|
295
|
+
setOutletActionsSlot(null);
|
|
296
|
+
}, [active, setOutletSlot, setOutletActionsSlot]);
|
|
297
|
+
if (!active) return null;
|
|
298
|
+
return React11.createElement(
|
|
299
|
+
"div",
|
|
300
|
+
{ className: `flex min-h-9 items-center justify-between gap-3${claimed || hasActions ? "" : " hidden"} ${className ?? "mb-3"}` },
|
|
301
|
+
React11.createElement("div", { ref: setOutletSlot, className: "flex min-w-0 flex-1 items-center" }),
|
|
302
|
+
React11.createElement("div", { ref: setOutletActionsSlot, className: "flex shrink-0 items-center gap-2" })
|
|
303
|
+
);
|
|
286
304
|
}
|
|
287
305
|
function usePageHeader(active, options) {
|
|
288
306
|
const id = React11.useId();
|
|
@@ -301,6 +319,16 @@ function usePageHeader(active, options) {
|
|
|
301
319
|
function useHasPageHeaderBack() {
|
|
302
320
|
return usePageHeaderStore((s) => s.hasBack);
|
|
303
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
|
+
}
|
|
304
332
|
function PageTitlePortal({ children }) {
|
|
305
333
|
const slot = usePageTitleSlot();
|
|
306
334
|
if (!slot) return React11.createElement(React11.Fragment, null, children);
|
|
@@ -539,6 +567,7 @@ function useRailFlyout({
|
|
|
539
567
|
"div",
|
|
540
568
|
{
|
|
541
569
|
ref: panelRef,
|
|
570
|
+
style: { borderTopLeftRadius: 2, borderBottomLeftRadius: 2 },
|
|
542
571
|
className: cn(
|
|
543
572
|
// Sidebar tone, sidebar border: the panel is the menu leaning out,
|
|
544
573
|
// not a popover from the page underneath it.
|
|
@@ -619,6 +648,51 @@ function FlyoutBody({
|
|
|
619
648
|
] })
|
|
620
649
|
] });
|
|
621
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
|
+
}
|
|
622
696
|
var RAIL_PUSH_MS = 260;
|
|
623
697
|
var useIsomorphicLayoutEffect2 = typeof window !== "undefined" ? React11.useLayoutEffect : React11.useEffect;
|
|
624
698
|
function getIcon(name) {
|
|
@@ -845,47 +919,7 @@ function NavGroup({
|
|
|
845
919
|
// to /70 when inactive, and a line fading along with the label it
|
|
846
920
|
// points AT was nearly invisible on a dark rail.
|
|
847
921
|
/* @__PURE__ */ jsxs("div", { className: "relative h-8 text-sidebar-foreground/45", children: [
|
|
848
|
-
|
|
849
|
-
"span",
|
|
850
|
-
{
|
|
851
|
-
"aria-hidden": true,
|
|
852
|
-
className: "pointer-events-none absolute bottom-0 left-[13px] top-0 w-[1.5px] bg-current"
|
|
853
|
-
}
|
|
854
|
-
),
|
|
855
|
-
isActive && /* @__PURE__ */ jsxs(
|
|
856
|
-
"svg",
|
|
857
|
-
{
|
|
858
|
-
"aria-hidden": true,
|
|
859
|
-
className: "pointer-events-none absolute left-1 top-0",
|
|
860
|
-
width: "21",
|
|
861
|
-
height: "32",
|
|
862
|
-
viewBox: "0 0 21 32",
|
|
863
|
-
fill: "none",
|
|
864
|
-
children: [
|
|
865
|
-
/* @__PURE__ */ jsx(
|
|
866
|
-
"path",
|
|
867
|
-
{
|
|
868
|
-
d: "M9.75 0 V11 Q9.75 16 14.75 16 H20",
|
|
869
|
-
stroke: "currentColor",
|
|
870
|
-
strokeWidth: "1.5",
|
|
871
|
-
strokeLinecap: "round",
|
|
872
|
-
fill: "none"
|
|
873
|
-
}
|
|
874
|
-
),
|
|
875
|
-
/* @__PURE__ */ jsx(
|
|
876
|
-
"path",
|
|
877
|
-
{
|
|
878
|
-
d: "M17 13 L20 16 L17 19",
|
|
879
|
-
stroke: "currentColor",
|
|
880
|
-
strokeWidth: "1.5",
|
|
881
|
-
strokeLinecap: "round",
|
|
882
|
-
strokeLinejoin: "round",
|
|
883
|
-
fill: "none"
|
|
884
|
-
}
|
|
885
|
-
)
|
|
886
|
-
]
|
|
887
|
-
}
|
|
888
|
-
),
|
|
922
|
+
/* @__PURE__ */ jsx(NavChildConnector, { onPath, active: isActive }),
|
|
889
923
|
row
|
|
890
924
|
] }, child.id)
|
|
891
925
|
);
|
|
@@ -926,6 +960,7 @@ function Sidebar({
|
|
|
926
960
|
borderless,
|
|
927
961
|
userMenuSlot,
|
|
928
962
|
notificationSlot,
|
|
963
|
+
hideNotifications = false,
|
|
929
964
|
unreadCount = 0,
|
|
930
965
|
searchLabel: _searchLabel,
|
|
931
966
|
sectionLabels,
|
|
@@ -1197,7 +1232,7 @@ function Sidebar({
|
|
|
1197
1232
|
), children: [
|
|
1198
1233
|
withCollapsed(userMenuSlot, collapsed),
|
|
1199
1234
|
!collapsed && /* @__PURE__ */ jsx("div", { className: "flex-1" }),
|
|
1200
|
-
withCollapsed(notificationSlot, collapsed) ?? /* @__PURE__ */ jsxs(
|
|
1235
|
+
!hideNotifications && (withCollapsed(notificationSlot, collapsed) ?? /* @__PURE__ */ jsxs(
|
|
1201
1236
|
"button",
|
|
1202
1237
|
{
|
|
1203
1238
|
...collapsed ? flyout.rowProps({
|
|
@@ -1211,7 +1246,7 @@ function Sidebar({
|
|
|
1211
1246
|
unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute right-1 top-1 h-2 w-2 rounded-full bg-destructive" })
|
|
1212
1247
|
]
|
|
1213
1248
|
}
|
|
1214
|
-
),
|
|
1249
|
+
)),
|
|
1215
1250
|
!drawer && /* @__PURE__ */ jsx(
|
|
1216
1251
|
"button",
|
|
1217
1252
|
{
|
|
@@ -1914,7 +1949,9 @@ function SidebarLayout({
|
|
|
1914
1949
|
railOpen
|
|
1915
1950
|
}) {
|
|
1916
1951
|
const sidebarCollapsed = useLayoutStore((s) => s.sidebarCollapsed);
|
|
1917
|
-
const
|
|
1952
|
+
const rawClaimed = usePageHeaderClaimed();
|
|
1953
|
+
const hasOutlet = useHasPageHeaderOutlet();
|
|
1954
|
+
const pageHeaderClaimed = hasOutlet ? false : rawClaimed;
|
|
1918
1955
|
const setTitleSlot = usePageTitleSlotHost();
|
|
1919
1956
|
usePageHeaderHost();
|
|
1920
1957
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
@@ -1959,7 +1996,7 @@ function SidebarLayout({
|
|
|
1959
1996
|
footerContent: sidebarFooterContent,
|
|
1960
1997
|
borderless: frame,
|
|
1961
1998
|
userMenuSlot,
|
|
1962
|
-
|
|
1999
|
+
hideNotifications: true,
|
|
1963
2000
|
unreadCount,
|
|
1964
2001
|
searchLabel,
|
|
1965
2002
|
sectionLabels: menuNavigation ? void 0 : sidebarSectionLabels,
|
|
@@ -2025,19 +2062,22 @@ function SidebarLayout({
|
|
|
2025
2062
|
]
|
|
2026
2063
|
}
|
|
2027
2064
|
),
|
|
2028
|
-
!pageHeaderClaimed && /* @__PURE__ */ jsx(ShellPageTitle, { title: pageTitle, back: pageBack, primary: pagePrimary }),
|
|
2029
|
-
/* @__PURE__ */ jsx("div", { ref: setTitleSlot, className: "flex min-w-0 items-center empty:hidden" }),
|
|
2030
2065
|
topbarStart,
|
|
2031
2066
|
/* @__PURE__ */ jsx("div", { ref: setHeaderSlot, className: "flex min-w-0 flex-1 items-center" })
|
|
2032
2067
|
] }),
|
|
2033
2068
|
/* @__PURE__ */ jsx("div", { className: "hidden min-w-0 flex-1 justify-center px-2 md:flex", children: /* @__PURE__ */ jsx(ShellSearch, { tone: "bar", label: searchLabel, className: "w-full max-w-[280px]" }) }),
|
|
2034
2069
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 shrink-0 items-center justify-end gap-2 md:flex-1", children: [
|
|
2035
|
-
|
|
2036
|
-
|
|
2070
|
+
topbarEnd,
|
|
2071
|
+
notificationSlot
|
|
2037
2072
|
] })
|
|
2038
2073
|
] }),
|
|
2039
2074
|
/* @__PURE__ */ jsxs("div", { "data-frame": frame || void 0, className: cn(
|
|
2040
|
-
|
|
2075
|
+
// `flex-col`: a faixa da página é a PRIMEIRA fila do cartão e
|
|
2076
|
+
// atravessa-o inteiro; a trilha da página e o conteúdo dividem a fila
|
|
2077
|
+
// de baixo. Era uma coluna só, com a trilha ao lado da faixa: a
|
|
2078
|
+
// migalha começava depois do menu de Configurações e a régua sob ela
|
|
2079
|
+
// parava no meio do cartão, como se fossem duas telas encostadas.
|
|
2080
|
+
"relative flex min-w-0 flex-1 flex-col overflow-hidden",
|
|
2041
2081
|
// `content`, not `card`: this is the page's own surface, and cards have
|
|
2042
2082
|
// to sit ON it. Painted card, the frame was the same tone as everything
|
|
2043
2083
|
// inside it and the page read as one flat sheet.
|
|
@@ -2054,10 +2094,49 @@ function SidebarLayout({
|
|
|
2054
2094
|
frame && (railOpen ? "md:rounded-r-none md:border-r-0" : "md:mr-2"),
|
|
2055
2095
|
immersive && "md:overflow-hidden"
|
|
2056
2096
|
), children: [
|
|
2057
|
-
/* @__PURE__ */
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
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
|
+
),
|
|
2134
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex min-w-0 min-h-0 flex-1 overflow-hidden", children: [
|
|
2135
|
+
/* @__PURE__ */ jsx("div", { ref: setPageRailSlot, className: "flex shrink-0 empty:hidden" }),
|
|
2136
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden", children: [
|
|
2137
|
+
/* @__PURE__ */ jsx("main", { className: cn("min-w-0 flex-1 overflow-y-auto pb-16 md:pb-0", menuOpen && "invisible md:visible"), children }),
|
|
2138
|
+
/* @__PURE__ */ jsx(SaveBar, {})
|
|
2139
|
+
] })
|
|
2061
2140
|
] })
|
|
2062
2141
|
] })
|
|
2063
2142
|
] }),
|
|
@@ -2185,43 +2264,49 @@ function TopbarLayout({
|
|
|
2185
2264
|
hideMobileChrome: barOwnsNav
|
|
2186
2265
|
}
|
|
2187
2266
|
),
|
|
2188
|
-
/* @__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__ */ jsxs("div", { "data-frame": frame || void 0, className: cn("fz-page-surface flex min-w-0 min-h-0 flex-1 overflow-hidden", frame && "md:rounded-xl md:border md:border-border md:bg-content"), children: [
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
/* @__PURE__ */ jsx(
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2267
|
+
/* @__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__ */ jsxs("div", { "data-frame": frame || void 0, className: cn("fz-page-surface flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden", frame && "md:rounded-xl md:border md:border-border md:bg-content"), children: [
|
|
2268
|
+
(pageHeaderClaimed || pageBack || hasPageActions || barOwnsNav) && /* @__PURE__ */ jsxs(
|
|
2269
|
+
"div",
|
|
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
|
+
},
|
|
2277
|
+
className: cn(
|
|
2278
|
+
// `relative` + glass for the same reason as the sidebar
|
|
2279
|
+
// layout's band: on a phone this IS the navigation bar.
|
|
2280
|
+
"relative flex min-h-[44px] md:min-h-12 shrink-0 items-center justify-between gap-3 px-4 py-2",
|
|
2281
|
+
menuOpen && "invisible md:visible",
|
|
2282
|
+
"fayz-glass-topbar",
|
|
2283
|
+
!(pageHeaderClaimed || pageBack || hasPageActions) && "md:hidden"
|
|
2284
|
+
),
|
|
2285
|
+
children: [
|
|
2286
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
|
|
2287
|
+
mobileBackToMenu && /* @__PURE__ */ jsxs(
|
|
2288
|
+
"button",
|
|
2289
|
+
{
|
|
2290
|
+
type: "button",
|
|
2291
|
+
onClick: mobileBackToMenu,
|
|
2292
|
+
className: "fz-ios-tint fz-tap -ml-1 inline-flex shrink-0 items-center gap-0.5 text-[15px] md:hidden",
|
|
2293
|
+
children: [
|
|
2294
|
+
/* @__PURE__ */ jsx(ChevronLeft, { className: "h-5 w-5" }),
|
|
2295
|
+
/* @__PURE__ */ jsx("span", { children: "Voltar" })
|
|
2296
|
+
]
|
|
2297
|
+
}
|
|
2298
|
+
),
|
|
2299
|
+
!pageHeaderClaimed && /* @__PURE__ */ jsx(ShellPageTitle, { title: showTitle ? pageTitle : void 0, back: pageBack, primary: pagePrimary }),
|
|
2300
|
+
/* @__PURE__ */ jsx("div", { ref: setTitleSlot, className: "flex min-w-0 items-center empty:hidden" }),
|
|
2301
|
+
/* @__PURE__ */ jsx("div", { ref: setHeaderSlot, className: "flex min-w-0 flex-1 items-center" })
|
|
2302
|
+
] }),
|
|
2303
|
+
/* @__PURE__ */ jsx("div", { ref: setActionsSlot, className: "flex shrink-0 items-center gap-2", style: { "--primary": "var(--primary-on-rail)", "--primary-foreground": "var(--primary-on-rail-foreground)" } })
|
|
2304
|
+
]
|
|
2305
|
+
}
|
|
2306
|
+
),
|
|
2307
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 min-h-0 flex-1 overflow-hidden", children: [
|
|
2308
|
+
/* @__PURE__ */ jsx("div", { ref: setPageRailSlot, className: "flex shrink-0 empty:hidden" }),
|
|
2309
|
+
/* @__PURE__ */ jsx("div", { className: cn("min-w-0 min-h-0 flex-1 overflow-y-auto pb-16 md:pb-0", menuOpen && "invisible md:visible"), children })
|
|
2225
2310
|
] })
|
|
2226
2311
|
] }) }),
|
|
2227
2312
|
/* @__PURE__ */ jsx(SaveBar, {}),
|
|
@@ -3337,13 +3422,26 @@ function HeaderTabs({
|
|
|
3337
3422
|
}
|
|
3338
3423
|
);
|
|
3339
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
|
+
}
|
|
3340
3433
|
function PageTabs({ actions, className, ...props }) {
|
|
3341
3434
|
return /* @__PURE__ */ jsxs(
|
|
3342
3435
|
"div",
|
|
3343
3436
|
{
|
|
3344
3437
|
style: { background: "var(--page-surface, hsl(var(--background)))" },
|
|
3345
3438
|
className: cn(
|
|
3346
|
-
|
|
3439
|
+
// `flex-nowrap`: a faixa NÃO quebra mais. Quebrando, o slot da direita
|
|
3440
|
+
// (filtros, modos de ver) descia para uma segunda linha e a tela ganhava
|
|
3441
|
+
// um terceiro andar de chrome antes do conteúdo — e, pior, as abas
|
|
3442
|
+
// comiam a largura dele primeiro. Agora o slot da direita tem lugar
|
|
3443
|
+
// garantido e são as ABAS que rolam na horizontal quando não cabem.
|
|
3444
|
+
"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",
|
|
3347
3445
|
// 48px no desktop, a mesma altura do subcabeçalho dos painéis do
|
|
3348
3446
|
// assistente à direita (TasksFilterBar, NotebookPanel). Eram 34 aqui e
|
|
3349
3447
|
// 48 lá: os dois fios que fecham as duas faixas paravam em alturas
|
|
@@ -3354,8 +3452,8 @@ function PageTabs({ actions, className, ...props }) {
|
|
|
3354
3452
|
className
|
|
3355
3453
|
),
|
|
3356
3454
|
children: [
|
|
3357
|
-
/* @__PURE__ */ jsx(HeaderTabs, { ...props, className: "-mb-px" }),
|
|
3358
|
-
actions && /* @__PURE__ */ jsx("div", { className: "
|
|
3455
|
+
/* @__PURE__ */ jsx(HeaderTabs, { ...props, className: "-mb-px min-w-0 flex-1" }),
|
|
3456
|
+
actions && /* @__PURE__ */ jsx("div", { className: "-mt-1 flex shrink-0 items-center gap-2 pb-1 empty:hidden", children: actions })
|
|
3359
3457
|
]
|
|
3360
3458
|
}
|
|
3361
3459
|
);
|
|
@@ -3434,15 +3532,15 @@ function navigateToCrumb(crumb) {
|
|
|
3434
3532
|
else window.location.hash = crumb.href;
|
|
3435
3533
|
}
|
|
3436
3534
|
function useCurrentRouteHref() {
|
|
3437
|
-
const
|
|
3535
|
+
const read2 = () => {
|
|
3438
3536
|
if (typeof window === "undefined") return "";
|
|
3439
3537
|
const hash = window.location.hash.replace(/^#/, "");
|
|
3440
3538
|
const clean = hash.split("?")[0];
|
|
3441
3539
|
return clean.startsWith("/") ? clean : `/${clean}`;
|
|
3442
3540
|
};
|
|
3443
|
-
const [href, setHref] = React11.useState(
|
|
3541
|
+
const [href, setHref] = React11.useState(read2);
|
|
3444
3542
|
React11.useEffect(() => {
|
|
3445
|
-
const handler = () => setHref(
|
|
3543
|
+
const handler = () => setHref(read2());
|
|
3446
3544
|
window.addEventListener("hashchange", handler);
|
|
3447
3545
|
handler();
|
|
3448
3546
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -3457,6 +3555,241 @@ function useTrailBack(href) {
|
|
|
3457
3555
|
[parent]
|
|
3458
3556
|
);
|
|
3459
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
|
+
}
|
|
3460
3793
|
function PageRail({ children }) {
|
|
3461
3794
|
const slot = usePageRailSlot();
|
|
3462
3795
|
if (slot) return createPortal(children, slot);
|
|
@@ -3479,21 +3812,11 @@ function ViewBarHost() {
|
|
|
3479
3812
|
return /* @__PURE__ */ jsx(
|
|
3480
3813
|
"div",
|
|
3481
3814
|
{
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
)
|
|
3487
|
-
children: /* @__PURE__ */ jsx(
|
|
3488
|
-
"div",
|
|
3489
|
-
{
|
|
3490
|
-
ref: (el) => {
|
|
3491
|
-
viewBarSlot = el;
|
|
3492
|
-
viewBarNotify();
|
|
3493
|
-
},
|
|
3494
|
-
className: "flex min-h-7 items-center justify-between gap-2"
|
|
3495
|
-
}
|
|
3496
|
-
)
|
|
3815
|
+
ref: (el) => {
|
|
3816
|
+
viewBarSlot = el;
|
|
3817
|
+
viewBarNotify();
|
|
3818
|
+
},
|
|
3819
|
+
className: cn("flex items-center gap-2", !active && "hidden")
|
|
3497
3820
|
}
|
|
3498
3821
|
);
|
|
3499
3822
|
}
|
|
@@ -3508,10 +3831,165 @@ function PageViewBar({ children }) {
|
|
|
3508
3831
|
};
|
|
3509
3832
|
}, []);
|
|
3510
3833
|
if (slot) return createPortal(children, slot);
|
|
3511
|
-
return /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center justify-
|
|
3834
|
+
return /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center justify-end gap-2", children });
|
|
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
|
+
] });
|
|
3512
3988
|
}
|
|
3513
3989
|
function PageHeaderActions({ children }) {
|
|
3514
|
-
const
|
|
3990
|
+
const outlet = usePageActionsOutletSlot();
|
|
3991
|
+
const shellSlot = useModuleHeaderActionsSlot();
|
|
3992
|
+
const slot = outlet ?? shellSlot;
|
|
3515
3993
|
useRegisterPageActions();
|
|
3516
3994
|
if (slot) return createPortal(children, slot);
|
|
3517
3995
|
return /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center justify-end gap-2", children });
|
|
@@ -3528,8 +4006,11 @@ function ModuleLayoutProvider({ variant, children }) {
|
|
|
3528
4006
|
function useModuleLayout() {
|
|
3529
4007
|
return React11.useContext(ModuleLayoutContext);
|
|
3530
4008
|
}
|
|
3531
|
-
function RailNavItem({ item }) {
|
|
3532
|
-
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]);
|
|
3533
4014
|
const Icon = item.icon ? ICON_MAP[item.icon] ?? null : null;
|
|
3534
4015
|
const hasChildren = item.children && item.children.length > 0;
|
|
3535
4016
|
const hasActiveChild = hasChildren && item.children.some((c) => c.active);
|
|
@@ -3540,36 +4021,53 @@ function RailNavItem({ item }) {
|
|
|
3540
4021
|
{
|
|
3541
4022
|
type: "button",
|
|
3542
4023
|
"data-tour": `modnav.${item.id}`,
|
|
3543
|
-
onClick: () => hasChildren ? setExpanded(!expanded) : item.onClick?.(),
|
|
4024
|
+
onClick: () => hasChildren && !collapsed ? setExpanded(!expanded) : item.onClick?.(),
|
|
4025
|
+
title: collapsed ? item.label : void 0,
|
|
3544
4026
|
className: cn(
|
|
3545
|
-
|
|
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",
|
|
3546
4036
|
isActive ? "bg-primary/10 text-primary font-medium" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
|
|
3547
4037
|
),
|
|
3548
4038
|
children: [
|
|
3549
4039
|
Icon && /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
3550
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left
|
|
3551
|
-
item.premium && /* @__PURE__ */ jsx(PremiumBadge, { className: "ml-1" }),
|
|
3552
|
-
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" }))
|
|
3553
4043
|
]
|
|
3554
4044
|
}
|
|
3555
4045
|
),
|
|
3556
|
-
hasChildren && expanded && /* @__PURE__ */ jsx("div", { className: "
|
|
3557
|
-
|
|
3558
|
-
{
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
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
|
+
}) })
|
|
3573
4071
|
] });
|
|
3574
4072
|
}
|
|
3575
4073
|
function defaultChildOf(item) {
|
|
@@ -3765,11 +4263,18 @@ function ShellSubpageHeader({
|
|
|
3765
4263
|
/* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsx("div", { className: "no-print flex shrink-0 items-center gap-2", children: actions }) })
|
|
3766
4264
|
] });
|
|
3767
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
|
+
}
|
|
3768
4277
|
function ModuleHeader({ nav }) {
|
|
3769
|
-
function defaultChild(item) {
|
|
3770
|
-
const kids2 = (item.children ?? []).filter((c) => c.kind !== "action");
|
|
3771
|
-
return kids2.find((c) => /list/i.test(c.id) || /^list$/i.test(c.label)) ?? kids2[kids2.length - 1];
|
|
3772
|
-
}
|
|
3773
4278
|
const activeItem = nav.find((item) => item.active || item.children?.some((c) => c.active));
|
|
3774
4279
|
const tabs = nav.map((item) => ({
|
|
3775
4280
|
value: item.id,
|
|
@@ -3783,23 +4288,12 @@ function ModuleHeader({ nav }) {
|
|
|
3783
4288
|
const item = nav.find((n) => n.id === id);
|
|
3784
4289
|
if (!item) return;
|
|
3785
4290
|
const hasChildren = item.children && item.children.length > 0;
|
|
3786
|
-
if (hasChildren)
|
|
4291
|
+
if (hasChildren) defaultChildOf(item)?.onClick?.();
|
|
3787
4292
|
else item.onClick?.();
|
|
3788
4293
|
};
|
|
3789
4294
|
const kids = (activeItem?.children ?? []).filter((c) => c.kind !== "action");
|
|
3790
4295
|
const activeKid = kids.find((c) => c.active)?.id ?? kids[0]?.id;
|
|
3791
|
-
const
|
|
3792
|
-
/* @__PURE__ */ jsx(
|
|
3793
|
-
ViewTabs,
|
|
3794
|
-
{
|
|
3795
|
-
"aria-label": activeItem?.label,
|
|
3796
|
-
options: kids.map((c) => ({ value: c.id, label: c.label })),
|
|
3797
|
-
value: activeKid,
|
|
3798
|
-
onChange: (id) => kids.find((c) => c.id === id)?.onClick?.()
|
|
3799
|
-
}
|
|
3800
|
-
),
|
|
3801
|
-
/* @__PURE__ */ jsx("span", {})
|
|
3802
|
-
] }) : 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;
|
|
3803
4297
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3804
4298
|
/* @__PURE__ */ jsx(
|
|
3805
4299
|
PageTabs,
|
|
@@ -3807,17 +4301,39 @@ function ModuleHeader({ nav }) {
|
|
|
3807
4301
|
tabs,
|
|
3808
4302
|
value: activeItem?.id ?? nav[0]?.id ?? "",
|
|
3809
4303
|
onChange,
|
|
3810
|
-
anchorPrefix: "modnav"
|
|
4304
|
+
anchorPrefix: "modnav",
|
|
4305
|
+
actions: /* @__PURE__ */ jsx(ViewBarHost, {})
|
|
3811
4306
|
}
|
|
3812
4307
|
),
|
|
3813
|
-
|
|
4308
|
+
/* @__PURE__ */ jsx(SubNavBandHost, { leading: childNav, label: activeItem?.label })
|
|
3814
4309
|
] });
|
|
3815
4310
|
}
|
|
3816
|
-
function ModulePage({ title: _title, subtitle, nav, children, className, headerAction, showHeader = true, sidebarFooter, navVariant, viewKey, direction }) {
|
|
4311
|
+
function ModulePage({ title: _title, subtitle, nav, children, className, headerAction, showHeader = true, sidebarFooter, navVariant, viewKey, direction, navFilterPlaceholder }) {
|
|
3817
4312
|
const ctxVariant = useModuleLayout();
|
|
3818
4313
|
const variant = navVariant ?? ctxVariant;
|
|
4314
|
+
const [navQuery, setNavQuery] = React11.useState("");
|
|
4315
|
+
const filteredNav = React11.useMemo(() => {
|
|
4316
|
+
const q = navQuery.trim().toLowerCase();
|
|
4317
|
+
if (!q) return nav;
|
|
4318
|
+
const hit = (label) => label.toLowerCase().includes(q);
|
|
4319
|
+
return nav.flatMap((item) => {
|
|
4320
|
+
if (hit(item.label)) return [item];
|
|
4321
|
+
const kids = (item.children ?? []).filter((c) => hit(c.label));
|
|
4322
|
+
return kids.length ? [{ ...item, children: kids }] : [];
|
|
4323
|
+
});
|
|
4324
|
+
}, [nav, navQuery]);
|
|
3819
4325
|
const transitionKey = viewKey ?? "view";
|
|
3820
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);
|
|
3821
4337
|
if (variant === "sidebar") {
|
|
3822
4338
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3823
4339
|
showHeader && headerAction && /* @__PURE__ */ jsx(PageHeaderActions, { children: headerAction }),
|
|
@@ -3827,24 +4343,28 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
|
|
|
3827
4343
|
if (variant === "tabs") {
|
|
3828
4344
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3829
4345
|
!onSubpage && /* @__PURE__ */ jsx(ModuleHeader, { nav }),
|
|
3830
|
-
!onSubpage && /* @__PURE__ */ jsx(ViewBarHost, {}),
|
|
3831
4346
|
showHeader && headerAction && /* @__PURE__ */ jsx(PageHeaderActions, { children: headerAction }),
|
|
3832
4347
|
/* @__PURE__ */ jsx(PageTransition, { transitionKey, direction, className: cn("min-w-0", className), children })
|
|
3833
4348
|
] });
|
|
3834
4349
|
}
|
|
3835
4350
|
return /* @__PURE__ */ jsxs("div", { className: cn("min-w-0", className), children: [
|
|
3836
|
-
/* @__PURE__ */ jsx(PageRail, { children: /* @__PURE__ */
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
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
|
+
) }),
|
|
3840
4359
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
3841
4360
|
showHeader && headerAction && /* @__PURE__ */ jsx(PageHeaderActions, { children: headerAction }),
|
|
3842
4361
|
!onSubpage && /* @__PURE__ */ jsx(MobileTabs, { nav }),
|
|
4362
|
+
!onSubpage && /* @__PURE__ */ jsx(ModuleSubBand, { nav }),
|
|
3843
4363
|
/* @__PURE__ */ jsx(PageTransition, { transitionKey, direction, children })
|
|
3844
4364
|
] })
|
|
3845
4365
|
] });
|
|
3846
4366
|
}
|
|
3847
4367
|
|
|
3848
|
-
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 };
|
|
3849
|
-
//# sourceMappingURL=chunk-
|
|
3850
|
-
//# 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
|