@fayz-ai/ui 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/{chunk-UDY4KJRX.js → chunk-3XKDGBP4.js} +7 -5
  2. package/dist/chunk-3XKDGBP4.js.map +1 -0
  3. package/dist/{chunk-VDAYIQX4.js → chunk-C6PW5C5Q.js} +3 -3
  4. package/dist/chunk-C6PW5C5Q.js.map +1 -0
  5. package/dist/{chunk-NTPQRDJF.js → chunk-NXSDQ7HO.js} +4 -4
  6. package/dist/{chunk-NTPQRDJF.js.map → chunk-NXSDQ7HO.js.map} +1 -1
  7. package/dist/{chunk-VBYFN5ZL.js → chunk-PL5CUWNE.js} +138 -82
  8. package/dist/chunk-PL5CUWNE.js.map +1 -0
  9. package/dist/{chunk-ABY2HXG4.js → chunk-UFT3MA5H.js} +24 -16
  10. package/dist/chunk-UFT3MA5H.js.map +1 -0
  11. package/dist/dashboard/index.js +3 -3
  12. package/dist/index.js +9 -9
  13. package/dist/layout/AppShell.d.ts.map +1 -1
  14. package/dist/layout/ModulePage.d.ts +8 -1
  15. package/dist/layout/ModulePage.d.ts.map +1 -1
  16. package/dist/layout/Sidebar.d.ts +6 -1
  17. package/dist/layout/Sidebar.d.ts.map +1 -1
  18. package/dist/layout/index.js +1 -1
  19. package/dist/primitives/data-table.d.ts +10 -1
  20. package/dist/primitives/data-table.d.ts.map +1 -1
  21. package/dist/primitives/date-picker.d.ts +6 -1
  22. package/dist/primitives/date-picker.d.ts.map +1 -1
  23. package/dist/primitives/header-tabs.d.ts.map +1 -1
  24. package/dist/primitives/index.js +3 -3
  25. package/dist/primitives/input.d.ts.map +1 -1
  26. package/dist/primitives/list-view.d.ts +3 -1
  27. package/dist/primitives/list-view.d.ts.map +1 -1
  28. package/dist/primitives/phone-field.d.ts.map +1 -1
  29. package/dist/stores/page-header.store.d.ts +18 -1
  30. package/dist/stores/page-header.store.d.ts.map +1 -1
  31. package/dist/styles.css +8 -1
  32. package/dist/theme/index.js +1 -1
  33. package/package.json +2 -2
  34. package/dist/chunk-ABY2HXG4.js.map +0 -1
  35. package/dist/chunk-UDY4KJRX.js.map +0 -1
  36. package/dist/chunk-VBYFN5ZL.js.map +0 -1
  37. package/dist/chunk-VDAYIQX4.js.map +0 -1
@@ -219,6 +219,8 @@ var usePageHeaderStore = create((set, get) => ({
219
219
  setShellSlot: (element) => set({ shellSlot: element }),
220
220
  outletSlot: null,
221
221
  setOutletSlot: (element) => set({ outletSlot: element }),
222
+ outletActionsSlot: null,
223
+ setOutletActionsSlot: (element) => set({ outletActionsSlot: element }),
222
224
  claimed: false,
223
225
  owner: null,
224
226
  hasBack: false,
@@ -253,6 +255,9 @@ function usePageHeaderClaimed() {
253
255
  function usePageTitleSlot() {
254
256
  return usePageHeaderStore((s) => s.outletSlot ?? s.shellSlot);
255
257
  }
258
+ function usePageActionsOutletSlot() {
259
+ return usePageHeaderStore((s) => s.outletActionsSlot);
260
+ }
256
261
  function usePageTitleSlotHost() {
257
262
  return usePageHeaderStore((s) => s.setShellSlot);
258
263
  }
@@ -270,19 +275,30 @@ function useHasPageHeaderHost() {
270
275
  function useHasPageHeaderOutlet() {
271
276
  return usePageHeaderStore((s) => s.outlets > 0);
272
277
  }
273
- function PageHeaderOutlet({ className }) {
278
+ function PageHeaderOutlet({ className, active = true }) {
274
279
  const setOutletSlot = usePageHeaderStore((s) => s.setOutletSlot);
280
+ const setOutletActionsSlot = usePageHeaderStore((s) => s.setOutletActionsSlot);
275
281
  const claimed = usePageHeaderStore((s) => s.claimed);
282
+ const hasActions = usePageHeaderStore((s) => s.actions > 0);
276
283
  const addOutlet = usePageHeaderStore((s) => s.addOutlet);
277
284
  const removeOutlet = usePageHeaderStore((s) => s.removeOutlet);
278
285
  React11.useEffect(() => {
286
+ if (!active) return;
279
287
  addOutlet();
280
288
  return removeOutlet;
281
- }, [addOutlet, removeOutlet]);
282
- return React11.createElement("div", {
283
- ref: setOutletSlot,
284
- className: `${className ?? "mb-4"}${claimed ? "" : " hidden"}`
285
- });
289
+ }, [active, addOutlet, removeOutlet]);
290
+ React11.useEffect(() => {
291
+ if (active) return;
292
+ setOutletSlot(null);
293
+ setOutletActionsSlot(null);
294
+ }, [active, setOutletSlot, setOutletActionsSlot]);
295
+ if (!active) return null;
296
+ return React11.createElement(
297
+ "div",
298
+ { className: `flex min-h-9 items-center justify-between gap-3${claimed || hasActions ? "" : " hidden"} ${className ?? "mb-3"}` },
299
+ React11.createElement("div", { ref: setOutletSlot, className: "flex min-w-0 flex-1 items-center" }),
300
+ React11.createElement("div", { ref: setOutletActionsSlot, className: "flex shrink-0 items-center gap-2" })
301
+ );
286
302
  }
287
303
  function usePageHeader(active, options) {
288
304
  const id = React11.useId();
@@ -926,6 +942,7 @@ function Sidebar({
926
942
  borderless,
927
943
  userMenuSlot,
928
944
  notificationSlot,
945
+ hideNotifications = false,
929
946
  unreadCount = 0,
930
947
  searchLabel: _searchLabel,
931
948
  sectionLabels,
@@ -1197,7 +1214,7 @@ function Sidebar({
1197
1214
  ), children: [
1198
1215
  withCollapsed(userMenuSlot, collapsed),
1199
1216
  !collapsed && /* @__PURE__ */ jsx("div", { className: "flex-1" }),
1200
- withCollapsed(notificationSlot, collapsed) ?? /* @__PURE__ */ jsxs(
1217
+ !hideNotifications && (withCollapsed(notificationSlot, collapsed) ?? /* @__PURE__ */ jsxs(
1201
1218
  "button",
1202
1219
  {
1203
1220
  ...collapsed ? flyout.rowProps({
@@ -1211,7 +1228,7 @@ function Sidebar({
1211
1228
  unreadCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute right-1 top-1 h-2 w-2 rounded-full bg-destructive" })
1212
1229
  ]
1213
1230
  }
1214
- ),
1231
+ )),
1215
1232
  !drawer && /* @__PURE__ */ jsx(
1216
1233
  "button",
1217
1234
  {
@@ -1914,7 +1931,9 @@ function SidebarLayout({
1914
1931
  railOpen
1915
1932
  }) {
1916
1933
  const sidebarCollapsed = useLayoutStore((s) => s.sidebarCollapsed);
1917
- const pageHeaderClaimed = usePageHeaderClaimed();
1934
+ const rawClaimed = usePageHeaderClaimed();
1935
+ const hasOutlet = useHasPageHeaderOutlet();
1936
+ const pageHeaderClaimed = hasOutlet ? false : rawClaimed;
1918
1937
  const setTitleSlot = usePageTitleSlotHost();
1919
1938
  usePageHeaderHost();
1920
1939
  const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
@@ -1959,7 +1978,7 @@ function SidebarLayout({
1959
1978
  footerContent: sidebarFooterContent,
1960
1979
  borderless: frame,
1961
1980
  userMenuSlot,
1962
- notificationSlot,
1981
+ hideNotifications: true,
1963
1982
  unreadCount,
1964
1983
  searchLabel,
1965
1984
  sectionLabels: menuNavigation ? void 0 : sidebarSectionLabels,
@@ -2025,19 +2044,22 @@ function SidebarLayout({
2025
2044
  ]
2026
2045
  }
2027
2046
  ),
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
2047
  topbarStart,
2031
2048
  /* @__PURE__ */ jsx("div", { ref: setHeaderSlot, className: "flex min-w-0 flex-1 items-center" })
2032
2049
  ] }),
2033
2050
  /* @__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
2051
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 shrink-0 items-center justify-end gap-2 md:flex-1", children: [
2035
- /* @__PURE__ */ jsx("div", { ref: setActionsSlot, className: "flex items-center gap-2", style: { "--primary": "var(--primary-on-rail)", "--primary-foreground": "var(--primary-on-rail-foreground)" } }),
2036
- topbarEnd
2052
+ topbarEnd,
2053
+ notificationSlot
2037
2054
  ] })
2038
2055
  ] }),
2039
2056
  /* @__PURE__ */ jsxs("div", { "data-frame": frame || void 0, className: cn(
2040
- "relative flex min-w-0 flex-1 overflow-hidden",
2057
+ // `flex-col`: a faixa da página é a PRIMEIRA fila do cartão e
2058
+ // atravessa-o inteiro; a trilha da página e o conteúdo dividem a fila
2059
+ // de baixo. Era uma coluna só, com a trilha ao lado da faixa: a
2060
+ // migalha começava depois do menu de Configurações e a régua sob ela
2061
+ // parava no meio do cartão, como se fossem duas telas encostadas.
2062
+ "relative flex min-w-0 flex-1 flex-col overflow-hidden",
2041
2063
  // `content`, not `card`: this is the page's own surface, and cards have
2042
2064
  // to sit ON it. Painted card, the frame was the same tone as everything
2043
2065
  // inside it and the page read as one flat sheet.
@@ -2054,10 +2076,22 @@ function SidebarLayout({
2054
2076
  frame && (railOpen ? "md:rounded-r-none md:border-r-0" : "md:mr-2"),
2055
2077
  immersive && "md:overflow-hidden"
2056
2078
  ), children: [
2057
- /* @__PURE__ */ jsx("div", { ref: setPageRailSlot, className: "flex shrink-0 empty:hidden" }),
2058
- /* @__PURE__ */ jsxs("div", { className: "relative flex min-w-0 flex-1 flex-col overflow-hidden", children: [
2059
- /* @__PURE__ */ jsx("main", { className: cn("min-w-0 flex-1 overflow-y-auto pb-16 md:pb-0", menuOpen && "invisible md:visible"), children }),
2060
- /* @__PURE__ */ jsx(SaveBar, {})
2079
+ /* @__PURE__ */ jsxs("div", { className: cn(
2080
+ "relative z-20 flex min-h-12 shrink-0 items-center justify-between gap-3 border-b border-border px-3 md:px-6",
2081
+ menuOpen && "invisible md:visible"
2082
+ ), children: [
2083
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
2084
+ !pageHeaderClaimed && /* @__PURE__ */ jsx(ShellPageTitle, { title: pageTitle, back: pageBack, primary: pagePrimary }),
2085
+ /* @__PURE__ */ jsx("div", { ref: setTitleSlot, className: "flex min-w-0 items-center empty:hidden" })
2086
+ ] }),
2087
+ /* @__PURE__ */ jsx("div", { ref: setActionsSlot, className: "flex shrink-0 items-center gap-2" })
2088
+ ] }),
2089
+ /* @__PURE__ */ jsxs("div", { className: "relative flex min-w-0 min-h-0 flex-1 overflow-hidden", children: [
2090
+ /* @__PURE__ */ jsx("div", { ref: setPageRailSlot, className: "flex shrink-0 empty:hidden" }),
2091
+ /* @__PURE__ */ jsxs("div", { className: "relative flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden", children: [
2092
+ /* @__PURE__ */ jsx("main", { className: cn("min-w-0 flex-1 overflow-y-auto pb-16 md:pb-0", menuOpen && "invisible md:visible"), children }),
2093
+ /* @__PURE__ */ jsx(SaveBar, {})
2094
+ ] })
2061
2095
  ] })
2062
2096
  ] })
2063
2097
  ] }),
@@ -2185,43 +2219,43 @@ function TopbarLayout({
2185
2219
  hideMobileChrome: barOwnsNav
2186
2220
  }
2187
2221
  ),
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
- /* @__PURE__ */ jsx("div", { ref: setPageRailSlot, className: "flex shrink-0 empty:hidden" }),
2190
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 min-h-0 flex-1 flex-col overflow-hidden", children: [
2191
- (pageHeaderClaimed || pageBack || hasPageActions || barOwnsNav) && /* @__PURE__ */ jsxs(
2192
- "div",
2193
- {
2194
- className: cn(
2195
- // `relative` + glass for the same reason as the sidebar
2196
- // layout's band: on a phone this IS the navigation bar.
2197
- "relative flex min-h-[44px] md:min-h-12 shrink-0 items-center justify-between gap-3 border-b border-border px-4 py-2",
2198
- menuOpen && "invisible md:visible",
2199
- "fayz-glass-topbar",
2200
- !(pageHeaderClaimed || pageBack || hasPageActions) && "md:hidden"
2201
- ),
2202
- children: [
2203
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
2204
- mobileBackToMenu && /* @__PURE__ */ jsxs(
2205
- "button",
2206
- {
2207
- type: "button",
2208
- onClick: mobileBackToMenu,
2209
- className: "fz-ios-tint fz-tap -ml-1 inline-flex shrink-0 items-center gap-0.5 text-[15px] md:hidden",
2210
- children: [
2211
- /* @__PURE__ */ jsx(ChevronLeft, { className: "h-5 w-5" }),
2212
- /* @__PURE__ */ jsx("span", { children: "Voltar" })
2213
- ]
2214
- }
2215
- ),
2216
- !pageHeaderClaimed && /* @__PURE__ */ jsx(ShellPageTitle, { title: showTitle ? pageTitle : void 0, back: pageBack, primary: pagePrimary }),
2217
- /* @__PURE__ */ jsx("div", { ref: setTitleSlot, className: "flex min-w-0 items-center empty:hidden" }),
2218
- /* @__PURE__ */ jsx("div", { ref: setHeaderSlot, className: "flex min-w-0 flex-1 items-center" })
2219
- ] }),
2220
- /* @__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)" } })
2221
- ]
2222
- }
2223
- ),
2224
- /* @__PURE__ */ jsx("div", { className: cn("min-h-0 flex-1 overflow-y-auto pb-16 md:pb-0", menuOpen && "invisible md:visible"), children })
2222
+ /* @__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: [
2223
+ (pageHeaderClaimed || pageBack || hasPageActions || barOwnsNav) && /* @__PURE__ */ jsxs(
2224
+ "div",
2225
+ {
2226
+ className: cn(
2227
+ // `relative` + glass for the same reason as the sidebar
2228
+ // 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 border-b border-border px-4 py-2",
2230
+ menuOpen && "invisible md:visible",
2231
+ "fayz-glass-topbar",
2232
+ !(pageHeaderClaimed || pageBack || hasPageActions) && "md:hidden"
2233
+ ),
2234
+ children: [
2235
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
2236
+ mobileBackToMenu && /* @__PURE__ */ jsxs(
2237
+ "button",
2238
+ {
2239
+ type: "button",
2240
+ onClick: mobileBackToMenu,
2241
+ className: "fz-ios-tint fz-tap -ml-1 inline-flex shrink-0 items-center gap-0.5 text-[15px] md:hidden",
2242
+ children: [
2243
+ /* @__PURE__ */ jsx(ChevronLeft, { className: "h-5 w-5" }),
2244
+ /* @__PURE__ */ jsx("span", { children: "Voltar" })
2245
+ ]
2246
+ }
2247
+ ),
2248
+ !pageHeaderClaimed && /* @__PURE__ */ jsx(ShellPageTitle, { title: showTitle ? pageTitle : void 0, back: pageBack, primary: pagePrimary }),
2249
+ /* @__PURE__ */ jsx("div", { ref: setTitleSlot, className: "flex min-w-0 items-center empty:hidden" }),
2250
+ /* @__PURE__ */ jsx("div", { ref: setHeaderSlot, className: "flex min-w-0 flex-1 items-center" })
2251
+ ] }),
2252
+ /* @__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)" } })
2253
+ ]
2254
+ }
2255
+ ),
2256
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 min-h-0 flex-1 overflow-hidden", children: [
2257
+ /* @__PURE__ */ jsx("div", { ref: setPageRailSlot, className: "flex shrink-0 empty:hidden" }),
2258
+ /* @__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
2259
  ] })
2226
2260
  ] }) }),
2227
2261
  /* @__PURE__ */ jsx(SaveBar, {}),
@@ -3343,7 +3377,12 @@ function PageTabs({ actions, className, ...props }) {
3343
3377
  {
3344
3378
  style: { background: "var(--page-surface, hsl(var(--background)))" },
3345
3379
  className: cn(
3346
- "sticky top-0 z-20 -mx-3 -mt-3 mb-4 flex flex-wrap items-end justify-between gap-3 border-b border-border px-3 pt-2 md:-mx-6 md:-mt-4 md:px-6",
3380
+ // `flex-nowrap`: a faixa NÃO quebra mais. Quebrando, o slot da direita
3381
+ // (filtros, modos de ver) descia para uma segunda linha e a tela ganhava
3382
+ // um terceiro andar de chrome antes do conteúdo — e, pior, as abas
3383
+ // comiam a largura dele primeiro. Agora o slot da direita tem lugar
3384
+ // garantido e são as ABAS que rolam na horizontal quando não cabem.
3385
+ "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
3386
  // 48px no desktop, a mesma altura do subcabeçalho dos painéis do
3348
3387
  // assistente à direita (TasksFilterBar, NotebookPanel). Eram 34 aqui e
3349
3388
  // 48 lá: os dois fios que fecham as duas faixas paravam em alturas
@@ -3354,8 +3393,8 @@ function PageTabs({ actions, className, ...props }) {
3354
3393
  className
3355
3394
  ),
3356
3395
  children: [
3357
- /* @__PURE__ */ jsx(HeaderTabs, { ...props, className: "-mb-px" }),
3358
- actions && /* @__PURE__ */ jsx("div", { className: "ml-auto flex shrink-0 items-center gap-2 pb-1.5", children: actions })
3396
+ /* @__PURE__ */ jsx(HeaderTabs, { ...props, className: "-mb-px min-w-0 flex-1" }),
3397
+ actions && /* @__PURE__ */ jsx("div", { className: "-mt-1 flex shrink-0 items-center gap-2 pb-1 empty:hidden", children: actions })
3359
3398
  ]
3360
3399
  }
3361
3400
  );
@@ -3479,21 +3518,11 @@ function ViewBarHost() {
3479
3518
  return /* @__PURE__ */ jsx(
3480
3519
  "div",
3481
3520
  {
3482
- style: { background: "var(--page-surface, hsl(var(--background)))", marginTop: "-1rem" },
3483
- className: cn(
3484
- "sticky top-[2.4rem] z-10 -mx-3 mb-3 border-b border-border px-3 py-1 md:top-[2.5rem] md:-mx-6 md:px-6",
3485
- !active && "hidden"
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
- )
3521
+ ref: (el) => {
3522
+ viewBarSlot = el;
3523
+ viewBarNotify();
3524
+ },
3525
+ className: cn("flex items-center gap-2", !active && "hidden")
3497
3526
  }
3498
3527
  );
3499
3528
  }
@@ -3508,10 +3537,12 @@ function PageViewBar({ children }) {
3508
3537
  };
3509
3538
  }, []);
3510
3539
  if (slot) return createPortal(children, slot);
3511
- return /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center justify-between gap-2", children });
3540
+ return /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center justify-end gap-2", children });
3512
3541
  }
3513
3542
  function PageHeaderActions({ children }) {
3514
- const slot = useModuleHeaderActionsSlot();
3543
+ const outlet = usePageActionsOutletSlot();
3544
+ const shellSlot = useModuleHeaderActionsSlot();
3545
+ const slot = outlet ?? shellSlot;
3515
3546
  useRegisterPageActions();
3516
3547
  if (slot) return createPortal(children, slot);
3517
3548
  return /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center justify-end gap-2", children });
@@ -3807,15 +3838,27 @@ function ModuleHeader({ nav }) {
3807
3838
  tabs,
3808
3839
  value: activeItem?.id ?? nav[0]?.id ?? "",
3809
3840
  onChange,
3810
- anchorPrefix: "modnav"
3841
+ anchorPrefix: "modnav",
3842
+ actions: /* @__PURE__ */ jsx(ViewBarHost, {})
3811
3843
  }
3812
3844
  ),
3813
3845
  childControl
3814
3846
  ] });
3815
3847
  }
3816
- function ModulePage({ title: _title, subtitle, nav, children, className, headerAction, showHeader = true, sidebarFooter, navVariant, viewKey, direction }) {
3848
+ function ModulePage({ title: _title, subtitle, nav, children, className, headerAction, showHeader = true, sidebarFooter, navVariant, viewKey, direction, navFilterPlaceholder }) {
3817
3849
  const ctxVariant = useModuleLayout();
3818
3850
  const variant = navVariant ?? ctxVariant;
3851
+ const [navQuery, setNavQuery] = React11.useState("");
3852
+ const filteredNav = React11.useMemo(() => {
3853
+ const q = navQuery.trim().toLowerCase();
3854
+ if (!q) return nav;
3855
+ const hit = (label) => label.toLowerCase().includes(q);
3856
+ return nav.flatMap((item) => {
3857
+ if (hit(item.label)) return [item];
3858
+ const kids = (item.children ?? []).filter((c) => hit(c.label));
3859
+ return kids.length ? [{ ...item, children: kids }] : [];
3860
+ });
3861
+ }, [nav, navQuery]);
3819
3862
  const transitionKey = viewKey ?? "view";
3820
3863
  const onSubpage = useHasPageHeaderBack();
3821
3864
  if (variant === "sidebar") {
@@ -3827,14 +3870,27 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
3827
3870
  if (variant === "tabs") {
3828
3871
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3829
3872
  !onSubpage && /* @__PURE__ */ jsx(ModuleHeader, { nav }),
3830
- !onSubpage && /* @__PURE__ */ jsx(ViewBarHost, {}),
3831
3873
  showHeader && headerAction && /* @__PURE__ */ jsx(PageHeaderActions, { children: headerAction }),
3832
3874
  /* @__PURE__ */ jsx(PageTransition, { transitionKey, direction, className: cn("min-w-0", className), children })
3833
3875
  ] });
3834
3876
  }
3835
3877
  return /* @__PURE__ */ jsxs("div", { className: cn("min-w-0", className), children: [
3836
3878
  /* @__PURE__ */ jsx(PageRail, { children: /* @__PURE__ */ jsxs("div", { className: "hidden w-48 shrink-0 flex-col overflow-y-auto border-r border-border p-3 no-print md:flex", children: [
3837
- /* @__PURE__ */ jsx("nav", { className: "space-y-0.5", children: nav.map((item) => /* @__PURE__ */ jsx(RailNavItem, { item }, item.id)) }),
3879
+ navFilterPlaceholder && /* @__PURE__ */ jsxs("div", { className: "relative mb-2", children: [
3880
+ /* @__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" }),
3881
+ /* @__PURE__ */ jsx(
3882
+ "input",
3883
+ {
3884
+ type: "search",
3885
+ value: navQuery,
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)) }),
3838
3894
  sidebarFooter && /* @__PURE__ */ jsx("div", { className: "mt-auto pt-3", children: sidebarFooter })
3839
3895
  ] }) }),
3840
3896
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
@@ -3846,5 +3902,5 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
3846
3902
  }
3847
3903
 
3848
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 };
3849
- //# sourceMappingURL=chunk-VBYFN5ZL.js.map
3850
- //# sourceMappingURL=chunk-VBYFN5ZL.js.map
3905
+ //# sourceMappingURL=chunk-PL5CUWNE.js.map
3906
+ //# sourceMappingURL=chunk-PL5CUWNE.js.map