@fayz-ai/ui 0.33.1 → 0.36.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-6GWXDVCO.js → chunk-7W6WRDDF.js} +54 -102
- package/dist/chunk-7W6WRDDF.js.map +1 -0
- package/dist/{chunk-Q2B5RPH5.js → chunk-N7JP63VB.js} +5 -5
- package/dist/{chunk-Q2B5RPH5.js.map → chunk-N7JP63VB.js.map} +1 -1
- package/dist/{chunk-UNEEY5XG.js → chunk-UCNY76FQ.js} +3 -3
- package/dist/{chunk-UNEEY5XG.js.map → chunk-UCNY76FQ.js.map} +1 -1
- package/dist/{chunk-33A7SN2N.js → chunk-XR3WXB6N.js} +363 -235
- package/dist/chunk-XR3WXB6N.js.map +1 -0
- package/dist/{chunk-ATDIWKBD.js → chunk-ZTS5S6BZ.js} +4 -3
- package/dist/chunk-ZTS5S6BZ.js.map +1 -0
- package/dist/dashboard/index.js +4 -4
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -9
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/SaveBar.d.ts.map +1 -1
- package/dist/layout/index.js +2 -2
- package/dist/layout/rail-flyout.d.ts.map +1 -1
- package/dist/primitives/ai-action-button.d.ts +13 -0
- package/dist/primitives/ai-action-button.d.ts.map +1 -0
- package/dist/primitives/date-picker.d.ts.map +1 -1
- package/dist/primitives/index.d.ts +3 -1
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +4 -4
- package/dist/primitives/inline-link.d.ts +29 -0
- package/dist/primitives/inline-link.d.ts.map +1 -0
- package/dist/primitives/modal.d.ts +2 -0
- package/dist/primitives/modal.d.ts.map +1 -1
- package/dist/primitives/page-actions.d.ts.map +1 -1
- package/dist/primitives/person-picker.d.ts +1 -1
- package/dist/primitives/person-picker.d.ts.map +1 -1
- package/dist/primitives/search-select.d.ts +4 -1
- package/dist/primitives/search-select.d.ts.map +1 -1
- package/dist/styles.css +26 -0
- package/package.json +2 -2
- package/dist/chunk-33A7SN2N.js.map +0 -1
- package/dist/chunk-6GWXDVCO.js.map +0 -1
- package/dist/chunk-ATDIWKBD.js.map +0 -1
|
@@ -1,17 +1,120 @@
|
|
|
1
1
|
import { cn } from './chunk-OKZ6WQB3.js';
|
|
2
|
-
import { ICON_MAP } from './chunk-
|
|
3
|
-
import * as
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
2
|
+
import { ICON_MAP } from './chunk-ZTS5S6BZ.js';
|
|
3
|
+
import * as React12 from 'react';
|
|
4
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
5
|
+
import { X, Loader2, ChevronLeft, ArrowLeft, Bell, PanelLeft, PanelLeftClose, Search, CornerDownLeft, Menu, Crown, ChevronsRight, ChevronsLeft, ChevronDown, ChevronRight, Info, ExternalLink, CreditCard, Sparkles, Home, ChevronUp, Plus, Settings, UserCog, LogOut } from 'lucide-react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
|
-
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
8
7
|
import { createPortal } from 'react-dom';
|
|
8
|
+
import { useTranslation, useNavReferrer, routeModule, navHistoryBack, recordNavigation } from '@fayz-ai/core';
|
|
9
|
+
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
9
10
|
import { create } from 'zustand';
|
|
10
11
|
import * as Popover from '@radix-ui/react-popover';
|
|
11
12
|
|
|
13
|
+
var SIZE_MAP = {
|
|
14
|
+
sm: "sm:max-w-sm",
|
|
15
|
+
md: "sm:max-w-md",
|
|
16
|
+
lg: "sm:max-w-lg",
|
|
17
|
+
xl: "sm:max-w-xl",
|
|
18
|
+
"2xl": "sm:max-w-2xl",
|
|
19
|
+
"3xl": "sm:max-w-3xl",
|
|
20
|
+
// Duas colunas de trabalho lado a lado (ficha + linha do tempo) não cabem em
|
|
21
|
+
// 3xl: a coluna da direita fica com 20rem e o texto de cada anotação quebra
|
|
22
|
+
// a cada quatro palavras.
|
|
23
|
+
"4xl": "sm:max-w-4xl",
|
|
24
|
+
"5xl": "sm:max-w-5xl",
|
|
25
|
+
full: "sm:max-w-[calc(100vw-4rem)]"
|
|
26
|
+
};
|
|
27
|
+
var Modal = DialogPrimitive.Root;
|
|
28
|
+
var ModalTrigger = DialogPrimitive.Trigger;
|
|
29
|
+
var ModalClose = DialogPrimitive.Close;
|
|
30
|
+
var ModalPortal = DialogPrimitive.Portal;
|
|
31
|
+
var ModalHostContext = React12.createContext(null);
|
|
32
|
+
function useModalHost() {
|
|
33
|
+
return React12.useContext(ModalHostContext);
|
|
34
|
+
}
|
|
35
|
+
var ModalOverlay = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
36
|
+
DialogPrimitive.Overlay,
|
|
37
|
+
{
|
|
38
|
+
ref,
|
|
39
|
+
className: cn(
|
|
40
|
+
"fayz-modal-overlay saas-mdl-ov fixed inset-0 z-[100]",
|
|
41
|
+
"flex items-center justify-center p-0 sm:p-6",
|
|
42
|
+
className
|
|
43
|
+
),
|
|
44
|
+
...props
|
|
45
|
+
}
|
|
46
|
+
));
|
|
47
|
+
ModalOverlay.displayName = "ModalOverlay";
|
|
48
|
+
var ModalContent = React12.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => {
|
|
49
|
+
const [host, setHost] = React12.useState(null);
|
|
50
|
+
const attach = React12.useCallback((node) => {
|
|
51
|
+
setHost(node);
|
|
52
|
+
if (typeof ref === "function") ref(node);
|
|
53
|
+
else if (ref) ref.current = node;
|
|
54
|
+
}, [ref]);
|
|
55
|
+
return /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsx(ModalOverlay, { children: /* @__PURE__ */ jsxs(
|
|
56
|
+
DialogPrimitive.Content,
|
|
57
|
+
{
|
|
58
|
+
ref: attach,
|
|
59
|
+
onCloseAutoFocus: (e) => {
|
|
60
|
+
e.preventDefault();
|
|
61
|
+
onCloseAutoFocus?.(e);
|
|
62
|
+
},
|
|
63
|
+
onPointerDownOutside: (e) => {
|
|
64
|
+
const target = e.target;
|
|
65
|
+
if (target.closest("[data-modal-passthrough]") || target.closest("[data-radix-popper-content-wrapper]")) {
|
|
66
|
+
e.preventDefault();
|
|
67
|
+
}
|
|
68
|
+
onPointerDownOutside?.(e);
|
|
69
|
+
},
|
|
70
|
+
onInteractOutside: (e) => {
|
|
71
|
+
const target = e.target;
|
|
72
|
+
if (target.closest("[data-modal-passthrough]") || target.closest("[data-radix-popper-content-wrapper]")) {
|
|
73
|
+
e.preventDefault();
|
|
74
|
+
}
|
|
75
|
+
onInteractOutside?.(e);
|
|
76
|
+
},
|
|
77
|
+
className: cn(
|
|
78
|
+
// fz-container: a form inside a dialog measures the DIALOG. Without
|
|
79
|
+
// it a two-column field grid in an `sm` modal read the window's width
|
|
80
|
+
// and kept both columns in 380px.
|
|
81
|
+
"fayz-glass-surface fayz-modal-content saas-mdl-ct fz-container relative z-[100] flex flex-col w-full outline-none",
|
|
82
|
+
// Mobile fullscreen
|
|
83
|
+
"h-full rounded-none border-0",
|
|
84
|
+
// Desktop centered card
|
|
85
|
+
"sm:h-auto sm:max-h-[85vh] sm:rounded-2xl sm:border",
|
|
86
|
+
SIZE_MAP[size],
|
|
87
|
+
noPadding ? "" : "p-6 gap-4",
|
|
88
|
+
className
|
|
89
|
+
),
|
|
90
|
+
...props,
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsx(ModalHostContext.Provider, { value: host, children }),
|
|
93
|
+
!hideClose && /* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "absolute right-4 top-4 z-10 flex h-7 w-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring", children: [
|
|
94
|
+
/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
|
|
95
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
96
|
+
] })
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
) }) });
|
|
100
|
+
});
|
|
101
|
+
ModalContent.displayName = "ModalContent";
|
|
102
|
+
function ModalHeader({ className, ...props }) {
|
|
103
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left shrink-0", className), ...props });
|
|
104
|
+
}
|
|
105
|
+
function ModalBody({ className, ...props }) {
|
|
106
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-1 flex-col overflow-y-auto min-h-0", className), ...props });
|
|
107
|
+
}
|
|
108
|
+
function ModalFooter({ className, ...props }) {
|
|
109
|
+
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 });
|
|
110
|
+
}
|
|
111
|
+
var ModalTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
|
|
112
|
+
ModalTitle.displayName = "ModalTitle";
|
|
113
|
+
var ModalDescription = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
114
|
+
ModalDescription.displayName = "ModalDescription";
|
|
12
115
|
var HIDDEN = { visible: false, saving: false };
|
|
13
|
-
var SaveBarApiContext =
|
|
14
|
-
var SaveBarStateContext =
|
|
116
|
+
var SaveBarApiContext = React12.createContext(null);
|
|
117
|
+
var SaveBarStateContext = React12.createContext({ visible: false, saving: false });
|
|
15
118
|
var _saveBarVisible = false;
|
|
16
119
|
var _saveBarSubs = /* @__PURE__ */ new Set();
|
|
17
120
|
function setSaveBarVisibleSignal(v) {
|
|
@@ -20,7 +123,7 @@ function setSaveBarVisibleSignal(v) {
|
|
|
20
123
|
_saveBarSubs.forEach((fn) => fn());
|
|
21
124
|
}
|
|
22
125
|
function useSaveBarVisible() {
|
|
23
|
-
return
|
|
126
|
+
return React12.useSyncExternalStore(
|
|
24
127
|
(cb) => {
|
|
25
128
|
_saveBarSubs.add(cb);
|
|
26
129
|
return () => {
|
|
@@ -32,10 +135,10 @@ function useSaveBarVisible() {
|
|
|
32
135
|
);
|
|
33
136
|
}
|
|
34
137
|
function SaveBarProvider({ children }) {
|
|
35
|
-
const [state, setState] =
|
|
36
|
-
const handlers =
|
|
37
|
-
const entries =
|
|
38
|
-
const api =
|
|
138
|
+
const [state, setState] = React12.useState({ visible: false, saving: false });
|
|
139
|
+
const handlers = React12.useRef({});
|
|
140
|
+
const entries = React12.useRef([]);
|
|
141
|
+
const api = React12.useMemo(() => ({
|
|
39
142
|
setState,
|
|
40
143
|
handlers,
|
|
41
144
|
entries,
|
|
@@ -45,12 +148,12 @@ function SaveBarProvider({ children }) {
|
|
|
45
148
|
setState(top ? top.state : HIDDEN);
|
|
46
149
|
}
|
|
47
150
|
}), []);
|
|
48
|
-
const backStack =
|
|
49
|
-
const backApi =
|
|
50
|
-
|
|
151
|
+
const backStack = React12.useRef([]);
|
|
152
|
+
const backApi = React12.useMemo(() => ({ stack: backStack }), []);
|
|
153
|
+
React12.useEffect(() => {
|
|
51
154
|
setSaveBarVisibleSignal(state.visible);
|
|
52
155
|
}, [state.visible]);
|
|
53
|
-
|
|
156
|
+
React12.useEffect(() => {
|
|
54
157
|
function onKey(e) {
|
|
55
158
|
if (state.visible && !state.saving) {
|
|
56
159
|
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
|
@@ -78,7 +181,7 @@ function SaveBarProvider({ children }) {
|
|
|
78
181
|
}, [state.visible, state.saving]);
|
|
79
182
|
return /* @__PURE__ */ jsx(SaveBarApiContext.Provider, { value: api, children: /* @__PURE__ */ jsx(BackNavApiContext.Provider, { value: backApi, children: /* @__PURE__ */ jsx(SaveBarStateContext.Provider, { value: state, children }) }) });
|
|
80
183
|
}
|
|
81
|
-
var BackNavApiContext =
|
|
184
|
+
var BackNavApiContext = React12.createContext(null);
|
|
82
185
|
function isEditableTarget(target) {
|
|
83
186
|
const el = target;
|
|
84
187
|
if (!el || !el.tagName) return false;
|
|
@@ -86,12 +189,12 @@ function isEditableTarget(target) {
|
|
|
86
189
|
return tag === "input" || tag === "textarea" || tag === "select" || el.isContentEditable;
|
|
87
190
|
}
|
|
88
191
|
function useBackHandler(onBack) {
|
|
89
|
-
const api =
|
|
90
|
-
const ref =
|
|
91
|
-
|
|
192
|
+
const api = React12.useContext(BackNavApiContext);
|
|
193
|
+
const ref = React12.useRef(onBack);
|
|
194
|
+
React12.useEffect(() => {
|
|
92
195
|
ref.current = onBack;
|
|
93
196
|
});
|
|
94
|
-
|
|
197
|
+
React12.useEffect(() => {
|
|
95
198
|
if (!api) return;
|
|
96
199
|
const stack = api.stack.current;
|
|
97
200
|
stack.push(ref);
|
|
@@ -102,15 +205,16 @@ function useBackHandler(onBack) {
|
|
|
102
205
|
}, [api]);
|
|
103
206
|
}
|
|
104
207
|
function useSaveBar({ dirty, alwaysVisible, saving = false, onSave, onDiscard, message, saveLabel, discardLabel }) {
|
|
105
|
-
const api =
|
|
106
|
-
const
|
|
107
|
-
|
|
208
|
+
const api = React12.useContext(SaveBarApiContext);
|
|
209
|
+
const host = useModalHost();
|
|
210
|
+
const entry = React12.useRef({ state: HIDDEN, handlers: {} });
|
|
211
|
+
React12.useEffect(() => {
|
|
108
212
|
entry.current.handlers = { onSave, onDiscard };
|
|
109
213
|
if (api && api.entries.current[api.entries.current.length - 1] === entry.current) {
|
|
110
214
|
api.handlers.current = entry.current.handlers;
|
|
111
215
|
}
|
|
112
216
|
});
|
|
113
|
-
|
|
217
|
+
React12.useEffect(() => {
|
|
114
218
|
if (!api) return;
|
|
115
219
|
const list = api.entries.current;
|
|
116
220
|
list.push(entry.current);
|
|
@@ -121,19 +225,19 @@ function useSaveBar({ dirty, alwaysVisible, saving = false, onSave, onDiscard, m
|
|
|
121
225
|
api.sync();
|
|
122
226
|
};
|
|
123
227
|
}, [api]);
|
|
124
|
-
|
|
228
|
+
React12.useEffect(() => {
|
|
125
229
|
if (!api) return;
|
|
126
|
-
entry.current.state = { visible: dirty || !!alwaysVisible, dirty, saving, message, saveLabel, discardLabel };
|
|
230
|
+
entry.current.state = { visible: dirty || !!alwaysVisible, dirty, saving, message, saveLabel, discardLabel, host };
|
|
127
231
|
if (api.entries.current[api.entries.current.length - 1] === entry.current) api.sync();
|
|
128
|
-
}, [api, dirty, alwaysVisible, saving, message, saveLabel, discardLabel]);
|
|
232
|
+
}, [api, dirty, alwaysVisible, saving, message, saveLabel, discardLabel, host]);
|
|
129
233
|
}
|
|
130
234
|
function SaveBar({ className }) {
|
|
131
|
-
const state =
|
|
132
|
-
const api =
|
|
235
|
+
const state = React12.useContext(SaveBarStateContext);
|
|
236
|
+
const api = React12.useContext(SaveBarApiContext);
|
|
133
237
|
const t = useTranslation();
|
|
134
|
-
const [rendered, setRendered] =
|
|
135
|
-
const [closing, setClosing] =
|
|
136
|
-
|
|
238
|
+
const [rendered, setRendered] = React12.useState(state.visible);
|
|
239
|
+
const [closing, setClosing] = React12.useState(false);
|
|
240
|
+
React12.useEffect(() => {
|
|
137
241
|
if (state.visible) {
|
|
138
242
|
setRendered(true);
|
|
139
243
|
setClosing(false);
|
|
@@ -148,15 +252,12 @@ function SaveBar({ className }) {
|
|
|
148
252
|
return () => clearTimeout(id);
|
|
149
253
|
}, [state.visible, rendered]);
|
|
150
254
|
if (!api || !rendered) return null;
|
|
151
|
-
const { saving, message, saveLabel, discardLabel } = state;
|
|
152
|
-
|
|
255
|
+
const { saving, message, saveLabel, discardLabel, host } = state;
|
|
256
|
+
const island = /* @__PURE__ */ jsx(
|
|
153
257
|
"div",
|
|
154
258
|
{
|
|
155
259
|
className: cn(
|
|
156
|
-
|
|
157
|
-
// clear of the bar's height so its actions are not sitting under it.
|
|
158
|
-
"pointer-events-none fixed inset-x-0 z-[55] flex justify-center px-4",
|
|
159
|
-
"bottom-[calc(var(--fz-bottom-bar,0px)+1.25rem)]",
|
|
260
|
+
host ? "pointer-events-none absolute inset-x-0 bottom-4 z-10 flex justify-center px-4" : "pointer-events-none fixed inset-x-0 z-[55] flex justify-center px-4 bottom-[calc(var(--fz-bottom-bar,0px)+1.25rem)]",
|
|
160
261
|
className
|
|
161
262
|
),
|
|
162
263
|
children: /* @__PURE__ */ jsxs("div", { className: cn(
|
|
@@ -197,11 +298,12 @@ function SaveBar({ className }) {
|
|
|
197
298
|
] })
|
|
198
299
|
}
|
|
199
300
|
);
|
|
301
|
+
return host ? createPortal(island, host) : island;
|
|
200
302
|
}
|
|
201
303
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
202
304
|
var Tooltip = TooltipPrimitive.Root;
|
|
203
305
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
204
|
-
var TooltipContent =
|
|
306
|
+
var TooltipContent = React12.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
205
307
|
TooltipPrimitive.Content,
|
|
206
308
|
{
|
|
207
309
|
ref,
|
|
@@ -243,7 +345,7 @@ var usePageHeaderStore = create((set, get) => ({
|
|
|
243
345
|
function useRegisterPageActions() {
|
|
244
346
|
const add = usePageHeaderStore((s) => s.addActions);
|
|
245
347
|
const remove = usePageHeaderStore((s) => s.removeActions);
|
|
246
|
-
|
|
348
|
+
React12.useEffect(() => {
|
|
247
349
|
add();
|
|
248
350
|
return remove;
|
|
249
351
|
}, [add, remove]);
|
|
@@ -266,7 +368,7 @@ function usePageTitleSlotHost() {
|
|
|
266
368
|
function usePageHeaderHost() {
|
|
267
369
|
const addHost = usePageHeaderStore((s) => s.addHost);
|
|
268
370
|
const removeHost = usePageHeaderStore((s) => s.removeHost);
|
|
269
|
-
|
|
371
|
+
React12.useEffect(() => {
|
|
270
372
|
addHost();
|
|
271
373
|
return removeHost;
|
|
272
374
|
}, [addHost, removeHost]);
|
|
@@ -284,30 +386,30 @@ function PageHeaderOutlet({ className, active = true }) {
|
|
|
284
386
|
const hasActions = usePageHeaderStore((s) => s.actions > 0);
|
|
285
387
|
const addOutlet = usePageHeaderStore((s) => s.addOutlet);
|
|
286
388
|
const removeOutlet = usePageHeaderStore((s) => s.removeOutlet);
|
|
287
|
-
|
|
389
|
+
React12.useEffect(() => {
|
|
288
390
|
if (!active) return;
|
|
289
391
|
addOutlet();
|
|
290
392
|
return removeOutlet;
|
|
291
393
|
}, [active, addOutlet, removeOutlet]);
|
|
292
|
-
|
|
394
|
+
React12.useEffect(() => {
|
|
293
395
|
if (active) return;
|
|
294
396
|
setOutletSlot(null);
|
|
295
397
|
setOutletActionsSlot(null);
|
|
296
398
|
}, [active, setOutletSlot, setOutletActionsSlot]);
|
|
297
399
|
if (!active) return null;
|
|
298
|
-
return
|
|
400
|
+
return React12.createElement(
|
|
299
401
|
"div",
|
|
300
402
|
{ className: `flex min-h-9 items-center justify-between gap-3${claimed || hasActions ? "" : " hidden"} ${className ?? "mb-3"}` },
|
|
301
|
-
|
|
302
|
-
|
|
403
|
+
React12.createElement("div", { ref: setOutletSlot, className: "flex min-w-0 flex-1 items-center" }),
|
|
404
|
+
React12.createElement("div", { ref: setOutletActionsSlot, className: "flex shrink-0 items-center gap-2" })
|
|
303
405
|
);
|
|
304
406
|
}
|
|
305
407
|
function usePageHeader(active, options) {
|
|
306
|
-
const id =
|
|
408
|
+
const id = React12.useId();
|
|
307
409
|
const claim = usePageHeaderStore((s) => s.claim);
|
|
308
410
|
const release = usePageHeaderStore((s) => s.release);
|
|
309
411
|
const back = options?.back ?? false;
|
|
310
|
-
|
|
412
|
+
React12.useEffect(() => {
|
|
311
413
|
if (!active) {
|
|
312
414
|
release(id);
|
|
313
415
|
return;
|
|
@@ -324,18 +426,18 @@ function useModuleViewLabel() {
|
|
|
324
426
|
}
|
|
325
427
|
function usePublishModuleViewLabel(label) {
|
|
326
428
|
const setLabel = usePageHeaderStore((s) => s.setModuleViewLabel);
|
|
327
|
-
|
|
429
|
+
React12.useEffect(() => {
|
|
328
430
|
setLabel(label ?? null);
|
|
329
431
|
return () => setLabel(null);
|
|
330
432
|
}, [label, setLabel]);
|
|
331
433
|
}
|
|
332
434
|
function PageTitlePortal({ children }) {
|
|
333
435
|
const slot = usePageTitleSlot();
|
|
334
|
-
if (!slot) return
|
|
436
|
+
if (!slot) return React12.createElement(React12.Fragment, null, children);
|
|
335
437
|
return createPortal(children, slot);
|
|
336
438
|
}
|
|
337
|
-
var Hint =
|
|
338
|
-
if (!label) return
|
|
439
|
+
var Hint = React12.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
|
|
440
|
+
if (!label) return React12.cloneElement(children, { ...rest, ref });
|
|
339
441
|
return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
340
442
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, ...rest, ref, children }),
|
|
341
443
|
/* @__PURE__ */ jsx(TooltipContent, { side, className: "px-2 py-1 text-xs font-medium", children: label })
|
|
@@ -424,7 +526,7 @@ function PageHeader({ title, onBack, parentLabel, backLabel }) {
|
|
|
424
526
|
const hasHost = useHasPageHeaderHost();
|
|
425
527
|
const { onBack: effectiveOnBack, parentLabel: effectiveParent } = useCrossModuleBack(onBack, parentLabel);
|
|
426
528
|
useBackHandler(effectiveOnBack);
|
|
427
|
-
const node =
|
|
529
|
+
const node = React12.useMemo(() => /* @__PURE__ */ jsx(
|
|
428
530
|
PageHeaderCrumb,
|
|
429
531
|
{
|
|
430
532
|
title,
|
|
@@ -438,15 +540,15 @@ function PageHeader({ title, onBack, parentLabel, backLabel }) {
|
|
|
438
540
|
}
|
|
439
541
|
var GUTTER_PX = 8;
|
|
440
542
|
var CLOSE_DELAY_MS = 140;
|
|
441
|
-
var useIsomorphicLayoutEffect = typeof window !== "undefined" ?
|
|
543
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React12.useLayoutEffect : React12.useEffect;
|
|
442
544
|
function iconOf(name) {
|
|
443
545
|
if (!name) return null;
|
|
444
546
|
return ICON_MAP[name] ?? null;
|
|
445
547
|
}
|
|
446
|
-
var RailFlyoutContext =
|
|
548
|
+
var RailFlyoutContext = React12.createContext(null);
|
|
447
549
|
var RailFlyoutProvider = RailFlyoutContext.Provider;
|
|
448
550
|
function useRailRow(content) {
|
|
449
|
-
const flyout =
|
|
551
|
+
const flyout = React12.useContext(RailFlyoutContext);
|
|
450
552
|
if (!flyout || !content) return {};
|
|
451
553
|
return flyout.rowProps(content);
|
|
452
554
|
}
|
|
@@ -456,19 +558,19 @@ function useRailFlyout({
|
|
|
456
558
|
activeRoute,
|
|
457
559
|
onNavigate
|
|
458
560
|
}) {
|
|
459
|
-
const [state, setState] =
|
|
460
|
-
const [pos, setPos] =
|
|
461
|
-
const [animate, setAnimate] =
|
|
462
|
-
const panelRef =
|
|
463
|
-
const closeTimer =
|
|
464
|
-
const lastContent =
|
|
465
|
-
const cancelClose =
|
|
561
|
+
const [state, setState] = React12.useState(null);
|
|
562
|
+
const [pos, setPos] = React12.useState({ top: 0, arrow: 20 });
|
|
563
|
+
const [animate, setAnimate] = React12.useState(false);
|
|
564
|
+
const panelRef = React12.useRef(null);
|
|
565
|
+
const closeTimer = React12.useRef(null);
|
|
566
|
+
const lastContent = React12.useRef(null);
|
|
567
|
+
const cancelClose = React12.useCallback(() => {
|
|
466
568
|
if (closeTimer.current) {
|
|
467
569
|
clearTimeout(closeTimer.current);
|
|
468
570
|
closeTimer.current = null;
|
|
469
571
|
}
|
|
470
572
|
}, []);
|
|
471
|
-
const show =
|
|
573
|
+
const show = React12.useCallback(
|
|
472
574
|
(anchor, content2) => {
|
|
473
575
|
if (!enabled) return;
|
|
474
576
|
cancelClose();
|
|
@@ -476,19 +578,19 @@ function useRailFlyout({
|
|
|
476
578
|
},
|
|
477
579
|
[enabled, cancelClose]
|
|
478
580
|
);
|
|
479
|
-
const hide =
|
|
581
|
+
const hide = React12.useCallback(() => {
|
|
480
582
|
cancelClose();
|
|
481
583
|
closeTimer.current = setTimeout(() => setState(null), CLOSE_DELAY_MS);
|
|
482
584
|
}, [cancelClose]);
|
|
483
|
-
const dismiss =
|
|
585
|
+
const dismiss = React12.useCallback(() => {
|
|
484
586
|
cancelClose();
|
|
485
587
|
setState(null);
|
|
486
588
|
}, [cancelClose]);
|
|
487
|
-
|
|
488
|
-
|
|
589
|
+
React12.useEffect(() => () => cancelClose(), [cancelClose]);
|
|
590
|
+
React12.useEffect(() => {
|
|
489
591
|
if (!enabled) dismiss();
|
|
490
592
|
}, [enabled, dismiss]);
|
|
491
|
-
const reposition =
|
|
593
|
+
const reposition = React12.useCallback(() => {
|
|
492
594
|
const rail = railRef.current;
|
|
493
595
|
const anchor = state?.anchor;
|
|
494
596
|
if (!rail || !anchor) return;
|
|
@@ -503,7 +605,7 @@ function useRailFlyout({
|
|
|
503
605
|
setPos({ top, arrow });
|
|
504
606
|
}, [railRef, state]);
|
|
505
607
|
useIsomorphicLayoutEffect(reposition, [reposition, state?.content.key]);
|
|
506
|
-
|
|
608
|
+
React12.useEffect(() => {
|
|
507
609
|
if (!state) return;
|
|
508
610
|
const rail = railRef.current;
|
|
509
611
|
const onScroll = () => reposition();
|
|
@@ -515,7 +617,7 @@ function useRailFlyout({
|
|
|
515
617
|
};
|
|
516
618
|
}, [state, railRef, reposition]);
|
|
517
619
|
const visible = !!state;
|
|
518
|
-
|
|
620
|
+
React12.useEffect(() => {
|
|
519
621
|
if (!visible) {
|
|
520
622
|
setAnimate(false);
|
|
521
623
|
return;
|
|
@@ -523,7 +625,7 @@ function useRailFlyout({
|
|
|
523
625
|
const id = requestAnimationFrame(() => setAnimate(true));
|
|
524
626
|
return () => cancelAnimationFrame(id);
|
|
525
627
|
}, [visible]);
|
|
526
|
-
|
|
628
|
+
React12.useEffect(() => {
|
|
527
629
|
if (!visible) return;
|
|
528
630
|
const onKey = (event) => {
|
|
529
631
|
if (event.key === "Escape") dismiss();
|
|
@@ -531,7 +633,7 @@ function useRailFlyout({
|
|
|
531
633
|
window.addEventListener("keydown", onKey);
|
|
532
634
|
return () => window.removeEventListener("keydown", onKey);
|
|
533
635
|
}, [visible, dismiss]);
|
|
534
|
-
const rowProps =
|
|
636
|
+
const rowProps = React12.useCallback(
|
|
535
637
|
(content2) => ({
|
|
536
638
|
onMouseEnter: (event) => show(event.currentTarget, content2),
|
|
537
639
|
onFocus: (event) => show(event.currentTarget, content2),
|
|
@@ -567,7 +669,20 @@ function useRailFlyout({
|
|
|
567
669
|
"div",
|
|
568
670
|
{
|
|
569
671
|
ref: panelRef,
|
|
570
|
-
style: {
|
|
672
|
+
style: {
|
|
673
|
+
borderTopLeftRadius: 2,
|
|
674
|
+
borderBottomLeftRadius: 2,
|
|
675
|
+
// A cor vai em `style` e vem acompanhada de blur. Só a classe
|
|
676
|
+
// `bg-sidebar` deixava o painel atravessável sempre que
|
|
677
|
+
// `hsl(var(--sidebar))` nao resolvia — o tema da conta escreve esse
|
|
678
|
+
// token em runtime, e um valor que o `hsl()` nao aceita faz o
|
|
679
|
+
// navegador DESCARTAR a declaracao inteira, sem erro e so em
|
|
680
|
+
// producao. O blur e a rede embaixo disso: mesmo sem cor nenhuma, a
|
|
681
|
+
// pagina nao atravessa mais o texto do menu.
|
|
682
|
+
backgroundColor: "hsl(var(--sidebar) / 0.9)",
|
|
683
|
+
backdropFilter: "blur(16px) saturate(140%)",
|
|
684
|
+
WebkitBackdropFilter: "blur(16px) saturate(140%)"
|
|
685
|
+
},
|
|
571
686
|
className: cn(
|
|
572
687
|
// Sidebar tone, sidebar border: the panel is the menu leaning out,
|
|
573
688
|
// not a popover from the page underneath it.
|
|
@@ -579,7 +694,12 @@ function useRailFlyout({
|
|
|
579
694
|
"span",
|
|
580
695
|
{
|
|
581
696
|
"aria-hidden": true,
|
|
582
|
-
style: {
|
|
697
|
+
style: {
|
|
698
|
+
top: pos.arrow,
|
|
699
|
+
backgroundColor: "hsl(var(--sidebar) / 0.9)",
|
|
700
|
+
backdropFilter: "blur(16px) saturate(140%)",
|
|
701
|
+
WebkitBackdropFilter: "blur(16px) saturate(140%)"
|
|
702
|
+
},
|
|
583
703
|
className: "absolute -left-[5px] h-2.5 w-2.5 -translate-y-1/2 rotate-45 border-b border-l border-sidebar-border bg-sidebar"
|
|
584
704
|
}
|
|
585
705
|
),
|
|
@@ -694,7 +814,7 @@ function NavChildConnector({ onPath, active }) {
|
|
|
694
814
|
] });
|
|
695
815
|
}
|
|
696
816
|
var RAIL_PUSH_MS = 260;
|
|
697
|
-
var useIsomorphicLayoutEffect2 = typeof window !== "undefined" ?
|
|
817
|
+
var useIsomorphicLayoutEffect2 = typeof window !== "undefined" ? React12.useLayoutEffect : React12.useEffect;
|
|
698
818
|
function getIcon(name) {
|
|
699
819
|
return ICON_MAP[name] ?? Home;
|
|
700
820
|
}
|
|
@@ -905,7 +1025,7 @@ function NavGroup({
|
|
|
905
1025
|
// case in an app that groups its rail).
|
|
906
1026
|
/* @__PURE__ */ jsx("button", { "data-tour": `nav.${child.route}`, onClick: () => onNavigate(child.route), className: childClass, children: childInner })
|
|
907
1027
|
);
|
|
908
|
-
if (!childConnector) return /* @__PURE__ */ jsx(
|
|
1028
|
+
if (!childConnector) return /* @__PURE__ */ jsx(React12.Fragment, { children: row }, child.id);
|
|
909
1029
|
const activeIndex = item.children.findIndex((c) => c.route === activeRoute);
|
|
910
1030
|
const onPath = activeIndex >= 0 && childIndex < activeIndex;
|
|
911
1031
|
return (
|
|
@@ -927,9 +1047,9 @@ function NavGroup({
|
|
|
927
1047
|
] });
|
|
928
1048
|
}
|
|
929
1049
|
function withCollapsed(slot, collapsed) {
|
|
930
|
-
if (!
|
|
1050
|
+
if (!React12.isValidElement(slot)) return slot;
|
|
931
1051
|
if (typeof slot.type === "string") return slot;
|
|
932
|
-
return
|
|
1052
|
+
return React12.cloneElement(slot, { collapsed });
|
|
933
1053
|
}
|
|
934
1054
|
var SKELETON_ROWS = [
|
|
935
1055
|
{ width: 56, group: false },
|
|
@@ -971,7 +1091,7 @@ function Sidebar({
|
|
|
971
1091
|
}) {
|
|
972
1092
|
const currentPath = currentPathProp;
|
|
973
1093
|
const activeRoute = resolveActiveRoute(navigation, currentPath);
|
|
974
|
-
const railRef =
|
|
1094
|
+
const railRef = React12.useRef(null);
|
|
975
1095
|
const flyout = useRailFlyout({
|
|
976
1096
|
enabled: collapsed,
|
|
977
1097
|
railRef,
|
|
@@ -984,14 +1104,14 @@ function Sidebar({
|
|
|
984
1104
|
const handleNavigate = (route) => {
|
|
985
1105
|
onNavigate?.(route);
|
|
986
1106
|
};
|
|
987
|
-
const groupWithActiveRoute =
|
|
1107
|
+
const groupWithActiveRoute = React12.useMemo(() => {
|
|
988
1108
|
const groups = navigation.filter((item) => item.children && item.children.length > 0);
|
|
989
1109
|
return groups.find(
|
|
990
1110
|
(item) => item.route === activeRoute || item.children.some((child) => child.route === activeRoute)
|
|
991
1111
|
)?.id ?? null;
|
|
992
1112
|
}, [navigation, activeRoute]);
|
|
993
|
-
const [openGroup, setOpenGroup] =
|
|
994
|
-
|
|
1113
|
+
const [openGroup, setOpenGroup] = React12.useState(groupWithActiveRoute);
|
|
1114
|
+
React12.useEffect(() => {
|
|
995
1115
|
if (groupWithActiveRoute) setOpenGroup(groupWithActiveRoute);
|
|
996
1116
|
}, [groupWithActiveRoute]);
|
|
997
1117
|
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;
|
|
@@ -1043,10 +1163,10 @@ function Sidebar({
|
|
|
1043
1163
|
mainItems.length > 0 && renderSection(mainItems, sectionLabels?.main),
|
|
1044
1164
|
secondaryItems.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-6", children: renderSection(secondaryItems, sectionLabels?.secondary) })
|
|
1045
1165
|
] });
|
|
1046
|
-
const [outgoing, setOutgoing] =
|
|
1047
|
-
const lastBodyRef =
|
|
1048
|
-
const lastKeyRef =
|
|
1049
|
-
const timerRef =
|
|
1166
|
+
const [outgoing, setOutgoing] = React12.useState(null);
|
|
1167
|
+
const lastBodyRef = React12.useRef(null);
|
|
1168
|
+
const lastKeyRef = React12.useRef(navKey);
|
|
1169
|
+
const timerRef = React12.useRef(null);
|
|
1050
1170
|
useIsomorphicLayoutEffect2(() => {
|
|
1051
1171
|
if (lastKeyRef.current !== navKey) {
|
|
1052
1172
|
const previousBody = lastBodyRef.current;
|
|
@@ -1059,7 +1179,7 @@ function Sidebar({
|
|
|
1059
1179
|
}
|
|
1060
1180
|
lastBodyRef.current = navBody;
|
|
1061
1181
|
});
|
|
1062
|
-
|
|
1182
|
+
React12.useEffect(() => () => {
|
|
1063
1183
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1064
1184
|
}, []);
|
|
1065
1185
|
return (
|
|
@@ -1303,7 +1423,7 @@ function ShellSearch({
|
|
|
1303
1423
|
const rail = tone === "rail";
|
|
1304
1424
|
const contextual = !!onValueChange && !collapsed;
|
|
1305
1425
|
const query = value ?? "";
|
|
1306
|
-
const inputRef =
|
|
1426
|
+
const inputRef = React12.useRef(null);
|
|
1307
1427
|
const escalate = () => setCommandPaletteOpen(true, query);
|
|
1308
1428
|
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";
|
|
1309
1429
|
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";
|
|
@@ -1414,7 +1534,7 @@ function TopbarUserMenu({
|
|
|
1414
1534
|
onBilling,
|
|
1415
1535
|
userMenuExtras
|
|
1416
1536
|
}) {
|
|
1417
|
-
const [open, setOpen] =
|
|
1537
|
+
const [open, setOpen] = React12.useState(false);
|
|
1418
1538
|
if (!user) return null;
|
|
1419
1539
|
const initial = (user.fullName?.trim()?.[0] ?? user.email?.[0] ?? "?").toUpperCase();
|
|
1420
1540
|
const item = (label, onClick, Icon) => onClick ? /* @__PURE__ */ jsxs(
|
|
@@ -1498,7 +1618,7 @@ function getIcon2(name) {
|
|
|
1498
1618
|
return ICON_MAP[name] ?? Home;
|
|
1499
1619
|
}
|
|
1500
1620
|
function NavDropdown({ item, currentPath, onNavigate }) {
|
|
1501
|
-
const [open, setOpen] =
|
|
1621
|
+
const [open, setOpen] = React12.useState(false);
|
|
1502
1622
|
const Icon = getIcon2(item.icon);
|
|
1503
1623
|
const isChildActive = item.children?.some(
|
|
1504
1624
|
(child) => currentPath === child.route || currentPath.startsWith(child.route + "/")
|
|
@@ -1666,9 +1786,9 @@ function Topbar({
|
|
|
1666
1786
|
] });
|
|
1667
1787
|
}
|
|
1668
1788
|
function useSheetDrag({ onDismiss, canDrag }) {
|
|
1669
|
-
const [offset, setOffset] =
|
|
1670
|
-
const [dragging, setDragging] =
|
|
1671
|
-
const start =
|
|
1789
|
+
const [offset, setOffset] = React12.useState(0);
|
|
1790
|
+
const [dragging, setDragging] = React12.useState(false);
|
|
1791
|
+
const start = React12.useRef(null);
|
|
1672
1792
|
const onPointerDown = (e) => {
|
|
1673
1793
|
if (e.pointerType === "mouse") return;
|
|
1674
1794
|
if (canDrag && !canDrag()) return;
|
|
@@ -1702,9 +1822,9 @@ function useSheetDrag({ onDismiss, canDrag }) {
|
|
|
1702
1822
|
handlers: { onPointerDown, onPointerMove, onPointerUp: end, onPointerCancel: end }
|
|
1703
1823
|
};
|
|
1704
1824
|
}
|
|
1705
|
-
var SheetCloseContext =
|
|
1825
|
+
var SheetCloseContext = React12.createContext(null);
|
|
1706
1826
|
function useSheetClose() {
|
|
1707
|
-
const close =
|
|
1827
|
+
const close = React12.useContext(SheetCloseContext);
|
|
1708
1828
|
return close ?? (() => {
|
|
1709
1829
|
});
|
|
1710
1830
|
}
|
|
@@ -1718,9 +1838,9 @@ function BottomSheet({
|
|
|
1718
1838
|
className,
|
|
1719
1839
|
label
|
|
1720
1840
|
}) {
|
|
1721
|
-
const [leaving, setLeaving] =
|
|
1722
|
-
const scroller =
|
|
1723
|
-
const close =
|
|
1841
|
+
const [leaving, setLeaving] = React12.useState(false);
|
|
1842
|
+
const scroller = React12.useRef(null);
|
|
1843
|
+
const close = React12.useCallback(() => {
|
|
1724
1844
|
setLeaving(true);
|
|
1725
1845
|
window.setTimeout(onClose, 200);
|
|
1726
1846
|
}, [onClose]);
|
|
@@ -1728,7 +1848,7 @@ function BottomSheet({
|
|
|
1728
1848
|
onDismiss: close,
|
|
1729
1849
|
canDrag: () => (scroller.current?.scrollTop ?? 0) <= 0
|
|
1730
1850
|
});
|
|
1731
|
-
|
|
1851
|
+
React12.useEffect(() => {
|
|
1732
1852
|
const onKey = (e) => {
|
|
1733
1853
|
if (e.key !== "Escape") return;
|
|
1734
1854
|
if (onBack) onBack();
|
|
@@ -1737,15 +1857,15 @@ function BottomSheet({
|
|
|
1737
1857
|
window.addEventListener("keydown", onKey);
|
|
1738
1858
|
return () => window.removeEventListener("keydown", onKey);
|
|
1739
1859
|
}, [close, onBack]);
|
|
1740
|
-
|
|
1860
|
+
React12.useEffect(() => {
|
|
1741
1861
|
const previous = document.body.style.overflow;
|
|
1742
1862
|
document.body.style.overflow = "hidden";
|
|
1743
1863
|
return () => {
|
|
1744
1864
|
document.body.style.overflow = previous;
|
|
1745
1865
|
};
|
|
1746
1866
|
}, []);
|
|
1747
|
-
const [host, setHost] =
|
|
1748
|
-
|
|
1867
|
+
const [host, setHost] = React12.useState(null);
|
|
1868
|
+
React12.useEffect(() => {
|
|
1749
1869
|
setHost(document.body);
|
|
1750
1870
|
}, []);
|
|
1751
1871
|
if (!host) return null;
|
|
@@ -1860,17 +1980,17 @@ function SheetRow({
|
|
|
1860
1980
|
}
|
|
1861
1981
|
);
|
|
1862
1982
|
}
|
|
1863
|
-
var ModuleHeaderSlotContext =
|
|
1983
|
+
var ModuleHeaderSlotContext = React12.createContext(null);
|
|
1864
1984
|
function useModuleHeaderSlot() {
|
|
1865
|
-
return
|
|
1985
|
+
return React12.useContext(ModuleHeaderSlotContext);
|
|
1866
1986
|
}
|
|
1867
|
-
var ModuleHeaderActionsSlotContext =
|
|
1987
|
+
var ModuleHeaderActionsSlotContext = React12.createContext(null);
|
|
1868
1988
|
function useModuleHeaderActionsSlot() {
|
|
1869
|
-
return
|
|
1989
|
+
return React12.useContext(ModuleHeaderActionsSlotContext);
|
|
1870
1990
|
}
|
|
1871
|
-
var PageRailSlotContext =
|
|
1991
|
+
var PageRailSlotContext = React12.createContext(null);
|
|
1872
1992
|
function usePageRailSlot() {
|
|
1873
|
-
return
|
|
1993
|
+
return React12.useContext(PageRailSlotContext);
|
|
1874
1994
|
}
|
|
1875
1995
|
function isCreateRoute(route) {
|
|
1876
1996
|
return !!route && /\/(new|create)$/.test(route);
|
|
@@ -1957,9 +2077,9 @@ function SidebarLayout({
|
|
|
1957
2077
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
1958
2078
|
const mobileMenuOpen = useLayoutStore((st) => st.mobileDrawerOpen);
|
|
1959
2079
|
const setMobileMenuOpen = useLayoutStore((st) => st.setMobileDrawerOpen);
|
|
1960
|
-
const [headerSlot, setHeaderSlot] =
|
|
1961
|
-
const [actionsSlot, setActionsSlot] =
|
|
1962
|
-
const [pageRailSlot, setPageRailSlot] =
|
|
2080
|
+
const [headerSlot, setHeaderSlot] = React12.useState(null);
|
|
2081
|
+
const [actionsSlot, setActionsSlot] = React12.useState(null);
|
|
2082
|
+
const [pageRailSlot, setPageRailSlot] = React12.useState(null);
|
|
1963
2083
|
const hasPageActions = useHasPageActions();
|
|
1964
2084
|
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(
|
|
1965
2085
|
"shell-enter fz-viewport-h flex overflow-hidden bg-background",
|
|
@@ -2032,6 +2152,10 @@ function SidebarLayout({
|
|
|
2032
2152
|
// Com `min-h` bastava um controle mais alto de um lado para o cartão
|
|
2033
2153
|
// daquele lado descer sozinho.
|
|
2034
2154
|
frame && "fz-on-band md:h-14 md:border-b-0 md:text-sidebar-foreground md:[--accent-foreground:var(--sidebar-accent-foreground)] md:[--accent:var(--sidebar-accent)] md:[--background:var(--sidebar)] md:[--border:var(--sidebar-border)] md:[--card:var(--sidebar)] md:[--foreground:var(--sidebar-foreground)] md:[--muted-foreground:var(--sidebar-muted)] md:[--muted:var(--sidebar-accent)]",
|
|
2155
|
+
// A destination keeps the app controls; a deeper screen keeps its
|
|
2156
|
+
// own title/back row. On phones with complete bottom navigation,
|
|
2157
|
+
// showing both was a two-storey header with no extra way out.
|
|
2158
|
+
barOwnsNav && !pagePrimary && "hidden md:flex",
|
|
2035
2159
|
// …unless the page put its actions in it. Hiding the bar on mobile
|
|
2036
2160
|
// used to hide the only "Novo" the screen had.
|
|
2037
2161
|
mobileHeader !== "minimal" && !hasPageActions && "hidden md:flex",
|
|
@@ -2120,10 +2244,19 @@ function SidebarLayout({
|
|
|
2120
2244
|
// senão as duas superfícies encostadas saem em tons diferentes e
|
|
2121
2245
|
// a emenda que acabamos de apagar volta como degrau de cor.
|
|
2122
2246
|
"fz-liquid-glass relative z-20 flex min-h-12 shrink-0 items-center justify-between gap-3 px-3 md:px-6",
|
|
2123
|
-
menuOpen && "invisible md:visible"
|
|
2247
|
+
menuOpen && "invisible md:visible",
|
|
2248
|
+
// On a primary phone destination the selected bottom-nav item
|
|
2249
|
+
// already names the page. Declared actions render as a body-level
|
|
2250
|
+
// FAB, so this entire duplicate band can disappear.
|
|
2251
|
+
barOwnsNav && pagePrimary && "hidden md:flex"
|
|
2124
2252
|
),
|
|
2125
2253
|
children: [
|
|
2126
|
-
/* @__PURE__ */ jsxs("div", { className:
|
|
2254
|
+
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
2255
|
+
"flex min-w-0 flex-1 items-center gap-3",
|
|
2256
|
+
// Primary destinations are already named by the selected mobile
|
|
2257
|
+
// navigation item. Keep this side only for deeper breadcrumbs.
|
|
2258
|
+
pagePrimary && "hidden md:flex"
|
|
2259
|
+
), children: [
|
|
2127
2260
|
!pageHeaderClaimed && /* @__PURE__ */ jsx(ShellPageTitle, { title: pageTitle, back: pageBack, primary: pagePrimary }),
|
|
2128
2261
|
/* @__PURE__ */ jsx("div", { ref: setTitleSlot, className: "flex min-w-0 items-center empty:hidden" })
|
|
2129
2262
|
] }),
|
|
@@ -2227,9 +2360,9 @@ function TopbarLayout({
|
|
|
2227
2360
|
}) {
|
|
2228
2361
|
const mobileMenuOpen = useLayoutStore((st) => st.mobileDrawerOpen);
|
|
2229
2362
|
const setMobileMenuOpen = useLayoutStore((st) => st.setMobileDrawerOpen);
|
|
2230
|
-
const [headerSlot, setHeaderSlot] =
|
|
2231
|
-
const [actionsSlot, setActionsSlot] =
|
|
2232
|
-
const [pageRailSlot, setPageRailSlot] =
|
|
2363
|
+
const [headerSlot, setHeaderSlot] = React12.useState(null);
|
|
2364
|
+
const [actionsSlot, setActionsSlot] = React12.useState(null);
|
|
2365
|
+
const [pageRailSlot, setPageRailSlot] = React12.useState(null);
|
|
2233
2366
|
const rawClaimed = usePageHeaderClaimed();
|
|
2234
2367
|
const setTitleSlot = usePageTitleSlotHost();
|
|
2235
2368
|
const hasOutlet = useHasPageHeaderOutlet();
|
|
@@ -2362,17 +2495,16 @@ function MobileMoreScreen({
|
|
|
2362
2495
|
orgSwitcher,
|
|
2363
2496
|
mobileIdentity,
|
|
2364
2497
|
identity,
|
|
2365
|
-
notificationSlot,
|
|
2366
2498
|
searchLabel,
|
|
2367
2499
|
sectionLabels,
|
|
2368
2500
|
leaving = false,
|
|
2369
2501
|
onDismiss,
|
|
2370
2502
|
onClose
|
|
2371
2503
|
}) {
|
|
2372
|
-
const [pushed, setPushed] =
|
|
2373
|
-
const [query, setQuery] =
|
|
2374
|
-
const scroller =
|
|
2375
|
-
const close =
|
|
2504
|
+
const [pushed, setPushed] = React12.useState(null);
|
|
2505
|
+
const [query, setQuery] = React12.useState("");
|
|
2506
|
+
const scroller = React12.useRef(null);
|
|
2507
|
+
const close = React12.useCallback(() => {
|
|
2376
2508
|
onClose();
|
|
2377
2509
|
}, [onClose]);
|
|
2378
2510
|
const drag = useSheetDrag({
|
|
@@ -2381,7 +2513,7 @@ function MobileMoreScreen({
|
|
|
2381
2513
|
// a pushed section would dismiss the screen the back button is for.
|
|
2382
2514
|
canDrag: () => !pushed && (scroller.current?.scrollTop ?? 0) <= 0
|
|
2383
2515
|
});
|
|
2384
|
-
|
|
2516
|
+
React12.useEffect(() => {
|
|
2385
2517
|
const onKey = (e) => {
|
|
2386
2518
|
if (e.key !== "Escape") return;
|
|
2387
2519
|
if (pushed) setPushed(null);
|
|
@@ -2390,7 +2522,7 @@ function MobileMoreScreen({
|
|
|
2390
2522
|
window.addEventListener("keydown", onKey);
|
|
2391
2523
|
return () => window.removeEventListener("keydown", onKey);
|
|
2392
2524
|
}, [close, pushed]);
|
|
2393
|
-
|
|
2525
|
+
React12.useEffect(() => {
|
|
2394
2526
|
const previous = document.body.style.overflow;
|
|
2395
2527
|
document.body.style.overflow = "hidden";
|
|
2396
2528
|
return () => {
|
|
@@ -2410,13 +2542,13 @@ function MobileMoreScreen({
|
|
|
2410
2542
|
else onNavigate?.(route);
|
|
2411
2543
|
};
|
|
2412
2544
|
const q = query.trim().toLowerCase();
|
|
2413
|
-
const flat =
|
|
2545
|
+
const flat = React12.useMemo(
|
|
2414
2546
|
() => navigation.flatMap((n) => n.children?.length ? n.children : [n]),
|
|
2415
2547
|
[navigation]
|
|
2416
2548
|
);
|
|
2417
2549
|
const searching = q.length > 0;
|
|
2418
2550
|
const hits = searching ? flat.filter((n) => n.label.toLowerCase().includes(q)) : [];
|
|
2419
|
-
const sections =
|
|
2551
|
+
const sections = React12.useMemo(() => {
|
|
2420
2552
|
const out = [];
|
|
2421
2553
|
for (const key of ["main", "secondary", "settings"]) {
|
|
2422
2554
|
const items = navigation.filter((n) => n.section === key);
|
|
@@ -2437,7 +2569,10 @@ function MobileMoreScreen({
|
|
|
2437
2569
|
"div",
|
|
2438
2570
|
{
|
|
2439
2571
|
className: cn(
|
|
2440
|
-
|
|
2572
|
+
// Isolate the full-screen menu into its own backdrop root. Without it,
|
|
2573
|
+
// the glass header samples the app header underneath and both sets of
|
|
2574
|
+
// controls become visible in the same 44px strip.
|
|
2575
|
+
"fixed inset-0 z-[65] isolate flex flex-col bg-background text-foreground will-change-transform md:hidden",
|
|
2441
2576
|
leaving ? "fz-sheet-out" : "fz-sheet-in",
|
|
2442
2577
|
drag.dragging && "transition-none",
|
|
2443
2578
|
!drag.dragging && !leaving && "transition-transform duration-200 ease-out"
|
|
@@ -2461,18 +2596,15 @@ function MobileMoreScreen({
|
|
|
2461
2596
|
}
|
|
2462
2597
|
) }),
|
|
2463
2598
|
/* @__PURE__ */ jsx("h1", { className: "truncate px-1 text-[15px] font-semibold", children: pushed?.label ?? "Mais" }),
|
|
2464
|
-
/* @__PURE__ */
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
"button",
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
}
|
|
2474
|
-
)
|
|
2475
|
-
] })
|
|
2599
|
+
/* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-center justify-end gap-1", children: /* @__PURE__ */ jsx(
|
|
2600
|
+
"button",
|
|
2601
|
+
{
|
|
2602
|
+
type: "button",
|
|
2603
|
+
onClick: close,
|
|
2604
|
+
className: "fz-ios-tint fz-tap rounded-button px-2 py-1 text-[15px] font-semibold",
|
|
2605
|
+
children: "Conclu\xEDdo"
|
|
2606
|
+
}
|
|
2607
|
+
) })
|
|
2476
2608
|
] }) }),
|
|
2477
2609
|
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsxs(
|
|
2478
2610
|
"div",
|
|
@@ -2685,23 +2817,23 @@ function MinimalLayout({
|
|
|
2685
2817
|
] });
|
|
2686
2818
|
}
|
|
2687
2819
|
function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
|
|
2688
|
-
const [visible, setVisible] =
|
|
2689
|
-
|
|
2820
|
+
const [visible, setVisible] = React12.useState(false);
|
|
2821
|
+
React12.useEffect(() => {
|
|
2690
2822
|
const id = requestAnimationFrame(() => setVisible(true));
|
|
2691
2823
|
return () => cancelAnimationFrame(id);
|
|
2692
2824
|
}, []);
|
|
2693
|
-
const close =
|
|
2825
|
+
const close = React12.useCallback(() => {
|
|
2694
2826
|
setVisible(false);
|
|
2695
2827
|
window.setTimeout(onClose, 250);
|
|
2696
2828
|
}, [onClose]);
|
|
2697
|
-
|
|
2829
|
+
React12.useEffect(() => {
|
|
2698
2830
|
const previous = document.body.style.overflow;
|
|
2699
2831
|
document.body.style.overflow = "hidden";
|
|
2700
2832
|
return () => {
|
|
2701
2833
|
document.body.style.overflow = previous;
|
|
2702
2834
|
};
|
|
2703
2835
|
}, []);
|
|
2704
|
-
|
|
2836
|
+
React12.useEffect(() => {
|
|
2705
2837
|
const onKey = (e) => {
|
|
2706
2838
|
if (e.key === "Escape") close();
|
|
2707
2839
|
};
|
|
@@ -2804,11 +2936,11 @@ function MobileBottomNav({
|
|
|
2804
2936
|
retracted
|
|
2805
2937
|
}) {
|
|
2806
2938
|
const path = currentPath ?? "";
|
|
2807
|
-
const [openSheet, setOpenSheet] =
|
|
2808
|
-
|
|
2939
|
+
const [openSheet, setOpenSheet] = React12.useState(null);
|
|
2940
|
+
React12.useEffect(() => {
|
|
2809
2941
|
setOpenSheet(null);
|
|
2810
2942
|
}, [currentPath]);
|
|
2811
|
-
|
|
2943
|
+
React12.useEffect(() => {
|
|
2812
2944
|
if (retracted) setOpenSheet(null);
|
|
2813
2945
|
}, [retracted]);
|
|
2814
2946
|
const sheetItem = openSheet != null ? items[openSheet] : void 0;
|
|
@@ -2819,12 +2951,8 @@ function MobileBottomNav({
|
|
|
2819
2951
|
"aria-label": "Navega\xE7\xE3o principal",
|
|
2820
2952
|
"aria-hidden": retracted || void 0,
|
|
2821
2953
|
className: cn(
|
|
2822
|
-
// Liquid glass, not a painted strip: the bar sits ON the content, so
|
|
2823
|
-
// the content keeps showing through it as a wash. An opaque bar in the
|
|
2824
|
-
// page's own colour just cut the screen short; an opaque bar in the
|
|
2825
|
-
// RAIL's dark colour made a phone look like it had a second theme.
|
|
2826
2954
|
"fz-safe-b fixed inset-x-0 bottom-0 z-50 flex min-h-16 items-stretch justify-around md:hidden",
|
|
2827
|
-
"
|
|
2955
|
+
"border-t border-sidebar-border bg-sidebar text-sidebar-foreground shadow-[0_-8px_24px_hsl(var(--sidebar)/0.18)]",
|
|
2828
2956
|
"motion-safe:transition-transform motion-safe:duration-200 motion-safe:ease-out",
|
|
2829
2957
|
retracted && "pointer-events-none translate-y-full"
|
|
2830
2958
|
),
|
|
@@ -2877,7 +3005,7 @@ function MobileBottomNav({
|
|
|
2877
3005
|
// min-h-[44px] is the floor a finger needs; the bar was letting
|
|
2878
3006
|
// content decide and landing around 40.
|
|
2879
3007
|
"relative flex min-h-[44px] flex-1 flex-col items-center justify-center gap-0.5 px-1 py-2 transition-colors",
|
|
2880
|
-
isActive ? "text-
|
|
3008
|
+
isActive ? "text-sidebar-accent-foreground" : "text-sidebar-muted"
|
|
2881
3009
|
),
|
|
2882
3010
|
children: [
|
|
2883
3011
|
/* @__PURE__ */ jsx(
|
|
@@ -2886,7 +3014,7 @@ function MobileBottomNav({
|
|
|
2886
3014
|
"aria-hidden": true,
|
|
2887
3015
|
className: cn(
|
|
2888
3016
|
"absolute inset-x-3 top-0 h-0.5 rounded-full transition-opacity",
|
|
2889
|
-
isActive ? "bg-
|
|
3017
|
+
isActive ? "bg-sidebar-accent-foreground opacity-100" : "opacity-0"
|
|
2890
3018
|
)
|
|
2891
3019
|
}
|
|
2892
3020
|
),
|
|
@@ -2984,7 +3112,7 @@ function AppShell({
|
|
|
2984
3112
|
const hasBottomNav = !!bottomNav?.length;
|
|
2985
3113
|
const barOwnsNav = bottomNavReachesAll(bottomNav);
|
|
2986
3114
|
const menuNavigation = appNavigation ?? navigation;
|
|
2987
|
-
const routeLabel =
|
|
3115
|
+
const routeLabel = React12.useCallback((path) => {
|
|
2988
3116
|
let best;
|
|
2989
3117
|
const consider = (route, label) => {
|
|
2990
3118
|
if (!route || !label) return;
|
|
@@ -2999,14 +3127,14 @@ function AppShell({
|
|
|
2999
3127
|
}
|
|
3000
3128
|
return best?.label ?? pageTitle ?? "";
|
|
3001
3129
|
}, [menuNavigation, pageTitle]);
|
|
3002
|
-
|
|
3130
|
+
React12.useEffect(() => {
|
|
3003
3131
|
if (!currentPath) return;
|
|
3004
3132
|
if (currentPath === MENU_ROUTE) return;
|
|
3005
3133
|
const label = routeLabel(currentPath);
|
|
3006
3134
|
if (!label) return;
|
|
3007
3135
|
recordNavigation(currentPath, label);
|
|
3008
3136
|
}, [currentPath, routeLabel]);
|
|
3009
|
-
const destinationRoutes =
|
|
3137
|
+
const destinationRoutes = React12.useMemo(() => {
|
|
3010
3138
|
const routes = [];
|
|
3011
3139
|
for (const item of menuNavigation) {
|
|
3012
3140
|
if (item.route) routes.push(item.route);
|
|
@@ -3015,7 +3143,7 @@ function AppShell({
|
|
|
3015
3143
|
return routes;
|
|
3016
3144
|
}, [menuNavigation]);
|
|
3017
3145
|
const isDestination = !!currentPath && destinationRoutes.includes(currentPath);
|
|
3018
|
-
|
|
3146
|
+
React12.useEffect(() => {
|
|
3019
3147
|
setDestinationRoutes(destinationRoutes);
|
|
3020
3148
|
}, [destinationRoutes]);
|
|
3021
3149
|
const pageClaimedBack = useHasPageHeaderBack();
|
|
@@ -3023,7 +3151,7 @@ function AppShell({
|
|
|
3023
3151
|
const barRetracted = !!pageBack || pageClaimedBack || inSettings;
|
|
3024
3152
|
const mobileDrawerOpen = useLayoutStore((st) => st.mobileDrawerOpen);
|
|
3025
3153
|
const setMobileDrawerOpen = useLayoutStore((st) => st.setMobileDrawerOpen);
|
|
3026
|
-
|
|
3154
|
+
React12.useEffect(() => {
|
|
3027
3155
|
if (useLayoutStore.getState().drawerKeepOpenOnce) {
|
|
3028
3156
|
useLayoutStore.setState({ drawerKeepOpenOnce: false });
|
|
3029
3157
|
return;
|
|
@@ -3031,12 +3159,12 @@ function AppShell({
|
|
|
3031
3159
|
setMobileDrawerOpen(false);
|
|
3032
3160
|
}, [currentPath]);
|
|
3033
3161
|
const menuRouteOpen = barOwnsNav && currentPath === MENU_ROUTE;
|
|
3034
|
-
const firstDestination =
|
|
3162
|
+
const firstDestination = React12.useMemo(() => {
|
|
3035
3163
|
const first = bottomNav?.find((i) => !("kind" in i) || i.kind === "route");
|
|
3036
3164
|
return first?.route ?? "/";
|
|
3037
3165
|
}, [bottomNav]);
|
|
3038
|
-
const menuOrigin =
|
|
3039
|
-
const openMenu =
|
|
3166
|
+
const menuOrigin = React12.useRef(void 0);
|
|
3167
|
+
const openMenu = React12.useCallback(() => {
|
|
3040
3168
|
if (!barOwnsNav) {
|
|
3041
3169
|
setMobileDrawerOpen(true);
|
|
3042
3170
|
return;
|
|
@@ -3047,10 +3175,10 @@ function AppShell({
|
|
|
3047
3175
|
menuOrigin.current = currentPath;
|
|
3048
3176
|
onNavigate?.(MENU_ROUTE);
|
|
3049
3177
|
}, [barOwnsNav, currentPath, onNavigate, setMobileDrawerOpen]);
|
|
3050
|
-
const [menuLeaving, setMenuLeaving] =
|
|
3051
|
-
const [menuLingering, setMenuLingering] =
|
|
3052
|
-
const menuTimer =
|
|
3053
|
-
const dismissMenu =
|
|
3178
|
+
const [menuLeaving, setMenuLeaving] = React12.useState(false);
|
|
3179
|
+
const [menuLingering, setMenuLingering] = React12.useState(false);
|
|
3180
|
+
const menuTimer = React12.useRef(void 0);
|
|
3181
|
+
const dismissMenu = React12.useCallback((navigate) => {
|
|
3054
3182
|
window.clearTimeout(menuTimer.current);
|
|
3055
3183
|
setMenuLingering(true);
|
|
3056
3184
|
setMenuLeaving(true);
|
|
@@ -3060,8 +3188,8 @@ function AppShell({
|
|
|
3060
3188
|
setMenuLingering(false);
|
|
3061
3189
|
}, 240);
|
|
3062
3190
|
}, []);
|
|
3063
|
-
|
|
3064
|
-
const closeMenu =
|
|
3191
|
+
React12.useEffect(() => () => window.clearTimeout(menuTimer.current), []);
|
|
3192
|
+
const closeMenu = React12.useCallback(() => {
|
|
3065
3193
|
if (!barOwnsNav) {
|
|
3066
3194
|
setMobileDrawerOpen(false);
|
|
3067
3195
|
return;
|
|
@@ -3074,7 +3202,7 @@ function AppShell({
|
|
|
3074
3202
|
onNavigate?.(back);
|
|
3075
3203
|
});
|
|
3076
3204
|
}, [barOwnsNav, setMobileDrawerOpen, onNavigate, firstDestination, dismissMenu]);
|
|
3077
|
-
|
|
3205
|
+
React12.useEffect(() => {
|
|
3078
3206
|
if (!menuRouteOpen || typeof window === "undefined") return;
|
|
3079
3207
|
const wide = window.matchMedia("(min-width: 768px)");
|
|
3080
3208
|
const settle = () => {
|
|
@@ -3235,13 +3363,13 @@ function SplitWithRightRail({
|
|
|
3235
3363
|
maxWidth = 720,
|
|
3236
3364
|
resizeLabel = "Resize panel"
|
|
3237
3365
|
}) {
|
|
3238
|
-
const [width, setWidth] =
|
|
3239
|
-
const [dragging, setDragging] =
|
|
3240
|
-
const clamp =
|
|
3366
|
+
const [width, setWidth] = React12.useState(defaultWidth);
|
|
3367
|
+
const [dragging, setDragging] = React12.useState(false);
|
|
3368
|
+
const clamp = React12.useCallback(
|
|
3241
3369
|
(value) => Math.min(maxWidth, Math.max(minWidth, value)),
|
|
3242
3370
|
[minWidth, maxWidth]
|
|
3243
3371
|
);
|
|
3244
|
-
|
|
3372
|
+
React12.useEffect(() => {
|
|
3245
3373
|
if (!dragging) return;
|
|
3246
3374
|
const onMove = (event) => {
|
|
3247
3375
|
event.preventDefault();
|
|
@@ -3263,7 +3391,7 @@ function SplitWithRightRail({
|
|
|
3263
3391
|
document.body.style.cursor = previousCursor;
|
|
3264
3392
|
};
|
|
3265
3393
|
}, [dragging, clamp]);
|
|
3266
|
-
|
|
3394
|
+
React12.useEffect(() => {
|
|
3267
3395
|
if (dragging) return;
|
|
3268
3396
|
onWidthChange?.(width);
|
|
3269
3397
|
}, [dragging]);
|
|
@@ -3478,12 +3606,12 @@ function ViewTabs({ value, onChange, options, "aria-label": ariaLabel, className
|
|
|
3478
3606
|
);
|
|
3479
3607
|
}) });
|
|
3480
3608
|
}
|
|
3481
|
-
var NavTransitionContext =
|
|
3609
|
+
var NavTransitionContext = React12.createContext("slide");
|
|
3482
3610
|
function NavTransitionProvider({ value, children }) {
|
|
3483
3611
|
return /* @__PURE__ */ jsx(NavTransitionContext.Provider, { value, children });
|
|
3484
3612
|
}
|
|
3485
3613
|
function useNavTransition() {
|
|
3486
|
-
return
|
|
3614
|
+
return React12.useContext(NavTransitionContext);
|
|
3487
3615
|
}
|
|
3488
3616
|
function resolveTransitionClass(transition, direction) {
|
|
3489
3617
|
if (transition === "none") return "";
|
|
@@ -3503,26 +3631,26 @@ function PageTransition({
|
|
|
3503
3631
|
return /* @__PURE__ */ jsx("div", { className: cn(animClass, className), children }, transitionKey);
|
|
3504
3632
|
}
|
|
3505
3633
|
var EMPTY = [];
|
|
3506
|
-
var PageTrailContext =
|
|
3634
|
+
var PageTrailContext = React12.createContext(EMPTY);
|
|
3507
3635
|
function PageTrail({
|
|
3508
3636
|
label,
|
|
3509
3637
|
href,
|
|
3510
3638
|
onNavigate,
|
|
3511
3639
|
children
|
|
3512
3640
|
}) {
|
|
3513
|
-
const parent =
|
|
3514
|
-
const trail =
|
|
3641
|
+
const parent = React12.useContext(PageTrailContext);
|
|
3642
|
+
const trail = React12.useMemo(
|
|
3515
3643
|
() => [...parent, { label, href, onNavigate }],
|
|
3516
3644
|
[parent, label, href, onNavigate]
|
|
3517
3645
|
);
|
|
3518
3646
|
return /* @__PURE__ */ jsx(PageTrailContext.Provider, { value: trail, children });
|
|
3519
3647
|
}
|
|
3520
3648
|
function usePageTrail() {
|
|
3521
|
-
return
|
|
3649
|
+
return React12.useContext(PageTrailContext);
|
|
3522
3650
|
}
|
|
3523
3651
|
function usePageTrailParent(href) {
|
|
3524
|
-
const trail =
|
|
3525
|
-
return
|
|
3652
|
+
const trail = React12.useContext(PageTrailContext);
|
|
3653
|
+
return React12.useMemo(() => {
|
|
3526
3654
|
const above = href ? trail.filter((c) => c.href !== href) : trail;
|
|
3527
3655
|
return above[above.length - 1];
|
|
3528
3656
|
}, [trail, href]);
|
|
@@ -3538,8 +3666,8 @@ function useCurrentRouteHref() {
|
|
|
3538
3666
|
const clean = hash.split("?")[0];
|
|
3539
3667
|
return clean.startsWith("/") ? clean : `/${clean}`;
|
|
3540
3668
|
};
|
|
3541
|
-
const [href, setHref] =
|
|
3542
|
-
|
|
3669
|
+
const [href, setHref] = React12.useState(read2);
|
|
3670
|
+
React12.useEffect(() => {
|
|
3543
3671
|
const handler = () => setHref(read2());
|
|
3544
3672
|
window.addEventListener("hashchange", handler);
|
|
3545
3673
|
handler();
|
|
@@ -3550,7 +3678,7 @@ function useCurrentRouteHref() {
|
|
|
3550
3678
|
function useTrailBack(href) {
|
|
3551
3679
|
const current = useCurrentRouteHref();
|
|
3552
3680
|
const parent = usePageTrailParent(href ?? current);
|
|
3553
|
-
return
|
|
3681
|
+
return React12.useMemo(
|
|
3554
3682
|
() => parent ? { onBack: () => navigateToCrumb(parent), parentLabel: parent.label } : {},
|
|
3555
3683
|
[parent]
|
|
3556
3684
|
);
|
|
@@ -3577,23 +3705,23 @@ function CollapsibleColumn({
|
|
|
3577
3705
|
"aria-label": ariaLabel
|
|
3578
3706
|
}) {
|
|
3579
3707
|
const pinnedKey = `${storageKey}.pinned`;
|
|
3580
|
-
const [collapsed, setCollapsed] =
|
|
3581
|
-
const [pinned, setPinned] =
|
|
3582
|
-
const [hovering, setHovering] =
|
|
3583
|
-
const hoveringRef =
|
|
3584
|
-
const collapsedRef =
|
|
3708
|
+
const [collapsed, setCollapsed] = React12.useState(() => read(storageKey));
|
|
3709
|
+
const [pinned, setPinned] = React12.useState(() => read(pinnedKey));
|
|
3710
|
+
const [hovering, setHovering] = React12.useState(false);
|
|
3711
|
+
const hoveringRef = React12.useRef(false);
|
|
3712
|
+
const collapsedRef = React12.useRef(collapsed);
|
|
3585
3713
|
collapsedRef.current = collapsed;
|
|
3586
|
-
const autoRef =
|
|
3714
|
+
const autoRef = React12.useRef(false);
|
|
3587
3715
|
const open = !collapsed || hovering;
|
|
3588
3716
|
const width = open ? COLUMN_WIDTH : COLUMN_COLLAPSED_WIDTH;
|
|
3589
3717
|
const setHover = (on) => {
|
|
3590
3718
|
hoveringRef.current = on;
|
|
3591
3719
|
setHovering(on);
|
|
3592
3720
|
};
|
|
3593
|
-
|
|
3721
|
+
React12.useEffect(() => {
|
|
3594
3722
|
onWidth?.(width);
|
|
3595
3723
|
}, [width, onWidth]);
|
|
3596
|
-
const setOpenState =
|
|
3724
|
+
const setOpenState = React12.useCallback((nextCollapsed) => {
|
|
3597
3725
|
setCollapsed(nextCollapsed);
|
|
3598
3726
|
setPinned(!nextCollapsed);
|
|
3599
3727
|
autoRef.current = false;
|
|
@@ -3604,7 +3732,7 @@ function CollapsibleColumn({
|
|
|
3604
3732
|
}
|
|
3605
3733
|
if (nextCollapsed) setHover(false);
|
|
3606
3734
|
}, [storageKey, pinnedKey]);
|
|
3607
|
-
|
|
3735
|
+
React12.useEffect(() => {
|
|
3608
3736
|
if (squeezed === void 0) return;
|
|
3609
3737
|
if (squeezed) {
|
|
3610
3738
|
if (!collapsedRef.current) {
|
|
@@ -3616,8 +3744,8 @@ function CollapsibleColumn({
|
|
|
3616
3744
|
setCollapsed(false);
|
|
3617
3745
|
}
|
|
3618
3746
|
}, [squeezed]);
|
|
3619
|
-
const seen =
|
|
3620
|
-
|
|
3747
|
+
const seen = React12.useRef(null);
|
|
3748
|
+
React12.useEffect(() => {
|
|
3621
3749
|
if (autoCollapseKey === void 0) return;
|
|
3622
3750
|
if (seen.current === null) {
|
|
3623
3751
|
seen.current = autoCollapseKey;
|
|
@@ -3631,14 +3759,14 @@ function CollapsibleColumn({
|
|
|
3631
3759
|
}, autoCollapseMs);
|
|
3632
3760
|
return () => clearTimeout(t);
|
|
3633
3761
|
}, [autoCollapseKey, collapsed, pinned, autoCollapseMs]);
|
|
3634
|
-
const scrollRef =
|
|
3635
|
-
const [hasMore, setHasMore] =
|
|
3636
|
-
const onScroll =
|
|
3762
|
+
const scrollRef = React12.useRef(null);
|
|
3763
|
+
const [hasMore, setHasMore] = React12.useState(false);
|
|
3764
|
+
const onScroll = React12.useCallback(() => {
|
|
3637
3765
|
const el = scrollRef.current;
|
|
3638
3766
|
if (!el) return;
|
|
3639
3767
|
setHasMore(el.scrollHeight - el.scrollTop - el.clientHeight > 4);
|
|
3640
3768
|
}, []);
|
|
3641
|
-
|
|
3769
|
+
React12.useEffect(() => {
|
|
3642
3770
|
onScroll();
|
|
3643
3771
|
const el = scrollRef.current;
|
|
3644
3772
|
if (!el) return;
|
|
@@ -3648,11 +3776,11 @@ function CollapsibleColumn({
|
|
|
3648
3776
|
ro.disconnect();
|
|
3649
3777
|
};
|
|
3650
3778
|
}, [onScroll, open, children]);
|
|
3651
|
-
const boxRef =
|
|
3652
|
-
const panelRef =
|
|
3653
|
-
const [seamed, setSeamed] =
|
|
3654
|
-
const armedRef =
|
|
3655
|
-
const publish =
|
|
3779
|
+
const boxRef = React12.useRef(null);
|
|
3780
|
+
const panelRef = React12.useRef(null);
|
|
3781
|
+
const [seamed, setSeamed] = React12.useState(false);
|
|
3782
|
+
const armedRef = React12.useRef(false);
|
|
3783
|
+
const publish = React12.useCallback(() => {
|
|
3656
3784
|
if (!seamTop) return;
|
|
3657
3785
|
const el = panelRef.current;
|
|
3658
3786
|
const card = el?.closest(".fz-page-surface");
|
|
@@ -3675,10 +3803,10 @@ function CollapsibleColumn({
|
|
|
3675
3803
|
});
|
|
3676
3804
|
}
|
|
3677
3805
|
}, [seamTop]);
|
|
3678
|
-
|
|
3806
|
+
React12.useEffect(() => {
|
|
3679
3807
|
publish();
|
|
3680
3808
|
}, [publish, width]);
|
|
3681
|
-
|
|
3809
|
+
React12.useEffect(() => {
|
|
3682
3810
|
if (!seamTop) return;
|
|
3683
3811
|
const el = panelRef.current;
|
|
3684
3812
|
const card = el?.closest(".fz-page-surface");
|
|
@@ -3808,7 +3936,7 @@ function viewBarSubscribe(l) {
|
|
|
3808
3936
|
};
|
|
3809
3937
|
}
|
|
3810
3938
|
function ViewBarHost() {
|
|
3811
|
-
const active =
|
|
3939
|
+
const active = React12.useSyncExternalStore(viewBarSubscribe, () => viewBarCount > 0);
|
|
3812
3940
|
return /* @__PURE__ */ jsx(
|
|
3813
3941
|
"div",
|
|
3814
3942
|
{
|
|
@@ -3821,8 +3949,8 @@ function ViewBarHost() {
|
|
|
3821
3949
|
);
|
|
3822
3950
|
}
|
|
3823
3951
|
function PageViewBar({ children }) {
|
|
3824
|
-
const slot =
|
|
3825
|
-
|
|
3952
|
+
const slot = React12.useSyncExternalStore(viewBarSubscribe, () => viewBarSlot);
|
|
3953
|
+
React12.useEffect(() => {
|
|
3826
3954
|
viewBarCount++;
|
|
3827
3955
|
viewBarNotify();
|
|
3828
3956
|
return () => {
|
|
@@ -3858,9 +3986,9 @@ function RailSections({ sections, search, collapsed }) {
|
|
|
3858
3986
|
}
|
|
3859
3987
|
var RAIL_COLLAPSED_KEY = "fayz.subnav.collapsed";
|
|
3860
3988
|
function RailColumn({ className, "aria-label": ariaLabel, sections, search, footer }) {
|
|
3861
|
-
const boxRef =
|
|
3862
|
-
const [squeezed, setSqueezed] =
|
|
3863
|
-
|
|
3989
|
+
const boxRef = React12.useRef(null);
|
|
3990
|
+
const [squeezed, setSqueezed] = React12.useState(void 0);
|
|
3991
|
+
React12.useEffect(() => {
|
|
3864
3992
|
if (typeof window === "undefined") return;
|
|
3865
3993
|
const row = boxRef.current?.parentElement?.parentElement;
|
|
3866
3994
|
if (!row) return;
|
|
@@ -3920,10 +4048,10 @@ function unpublishSubNav(id) {
|
|
|
3920
4048
|
subNavNotify();
|
|
3921
4049
|
}
|
|
3922
4050
|
function useSubNavPublished() {
|
|
3923
|
-
return
|
|
4051
|
+
return React12.useSyncExternalStore(subNavSubscribe, () => published, () => published);
|
|
3924
4052
|
}
|
|
3925
4053
|
function useSubNavHost() {
|
|
3926
|
-
|
|
4054
|
+
React12.useEffect(() => {
|
|
3927
4055
|
subNavHosts++;
|
|
3928
4056
|
subNavNotify();
|
|
3929
4057
|
return () => {
|
|
@@ -3933,7 +4061,7 @@ function useSubNavHost() {
|
|
|
3933
4061
|
}, []);
|
|
3934
4062
|
}
|
|
3935
4063
|
function useHasSubNavHost() {
|
|
3936
|
-
return
|
|
4064
|
+
return React12.useSyncExternalStore(subNavSubscribe, () => subNavHosts > 0, () => false);
|
|
3937
4065
|
}
|
|
3938
4066
|
function SubNavBand({ sections, "aria-label": ariaLabel, className }) {
|
|
3939
4067
|
const items = sections.flatMap((s) => s.items);
|
|
@@ -3965,13 +4093,13 @@ function SubNavBandHost({ leading, label }) {
|
|
|
3965
4093
|
);
|
|
3966
4094
|
}
|
|
3967
4095
|
function PageSubNav({ items, sections, search, footer, style, "aria-label": ariaLabel }) {
|
|
3968
|
-
const id =
|
|
4096
|
+
const id = React12.useId();
|
|
3969
4097
|
const hasHost = useHasSubNavHost();
|
|
3970
4098
|
const resolved = sections ?? (items ? [{ items }] : []);
|
|
3971
|
-
const ref =
|
|
4099
|
+
const ref = React12.useRef(resolved);
|
|
3972
4100
|
ref.current = resolved;
|
|
3973
4101
|
const signature = JSON.stringify(resolved.map((s) => [s.key, s.heading, s.items.map((i) => [i.id, i.label, i.icon, !!i.active, !!i.premium])]));
|
|
3974
|
-
|
|
4102
|
+
React12.useEffect(() => {
|
|
3975
4103
|
publishSubNav({ id, label: ariaLabel, sections: ref.current });
|
|
3976
4104
|
return () => unpublishSubNav(id);
|
|
3977
4105
|
}, [id, ariaLabel, signature]);
|
|
@@ -3999,16 +4127,16 @@ function PremiumBadge({ className }) {
|
|
|
3999
4127
|
const tip = t("upgrade.badgeTooltip");
|
|
4000
4128
|
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 }) });
|
|
4001
4129
|
}
|
|
4002
|
-
var ModuleLayoutContext =
|
|
4130
|
+
var ModuleLayoutContext = React12.createContext("rail");
|
|
4003
4131
|
function ModuleLayoutProvider({ variant, children }) {
|
|
4004
4132
|
return /* @__PURE__ */ jsx(ModuleLayoutContext.Provider, { value: variant, children });
|
|
4005
4133
|
}
|
|
4006
4134
|
function useModuleLayout() {
|
|
4007
|
-
return
|
|
4135
|
+
return React12.useContext(ModuleLayoutContext);
|
|
4008
4136
|
}
|
|
4009
4137
|
function RailNavItem({ item, collapsed }) {
|
|
4010
|
-
const [expanded, setExpanded] =
|
|
4011
|
-
|
|
4138
|
+
const [expanded, setExpanded] = React12.useState(false);
|
|
4139
|
+
React12.useEffect(() => {
|
|
4012
4140
|
if (collapsed) setExpanded(false);
|
|
4013
4141
|
}, [collapsed]);
|
|
4014
4142
|
const Icon = item.icon ? ICON_MAP[item.icon] ?? null : null;
|
|
@@ -4075,9 +4203,9 @@ function defaultChildOf(item) {
|
|
|
4075
4203
|
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];
|
|
4076
4204
|
}
|
|
4077
4205
|
function MobileTabs({ nav }) {
|
|
4078
|
-
const scrollRef =
|
|
4079
|
-
const [expandedId, setExpandedId] =
|
|
4080
|
-
|
|
4206
|
+
const scrollRef = React12.useRef(null);
|
|
4207
|
+
const [expandedId, setExpandedId] = React12.useState(null);
|
|
4208
|
+
React12.useEffect(() => {
|
|
4081
4209
|
const container = scrollRef.current;
|
|
4082
4210
|
if (!container) return;
|
|
4083
4211
|
const activeEl = container.querySelector('[data-active="true"]');
|
|
@@ -4150,12 +4278,12 @@ function MobileTabs({ nav }) {
|
|
|
4150
4278
|
})()
|
|
4151
4279
|
] });
|
|
4152
4280
|
}
|
|
4153
|
-
var BackStyleContext =
|
|
4281
|
+
var BackStyleContext = React12.createContext("link");
|
|
4154
4282
|
function BackStyleProvider({ style, children }) {
|
|
4155
4283
|
return /* @__PURE__ */ jsx(BackStyleContext.Provider, { value: style, children });
|
|
4156
4284
|
}
|
|
4157
4285
|
function useBackStyle() {
|
|
4158
|
-
return
|
|
4286
|
+
return React12.useContext(BackStyleContext);
|
|
4159
4287
|
}
|
|
4160
4288
|
function SubpageHeader({ title, subtitle, description, icon, onBack, parentLabel, actions, backStyle, inline }) {
|
|
4161
4289
|
const t = useTranslation();
|
|
@@ -4311,8 +4439,8 @@ function ModuleHeader({ nav }) {
|
|
|
4311
4439
|
function ModulePage({ title: _title, subtitle, nav, children, className, headerAction, showHeader = true, sidebarFooter, navVariant, viewKey, direction, navFilterPlaceholder }) {
|
|
4312
4440
|
const ctxVariant = useModuleLayout();
|
|
4313
4441
|
const variant = navVariant ?? ctxVariant;
|
|
4314
|
-
const [navQuery, setNavQuery] =
|
|
4315
|
-
const filteredNav =
|
|
4442
|
+
const [navQuery, setNavQuery] = React12.useState("");
|
|
4443
|
+
const filteredNav = React12.useMemo(() => {
|
|
4316
4444
|
const q = navQuery.trim().toLowerCase();
|
|
4317
4445
|
if (!q) return nav;
|
|
4318
4446
|
const hit = (label) => label.toLowerCase().includes(q);
|
|
@@ -4324,7 +4452,7 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
|
|
|
4324
4452
|
}, [nav, navQuery]);
|
|
4325
4453
|
const transitionKey = viewKey ?? "view";
|
|
4326
4454
|
const onSubpage = useHasPageHeaderBack();
|
|
4327
|
-
const activeLabel =
|
|
4455
|
+
const activeLabel = React12.useMemo(() => {
|
|
4328
4456
|
if (onSubpage) return null;
|
|
4329
4457
|
for (const item of nav) {
|
|
4330
4458
|
const kid = item.children?.find((c) => c.active);
|
|
@@ -4365,6 +4493,6 @@ function ModulePage({ title: _title, subtitle, nav, children, className, headerA
|
|
|
4365
4493
|
] });
|
|
4366
4494
|
}
|
|
4367
4495
|
|
|
4368
|
-
export { AppShell, BackStyleProvider, BottomSheet, COLUMN_WIDTH, CollapsibleColumn, HeaderTabs, Hint, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageHeader, PageHeaderActions, PageHeaderCrumb, PageHeaderOutlet, PageRail, PageSubNav, PageTabs, PageTitlePortal, PageTrail, PageTransition, PageViewBar, RailColumn, RailNavItem, SUB_NAV_STYLE, SaveBar, SaveBarProvider, SheetCard, SheetRow, ShellSearch, Sidebar, SubpageHeader, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, Topbar, ViewTabs, bottomNavReachesAll, isCreateRoute, navigateToCrumb, useBackHandler, useBackStyle, useCrossModuleBack, useCurrentRouteHref, useHasPageActions, useHasPageHeaderBack, useHasPageHeaderHost, useHasPageHeaderOutlet, useLayoutStore, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useModuleViewLabel, useNavTransition, usePageHeader, usePageHeaderClaimed, usePageHeaderHost, usePageTrail, usePageTrailParent, usePublishModuleViewLabel, useRailRow, useRegisterPageActions, useSaveBar, useSaveBarVisible, useSheetClose, useSheetDrag, useTrailBack };
|
|
4369
|
-
//# sourceMappingURL=chunk-
|
|
4370
|
-
//# sourceMappingURL=chunk-
|
|
4496
|
+
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 };
|
|
4497
|
+
//# sourceMappingURL=chunk-XR3WXB6N.js.map
|
|
4498
|
+
//# sourceMappingURL=chunk-XR3WXB6N.js.map
|