@fayz-ai/ui 0.42.0 → 0.43.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.
- package/dist/{chunk-47B6ISJ6.js → chunk-3HGLZIQT.js} +140 -344
- package/dist/chunk-3HGLZIQT.js.map +1 -0
- package/dist/{chunk-W7CIJU5U.js → chunk-4BP33MTZ.js} +4 -4
- package/dist/{chunk-W7CIJU5U.js.map → chunk-4BP33MTZ.js.map} +1 -1
- package/dist/{chunk-UKMRHO5B.js → chunk-L6PNGGHM.js} +713 -244
- package/dist/chunk-L6PNGGHM.js.map +1 -0
- package/dist/{chunk-GG5XY6SF.js → chunk-ZMS7TNJD.js} +149 -196
- package/dist/chunk-ZMS7TNJD.js.map +1 -0
- package/dist/dashboard/index.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -8
- package/dist/layout/AppShell.d.ts +4 -1
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/index.js +1 -1
- package/dist/primitives/bulk-action-bar.d.ts +3 -1
- package/dist/primitives/bulk-action-bar.d.ts.map +1 -1
- package/dist/primitives/data-table.d.ts +8 -1
- package/dist/primitives/data-table.d.ts.map +1 -1
- package/dist/primitives/dropdown.d.ts +2 -2
- package/dist/primitives/dropdown.d.ts.map +1 -1
- package/dist/primitives/index.d.ts +1 -1
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +3 -3
- package/dist/primitives/list-view.d.ts +3 -1
- package/dist/primitives/list-view.d.ts.map +1 -1
- package/dist/primitives/mobile-scrim.d.ts +29 -0
- package/dist/primitives/mobile-scrim.d.ts.map +1 -0
- package/dist/primitives/page-actions.d.ts +5 -14
- package/dist/primitives/page-actions.d.ts.map +1 -1
- package/dist/primitives/use-row-selection.d.ts +2 -0
- package/dist/primitives/use-row-selection.d.ts.map +1 -1
- package/dist/styles.css +55 -0
- package/package.json +2 -2
- package/dist/chunk-47B6ISJ6.js.map +0 -1
- package/dist/chunk-GG5XY6SF.js.map +0 -1
- package/dist/chunk-UKMRHO5B.js.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { cn, ConfirmDialog } from './chunk-FKYFYGAS.js';
|
|
1
|
+
import { cn, ConfirmDialog, Button } from './chunk-FKYFYGAS.js';
|
|
2
2
|
import { ICON_MAP } from './chunk-ZTS5S6BZ.js';
|
|
3
|
-
import * as
|
|
3
|
+
import * as React16 from 'react';
|
|
4
4
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
5
|
-
import { X, Loader2, ChevronLeft, ArrowLeft, Bell, PanelLeft, PanelLeftClose, Search, CornerDownLeft, Menu, Crown, ChevronsRight, ChevronsLeft,
|
|
5
|
+
import { X, ChevronRight, Check, Circle, Loader2, ChevronLeft, ArrowLeft, ChevronDown, MoreHorizontal, Bell, PanelLeft, PanelLeftClose, Search, CornerDownLeft, Menu, Crown, ChevronsRight, ChevronsLeft, Info, ExternalLink, CreditCard, Sparkles, Home, ChevronUp, Plus, Settings, SlidersHorizontal, MoreVertical, UserCog, LogOut } from 'lucide-react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import { createPortal } from 'react-dom';
|
|
8
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
8
9
|
import { useTranslation, useNavReferrer, routeModule, navHistoryBack, recordNavigation } from '@fayz-ai/core';
|
|
9
10
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
10
11
|
import { create } from 'zustand';
|
|
@@ -28,11 +29,11 @@ var Modal = DialogPrimitive.Root;
|
|
|
28
29
|
var ModalTrigger = DialogPrimitive.Trigger;
|
|
29
30
|
var ModalClose = DialogPrimitive.Close;
|
|
30
31
|
var ModalPortal = DialogPrimitive.Portal;
|
|
31
|
-
var ModalHostContext =
|
|
32
|
+
var ModalHostContext = React16.createContext(null);
|
|
32
33
|
function useModalHost() {
|
|
33
|
-
return
|
|
34
|
+
return React16.useContext(ModalHostContext);
|
|
34
35
|
}
|
|
35
|
-
var ModalOverlay =
|
|
36
|
+
var ModalOverlay = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
36
37
|
DialogPrimitive.Overlay,
|
|
37
38
|
{
|
|
38
39
|
ref,
|
|
@@ -45,9 +46,9 @@ var ModalOverlay = React12.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
45
46
|
}
|
|
46
47
|
));
|
|
47
48
|
ModalOverlay.displayName = "ModalOverlay";
|
|
48
|
-
var ModalContent =
|
|
49
|
-
const [host, setHost] =
|
|
50
|
-
const attach =
|
|
49
|
+
var ModalContent = React16.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => {
|
|
50
|
+
const [host, setHost] = React16.useState(null);
|
|
51
|
+
const attach = React16.useCallback((node) => {
|
|
51
52
|
setHost(node);
|
|
52
53
|
if (typeof ref === "function") ref(node);
|
|
53
54
|
else if (ref) ref.current = node;
|
|
@@ -132,13 +133,229 @@ function ModalFooter({ className, variant = "inline", start, children, ...props
|
|
|
132
133
|
}
|
|
133
134
|
return /* @__PURE__ */ jsx("div", { className: cn("mt-auto flex flex-col-reverse gap-2 pb-[env(safe-area-inset-bottom)] sm:mt-0 sm:flex-row sm:justify-end sm:gap-0 sm:space-x-2 sm:pb-0 shrink-0", className), ...props, children });
|
|
134
135
|
}
|
|
135
|
-
var ModalTitle =
|
|
136
|
+
var ModalTitle = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
|
|
136
137
|
ModalTitle.displayName = "ModalTitle";
|
|
137
|
-
var ModalDescription =
|
|
138
|
+
var ModalDescription = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
138
139
|
ModalDescription.displayName = "ModalDescription";
|
|
140
|
+
function useScrim(open) {
|
|
141
|
+
const [mounted, setMounted] = React16.useState(open);
|
|
142
|
+
const [visible, setVisible] = React16.useState(open);
|
|
143
|
+
React16.useEffect(() => {
|
|
144
|
+
if (open) {
|
|
145
|
+
setMounted(true);
|
|
146
|
+
let frame = requestAnimationFrame(() => {
|
|
147
|
+
frame = requestAnimationFrame(() => setVisible(true));
|
|
148
|
+
});
|
|
149
|
+
return () => cancelAnimationFrame(frame);
|
|
150
|
+
}
|
|
151
|
+
setVisible(false);
|
|
152
|
+
const timer = window.setTimeout(() => setMounted(false), SCRIM_MS);
|
|
153
|
+
return () => window.clearTimeout(timer);
|
|
154
|
+
}, [open]);
|
|
155
|
+
return { mounted, visible };
|
|
156
|
+
}
|
|
157
|
+
var SCRIM_MS = 200;
|
|
158
|
+
function MobileScrim({ open, onClose, focus }) {
|
|
159
|
+
const scrim = useScrim(open);
|
|
160
|
+
const [box, setBox] = React16.useState(null);
|
|
161
|
+
React16.useEffect(() => {
|
|
162
|
+
if (open) setBox(focus ? focus.getBoundingClientRect() : null);
|
|
163
|
+
}, [open, focus]);
|
|
164
|
+
if (!scrim.mounted || typeof document === "undefined") return null;
|
|
165
|
+
const fade = cn("transition-opacity duration-200 motion-reduce:transition-none", scrim.visible ? "opacity-100" : "opacity-0");
|
|
166
|
+
return createPortal(
|
|
167
|
+
box ? /* @__PURE__ */ jsx("div", { "aria-hidden": true, onClick: onClose, className: cn("fixed inset-0 z-[100] overflow-hidden md:hidden", fade), children: /* @__PURE__ */ jsx(
|
|
168
|
+
"div",
|
|
169
|
+
{
|
|
170
|
+
className: cn(
|
|
171
|
+
"absolute rounded-xl ring-1 ring-foreground/10 transition-transform duration-200 ease-out motion-reduce:transition-none",
|
|
172
|
+
scrim.visible ? "scale-100" : "scale-[1.04]"
|
|
173
|
+
),
|
|
174
|
+
style: {
|
|
175
|
+
left: box.left,
|
|
176
|
+
top: box.top,
|
|
177
|
+
width: box.width,
|
|
178
|
+
height: box.height,
|
|
179
|
+
boxShadow: "0 0 0 200vmax hsl(var(--foreground) / 0.4)"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
) }) : /* @__PURE__ */ jsx("div", { "aria-hidden": true, onClick: onClose, className: cn("fixed inset-0 z-[100] bg-foreground/40 md:hidden", fade) }),
|
|
183
|
+
document.body
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
function Dropdown({ open: openProp, defaultOpen, onOpenChange, ...props }) {
|
|
187
|
+
const [own, setOwn] = React16.useState(defaultOpen ?? false);
|
|
188
|
+
const open = openProp ?? own;
|
|
189
|
+
const change = (next) => {
|
|
190
|
+
setOwn(next);
|
|
191
|
+
onOpenChange?.(next);
|
|
192
|
+
};
|
|
193
|
+
const [trigger, setTrigger] = React16.useState(null);
|
|
194
|
+
const focus = open ? trigger?.closest("[data-scrim-focus]") ?? null : null;
|
|
195
|
+
return /* @__PURE__ */ jsxs(DropdownTriggerContext.Provider, { value: setTrigger, children: [
|
|
196
|
+
/* @__PURE__ */ jsx(MobileScrim, { open, onClose: () => change(false), focus }),
|
|
197
|
+
/* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, { open, onOpenChange: change, ...props })
|
|
198
|
+
] });
|
|
199
|
+
}
|
|
200
|
+
var DropdownTriggerContext = React16.createContext(null);
|
|
201
|
+
var DropdownTrigger = React16.forwardRef((props, ref) => {
|
|
202
|
+
const register = React16.useContext(DropdownTriggerContext);
|
|
203
|
+
const setRef = React16.useCallback((el) => {
|
|
204
|
+
register?.(el);
|
|
205
|
+
if (typeof ref === "function") ref(el);
|
|
206
|
+
else if (ref) ref.current = el;
|
|
207
|
+
}, [register, ref]);
|
|
208
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Trigger, { ref: setRef, ...props });
|
|
209
|
+
});
|
|
210
|
+
DropdownTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName;
|
|
211
|
+
var DropdownGroup = DropdownMenuPrimitive.Group;
|
|
212
|
+
var DropdownPortal = DropdownMenuPrimitive.Portal;
|
|
213
|
+
var DropdownSub = DropdownMenuPrimitive.Sub;
|
|
214
|
+
var DropdownRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
215
|
+
var DropdownSubTrigger = React16.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
216
|
+
DropdownMenuPrimitive.SubTrigger,
|
|
217
|
+
{
|
|
218
|
+
ref,
|
|
219
|
+
className: cn(
|
|
220
|
+
"flex cursor-default select-none items-center rounded-button px-2 py-1.5 text-sm outline-none focus:bg-muted data-[state=open]:bg-muted",
|
|
221
|
+
inset && "pl-8",
|
|
222
|
+
className
|
|
223
|
+
),
|
|
224
|
+
...props,
|
|
225
|
+
children: [
|
|
226
|
+
children,
|
|
227
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto h-4 w-4" })
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
));
|
|
231
|
+
DropdownSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
232
|
+
var DropdownSubContent = React16.forwardRef(({ className, ...props }, ref) => (
|
|
233
|
+
// Portaled, like DropdownContent. Without it the submenu renders inside the
|
|
234
|
+
// parent panel's DOM — and that panel is `overflow-hidden`, so the submenu
|
|
235
|
+
// was clipped to its box: a flyout you could open and never reach.
|
|
236
|
+
/* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
237
|
+
DropdownMenuPrimitive.SubContent,
|
|
238
|
+
{
|
|
239
|
+
ref,
|
|
240
|
+
className: cn(
|
|
241
|
+
"fayz-glass-surface fz-menu-glass z-[110] min-w-[8rem] overflow-hidden rounded-card border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
242
|
+
className
|
|
243
|
+
),
|
|
244
|
+
...props
|
|
245
|
+
}
|
|
246
|
+
) })
|
|
247
|
+
));
|
|
248
|
+
DropdownSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
249
|
+
var DropdownContent = React16.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
250
|
+
DropdownMenuPrimitive.Content,
|
|
251
|
+
{
|
|
252
|
+
ref,
|
|
253
|
+
sideOffset,
|
|
254
|
+
className: cn(
|
|
255
|
+
"fayz-glass-surface fz-menu-glass z-[110] min-w-[8rem] overflow-hidden rounded-card border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
256
|
+
className
|
|
257
|
+
),
|
|
258
|
+
...props
|
|
259
|
+
}
|
|
260
|
+
) }));
|
|
261
|
+
DropdownContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
262
|
+
var DropdownItem = React16.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
263
|
+
DropdownMenuPrimitive.Item,
|
|
264
|
+
{
|
|
265
|
+
ref,
|
|
266
|
+
className: cn(
|
|
267
|
+
"relative flex cursor-default select-none items-center rounded-button px-2 py-1.5 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
268
|
+
inset && "pl-8",
|
|
269
|
+
className
|
|
270
|
+
),
|
|
271
|
+
...props
|
|
272
|
+
}
|
|
273
|
+
));
|
|
274
|
+
DropdownItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
275
|
+
var DropdownCheckboxItem = React16.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
276
|
+
DropdownMenuPrimitive.CheckboxItem,
|
|
277
|
+
{
|
|
278
|
+
ref,
|
|
279
|
+
className: cn(
|
|
280
|
+
"relative flex cursor-default select-none items-center rounded-button py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
281
|
+
className
|
|
282
|
+
),
|
|
283
|
+
checked,
|
|
284
|
+
...props,
|
|
285
|
+
children: [
|
|
286
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
|
|
287
|
+
children
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
));
|
|
291
|
+
DropdownCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
292
|
+
var DropdownRadioItem = React16.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
293
|
+
DropdownMenuPrimitive.RadioItem,
|
|
294
|
+
{
|
|
295
|
+
ref,
|
|
296
|
+
className: cn(
|
|
297
|
+
"relative flex cursor-default select-none items-center rounded-button py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
298
|
+
className
|
|
299
|
+
),
|
|
300
|
+
...props,
|
|
301
|
+
children: [
|
|
302
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Circle, { className: "h-2 w-2 fill-current" }) }) }),
|
|
303
|
+
children
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
));
|
|
307
|
+
DropdownRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
308
|
+
var DropdownLabel = React16.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
309
|
+
DropdownMenuPrimitive.Label,
|
|
310
|
+
{
|
|
311
|
+
ref,
|
|
312
|
+
className: cn(
|
|
313
|
+
"px-2 py-1.5 text-sm font-semibold",
|
|
314
|
+
inset && "pl-8",
|
|
315
|
+
className
|
|
316
|
+
),
|
|
317
|
+
...props
|
|
318
|
+
}
|
|
319
|
+
));
|
|
320
|
+
DropdownLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
321
|
+
var DropdownSeparator = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
322
|
+
DropdownMenuPrimitive.Separator,
|
|
323
|
+
{
|
|
324
|
+
ref,
|
|
325
|
+
className: cn("-mx-1 my-1 h-px bg-muted", className),
|
|
326
|
+
...props
|
|
327
|
+
}
|
|
328
|
+
));
|
|
329
|
+
DropdownSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
330
|
+
var DropdownShortcut = ({
|
|
331
|
+
className,
|
|
332
|
+
...props
|
|
333
|
+
}) => {
|
|
334
|
+
return /* @__PURE__ */ jsx(
|
|
335
|
+
"span",
|
|
336
|
+
{
|
|
337
|
+
className: cn("ml-auto text-xs tracking-widest opacity-60", className),
|
|
338
|
+
...props
|
|
339
|
+
}
|
|
340
|
+
);
|
|
341
|
+
};
|
|
342
|
+
DropdownShortcut.displayName = "DropdownShortcut";
|
|
343
|
+
var WIDE_QUERY = "(min-width: 768px)";
|
|
344
|
+
function useIsWide(query = WIDE_QUERY) {
|
|
345
|
+
const [wide, setWide] = React16.useState(
|
|
346
|
+
() => typeof window === "undefined" ? true : window.matchMedia(query).matches
|
|
347
|
+
);
|
|
348
|
+
React16.useEffect(() => {
|
|
349
|
+
const mq = window.matchMedia(query);
|
|
350
|
+
const onChange = () => setWide(mq.matches);
|
|
351
|
+
mq.addEventListener("change", onChange);
|
|
352
|
+
return () => mq.removeEventListener("change", onChange);
|
|
353
|
+
}, [query]);
|
|
354
|
+
return wide;
|
|
355
|
+
}
|
|
139
356
|
var HIDDEN = { visible: false, saving: false };
|
|
140
|
-
var SaveBarApiContext =
|
|
141
|
-
var SaveBarStateContext =
|
|
357
|
+
var SaveBarApiContext = React16.createContext(null);
|
|
358
|
+
var SaveBarStateContext = React16.createContext({ visible: false, saving: false });
|
|
142
359
|
var _saveBarVisible = false;
|
|
143
360
|
var saveFlow = { current: null };
|
|
144
361
|
var requestSave = (onSave) => {
|
|
@@ -157,7 +374,7 @@ function setSaveBarVisibleSignal(v) {
|
|
|
157
374
|
_saveBarSubs.forEach((fn) => fn());
|
|
158
375
|
}
|
|
159
376
|
function useSaveBarVisible() {
|
|
160
|
-
return
|
|
377
|
+
return React16.useSyncExternalStore(
|
|
161
378
|
(cb) => {
|
|
162
379
|
_saveBarSubs.add(cb);
|
|
163
380
|
return () => {
|
|
@@ -169,10 +386,10 @@ function useSaveBarVisible() {
|
|
|
169
386
|
);
|
|
170
387
|
}
|
|
171
388
|
function SaveBarProvider({ children }) {
|
|
172
|
-
const [state, setState] =
|
|
173
|
-
const handlers =
|
|
174
|
-
const entries =
|
|
175
|
-
const api =
|
|
389
|
+
const [state, setState] = React16.useState({ visible: false, saving: false });
|
|
390
|
+
const handlers = React16.useRef({});
|
|
391
|
+
const entries = React16.useRef([]);
|
|
392
|
+
const api = React16.useMemo(() => ({
|
|
176
393
|
setState,
|
|
177
394
|
handlers,
|
|
178
395
|
entries,
|
|
@@ -182,16 +399,16 @@ function SaveBarProvider({ children }) {
|
|
|
182
399
|
setState(top ? top.state : HIDDEN);
|
|
183
400
|
}
|
|
184
401
|
}), []);
|
|
185
|
-
const backStack =
|
|
186
|
-
const backApi =
|
|
187
|
-
|
|
402
|
+
const backStack = React16.useRef([]);
|
|
403
|
+
const backApi = React16.useMemo(() => ({ stack: backStack }), []);
|
|
404
|
+
React16.useEffect(() => {
|
|
188
405
|
setSaveBarVisibleSignal(state.visible);
|
|
189
406
|
}, [state.visible]);
|
|
190
|
-
const [leaveTo, setLeaveTo] =
|
|
191
|
-
const bypass =
|
|
407
|
+
const [leaveTo, setLeaveTo] = React16.useState(null);
|
|
408
|
+
const bypass = React16.useRef(false);
|
|
192
409
|
if (state.saving && saveFlow.current) saveFlow.current.started = true;
|
|
193
410
|
const t = useTranslation();
|
|
194
|
-
|
|
411
|
+
React16.useEffect(() => {
|
|
195
412
|
if (!state.dirty || state.host || typeof window === "undefined") return;
|
|
196
413
|
const guarded = window.location.href;
|
|
197
414
|
const onNav = (e) => {
|
|
@@ -226,7 +443,7 @@ function SaveBarProvider({ children }) {
|
|
|
226
443
|
bypass.current = false;
|
|
227
444
|
}, 0);
|
|
228
445
|
};
|
|
229
|
-
|
|
446
|
+
React16.useEffect(() => {
|
|
230
447
|
function onKey(e) {
|
|
231
448
|
if (state.visible && !state.saving) {
|
|
232
449
|
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
|
@@ -269,7 +486,7 @@ function SaveBarProvider({ children }) {
|
|
|
269
486
|
)
|
|
270
487
|
] }) }) });
|
|
271
488
|
}
|
|
272
|
-
var BackNavApiContext =
|
|
489
|
+
var BackNavApiContext = React16.createContext(null);
|
|
273
490
|
function isEditableTarget(target) {
|
|
274
491
|
const el = target;
|
|
275
492
|
if (!el || !el.tagName) return false;
|
|
@@ -277,12 +494,12 @@ function isEditableTarget(target) {
|
|
|
277
494
|
return tag === "input" || tag === "textarea" || tag === "select" || el.isContentEditable;
|
|
278
495
|
}
|
|
279
496
|
function useBackHandler(onBack) {
|
|
280
|
-
const api =
|
|
281
|
-
const ref =
|
|
282
|
-
|
|
497
|
+
const api = React16.useContext(BackNavApiContext);
|
|
498
|
+
const ref = React16.useRef(onBack);
|
|
499
|
+
React16.useEffect(() => {
|
|
283
500
|
ref.current = onBack;
|
|
284
501
|
});
|
|
285
|
-
|
|
502
|
+
React16.useEffect(() => {
|
|
286
503
|
if (!api) return;
|
|
287
504
|
const stack = api.stack.current;
|
|
288
505
|
stack.push(ref);
|
|
@@ -293,16 +510,16 @@ function useBackHandler(onBack) {
|
|
|
293
510
|
}, [api]);
|
|
294
511
|
}
|
|
295
512
|
function useSaveBar({ dirty, alwaysVisible, saving = false, onSave, onDiscard, message, saveLabel, discardLabel }) {
|
|
296
|
-
const api =
|
|
513
|
+
const api = React16.useContext(SaveBarApiContext);
|
|
297
514
|
const host = useModalHost();
|
|
298
|
-
const entry =
|
|
299
|
-
|
|
515
|
+
const entry = React16.useRef({ state: HIDDEN, handlers: {} });
|
|
516
|
+
React16.useEffect(() => {
|
|
300
517
|
entry.current.handlers = { onSave, onDiscard };
|
|
301
518
|
if (api && api.entries.current[api.entries.current.length - 1] === entry.current) {
|
|
302
519
|
api.handlers.current = entry.current.handlers;
|
|
303
520
|
}
|
|
304
521
|
});
|
|
305
|
-
|
|
522
|
+
React16.useEffect(() => {
|
|
306
523
|
if (!api) return;
|
|
307
524
|
const list = api.entries.current;
|
|
308
525
|
list.push(entry.current);
|
|
@@ -313,19 +530,19 @@ function useSaveBar({ dirty, alwaysVisible, saving = false, onSave, onDiscard, m
|
|
|
313
530
|
api.sync();
|
|
314
531
|
};
|
|
315
532
|
}, [api]);
|
|
316
|
-
|
|
533
|
+
React16.useEffect(() => {
|
|
317
534
|
if (!api) return;
|
|
318
535
|
entry.current.state = { visible: dirty || !!alwaysVisible, dirty, saving, message, saveLabel, discardLabel, host };
|
|
319
536
|
if (api.entries.current[api.entries.current.length - 1] === entry.current) api.sync();
|
|
320
537
|
}, [api, dirty, alwaysVisible, saving, message, saveLabel, discardLabel, host]);
|
|
321
538
|
}
|
|
322
539
|
function SaveBar({ className }) {
|
|
323
|
-
const state =
|
|
324
|
-
const api =
|
|
540
|
+
const state = React16.useContext(SaveBarStateContext);
|
|
541
|
+
const api = React16.useContext(SaveBarApiContext);
|
|
325
542
|
const t = useTranslation();
|
|
326
|
-
const [rendered, setRendered] =
|
|
327
|
-
const [closing, setClosing] =
|
|
328
|
-
|
|
543
|
+
const [rendered, setRendered] = React16.useState(state.visible);
|
|
544
|
+
const [closing, setClosing] = React16.useState(false);
|
|
545
|
+
React16.useEffect(() => {
|
|
329
546
|
if (state.visible) {
|
|
330
547
|
setRendered(true);
|
|
331
548
|
setClosing(false);
|
|
@@ -391,7 +608,7 @@ function SaveBar({ className }) {
|
|
|
391
608
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
392
609
|
var Tooltip = TooltipPrimitive.Root;
|
|
393
610
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
394
|
-
var TooltipContent =
|
|
611
|
+
var TooltipContent = React16.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (
|
|
395
612
|
// Portaled: inside a scroll box (a table, a modal body) the tip was clipped by its container.
|
|
396
613
|
/* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
397
614
|
TooltipPrimitive.Content,
|
|
@@ -436,7 +653,7 @@ var usePageHeaderStore = create((set, get) => ({
|
|
|
436
653
|
function useRegisterPageActions() {
|
|
437
654
|
const add = usePageHeaderStore((s) => s.addActions);
|
|
438
655
|
const remove = usePageHeaderStore((s) => s.removeActions);
|
|
439
|
-
|
|
656
|
+
React16.useEffect(() => {
|
|
440
657
|
add();
|
|
441
658
|
return remove;
|
|
442
659
|
}, [add, remove]);
|
|
@@ -459,7 +676,7 @@ function usePageTitleSlotHost() {
|
|
|
459
676
|
function usePageHeaderHost() {
|
|
460
677
|
const addHost = usePageHeaderStore((s) => s.addHost);
|
|
461
678
|
const removeHost = usePageHeaderStore((s) => s.removeHost);
|
|
462
|
-
|
|
679
|
+
React16.useEffect(() => {
|
|
463
680
|
addHost();
|
|
464
681
|
return removeHost;
|
|
465
682
|
}, [addHost, removeHost]);
|
|
@@ -477,30 +694,30 @@ function PageHeaderOutlet({ className, active = true }) {
|
|
|
477
694
|
const hasActions = usePageHeaderStore((s) => s.actions > 0);
|
|
478
695
|
const addOutlet = usePageHeaderStore((s) => s.addOutlet);
|
|
479
696
|
const removeOutlet = usePageHeaderStore((s) => s.removeOutlet);
|
|
480
|
-
|
|
697
|
+
React16.useEffect(() => {
|
|
481
698
|
if (!active) return;
|
|
482
699
|
addOutlet();
|
|
483
700
|
return removeOutlet;
|
|
484
701
|
}, [active, addOutlet, removeOutlet]);
|
|
485
|
-
|
|
702
|
+
React16.useEffect(() => {
|
|
486
703
|
if (active) return;
|
|
487
704
|
setOutletSlot(null);
|
|
488
705
|
setOutletActionsSlot(null);
|
|
489
706
|
}, [active, setOutletSlot, setOutletActionsSlot]);
|
|
490
707
|
if (!active) return null;
|
|
491
|
-
return
|
|
708
|
+
return React16.createElement(
|
|
492
709
|
"div",
|
|
493
710
|
{ className: `flex min-h-9 items-center justify-between gap-3${claimed || hasActions ? "" : " hidden"} ${className ?? "mb-3"}` },
|
|
494
|
-
|
|
495
|
-
|
|
711
|
+
React16.createElement("div", { ref: setOutletSlot, className: "flex min-w-0 flex-1 items-center" }),
|
|
712
|
+
React16.createElement("div", { ref: setOutletActionsSlot, className: "flex shrink-0 items-center gap-2" })
|
|
496
713
|
);
|
|
497
714
|
}
|
|
498
715
|
function usePageHeader(active, options) {
|
|
499
|
-
const id =
|
|
716
|
+
const id = React16.useId();
|
|
500
717
|
const claim = usePageHeaderStore((s) => s.claim);
|
|
501
718
|
const release = usePageHeaderStore((s) => s.release);
|
|
502
719
|
const back = options?.back ?? false;
|
|
503
|
-
|
|
720
|
+
React16.useEffect(() => {
|
|
504
721
|
if (!active) {
|
|
505
722
|
release(id);
|
|
506
723
|
return;
|
|
@@ -517,18 +734,18 @@ function useModuleViewLabel() {
|
|
|
517
734
|
}
|
|
518
735
|
function usePublishModuleViewLabel(label) {
|
|
519
736
|
const setLabel = usePageHeaderStore((s) => s.setModuleViewLabel);
|
|
520
|
-
|
|
737
|
+
React16.useEffect(() => {
|
|
521
738
|
setLabel(label ?? null);
|
|
522
739
|
return () => setLabel(null);
|
|
523
740
|
}, [label, setLabel]);
|
|
524
741
|
}
|
|
525
742
|
function PageTitlePortal({ children }) {
|
|
526
743
|
const slot = usePageTitleSlot();
|
|
527
|
-
if (!slot) return
|
|
744
|
+
if (!slot) return React16.createElement(React16.Fragment, null, children);
|
|
528
745
|
return createPortal(children, slot);
|
|
529
746
|
}
|
|
530
|
-
var Hint =
|
|
531
|
-
if (!label) return
|
|
747
|
+
var Hint = React16.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
|
|
748
|
+
if (!label) return React16.cloneElement(children, { ...rest, ref });
|
|
532
749
|
return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
533
750
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, ...rest, ref, children }),
|
|
534
751
|
/* @__PURE__ */ jsx(TooltipContent, { side, className: "px-2 py-1 text-xs font-medium", children: label })
|
|
@@ -617,7 +834,7 @@ function PageHeader({ title, onBack, parentLabel, backLabel }) {
|
|
|
617
834
|
const hasHost = useHasPageHeaderHost();
|
|
618
835
|
const { onBack: effectiveOnBack, parentLabel: effectiveParent } = useCrossModuleBack(onBack, parentLabel);
|
|
619
836
|
useBackHandler(effectiveOnBack);
|
|
620
|
-
const node =
|
|
837
|
+
const node = React16.useMemo(() => /* @__PURE__ */ jsx(
|
|
621
838
|
PageHeaderCrumb,
|
|
622
839
|
{
|
|
623
840
|
title,
|
|
@@ -629,17 +846,198 @@ function PageHeader({ title, onBack, parentLabel, backLabel }) {
|
|
|
629
846
|
if (hasHost) return /* @__PURE__ */ jsx(PageTitlePortal, { children: node });
|
|
630
847
|
return /* @__PURE__ */ jsx("div", { className: "mb-4", children: node });
|
|
631
848
|
}
|
|
849
|
+
function iconOf(action, className) {
|
|
850
|
+
const Icon = action.icon;
|
|
851
|
+
return Icon ? /* @__PURE__ */ jsx(Icon, { className }) : null;
|
|
852
|
+
}
|
|
853
|
+
function PageActionBar({ actions, className }) {
|
|
854
|
+
const wide = useIsWide();
|
|
855
|
+
const visible = actions.filter((a) => !a.hidden);
|
|
856
|
+
if (visible.length === 0) return null;
|
|
857
|
+
if (!wide) {
|
|
858
|
+
const usable = visible.filter((a) => !a.desktopOnly);
|
|
859
|
+
if (usable.length === 0) return null;
|
|
860
|
+
const fab = /* @__PURE__ */ jsx(PageActionFab, { actions: usable });
|
|
861
|
+
const fabHost = typeof document !== "undefined" ? document.querySelector(".shell-enter") ?? document.body : null;
|
|
862
|
+
return fabHost ? createPortal(fab, fabHost) : fab;
|
|
863
|
+
}
|
|
864
|
+
let seenPrimary = false;
|
|
865
|
+
const primary = [];
|
|
866
|
+
const secondary = [];
|
|
867
|
+
const utility = [];
|
|
868
|
+
const danger = [];
|
|
869
|
+
for (const a of visible) {
|
|
870
|
+
const intent = a.intent ?? "secondary";
|
|
871
|
+
if (intent === "primary" && !seenPrimary) {
|
|
872
|
+
seenPrimary = true;
|
|
873
|
+
primary.push(a);
|
|
874
|
+
continue;
|
|
875
|
+
}
|
|
876
|
+
if (intent === "danger") {
|
|
877
|
+
danger.push(a);
|
|
878
|
+
continue;
|
|
879
|
+
}
|
|
880
|
+
if (intent === "utility") {
|
|
881
|
+
utility.push(a);
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
884
|
+
secondary.push(a);
|
|
885
|
+
}
|
|
886
|
+
const head = primary[0];
|
|
887
|
+
const menu = [...secondary, ...danger];
|
|
888
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 items-center gap-2", className), children: [
|
|
889
|
+
utility.map((a) => (
|
|
890
|
+
// Um botão só de ícone não diz o que faz. `title=` parecia resolver e
|
|
891
|
+
// não resolve: espera ~1s que ninguém controla, sai na pintura do
|
|
892
|
+
// sistema operacional, nunca aparece no toque e vários leitores de tela
|
|
893
|
+
// pulam. Hint é o tooltip do design system, e o texto é ANUNCIADO.
|
|
894
|
+
/* @__PURE__ */ jsx(Hint, { label: a.label, children: /* @__PURE__ */ jsx(
|
|
895
|
+
Button,
|
|
896
|
+
{
|
|
897
|
+
variant: "ghost",
|
|
898
|
+
size: "icon",
|
|
899
|
+
onClick: () => void a.onSelect(),
|
|
900
|
+
disabled: a.disabled,
|
|
901
|
+
"aria-label": a.label,
|
|
902
|
+
"data-testid": a.testId,
|
|
903
|
+
"data-tour": `action.${a.id}`,
|
|
904
|
+
children: iconOf(a, "h-4 w-4")
|
|
905
|
+
}
|
|
906
|
+
) }, a.id)
|
|
907
|
+
)),
|
|
908
|
+
head && menu.length === 0 && /* @__PURE__ */ jsxs(Button, { className: head.ai ? "fz-ai-button" : void 0, onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, "data-tour": `action.${head.id}`, children: [
|
|
909
|
+
iconOf(head, "mr-1.5 h-4 w-4"),
|
|
910
|
+
head.label
|
|
911
|
+
] }),
|
|
912
|
+
head && menu.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
913
|
+
/* @__PURE__ */ jsxs(Button, { className: "rounded-r-none", onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, "data-tour": `action.${head.id}`, children: [
|
|
914
|
+
iconOf(head, "mr-1.5 h-4 w-4"),
|
|
915
|
+
head.label
|
|
916
|
+
] }),
|
|
917
|
+
/* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
918
|
+
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: `${head.label}\u2026`, children: /* @__PURE__ */ jsx(
|
|
919
|
+
Button,
|
|
920
|
+
{
|
|
921
|
+
className: "-ml-px rounded-l-none px-2",
|
|
922
|
+
"aria-label": `${head.label}\u2026`,
|
|
923
|
+
"data-tour": menu.map((a) => `action.${a.id}`).join(" "),
|
|
924
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
|
|
925
|
+
}
|
|
926
|
+
) }) }),
|
|
927
|
+
/* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
|
|
928
|
+
] })
|
|
929
|
+
] }),
|
|
930
|
+
!head && menu.length > 0 && /* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
931
|
+
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: "A\xE7\xF5es", children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": "A\xE7\xF5es", children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" }) }) }) }),
|
|
932
|
+
/* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
|
|
933
|
+
] })
|
|
934
|
+
] });
|
|
935
|
+
}
|
|
936
|
+
function ActionItems({ actions, stagger }) {
|
|
937
|
+
const out = [];
|
|
938
|
+
actions.forEach((a, i) => {
|
|
939
|
+
const isDanger = a.intent === "danger";
|
|
940
|
+
const prevSafe = i > 0 && actions[i - 1].intent !== "danger";
|
|
941
|
+
if (isDanger && prevSafe) out.push(/* @__PURE__ */ jsx(DropdownSeparator, {}, `${a.id}-sep`));
|
|
942
|
+
out.push(
|
|
943
|
+
/* @__PURE__ */ jsxs(
|
|
944
|
+
DropdownItem,
|
|
945
|
+
{
|
|
946
|
+
disabled: a.disabled,
|
|
947
|
+
onSelect: () => void a.onSelect(),
|
|
948
|
+
"data-testid": a.testId,
|
|
949
|
+
style: stagger ? { ["--i"]: i } : void 0,
|
|
950
|
+
className: cn("gap-2", stagger && "fz-fab-item min-h-12 gap-3 px-3 text-[15px]", isDanger && "text-destructive focus:text-destructive", a.ai && "fz-ai-action"),
|
|
951
|
+
children: [
|
|
952
|
+
iconOf(a, "h-4 w-4 shrink-0"),
|
|
953
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
|
|
954
|
+
/* @__PURE__ */ jsx("span", { className: "block truncate", children: a.label }),
|
|
955
|
+
a.description && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-muted-foreground", children: a.description })
|
|
956
|
+
] })
|
|
957
|
+
]
|
|
958
|
+
},
|
|
959
|
+
a.id
|
|
960
|
+
)
|
|
961
|
+
);
|
|
962
|
+
});
|
|
963
|
+
return /* @__PURE__ */ jsx(Fragment, { children: out });
|
|
964
|
+
}
|
|
965
|
+
function PageActionFab({ actions }) {
|
|
966
|
+
const byIntent = (i) => actions.filter((a) => (a.intent ?? "secondary") === i);
|
|
967
|
+
const utility = byIntent("utility");
|
|
968
|
+
const main = [...byIntent("primary"), ...byIntent("secondary"), ...byIntent("danger")];
|
|
969
|
+
if (main.length === 0) return /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral" });
|
|
970
|
+
const isCreate = main.every((a) => a.creates ?? a.icon === Plus);
|
|
971
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
972
|
+
utility.length > 0 && /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral", mini: true }),
|
|
973
|
+
/* @__PURE__ */ jsx(FabButton, { actions: main, tone: isCreate ? "primary" : "neutral" })
|
|
974
|
+
] });
|
|
975
|
+
}
|
|
976
|
+
function FabButton({ actions, tone, mini }) {
|
|
977
|
+
const [open, setOpen] = React16.useState(false);
|
|
978
|
+
if (actions.length === 0) return null;
|
|
979
|
+
const isCreate = tone === "primary";
|
|
980
|
+
const FabIcon = isCreate ? Plus : MoreVertical;
|
|
981
|
+
const style = {
|
|
982
|
+
bottom: mini ? "calc(var(--fz-bottom-bar, 0px) + 4.75rem)" : "calc(var(--fz-bottom-bar, 0px) + 1rem)"
|
|
983
|
+
};
|
|
984
|
+
const shell = cn(
|
|
985
|
+
"fz-tap fixed z-40 flex items-center justify-center rounded-full",
|
|
986
|
+
"transition-transform active:scale-95 md:hidden",
|
|
987
|
+
// Centred on the main circle's column, so the two read as one stack.
|
|
988
|
+
mini ? "right-5 h-12 w-12" : "right-4 h-14 w-14",
|
|
989
|
+
// Glass, like the bars it floats between: a tinted fill over a heavy blur,
|
|
990
|
+
// lit on the top edge. The blur is what keeps the glyph legible over
|
|
991
|
+
// whatever scrolls beneath — the fill alone would not.
|
|
992
|
+
"backdrop-blur-xl backdrop-saturate-150",
|
|
993
|
+
isCreate ? "bg-primary/75 text-primary-foreground ring-1 ring-white/25 shadow-[inset_0_1px_0_rgb(255_255_255/0.35),0_10px_24px_-8px_hsl(var(--primary)/0.5)]" : "bg-card/60 text-foreground ring-1 ring-border/60 shadow-[inset_0_1px_0_rgb(255_255_255/0.5),0_10px_24px_-10px_rgb(0_0_0/0.35)]"
|
|
994
|
+
);
|
|
995
|
+
if (actions.length === 1) {
|
|
996
|
+
const only = actions[0];
|
|
997
|
+
const Icon = only.icon ?? FabIcon;
|
|
998
|
+
return /* @__PURE__ */ jsx(
|
|
999
|
+
"button",
|
|
1000
|
+
{
|
|
1001
|
+
type: "button",
|
|
1002
|
+
style,
|
|
1003
|
+
className: shell,
|
|
1004
|
+
onClick: () => void only.onSelect(),
|
|
1005
|
+
disabled: only.disabled,
|
|
1006
|
+
"aria-label": only.label,
|
|
1007
|
+
"data-testid": only.testId,
|
|
1008
|
+
children: /* @__PURE__ */ jsx(Icon, { className: mini ? "h-5 w-5" : "h-6 w-6" })
|
|
1009
|
+
}
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
return /* @__PURE__ */ jsxs(Dropdown, { open, onOpenChange: setOpen, children: [
|
|
1013
|
+
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1014
|
+
"button",
|
|
1015
|
+
{
|
|
1016
|
+
type: "button",
|
|
1017
|
+
style,
|
|
1018
|
+
className: cn(shell, open && "z-[105]", isCreate && "fz-fab-trigger"),
|
|
1019
|
+
"aria-label": actionsMenuLabel,
|
|
1020
|
+
children: /* @__PURE__ */ jsx(FabIcon, { className: mini ? "h-5 w-5" : "h-6 w-6" })
|
|
1021
|
+
}
|
|
1022
|
+
) }),
|
|
1023
|
+
/* @__PURE__ */ jsx(DropdownContent, { side: "top", align: "end", sideOffset: 12, className: "fz-fab-menu w-72 p-1.5 md:hidden", children: /* @__PURE__ */ jsx(ActionItems, { actions, stagger: true }) })
|
|
1024
|
+
] });
|
|
1025
|
+
}
|
|
1026
|
+
var actionsMenuLabel = "A\xE7\xF5es";
|
|
1027
|
+
function setActionsMenuLabel(label) {
|
|
1028
|
+
actionsMenuLabel = label;
|
|
1029
|
+
}
|
|
632
1030
|
var GUTTER_PX = 8;
|
|
633
1031
|
var CLOSE_DELAY_MS = 140;
|
|
634
|
-
var useIsomorphicLayoutEffect = typeof window !== "undefined" ?
|
|
635
|
-
function
|
|
1032
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React16.useLayoutEffect : React16.useEffect;
|
|
1033
|
+
function iconOf2(name) {
|
|
636
1034
|
if (!name) return null;
|
|
637
1035
|
return ICON_MAP[name] ?? null;
|
|
638
1036
|
}
|
|
639
|
-
var RailFlyoutContext =
|
|
1037
|
+
var RailFlyoutContext = React16.createContext(null);
|
|
640
1038
|
var RailFlyoutProvider = RailFlyoutContext.Provider;
|
|
641
1039
|
function useRailRow(content) {
|
|
642
|
-
const flyout =
|
|
1040
|
+
const flyout = React16.useContext(RailFlyoutContext);
|
|
643
1041
|
if (!flyout || !content) return {};
|
|
644
1042
|
return flyout.rowProps(content);
|
|
645
1043
|
}
|
|
@@ -649,19 +1047,19 @@ function useRailFlyout({
|
|
|
649
1047
|
activeRoute,
|
|
650
1048
|
onNavigate
|
|
651
1049
|
}) {
|
|
652
|
-
const [state, setState] =
|
|
653
|
-
const [pos, setPos] =
|
|
654
|
-
const [animate, setAnimate] =
|
|
655
|
-
const panelRef =
|
|
656
|
-
const closeTimer =
|
|
657
|
-
const lastContent =
|
|
658
|
-
const cancelClose =
|
|
1050
|
+
const [state, setState] = React16.useState(null);
|
|
1051
|
+
const [pos, setPos] = React16.useState({ top: 0, arrow: 20 });
|
|
1052
|
+
const [animate, setAnimate] = React16.useState(false);
|
|
1053
|
+
const panelRef = React16.useRef(null);
|
|
1054
|
+
const closeTimer = React16.useRef(null);
|
|
1055
|
+
const lastContent = React16.useRef(null);
|
|
1056
|
+
const cancelClose = React16.useCallback(() => {
|
|
659
1057
|
if (closeTimer.current) {
|
|
660
1058
|
clearTimeout(closeTimer.current);
|
|
661
1059
|
closeTimer.current = null;
|
|
662
1060
|
}
|
|
663
1061
|
}, []);
|
|
664
|
-
const show =
|
|
1062
|
+
const show = React16.useCallback(
|
|
665
1063
|
(anchor, content2) => {
|
|
666
1064
|
if (!enabled) return;
|
|
667
1065
|
cancelClose();
|
|
@@ -669,19 +1067,19 @@ function useRailFlyout({
|
|
|
669
1067
|
},
|
|
670
1068
|
[enabled, cancelClose]
|
|
671
1069
|
);
|
|
672
|
-
const hide =
|
|
1070
|
+
const hide = React16.useCallback(() => {
|
|
673
1071
|
cancelClose();
|
|
674
1072
|
closeTimer.current = setTimeout(() => setState(null), CLOSE_DELAY_MS);
|
|
675
1073
|
}, [cancelClose]);
|
|
676
|
-
const dismiss =
|
|
1074
|
+
const dismiss = React16.useCallback(() => {
|
|
677
1075
|
cancelClose();
|
|
678
1076
|
setState(null);
|
|
679
1077
|
}, [cancelClose]);
|
|
680
|
-
|
|
681
|
-
|
|
1078
|
+
React16.useEffect(() => () => cancelClose(), [cancelClose]);
|
|
1079
|
+
React16.useEffect(() => {
|
|
682
1080
|
if (!enabled) dismiss();
|
|
683
1081
|
}, [enabled, dismiss]);
|
|
684
|
-
const reposition =
|
|
1082
|
+
const reposition = React16.useCallback(() => {
|
|
685
1083
|
const rail = railRef.current;
|
|
686
1084
|
const anchor = state?.anchor;
|
|
687
1085
|
if (!rail || !anchor) return;
|
|
@@ -696,7 +1094,7 @@ function useRailFlyout({
|
|
|
696
1094
|
setPos({ top, arrow });
|
|
697
1095
|
}, [railRef, state]);
|
|
698
1096
|
useIsomorphicLayoutEffect(reposition, [reposition, state?.content.key]);
|
|
699
|
-
|
|
1097
|
+
React16.useEffect(() => {
|
|
700
1098
|
if (!state) return;
|
|
701
1099
|
const rail = railRef.current;
|
|
702
1100
|
const onScroll = () => reposition();
|
|
@@ -708,7 +1106,7 @@ function useRailFlyout({
|
|
|
708
1106
|
};
|
|
709
1107
|
}, [state, railRef, reposition]);
|
|
710
1108
|
const visible = !!state;
|
|
711
|
-
|
|
1109
|
+
React16.useEffect(() => {
|
|
712
1110
|
if (!visible) {
|
|
713
1111
|
setAnimate(false);
|
|
714
1112
|
return;
|
|
@@ -716,7 +1114,7 @@ function useRailFlyout({
|
|
|
716
1114
|
const id = requestAnimationFrame(() => setAnimate(true));
|
|
717
1115
|
return () => cancelAnimationFrame(id);
|
|
718
1116
|
}, [visible]);
|
|
719
|
-
|
|
1117
|
+
React16.useEffect(() => {
|
|
720
1118
|
if (!visible) return;
|
|
721
1119
|
const onKey = (event) => {
|
|
722
1120
|
if (event.key === "Escape") dismiss();
|
|
@@ -724,7 +1122,7 @@ function useRailFlyout({
|
|
|
724
1122
|
window.addEventListener("keydown", onKey);
|
|
725
1123
|
return () => window.removeEventListener("keydown", onKey);
|
|
726
1124
|
}, [visible, dismiss]);
|
|
727
|
-
const rowProps =
|
|
1125
|
+
const rowProps = React16.useCallback(
|
|
728
1126
|
(content2) => ({
|
|
729
1127
|
onMouseEnter: (event) => show(event.currentTarget, content2),
|
|
730
1128
|
onFocus: (event) => show(event.currentTarget, content2),
|
|
@@ -834,7 +1232,7 @@ function FlyoutBody({
|
|
|
834
1232
|
hasEntries && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
835
1233
|
/* @__PURE__ */ jsx("div", { className: "my-1 h-px bg-sidebar-border" }),
|
|
836
1234
|
/* @__PURE__ */ jsx("div", { className: "flex flex-col", children: entries.map((entry) => {
|
|
837
|
-
const EntryIcon =
|
|
1235
|
+
const EntryIcon = iconOf2(entry.icon);
|
|
838
1236
|
const isActive = !!entry.route && entry.route === activeRoute;
|
|
839
1237
|
return /* @__PURE__ */ jsxs(
|
|
840
1238
|
"button",
|
|
@@ -905,7 +1303,7 @@ function NavChildConnector({ onPath, active }) {
|
|
|
905
1303
|
] });
|
|
906
1304
|
}
|
|
907
1305
|
var RAIL_PUSH_MS = 260;
|
|
908
|
-
var useIsomorphicLayoutEffect2 = typeof window !== "undefined" ?
|
|
1306
|
+
var useIsomorphicLayoutEffect2 = typeof window !== "undefined" ? React16.useLayoutEffect : React16.useEffect;
|
|
909
1307
|
function getIcon(name) {
|
|
910
1308
|
return ICON_MAP[name] ?? Home;
|
|
911
1309
|
}
|
|
@@ -1116,7 +1514,7 @@ function NavGroup({
|
|
|
1116
1514
|
// case in an app that groups its rail).
|
|
1117
1515
|
/* @__PURE__ */ jsx("button", { "data-tour": `nav.${child.route}`, onClick: () => onNavigate(child.route), className: childClass, children: childInner })
|
|
1118
1516
|
);
|
|
1119
|
-
if (!childConnector) return /* @__PURE__ */ jsx(
|
|
1517
|
+
if (!childConnector) return /* @__PURE__ */ jsx(React16.Fragment, { children: row }, child.id);
|
|
1120
1518
|
const activeIndex = item.children.findIndex((c) => c.route === activeRoute);
|
|
1121
1519
|
const onPath = activeIndex >= 0 && childIndex < activeIndex;
|
|
1122
1520
|
return (
|
|
@@ -1138,9 +1536,9 @@ function NavGroup({
|
|
|
1138
1536
|
] });
|
|
1139
1537
|
}
|
|
1140
1538
|
function withCollapsed(slot, collapsed) {
|
|
1141
|
-
if (!
|
|
1539
|
+
if (!React16.isValidElement(slot)) return slot;
|
|
1142
1540
|
if (typeof slot.type === "string") return slot;
|
|
1143
|
-
return
|
|
1541
|
+
return React16.cloneElement(slot, { collapsed });
|
|
1144
1542
|
}
|
|
1145
1543
|
var SKELETON_ROWS = [
|
|
1146
1544
|
{ width: 56, group: false },
|
|
@@ -1182,7 +1580,7 @@ function Sidebar({
|
|
|
1182
1580
|
}) {
|
|
1183
1581
|
const currentPath = currentPathProp;
|
|
1184
1582
|
const activeRoute = resolveActiveRoute(navigation, currentPath);
|
|
1185
|
-
const railRef =
|
|
1583
|
+
const railRef = React16.useRef(null);
|
|
1186
1584
|
const flyout = useRailFlyout({
|
|
1187
1585
|
enabled: collapsed,
|
|
1188
1586
|
railRef,
|
|
@@ -1195,14 +1593,14 @@ function Sidebar({
|
|
|
1195
1593
|
const handleNavigate = (route) => {
|
|
1196
1594
|
onNavigate?.(route);
|
|
1197
1595
|
};
|
|
1198
|
-
const groupWithActiveRoute =
|
|
1596
|
+
const groupWithActiveRoute = React16.useMemo(() => {
|
|
1199
1597
|
const groups = navigation.filter((item) => item.children && item.children.length > 0);
|
|
1200
1598
|
return groups.find(
|
|
1201
1599
|
(item) => item.route === activeRoute || item.children.some((child) => child.route === activeRoute)
|
|
1202
1600
|
)?.id ?? null;
|
|
1203
1601
|
}, [navigation, activeRoute]);
|
|
1204
|
-
const [openGroup, setOpenGroup] =
|
|
1205
|
-
|
|
1602
|
+
const [openGroup, setOpenGroup] = React16.useState(groupWithActiveRoute);
|
|
1603
|
+
React16.useEffect(() => {
|
|
1206
1604
|
if (groupWithActiveRoute) setOpenGroup(groupWithActiveRoute);
|
|
1207
1605
|
}, [groupWithActiveRoute]);
|
|
1208
1606
|
const sectionHeading = (label) => label && !collapsed ? /* @__PURE__ */ jsx("p", { className: "px-2.5 pb-0.5 pt-1 text-[10px] font-semibold uppercase tracking-wider text-sidebar-muted", children: label }) : null;
|
|
@@ -1254,10 +1652,10 @@ function Sidebar({
|
|
|
1254
1652
|
mainItems.length > 0 && renderSection(mainItems, sectionLabels?.main),
|
|
1255
1653
|
secondaryItems.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-6", children: renderSection(secondaryItems, sectionLabels?.secondary) })
|
|
1256
1654
|
] });
|
|
1257
|
-
const [outgoing, setOutgoing] =
|
|
1258
|
-
const lastBodyRef =
|
|
1259
|
-
const lastKeyRef =
|
|
1260
|
-
const timerRef =
|
|
1655
|
+
const [outgoing, setOutgoing] = React16.useState(null);
|
|
1656
|
+
const lastBodyRef = React16.useRef(null);
|
|
1657
|
+
const lastKeyRef = React16.useRef(navKey);
|
|
1658
|
+
const timerRef = React16.useRef(null);
|
|
1261
1659
|
useIsomorphicLayoutEffect2(() => {
|
|
1262
1660
|
if (lastKeyRef.current !== navKey) {
|
|
1263
1661
|
const previousBody = lastBodyRef.current;
|
|
@@ -1270,7 +1668,7 @@ function Sidebar({
|
|
|
1270
1668
|
}
|
|
1271
1669
|
lastBodyRef.current = navBody;
|
|
1272
1670
|
});
|
|
1273
|
-
|
|
1671
|
+
React16.useEffect(() => () => {
|
|
1274
1672
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1275
1673
|
}, []);
|
|
1276
1674
|
return (
|
|
@@ -1514,7 +1912,7 @@ function ShellSearch({
|
|
|
1514
1912
|
const rail = tone === "rail";
|
|
1515
1913
|
const contextual = !!onValueChange && !collapsed;
|
|
1516
1914
|
const query = value ?? "";
|
|
1517
|
-
const inputRef =
|
|
1915
|
+
const inputRef = React16.useRef(null);
|
|
1518
1916
|
const escalate = () => setCommandPaletteOpen(true, query);
|
|
1519
1917
|
const surface = rail ? "bg-sidebar-accent/40 text-sidebar-muted hover:bg-sidebar-accent/70 hover:text-sidebar-foreground" : "bg-accent/40 text-muted-foreground hover:bg-accent/70 hover:text-foreground";
|
|
1520
1918
|
const ring = rail ? "focus-within:bg-sidebar-accent/70 focus-within:ring-1 focus-within:ring-sidebar-accent-foreground/25" : "focus-within:bg-accent/70 focus-within:ring-1 focus-within:ring-ring/40";
|
|
@@ -1625,7 +2023,7 @@ function TopbarUserMenu({
|
|
|
1625
2023
|
onBilling,
|
|
1626
2024
|
userMenuExtras
|
|
1627
2025
|
}) {
|
|
1628
|
-
const [open, setOpen] =
|
|
2026
|
+
const [open, setOpen] = React16.useState(false);
|
|
1629
2027
|
if (!user) return null;
|
|
1630
2028
|
const initial = (user.fullName?.trim()?.[0] ?? user.email?.[0] ?? "?").toUpperCase();
|
|
1631
2029
|
const item = (label, onClick, Icon) => onClick ? /* @__PURE__ */ jsxs(
|
|
@@ -1709,7 +2107,7 @@ function getIcon2(name) {
|
|
|
1709
2107
|
return ICON_MAP[name] ?? Home;
|
|
1710
2108
|
}
|
|
1711
2109
|
function NavDropdown({ item, currentPath, onNavigate }) {
|
|
1712
|
-
const [open, setOpen] =
|
|
2110
|
+
const [open, setOpen] = React16.useState(false);
|
|
1713
2111
|
const Icon = getIcon2(item.icon);
|
|
1714
2112
|
const isChildActive = item.children?.some(
|
|
1715
2113
|
(child) => currentPath === child.route || currentPath.startsWith(child.route + "/")
|
|
@@ -1877,9 +2275,9 @@ function Topbar({
|
|
|
1877
2275
|
] });
|
|
1878
2276
|
}
|
|
1879
2277
|
function useSheetDrag({ onDismiss, canDrag }) {
|
|
1880
|
-
const [offset, setOffset] =
|
|
1881
|
-
const [dragging, setDragging] =
|
|
1882
|
-
const start =
|
|
2278
|
+
const [offset, setOffset] = React16.useState(0);
|
|
2279
|
+
const [dragging, setDragging] = React16.useState(false);
|
|
2280
|
+
const start = React16.useRef(null);
|
|
1883
2281
|
const onPointerDown = (e) => {
|
|
1884
2282
|
if (e.pointerType === "mouse") return;
|
|
1885
2283
|
if (canDrag && !canDrag()) return;
|
|
@@ -1913,9 +2311,9 @@ function useSheetDrag({ onDismiss, canDrag }) {
|
|
|
1913
2311
|
handlers: { onPointerDown, onPointerMove, onPointerUp: end, onPointerCancel: end }
|
|
1914
2312
|
};
|
|
1915
2313
|
}
|
|
1916
|
-
var SheetCloseContext =
|
|
2314
|
+
var SheetCloseContext = React16.createContext(null);
|
|
1917
2315
|
function useSheetClose() {
|
|
1918
|
-
const close =
|
|
2316
|
+
const close = React16.useContext(SheetCloseContext);
|
|
1919
2317
|
return close ?? (() => {
|
|
1920
2318
|
});
|
|
1921
2319
|
}
|
|
@@ -1929,9 +2327,9 @@ function BottomSheet({
|
|
|
1929
2327
|
className,
|
|
1930
2328
|
label
|
|
1931
2329
|
}) {
|
|
1932
|
-
const [leaving, setLeaving] =
|
|
1933
|
-
const scroller =
|
|
1934
|
-
const close =
|
|
2330
|
+
const [leaving, setLeaving] = React16.useState(false);
|
|
2331
|
+
const scroller = React16.useRef(null);
|
|
2332
|
+
const close = React16.useCallback(() => {
|
|
1935
2333
|
setLeaving(true);
|
|
1936
2334
|
window.setTimeout(onClose, 200);
|
|
1937
2335
|
}, [onClose]);
|
|
@@ -1939,7 +2337,7 @@ function BottomSheet({
|
|
|
1939
2337
|
onDismiss: close,
|
|
1940
2338
|
canDrag: () => (scroller.current?.scrollTop ?? 0) <= 0
|
|
1941
2339
|
});
|
|
1942
|
-
|
|
2340
|
+
React16.useEffect(() => {
|
|
1943
2341
|
const onKey = (e) => {
|
|
1944
2342
|
if (e.key !== "Escape") return;
|
|
1945
2343
|
if (onBack) onBack();
|
|
@@ -1948,15 +2346,15 @@ function BottomSheet({
|
|
|
1948
2346
|
window.addEventListener("keydown", onKey);
|
|
1949
2347
|
return () => window.removeEventListener("keydown", onKey);
|
|
1950
2348
|
}, [close, onBack]);
|
|
1951
|
-
|
|
2349
|
+
React16.useEffect(() => {
|
|
1952
2350
|
const previous = document.body.style.overflow;
|
|
1953
2351
|
document.body.style.overflow = "hidden";
|
|
1954
2352
|
return () => {
|
|
1955
2353
|
document.body.style.overflow = previous;
|
|
1956
2354
|
};
|
|
1957
2355
|
}, []);
|
|
1958
|
-
const [host, setHost] =
|
|
1959
|
-
|
|
2356
|
+
const [host, setHost] = React16.useState(null);
|
|
2357
|
+
React16.useEffect(() => {
|
|
1960
2358
|
setHost(document.body);
|
|
1961
2359
|
}, []);
|
|
1962
2360
|
if (!host) return null;
|
|
@@ -2071,17 +2469,17 @@ function SheetRow({
|
|
|
2071
2469
|
}
|
|
2072
2470
|
);
|
|
2073
2471
|
}
|
|
2074
|
-
var ModuleHeaderSlotContext =
|
|
2472
|
+
var ModuleHeaderSlotContext = React16.createContext(null);
|
|
2075
2473
|
function useModuleHeaderSlot() {
|
|
2076
|
-
return
|
|
2474
|
+
return React16.useContext(ModuleHeaderSlotContext);
|
|
2077
2475
|
}
|
|
2078
|
-
var ModuleHeaderActionsSlotContext =
|
|
2476
|
+
var ModuleHeaderActionsSlotContext = React16.createContext(null);
|
|
2079
2477
|
function useModuleHeaderActionsSlot() {
|
|
2080
|
-
return
|
|
2478
|
+
return React16.useContext(ModuleHeaderActionsSlotContext);
|
|
2081
2479
|
}
|
|
2082
|
-
var PageRailSlotContext =
|
|
2480
|
+
var PageRailSlotContext = React16.createContext(null);
|
|
2083
2481
|
function usePageRailSlot() {
|
|
2084
|
-
return
|
|
2482
|
+
return React16.useContext(PageRailSlotContext);
|
|
2085
2483
|
}
|
|
2086
2484
|
function isCreateRoute(route) {
|
|
2087
2485
|
return !!route && /\/(new|create)$/.test(route);
|
|
@@ -2108,6 +2506,62 @@ function ShellPageTitle({
|
|
|
2108
2506
|
}
|
|
2109
2507
|
);
|
|
2110
2508
|
}
|
|
2509
|
+
function MobileQuickControls({ children }) {
|
|
2510
|
+
const [open, setOpen] = React16.useState(false);
|
|
2511
|
+
const [hasItems, setHasItems] = React16.useState(false);
|
|
2512
|
+
const rootRef = React16.useRef(null);
|
|
2513
|
+
const panelRef = React16.useRef(null);
|
|
2514
|
+
React16.useEffect(() => {
|
|
2515
|
+
const panel = panelRef.current;
|
|
2516
|
+
if (!panel) return;
|
|
2517
|
+
const read2 = () => setHasItems(!!panel.querySelector("button, a, input, select, [role]"));
|
|
2518
|
+
read2();
|
|
2519
|
+
const observer = new MutationObserver(read2);
|
|
2520
|
+
observer.observe(panel, { childList: true, subtree: true });
|
|
2521
|
+
return () => observer.disconnect();
|
|
2522
|
+
}, []);
|
|
2523
|
+
React16.useEffect(() => {
|
|
2524
|
+
if (!open) return;
|
|
2525
|
+
const onDown = (e) => {
|
|
2526
|
+
const target = e.target;
|
|
2527
|
+
if (!target || rootRef.current?.contains(target)) return;
|
|
2528
|
+
if (target.closest('[data-radix-popper-content-wrapper], [role="dialog"]')) return;
|
|
2529
|
+
setOpen(false);
|
|
2530
|
+
};
|
|
2531
|
+
document.addEventListener("pointerdown", onDown);
|
|
2532
|
+
return () => document.removeEventListener("pointerdown", onDown);
|
|
2533
|
+
}, [open]);
|
|
2534
|
+
return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: cn("relative", open && "z-[105]", !hasItems && "hidden"), children: [
|
|
2535
|
+
/* @__PURE__ */ jsx(MobileScrim, { open, onClose: () => setOpen(false) }),
|
|
2536
|
+
/* @__PURE__ */ jsx(
|
|
2537
|
+
"button",
|
|
2538
|
+
{
|
|
2539
|
+
type: "button",
|
|
2540
|
+
onClick: () => setOpen((v) => !v),
|
|
2541
|
+
"aria-label": "Ajustes r\xE1pidos",
|
|
2542
|
+
"aria-expanded": open,
|
|
2543
|
+
className: cn(
|
|
2544
|
+
"inline-flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent",
|
|
2545
|
+
open && "bg-accent text-foreground"
|
|
2546
|
+
),
|
|
2547
|
+
children: /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-5 w-5" })
|
|
2548
|
+
}
|
|
2549
|
+
),
|
|
2550
|
+
/* @__PURE__ */ jsx(
|
|
2551
|
+
"div",
|
|
2552
|
+
{
|
|
2553
|
+
ref: panelRef,
|
|
2554
|
+
className: cn(
|
|
2555
|
+
"absolute right-0 top-full z-30 mt-2 flex w-[min(20rem,calc(100vw-2rem))] flex-col items-stretch gap-1.5 rounded-2xl border border-border bg-popover p-3 text-[15px] text-popover-foreground shadow-lg fz-menu-glass [&>*]:min-h-11",
|
|
2556
|
+
// Rail-shaped controls are written in the rail's tokens; here they sit on paper.
|
|
2557
|
+
"[--sidebar-accent-foreground:var(--accent-foreground)] [--sidebar-accent:var(--accent)] [--sidebar-foreground:var(--foreground)] [--sidebar-muted:var(--muted-foreground)]",
|
|
2558
|
+
!open && "hidden"
|
|
2559
|
+
),
|
|
2560
|
+
children
|
|
2561
|
+
}
|
|
2562
|
+
)
|
|
2563
|
+
] });
|
|
2564
|
+
}
|
|
2111
2565
|
function SidebarLayout({
|
|
2112
2566
|
navigation = [],
|
|
2113
2567
|
navLoading = false,
|
|
@@ -2169,10 +2623,11 @@ function SidebarLayout({
|
|
|
2169
2623
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
2170
2624
|
const mobileMenuOpen = useLayoutStore((st) => st.mobileDrawerOpen);
|
|
2171
2625
|
const setMobileMenuOpen = useLayoutStore((st) => st.setMobileDrawerOpen);
|
|
2172
|
-
const [headerSlot, setHeaderSlot] =
|
|
2173
|
-
const [actionsSlot, setActionsSlot] =
|
|
2174
|
-
const [pageRailSlot, setPageRailSlot] =
|
|
2626
|
+
const [headerSlot, setHeaderSlot] = React16.useState(null);
|
|
2627
|
+
const [actionsSlot, setActionsSlot] = React16.useState(null);
|
|
2628
|
+
const [pageRailSlot, setPageRailSlot] = React16.useState(null);
|
|
2175
2629
|
const hasPageActions = useHasPageActions();
|
|
2630
|
+
const wide = useIsWide();
|
|
2176
2631
|
return /* @__PURE__ */ jsx(SaveBarProvider, { children: /* @__PURE__ */ jsx(ModuleHeaderSlotContext.Provider, { value: headerSlot, children: /* @__PURE__ */ jsx(ModuleHeaderActionsSlotContext.Provider, { value: actionsSlot, children: /* @__PURE__ */ jsx(PageRailSlotContext.Provider, { value: pageRailSlot, children: /* @__PURE__ */ jsxs("div", { className: cn(
|
|
2177
2632
|
"shell-enter fz-viewport-h flex overflow-hidden bg-background",
|
|
2178
2633
|
hasBottomNav && "fz-has-bottom-bar",
|
|
@@ -2227,7 +2682,7 @@ function SidebarLayout({
|
|
|
2227
2682
|
// 44px on a phone — the height every other bar in this product now
|
|
2228
2683
|
// uses (the "Mais" screen, a sheet's header) and the height a phone's
|
|
2229
2684
|
// own navigation bar has. Desktop keeps its 56px band.
|
|
2230
|
-
"min-h-[44px] md:min-h-14 border-b border-border",
|
|
2685
|
+
"min-h-[44px] md:min-h-14 md:border-b md:border-border",
|
|
2231
2686
|
// On a phone this band IS the navigation bar, so it is made of the
|
|
2232
2687
|
// same glass as the tab bar below it and the sheets between them —
|
|
2233
2688
|
// one material for the chrome, the page reading through all of it.
|
|
@@ -2279,11 +2734,12 @@ function SidebarLayout({
|
|
|
2279
2734
|
}
|
|
2280
2735
|
),
|
|
2281
2736
|
topbarStart,
|
|
2737
|
+
barOwnsNav && pagePrimary && pageTitle && /* @__PURE__ */ jsx("h1", { className: "absolute left-1/2 top-1/2 max-w-[50%] -translate-x-1/2 -translate-y-1/2 truncate text-[15px] font-semibold text-foreground md:hidden", children: pageTitle }),
|
|
2282
2738
|
/* @__PURE__ */ jsx("div", { ref: setHeaderSlot, className: "flex min-w-0 flex-1 items-center" })
|
|
2283
2739
|
] }),
|
|
2284
2740
|
/* @__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]" }) }),
|
|
2285
2741
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 shrink-0 items-center justify-end gap-2 md:flex-1", children: [
|
|
2286
|
-
topbarEnd,
|
|
2742
|
+
wide ? topbarEnd : /* @__PURE__ */ jsx(MobileQuickControls, { children: topbarEnd }),
|
|
2287
2743
|
notificationSlot
|
|
2288
2744
|
] })
|
|
2289
2745
|
] }),
|
|
@@ -2453,9 +2909,9 @@ function TopbarLayout({
|
|
|
2453
2909
|
const saveBarVisible = useSaveBarVisible();
|
|
2454
2910
|
const mobileMenuOpen = useLayoutStore((st) => st.mobileDrawerOpen);
|
|
2455
2911
|
const setMobileMenuOpen = useLayoutStore((st) => st.setMobileDrawerOpen);
|
|
2456
|
-
const [headerSlot, setHeaderSlot] =
|
|
2457
|
-
const [actionsSlot, setActionsSlot] =
|
|
2458
|
-
const [pageRailSlot, setPageRailSlot] =
|
|
2912
|
+
const [headerSlot, setHeaderSlot] = React16.useState(null);
|
|
2913
|
+
const [actionsSlot, setActionsSlot] = React16.useState(null);
|
|
2914
|
+
const [pageRailSlot, setPageRailSlot] = React16.useState(null);
|
|
2459
2915
|
const rawClaimed = usePageHeaderClaimed();
|
|
2460
2916
|
const setTitleSlot = usePageTitleSlotHost();
|
|
2461
2917
|
const hasOutlet = useHasPageHeaderOutlet();
|
|
@@ -2594,10 +3050,10 @@ function MobileMoreScreen({
|
|
|
2594
3050
|
onDismiss,
|
|
2595
3051
|
onClose
|
|
2596
3052
|
}) {
|
|
2597
|
-
const [pushed, setPushed] =
|
|
2598
|
-
const [query, setQuery] =
|
|
2599
|
-
const scroller =
|
|
2600
|
-
const close =
|
|
3053
|
+
const [pushed, setPushed] = React16.useState(null);
|
|
3054
|
+
const [query, setQuery] = React16.useState("");
|
|
3055
|
+
const scroller = React16.useRef(null);
|
|
3056
|
+
const close = React16.useCallback(() => {
|
|
2601
3057
|
onClose();
|
|
2602
3058
|
}, [onClose]);
|
|
2603
3059
|
const drag = useSheetDrag({
|
|
@@ -2606,7 +3062,7 @@ function MobileMoreScreen({
|
|
|
2606
3062
|
// a pushed section would dismiss the screen the back button is for.
|
|
2607
3063
|
canDrag: () => !pushed && (scroller.current?.scrollTop ?? 0) <= 0
|
|
2608
3064
|
});
|
|
2609
|
-
|
|
3065
|
+
React16.useEffect(() => {
|
|
2610
3066
|
const onKey = (e) => {
|
|
2611
3067
|
if (e.key !== "Escape") return;
|
|
2612
3068
|
if (pushed) setPushed(null);
|
|
@@ -2615,7 +3071,7 @@ function MobileMoreScreen({
|
|
|
2615
3071
|
window.addEventListener("keydown", onKey);
|
|
2616
3072
|
return () => window.removeEventListener("keydown", onKey);
|
|
2617
3073
|
}, [close, pushed]);
|
|
2618
|
-
|
|
3074
|
+
React16.useEffect(() => {
|
|
2619
3075
|
const previous = document.body.style.overflow;
|
|
2620
3076
|
document.body.style.overflow = "hidden";
|
|
2621
3077
|
return () => {
|
|
@@ -2635,13 +3091,13 @@ function MobileMoreScreen({
|
|
|
2635
3091
|
else onNavigate?.(route);
|
|
2636
3092
|
};
|
|
2637
3093
|
const q = query.trim().toLowerCase();
|
|
2638
|
-
const flat =
|
|
3094
|
+
const flat = React16.useMemo(
|
|
2639
3095
|
() => navigation.flatMap((n) => n.children?.length ? n.children : [n]),
|
|
2640
3096
|
[navigation]
|
|
2641
3097
|
);
|
|
2642
3098
|
const searching = q.length > 0;
|
|
2643
3099
|
const hits = searching ? flat.filter((n) => n.label.toLowerCase().includes(q)) : [];
|
|
2644
|
-
const sections =
|
|
3100
|
+
const sections = React16.useMemo(() => {
|
|
2645
3101
|
const out = [];
|
|
2646
3102
|
for (const key of ["main", "secondary", "settings"]) {
|
|
2647
3103
|
const items = navigation.filter((n) => n.section === key);
|
|
@@ -2910,23 +3366,23 @@ function MinimalLayout({
|
|
|
2910
3366
|
] });
|
|
2911
3367
|
}
|
|
2912
3368
|
function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
|
|
2913
|
-
const [visible, setVisible] =
|
|
2914
|
-
|
|
3369
|
+
const [visible, setVisible] = React16.useState(false);
|
|
3370
|
+
React16.useEffect(() => {
|
|
2915
3371
|
const id = requestAnimationFrame(() => setVisible(true));
|
|
2916
3372
|
return () => cancelAnimationFrame(id);
|
|
2917
3373
|
}, []);
|
|
2918
|
-
const close =
|
|
3374
|
+
const close = React16.useCallback(() => {
|
|
2919
3375
|
setVisible(false);
|
|
2920
3376
|
window.setTimeout(onClose, 250);
|
|
2921
3377
|
}, [onClose]);
|
|
2922
|
-
|
|
3378
|
+
React16.useEffect(() => {
|
|
2923
3379
|
const previous = document.body.style.overflow;
|
|
2924
3380
|
document.body.style.overflow = "hidden";
|
|
2925
3381
|
return () => {
|
|
2926
3382
|
document.body.style.overflow = previous;
|
|
2927
3383
|
};
|
|
2928
3384
|
}, []);
|
|
2929
|
-
|
|
3385
|
+
React16.useEffect(() => {
|
|
2930
3386
|
const onKey = (e) => {
|
|
2931
3387
|
if (e.key === "Escape") close();
|
|
2932
3388
|
};
|
|
@@ -3026,14 +3482,16 @@ function MobileBottomNav({
|
|
|
3026
3482
|
onAssistant,
|
|
3027
3483
|
assistantOpen,
|
|
3028
3484
|
moreOpen,
|
|
3029
|
-
retracted
|
|
3485
|
+
retracted,
|
|
3486
|
+
frame,
|
|
3487
|
+
assistantFace
|
|
3030
3488
|
}) {
|
|
3031
3489
|
const path = currentPath ?? "";
|
|
3032
|
-
const [openSheet, setOpenSheet] =
|
|
3033
|
-
|
|
3490
|
+
const [openSheet, setOpenSheet] = React16.useState(null);
|
|
3491
|
+
React16.useEffect(() => {
|
|
3034
3492
|
setOpenSheet(null);
|
|
3035
3493
|
}, [currentPath]);
|
|
3036
|
-
|
|
3494
|
+
React16.useEffect(() => {
|
|
3037
3495
|
if (retracted) setOpenSheet(null);
|
|
3038
3496
|
}, [retracted]);
|
|
3039
3497
|
const sheetItem = openSheet != null ? items[openSheet] : void 0;
|
|
@@ -3045,9 +3503,13 @@ function MobileBottomNav({
|
|
|
3045
3503
|
"aria-hidden": retracted || void 0,
|
|
3046
3504
|
className: cn(
|
|
3047
3505
|
"fz-safe-b fixed inset-x-0 bottom-0 z-50 flex min-h-16 items-stretch justify-around md:hidden",
|
|
3048
|
-
"
|
|
3506
|
+
"fz-glass-tabbar text-sidebar-foreground",
|
|
3049
3507
|
"motion-safe:transition-transform motion-safe:duration-200 motion-safe:ease-out",
|
|
3050
|
-
|
|
3508
|
+
// The framed shell rounds its content card; the bar is the phone's
|
|
3509
|
+
// piece of that same frame.
|
|
3510
|
+
frame && "rounded-t-[28px]",
|
|
3511
|
+
// Past its own height: the assistant button stands above the bar's edge.
|
|
3512
|
+
retracted && "pointer-events-none translate-y-[calc(100%+2.5rem)]"
|
|
3051
3513
|
),
|
|
3052
3514
|
children: items.map((item, i) => {
|
|
3053
3515
|
if ("kind" in item && item.kind === "action") {
|
|
@@ -3063,18 +3525,36 @@ function MobileBottomNav({
|
|
|
3063
3525
|
}
|
|
3064
3526
|
) }, item.id);
|
|
3065
3527
|
}
|
|
3528
|
+
if ("kind" in item && item.kind === "assistant") {
|
|
3529
|
+
const AssistantIcon = bottomNavIcon(item.icon, Sparkles);
|
|
3530
|
+
const label2 = item.label ?? "IA";
|
|
3531
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-start justify-center", children: /* @__PURE__ */ jsx(
|
|
3532
|
+
"button",
|
|
3533
|
+
{
|
|
3534
|
+
type: "button",
|
|
3535
|
+
onClick: () => {
|
|
3536
|
+
setOpenSheet(null);
|
|
3537
|
+
onAssistant?.();
|
|
3538
|
+
},
|
|
3539
|
+
"aria-label": label2,
|
|
3540
|
+
"aria-expanded": !!assistantOpen,
|
|
3541
|
+
className: cn(
|
|
3542
|
+
"-mt-3 flex h-[60px] w-[60px] items-center justify-center rounded-full shadow-lg ring-[5px] ring-sidebar transition-transform active:scale-95",
|
|
3543
|
+
assistantFace ? "bg-card" : "bg-primary text-primary-foreground",
|
|
3544
|
+
assistantOpen && "ring-sidebar-accent-foreground"
|
|
3545
|
+
),
|
|
3546
|
+
children: assistantFace ?? /* @__PURE__ */ jsx(AssistantIcon, { className: "h-6 w-6" })
|
|
3547
|
+
}
|
|
3548
|
+
) }, "assistant");
|
|
3549
|
+
}
|
|
3066
3550
|
const isMore = "kind" in item && item.kind === "more";
|
|
3067
|
-
const
|
|
3068
|
-
const
|
|
3069
|
-
const
|
|
3070
|
-
|
|
3071
|
-
isMore ? Menu : isAssistant ? Sparkles : Home
|
|
3072
|
-
);
|
|
3073
|
-
const route = isMore || isAssistant ? void 0 : item.route;
|
|
3074
|
-
const children = isMore || isAssistant ? void 0 : item.children?.filter((c) => !isCreateRoute(c.route));
|
|
3551
|
+
const label = isMore ? item.label ?? "Mais" : item.label;
|
|
3552
|
+
const Icon = bottomNavIcon(item.icon, isMore ? Menu : Home);
|
|
3553
|
+
const route = isMore ? void 0 : item.route;
|
|
3554
|
+
const children = isMore ? void 0 : item.children?.filter((c) => !isCreateRoute(c.route));
|
|
3075
3555
|
const hasChoices = !!children && children.length > 1;
|
|
3076
3556
|
const sheetOpen = openSheet === i;
|
|
3077
|
-
const isActive = isMore ? !!moreOpen :
|
|
3557
|
+
const isActive = isMore ? !!moreOpen : sheetOpen ? true : route === "/" ? path === "/" || path === "" : !!route && (path === route || path.startsWith(route + "/"));
|
|
3078
3558
|
return /* @__PURE__ */ jsxs(
|
|
3079
3559
|
"button",
|
|
3080
3560
|
{
|
|
@@ -3084,15 +3564,11 @@ function MobileBottomNav({
|
|
|
3084
3564
|
setOpenSheet(null);
|
|
3085
3565
|
return onMore?.();
|
|
3086
3566
|
}
|
|
3087
|
-
if (isAssistant) {
|
|
3088
|
-
setOpenSheet(null);
|
|
3089
|
-
return onAssistant?.();
|
|
3090
|
-
}
|
|
3091
3567
|
if (hasChoices) return setOpenSheet(sheetOpen ? null : i);
|
|
3092
3568
|
onNavigate?.(children?.[0]?.route ?? route);
|
|
3093
3569
|
},
|
|
3094
3570
|
"aria-current": isActive && route && !hasChoices ? "page" : void 0,
|
|
3095
|
-
"aria-expanded": isMore
|
|
3571
|
+
"aria-expanded": isMore ? isActive : hasChoices ? sheetOpen : void 0,
|
|
3096
3572
|
"aria-haspopup": hasChoices ? "menu" : void 0,
|
|
3097
3573
|
className: cn(
|
|
3098
3574
|
// min-h-[44px] is the floor a finger needs; the bar was letting
|
|
@@ -3101,16 +3577,6 @@ function MobileBottomNav({
|
|
|
3101
3577
|
isActive ? "text-sidebar-accent-foreground" : "text-sidebar-muted"
|
|
3102
3578
|
),
|
|
3103
3579
|
children: [
|
|
3104
|
-
/* @__PURE__ */ jsx(
|
|
3105
|
-
"span",
|
|
3106
|
-
{
|
|
3107
|
-
"aria-hidden": true,
|
|
3108
|
-
className: cn(
|
|
3109
|
-
"absolute inset-x-3 top-0 h-0.5 rounded-full transition-opacity",
|
|
3110
|
-
isActive ? "bg-sidebar-accent-foreground opacity-100" : "opacity-0"
|
|
3111
|
-
)
|
|
3112
|
-
}
|
|
3113
|
-
),
|
|
3114
3580
|
/* @__PURE__ */ jsxs("span", { className: "relative flex items-center", children: [
|
|
3115
3581
|
/* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 shrink-0" }),
|
|
3116
3582
|
hasChoices && /* @__PURE__ */ jsx(
|
|
@@ -3124,10 +3590,10 @@ function MobileBottomNav({
|
|
|
3124
3590
|
}
|
|
3125
3591
|
)
|
|
3126
3592
|
] }),
|
|
3127
|
-
/* @__PURE__ */ jsx("span", { className: "max-w-full truncate text-[11px] leading-tight", children: label })
|
|
3593
|
+
/* @__PURE__ */ jsx("span", { className: cn("max-w-full truncate text-[11px] leading-tight", isActive && "font-semibold"), children: label })
|
|
3128
3594
|
]
|
|
3129
3595
|
},
|
|
3130
|
-
isMore ? "more" :
|
|
3596
|
+
isMore ? "more" : `${route}-${i}`
|
|
3131
3597
|
);
|
|
3132
3598
|
})
|
|
3133
3599
|
}
|
|
@@ -3183,6 +3649,7 @@ function AppShell({
|
|
|
3183
3649
|
onBottomNavAction,
|
|
3184
3650
|
onAssistantToggle,
|
|
3185
3651
|
assistantOpen,
|
|
3652
|
+
assistantFace,
|
|
3186
3653
|
mobileHeader = "minimal",
|
|
3187
3654
|
immersive = false,
|
|
3188
3655
|
userMenuSlot,
|
|
@@ -3205,7 +3672,7 @@ function AppShell({
|
|
|
3205
3672
|
const hasBottomNav = !!bottomNav?.length;
|
|
3206
3673
|
const barOwnsNav = bottomNavReachesAll(bottomNav);
|
|
3207
3674
|
const menuNavigation = appNavigation ?? navigation;
|
|
3208
|
-
const routeLabel =
|
|
3675
|
+
const routeLabel = React16.useCallback((path) => {
|
|
3209
3676
|
let best;
|
|
3210
3677
|
const consider = (route, label) => {
|
|
3211
3678
|
if (!route || !label) return;
|
|
@@ -3220,14 +3687,14 @@ function AppShell({
|
|
|
3220
3687
|
}
|
|
3221
3688
|
return best?.label ?? pageTitle ?? "";
|
|
3222
3689
|
}, [menuNavigation, pageTitle]);
|
|
3223
|
-
|
|
3690
|
+
React16.useEffect(() => {
|
|
3224
3691
|
if (!currentPath) return;
|
|
3225
3692
|
if (currentPath === MENU_ROUTE) return;
|
|
3226
3693
|
const label = routeLabel(currentPath);
|
|
3227
3694
|
if (!label) return;
|
|
3228
3695
|
recordNavigation(currentPath, label);
|
|
3229
3696
|
}, [currentPath, routeLabel]);
|
|
3230
|
-
const destinationRoutes =
|
|
3697
|
+
const destinationRoutes = React16.useMemo(() => {
|
|
3231
3698
|
const routes = [];
|
|
3232
3699
|
for (const item of menuNavigation) {
|
|
3233
3700
|
if (item.route) routes.push(item.route);
|
|
@@ -3236,7 +3703,7 @@ function AppShell({
|
|
|
3236
3703
|
return routes;
|
|
3237
3704
|
}, [menuNavigation]);
|
|
3238
3705
|
const isDestination = !!currentPath && destinationRoutes.includes(currentPath);
|
|
3239
|
-
|
|
3706
|
+
React16.useEffect(() => {
|
|
3240
3707
|
setDestinationRoutes(destinationRoutes);
|
|
3241
3708
|
}, [destinationRoutes]);
|
|
3242
3709
|
const pageClaimedBack = useHasPageHeaderBack();
|
|
@@ -3244,7 +3711,7 @@ function AppShell({
|
|
|
3244
3711
|
const barRetracted = !!pageBack || pageClaimedBack || inSettings;
|
|
3245
3712
|
const mobileDrawerOpen = useLayoutStore((st) => st.mobileDrawerOpen);
|
|
3246
3713
|
const setMobileDrawerOpen = useLayoutStore((st) => st.setMobileDrawerOpen);
|
|
3247
|
-
|
|
3714
|
+
React16.useEffect(() => {
|
|
3248
3715
|
if (useLayoutStore.getState().drawerKeepOpenOnce) {
|
|
3249
3716
|
useLayoutStore.setState({ drawerKeepOpenOnce: false });
|
|
3250
3717
|
return;
|
|
@@ -3252,12 +3719,12 @@ function AppShell({
|
|
|
3252
3719
|
setMobileDrawerOpen(false);
|
|
3253
3720
|
}, [currentPath]);
|
|
3254
3721
|
const menuRouteOpen = barOwnsNav && currentPath === MENU_ROUTE;
|
|
3255
|
-
const firstDestination =
|
|
3722
|
+
const firstDestination = React16.useMemo(() => {
|
|
3256
3723
|
const first = bottomNav?.find((i) => !("kind" in i) || i.kind === "route");
|
|
3257
3724
|
return first?.route ?? "/";
|
|
3258
3725
|
}, [bottomNav]);
|
|
3259
|
-
const menuOrigin =
|
|
3260
|
-
const openMenu =
|
|
3726
|
+
const menuOrigin = React16.useRef(void 0);
|
|
3727
|
+
const openMenu = React16.useCallback(() => {
|
|
3261
3728
|
if (!barOwnsNav) {
|
|
3262
3729
|
setMobileDrawerOpen(true);
|
|
3263
3730
|
return;
|
|
@@ -3268,10 +3735,10 @@ function AppShell({
|
|
|
3268
3735
|
menuOrigin.current = currentPath;
|
|
3269
3736
|
onNavigate?.(MENU_ROUTE);
|
|
3270
3737
|
}, [barOwnsNav, currentPath, onNavigate, setMobileDrawerOpen]);
|
|
3271
|
-
const [menuLeaving, setMenuLeaving] =
|
|
3272
|
-
const [menuLingering, setMenuLingering] =
|
|
3273
|
-
const menuTimer =
|
|
3274
|
-
const dismissMenu =
|
|
3738
|
+
const [menuLeaving, setMenuLeaving] = React16.useState(false);
|
|
3739
|
+
const [menuLingering, setMenuLingering] = React16.useState(false);
|
|
3740
|
+
const menuTimer = React16.useRef(void 0);
|
|
3741
|
+
const dismissMenu = React16.useCallback((navigate) => {
|
|
3275
3742
|
window.clearTimeout(menuTimer.current);
|
|
3276
3743
|
setMenuLingering(true);
|
|
3277
3744
|
setMenuLeaving(true);
|
|
@@ -3281,8 +3748,8 @@ function AppShell({
|
|
|
3281
3748
|
setMenuLingering(false);
|
|
3282
3749
|
}, 240);
|
|
3283
3750
|
}, []);
|
|
3284
|
-
|
|
3285
|
-
const closeMenu =
|
|
3751
|
+
React16.useEffect(() => () => window.clearTimeout(menuTimer.current), []);
|
|
3752
|
+
const closeMenu = React16.useCallback(() => {
|
|
3286
3753
|
if (!barOwnsNav) {
|
|
3287
3754
|
setMobileDrawerOpen(false);
|
|
3288
3755
|
return;
|
|
@@ -3295,7 +3762,7 @@ function AppShell({
|
|
|
3295
3762
|
onNavigate?.(back);
|
|
3296
3763
|
});
|
|
3297
3764
|
}, [barOwnsNav, setMobileDrawerOpen, onNavigate, firstDestination, dismissMenu]);
|
|
3298
|
-
|
|
3765
|
+
React16.useEffect(() => {
|
|
3299
3766
|
if (!menuRouteOpen || typeof window === "undefined") return;
|
|
3300
3767
|
const wide = window.matchMedia("(min-width: 768px)");
|
|
3301
3768
|
const settle = () => {
|
|
@@ -3317,6 +3784,8 @@ function AppShell({
|
|
|
3317
3784
|
moreOpen: barOwnsNav ? menuRouteOpen : mobileDrawerOpen,
|
|
3318
3785
|
onAssistant: onAssistantToggle,
|
|
3319
3786
|
assistantOpen,
|
|
3787
|
+
assistantFace,
|
|
3788
|
+
frame: contentFrame,
|
|
3320
3789
|
retracted: barRetracted
|
|
3321
3790
|
}
|
|
3322
3791
|
) : null;
|
|
@@ -3456,13 +3925,13 @@ function SplitWithRightRail({
|
|
|
3456
3925
|
maxWidth = 720,
|
|
3457
3926
|
resizeLabel = "Resize panel"
|
|
3458
3927
|
}) {
|
|
3459
|
-
const [width, setWidth] =
|
|
3460
|
-
const [dragging, setDragging] =
|
|
3461
|
-
const clamp =
|
|
3928
|
+
const [width, setWidth] = React16.useState(defaultWidth);
|
|
3929
|
+
const [dragging, setDragging] = React16.useState(false);
|
|
3930
|
+
const clamp = React16.useCallback(
|
|
3462
3931
|
(value) => Math.min(maxWidth, Math.max(minWidth, value)),
|
|
3463
3932
|
[minWidth, maxWidth]
|
|
3464
3933
|
);
|
|
3465
|
-
|
|
3934
|
+
React16.useEffect(() => {
|
|
3466
3935
|
if (!dragging) return;
|
|
3467
3936
|
const onMove = (event) => {
|
|
3468
3937
|
event.preventDefault();
|
|
@@ -3484,7 +3953,7 @@ function SplitWithRightRail({
|
|
|
3484
3953
|
document.body.style.cursor = previousCursor;
|
|
3485
3954
|
};
|
|
3486
3955
|
}, [dragging, clamp]);
|
|
3487
|
-
|
|
3956
|
+
React16.useEffect(() => {
|
|
3488
3957
|
if (dragging) return;
|
|
3489
3958
|
onWidthChange?.(width);
|
|
3490
3959
|
}, [dragging]);
|
|
@@ -3699,12 +4168,12 @@ function ViewTabs({ value, onChange, options, "aria-label": ariaLabel, className
|
|
|
3699
4168
|
);
|
|
3700
4169
|
}) });
|
|
3701
4170
|
}
|
|
3702
|
-
var NavTransitionContext =
|
|
4171
|
+
var NavTransitionContext = React16.createContext("slide");
|
|
3703
4172
|
function NavTransitionProvider({ value, children }) {
|
|
3704
4173
|
return /* @__PURE__ */ jsx(NavTransitionContext.Provider, { value, children });
|
|
3705
4174
|
}
|
|
3706
4175
|
function useNavTransition() {
|
|
3707
|
-
return
|
|
4176
|
+
return React16.useContext(NavTransitionContext);
|
|
3708
4177
|
}
|
|
3709
4178
|
function resolveTransitionClass(transition, direction) {
|
|
3710
4179
|
if (transition === "none") return "";
|
|
@@ -3724,26 +4193,26 @@ function PageTransition({
|
|
|
3724
4193
|
return /* @__PURE__ */ jsx("div", { className: cn(animClass, className), children }, transitionKey);
|
|
3725
4194
|
}
|
|
3726
4195
|
var EMPTY = [];
|
|
3727
|
-
var PageTrailContext =
|
|
4196
|
+
var PageTrailContext = React16.createContext(EMPTY);
|
|
3728
4197
|
function PageTrail({
|
|
3729
4198
|
label,
|
|
3730
4199
|
href,
|
|
3731
4200
|
onNavigate,
|
|
3732
4201
|
children
|
|
3733
4202
|
}) {
|
|
3734
|
-
const parent =
|
|
3735
|
-
const trail =
|
|
4203
|
+
const parent = React16.useContext(PageTrailContext);
|
|
4204
|
+
const trail = React16.useMemo(
|
|
3736
4205
|
() => [...parent, { label, href, onNavigate }],
|
|
3737
4206
|
[parent, label, href, onNavigate]
|
|
3738
4207
|
);
|
|
3739
4208
|
return /* @__PURE__ */ jsx(PageTrailContext.Provider, { value: trail, children });
|
|
3740
4209
|
}
|
|
3741
4210
|
function usePageTrail() {
|
|
3742
|
-
return
|
|
4211
|
+
return React16.useContext(PageTrailContext);
|
|
3743
4212
|
}
|
|
3744
4213
|
function usePageTrailParent(href) {
|
|
3745
|
-
const trail =
|
|
3746
|
-
return
|
|
4214
|
+
const trail = React16.useContext(PageTrailContext);
|
|
4215
|
+
return React16.useMemo(() => {
|
|
3747
4216
|
const above = href ? trail.filter((c) => c.href !== href) : trail;
|
|
3748
4217
|
return above[above.length - 1];
|
|
3749
4218
|
}, [trail, href]);
|
|
@@ -3759,8 +4228,8 @@ function useCurrentRouteHref() {
|
|
|
3759
4228
|
const clean = hash.split("?")[0];
|
|
3760
4229
|
return clean.startsWith("/") ? clean : `/${clean}`;
|
|
3761
4230
|
};
|
|
3762
|
-
const [href, setHref] =
|
|
3763
|
-
|
|
4231
|
+
const [href, setHref] = React16.useState(read2);
|
|
4232
|
+
React16.useEffect(() => {
|
|
3764
4233
|
const handler = () => setHref(read2());
|
|
3765
4234
|
window.addEventListener("hashchange", handler);
|
|
3766
4235
|
handler();
|
|
@@ -3771,7 +4240,7 @@ function useCurrentRouteHref() {
|
|
|
3771
4240
|
function useTrailBack(href) {
|
|
3772
4241
|
const current = useCurrentRouteHref();
|
|
3773
4242
|
const parent = usePageTrailParent(href ?? current);
|
|
3774
|
-
return
|
|
4243
|
+
return React16.useMemo(
|
|
3775
4244
|
() => parent ? { onBack: () => navigateToCrumb(parent), parentLabel: parent.label } : {},
|
|
3776
4245
|
[parent]
|
|
3777
4246
|
);
|
|
@@ -3798,23 +4267,23 @@ function CollapsibleColumn({
|
|
|
3798
4267
|
"aria-label": ariaLabel
|
|
3799
4268
|
}) {
|
|
3800
4269
|
const pinnedKey = `${storageKey}.pinned`;
|
|
3801
|
-
const [collapsed, setCollapsed] =
|
|
3802
|
-
const [pinned, setPinned] =
|
|
3803
|
-
const [hovering, setHovering] =
|
|
3804
|
-
const hoveringRef =
|
|
3805
|
-
const collapsedRef =
|
|
4270
|
+
const [collapsed, setCollapsed] = React16.useState(() => read(storageKey));
|
|
4271
|
+
const [pinned, setPinned] = React16.useState(() => read(pinnedKey));
|
|
4272
|
+
const [hovering, setHovering] = React16.useState(false);
|
|
4273
|
+
const hoveringRef = React16.useRef(false);
|
|
4274
|
+
const collapsedRef = React16.useRef(collapsed);
|
|
3806
4275
|
collapsedRef.current = collapsed;
|
|
3807
|
-
const autoRef =
|
|
4276
|
+
const autoRef = React16.useRef(false);
|
|
3808
4277
|
const open = !collapsed || hovering;
|
|
3809
4278
|
const width = open ? COLUMN_WIDTH : COLUMN_COLLAPSED_WIDTH;
|
|
3810
4279
|
const setHover = (on) => {
|
|
3811
4280
|
hoveringRef.current = on;
|
|
3812
4281
|
setHovering(on);
|
|
3813
4282
|
};
|
|
3814
|
-
|
|
4283
|
+
React16.useEffect(() => {
|
|
3815
4284
|
onWidth?.(width);
|
|
3816
4285
|
}, [width, onWidth]);
|
|
3817
|
-
const setOpenState =
|
|
4286
|
+
const setOpenState = React16.useCallback((nextCollapsed) => {
|
|
3818
4287
|
setCollapsed(nextCollapsed);
|
|
3819
4288
|
setPinned(!nextCollapsed);
|
|
3820
4289
|
autoRef.current = false;
|
|
@@ -3825,7 +4294,7 @@ function CollapsibleColumn({
|
|
|
3825
4294
|
}
|
|
3826
4295
|
if (nextCollapsed) setHover(false);
|
|
3827
4296
|
}, [storageKey, pinnedKey]);
|
|
3828
|
-
|
|
4297
|
+
React16.useEffect(() => {
|
|
3829
4298
|
if (squeezed === void 0) return;
|
|
3830
4299
|
if (squeezed) {
|
|
3831
4300
|
if (!collapsedRef.current) {
|
|
@@ -3837,8 +4306,8 @@ function CollapsibleColumn({
|
|
|
3837
4306
|
setCollapsed(false);
|
|
3838
4307
|
}
|
|
3839
4308
|
}, [squeezed]);
|
|
3840
|
-
const seen =
|
|
3841
|
-
|
|
4309
|
+
const seen = React16.useRef(null);
|
|
4310
|
+
React16.useEffect(() => {
|
|
3842
4311
|
if (autoCollapseKey === void 0) return;
|
|
3843
4312
|
if (seen.current === null) {
|
|
3844
4313
|
seen.current = autoCollapseKey;
|
|
@@ -3852,14 +4321,14 @@ function CollapsibleColumn({
|
|
|
3852
4321
|
}, autoCollapseMs);
|
|
3853
4322
|
return () => clearTimeout(t);
|
|
3854
4323
|
}, [autoCollapseKey, collapsed, pinned, autoCollapseMs]);
|
|
3855
|
-
const scrollRef =
|
|
3856
|
-
const [hasMore, setHasMore] =
|
|
3857
|
-
const onScroll =
|
|
4324
|
+
const scrollRef = React16.useRef(null);
|
|
4325
|
+
const [hasMore, setHasMore] = React16.useState(false);
|
|
4326
|
+
const onScroll = React16.useCallback(() => {
|
|
3858
4327
|
const el = scrollRef.current;
|
|
3859
4328
|
if (!el) return;
|
|
3860
4329
|
setHasMore(el.scrollHeight - el.scrollTop - el.clientHeight > 4);
|
|
3861
4330
|
}, []);
|
|
3862
|
-
|
|
4331
|
+
React16.useEffect(() => {
|
|
3863
4332
|
onScroll();
|
|
3864
4333
|
const el = scrollRef.current;
|
|
3865
4334
|
if (!el) return;
|
|
@@ -3869,11 +4338,11 @@ function CollapsibleColumn({
|
|
|
3869
4338
|
ro.disconnect();
|
|
3870
4339
|
};
|
|
3871
4340
|
}, [onScroll, open, children]);
|
|
3872
|
-
const boxRef =
|
|
3873
|
-
const panelRef =
|
|
3874
|
-
const [seamed, setSeamed] =
|
|
3875
|
-
const armedRef =
|
|
3876
|
-
const publish =
|
|
4341
|
+
const boxRef = React16.useRef(null);
|
|
4342
|
+
const panelRef = React16.useRef(null);
|
|
4343
|
+
const [seamed, setSeamed] = React16.useState(false);
|
|
4344
|
+
const armedRef = React16.useRef(false);
|
|
4345
|
+
const publish = React16.useCallback(() => {
|
|
3877
4346
|
if (!seamTop) return;
|
|
3878
4347
|
const el = panelRef.current;
|
|
3879
4348
|
const card = el?.closest(".fz-page-surface");
|
|
@@ -3896,10 +4365,10 @@ function CollapsibleColumn({
|
|
|
3896
4365
|
});
|
|
3897
4366
|
}
|
|
3898
4367
|
}, [seamTop]);
|
|
3899
|
-
|
|
4368
|
+
React16.useEffect(() => {
|
|
3900
4369
|
publish();
|
|
3901
4370
|
}, [publish, width]);
|
|
3902
|
-
|
|
4371
|
+
React16.useEffect(() => {
|
|
3903
4372
|
if (!seamTop) return;
|
|
3904
4373
|
const el = panelRef.current;
|
|
3905
4374
|
const card = el?.closest(".fz-page-surface");
|
|
@@ -4029,7 +4498,7 @@ function viewBarSubscribe(l) {
|
|
|
4029
4498
|
};
|
|
4030
4499
|
}
|
|
4031
4500
|
function ViewBarHost() {
|
|
4032
|
-
const active =
|
|
4501
|
+
const active = React16.useSyncExternalStore(viewBarSubscribe, () => viewBarCount > 0);
|
|
4033
4502
|
return /* @__PURE__ */ jsx(
|
|
4034
4503
|
"div",
|
|
4035
4504
|
{
|
|
@@ -4042,8 +4511,8 @@ function ViewBarHost() {
|
|
|
4042
4511
|
);
|
|
4043
4512
|
}
|
|
4044
4513
|
function PageViewBar({ children }) {
|
|
4045
|
-
const slot =
|
|
4046
|
-
|
|
4514
|
+
const slot = React16.useSyncExternalStore(viewBarSubscribe, () => viewBarSlot);
|
|
4515
|
+
React16.useEffect(() => {
|
|
4047
4516
|
viewBarCount++;
|
|
4048
4517
|
viewBarNotify();
|
|
4049
4518
|
return () => {
|
|
@@ -4080,9 +4549,9 @@ function RailSections({ sections, search, collapsed }) {
|
|
|
4080
4549
|
}
|
|
4081
4550
|
var RAIL_COLLAPSED_KEY = "fayz.subnav.collapsed";
|
|
4082
4551
|
function RailColumn({ className, "aria-label": ariaLabel, sections, search, footer }) {
|
|
4083
|
-
const boxRef =
|
|
4084
|
-
const [squeezed, setSqueezed] =
|
|
4085
|
-
|
|
4552
|
+
const boxRef = React16.useRef(null);
|
|
4553
|
+
const [squeezed, setSqueezed] = React16.useState(void 0);
|
|
4554
|
+
React16.useEffect(() => {
|
|
4086
4555
|
if (typeof window === "undefined") return;
|
|
4087
4556
|
const row = boxRef.current?.parentElement?.parentElement;
|
|
4088
4557
|
if (!row) return;
|
|
@@ -4142,10 +4611,10 @@ function unpublishSubNav(id) {
|
|
|
4142
4611
|
subNavNotify();
|
|
4143
4612
|
}
|
|
4144
4613
|
function useSubNavPublished() {
|
|
4145
|
-
return
|
|
4614
|
+
return React16.useSyncExternalStore(subNavSubscribe, () => published, () => published);
|
|
4146
4615
|
}
|
|
4147
4616
|
function useSubNavHost() {
|
|
4148
|
-
|
|
4617
|
+
React16.useEffect(() => {
|
|
4149
4618
|
subNavHosts++;
|
|
4150
4619
|
subNavNotify();
|
|
4151
4620
|
return () => {
|
|
@@ -4155,7 +4624,7 @@ function useSubNavHost() {
|
|
|
4155
4624
|
}, []);
|
|
4156
4625
|
}
|
|
4157
4626
|
function useHasSubNavHost() {
|
|
4158
|
-
return
|
|
4627
|
+
return React16.useSyncExternalStore(subNavSubscribe, () => subNavHosts > 0, () => false);
|
|
4159
4628
|
}
|
|
4160
4629
|
function SubNavBand({ sections, "aria-label": ariaLabel, className }) {
|
|
4161
4630
|
const items = sections.flatMap((s) => s.items);
|
|
@@ -4187,13 +4656,13 @@ function SubNavBandHost({ leading, label }) {
|
|
|
4187
4656
|
);
|
|
4188
4657
|
}
|
|
4189
4658
|
function PageSubNav({ items, sections, search, footer, style, "aria-label": ariaLabel }) {
|
|
4190
|
-
const id =
|
|
4659
|
+
const id = React16.useId();
|
|
4191
4660
|
const hasHost = useHasSubNavHost();
|
|
4192
4661
|
const resolved = sections ?? (items ? [{ items }] : []);
|
|
4193
|
-
const ref =
|
|
4662
|
+
const ref = React16.useRef(resolved);
|
|
4194
4663
|
ref.current = resolved;
|
|
4195
4664
|
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])]));
|
|
4196
|
-
|
|
4665
|
+
React16.useEffect(() => {
|
|
4197
4666
|
publishSubNav({ id, label: ariaLabel, sections: ref.current });
|
|
4198
4667
|
return () => unpublishSubNav(id);
|
|
4199
4668
|
}, [id, ariaLabel, signature]);
|
|
@@ -4221,16 +4690,16 @@ function PremiumBadge({ className }) {
|
|
|
4221
4690
|
const tip = t("upgrade.badgeTooltip");
|
|
4222
4691
|
return /* @__PURE__ */ jsx("span", { title: tip, "aria-label": tip, className: cn("inline-flex shrink-0", className), children: /* @__PURE__ */ jsx(Crown, { className: "h-3.5 w-3.5 text-amber-500", "aria-hidden": true }) });
|
|
4223
4692
|
}
|
|
4224
|
-
var ModuleLayoutContext =
|
|
4693
|
+
var ModuleLayoutContext = React16.createContext("rail");
|
|
4225
4694
|
function ModuleLayoutProvider({ variant, children }) {
|
|
4226
4695
|
return /* @__PURE__ */ jsx(ModuleLayoutContext.Provider, { value: variant, children });
|
|
4227
4696
|
}
|
|
4228
4697
|
function useModuleLayout() {
|
|
4229
|
-
return
|
|
4698
|
+
return React16.useContext(ModuleLayoutContext);
|
|
4230
4699
|
}
|
|
4231
4700
|
function RailNavItem({ item, collapsed }) {
|
|
4232
|
-
const [expanded, setExpanded] =
|
|
4233
|
-
|
|
4701
|
+
const [expanded, setExpanded] = React16.useState(false);
|
|
4702
|
+
React16.useEffect(() => {
|
|
4234
4703
|
if (collapsed) setExpanded(false);
|
|
4235
4704
|
}, [collapsed]);
|
|
4236
4705
|
const Icon = item.icon ? ICON_MAP[item.icon] ?? null : null;
|
|
@@ -4297,9 +4766,9 @@ function defaultChildOf(item) {
|
|
|
4297
4766
|
return kids.find((c) => c.defaultChild) ?? kids.find((c) => /(^|-)list$/i.test(c.id)) ?? kids.find((c) => !/(^|-)(new|novo|nova|create)$/i.test(c.id)) ?? kids[0];
|
|
4298
4767
|
}
|
|
4299
4768
|
function MobileTabs({ nav }) {
|
|
4300
|
-
const scrollRef =
|
|
4301
|
-
const [expandedId, setExpandedId] =
|
|
4302
|
-
|
|
4769
|
+
const scrollRef = React16.useRef(null);
|
|
4770
|
+
const [expandedId, setExpandedId] = React16.useState(null);
|
|
4771
|
+
React16.useEffect(() => {
|
|
4303
4772
|
const container = scrollRef.current;
|
|
4304
4773
|
if (!container) return;
|
|
4305
4774
|
const activeEl = container.querySelector('[data-active="true"]');
|
|
@@ -4372,12 +4841,12 @@ function MobileTabs({ nav }) {
|
|
|
4372
4841
|
})()
|
|
4373
4842
|
] });
|
|
4374
4843
|
}
|
|
4375
|
-
var BackStyleContext =
|
|
4844
|
+
var BackStyleContext = React16.createContext("link");
|
|
4376
4845
|
function BackStyleProvider({ style, children }) {
|
|
4377
4846
|
return /* @__PURE__ */ jsx(BackStyleContext.Provider, { value: style, children });
|
|
4378
4847
|
}
|
|
4379
4848
|
function useBackStyle() {
|
|
4380
|
-
return
|
|
4849
|
+
return React16.useContext(BackStyleContext);
|
|
4381
4850
|
}
|
|
4382
4851
|
function SubpageHeader({ title, subtitle, description, icon, onBack, parentLabel, actions, backStyle, inline }) {
|
|
4383
4852
|
const t = useTranslation();
|
|
@@ -4533,8 +5002,8 @@ function ModuleHeader({ nav }) {
|
|
|
4533
5002
|
function ModulePage({ title: _title, subtitle, nav, children, className, headerAction, showHeader = true, sidebarFooter, navVariant, viewKey, direction, navFilterPlaceholder }) {
|
|
4534
5003
|
const ctxVariant = useModuleLayout();
|
|
4535
5004
|
const variant = navVariant ?? ctxVariant;
|
|
4536
|
-
const [navQuery, setNavQuery] =
|
|
4537
|
-
const filteredNav =
|
|
5005
|
+
const [navQuery, setNavQuery] = React16.useState("");
|
|
5006
|
+
const filteredNav = React16.useMemo(() => {
|
|
4538
5007
|
const q = navQuery.trim().toLowerCase();
|
|
4539
5008
|
if (!q) return nav;
|
|
4540
5009
|
const hit = (label) => label.toLowerCase().includes(q);
|
|
@@ -4546,7 +5015,7 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
|
|
|
4546
5015
|
}, [nav, navQuery]);
|
|
4547
5016
|
const transitionKey = viewKey ?? "view";
|
|
4548
5017
|
const onSubpage = useHasPageHeaderBack();
|
|
4549
|
-
const activeLabel =
|
|
5018
|
+
const activeLabel = React16.useMemo(() => {
|
|
4550
5019
|
if (onSubpage) return null;
|
|
4551
5020
|
for (const item of nav) {
|
|
4552
5021
|
const kid = item.children?.find((c) => c.active);
|
|
@@ -4587,6 +5056,6 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
|
|
|
4587
5056
|
] });
|
|
4588
5057
|
}
|
|
4589
5058
|
|
|
4590
|
-
export { AppShell, BackStyleProvider, BottomSheet, COLUMN_WIDTH, CollapsibleColumn, HeaderTabs, Hint, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, 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, useModalHost, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useModuleViewLabel, useNavTransition, usePageHeader, usePageHeaderClaimed, usePageHeaderHost, usePageTrail, usePageTrailParent, usePublishModuleViewLabel, useRailRow, useRegisterPageActions, useSaveBar, useSaveBarVisible, useSheetClose, useSheetDrag, useTrailBack };
|
|
4591
|
-
//# sourceMappingURL=chunk-
|
|
4592
|
-
//# sourceMappingURL=chunk-
|
|
5059
|
+
export { AppShell, BackStyleProvider, BottomSheet, COLUMN_WIDTH, CollapsibleColumn, Dropdown, DropdownCheckboxItem, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownPortal, DropdownRadioGroup, DropdownRadioItem, DropdownSeparator, DropdownShortcut, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownTrigger, HeaderTabs, Hint, MobileScrim, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageActionBar, 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, WIDE_QUERY, bottomNavReachesAll, isCreateRoute, navigateToCrumb, setActionsMenuLabel, useBackHandler, useBackStyle, useCrossModuleBack, useCurrentRouteHref, useHasPageActions, useHasPageHeaderBack, useHasPageHeaderHost, useHasPageHeaderOutlet, useIsWide, useLayoutStore, useModalHost, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useModuleViewLabel, useNavTransition, usePageHeader, usePageHeaderClaimed, usePageHeaderHost, usePageTrail, usePageTrailParent, usePublishModuleViewLabel, useRailRow, useRegisterPageActions, useSaveBar, useSaveBarVisible, useSheetClose, useSheetDrag, useTrailBack };
|
|
5060
|
+
//# sourceMappingURL=chunk-L6PNGGHM.js.map
|
|
5061
|
+
//# sourceMappingURL=chunk-L6PNGGHM.js.map
|