@flytedan/flytebot-design-system 0.72.0 → 0.73.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +586 -519
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -13
- package/dist/index.d.ts +31 -13
- package/dist/index.js +584 -519
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1013,6 +1013,7 @@ __export(index_exports, {
|
|
|
1013
1013
|
ModeSwitch: () => ModeSwitch,
|
|
1014
1014
|
ModelControls: () => ModelControls,
|
|
1015
1015
|
NumberInput: () => NumberInput,
|
|
1016
|
+
OVERLAY_BREAKPOINT: () => OVERLAY_BREAKPOINT,
|
|
1016
1017
|
OVERLAY_CEILING: () => OVERLAY_CEILING,
|
|
1017
1018
|
POPOVER_BODY_MIN: () => POPOVER_BODY_MIN,
|
|
1018
1019
|
PacketCard: () => PacketCard,
|
|
@@ -1137,6 +1138,7 @@ __export(index_exports, {
|
|
|
1137
1138
|
useDocumentTitle: () => useDocumentTitle,
|
|
1138
1139
|
useFeatureStatus: () => useFeatureStatus,
|
|
1139
1140
|
useLayerZIndex: () => useLayerZIndex,
|
|
1141
|
+
useOverlayLayout: () => useOverlayLayout,
|
|
1140
1142
|
usePopoverPosition: () => usePopoverPosition,
|
|
1141
1143
|
useResponsiveRail: () => useResponsiveRail,
|
|
1142
1144
|
useRuntimeMode: () => useRuntimeMode,
|
|
@@ -2080,26 +2082,57 @@ function Collapsible({
|
|
|
2080
2082
|
}
|
|
2081
2083
|
|
|
2082
2084
|
// src/components/surfaces/Drawer.tsx
|
|
2083
|
-
var
|
|
2085
|
+
var React7 = __toESM(require("react"), 1);
|
|
2084
2086
|
var import_react_dom3 = require("react-dom");
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2087
|
+
|
|
2088
|
+
// src/kits/useClosingAnimation.ts
|
|
2089
|
+
var React6 = __toESM(require("react"), 1);
|
|
2090
|
+
function useClosingAnimation(open2, onClose, durationMs) {
|
|
2088
2091
|
const [closing, setClosing] = React6.useState(false);
|
|
2092
|
+
const timer = React6.useRef(null);
|
|
2093
|
+
const cancel = React6.useCallback(() => {
|
|
2094
|
+
if (timer.current !== null) clearTimeout(timer.current);
|
|
2095
|
+
timer.current = null;
|
|
2096
|
+
}, []);
|
|
2097
|
+
React6.useEffect(() => {
|
|
2098
|
+
if (!open2) {
|
|
2099
|
+
cancel();
|
|
2100
|
+
setClosing(false);
|
|
2101
|
+
}
|
|
2102
|
+
}, [open2, cancel]);
|
|
2103
|
+
React6.useEffect(() => cancel, [cancel]);
|
|
2089
2104
|
const close2 = React6.useCallback(() => {
|
|
2090
2105
|
if (!onClose) return;
|
|
2106
|
+
cancel();
|
|
2091
2107
|
setClosing(true);
|
|
2092
|
-
setTimeout(
|
|
2093
|
-
|
|
2108
|
+
timer.current = setTimeout(() => {
|
|
2109
|
+
timer.current = null;
|
|
2110
|
+
onClose();
|
|
2111
|
+
}, durationMs);
|
|
2112
|
+
}, [onClose, durationMs, cancel]);
|
|
2113
|
+
return { closing, close: close2 };
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
// src/components/surfaces/Drawer.tsx
|
|
2117
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2118
|
+
function Drawer({ open: open2 = true, title, label, onClose, footer, bare = false, children, className = "", ...rest }) {
|
|
2119
|
+
const asideRef = React7.useRef(null);
|
|
2120
|
+
const { closing, close: close2 } = useClosingAnimation(!!open2, onClose, 210);
|
|
2094
2121
|
const layer = useStackedLayer({ active: !!open2, containerRef: asideRef, trap: true, onEscape: onClose ? close2 : void 0 });
|
|
2095
2122
|
const zIndex = useLayerZIndex(layer);
|
|
2123
|
+
const titleId = React7.useId();
|
|
2124
|
+
const accessibleName = bare ? label ?? (typeof title === "string" ? title : void 0) : label;
|
|
2125
|
+
const unnamed = !!open2 && bare && !accessibleName;
|
|
2126
|
+
React7.useEffect(() => {
|
|
2127
|
+
if (process.env.NODE_ENV !== "production" && unnamed) console.warn("Drawer: a bare Drawer has no header to name it. Pass `label`, or a string `title`, so the dialog has an accessible name.");
|
|
2128
|
+
}, [unnamed]);
|
|
2096
2129
|
if (!open2) return null;
|
|
2097
2130
|
return (0, import_react_dom3.createPortal)(
|
|
2098
2131
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(StackedLayerProvider, { layer, children: [
|
|
2099
2132
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "fd-scrim" + (closing ? " is-closing" : ""), style: { display: "block", zIndex: zIndex - LAYER_STEP }, onClick: close2 }),
|
|
2100
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("aside", { ref: asideRef, className: ["fd-drawer", bare ? "is-bare" : "", closing ? "is-closing" : "", className].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", "aria-label":
|
|
2133
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("aside", { ref: asideRef, className: ["fd-drawer", bare ? "is-bare" : "", closing ? "is-closing" : "", className].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", "aria-label": accessibleName, "aria-labelledby": bare || label ? void 0 : titleId, ...rest, style: { zIndex }, children: [
|
|
2101
2134
|
bare ? null : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "fd-card-head", style: { flex: "none" }, children: [
|
|
2102
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "fd-card-head-title", title: truncationTitle(title), children: title }),
|
|
2135
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: titleId, className: "fd-card-head-title", title: truncationTitle(title), children: title }),
|
|
2103
2136
|
onClose ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Close", onClick: close2, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("i", { className: "ph ph-x" }) }) : null
|
|
2104
2137
|
] }),
|
|
2105
2138
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: bare ? { flex: "1 1 auto", minHeight: 0, display: "flex", flexDirection: "column" } : { flex: "1 1 auto", minHeight: 0, overflow: "auto", padding: 20 }, children: typeof children === "function" ? children(close2) : children }),
|
|
@@ -2111,17 +2144,12 @@ function Drawer({ open: open2 = true, title, onClose, footer, bare = false, chil
|
|
|
2111
2144
|
}
|
|
2112
2145
|
|
|
2113
2146
|
// src/components/surfaces/Modal.tsx
|
|
2114
|
-
var
|
|
2147
|
+
var React8 = __toESM(require("react"), 1);
|
|
2115
2148
|
var import_react_dom4 = require("react-dom");
|
|
2116
2149
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2117
2150
|
function Modal({ open: open2 = true, title, description, onClose, footer, wide = false, children, className = "", ...rest }) {
|
|
2118
|
-
const
|
|
2119
|
-
const
|
|
2120
|
-
const close2 = React7.useCallback(() => {
|
|
2121
|
-
if (!onClose) return;
|
|
2122
|
-
setClosing(true);
|
|
2123
|
-
setTimeout(onClose, 190);
|
|
2124
|
-
}, [onClose]);
|
|
2151
|
+
const boxRef = React8.useRef(null);
|
|
2152
|
+
const { closing, close: close2 } = useClosingAnimation(!!open2, onClose, 190);
|
|
2125
2153
|
const layer = useStackedLayer({ active: !!open2, containerRef: boxRef, trap: true, onEscape: onClose ? close2 : void 0 });
|
|
2126
2154
|
const zIndex = useLayerZIndex(layer);
|
|
2127
2155
|
if (!open2) return null;
|
|
@@ -2204,13 +2232,13 @@ function ScreenHead({ kicker, title, lede, actions }) {
|
|
|
2204
2232
|
}
|
|
2205
2233
|
|
|
2206
2234
|
// src/components/layout/CardGrid.tsx
|
|
2207
|
-
var
|
|
2235
|
+
var React9 = __toESM(require("react"), 1);
|
|
2208
2236
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2209
2237
|
function flattenFragments(children) {
|
|
2210
2238
|
const out = [];
|
|
2211
|
-
|
|
2239
|
+
React9.Children.forEach(children, (child) => {
|
|
2212
2240
|
if (child === null || child === void 0 || typeof child === "boolean") return;
|
|
2213
|
-
if (
|
|
2241
|
+
if (React9.isValidElement(child) && child.type === React9.Fragment) {
|
|
2214
2242
|
const fragmentChildren = child.props.children;
|
|
2215
2243
|
out.push(...flattenFragments(fragmentChildren));
|
|
2216
2244
|
return;
|
|
@@ -2228,7 +2256,7 @@ function CardGrid({ children, minCardWidth = 280, gap = "lg", className = "", st
|
|
|
2228
2256
|
className: ["fd-card-grid", "fd-gap-" + gap, className].filter(Boolean).join(" "),
|
|
2229
2257
|
style: { ["--card-grid-min"]: minCardWidth + "px", ...style },
|
|
2230
2258
|
children: items.map((child, i) => {
|
|
2231
|
-
if (
|
|
2259
|
+
if (React9.isValidElement(child)) {
|
|
2232
2260
|
const existingRole = child.props.role;
|
|
2233
2261
|
if (existingRole) return child;
|
|
2234
2262
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { role: "listitem", children: child }, child.key ?? i);
|
|
@@ -2278,10 +2306,10 @@ function LoadingRegion({
|
|
|
2278
2306
|
}
|
|
2279
2307
|
|
|
2280
2308
|
// src/components/loading/JobTray.tsx
|
|
2281
|
-
var
|
|
2309
|
+
var React11 = __toESM(require("react"), 1);
|
|
2282
2310
|
|
|
2283
2311
|
// src/kits/cornerStack.tsx
|
|
2284
|
-
var
|
|
2312
|
+
var React10 = __toESM(require("react"), 1);
|
|
2285
2313
|
var import_react_dom5 = require("react-dom");
|
|
2286
2314
|
var CORNER_STACK_INSET_PROPERTY = "--fd-corner-stack-inset";
|
|
2287
2315
|
var SLOTS = ["jobs", "toasts"];
|
|
@@ -2331,9 +2359,9 @@ function release(slot) {
|
|
|
2331
2359
|
slotElements.clear();
|
|
2332
2360
|
}
|
|
2333
2361
|
}
|
|
2334
|
-
var useSlotEffect = typeof document === "undefined" ?
|
|
2362
|
+
var useSlotEffect = typeof document === "undefined" ? React10.useEffect : React10.useLayoutEffect;
|
|
2335
2363
|
function useCornerStackSlot(slot) {
|
|
2336
|
-
const [element, setElement] =
|
|
2364
|
+
const [element, setElement] = React10.useState(null);
|
|
2337
2365
|
useSlotEffect(() => {
|
|
2338
2366
|
setElement(acquire(slot));
|
|
2339
2367
|
return () => {
|
|
@@ -2390,9 +2418,9 @@ function announcementFor(job) {
|
|
|
2390
2418
|
return title + ": in progress";
|
|
2391
2419
|
}
|
|
2392
2420
|
function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
|
|
2393
|
-
const [announcement, setAnnouncement] =
|
|
2394
|
-
const prevStatuses =
|
|
2395
|
-
|
|
2421
|
+
const [announcement, setAnnouncement] = React11.useState("");
|
|
2422
|
+
const prevStatuses = React11.useRef({});
|
|
2423
|
+
React11.useEffect(() => {
|
|
2396
2424
|
let next = "";
|
|
2397
2425
|
for (const job of jobs2) {
|
|
2398
2426
|
if (prevStatuses.current[job.id] !== job.status) {
|
|
@@ -2443,7 +2471,7 @@ function JobCard({ job, onDismiss }) {
|
|
|
2443
2471
|
}
|
|
2444
2472
|
|
|
2445
2473
|
// src/components/loading/PhasedProgress.tsx
|
|
2446
|
-
var
|
|
2474
|
+
var React12 = __toESM(require("react"), 1);
|
|
2447
2475
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2448
2476
|
var ICON = {
|
|
2449
2477
|
pending: "ph-circle",
|
|
@@ -2456,9 +2484,9 @@ function textOf2(node) {
|
|
|
2456
2484
|
return "";
|
|
2457
2485
|
}
|
|
2458
2486
|
function PhasedProgress({ phases, summary, className = "" }) {
|
|
2459
|
-
const [announcement, setAnnouncement] =
|
|
2460
|
-
const prevStatuses =
|
|
2461
|
-
|
|
2487
|
+
const [announcement, setAnnouncement] = React12.useState("");
|
|
2488
|
+
const prevStatuses = React12.useRef({});
|
|
2489
|
+
React12.useEffect(() => {
|
|
2462
2490
|
let next = "";
|
|
2463
2491
|
for (const phase of phases) {
|
|
2464
2492
|
if (prevStatuses.current[phase.id] !== phase.status) {
|
|
@@ -2538,12 +2566,12 @@ function Spinner({ size = "md", label = "Loading", className = "", style, ...res
|
|
|
2538
2566
|
}
|
|
2539
2567
|
|
|
2540
2568
|
// src/components/navigation/SidebarNav.tsx
|
|
2541
|
-
var
|
|
2569
|
+
var React13 = __toESM(require("react"), 1);
|
|
2542
2570
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2543
2571
|
function Tip({ label, children }) {
|
|
2544
2572
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { title: label, style: { display: "inline-flex", flex: "none" }, children });
|
|
2545
2573
|
}
|
|
2546
|
-
var SidebarNav =
|
|
2574
|
+
var SidebarNav = React13.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open: open2 = false, className = "", ...rest }, ref) {
|
|
2547
2575
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
2548
2576
|
"nav",
|
|
2549
2577
|
{
|
|
@@ -2582,15 +2610,15 @@ var SidebarNav = React12.forwardRef(function SidebarNav2({ brand, groups = [], c
|
|
|
2582
2610
|
});
|
|
2583
2611
|
|
|
2584
2612
|
// src/components/navigation/Topbar.tsx
|
|
2585
|
-
var
|
|
2613
|
+
var React15 = __toESM(require("react"), 1);
|
|
2586
2614
|
|
|
2587
2615
|
// src/kits/useIsNarrow.ts
|
|
2588
|
-
var
|
|
2616
|
+
var React14 = __toESM(require("react"), 1);
|
|
2589
2617
|
function useIsNarrow(breakpoint) {
|
|
2590
|
-
const [narrow, setNarrow] =
|
|
2618
|
+
const [narrow, setNarrow] = React14.useState(
|
|
2591
2619
|
() => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
2592
2620
|
);
|
|
2593
|
-
|
|
2621
|
+
React14.useEffect(() => {
|
|
2594
2622
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
2595
2623
|
const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
2596
2624
|
const apply = () => setNarrow(mq.matches);
|
|
@@ -2614,11 +2642,11 @@ function Topbar({
|
|
|
2614
2642
|
...rest
|
|
2615
2643
|
}) {
|
|
2616
2644
|
const narrow = useIsNarrow(overflowBreakpoint);
|
|
2617
|
-
const [moreOpen, setMoreOpen] =
|
|
2618
|
-
const moreRef =
|
|
2645
|
+
const [moreOpen, setMoreOpen] = React15.useState(false);
|
|
2646
|
+
const moreRef = React15.useRef(null);
|
|
2619
2647
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
|
|
2620
2648
|
onMenu ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("i", { className: "ph ph-list" }) }) : null,
|
|
2621
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2649
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(React15.Fragment, { children: [
|
|
2622
2650
|
i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
|
|
2623
2651
|
i === crumbs.length - 1 ? (
|
|
2624
2652
|
// MP-141: the current crumb mixes a static route label with (usually) a
|
|
@@ -2671,29 +2699,37 @@ function Topbar({
|
|
|
2671
2699
|
}
|
|
2672
2700
|
|
|
2673
2701
|
// src/kits/useResponsiveRail.ts
|
|
2674
|
-
var
|
|
2702
|
+
var React16 = __toESM(require("react"), 1);
|
|
2703
|
+
|
|
2704
|
+
// src/kits/overlayLayout.ts
|
|
2705
|
+
var OVERLAY_BREAKPOINT = 1024;
|
|
2706
|
+
function useOverlayLayout() {
|
|
2707
|
+
return useIsNarrow(OVERLAY_BREAKPOINT);
|
|
2708
|
+
}
|
|
2709
|
+
|
|
2710
|
+
// src/kits/useResponsiveRail.ts
|
|
2675
2711
|
function useResponsiveRail(options = {}) {
|
|
2676
|
-
const { breakpoint =
|
|
2677
|
-
const navRef =
|
|
2712
|
+
const { breakpoint = OVERLAY_BREAKPOINT, initialOpen = true, onPersist } = options;
|
|
2713
|
+
const navRef = React16.useRef(null);
|
|
2678
2714
|
const overlay = useIsNarrow(breakpoint);
|
|
2679
|
-
const [open2, setOpenRaw] =
|
|
2680
|
-
const setOpen =
|
|
2715
|
+
const [open2, setOpenRaw] = React16.useState(() => overlay ? false : initialOpen);
|
|
2716
|
+
const setOpen = React16.useCallback(
|
|
2681
2717
|
(value) => {
|
|
2682
2718
|
setOpenRaw(value);
|
|
2683
2719
|
if (!overlay) onPersist?.(value);
|
|
2684
2720
|
},
|
|
2685
2721
|
[overlay, onPersist]
|
|
2686
2722
|
);
|
|
2687
|
-
const toggle =
|
|
2688
|
-
const close2 =
|
|
2689
|
-
const lastOverlay =
|
|
2690
|
-
|
|
2723
|
+
const toggle = React16.useCallback(() => setOpen(!open2), [open2, setOpen]);
|
|
2724
|
+
const close2 = React16.useCallback(() => setOpenRaw(false), []);
|
|
2725
|
+
const lastOverlay = React16.useRef(overlay);
|
|
2726
|
+
React16.useEffect(() => {
|
|
2691
2727
|
if (lastOverlay.current === overlay) return;
|
|
2692
2728
|
lastOverlay.current = overlay;
|
|
2693
2729
|
setOpenRaw(!overlay);
|
|
2694
2730
|
}, [overlay]);
|
|
2695
2731
|
const layer = useStackedLayer({ active: overlay && open2, containerRef: navRef, trap: true, onEscape: close2 });
|
|
2696
|
-
|
|
2732
|
+
React16.useEffect(() => {
|
|
2697
2733
|
if (!overlay || !open2) return;
|
|
2698
2734
|
const previousOverflow = document.body.style.overflow;
|
|
2699
2735
|
document.body.style.overflow = "hidden";
|
|
@@ -2714,7 +2750,7 @@ function AppShell({
|
|
|
2714
2750
|
navFooter,
|
|
2715
2751
|
initialNavOpen = true,
|
|
2716
2752
|
onNavOpenChange,
|
|
2717
|
-
railBreakpoint =
|
|
2753
|
+
railBreakpoint = OVERLAY_BREAKPOINT,
|
|
2718
2754
|
crumbs,
|
|
2719
2755
|
loading,
|
|
2720
2756
|
actions,
|
|
@@ -2820,20 +2856,20 @@ function installFlytedeskFavicon(url) {
|
|
|
2820
2856
|
}
|
|
2821
2857
|
|
|
2822
2858
|
// src/components/navigation/Tabs.tsx
|
|
2823
|
-
var
|
|
2859
|
+
var React17 = __toESM(require("react"), 1);
|
|
2824
2860
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2825
2861
|
var FADE_WIDTH = 32;
|
|
2826
2862
|
function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
2827
|
-
const strip =
|
|
2828
|
-
const [more, setMore] =
|
|
2829
|
-
const measure =
|
|
2863
|
+
const strip = React17.useRef(null);
|
|
2864
|
+
const [more, setMore] = React17.useState({ start: false, end: false });
|
|
2865
|
+
const measure = React17.useCallback(() => {
|
|
2830
2866
|
const el = strip.current;
|
|
2831
2867
|
if (!el) return;
|
|
2832
2868
|
const start = el.scrollLeft > 1;
|
|
2833
2869
|
const end = el.scrollLeft + el.clientWidth < el.scrollWidth - 1;
|
|
2834
2870
|
setMore((m) => m.start === start && m.end === end ? m : { start, end });
|
|
2835
2871
|
}, []);
|
|
2836
|
-
|
|
2872
|
+
React17.useLayoutEffect(() => {
|
|
2837
2873
|
const el = strip.current;
|
|
2838
2874
|
measure();
|
|
2839
2875
|
if (!el || typeof ResizeObserver === "undefined") return;
|
|
@@ -2841,7 +2877,7 @@ function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
|
2841
2877
|
observer.observe(el);
|
|
2842
2878
|
return () => observer.disconnect();
|
|
2843
2879
|
}, [measure, tabs]);
|
|
2844
|
-
const revealActive =
|
|
2880
|
+
const revealActive = React17.useCallback(() => {
|
|
2845
2881
|
const el = strip.current;
|
|
2846
2882
|
const active = el?.querySelector('[aria-selected="true"]');
|
|
2847
2883
|
if (!el || !active || el.scrollWidth <= el.clientWidth) return;
|
|
@@ -2851,9 +2887,9 @@ function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
|
2851
2887
|
else if (tab.right > box.right - FADE_WIDTH) el.scrollLeft += tab.right - box.right + FADE_WIDTH;
|
|
2852
2888
|
measure();
|
|
2853
2889
|
}, [measure]);
|
|
2854
|
-
|
|
2890
|
+
React17.useLayoutEffect(revealActive, [value, revealActive]);
|
|
2855
2891
|
const tabKeys = tabs.map((t) => typeof t === "string" ? t : t.value).join(",");
|
|
2856
|
-
|
|
2892
|
+
React17.useLayoutEffect(() => {
|
|
2857
2893
|
const el = strip.current;
|
|
2858
2894
|
if (!el || typeof ResizeObserver === "undefined") return;
|
|
2859
2895
|
const observer = new ResizeObserver(revealActive);
|
|
@@ -3108,15 +3144,15 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
|
|
|
3108
3144
|
}
|
|
3109
3145
|
|
|
3110
3146
|
// src/components/feedback/ToastProvider.tsx
|
|
3111
|
-
var
|
|
3147
|
+
var React18 = __toESM(require("react"), 1);
|
|
3112
3148
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
3113
3149
|
var DEFAULT_TOAST_DURATION_MS = 5e3;
|
|
3114
|
-
var ToastContext =
|
|
3150
|
+
var ToastContext = React18.createContext(null);
|
|
3115
3151
|
function ToastProvider({ children }) {
|
|
3116
|
-
const [items, setItems] =
|
|
3117
|
-
const timers =
|
|
3118
|
-
const nextId =
|
|
3119
|
-
const dismiss =
|
|
3152
|
+
const [items, setItems] = React18.useState([]);
|
|
3153
|
+
const timers = React18.useRef(/* @__PURE__ */ new Map());
|
|
3154
|
+
const nextId = React18.useRef(1);
|
|
3155
|
+
const dismiss = React18.useCallback((id) => {
|
|
3120
3156
|
setItems((current2) => current2.filter((item) => item.id !== id));
|
|
3121
3157
|
const timer = timers.current.get(id);
|
|
3122
3158
|
if (timer !== void 0) {
|
|
@@ -3124,7 +3160,7 @@ function ToastProvider({ children }) {
|
|
|
3124
3160
|
timers.current.delete(id);
|
|
3125
3161
|
}
|
|
3126
3162
|
}, []);
|
|
3127
|
-
const show =
|
|
3163
|
+
const show = React18.useCallback(
|
|
3128
3164
|
(title, options = {}) => {
|
|
3129
3165
|
const { tone = "success", duration = DEFAULT_TOAST_DURATION_MS } = options;
|
|
3130
3166
|
const id = nextId.current++;
|
|
@@ -3133,36 +3169,36 @@ function ToastProvider({ children }) {
|
|
|
3133
3169
|
},
|
|
3134
3170
|
[dismiss]
|
|
3135
3171
|
);
|
|
3136
|
-
|
|
3172
|
+
React18.useEffect(() => {
|
|
3137
3173
|
const pending = timers.current;
|
|
3138
3174
|
return () => {
|
|
3139
3175
|
pending.forEach(clearTimeout);
|
|
3140
3176
|
pending.clear();
|
|
3141
3177
|
};
|
|
3142
3178
|
}, []);
|
|
3143
|
-
const api =
|
|
3179
|
+
const api = React18.useMemo(() => ({ show }), [show]);
|
|
3144
3180
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(ToastContext.Provider, { value: api, children: [
|
|
3145
3181
|
children,
|
|
3146
3182
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CornerStackPortal, { slot: "toasts", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "fd-toast-region", "aria-live": "polite", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Toast, { title: item.title, tone: item.tone, onDismiss: () => dismiss(item.id) }, item.id)) }) })
|
|
3147
3183
|
] });
|
|
3148
3184
|
}
|
|
3149
3185
|
function useToast() {
|
|
3150
|
-
const api =
|
|
3186
|
+
const api = React18.useContext(ToastContext);
|
|
3151
3187
|
if (!api) throw new Error("useToast must be used inside a <ToastProvider>");
|
|
3152
3188
|
return api;
|
|
3153
3189
|
}
|
|
3154
3190
|
|
|
3155
3191
|
// src/components/feedback/Tooltip.tsx
|
|
3156
|
-
var
|
|
3192
|
+
var React20 = __toESM(require("react"), 1);
|
|
3157
3193
|
|
|
3158
3194
|
// src/components/feedback/useTooltip.tsx
|
|
3159
|
-
var
|
|
3195
|
+
var React19 = __toESM(require("react"), 1);
|
|
3160
3196
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
3161
3197
|
var CLOSE_DELAY_MS = 120;
|
|
3162
3198
|
var isMouse = (e) => e.pointerType === "mouse";
|
|
3163
3199
|
function TooltipBubble({ open: open2, labels, placement, className, onHide, onEnter, onLeave }) {
|
|
3164
|
-
const anchorRef =
|
|
3165
|
-
const bubbleRef =
|
|
3200
|
+
const anchorRef = React19.useRef(open2.anchor);
|
|
3201
|
+
const bubbleRef = React19.useRef(null);
|
|
3166
3202
|
const pos = usePopoverPosition(true, anchorRef, {
|
|
3167
3203
|
placement: placement === "bottom" ? "bottom-center" : "top-center",
|
|
3168
3204
|
offset: 8,
|
|
@@ -3173,7 +3209,7 @@ function TooltipBubble({ open: open2, labels, placement, className, onHide, onEn
|
|
|
3173
3209
|
});
|
|
3174
3210
|
const layer = useStackedLayer({ active: true, containerRef: bubbleRef, onEscape: onHide, returnFocus: false });
|
|
3175
3211
|
const zIndex = useLayerZIndex(layer);
|
|
3176
|
-
|
|
3212
|
+
React19.useEffect(() => {
|
|
3177
3213
|
const away = (e) => {
|
|
3178
3214
|
const t = e.target;
|
|
3179
3215
|
if (open2.anchor.contains(t)) return;
|
|
@@ -3204,16 +3240,16 @@ function TooltipBubble({ open: open2, labels, placement, className, onHide, onEn
|
|
|
3204
3240
|
);
|
|
3205
3241
|
}
|
|
3206
3242
|
function useTooltip({ placement = "top", className = "" } = {}) {
|
|
3207
|
-
const [open2, setOpen] =
|
|
3208
|
-
const closeTimer =
|
|
3209
|
-
const focused =
|
|
3210
|
-
const cancelClose =
|
|
3243
|
+
const [open2, setOpen] = React19.useState(null);
|
|
3244
|
+
const closeTimer = React19.useRef(null);
|
|
3245
|
+
const focused = React19.useRef(null);
|
|
3246
|
+
const cancelClose = React19.useCallback(() => {
|
|
3211
3247
|
if (closeTimer.current) {
|
|
3212
3248
|
clearTimeout(closeTimer.current);
|
|
3213
3249
|
closeTimer.current = null;
|
|
3214
3250
|
}
|
|
3215
3251
|
}, []);
|
|
3216
|
-
const hide =
|
|
3252
|
+
const hide = React19.useCallback(() => {
|
|
3217
3253
|
cancelClose();
|
|
3218
3254
|
focused.current = null;
|
|
3219
3255
|
setOpen(null);
|
|
@@ -3233,7 +3269,7 @@ function useTooltip({ placement = "top", className = "" } = {}) {
|
|
|
3233
3269
|
setOpen((o) => o && o.reason === "hover" ? focused.current : o);
|
|
3234
3270
|
}, CLOSE_DELAY_MS);
|
|
3235
3271
|
};
|
|
3236
|
-
|
|
3272
|
+
React19.useEffect(() => cancelClose, [cancelClose]);
|
|
3237
3273
|
const labels = /* @__PURE__ */ new Map();
|
|
3238
3274
|
const bind = (id, label) => {
|
|
3239
3275
|
labels.set(id, label);
|
|
@@ -3286,17 +3322,17 @@ function useTooltip({ placement = "top", className = "" } = {}) {
|
|
|
3286
3322
|
// src/components/feedback/Tooltip.tsx
|
|
3287
3323
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
3288
3324
|
function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
3289
|
-
const id =
|
|
3325
|
+
const id = React20.useId();
|
|
3290
3326
|
const descId = id + "-desc";
|
|
3291
3327
|
const tip = useTooltip({ placement, className });
|
|
3292
|
-
const described =
|
|
3328
|
+
const described = React20.isValidElement(children) ? React20.cloneElement(children, {
|
|
3293
3329
|
"aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
|
|
3294
3330
|
}) : children;
|
|
3295
3331
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
3296
3332
|
"span",
|
|
3297
3333
|
{
|
|
3298
3334
|
className: "fd-tooltip-anchor",
|
|
3299
|
-
"aria-describedby":
|
|
3335
|
+
"aria-describedby": React20.isValidElement(children) ? void 0 : descId,
|
|
3300
3336
|
...tip.bind(id, label),
|
|
3301
3337
|
children: [
|
|
3302
3338
|
described,
|
|
@@ -3308,16 +3344,16 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
3308
3344
|
}
|
|
3309
3345
|
|
|
3310
3346
|
// src/components/data/AnimNum.tsx
|
|
3311
|
-
var
|
|
3347
|
+
var React21 = __toESM(require("react"), 1);
|
|
3312
3348
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
3313
3349
|
function shouldSkipEasing() {
|
|
3314
3350
|
if (typeof document !== "undefined" && document.hidden) return true;
|
|
3315
3351
|
return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
|
|
3316
3352
|
}
|
|
3317
3353
|
function AnimNum({ value, format, duration = 550 }) {
|
|
3318
|
-
const [display, setDisplay] =
|
|
3319
|
-
const prev =
|
|
3320
|
-
|
|
3354
|
+
const [display, setDisplay] = React21.useState(value);
|
|
3355
|
+
const prev = React21.useRef(value);
|
|
3356
|
+
React21.useEffect(() => {
|
|
3321
3357
|
const from = prev.current;
|
|
3322
3358
|
const to = value;
|
|
3323
3359
|
prev.current = to;
|
|
@@ -3345,14 +3381,14 @@ function AnimNum({ value, format, duration = 550 }) {
|
|
|
3345
3381
|
}
|
|
3346
3382
|
|
|
3347
3383
|
// src/components/data/TrendChart.tsx
|
|
3348
|
-
var
|
|
3384
|
+
var React24 = __toESM(require("react"), 1);
|
|
3349
3385
|
|
|
3350
3386
|
// src/components/useMeasuredWidth.ts
|
|
3351
|
-
var
|
|
3387
|
+
var React22 = __toESM(require("react"), 1);
|
|
3352
3388
|
function useMeasuredWidth(fallback) {
|
|
3353
|
-
const [element, setElement] =
|
|
3354
|
-
const [width, setWidth] =
|
|
3355
|
-
|
|
3389
|
+
const [element, setElement] = React22.useState(null);
|
|
3390
|
+
const [width, setWidth] = React22.useState(fallback);
|
|
3391
|
+
React22.useLayoutEffect(() => {
|
|
3356
3392
|
if (!element || typeof ResizeObserver === "undefined") return;
|
|
3357
3393
|
const measure = () => {
|
|
3358
3394
|
const measured = Math.round(element.getBoundingClientRect().width);
|
|
@@ -3367,7 +3403,7 @@ function useMeasuredWidth(fallback) {
|
|
|
3367
3403
|
}
|
|
3368
3404
|
|
|
3369
3405
|
// src/components/data/SegmentedMeter.tsx
|
|
3370
|
-
var
|
|
3406
|
+
var React23 = __toESM(require("react"), 1);
|
|
3371
3407
|
|
|
3372
3408
|
// src/kits/files.ts
|
|
3373
3409
|
function formatBytes(n) {
|
|
@@ -3572,7 +3608,7 @@ function SegmentedMeter({
|
|
|
3572
3608
|
const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
|
|
3573
3609
|
const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
|
|
3574
3610
|
const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
|
|
3575
|
-
const generatedId =
|
|
3611
|
+
const generatedId = React23.useId();
|
|
3576
3612
|
const uid2 = id || generatedId;
|
|
3577
3613
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
|
|
3578
3614
|
label || showTotal ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "fd-segmeter-head", children: [
|
|
@@ -3723,8 +3759,8 @@ function TrendChart({
|
|
|
3723
3759
|
onRetry,
|
|
3724
3760
|
className = ""
|
|
3725
3761
|
}) {
|
|
3726
|
-
const [activeId, setActiveId] =
|
|
3727
|
-
const [pointTip, setPointTip] =
|
|
3762
|
+
const [activeId, setActiveId] = React24.useState(null);
|
|
3763
|
+
const [pointTip, setPointTip] = React24.useState(null);
|
|
3728
3764
|
const isEmpty = state === "ready" && (!categories.length || !series.length || series.every((s) => !s.values.length));
|
|
3729
3765
|
const effectiveState = isEmpty ? "empty" : state;
|
|
3730
3766
|
const [plotRef, VBW] = useMeasuredWidth(INITIAL_WIDTH);
|
|
@@ -3838,7 +3874,7 @@ function TrendChart({
|
|
|
3838
3874
|
}
|
|
3839
3875
|
|
|
3840
3876
|
// src/components/data/DonutChart.tsx
|
|
3841
|
-
var
|
|
3877
|
+
var React25 = __toESM(require("react"), 1);
|
|
3842
3878
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
3843
3879
|
function DonutChart({
|
|
3844
3880
|
segments,
|
|
@@ -3853,7 +3889,7 @@ function DonutChart({
|
|
|
3853
3889
|
onRetry,
|
|
3854
3890
|
className = ""
|
|
3855
3891
|
}) {
|
|
3856
|
-
const [activeId, setActiveId] =
|
|
3892
|
+
const [activeId, setActiveId] = React25.useState(null);
|
|
3857
3893
|
const items = segments.filter((s) => Number(s.value) > 0);
|
|
3858
3894
|
const total = items.reduce((n, s) => n + Number(s.value), 0);
|
|
3859
3895
|
const isEmpty = state === "ready" && (!items.length || total <= 0);
|
|
@@ -3945,7 +3981,7 @@ function DonutChart({
|
|
|
3945
3981
|
}
|
|
3946
3982
|
|
|
3947
3983
|
// src/components/data/BarList.tsx
|
|
3948
|
-
var
|
|
3984
|
+
var React26 = __toESM(require("react"), 1);
|
|
3949
3985
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
3950
3986
|
var wholePercent = (share) => formatPercent(Math.round(share * 100));
|
|
3951
3987
|
function BarList({
|
|
@@ -3962,7 +3998,7 @@ function BarList({
|
|
|
3962
3998
|
onRetry,
|
|
3963
3999
|
className = ""
|
|
3964
4000
|
}) {
|
|
3965
|
-
const ordered =
|
|
4001
|
+
const ordered = React26.useMemo(() => {
|
|
3966
4002
|
const list = sort ? [...rows].sort((a, b) => Number(b.value) - Number(a.value)) : rows;
|
|
3967
4003
|
return maxRows ? list.slice(0, maxRows) : list;
|
|
3968
4004
|
}, [rows, sort, maxRows]);
|
|
@@ -4104,7 +4140,7 @@ function FunnelChart({
|
|
|
4104
4140
|
}
|
|
4105
4141
|
|
|
4106
4142
|
// src/components/data/Clamp.tsx
|
|
4107
|
-
var
|
|
4143
|
+
var React27 = __toESM(require("react"), 1);
|
|
4108
4144
|
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
4109
4145
|
function Clamp({
|
|
4110
4146
|
children,
|
|
@@ -4116,16 +4152,16 @@ function Clamp({
|
|
|
4116
4152
|
onToggle,
|
|
4117
4153
|
className = ""
|
|
4118
4154
|
}) {
|
|
4119
|
-
const [open2, setOpen] =
|
|
4120
|
-
const [overflows, setOverflows] =
|
|
4121
|
-
const bodyRef =
|
|
4122
|
-
const charClamped =
|
|
4155
|
+
const [open2, setOpen] = React27.useState(false);
|
|
4156
|
+
const [overflows, setOverflows] = React27.useState(false);
|
|
4157
|
+
const bodyRef = React27.useRef(null);
|
|
4158
|
+
const charClamped = React27.useMemo(() => {
|
|
4123
4159
|
if (open2 || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
|
|
4124
4160
|
const cut = text.slice(0, maxChars);
|
|
4125
4161
|
const at = cut.lastIndexOf(" ");
|
|
4126
4162
|
return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
4127
4163
|
}, [text, maxChars, open2]);
|
|
4128
|
-
|
|
4164
|
+
React27.useLayoutEffect(() => {
|
|
4129
4165
|
const node = bodyRef.current;
|
|
4130
4166
|
if (maxChars || !node || !maxHeight) return;
|
|
4131
4167
|
const measure = () => {
|
|
@@ -4383,16 +4419,16 @@ function StackedRows({ columns, rows, rowKey, loading, stale, skeletonRows, sort
|
|
|
4383
4419
|
}
|
|
4384
4420
|
|
|
4385
4421
|
// src/components/data/FilterBar.tsx
|
|
4386
|
-
var
|
|
4422
|
+
var React33 = __toESM(require("react"), 1);
|
|
4387
4423
|
|
|
4388
4424
|
// src/components/forms/NumberInput.tsx
|
|
4389
|
-
var
|
|
4425
|
+
var React30 = __toESM(require("react"), 1);
|
|
4390
4426
|
|
|
4391
4427
|
// src/components/forms/field.tsx
|
|
4392
|
-
var
|
|
4428
|
+
var React28 = __toESM(require("react"), 1);
|
|
4393
4429
|
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
4394
4430
|
function useFieldId(id) {
|
|
4395
|
-
const generated =
|
|
4431
|
+
const generated = React28.useId();
|
|
4396
4432
|
return id || generated;
|
|
4397
4433
|
}
|
|
4398
4434
|
function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
|
|
@@ -4411,10 +4447,10 @@ function HiddenFieldLabel({ id, children }) {
|
|
|
4411
4447
|
}
|
|
4412
4448
|
|
|
4413
4449
|
// src/components/useLatest.ts
|
|
4414
|
-
var
|
|
4450
|
+
var React29 = __toESM(require("react"), 1);
|
|
4415
4451
|
function useLatest(value) {
|
|
4416
|
-
const ref =
|
|
4417
|
-
|
|
4452
|
+
const ref = React29.useRef(value);
|
|
4453
|
+
React29.useInsertionEffect(() => {
|
|
4418
4454
|
ref.current = value;
|
|
4419
4455
|
});
|
|
4420
4456
|
return ref;
|
|
@@ -4497,20 +4533,20 @@ function NumberInput({
|
|
|
4497
4533
|
const n = typeof v === "number" ? v : parseNumberText(v);
|
|
4498
4534
|
return n == null || Number.isNaN(n) ? null : n;
|
|
4499
4535
|
};
|
|
4500
|
-
const [text, setText] =
|
|
4501
|
-
const [editing, setEditing] =
|
|
4536
|
+
const [text, setText] = React30.useState(() => toText(value));
|
|
4537
|
+
const [editing, setEditing] = React30.useState(false);
|
|
4502
4538
|
const parsed = parseNumberText(text);
|
|
4503
4539
|
const invalidMessage = parsed == null ? null : Number.isNaN(parsed) ? "Enter a number" : integer && !Number.isInteger(parsed) ? "Enter a whole number" : parsed < lo ? "Must be \u2265 " + lo : parsed > hi ? "Must be \u2264 " + hi : null;
|
|
4504
4540
|
const valid = invalidMessage == null;
|
|
4505
|
-
const committedRef =
|
|
4541
|
+
const committedRef = React30.useRef(toNumber(value));
|
|
4506
4542
|
const onChangeRef = useLatest(onChange);
|
|
4507
4543
|
const onValidityChangeRef = useLatest(onValidityChange);
|
|
4508
|
-
const focusedRef =
|
|
4509
|
-
|
|
4544
|
+
const focusedRef = React30.useRef(false);
|
|
4545
|
+
React30.useEffect(() => {
|
|
4510
4546
|
committedRef.current = toNumber(value);
|
|
4511
4547
|
if (!focusedRef.current) setText(toText(value));
|
|
4512
4548
|
}, [value]);
|
|
4513
|
-
|
|
4549
|
+
React30.useLayoutEffect(() => {
|
|
4514
4550
|
onValidityChangeRef.current?.(valid);
|
|
4515
4551
|
}, [valid, onValidityChangeRef]);
|
|
4516
4552
|
const fire = (n) => {
|
|
@@ -4526,7 +4562,7 @@ function NumberInput({
|
|
|
4526
4562
|
return true;
|
|
4527
4563
|
};
|
|
4528
4564
|
const bumpRef = useLatest(bump);
|
|
4529
|
-
const holdTimer =
|
|
4565
|
+
const holdTimer = React30.useRef(null);
|
|
4530
4566
|
const release2 = () => {
|
|
4531
4567
|
if (holdTimer.current) clearTimeout(holdTimer.current);
|
|
4532
4568
|
holdTimer.current = null;
|
|
@@ -4545,7 +4581,7 @@ function NumberInput({
|
|
|
4545
4581
|
};
|
|
4546
4582
|
holdTimer.current = setTimeout(tick, HOLD_DELAY_MS);
|
|
4547
4583
|
};
|
|
4548
|
-
|
|
4584
|
+
React30.useEffect(() => () => {
|
|
4549
4585
|
if (holdTimer.current) clearTimeout(holdTimer.current);
|
|
4550
4586
|
}, []);
|
|
4551
4587
|
const current2 = committedRef.current;
|
|
@@ -4648,7 +4684,7 @@ function NumberInput({
|
|
|
4648
4684
|
}
|
|
4649
4685
|
|
|
4650
4686
|
// src/components/forms/DatePicker.tsx
|
|
4651
|
-
var
|
|
4687
|
+
var React31 = __toESM(require("react"), 1);
|
|
4652
4688
|
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
4653
4689
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
4654
4690
|
var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
@@ -4681,10 +4717,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
4681
4717
|
const today = /* @__PURE__ */ new Date();
|
|
4682
4718
|
const sel = range ? value || {} : { start: value, end: value };
|
|
4683
4719
|
const anchor = parse(sel.start) || parse(initialMonth) || today;
|
|
4684
|
-
const [vy, setVy] =
|
|
4685
|
-
const [vm, setVm] =
|
|
4686
|
-
const [mode2, setMode] =
|
|
4687
|
-
const [hover, setHover] =
|
|
4720
|
+
const [vy, setVy] = React31.useState(anchor.getFullYear());
|
|
4721
|
+
const [vm, setVm] = React31.useState(anchor.getMonth());
|
|
4722
|
+
const [mode2, setMode] = React31.useState("days");
|
|
4723
|
+
const [hover, setHover] = React31.useState(null);
|
|
4688
4724
|
const s = parse(sel.start), e = parse(sel.end);
|
|
4689
4725
|
const hoverEnd = range && s && !e && hover ? parse(hover) : null;
|
|
4690
4726
|
const inRange = (d) => {
|
|
@@ -4695,12 +4731,12 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
4695
4731
|
const isEnd = (d) => !!e && iso(d) === iso(e);
|
|
4696
4732
|
const isEdge = (d) => isStart(d) || isEnd(d);
|
|
4697
4733
|
const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
|
|
4698
|
-
const [activeDate, setActiveDate] =
|
|
4734
|
+
const [activeDate, setActiveDate] = React31.useState(() => {
|
|
4699
4735
|
if (s) return s;
|
|
4700
4736
|
if (sameMonth(today, anchor.getFullYear(), anchor.getMonth())) return today;
|
|
4701
4737
|
return new Date(anchor.getFullYear(), anchor.getMonth(), 1);
|
|
4702
4738
|
});
|
|
4703
|
-
const calRef =
|
|
4739
|
+
const calRef = React31.useRef(null);
|
|
4704
4740
|
const pageToShow = (y, m) => {
|
|
4705
4741
|
const idx = y * 12 + m, firstIdx = vy * 12 + vm, secondIdx = firstIdx + 1;
|
|
4706
4742
|
if (idx === firstIdx || months > 1 && idx === secondIdx) return;
|
|
@@ -4717,7 +4753,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
4717
4753
|
setActiveDate(next);
|
|
4718
4754
|
pageToShow(next.getFullYear(), next.getMonth());
|
|
4719
4755
|
};
|
|
4720
|
-
|
|
4756
|
+
React31.useEffect(() => {
|
|
4721
4757
|
const el = calRef.current?.querySelector('[data-iso="' + iso(activeDate) + '"]');
|
|
4722
4758
|
if (el) el.focus({ preventScroll: true });
|
|
4723
4759
|
}, [activeDate, vy, vm]);
|
|
@@ -4910,9 +4946,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
4910
4946
|
}
|
|
4911
4947
|
function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, "aria-label": hiddenLabel, ...rest }) {
|
|
4912
4948
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
|
|
4913
|
-
const [open2, setOpen] =
|
|
4914
|
-
const rootRef =
|
|
4915
|
-
const boxRef =
|
|
4949
|
+
const [open2, setOpen] = React31.useState(false);
|
|
4950
|
+
const rootRef = React31.useRef(null);
|
|
4951
|
+
const boxRef = React31.useRef(null);
|
|
4916
4952
|
const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
|
|
4917
4953
|
const toggle = () => {
|
|
4918
4954
|
if (!disabled) setOpen(!open2);
|
|
@@ -5001,9 +5037,9 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
|
|
|
5001
5037
|
}
|
|
5002
5038
|
|
|
5003
5039
|
// src/components/forms/listbox.ts
|
|
5004
|
-
var
|
|
5040
|
+
var React32 = __toESM(require("react"), 1);
|
|
5005
5041
|
function useListboxNav({ count, onSelect }) {
|
|
5006
|
-
const [active, setActive] =
|
|
5042
|
+
const [active, setActive] = React32.useState(-1);
|
|
5007
5043
|
return {
|
|
5008
5044
|
active,
|
|
5009
5045
|
setActive,
|
|
@@ -5016,7 +5052,7 @@ function useListboxNav({ count, onSelect }) {
|
|
|
5016
5052
|
};
|
|
5017
5053
|
}
|
|
5018
5054
|
function useListboxScrollIntoView(active, listRef, enabled) {
|
|
5019
|
-
|
|
5055
|
+
React32.useEffect(() => {
|
|
5020
5056
|
if (!enabled || active < 0 || !listRef.current) return;
|
|
5021
5057
|
const list = listRef.current;
|
|
5022
5058
|
const el = list.querySelector('[data-i="' + active + '"]');
|
|
@@ -5034,7 +5070,7 @@ var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
|
5034
5070
|
var TAIL_CHARS = 12;
|
|
5035
5071
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
5036
5072
|
function splitForMiddleEllipsis(text) {
|
|
5037
|
-
const chars = Array.from(graphemes.segment(text), (
|
|
5073
|
+
const chars = Array.from(graphemes.segment(text), (part2) => part2.segment);
|
|
5038
5074
|
if (chars.length <= TAIL_CHARS) return { head: text, tail: "" };
|
|
5039
5075
|
return { head: chars.slice(0, -TAIL_CHARS).join(""), tail: chars.slice(-TAIL_CHARS).join("") };
|
|
5040
5076
|
}
|
|
@@ -5237,13 +5273,13 @@ function MultiSelectPanel({
|
|
|
5237
5273
|
onClose
|
|
5238
5274
|
}) {
|
|
5239
5275
|
const allowedOps = operatorsFor(field);
|
|
5240
|
-
const [draftOperator, setDraftOperator] =
|
|
5276
|
+
const [draftOperator, setDraftOperator] = React33.useState(value?.operator ?? allowedOps[0]);
|
|
5241
5277
|
const operator = allowedOps.length === 1 ? allowedOps[0] : value?.operator ?? draftOperator;
|
|
5242
5278
|
const selected = value?.values ?? [];
|
|
5243
5279
|
const selectedRef = useLatest(selected);
|
|
5244
5280
|
const operatorRef = useLatest(operator);
|
|
5245
|
-
const mountedRef =
|
|
5246
|
-
|
|
5281
|
+
const mountedRef = React33.useRef(true);
|
|
5282
|
+
React33.useEffect(() => {
|
|
5247
5283
|
mountedRef.current = true;
|
|
5248
5284
|
return () => {
|
|
5249
5285
|
mountedRef.current = false;
|
|
@@ -5257,20 +5293,20 @@ function MultiSelectPanel({
|
|
|
5257
5293
|
if (selectedRef.current.length > 0) commit(selectedRef.current, op);
|
|
5258
5294
|
else setDraftOperator(op);
|
|
5259
5295
|
};
|
|
5260
|
-
const [mode2, setMode] =
|
|
5261
|
-
const [query, setQuery] =
|
|
5262
|
-
const [asyncState, setAsyncState] =
|
|
5296
|
+
const [mode2, setMode] = React33.useState("search");
|
|
5297
|
+
const [query, setQuery] = React33.useState("");
|
|
5298
|
+
const [asyncState, setAsyncState] = React33.useState(
|
|
5263
5299
|
{ options: null, loading: !!field.loadOptions, error: false }
|
|
5264
5300
|
);
|
|
5265
|
-
const [retryTick, setRetryTick] =
|
|
5266
|
-
const inputRef =
|
|
5267
|
-
const listRef =
|
|
5268
|
-
const listId =
|
|
5301
|
+
const [retryTick, setRetryTick] = React33.useState(0);
|
|
5302
|
+
const inputRef = React33.useRef(null);
|
|
5303
|
+
const listRef = React33.useRef(null);
|
|
5304
|
+
const listId = React33.useId();
|
|
5269
5305
|
const loadOptionsRef = useLatest(field.loadOptions);
|
|
5270
|
-
|
|
5306
|
+
React33.useEffect(() => {
|
|
5271
5307
|
inputRef.current?.focus();
|
|
5272
5308
|
}, []);
|
|
5273
|
-
|
|
5309
|
+
React33.useEffect(() => {
|
|
5274
5310
|
const load = loadOptionsRef.current;
|
|
5275
5311
|
if (!load) return;
|
|
5276
5312
|
const controller = new AbortController();
|
|
@@ -5303,17 +5339,17 @@ function MultiSelectPanel({
|
|
|
5303
5339
|
};
|
|
5304
5340
|
const nav = useListboxNav({ count: options.length, onSelect: (i) => toggle(options[i]) });
|
|
5305
5341
|
useListboxScrollIntoView(nav.active, listRef, hasListbox);
|
|
5306
|
-
|
|
5342
|
+
React33.useEffect(() => {
|
|
5307
5343
|
nav.setActive(0);
|
|
5308
5344
|
}, [query, options.length]);
|
|
5309
5345
|
const activeId = hasListbox && options[nav.active] ? listId + "-opt-" + nav.active : void 0;
|
|
5310
5346
|
const liveMessage = showLoading ? "Loading\u2026" : showError ? "Couldn't load options." : options.length === 0 ? query === "" && field.emptyText || "No matches" : atLimit ? "Limit reached: at most " + field.maxValues + " values" : "";
|
|
5311
|
-
const [pasteText, setPasteText] =
|
|
5312
|
-
const [pasteLoading, setPasteLoading] =
|
|
5313
|
-
const [unmatchedTokens, setUnmatchedTokens] =
|
|
5314
|
-
const [pasteError, setPasteError] =
|
|
5315
|
-
const pasteWrapRef =
|
|
5316
|
-
|
|
5347
|
+
const [pasteText, setPasteText] = React33.useState("");
|
|
5348
|
+
const [pasteLoading, setPasteLoading] = React33.useState(false);
|
|
5349
|
+
const [unmatchedTokens, setUnmatchedTokens] = React33.useState([]);
|
|
5350
|
+
const [pasteError, setPasteError] = React33.useState(null);
|
|
5351
|
+
const pasteWrapRef = React33.useRef(null);
|
|
5352
|
+
React33.useEffect(() => {
|
|
5317
5353
|
if (mode2 === "paste") pasteWrapRef.current?.querySelector("textarea")?.focus();
|
|
5318
5354
|
}, [mode2]);
|
|
5319
5355
|
const doResolve = () => {
|
|
@@ -5486,8 +5522,8 @@ function MultiSelectPanel({
|
|
|
5486
5522
|
);
|
|
5487
5523
|
}
|
|
5488
5524
|
function useTextValidity(onFlip) {
|
|
5489
|
-
const invalidRef =
|
|
5490
|
-
const [, rerender] =
|
|
5525
|
+
const invalidRef = React33.useRef(/* @__PURE__ */ new Set());
|
|
5526
|
+
const [, rerender] = React33.useReducer((n) => n + 1, 0);
|
|
5491
5527
|
const onFlipRef = useLatest(onFlip);
|
|
5492
5528
|
const record = (name, valid) => {
|
|
5493
5529
|
const invalid = invalidRef.current;
|
|
@@ -5530,15 +5566,15 @@ function sameValue(a, b) {
|
|
|
5530
5566
|
return true;
|
|
5531
5567
|
}
|
|
5532
5568
|
function useReseedFromProps(value, applies, reseed) {
|
|
5533
|
-
const seen =
|
|
5534
|
-
|
|
5569
|
+
const seen = React33.useRef(value);
|
|
5570
|
+
React33.useLayoutEffect(() => {
|
|
5535
5571
|
if (seen.current === value) return;
|
|
5536
5572
|
seen.current = value;
|
|
5537
5573
|
if (!sameValue(value, applies())) reseed(value);
|
|
5538
5574
|
}, [value, applies, reseed]);
|
|
5539
5575
|
}
|
|
5540
5576
|
function usePreserveFocusAcrossRemount(seed, fields) {
|
|
5541
|
-
const pendingName =
|
|
5577
|
+
const pendingName = React33.useRef(null);
|
|
5542
5578
|
const fieldsRef = useLatest(fields);
|
|
5543
5579
|
const capture = () => {
|
|
5544
5580
|
const active = document.activeElement;
|
|
@@ -5551,7 +5587,7 @@ function usePreserveFocusAcrossRemount(seed, fields) {
|
|
|
5551
5587
|
}
|
|
5552
5588
|
}
|
|
5553
5589
|
};
|
|
5554
|
-
|
|
5590
|
+
React33.useLayoutEffect(() => {
|
|
5555
5591
|
const name = pendingName.current;
|
|
5556
5592
|
if (!name) return;
|
|
5557
5593
|
pendingName.current = null;
|
|
@@ -5567,14 +5603,14 @@ function RangePanel({
|
|
|
5567
5603
|
onCommit,
|
|
5568
5604
|
onClose
|
|
5569
5605
|
}) {
|
|
5570
|
-
const [draft, setDraft] =
|
|
5571
|
-
const [seed, setSeed] =
|
|
5572
|
-
const minId =
|
|
5573
|
-
const maxId =
|
|
5574
|
-
const minWrapRef =
|
|
5575
|
-
const maxWrapRef =
|
|
5606
|
+
const [draft, setDraft] = React33.useState(() => rangeDraft(value));
|
|
5607
|
+
const [seed, setSeed] = React33.useState(0);
|
|
5608
|
+
const minId = React33.useId();
|
|
5609
|
+
const maxId = React33.useId();
|
|
5610
|
+
const minWrapRef = React33.useRef(null);
|
|
5611
|
+
const maxWrapRef = React33.useRef(null);
|
|
5576
5612
|
const preserveFocus = usePreserveFocusAcrossRemount(seed, { min: minWrapRef, max: maxWrapRef });
|
|
5577
|
-
const draftRef =
|
|
5613
|
+
const draftRef = React33.useRef(draft);
|
|
5578
5614
|
const shown = () => {
|
|
5579
5615
|
const { min, max } = draftRef.current;
|
|
5580
5616
|
return applicable(field, min == null && max == null ? void 0 : { min, max }, validity.allValid());
|
|
@@ -5666,15 +5702,15 @@ function DatePanel({
|
|
|
5666
5702
|
onClose
|
|
5667
5703
|
}) {
|
|
5668
5704
|
const maxDays = effectiveMaxDays(field);
|
|
5669
|
-
const [initial] =
|
|
5670
|
-
const [kind, setKind] =
|
|
5671
|
-
const [daysDraft, setDaysDraft] =
|
|
5672
|
-
const daysRef =
|
|
5673
|
-
const daysConfirmed =
|
|
5674
|
-
const [between, setBetween] =
|
|
5675
|
-
const [seed, setSeed] =
|
|
5676
|
-
const daysId =
|
|
5677
|
-
const daysWrapRef =
|
|
5705
|
+
const [initial] = React33.useState(() => dateDraft(field, value));
|
|
5706
|
+
const [kind, setKind] = React33.useState(initial.kind);
|
|
5707
|
+
const [daysDraft, setDaysDraft] = React33.useState(initial.days);
|
|
5708
|
+
const daysRef = React33.useRef(daysDraft);
|
|
5709
|
+
const daysConfirmed = React33.useRef(value?.kind === "withinDays");
|
|
5710
|
+
const [between, setBetween] = React33.useState(initial.between);
|
|
5711
|
+
const [seed, setSeed] = React33.useState(0);
|
|
5712
|
+
const daysId = React33.useId();
|
|
5713
|
+
const daysWrapRef = React33.useRef(null);
|
|
5678
5714
|
const preserveFocus = usePreserveFocusAcrossRemount(seed, { days: daysWrapRef });
|
|
5679
5715
|
const shownWithinDays = () => {
|
|
5680
5716
|
const days = daysRef.current;
|
|
@@ -5792,11 +5828,11 @@ function FilterButton({ children, ...rest }) {
|
|
|
5792
5828
|
] });
|
|
5793
5829
|
}
|
|
5794
5830
|
function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", actions, onClearAll, showActiveCount = false, loading = false, loadingLabel = "Loading the filters", className = "", ...rest }) {
|
|
5795
|
-
const [panel, setPanel] =
|
|
5796
|
-
const editAnchorRef =
|
|
5797
|
-
const addAnchorRef =
|
|
5798
|
-
const textInputRef =
|
|
5799
|
-
const optionsRef =
|
|
5831
|
+
const [panel, setPanel] = React33.useState(null);
|
|
5832
|
+
const editAnchorRef = React33.useRef(null);
|
|
5833
|
+
const addAnchorRef = React33.useRef(null);
|
|
5834
|
+
const textInputRef = React33.useRef(null);
|
|
5835
|
+
const optionsRef = React33.useRef(null);
|
|
5800
5836
|
if (process.env.NODE_ENV !== "production") {
|
|
5801
5837
|
for (const f of fields) assertValidFieldDefinition(f);
|
|
5802
5838
|
}
|
|
@@ -5819,7 +5855,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
5819
5855
|
const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
|
|
5820
5856
|
const startEditing = (key) => setPanel({ kind: "edit", key });
|
|
5821
5857
|
const closeEditing = () => setPanel(null);
|
|
5822
|
-
|
|
5858
|
+
React33.useEffect(() => {
|
|
5823
5859
|
if (!panel || panel.kind !== "edit") return;
|
|
5824
5860
|
if (editingField?.type === "text") {
|
|
5825
5861
|
textInputRef.current?.focus();
|
|
@@ -6074,10 +6110,10 @@ function StatTile(props) {
|
|
|
6074
6110
|
}
|
|
6075
6111
|
|
|
6076
6112
|
// src/components/data/CodeBlock.tsx
|
|
6077
|
-
var
|
|
6113
|
+
var React35 = __toESM(require("react"), 1);
|
|
6078
6114
|
|
|
6079
6115
|
// src/kits/clipboard.ts
|
|
6080
|
-
var
|
|
6116
|
+
var React34 = __toESM(require("react"), 1);
|
|
6081
6117
|
var COPIED_FEEDBACK_MS = 1600;
|
|
6082
6118
|
function copyThroughSelection(text) {
|
|
6083
6119
|
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -6107,17 +6143,17 @@ async function copyToClipboard(text) {
|
|
|
6107
6143
|
return copyThroughSelection(text);
|
|
6108
6144
|
}
|
|
6109
6145
|
function useCopyToClipboard() {
|
|
6110
|
-
const [copied, setCopied] =
|
|
6111
|
-
const timer =
|
|
6112
|
-
const mounted =
|
|
6113
|
-
|
|
6146
|
+
const [copied, setCopied] = React34.useState(false);
|
|
6147
|
+
const timer = React34.useRef(null);
|
|
6148
|
+
const mounted = React34.useRef(true);
|
|
6149
|
+
React34.useEffect(() => {
|
|
6114
6150
|
mounted.current = true;
|
|
6115
6151
|
return () => {
|
|
6116
6152
|
mounted.current = false;
|
|
6117
6153
|
if (timer.current) clearTimeout(timer.current);
|
|
6118
6154
|
};
|
|
6119
6155
|
}, []);
|
|
6120
|
-
const copy =
|
|
6156
|
+
const copy = React34.useCallback(async (text) => {
|
|
6121
6157
|
const ok = await copyToClipboard(text);
|
|
6122
6158
|
if (ok && mounted.current) {
|
|
6123
6159
|
setCopied(true);
|
|
@@ -6285,7 +6321,7 @@ function tokenize(src, lang) {
|
|
|
6285
6321
|
return out;
|
|
6286
6322
|
}
|
|
6287
6323
|
function Highlighted({ code, lang }) {
|
|
6288
|
-
const toks =
|
|
6324
|
+
const toks = React35.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
6289
6325
|
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_jsx_runtime54.Fragment, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
|
|
6290
6326
|
}
|
|
6291
6327
|
function CodeBlock({
|
|
@@ -6299,8 +6335,8 @@ function CodeBlock({
|
|
|
6299
6335
|
actions,
|
|
6300
6336
|
className = ""
|
|
6301
6337
|
}) {
|
|
6302
|
-
const [wrap, setWrap] =
|
|
6303
|
-
const [open2, setOpen] =
|
|
6338
|
+
const [wrap, setWrap] = React35.useState(!!wrapDefault);
|
|
6339
|
+
const [open2, setOpen] = React35.useState(false);
|
|
6304
6340
|
const [copied, copy] = useCopyToClipboard();
|
|
6305
6341
|
const body = String(code).replace(/\n$/, "");
|
|
6306
6342
|
const lines = body.split("\n");
|
|
@@ -6329,7 +6365,7 @@ function CodeBlock({
|
|
|
6329
6365
|
] });
|
|
6330
6366
|
}
|
|
6331
6367
|
function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
|
|
6332
|
-
const [open2, setOpen] =
|
|
6368
|
+
const [open2, setOpen] = React35.useState(false);
|
|
6333
6369
|
const [copied, copy] = useCopyToClipboard();
|
|
6334
6370
|
const raw = String(diff).replace(/\n$/, "");
|
|
6335
6371
|
const all = raw.split("\n").map((line) => {
|
|
@@ -6375,7 +6411,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
6375
6411
|
}
|
|
6376
6412
|
|
|
6377
6413
|
// src/components/data/Markdown.tsx
|
|
6378
|
-
var
|
|
6414
|
+
var React36 = __toESM(require("react"), 1);
|
|
6379
6415
|
|
|
6380
6416
|
// src/components/data/markdownEscape.ts
|
|
6381
6417
|
var ESCAPABLE = /\\([!-/:-@[-`{-~])/g;
|
|
@@ -6448,7 +6484,7 @@ function hiddenInlineNodes(hidden, ctx, keyBase) {
|
|
|
6448
6484
|
const href = safeHref(d(g(2)));
|
|
6449
6485
|
out.push(href ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("a", { href, title: g(3) ? d(g(3)) : void 0, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: hiddenInlineNodes(g(1), ctx, key()) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { children: d(g(1)) }, key()));
|
|
6450
6486
|
} else if (kind === "cite") {
|
|
6451
|
-
out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6487
|
+
out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(React36.Fragment, { children: ctx.renderCitation(d(g(1))) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("sup", { className: "fd-md-cite", children: d(g(1)) }, key()));
|
|
6452
6488
|
} else if (kind === "strongem") out.push(/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("strong", { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("em", { children: hiddenInlineNodes(g(1), ctx, key()) }) }, key()));
|
|
6453
6489
|
else if (kind === "strong") out.push(/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("strong", { children: hiddenInlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
6454
6490
|
else if (kind === "em") out.push(/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("em", { children: hiddenInlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
@@ -6635,7 +6671,7 @@ function Markdown({
|
|
|
6635
6671
|
tone = "default"
|
|
6636
6672
|
}) {
|
|
6637
6673
|
const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
|
|
6638
|
-
const blocks =
|
|
6674
|
+
const blocks = React36.useMemo(() => parseBlocks(source), [source]);
|
|
6639
6675
|
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: mdClass("fd-md", size, tone, className), children: renderBlocks(blocks, ctx, "b") });
|
|
6640
6676
|
}
|
|
6641
6677
|
function MarkdownInline({ source = "", className = "", onLinkClick, size, tone }) {
|
|
@@ -6746,7 +6782,7 @@ function Pagination({
|
|
|
6746
6782
|
}
|
|
6747
6783
|
|
|
6748
6784
|
// src/components/data/RelativeTime.tsx
|
|
6749
|
-
var
|
|
6785
|
+
var React37 = __toESM(require("react"), 1);
|
|
6750
6786
|
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
6751
6787
|
var MIN = 6e4;
|
|
6752
6788
|
var HOUR = 36e5;
|
|
@@ -6798,9 +6834,9 @@ function formatDuration(ms) {
|
|
|
6798
6834
|
return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
|
|
6799
6835
|
}
|
|
6800
6836
|
function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
|
|
6801
|
-
const [, force] =
|
|
6837
|
+
const [, force] = React37.useState(0);
|
|
6802
6838
|
const t = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
6803
|
-
|
|
6839
|
+
React37.useEffect(() => {
|
|
6804
6840
|
if (!refresh2 || !t || isNaN(t)) return;
|
|
6805
6841
|
const abs2 = Math.abs(t - Date.now());
|
|
6806
6842
|
if (abs2 > DAY) return;
|
|
@@ -6816,7 +6852,7 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
|
|
|
6816
6852
|
}
|
|
6817
6853
|
|
|
6818
6854
|
// src/components/data/ScoreMeter.tsx
|
|
6819
|
-
var
|
|
6855
|
+
var React38 = __toESM(require("react"), 1);
|
|
6820
6856
|
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
6821
6857
|
function ScoreMeter({
|
|
6822
6858
|
score,
|
|
@@ -6831,10 +6867,10 @@ function ScoreMeter({
|
|
|
6831
6867
|
breakdownWidth = 280,
|
|
6832
6868
|
className = ""
|
|
6833
6869
|
}) {
|
|
6834
|
-
const [open2, setOpen] =
|
|
6835
|
-
const ref =
|
|
6870
|
+
const [open2, setOpen] = React38.useState(false);
|
|
6871
|
+
const ref = React38.useRef(null);
|
|
6836
6872
|
const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
6837
|
-
const body = /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
|
|
6873
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(React38.Fragment, { children: [
|
|
6838
6874
|
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
|
|
6839
6875
|
showScore ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
|
|
6840
6876
|
] });
|
|
@@ -6853,7 +6889,7 @@ function ScoreMeter({
|
|
|
6853
6889
|
}
|
|
6854
6890
|
);
|
|
6855
6891
|
}
|
|
6856
|
-
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
|
|
6892
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(React38.Fragment, { children: [
|
|
6857
6893
|
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
6858
6894
|
"button",
|
|
6859
6895
|
{
|
|
@@ -6884,11 +6920,11 @@ function ScoreMeter({
|
|
|
6884
6920
|
}
|
|
6885
6921
|
|
|
6886
6922
|
// src/components/actions/inlinePanel.tsx
|
|
6887
|
-
var
|
|
6923
|
+
var React39 = __toESM(require("react"), 1);
|
|
6888
6924
|
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
6889
6925
|
function useInlinePanel() {
|
|
6890
|
-
const [open2, setOpen] =
|
|
6891
|
-
const ref =
|
|
6926
|
+
const [open2, setOpen] = React39.useState(false);
|
|
6927
|
+
const ref = React39.useRef(null);
|
|
6892
6928
|
return { open: open2, setOpen, ref };
|
|
6893
6929
|
}
|
|
6894
6930
|
function InlinePanelSurface({ panel, align = "right", ...popover }) {
|
|
@@ -7059,7 +7095,7 @@ function SortMenu({
|
|
|
7059
7095
|
}
|
|
7060
7096
|
|
|
7061
7097
|
// src/components/data/StepList.tsx
|
|
7062
|
-
var
|
|
7098
|
+
var React40 = __toESM(require("react"), 1);
|
|
7063
7099
|
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
7064
7100
|
var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
|
|
7065
7101
|
function StepList({
|
|
@@ -7073,9 +7109,9 @@ function StepList({
|
|
|
7073
7109
|
className = "",
|
|
7074
7110
|
active = false
|
|
7075
7111
|
}) {
|
|
7076
|
-
const [openState, setOpenState] =
|
|
7112
|
+
const [openState, setOpenState] = React40.useState(defaultOpen);
|
|
7077
7113
|
const open2 = openProp == null ? openState : openProp;
|
|
7078
|
-
const [expanded, setExpanded] =
|
|
7114
|
+
const [expanded, setExpanded] = React40.useState({});
|
|
7079
7115
|
if (!steps.length) return null;
|
|
7080
7116
|
const running = steps.some((s) => s.status === "running");
|
|
7081
7117
|
const failed = steps.filter((s) => s.status === "error").length;
|
|
@@ -7133,7 +7169,7 @@ function StepList({
|
|
|
7133
7169
|
}
|
|
7134
7170
|
|
|
7135
7171
|
// src/components/data/VirtualList.tsx
|
|
7136
|
-
var
|
|
7172
|
+
var React41 = __toESM(require("react"), 1);
|
|
7137
7173
|
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
7138
7174
|
var VIRTUAL_LIST_BUFFER_ROWS = 20;
|
|
7139
7175
|
var VIRTUAL_LIST_ROW_GAP = 6;
|
|
@@ -7185,35 +7221,35 @@ function VirtualList({
|
|
|
7185
7221
|
className = "",
|
|
7186
7222
|
style
|
|
7187
7223
|
}) {
|
|
7188
|
-
const [scrollTop, setScrollTop] =
|
|
7189
|
-
const loaded =
|
|
7224
|
+
const [scrollTop, setScrollTop] = React41.useState(0);
|
|
7225
|
+
const loaded = React41.useMemo(
|
|
7190
7226
|
() => ({ firstItemIndex, count: items.length }),
|
|
7191
7227
|
[firstItemIndex, items.length]
|
|
7192
7228
|
);
|
|
7193
7229
|
const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
|
|
7194
7230
|
const bandKey = firstItemIndex + ":" + items.length;
|
|
7195
|
-
const win =
|
|
7231
|
+
const win = React41.useMemo(
|
|
7196
7232
|
() => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
|
|
7197
7233
|
[scrollTop, height, itemHeight, total, loaded]
|
|
7198
7234
|
);
|
|
7199
|
-
const need =
|
|
7235
|
+
const need = React41.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
|
|
7200
7236
|
const wantStart = need.start && hasMore?.start !== false;
|
|
7201
7237
|
const wantEnd = need.end && hasMore?.end !== false;
|
|
7202
7238
|
const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
|
|
7203
7239
|
const askKey = bandKey + "@" + bucket2;
|
|
7204
|
-
const asked =
|
|
7205
|
-
|
|
7240
|
+
const asked = React41.useRef({ start: null, end: null });
|
|
7241
|
+
React41.useEffect(() => {
|
|
7206
7242
|
if (loading || !wantStart || asked.current.start === askKey) return;
|
|
7207
7243
|
asked.current.start = askKey;
|
|
7208
7244
|
onNeedMore("start", win);
|
|
7209
7245
|
}, [wantStart, loading, askKey, onNeedMore, win]);
|
|
7210
|
-
|
|
7246
|
+
React41.useEffect(() => {
|
|
7211
7247
|
if (loading || !wantEnd || asked.current.end === askKey) return;
|
|
7212
7248
|
asked.current.end = askKey;
|
|
7213
7249
|
onNeedMore("end", win);
|
|
7214
7250
|
}, [wantEnd, loading, askKey, onNeedMore, win]);
|
|
7215
|
-
const lastKeysRef =
|
|
7216
|
-
const newKeys =
|
|
7251
|
+
const lastKeysRef = React41.useRef(null);
|
|
7252
|
+
const newKeys = React41.useMemo(() => {
|
|
7217
7253
|
const prev = lastKeysRef.current;
|
|
7218
7254
|
if (!prev) return /* @__PURE__ */ new Set();
|
|
7219
7255
|
const fresh = /* @__PURE__ */ new Set();
|
|
@@ -7223,7 +7259,7 @@ function VirtualList({
|
|
|
7223
7259
|
}
|
|
7224
7260
|
return fresh;
|
|
7225
7261
|
}, [items]);
|
|
7226
|
-
|
|
7262
|
+
React41.useEffect(() => {
|
|
7227
7263
|
lastKeysRef.current = new Set(items.map(keyOf));
|
|
7228
7264
|
}, [items]);
|
|
7229
7265
|
const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
|
|
@@ -7268,7 +7304,7 @@ function VirtualList({
|
|
|
7268
7304
|
}
|
|
7269
7305
|
|
|
7270
7306
|
// src/components/data/EntityRow.tsx
|
|
7271
|
-
var
|
|
7307
|
+
var React42 = __toESM(require("react"), 1);
|
|
7272
7308
|
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
7273
7309
|
var ENTITY_ROW_METRIC_WIDTH = 74;
|
|
7274
7310
|
var METRIC_TONE_COLOR = {
|
|
@@ -7281,7 +7317,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
|
|
|
7281
7317
|
const key = m.id || m.label || i;
|
|
7282
7318
|
const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
|
|
7283
7319
|
const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
|
|
7284
|
-
const content = /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
|
|
7320
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(React42.Fragment, { children: [
|
|
7285
7321
|
m.icon ? /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
|
|
7286
7322
|
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
|
|
7287
7323
|
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "fd-sr", children: " " + m.label })
|
|
@@ -7373,7 +7409,7 @@ function EntityRow({
|
|
|
7373
7409
|
}
|
|
7374
7410
|
|
|
7375
7411
|
// src/components/data/TransferList.tsx
|
|
7376
|
-
var
|
|
7412
|
+
var React43 = __toESM(require("react"), 1);
|
|
7377
7413
|
var import_react_dom6 = require("react-dom");
|
|
7378
7414
|
|
|
7379
7415
|
// src/components/forms/Input.tsx
|
|
@@ -7479,12 +7515,12 @@ function TransferList({
|
|
|
7479
7515
|
listHeight = 440,
|
|
7480
7516
|
className = ""
|
|
7481
7517
|
}) {
|
|
7482
|
-
const [drag, setDrag] =
|
|
7483
|
-
const [dragOverSide, setDragOverSide] =
|
|
7484
|
-
const dragRef =
|
|
7485
|
-
const armedRef =
|
|
7486
|
-
const sideRefs =
|
|
7487
|
-
const hitTestSide =
|
|
7518
|
+
const [drag, setDrag] = React43.useState(null);
|
|
7519
|
+
const [dragOverSide, setDragOverSide] = React43.useState(null);
|
|
7520
|
+
const dragRef = React43.useRef(null);
|
|
7521
|
+
const armedRef = React43.useRef(null);
|
|
7522
|
+
const sideRefs = React43.useRef({ left: null, right: null });
|
|
7523
|
+
const hitTestSide = React43.useCallback((x, y) => {
|
|
7488
7524
|
for (const side of ["left", "right"]) {
|
|
7489
7525
|
const el = sideRefs.current[side];
|
|
7490
7526
|
if (!el) continue;
|
|
@@ -7493,7 +7529,7 @@ function TransferList({
|
|
|
7493
7529
|
}
|
|
7494
7530
|
return null;
|
|
7495
7531
|
}, []);
|
|
7496
|
-
const findItem =
|
|
7532
|
+
const findItem = React43.useCallback(
|
|
7497
7533
|
(side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
|
|
7498
7534
|
[left.items, right.items, keyOf]
|
|
7499
7535
|
);
|
|
@@ -7515,7 +7551,7 @@ function TransferList({
|
|
|
7515
7551
|
height: rect.height
|
|
7516
7552
|
};
|
|
7517
7553
|
};
|
|
7518
|
-
|
|
7554
|
+
React43.useEffect(() => {
|
|
7519
7555
|
const onMovePointer = (e) => {
|
|
7520
7556
|
const armed = armedRef.current;
|
|
7521
7557
|
if (!armed || e.pointerId !== armed.pointerId) return;
|
|
@@ -7568,7 +7604,7 @@ function TransferList({
|
|
|
7568
7604
|
window.removeEventListener("pointercancel", endDrag);
|
|
7569
7605
|
};
|
|
7570
7606
|
}, [hitTestSide, findItem, onMove]);
|
|
7571
|
-
|
|
7607
|
+
React43.useEffect(() => {
|
|
7572
7608
|
if (!drag || typeof document === "undefined") return;
|
|
7573
7609
|
const prev = document.body.style.userSelect;
|
|
7574
7610
|
document.body.style.userSelect = "none";
|
|
@@ -7685,7 +7721,7 @@ function FactList({ facts = [], className = "", ...rest }) {
|
|
|
7685
7721
|
}
|
|
7686
7722
|
|
|
7687
7723
|
// src/components/data/USChoropleth.tsx
|
|
7688
|
-
var
|
|
7724
|
+
var React45 = __toESM(require("react"), 1);
|
|
7689
7725
|
init_usStates();
|
|
7690
7726
|
|
|
7691
7727
|
// src/components/data/usChoropleth/mapBox.ts
|
|
@@ -7752,11 +7788,11 @@ function buildChoroplethModel(values, topN, givenTotal) {
|
|
|
7752
7788
|
}
|
|
7753
7789
|
|
|
7754
7790
|
// src/components/data/usChoropleth/useUsStateShapes.ts
|
|
7755
|
-
var
|
|
7791
|
+
var React44 = __toESM(require("react"), 1);
|
|
7756
7792
|
function useUsStateShapes() {
|
|
7757
|
-
const [token, setToken] =
|
|
7758
|
-
const [settled, setSettled] =
|
|
7759
|
-
|
|
7793
|
+
const [token, setToken] = React44.useState(0);
|
|
7794
|
+
const [settled, setSettled] = React44.useState(null);
|
|
7795
|
+
React44.useEffect(() => {
|
|
7760
7796
|
let current2 = true;
|
|
7761
7797
|
Promise.resolve().then(() => (init_usStateShapes(), usStateShapes_exports)).then(({ STATE_SHAPES: STATE_SHAPES2 }) => {
|
|
7762
7798
|
if (current2) setSettled({ token, state: { status: "ready", shapes: STATE_SHAPES2 } });
|
|
@@ -7798,7 +7834,7 @@ function nextCode(key, from) {
|
|
|
7798
7834
|
}
|
|
7799
7835
|
function StateMap({ shapes, model, figures, label, formatReadout }) {
|
|
7800
7836
|
const tip = useTooltip();
|
|
7801
|
-
const [stop, setStop] =
|
|
7837
|
+
const [stop, setStop] = React45.useState(US_STATE_CODES[0]);
|
|
7802
7838
|
const onKeyDown = (event) => {
|
|
7803
7839
|
const from = event.target.getAttribute("data-state");
|
|
7804
7840
|
const to = from && nextCode(event.key, from);
|
|
@@ -7846,8 +7882,8 @@ function StateTable({ model, valueLabel, formatValue }) {
|
|
|
7846
7882
|
return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Collapsible, { title: TABLE_TITLE, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(DataTable, { columns, rows: model.rows, rowKey: "code", compact: true }) });
|
|
7847
7883
|
}
|
|
7848
7884
|
function USChoropleth({ values, label, valueLabel, formatValue, formatReadout, topN, total, className = "" }) {
|
|
7849
|
-
const model =
|
|
7850
|
-
const figures =
|
|
7885
|
+
const model = React45.useMemo(() => buildChoroplethModel(values, topN ?? 0, total), [values, topN, total]);
|
|
7886
|
+
const figures = React45.useMemo(() => new Map(model.rows.map((row) => [row.code, row])), [model]);
|
|
7851
7887
|
const { state, retry } = useUsStateShapes();
|
|
7852
7888
|
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: ["fd-uschoro", className].filter(Boolean).join(" "), children: [
|
|
7853
7889
|
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "fd-uschoro-layout", children: [
|
|
@@ -7885,11 +7921,11 @@ function USChoropleth({ values, label, valueLabel, formatValue, formatReadout, t
|
|
|
7885
7921
|
init_usStates();
|
|
7886
7922
|
|
|
7887
7923
|
// src/components/forms/Checkbox.tsx
|
|
7888
|
-
var
|
|
7924
|
+
var React46 = __toESM(require("react"), 1);
|
|
7889
7925
|
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
7890
7926
|
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
7891
|
-
const ref =
|
|
7892
|
-
|
|
7927
|
+
const ref = React46.useRef(null);
|
|
7928
|
+
React46.useEffect(() => {
|
|
7893
7929
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
7894
7930
|
}, [indeterminate]);
|
|
7895
7931
|
return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
@@ -7936,7 +7972,7 @@ function Switch({ label, description, className = "", ...rest }) {
|
|
|
7936
7972
|
}
|
|
7937
7973
|
|
|
7938
7974
|
// src/components/forms/Select.tsx
|
|
7939
|
-
var
|
|
7975
|
+
var React47 = __toESM(require("react"), 1);
|
|
7940
7976
|
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
7941
7977
|
var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
|
|
7942
7978
|
function Select({
|
|
@@ -7964,12 +8000,12 @@ function Select({
|
|
|
7964
8000
|
const isOn = (v) => multiple ? vals.includes(v) : v === value;
|
|
7965
8001
|
const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
|
|
7966
8002
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
|
|
7967
|
-
const [open2, setOpen] =
|
|
7968
|
-
const [q, setQ] =
|
|
7969
|
-
const rootRef =
|
|
7970
|
-
const boxRef =
|
|
7971
|
-
const listRef =
|
|
7972
|
-
const typeBuf =
|
|
8003
|
+
const [open2, setOpen] = React47.useState(false);
|
|
8004
|
+
const [q, setQ] = React47.useState("");
|
|
8005
|
+
const rootRef = React47.useRef(null);
|
|
8006
|
+
const boxRef = React47.useRef(null);
|
|
8007
|
+
const listRef = React47.useRef(null);
|
|
8008
|
+
const typeBuf = React47.useRef({ s: "", t: 0 });
|
|
7973
8009
|
const selected = multiple ? null : opts.find((o) => o.value === value);
|
|
7974
8010
|
const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
|
|
7975
8011
|
const boxText = multiple ? chosen.length === 0 ? placeholder : chosen.length === 1 ? chosen[0].label : summary ? summary(chosen.map((o) => o.value)) : chosen.length + " selected" : selected ? selected.label : placeholder;
|
|
@@ -8105,7 +8141,7 @@ function Select({
|
|
|
8105
8141
|
),
|
|
8106
8142
|
q ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
|
|
8107
8143
|
] }) : void 0,
|
|
8108
|
-
footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
|
|
8144
|
+
footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(React47.Fragment, { children: [
|
|
8109
8145
|
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
|
|
8110
8146
|
"button",
|
|
8111
8147
|
{
|
|
@@ -8136,7 +8172,7 @@ function Select({
|
|
|
8136
8172
|
'Nothing matches "',
|
|
8137
8173
|
q,
|
|
8138
8174
|
'".'
|
|
8139
|
-
] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
|
|
8175
|
+
] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(React47.Fragment, { children: [
|
|
8140
8176
|
grp.g ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "fd-pop-group", children: grp.g }) : null,
|
|
8141
8177
|
grp.items.map(({ o, i }) => /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
|
|
8142
8178
|
"button",
|
|
@@ -8173,7 +8209,7 @@ function Select({
|
|
|
8173
8209
|
}
|
|
8174
8210
|
|
|
8175
8211
|
// src/components/forms/TimePicker.tsx
|
|
8176
|
-
var
|
|
8212
|
+
var React48 = __toESM(require("react"), 1);
|
|
8177
8213
|
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
8178
8214
|
var pad = (n) => String(n).padStart(2, "0");
|
|
8179
8215
|
function ClockFace({ value = "09:00", onChange }) {
|
|
@@ -8182,9 +8218,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
8182
8218
|
if (isNaN(m)) m = 0;
|
|
8183
8219
|
const pm = h24 >= 12;
|
|
8184
8220
|
const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
|
|
8185
|
-
const [mode2, setMode] =
|
|
8186
|
-
const faceRef =
|
|
8187
|
-
const dragging =
|
|
8221
|
+
const [mode2, setMode] = React48.useState("h");
|
|
8222
|
+
const faceRef = React48.useRef(null);
|
|
8223
|
+
const dragging = React48.useRef(false);
|
|
8188
8224
|
const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
|
|
8189
8225
|
const R = 108, NR = 80;
|
|
8190
8226
|
const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
|
|
@@ -8257,9 +8293,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
8257
8293
|
}
|
|
8258
8294
|
function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
|
|
8259
8295
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
8260
|
-
const [open2, setOpen] =
|
|
8261
|
-
const rootRef =
|
|
8262
|
-
const boxRef =
|
|
8296
|
+
const [open2, setOpen] = React48.useState(false);
|
|
8297
|
+
const rootRef = React48.useRef(null);
|
|
8298
|
+
const boxRef = React48.useRef(null);
|
|
8263
8299
|
const disp = () => {
|
|
8264
8300
|
if (!value) return "";
|
|
8265
8301
|
const [h, m] = value.split(":").map(Number);
|
|
@@ -8302,7 +8338,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
8302
8338
|
offset: 6,
|
|
8303
8339
|
width: 262,
|
|
8304
8340
|
role: "presentation",
|
|
8305
|
-
footer: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
|
|
8341
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(React48.Fragment, { children: [
|
|
8306
8342
|
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
8307
8343
|
"button",
|
|
8308
8344
|
{
|
|
@@ -8330,7 +8366,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
8330
8366
|
}
|
|
8331
8367
|
|
|
8332
8368
|
// src/components/forms/Slider.tsx
|
|
8333
|
-
var
|
|
8369
|
+
var React49 = __toESM(require("react"), 1);
|
|
8334
8370
|
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
8335
8371
|
function Slider({
|
|
8336
8372
|
label,
|
|
@@ -8348,7 +8384,7 @@ function Slider({
|
|
|
8348
8384
|
...rest
|
|
8349
8385
|
}) {
|
|
8350
8386
|
const fieldId = useFieldId(id);
|
|
8351
|
-
const [dragging, setDragging] =
|
|
8387
|
+
const [dragging, setDragging] = React49.useState(false);
|
|
8352
8388
|
const v = value === void 0 ? min : Number(value);
|
|
8353
8389
|
const pct = max === min ? 0 : (v - min) / (max - min) * 100;
|
|
8354
8390
|
return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
|
|
@@ -8382,7 +8418,7 @@ function Slider({
|
|
|
8382
8418
|
}
|
|
8383
8419
|
|
|
8384
8420
|
// src/components/forms/RangeSlider.tsx
|
|
8385
|
-
var
|
|
8421
|
+
var React50 = __toESM(require("react"), 1);
|
|
8386
8422
|
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
8387
8423
|
function RangeSlider({
|
|
8388
8424
|
label,
|
|
@@ -8402,9 +8438,9 @@ function RangeSlider({
|
|
|
8402
8438
|
}) {
|
|
8403
8439
|
const fmt2 = format || ((v) => String(v));
|
|
8404
8440
|
const [a, b] = value || [min, max];
|
|
8405
|
-
const [drag, setDrag] =
|
|
8406
|
-
const [focus, setFocus] =
|
|
8407
|
-
const railRef =
|
|
8441
|
+
const [drag, setDrag] = React50.useState(null);
|
|
8442
|
+
const [focus, setFocus] = React50.useState(null);
|
|
8443
|
+
const railRef = React50.useRef(null);
|
|
8408
8444
|
const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
|
|
8409
8445
|
const clampPair = (i, v) => {
|
|
8410
8446
|
v = Math.min(max, Math.max(min, Math.round(v / step) * step));
|
|
@@ -8419,7 +8455,7 @@ function RangeSlider({
|
|
|
8419
8455
|
const r = railRef.current.getBoundingClientRect();
|
|
8420
8456
|
return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
|
|
8421
8457
|
};
|
|
8422
|
-
|
|
8458
|
+
React50.useEffect(() => {
|
|
8423
8459
|
if (drag === null) return;
|
|
8424
8460
|
const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
|
|
8425
8461
|
const upH = () => setDrag(null);
|
|
@@ -8500,7 +8536,7 @@ function RangeSlider({
|
|
|
8500
8536
|
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
|
|
8501
8537
|
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "fd-range-rail", ref: railRef }),
|
|
8502
8538
|
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
|
|
8503
|
-
marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
8539
|
+
marks.map((m) => /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(React50.Fragment, { children: [
|
|
8504
8540
|
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
|
|
8505
8541
|
m.label ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
|
|
8506
8542
|
] }, m.value)),
|
|
@@ -8529,7 +8565,7 @@ function RangeSlider({
|
|
|
8529
8565
|
}
|
|
8530
8566
|
|
|
8531
8567
|
// src/components/forms/Dropzone.tsx
|
|
8532
|
-
var
|
|
8568
|
+
var React51 = __toESM(require("react"), 1);
|
|
8533
8569
|
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
8534
8570
|
function Dropzone({
|
|
8535
8571
|
onFiles,
|
|
@@ -8544,8 +8580,8 @@ function Dropzone({
|
|
|
8544
8580
|
className = "",
|
|
8545
8581
|
style
|
|
8546
8582
|
}) {
|
|
8547
|
-
const [over, setOver] =
|
|
8548
|
-
const depth =
|
|
8583
|
+
const [over, setOver] = React51.useState(false);
|
|
8584
|
+
const depth = React51.useRef(0);
|
|
8549
8585
|
const has = (e) => {
|
|
8550
8586
|
const dt = e.dataTransfer;
|
|
8551
8587
|
if (!dt) return false;
|
|
@@ -8607,8 +8643,8 @@ function FilePickButton({
|
|
|
8607
8643
|
className = "",
|
|
8608
8644
|
children
|
|
8609
8645
|
}) {
|
|
8610
|
-
const ref =
|
|
8611
|
-
return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
|
|
8646
|
+
const ref = React51.useRef(null);
|
|
8647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(React51.Fragment, { children: [
|
|
8612
8648
|
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
8613
8649
|
"button",
|
|
8614
8650
|
{
|
|
@@ -8641,10 +8677,10 @@ function FilePickButton({
|
|
|
8641
8677
|
}
|
|
8642
8678
|
function useStagedFiles(upload, opts) {
|
|
8643
8679
|
const o = opts || {};
|
|
8644
|
-
const [items, setItems] =
|
|
8645
|
-
const controllers =
|
|
8680
|
+
const [items, setItems] = React51.useState([]);
|
|
8681
|
+
const controllers = React51.useRef({});
|
|
8646
8682
|
const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
|
|
8647
|
-
const run =
|
|
8683
|
+
const run = React51.useCallback((att) => {
|
|
8648
8684
|
if (!upload) return;
|
|
8649
8685
|
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
8650
8686
|
controllers.current[att.id] = ac;
|
|
@@ -8661,14 +8697,14 @@ function useStagedFiles(upload, opts) {
|
|
|
8661
8697
|
delete controllers.current[att.id];
|
|
8662
8698
|
});
|
|
8663
8699
|
}, [upload]);
|
|
8664
|
-
const add =
|
|
8700
|
+
const add = React51.useCallback((files) => {
|
|
8665
8701
|
if (!upload) return [];
|
|
8666
8702
|
const atts = Array.from(files).map((f) => toAttachment(f));
|
|
8667
8703
|
setItems((list) => list.concat(atts));
|
|
8668
8704
|
atts.forEach(run);
|
|
8669
8705
|
return atts;
|
|
8670
8706
|
}, [upload, run]);
|
|
8671
|
-
const remove =
|
|
8707
|
+
const remove = React51.useCallback((att) => {
|
|
8672
8708
|
const ac = controllers.current[att.id];
|
|
8673
8709
|
if (ac) {
|
|
8674
8710
|
try {
|
|
@@ -8679,10 +8715,10 @@ function useStagedFiles(upload, opts) {
|
|
|
8679
8715
|
}
|
|
8680
8716
|
setItems((list) => list.filter((f) => f.id !== att.id));
|
|
8681
8717
|
}, []);
|
|
8682
|
-
const retry =
|
|
8718
|
+
const retry = React51.useCallback((att) => {
|
|
8683
8719
|
run(att);
|
|
8684
8720
|
}, [run]);
|
|
8685
|
-
const clear =
|
|
8721
|
+
const clear = React51.useCallback(() => {
|
|
8686
8722
|
Object.values(controllers.current).forEach((ac) => {
|
|
8687
8723
|
try {
|
|
8688
8724
|
ac && ac.abort();
|
|
@@ -8806,7 +8842,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
|
|
|
8806
8842
|
}
|
|
8807
8843
|
|
|
8808
8844
|
// src/components/forms/MarkdownEditor.tsx
|
|
8809
|
-
var
|
|
8845
|
+
var React52 = __toESM(require("react"), 1);
|
|
8810
8846
|
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
8811
8847
|
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
|
|
8812
8848
|
var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
|
|
@@ -9020,7 +9056,7 @@ function syncDom(root, value) {
|
|
|
9020
9056
|
while (root.children.length > lines.length) root.removeChild(root.lastChild);
|
|
9021
9057
|
}
|
|
9022
9058
|
var LIST_CONT = RE_LI;
|
|
9023
|
-
var MarkdownEditor =
|
|
9059
|
+
var MarkdownEditor = React52.forwardRef(function MarkdownEditor2({
|
|
9024
9060
|
value = "",
|
|
9025
9061
|
onChange,
|
|
9026
9062
|
onSubmit,
|
|
@@ -9039,10 +9075,10 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
9039
9075
|
className = "",
|
|
9040
9076
|
id
|
|
9041
9077
|
}, ref) {
|
|
9042
|
-
const boxRef =
|
|
9043
|
-
const composing =
|
|
9044
|
-
const pendingCaret =
|
|
9045
|
-
|
|
9078
|
+
const boxRef = React52.useRef(null);
|
|
9079
|
+
const composing = React52.useRef(false);
|
|
9080
|
+
const pendingCaret = React52.useRef(null);
|
|
9081
|
+
React52.useLayoutEffect(() => {
|
|
9046
9082
|
const root = boxRef.current;
|
|
9047
9083
|
if (!root || composing.current) return;
|
|
9048
9084
|
const active = document.activeElement === root || root.contains(document.activeElement);
|
|
@@ -9051,7 +9087,7 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
9051
9087
|
pendingCaret.current = null;
|
|
9052
9088
|
if (active && caret != null) placeCaret(root, caret);
|
|
9053
9089
|
}, [value]);
|
|
9054
|
-
|
|
9090
|
+
React52.useEffect(() => {
|
|
9055
9091
|
if (autoFocus && boxRef.current) boxRef.current.focus();
|
|
9056
9092
|
}, [autoFocus]);
|
|
9057
9093
|
const caretNow = () => {
|
|
@@ -9118,8 +9154,8 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
9118
9154
|
api.replaceRange(from, to, next, from + next.length);
|
|
9119
9155
|
}
|
|
9120
9156
|
};
|
|
9121
|
-
|
|
9122
|
-
const caretAtKeydown =
|
|
9157
|
+
React52.useImperativeHandle(ref, () => api);
|
|
9158
|
+
const caretAtKeydown = React52.useRef(-1);
|
|
9123
9159
|
function detect(text, caret) {
|
|
9124
9160
|
if (!onTrigger) return;
|
|
9125
9161
|
const upto = text.slice(0, caret);
|
|
@@ -9272,7 +9308,7 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
9272
9308
|
});
|
|
9273
9309
|
|
|
9274
9310
|
// src/components/forms/CodeEditor.tsx
|
|
9275
|
-
var
|
|
9311
|
+
var React53 = __toESM(require("react"), 1);
|
|
9276
9312
|
var import_view = require("@codemirror/view");
|
|
9277
9313
|
var import_state = require("@codemirror/state");
|
|
9278
9314
|
var import_commands = require("@codemirror/commands");
|
|
@@ -9376,16 +9412,16 @@ function CodeEditor({
|
|
|
9376
9412
|
const fieldId = useFieldId(id);
|
|
9377
9413
|
const descId = fieldId + "-desc";
|
|
9378
9414
|
const liveId = fieldId + "-live";
|
|
9379
|
-
const hostRef =
|
|
9380
|
-
const viewRef =
|
|
9381
|
-
const valueRef =
|
|
9382
|
-
const onChangeRef =
|
|
9415
|
+
const hostRef = React53.useRef(null);
|
|
9416
|
+
const viewRef = React53.useRef(null);
|
|
9417
|
+
const valueRef = React53.useRef(value);
|
|
9418
|
+
const onChangeRef = React53.useRef(onChange);
|
|
9383
9419
|
onChangeRef.current = onChange;
|
|
9384
|
-
const editableCompartment =
|
|
9385
|
-
const attributesCompartment =
|
|
9386
|
-
const errorRef =
|
|
9420
|
+
const editableCompartment = React53.useRef(new import_state.Compartment()).current;
|
|
9421
|
+
const attributesCompartment = React53.useRef(new import_state.Compartment()).current;
|
|
9422
|
+
const errorRef = React53.useRef(error);
|
|
9387
9423
|
errorRef.current = error;
|
|
9388
|
-
const diagnosticsCountRef =
|
|
9424
|
+
const diagnosticsCountRef = React53.useRef(diagnostics.length);
|
|
9389
9425
|
diagnosticsCountRef.current = diagnostics.length;
|
|
9390
9426
|
function contentAttributes() {
|
|
9391
9427
|
return {
|
|
@@ -9395,7 +9431,7 @@ function CodeEditor({
|
|
|
9395
9431
|
...label ? { "aria-label": label } : {}
|
|
9396
9432
|
};
|
|
9397
9433
|
}
|
|
9398
|
-
|
|
9434
|
+
React53.useEffect(() => {
|
|
9399
9435
|
const host2 = hostRef.current;
|
|
9400
9436
|
if (!host2) return;
|
|
9401
9437
|
const updateListener = import_view.EditorView.updateListener.of((update) => {
|
|
@@ -9437,7 +9473,7 @@ function CodeEditor({
|
|
|
9437
9473
|
viewRef.current = null;
|
|
9438
9474
|
};
|
|
9439
9475
|
}, []);
|
|
9440
|
-
|
|
9476
|
+
React53.useEffect(() => {
|
|
9441
9477
|
const view = viewRef.current;
|
|
9442
9478
|
if (!view) return;
|
|
9443
9479
|
const current2 = view.state.doc.toString();
|
|
@@ -9446,12 +9482,12 @@ function CodeEditor({
|
|
|
9446
9482
|
}
|
|
9447
9483
|
valueRef.current = value;
|
|
9448
9484
|
}, [value]);
|
|
9449
|
-
|
|
9485
|
+
React53.useEffect(() => {
|
|
9450
9486
|
const view = viewRef.current;
|
|
9451
9487
|
if (!view) return;
|
|
9452
9488
|
view.dispatch({ effects: editableCompartment.reconfigure(import_view.EditorView.editable.of(!disabled)) });
|
|
9453
9489
|
}, [disabled, editableCompartment]);
|
|
9454
|
-
|
|
9490
|
+
React53.useEffect(() => {
|
|
9455
9491
|
const view = viewRef.current;
|
|
9456
9492
|
if (!view) return;
|
|
9457
9493
|
view.dispatch({
|
|
@@ -9509,11 +9545,11 @@ function CodeEditor({
|
|
|
9509
9545
|
}
|
|
9510
9546
|
|
|
9511
9547
|
// src/components/forms/RadioGroup.tsx
|
|
9512
|
-
var
|
|
9548
|
+
var React54 = __toESM(require("react"), 1);
|
|
9513
9549
|
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
9514
9550
|
function RadioGroup({ label, labelledBy, options, value, onChange, card = false, disabled = false, name, className = "" }) {
|
|
9515
|
-
const autoName =
|
|
9516
|
-
const labelId =
|
|
9551
|
+
const autoName = React54.useId();
|
|
9552
|
+
const labelId = React54.useId();
|
|
9517
9553
|
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { role: "radiogroup", "aria-labelledby": labelledBy ?? labelId, "aria-disabled": disabled || void 0, className: ["fd-radiogroup", className].filter(Boolean).join(" "), children: [
|
|
9518
9554
|
labelledBy === void 0 && /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { id: labelId, className: "fd-radiogroup-label", children: label }),
|
|
9519
9555
|
options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
@@ -9541,16 +9577,16 @@ function Fieldset({ busy = false, className = "", ...rest }) {
|
|
|
9541
9577
|
}
|
|
9542
9578
|
|
|
9543
9579
|
// src/components/platform/AccountMenu.tsx
|
|
9544
|
-
var
|
|
9580
|
+
var React56 = __toESM(require("react"), 1);
|
|
9545
9581
|
|
|
9546
9582
|
// src/kits/sessionContext.tsx
|
|
9547
|
-
var
|
|
9548
|
-
var SessionContext =
|
|
9583
|
+
var React55 = __toESM(require("react"), 1);
|
|
9584
|
+
var SessionContext = React55.createContext(null);
|
|
9549
9585
|
function SessionProvider({ value, children }) {
|
|
9550
|
-
return
|
|
9586
|
+
return React55.createElement(SessionContext.Provider, { value }, children);
|
|
9551
9587
|
}
|
|
9552
9588
|
function useSessionContext() {
|
|
9553
|
-
const ctx =
|
|
9589
|
+
const ctx = React55.useContext(SessionContext);
|
|
9554
9590
|
if (!ctx) {
|
|
9555
9591
|
throw new Error(
|
|
9556
9592
|
"useSessionContext() was called outside a <SessionProvider>. Wrap your app root in <SessionProvider value={...}> with your real session, or \u2014 in the docs site or a demo \u2014 in <DemoSessionProvider>, before rendering AccountMenu, Gate, ProfilePage or AppSwitcher."
|
|
@@ -9590,11 +9626,11 @@ function AccountMenu({
|
|
|
9590
9626
|
...rest
|
|
9591
9627
|
}) {
|
|
9592
9628
|
const { user, roles, can: can2, signOut: ctxSignOut, demo, pending } = useSessionContext();
|
|
9593
|
-
const [open2, setOpen] =
|
|
9594
|
-
const [switching, setSwitching] =
|
|
9595
|
-
const [signingOut, setSigningOut] =
|
|
9596
|
-
const [signOutError, setSignOutError] =
|
|
9597
|
-
const ref =
|
|
9629
|
+
const [open2, setOpen] = React56.useState(false);
|
|
9630
|
+
const [switching, setSwitching] = React56.useState(false);
|
|
9631
|
+
const [signingOut, setSigningOut] = React56.useState(false);
|
|
9632
|
+
const [signOutError, setSignOutError] = React56.useState(null);
|
|
9633
|
+
const ref = React56.useRef(null);
|
|
9598
9634
|
const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
|
|
9599
9635
|
const visibleGroups = groups.map((g) => ({ label: g.label, links: g.links.filter((l) => !l.perm || !pending && can2(l.perm)) })).filter((g) => g.links.length);
|
|
9600
9636
|
const closeMenu = () => {
|
|
@@ -9719,13 +9755,13 @@ function AccountMenu({
|
|
|
9719
9755
|
}
|
|
9720
9756
|
|
|
9721
9757
|
// src/components/platform/AppSwitcher.tsx
|
|
9722
|
-
var
|
|
9758
|
+
var React57 = __toESM(require("react"), 1);
|
|
9723
9759
|
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
9724
9760
|
function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
9725
9761
|
const { apps: contextApps } = useSessionContext();
|
|
9726
9762
|
const apps = appsProp ?? contextApps ?? [];
|
|
9727
|
-
const [open2, setOpen] =
|
|
9728
|
-
const anchorRef =
|
|
9763
|
+
const [open2, setOpen] = React57.useState(false);
|
|
9764
|
+
const anchorRef = React57.useRef(null);
|
|
9729
9765
|
if (!apps.length) return null;
|
|
9730
9766
|
const items = apps.map((app) => ({
|
|
9731
9767
|
id: app.key,
|
|
@@ -9739,7 +9775,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
9739
9775
|
window.location.href = app.url;
|
|
9740
9776
|
}
|
|
9741
9777
|
}));
|
|
9742
|
-
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
9778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(React57.Fragment, { children: [
|
|
9743
9779
|
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
9744
9780
|
IconButton,
|
|
9745
9781
|
{
|
|
@@ -9768,10 +9804,10 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
9768
9804
|
}
|
|
9769
9805
|
|
|
9770
9806
|
// src/components/platform/AppearanceMenu.tsx
|
|
9771
|
-
var
|
|
9807
|
+
var React60 = __toESM(require("react"), 1);
|
|
9772
9808
|
|
|
9773
9809
|
// src/kits/appearance.ts
|
|
9774
|
-
var
|
|
9810
|
+
var React58 = __toESM(require("react"), 1);
|
|
9775
9811
|
var DEFAULT_STORAGE_KEY = "fd-appearance";
|
|
9776
9812
|
var DEFAULT_PREFS = {
|
|
9777
9813
|
theme: "system",
|
|
@@ -9883,8 +9919,8 @@ function watchAppearance(store, root = document.documentElement) {
|
|
|
9883
9919
|
};
|
|
9884
9920
|
}
|
|
9885
9921
|
function useAppearancePrefs(store) {
|
|
9886
|
-
const prefs =
|
|
9887
|
-
const update =
|
|
9922
|
+
const prefs = React58.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
9923
|
+
const update = React58.useCallback(
|
|
9888
9924
|
(patch) => {
|
|
9889
9925
|
store.write({ ...store.getSnapshot(), ...patch });
|
|
9890
9926
|
},
|
|
@@ -9894,15 +9930,15 @@ function useAppearancePrefs(store) {
|
|
|
9894
9930
|
}
|
|
9895
9931
|
|
|
9896
9932
|
// src/components/platform/AppearanceProvider.tsx
|
|
9897
|
-
var
|
|
9933
|
+
var React59 = __toESM(require("react"), 1);
|
|
9898
9934
|
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
9899
|
-
var AppearanceStoreContext =
|
|
9935
|
+
var AppearanceStoreContext = React59.createContext(null);
|
|
9900
9936
|
function AppearanceProvider({ store, children }) {
|
|
9901
|
-
|
|
9937
|
+
React59.useLayoutEffect(() => watchAppearance(store), [store]);
|
|
9902
9938
|
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(AppearanceStoreContext.Provider, { value: store, children });
|
|
9903
9939
|
}
|
|
9904
9940
|
function useAppearanceStore() {
|
|
9905
|
-
const store =
|
|
9941
|
+
const store = React59.useContext(AppearanceStoreContext);
|
|
9906
9942
|
if (!store) throw new Error("AppearanceMenu and useAppearanceStore must be rendered inside an <AppearanceProvider>.");
|
|
9907
9943
|
return store;
|
|
9908
9944
|
}
|
|
@@ -9922,10 +9958,10 @@ var TEXT_SCALE_OPTIONS = [
|
|
|
9922
9958
|
];
|
|
9923
9959
|
function AppearanceMenu({ className = "" }) {
|
|
9924
9960
|
const [prefs, update] = useAppearancePrefs(useAppearanceStore());
|
|
9925
|
-
const [open2, setOpen] =
|
|
9926
|
-
const anchorRef =
|
|
9961
|
+
const [open2, setOpen] = React60.useState(false);
|
|
9962
|
+
const anchorRef = React60.useRef(null);
|
|
9927
9963
|
const patch = (p) => update(p);
|
|
9928
|
-
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
|
|
9964
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(React60.Fragment, { children: [
|
|
9929
9965
|
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
9930
9966
|
IconButton,
|
|
9931
9967
|
{
|
|
@@ -9994,14 +10030,14 @@ function AppearanceMenu({ className = "" }) {
|
|
|
9994
10030
|
}
|
|
9995
10031
|
|
|
9996
10032
|
// src/components/platform/ApiSpecBrowser.tsx
|
|
9997
|
-
var
|
|
10033
|
+
var React61 = __toESM(require("react"), 1);
|
|
9998
10034
|
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
9999
10035
|
var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
|
|
10000
10036
|
function Json({ obj }) {
|
|
10001
10037
|
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
|
|
10002
10038
|
}
|
|
10003
10039
|
function Endpoint({ s, onRequest }) {
|
|
10004
|
-
const [tried, setTried] =
|
|
10040
|
+
const [tried, setTried] = React61.useState(null);
|
|
10005
10041
|
const run = async () => {
|
|
10006
10042
|
setTried("busy");
|
|
10007
10043
|
const t0 = (window.performance || Date).now();
|
|
@@ -10074,10 +10110,10 @@ function ApiSpecBrowser({
|
|
|
10074
10110
|
className = "",
|
|
10075
10111
|
...rest
|
|
10076
10112
|
}) {
|
|
10077
|
-
const [q, setQ] =
|
|
10078
|
-
const [method, setMethod] =
|
|
10079
|
-
const [mod, setMod] =
|
|
10080
|
-
const [listOnly, setListOnly] =
|
|
10113
|
+
const [q, setQ] = React61.useState("");
|
|
10114
|
+
const [method, setMethod] = React61.useState(null);
|
|
10115
|
+
const [mod, setMod] = React61.useState(null);
|
|
10116
|
+
const [listOnly, setListOnly] = React61.useState(false);
|
|
10081
10117
|
const activeModule = modules && modules.find((m) => m.id === mod);
|
|
10082
10118
|
const hits = spec.filter((s) => (!method || s.method === method) && (!listOnly || s.isList) && (!activeModule || activeModule.endpoints.indexOf(s.id) >= 0) && (!q || (s.path + " " + s.title + " " + s.purpose + " " + (s.usedBy || []).join(" ")).toLowerCase().includes(q.toLowerCase())));
|
|
10083
10119
|
const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
|
|
@@ -10156,7 +10192,7 @@ function ApiSpecBrowser({
|
|
|
10156
10192
|
}
|
|
10157
10193
|
|
|
10158
10194
|
// src/components/platform/ProfilePage.tsx
|
|
10159
|
-
var
|
|
10195
|
+
var React62 = __toESM(require("react"), 1);
|
|
10160
10196
|
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
10161
10197
|
function fieldInitialValue(field, user) {
|
|
10162
10198
|
if (field.value) return field.value(user);
|
|
@@ -10192,21 +10228,21 @@ function ProfilePage({
|
|
|
10192
10228
|
}) {
|
|
10193
10229
|
const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
|
|
10194
10230
|
const user = userProp || sessionUser;
|
|
10195
|
-
const initialFieldValues =
|
|
10231
|
+
const initialFieldValues = React62.useMemo(() => {
|
|
10196
10232
|
const values2 = {};
|
|
10197
10233
|
for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
|
|
10198
10234
|
return values2;
|
|
10199
10235
|
}, [user.id, fields]);
|
|
10200
|
-
const initialNotify =
|
|
10236
|
+
const initialNotify = React62.useMemo(() => {
|
|
10201
10237
|
const values2 = {};
|
|
10202
10238
|
for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
|
|
10203
10239
|
return values2;
|
|
10204
10240
|
}, [user.id, notifications]);
|
|
10205
|
-
const [values, setValues] =
|
|
10206
|
-
const [notify, setNotify] =
|
|
10207
|
-
const [saving, setSaving] =
|
|
10208
|
-
const [saved, setSaved] =
|
|
10209
|
-
const [prevUserId, setPrevUserId] =
|
|
10241
|
+
const [values, setValues] = React62.useState(initialFieldValues);
|
|
10242
|
+
const [notify, setNotify] = React62.useState(initialNotify);
|
|
10243
|
+
const [saving, setSaving] = React62.useState(false);
|
|
10244
|
+
const [saved, setSaved] = React62.useState(false);
|
|
10245
|
+
const [prevUserId, setPrevUserId] = React62.useState(user.id);
|
|
10210
10246
|
if (user.id !== prevUserId) {
|
|
10211
10247
|
setPrevUserId(user.id);
|
|
10212
10248
|
setValues(initialFieldValues);
|
|
@@ -10394,7 +10430,7 @@ function ProfilePage({
|
|
|
10394
10430
|
}
|
|
10395
10431
|
|
|
10396
10432
|
// src/components/platform/SessionScreen.tsx
|
|
10397
|
-
var
|
|
10433
|
+
var React63 = __toESM(require("react"), 1);
|
|
10398
10434
|
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
10399
10435
|
var COPY = {
|
|
10400
10436
|
"signing-in": { busy: "Signing you in\u2026" },
|
|
@@ -10408,13 +10444,13 @@ function SessionScreen({ kind, error, onRetry, productName }) {
|
|
|
10408
10444
|
const copy = COPY[kind];
|
|
10409
10445
|
const busyMessage = "busy" in copy ? copy.busy : null;
|
|
10410
10446
|
const failureTitle = "failure" in copy ? copy.failure : null;
|
|
10411
|
-
const [announced, setAnnounced] =
|
|
10412
|
-
|
|
10447
|
+
const [announced, setAnnounced] = React63.useState("");
|
|
10448
|
+
React63.useEffect(() => {
|
|
10413
10449
|
setAnnounced(busyMessage ?? "");
|
|
10414
10450
|
}, [busyMessage]);
|
|
10415
|
-
const titleRef =
|
|
10451
|
+
const titleRef = React63.useRef(null);
|
|
10416
10452
|
const failed = failureTitle !== null;
|
|
10417
|
-
|
|
10453
|
+
React63.useEffect(() => {
|
|
10418
10454
|
titleRef.current?.focus({ preventScroll: true });
|
|
10419
10455
|
}, [failed]);
|
|
10420
10456
|
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("main", { className: "fd-session-screen", children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "fd-session-screen-inner", children: [
|
|
@@ -10437,10 +10473,10 @@ function SessionScreen({ kind, error, onRetry, productName }) {
|
|
|
10437
10473
|
}
|
|
10438
10474
|
|
|
10439
10475
|
// src/components/platform/RoadmapTimeline.tsx
|
|
10440
|
-
var
|
|
10476
|
+
var React66 = __toESM(require("react"), 1);
|
|
10441
10477
|
|
|
10442
10478
|
// src/kits/session.ts
|
|
10443
|
-
var
|
|
10479
|
+
var React64 = __toESM(require("react"), 1);
|
|
10444
10480
|
var PERMISSION_CATALOG = [
|
|
10445
10481
|
{ group: "Plans", items: [
|
|
10446
10482
|
{ key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
|
|
@@ -12007,8 +12043,8 @@ function roadmap(overrides) {
|
|
|
12007
12043
|
};
|
|
12008
12044
|
}
|
|
12009
12045
|
function useSession() {
|
|
12010
|
-
const [s, setS] =
|
|
12011
|
-
|
|
12046
|
+
const [s, setS] = React64.useState(getSession);
|
|
12047
|
+
React64.useEffect(() => subscribe(setS), []);
|
|
12012
12048
|
return s;
|
|
12013
12049
|
}
|
|
12014
12050
|
var SessionKit = {
|
|
@@ -12041,7 +12077,7 @@ var SessionKit = {
|
|
|
12041
12077
|
};
|
|
12042
12078
|
function DemoSessionProvider({ children }) {
|
|
12043
12079
|
const session = useSession();
|
|
12044
|
-
const value =
|
|
12080
|
+
const value = React64.useMemo(
|
|
12045
12081
|
() => ({
|
|
12046
12082
|
user: session.user,
|
|
12047
12083
|
roles: session.roles,
|
|
@@ -12057,11 +12093,11 @@ function DemoSessionProvider({ children }) {
|
|
|
12057
12093
|
}),
|
|
12058
12094
|
[session]
|
|
12059
12095
|
);
|
|
12060
|
-
return
|
|
12096
|
+
return React64.createElement(SessionProvider, { value }, children);
|
|
12061
12097
|
}
|
|
12062
12098
|
|
|
12063
12099
|
// src/kits/runtime.ts
|
|
12064
|
-
var
|
|
12100
|
+
var React65 = __toESM(require("react"), 1);
|
|
12065
12101
|
var WIRED_ENDPOINTS = [
|
|
12066
12102
|
// Nothing yet. Every id below would come from a real service:
|
|
12067
12103
|
// "plan.get", "placements.list", …
|
|
@@ -12232,8 +12268,8 @@ var RuntimeKit = {
|
|
|
12232
12268
|
};
|
|
12233
12269
|
RuntimeKit.declare(FEATURE_NEEDS);
|
|
12234
12270
|
function useRuntimeMode() {
|
|
12235
|
-
const [m, setM] =
|
|
12236
|
-
|
|
12271
|
+
const [m, setM] = React65.useState(RuntimeKit.getMode());
|
|
12272
|
+
React65.useEffect(() => RuntimeKit.subscribe(setM), []);
|
|
12237
12273
|
return m;
|
|
12238
12274
|
}
|
|
12239
12275
|
function useFeatureStatus(key) {
|
|
@@ -12316,12 +12352,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
12316
12352
|
}
|
|
12317
12353
|
function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
12318
12354
|
const session = SessionKit.useSession();
|
|
12319
|
-
const [project, setProject] =
|
|
12320
|
-
const [q, setQ] =
|
|
12321
|
-
const scrollRef =
|
|
12322
|
-
const nowRef =
|
|
12323
|
-
const rm =
|
|
12324
|
-
const byKey =
|
|
12355
|
+
const [project, setProject] = React66.useState("");
|
|
12356
|
+
const [q, setQ] = React66.useState("");
|
|
12357
|
+
const scrollRef = React66.useRef(null);
|
|
12358
|
+
const nowRef = React66.useRef(null);
|
|
12359
|
+
const rm = React66.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
|
|
12360
|
+
const byKey = React66.useMemo(() => {
|
|
12325
12361
|
const m = {};
|
|
12326
12362
|
rm.items.forEach((i) => {
|
|
12327
12363
|
m[i.key] = i;
|
|
@@ -12330,7 +12366,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
12330
12366
|
}, [rm]);
|
|
12331
12367
|
const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
|
|
12332
12368
|
const projects = [...new Set(rm.items.map((i) => i.project))];
|
|
12333
|
-
|
|
12369
|
+
React66.useEffect(() => {
|
|
12334
12370
|
let raf1 = 0, raf2 = 0;
|
|
12335
12371
|
const place = () => {
|
|
12336
12372
|
const box = scrollRef.current, mark = nowRef.current;
|
|
@@ -12404,7 +12440,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
12404
12440
|
lastPhase = item.phase;
|
|
12405
12441
|
const inPhase = items.filter((i) => i.phase === item.phase).length;
|
|
12406
12442
|
const isBoundary = n === firstPending;
|
|
12407
|
-
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
|
|
12443
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(React66.Fragment, { children: [
|
|
12408
12444
|
showPhase ? /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "fd-rm-era", children: [
|
|
12409
12445
|
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
|
|
12410
12446
|
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
|
|
@@ -12448,7 +12484,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
12448
12484
|
}
|
|
12449
12485
|
|
|
12450
12486
|
// src/components/platform/ComingSoon.tsx
|
|
12451
|
-
var
|
|
12487
|
+
var React67 = __toESM(require("react"), 1);
|
|
12452
12488
|
var import_react_dom7 = require("react-dom");
|
|
12453
12489
|
var import_jsx_runtime91 = require("react/jsx-runtime");
|
|
12454
12490
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
@@ -12466,8 +12502,8 @@ function writeBypassed(list) {
|
|
|
12466
12502
|
}
|
|
12467
12503
|
}
|
|
12468
12504
|
function useBypass(key) {
|
|
12469
|
-
const [on, setOn] =
|
|
12470
|
-
|
|
12505
|
+
const [on, setOn] = React67.useState(() => !!key && readBypassed().indexOf(key) >= 0);
|
|
12506
|
+
React67.useEffect(() => {
|
|
12471
12507
|
setOn(!!key && readBypassed().indexOf(key) >= 0);
|
|
12472
12508
|
}, [key]);
|
|
12473
12509
|
const set = (next) => {
|
|
@@ -12514,9 +12550,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
|
|
|
12514
12550
|
] });
|
|
12515
12551
|
}
|
|
12516
12552
|
function useHoverCard(open2) {
|
|
12517
|
-
const anchor =
|
|
12518
|
-
const [pos, setPos] =
|
|
12519
|
-
|
|
12553
|
+
const anchor = React67.useRef(null);
|
|
12554
|
+
const [pos, setPos] = React67.useState(null);
|
|
12555
|
+
React67.useLayoutEffect(() => {
|
|
12520
12556
|
if (!open2 || !anchor.current) {
|
|
12521
12557
|
setPos(null);
|
|
12522
12558
|
return;
|
|
@@ -12643,12 +12679,12 @@ function ComingSoon({
|
|
|
12643
12679
|
] });
|
|
12644
12680
|
}
|
|
12645
12681
|
function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
|
|
12646
|
-
const [open2, setOpen] =
|
|
12682
|
+
const [open2, setOpen] = React67.useState(false);
|
|
12647
12683
|
const [anchor, pos] = useHoverCard(open2);
|
|
12648
|
-
const hoverCardRef =
|
|
12684
|
+
const hoverCardRef = React67.useRef(null);
|
|
12649
12685
|
const hoverLayer = useStackedLayer({ active: open2, containerRef: hoverCardRef, returnFocus: false });
|
|
12650
12686
|
const zIndex = useLayerZIndex(hoverLayer);
|
|
12651
|
-
const close2 =
|
|
12687
|
+
const close2 = React67.useRef(null);
|
|
12652
12688
|
const show = () => {
|
|
12653
12689
|
if (close2.current) {
|
|
12654
12690
|
clearTimeout(close2.current);
|
|
@@ -12664,7 +12700,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
12664
12700
|
setOpen(false);
|
|
12665
12701
|
}, 140);
|
|
12666
12702
|
};
|
|
12667
|
-
|
|
12703
|
+
React67.useEffect(() => () => {
|
|
12668
12704
|
if (close2.current) clearTimeout(close2.current);
|
|
12669
12705
|
}, []);
|
|
12670
12706
|
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
|
|
@@ -13116,7 +13152,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
13116
13152
|
}
|
|
13117
13153
|
|
|
13118
13154
|
// src/components/planner/MixGap.tsx
|
|
13119
|
-
var
|
|
13155
|
+
var React68 = __toESM(require("react"), 1);
|
|
13120
13156
|
var import_jsx_runtime96 = require("react/jsx-runtime");
|
|
13121
13157
|
var MIX_GAP_LAYOUT = {
|
|
13122
13158
|
trackHeight: 30,
|
|
@@ -13131,7 +13167,7 @@ function mixGapOffset(value, max) {
|
|
|
13131
13167
|
}
|
|
13132
13168
|
function MixGap({ rows = [], loading = false, className = "" }) {
|
|
13133
13169
|
const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
|
|
13134
|
-
const [hover, setHover] =
|
|
13170
|
+
const [hover, setHover] = React68.useState(null);
|
|
13135
13171
|
const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
|
|
13136
13172
|
const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
|
|
13137
13173
|
const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
|
|
@@ -13274,7 +13310,7 @@ function ChannelContribution({
|
|
|
13274
13310
|
}
|
|
13275
13311
|
|
|
13276
13312
|
// src/components/planner/BudgetReallocator.tsx
|
|
13277
|
-
var
|
|
13313
|
+
var React69 = __toESM(require("react"), 1);
|
|
13278
13314
|
var import_jsx_runtime98 = require("react/jsx-runtime");
|
|
13279
13315
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
13280
13316
|
function BudgetReallocator({
|
|
@@ -13290,8 +13326,8 @@ function BudgetReallocator({
|
|
|
13290
13326
|
onCancel,
|
|
13291
13327
|
className = ""
|
|
13292
13328
|
}) {
|
|
13293
|
-
const [draft, setDraft] =
|
|
13294
|
-
|
|
13329
|
+
const [draft, setDraft] = React69.useState(spend);
|
|
13330
|
+
React69.useEffect(() => setDraft(spend), [spend]);
|
|
13295
13331
|
const dirty = draft !== spend;
|
|
13296
13332
|
const nextCrp = scoreFor ? scoreFor(draft) : crp;
|
|
13297
13333
|
const nextBand = bandFor(nextCrp);
|
|
@@ -13306,10 +13342,10 @@ function BudgetReallocator({
|
|
|
13306
13342
|
setDraft(spend);
|
|
13307
13343
|
if (onCancel) onCancel();
|
|
13308
13344
|
};
|
|
13309
|
-
const trackRef =
|
|
13310
|
-
const chipRef =
|
|
13311
|
-
const [chipLeft, setChipLeft] =
|
|
13312
|
-
|
|
13345
|
+
const trackRef = React69.useRef(null);
|
|
13346
|
+
const chipRef = React69.useRef(null);
|
|
13347
|
+
const [chipLeft, setChipLeft] = React69.useState(null);
|
|
13348
|
+
React69.useLayoutEffect(() => {
|
|
13313
13349
|
const track = trackRef.current;
|
|
13314
13350
|
if (!dirty || !track) {
|
|
13315
13351
|
setChipLeft(null);
|
|
@@ -13497,7 +13533,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
|
|
|
13497
13533
|
}
|
|
13498
13534
|
|
|
13499
13535
|
// src/components/planner/PreferenceMeter.tsx
|
|
13500
|
-
var
|
|
13536
|
+
var React70 = __toESM(require("react"), 1);
|
|
13501
13537
|
var import_jsx_runtime101 = require("react/jsx-runtime");
|
|
13502
13538
|
function preferenceScore(criteria) {
|
|
13503
13539
|
const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
|
|
@@ -13527,7 +13563,7 @@ function PreferenceMeter({
|
|
|
13527
13563
|
className = ""
|
|
13528
13564
|
}) {
|
|
13529
13565
|
const value = score == null ? preferenceScore(criteria) : score;
|
|
13530
|
-
const segments =
|
|
13566
|
+
const segments = React70.useMemo(() => preferenceSegments(criteria), [criteria]);
|
|
13531
13567
|
return /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
13532
13568
|
ScoreMeter,
|
|
13533
13569
|
{
|
|
@@ -13566,17 +13602,13 @@ function PreferenceMeter({
|
|
|
13566
13602
|
}
|
|
13567
13603
|
|
|
13568
13604
|
// src/components/chat/AgentChatPanel.tsx
|
|
13569
|
-
var
|
|
13605
|
+
var React77 = __toESM(require("react"), 1);
|
|
13570
13606
|
|
|
13571
13607
|
// src/components/chat/chatEngine.ts
|
|
13572
|
-
var
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
var
|
|
13576
|
-
var STORAGE_PREFIX = "fdchat:job:";
|
|
13577
|
-
var seq = 0;
|
|
13578
|
-
var uid = (p) => p + "_" + ++seq + "_" + Date.now().toString(36);
|
|
13579
|
-
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
13608
|
+
var React72 = __toESM(require("react"), 1);
|
|
13609
|
+
|
|
13610
|
+
// src/components/chat/chatStore.ts
|
|
13611
|
+
var React71 = __toESM(require("react"), 1);
|
|
13580
13612
|
var safeStore = {
|
|
13581
13613
|
get(k) {
|
|
13582
13614
|
try {
|
|
@@ -13598,6 +13630,38 @@ var safeStore = {
|
|
|
13598
13630
|
}
|
|
13599
13631
|
}
|
|
13600
13632
|
};
|
|
13633
|
+
var part = (v) => encodeURIComponent(v);
|
|
13634
|
+
var jobKey = (threadId) => "fdchat:job:" + part(threadId);
|
|
13635
|
+
var draftKey = (owner, contextType, contextId) => "fdchat:draft:" + [owner, contextType, contextId].map(part).join(":");
|
|
13636
|
+
function useChatDraft(owner, contextType, contextId, store = safeStore) {
|
|
13637
|
+
if (owner === "") throw new Error("useChatDraft: draftOwner is an empty string; pass the signed-in user's id, or null for no owner.");
|
|
13638
|
+
const key = owner === null ? null : draftKey(owner, contextType, contextId);
|
|
13639
|
+
const read2 = (k) => k ? store.get(k) || "" : "";
|
|
13640
|
+
const [state, setState] = React71.useState(() => ({ key, text: read2(key) }));
|
|
13641
|
+
let current2 = state;
|
|
13642
|
+
if (state.key !== key) {
|
|
13643
|
+
current2 = { key, text: read2(key) };
|
|
13644
|
+
setState(current2);
|
|
13645
|
+
}
|
|
13646
|
+
const setText = React71.useCallback((text) => {
|
|
13647
|
+
if (key) {
|
|
13648
|
+
if (text) {
|
|
13649
|
+
store.set(key, text);
|
|
13650
|
+
if (store.get(key) !== text) store.del(key);
|
|
13651
|
+
} else store.del(key);
|
|
13652
|
+
}
|
|
13653
|
+
setState({ key, text });
|
|
13654
|
+
}, [key, store]);
|
|
13655
|
+
return [current2.text, setText];
|
|
13656
|
+
}
|
|
13657
|
+
|
|
13658
|
+
// src/components/chat/chatEngine.ts
|
|
13659
|
+
var CHAT_UNAVAILABLE = "chat_unavailable";
|
|
13660
|
+
var JOB_PENDING = ["queued", "running"];
|
|
13661
|
+
var JOB_SUCCESS = ["completed", "recovered"];
|
|
13662
|
+
var seq = 0;
|
|
13663
|
+
var uid = (p) => p + "_" + ++seq + "_" + Date.now().toString(36);
|
|
13664
|
+
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
13601
13665
|
var isSystemMessage = (m) => !!m && (m.role === "system" || m.metadata != null && m.metadata.type === "system");
|
|
13602
13666
|
var visibleMessages = (list) => (list || []).filter((m) => !isSystemMessage(m));
|
|
13603
13667
|
function jobBucket(status) {
|
|
@@ -13638,33 +13702,33 @@ function useChatEngine(opts) {
|
|
|
13638
13702
|
onClear,
|
|
13639
13703
|
onFeedback
|
|
13640
13704
|
} = opts || {};
|
|
13641
|
-
const [status, setStatus] =
|
|
13642
|
-
const [threadId, setThreadId] =
|
|
13643
|
-
const [messages, setMessages] =
|
|
13644
|
-
const [queue, setQueue] =
|
|
13645
|
-
const [fatal, setFatal] =
|
|
13646
|
-
const [busy, setBusy] =
|
|
13647
|
-
const [turnStartedAt, setTurnStartedAt] =
|
|
13648
|
-
const listRef =
|
|
13649
|
-
const queueRef =
|
|
13650
|
-
const busyRef =
|
|
13651
|
-
const loadedRef =
|
|
13652
|
-
const stoppedRef =
|
|
13653
|
-
const abortRef =
|
|
13654
|
-
const serverCount =
|
|
13655
|
-
const serverIds =
|
|
13656
|
-
const liveTurn =
|
|
13657
|
-
const lastTurnOwn =
|
|
13658
|
-
const retired =
|
|
13659
|
-
const threadRef =
|
|
13660
|
-
const mounted =
|
|
13661
|
-
|
|
13705
|
+
const [status, setStatus] = React72.useState("idle");
|
|
13706
|
+
const [threadId, setThreadId] = React72.useState(null);
|
|
13707
|
+
const [messages, setMessages] = React72.useState([]);
|
|
13708
|
+
const [queue, setQueue] = React72.useState([]);
|
|
13709
|
+
const [fatal, setFatal] = React72.useState(null);
|
|
13710
|
+
const [busy, setBusy] = React72.useState(false);
|
|
13711
|
+
const [turnStartedAt, setTurnStartedAt] = React72.useState(null);
|
|
13712
|
+
const listRef = React72.useRef([]);
|
|
13713
|
+
const queueRef = React72.useRef([]);
|
|
13714
|
+
const busyRef = React72.useRef(false);
|
|
13715
|
+
const loadedRef = React72.useRef(false);
|
|
13716
|
+
const stoppedRef = React72.useRef(false);
|
|
13717
|
+
const abortRef = React72.useRef(null);
|
|
13718
|
+
const serverCount = React72.useRef(0);
|
|
13719
|
+
const serverIds = React72.useRef(/* @__PURE__ */ new Set());
|
|
13720
|
+
const liveTurn = React72.useRef(null);
|
|
13721
|
+
const lastTurnOwn = React72.useRef(/* @__PURE__ */ new Set());
|
|
13722
|
+
const retired = React72.useRef(/* @__PURE__ */ new Set());
|
|
13723
|
+
const threadRef = React72.useRef(null);
|
|
13724
|
+
const mounted = React72.useRef(true);
|
|
13725
|
+
React72.useEffect(() => {
|
|
13662
13726
|
mounted.current = true;
|
|
13663
13727
|
return () => {
|
|
13664
13728
|
mounted.current = false;
|
|
13665
13729
|
};
|
|
13666
13730
|
}, []);
|
|
13667
|
-
const describeWaitingRef =
|
|
13731
|
+
const describeWaitingRef = React72.useRef(describeWaiting);
|
|
13668
13732
|
describeWaitingRef.current = describeWaiting;
|
|
13669
13733
|
const commit = (next) => {
|
|
13670
13734
|
const derived = withWaiting(next, (pending) => describeWaitingRef.current(pending));
|
|
@@ -13683,7 +13747,7 @@ function useChatEngine(opts) {
|
|
|
13683
13747
|
}
|
|
13684
13748
|
return false;
|
|
13685
13749
|
};
|
|
13686
|
-
const loadThread =
|
|
13750
|
+
const loadThread = React72.useCallback(async (id) => {
|
|
13687
13751
|
const data = await apiAdapter.getThread(id);
|
|
13688
13752
|
const list = [...data && data.messages || []];
|
|
13689
13753
|
serverCount.current = list.length;
|
|
@@ -13723,7 +13787,7 @@ function useChatEngine(opts) {
|
|
|
13723
13787
|
packet: progress.packet ?? holder.packet
|
|
13724
13788
|
});
|
|
13725
13789
|
}
|
|
13726
|
-
|
|
13790
|
+
React72.useEffect(() => {
|
|
13727
13791
|
if (!apiAdapter) {
|
|
13728
13792
|
setStatus("idle");
|
|
13729
13793
|
setFatal(null);
|
|
@@ -13770,7 +13834,7 @@ function useChatEngine(opts) {
|
|
|
13770
13834
|
setStatus("ready");
|
|
13771
13835
|
loadedRef.current = true;
|
|
13772
13836
|
onThreadReady && onThreadReady(id);
|
|
13773
|
-
const stored = store.get(
|
|
13837
|
+
const stored = store.get(jobKey(id));
|
|
13774
13838
|
const last = [...visibleMessages(listRef.current)].reverse().find((m) => m.role === "assistant");
|
|
13775
13839
|
if (stored) resumeJob(stored);
|
|
13776
13840
|
else if (last && last.working && last.jobId) resumeJob(last.jobId, last.id);
|
|
@@ -13789,7 +13853,7 @@ function useChatEngine(opts) {
|
|
|
13789
13853
|
};
|
|
13790
13854
|
}, [apiAdapter, contextType, contextId, threadIdProp]);
|
|
13791
13855
|
async function pollJob(jobId, placeholderId) {
|
|
13792
|
-
store.set(
|
|
13856
|
+
store.set(jobKey(threadRef.current), jobId);
|
|
13793
13857
|
const deadline = Date.now() + pendingTimeoutMs;
|
|
13794
13858
|
while (true) {
|
|
13795
13859
|
if (stoppedRef.current) break;
|
|
@@ -13837,7 +13901,7 @@ function useChatEngine(opts) {
|
|
|
13837
13901
|
}
|
|
13838
13902
|
}
|
|
13839
13903
|
async function finishJob(_jobId, _job) {
|
|
13840
|
-
store.del(
|
|
13904
|
+
store.del(jobKey(threadRef.current));
|
|
13841
13905
|
try {
|
|
13842
13906
|
const list = await loadThread(threadRef.current);
|
|
13843
13907
|
const withPacket = [...list].reverse().find((m) => m && m.packet);
|
|
@@ -13847,7 +13911,7 @@ function useChatEngine(opts) {
|
|
|
13847
13911
|
}
|
|
13848
13912
|
}
|
|
13849
13913
|
function recordFailure(placeholderId, code, retryable, job) {
|
|
13850
|
-
store.del(
|
|
13914
|
+
store.del(jobKey(threadRef.current));
|
|
13851
13915
|
if (!listRef.current.some((m) => m.id === placeholderId)) {
|
|
13852
13916
|
push({ id: placeholderId, role: "assistant", text: null });
|
|
13853
13917
|
}
|
|
@@ -13955,7 +14019,7 @@ function useChatEngine(opts) {
|
|
|
13955
14019
|
await dispatchTurn(turn);
|
|
13956
14020
|
}
|
|
13957
14021
|
}
|
|
13958
|
-
const send =
|
|
14022
|
+
const send = React72.useCallback((text, attachments) => {
|
|
13959
14023
|
const body = (text || "").trim();
|
|
13960
14024
|
if (!body && !(attachments && attachments.length)) return;
|
|
13961
14025
|
if (status === "disconnected") return;
|
|
@@ -13965,7 +14029,7 @@ function useChatEngine(opts) {
|
|
|
13965
14029
|
stoppedRef.current = false;
|
|
13966
14030
|
drain();
|
|
13967
14031
|
}, [status]);
|
|
13968
|
-
const stop =
|
|
14032
|
+
const stop = React72.useCallback(() => {
|
|
13969
14033
|
stoppedRef.current = true;
|
|
13970
14034
|
const ac = abortRef.current;
|
|
13971
14035
|
if (ac) {
|
|
@@ -13981,14 +14045,14 @@ function useChatEngine(opts) {
|
|
|
13981
14045
|
Promise.resolve(apiAdapter.cancelJob(holder.jobId)).catch(() => {
|
|
13982
14046
|
});
|
|
13983
14047
|
}
|
|
13984
|
-
store.del(
|
|
14048
|
+
store.del(jobKey(threadRef.current));
|
|
13985
14049
|
}
|
|
13986
14050
|
}, [apiAdapter]);
|
|
13987
|
-
const removeQueued =
|
|
14051
|
+
const removeQueued = React72.useCallback((id) => {
|
|
13988
14052
|
queueRef.current = queueRef.current.filter((t) => t.id !== id);
|
|
13989
14053
|
setQueue(queueRef.current.slice());
|
|
13990
14054
|
}, []);
|
|
13991
|
-
const retry =
|
|
14055
|
+
const retry = React72.useCallback(() => {
|
|
13992
14056
|
const list = listRef.current;
|
|
13993
14057
|
let at = -1;
|
|
13994
14058
|
for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
|
|
@@ -14005,19 +14069,19 @@ function useChatEngine(opts) {
|
|
|
14005
14069
|
setQueue(queueRef.current.slice());
|
|
14006
14070
|
drain();
|
|
14007
14071
|
}, []);
|
|
14008
|
-
const clear =
|
|
14072
|
+
const clear = React72.useCallback(() => {
|
|
14009
14073
|
commit([]);
|
|
14010
14074
|
serverCount.current = 0;
|
|
14011
14075
|
queueRef.current = [];
|
|
14012
14076
|
setQueue([]);
|
|
14013
14077
|
onClear && onClear();
|
|
14014
14078
|
}, [onClear]);
|
|
14015
|
-
const setFeedback =
|
|
14079
|
+
const setFeedback = React72.useCallback((id, value) => {
|
|
14016
14080
|
patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
|
|
14017
14081
|
const msg = listRef.current.find((m) => m.id === id);
|
|
14018
14082
|
onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
|
|
14019
14083
|
}, [onFeedback]);
|
|
14020
|
-
const reload =
|
|
14084
|
+
const reload = React72.useCallback(async () => {
|
|
14021
14085
|
if (!threadRef.current) return;
|
|
14022
14086
|
setStatus("loading");
|
|
14023
14087
|
try {
|
|
@@ -14055,10 +14119,10 @@ var ChatKit = {
|
|
|
14055
14119
|
};
|
|
14056
14120
|
|
|
14057
14121
|
// src/components/chat/ChatTranscript.tsx
|
|
14058
|
-
var
|
|
14122
|
+
var React74 = __toESM(require("react"), 1);
|
|
14059
14123
|
|
|
14060
14124
|
// src/components/chat/ChatTurn.tsx
|
|
14061
|
-
var
|
|
14125
|
+
var React73 = __toESM(require("react"), 1);
|
|
14062
14126
|
var import_jsx_runtime102 = require("react/jsx-runtime");
|
|
14063
14127
|
function JsonView({ value }) {
|
|
14064
14128
|
let text;
|
|
@@ -14095,7 +14159,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
|
14095
14159
|
] });
|
|
14096
14160
|
}
|
|
14097
14161
|
function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
14098
|
-
const [open2, setOpen] =
|
|
14162
|
+
const [open2, setOpen] = React73.useState(defaultOpen);
|
|
14099
14163
|
if (!text) return null;
|
|
14100
14164
|
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
|
|
14101
14165
|
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -14112,7 +14176,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
|
14112
14176
|
] });
|
|
14113
14177
|
}
|
|
14114
14178
|
function Citations({ items = [], onOpen }) {
|
|
14115
|
-
const [open2, setOpen] =
|
|
14179
|
+
const [open2, setOpen] = React73.useState(false);
|
|
14116
14180
|
if (!items.length) return null;
|
|
14117
14181
|
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "fdc-cites", children: [
|
|
14118
14182
|
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -14138,7 +14202,7 @@ function clampText(text, max) {
|
|
|
14138
14202
|
return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
14139
14203
|
}
|
|
14140
14204
|
function MessageBody({ message: m, ctx }) {
|
|
14141
|
-
const [expanded, setExpanded] =
|
|
14205
|
+
const [expanded, setExpanded] = React73.useState(false);
|
|
14142
14206
|
const isUser = m.role === "user";
|
|
14143
14207
|
const raw = m.text || "";
|
|
14144
14208
|
const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
|
|
@@ -14217,7 +14281,7 @@ function RunActions({ group, ctx }) {
|
|
|
14217
14281
|
] }),
|
|
14218
14282
|
isAssistant && ctx.onRetry ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
|
|
14219
14283
|
group.role === "user" && ctx.onEdit ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
|
|
14220
|
-
isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(
|
|
14284
|
+
isAssistant && ctx.onFeedback ? /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)(React73.Fragment, { children: [
|
|
14221
14285
|
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("button", { type: "button", className: "fdc-act" + (fb === "up" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "up"), "aria-pressed": fb === "up", "aria-label": "Good response", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
|
|
14222
14286
|
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("button", { type: "button", className: "fdc-act" + (fb === "down" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "down"), "aria-pressed": fb === "down", "aria-label": "Bad response", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
|
|
14223
14287
|
] }) : null,
|
|
@@ -14312,10 +14376,10 @@ function ChatTranscript({
|
|
|
14312
14376
|
renderEmpty,
|
|
14313
14377
|
className = ""
|
|
14314
14378
|
}) {
|
|
14315
|
-
const scroller =
|
|
14316
|
-
const stick =
|
|
14317
|
-
const [pill, setPill] =
|
|
14318
|
-
const seen =
|
|
14379
|
+
const scroller = React74.useRef(null);
|
|
14380
|
+
const stick = React74.useRef(true);
|
|
14381
|
+
const [pill, setPill] = React74.useState(0);
|
|
14382
|
+
const seen = React74.useRef(0);
|
|
14319
14383
|
const toBottom = (smooth) => {
|
|
14320
14384
|
const el = scroller.current;
|
|
14321
14385
|
if (!el) return;
|
|
@@ -14334,7 +14398,7 @@ function ChatTranscript({
|
|
|
14334
14398
|
seen.current = messages.length;
|
|
14335
14399
|
}
|
|
14336
14400
|
};
|
|
14337
|
-
|
|
14401
|
+
React74.useLayoutEffect(() => {
|
|
14338
14402
|
const el = scroller.current;
|
|
14339
14403
|
if (!el) return;
|
|
14340
14404
|
if (stick.current) {
|
|
@@ -14342,7 +14406,7 @@ function ChatTranscript({
|
|
|
14342
14406
|
seen.current = messages.length;
|
|
14343
14407
|
} else setPill(Math.max(0, messages.length - seen.current));
|
|
14344
14408
|
}, [messages]);
|
|
14345
|
-
|
|
14409
|
+
React74.useEffect(() => {
|
|
14346
14410
|
const el = scroller.current;
|
|
14347
14411
|
const inner = el && el.firstChild;
|
|
14348
14412
|
if (!el || !inner || typeof ResizeObserver === "undefined") return;
|
|
@@ -14352,7 +14416,7 @@ function ChatTranscript({
|
|
|
14352
14416
|
ro.observe(inner);
|
|
14353
14417
|
return () => ro.disconnect();
|
|
14354
14418
|
}, []);
|
|
14355
|
-
const groups =
|
|
14419
|
+
const groups = React74.useMemo(() => groupMessages(messages), [messages]);
|
|
14356
14420
|
const empty = !messages.length && status === "ready";
|
|
14357
14421
|
return /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
|
|
14358
14422
|
/* @__PURE__ */ (0, import_jsx_runtime103.jsxs)("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
|
|
@@ -14376,7 +14440,7 @@ function ChatTranscript({
|
|
|
14376
14440
|
const prev = groups[i - 1];
|
|
14377
14441
|
const k = dayKey(g.messages[0].timestamp);
|
|
14378
14442
|
const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
|
|
14379
|
-
return /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)(
|
|
14443
|
+
return /* @__PURE__ */ (0, import_jsx_runtime103.jsxs)(React74.Fragment, { children: [
|
|
14380
14444
|
showDay ? /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("div", { className: "fdc-day", children: /* @__PURE__ */ (0, import_jsx_runtime103.jsx)("span", { children: dayLabel(k) }) }) : null,
|
|
14381
14445
|
/* @__PURE__ */ (0, import_jsx_runtime103.jsx)(ChatTurn, { group: g, ctx })
|
|
14382
14446
|
] }, g.key || i);
|
|
@@ -14393,7 +14457,7 @@ function ChatTranscript({
|
|
|
14393
14457
|
var TranscriptKit = { groupMessages };
|
|
14394
14458
|
|
|
14395
14459
|
// src/components/chat/ChatComposer.tsx
|
|
14396
|
-
var
|
|
14460
|
+
var React75 = __toESM(require("react"), 1);
|
|
14397
14461
|
var import_jsx_runtime104 = require("react/jsx-runtime");
|
|
14398
14462
|
function ChatComposer({
|
|
14399
14463
|
onSubmit,
|
|
@@ -14421,17 +14485,17 @@ function ChatComposer({
|
|
|
14421
14485
|
onReject,
|
|
14422
14486
|
onOpenAttachment
|
|
14423
14487
|
}) {
|
|
14424
|
-
const [text, setText] =
|
|
14425
|
-
const [trigger, setTrigger] =
|
|
14426
|
-
const [mentionItems, setMentionItems] =
|
|
14427
|
-
const [listening, setListening] =
|
|
14428
|
-
const [notice, setNotice] =
|
|
14429
|
-
const editor =
|
|
14430
|
-
const wrap =
|
|
14431
|
-
const stopVoice =
|
|
14488
|
+
const [text, setText] = React75.useState(draft || "");
|
|
14489
|
+
const [trigger, setTrigger] = React75.useState(null);
|
|
14490
|
+
const [mentionItems, setMentionItems] = React75.useState([]);
|
|
14491
|
+
const [listening, setListening] = React75.useState(false);
|
|
14492
|
+
const [notice, setNotice] = React75.useState(null);
|
|
14493
|
+
const editor = React75.useRef(null);
|
|
14494
|
+
const wrap = React75.useRef(null);
|
|
14495
|
+
const stopVoice = React75.useRef(null);
|
|
14432
14496
|
const staged = useStagedFiles(fileUploadHandler, { onError: () => {
|
|
14433
14497
|
} });
|
|
14434
|
-
|
|
14498
|
+
React75.useEffect(() => {
|
|
14435
14499
|
if (draft != null && draft !== text) setText(draft);
|
|
14436
14500
|
}, [draft]);
|
|
14437
14501
|
const change = (v) => {
|
|
@@ -14467,7 +14531,7 @@ function ChatComposer({
|
|
|
14467
14531
|
e.preventDefault();
|
|
14468
14532
|
staged.add(found.files);
|
|
14469
14533
|
};
|
|
14470
|
-
|
|
14534
|
+
React75.useEffect(() => {
|
|
14471
14535
|
if (!trigger || trigger.type !== "mention" || !mentionSources) {
|
|
14472
14536
|
setMentionItems([]);
|
|
14473
14537
|
return;
|
|
@@ -14485,7 +14549,7 @@ function ChatComposer({
|
|
|
14485
14549
|
const q = (trigger.query || "").toLowerCase();
|
|
14486
14550
|
setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
|
|
14487
14551
|
}, [trigger, mentionSources]);
|
|
14488
|
-
const slashItems =
|
|
14552
|
+
const slashItems = React75.useMemo(() => {
|
|
14489
14553
|
if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
|
|
14490
14554
|
const q = (trigger.query || "").toLowerCase();
|
|
14491
14555
|
return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
|
|
@@ -14655,12 +14719,12 @@ function ChatComposer({
|
|
|
14655
14719
|
}
|
|
14656
14720
|
|
|
14657
14721
|
// src/components/chat/ChatSessionBar.tsx
|
|
14658
|
-
var
|
|
14722
|
+
var React76 = __toESM(require("react"), 1);
|
|
14659
14723
|
var import_jsx_runtime105 = require("react/jsx-runtime");
|
|
14660
14724
|
var compact2 = meterFormats.compact;
|
|
14661
14725
|
function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
|
|
14662
|
-
const [open2, setOpen] =
|
|
14663
|
-
const anchor =
|
|
14726
|
+
const [open2, setOpen] = React76.useState(false);
|
|
14727
|
+
const anchor = React76.useRef(null);
|
|
14664
14728
|
const stats = sessionStats || null;
|
|
14665
14729
|
const cu = contextUsage || null;
|
|
14666
14730
|
const limits = usageLimits || null;
|
|
@@ -14675,7 +14739,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
14675
14739
|
if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
|
|
14676
14740
|
if (cu) bits.push(pct + "% context");
|
|
14677
14741
|
const expandable = !!(cu || limits);
|
|
14678
|
-
return /* @__PURE__ */ (0, import_jsx_runtime105.jsxs)(
|
|
14742
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsxs)(React76.Fragment, { children: [
|
|
14679
14743
|
/* @__PURE__ */ (0, import_jsx_runtime105.jsxs)("div", { className: "fdc-bar", children: [
|
|
14680
14744
|
/* @__PURE__ */ (0, import_jsx_runtime105.jsxs)(
|
|
14681
14745
|
"button",
|
|
@@ -14816,7 +14880,7 @@ function ModelControls({
|
|
|
14816
14880
|
] })
|
|
14817
14881
|
});
|
|
14818
14882
|
}
|
|
14819
|
-
return /* @__PURE__ */ (0, import_jsx_runtime105.jsxs)(
|
|
14883
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsxs)(React76.Fragment, { children: [
|
|
14820
14884
|
/* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
|
|
14821
14885
|
MenuButton,
|
|
14822
14886
|
{
|
|
@@ -14855,6 +14919,7 @@ function AgentChatPanel({
|
|
|
14855
14919
|
/* required */
|
|
14856
14920
|
contextType,
|
|
14857
14921
|
contextId,
|
|
14922
|
+
draftOwner,
|
|
14858
14923
|
apiAdapter,
|
|
14859
14924
|
threadId,
|
|
14860
14925
|
/* identity + chrome */
|
|
@@ -14935,11 +15000,11 @@ function AgentChatPanel({
|
|
|
14935
15000
|
onFeedback,
|
|
14936
15001
|
onEditMessage
|
|
14937
15002
|
}) {
|
|
14938
|
-
const [panelWidth, setPanelWidth] =
|
|
14939
|
-
const [applied, setApplied] =
|
|
14940
|
-
const [draft, setDraft] =
|
|
14941
|
-
const dragging =
|
|
14942
|
-
|
|
15003
|
+
const [panelWidth, setPanelWidth] = React77.useState(width);
|
|
15004
|
+
const [applied, setApplied] = React77.useState({});
|
|
15005
|
+
const [draft, setDraft] = useChatDraft(draftOwner, contextType, contextId);
|
|
15006
|
+
const dragging = React77.useRef(null);
|
|
15007
|
+
React77.useEffect(() => setPanelWidth(width), [width]);
|
|
14943
15008
|
const engine = useChatEngine({
|
|
14944
15009
|
contextType,
|
|
14945
15010
|
contextId,
|
|
@@ -15145,7 +15210,7 @@ function AgentChatPanel({
|
|
|
15145
15210
|
}
|
|
15146
15211
|
|
|
15147
15212
|
// src/components/files/FileViewer.tsx
|
|
15148
|
-
var
|
|
15213
|
+
var React78 = __toESM(require("react"), 1);
|
|
15149
15214
|
var import_jsx_runtime107 = require("react/jsx-runtime");
|
|
15150
15215
|
function previewKindOf(file) {
|
|
15151
15216
|
const mime = (file.mime || "").toLowerCase();
|
|
@@ -15202,13 +15267,13 @@ function parseDelimited(text, delimiter) {
|
|
|
15202
15267
|
return rows;
|
|
15203
15268
|
}
|
|
15204
15269
|
function usePreview(file, kind, resolveUrl) {
|
|
15205
|
-
const [state, setState] =
|
|
15206
|
-
const [attempt, setAttempt] =
|
|
15207
|
-
const resolveRef =
|
|
15208
|
-
|
|
15270
|
+
const [state, setState] = React78.useState({ status: "loading" });
|
|
15271
|
+
const [attempt, setAttempt] = React78.useState(0);
|
|
15272
|
+
const resolveRef = React78.useRef(resolveUrl);
|
|
15273
|
+
React78.useEffect(() => {
|
|
15209
15274
|
resolveRef.current = resolveUrl;
|
|
15210
15275
|
}, [resolveUrl]);
|
|
15211
|
-
|
|
15276
|
+
React78.useEffect(() => {
|
|
15212
15277
|
if (kind === "none") {
|
|
15213
15278
|
setState({ status: "ready" });
|
|
15214
15279
|
return;
|
|
@@ -15238,7 +15303,7 @@ function usePreview(file, kind, resolveUrl) {
|
|
|
15238
15303
|
if (ac) ac.abort();
|
|
15239
15304
|
};
|
|
15240
15305
|
}, [file.id, kind, attempt]);
|
|
15241
|
-
return { ...state, retry:
|
|
15306
|
+
return { ...state, retry: React78.useCallback(() => setAttempt((a) => a + 1), []) };
|
|
15242
15307
|
}
|
|
15243
15308
|
function PreviewBody({ file, kind, state }) {
|
|
15244
15309
|
if (kind === "image") return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
|
|
@@ -15283,13 +15348,13 @@ function PreviewBody({ file, kind, state }) {
|
|
|
15283
15348
|
] });
|
|
15284
15349
|
}
|
|
15285
15350
|
function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
|
|
15286
|
-
const kind =
|
|
15351
|
+
const kind = React78.useMemo(() => previewKindOf(file), [file]);
|
|
15287
15352
|
const preview = usePreview(file, kind, resolveUrl);
|
|
15288
|
-
const [tab, setTab] =
|
|
15289
|
-
const [downloading, setDownloading] =
|
|
15290
|
-
const [downloadError, setDownloadError] =
|
|
15353
|
+
const [tab, setTab] = React78.useState("preview");
|
|
15354
|
+
const [downloading, setDownloading] = React78.useState(false);
|
|
15355
|
+
const [downloadError, setDownloadError] = React78.useState(null);
|
|
15291
15356
|
const hasSide = sidePanel != null;
|
|
15292
|
-
|
|
15357
|
+
React78.useEffect(() => {
|
|
15293
15358
|
setTab("preview");
|
|
15294
15359
|
}, [file.id]);
|
|
15295
15360
|
const download = () => {
|
|
@@ -15356,7 +15421,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
15356
15421
|
}
|
|
15357
15422
|
|
|
15358
15423
|
// src/components/files/FileBrowser.tsx
|
|
15359
|
-
var
|
|
15424
|
+
var React79 = __toESM(require("react"), 1);
|
|
15360
15425
|
var import_jsx_runtime108 = require("react/jsx-runtime");
|
|
15361
15426
|
function childrenOf(folders, parentId) {
|
|
15362
15427
|
return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -15466,8 +15531,8 @@ function FolderPickerMenu({
|
|
|
15466
15531
|
] });
|
|
15467
15532
|
}
|
|
15468
15533
|
function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
|
|
15469
|
-
const [over, setOver] =
|
|
15470
|
-
const dragCounter =
|
|
15534
|
+
const [over, setOver] = React79.useState(false);
|
|
15535
|
+
const dragCounter = React79.useRef(0);
|
|
15471
15536
|
const dropHandlers = isDropTarget ? {
|
|
15472
15537
|
onDragEnter: (e) => {
|
|
15473
15538
|
if (!hasInternalPayload(e)) return;
|
|
@@ -15515,8 +15580,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
|
|
|
15515
15580
|
}
|
|
15516
15581
|
function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
|
|
15517
15582
|
const kids = childrenOf(folders, folder.id);
|
|
15518
|
-
const [expanded, setExpanded] =
|
|
15519
|
-
|
|
15583
|
+
const [expanded, setExpanded] = React79.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
|
|
15584
|
+
React79.useEffect(() => {
|
|
15520
15585
|
if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
|
|
15521
15586
|
}, [currentFolderId, folder.id, folders]);
|
|
15522
15587
|
const isCurrent = folder.id === currentFolderId;
|
|
@@ -15582,15 +15647,15 @@ function FileBrowser({
|
|
|
15582
15647
|
const canUpload = perm.canUpload !== false && !!onUpload;
|
|
15583
15648
|
const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
|
|
15584
15649
|
const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
|
|
15585
|
-
const [createOpen, setCreateOpen] =
|
|
15586
|
-
const [createName, setCreateName] =
|
|
15587
|
-
const [renameTarget, setRenameTarget] =
|
|
15588
|
-
const [renameValue, setRenameValue] =
|
|
15589
|
-
const [deleteTarget, setDeleteTarget] =
|
|
15590
|
-
const uploadInputRef =
|
|
15591
|
-
const crumbFolders =
|
|
15592
|
-
const subfolders =
|
|
15593
|
-
const currentFiles =
|
|
15650
|
+
const [createOpen, setCreateOpen] = React79.useState(false);
|
|
15651
|
+
const [createName, setCreateName] = React79.useState("");
|
|
15652
|
+
const [renameTarget, setRenameTarget] = React79.useState(null);
|
|
15653
|
+
const [renameValue, setRenameValue] = React79.useState("");
|
|
15654
|
+
const [deleteTarget, setDeleteTarget] = React79.useState(null);
|
|
15655
|
+
const uploadInputRef = React79.useRef(null);
|
|
15656
|
+
const crumbFolders = React79.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
15657
|
+
const subfolders = React79.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
15658
|
+
const currentFiles = React79.useMemo(
|
|
15594
15659
|
() => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
|
|
15595
15660
|
[files, currentFolderId]
|
|
15596
15661
|
);
|
|
@@ -15822,8 +15887,8 @@ function BreadcrumbCrumb({
|
|
|
15822
15887
|
isDropTarget,
|
|
15823
15888
|
onDropPayload
|
|
15824
15889
|
}) {
|
|
15825
|
-
const [over, setOver] =
|
|
15826
|
-
const dragCounter =
|
|
15890
|
+
const [over, setOver] = React79.useState(false);
|
|
15891
|
+
const dragCounter = React79.useRef(0);
|
|
15827
15892
|
const dropHandlers = isDropTarget ? {
|
|
15828
15893
|
onDragEnter: (e) => {
|
|
15829
15894
|
if (!hasInternalPayload(e)) return;
|
|
@@ -15852,7 +15917,7 @@ function BreadcrumbCrumb({
|
|
|
15852
15917
|
}
|
|
15853
15918
|
|
|
15854
15919
|
// src/kits/query.ts
|
|
15855
|
-
var
|
|
15920
|
+
var React80 = __toESM(require("react"), 1);
|
|
15856
15921
|
|
|
15857
15922
|
// src/kits/queryUrl.ts
|
|
15858
15923
|
var historyUrlAdapter = {
|
|
@@ -15990,38 +16055,38 @@ function requestFor(params, query, paging, after) {
|
|
|
15990
16055
|
}
|
|
15991
16056
|
var toError = (e) => e instanceof Error ? e : new Error(String(e));
|
|
15992
16057
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey, paging = "page", url }) {
|
|
15993
|
-
const [base] =
|
|
16058
|
+
const [base] = React80.useState(() => {
|
|
15994
16059
|
const store = PREFS || window.PlannerPrefs;
|
|
15995
16060
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
15996
16061
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
15997
16062
|
});
|
|
15998
|
-
const [mountParams] =
|
|
15999
|
-
const address =
|
|
16000
|
-
const [query, setQuery] =
|
|
16001
|
-
const savePref =
|
|
16063
|
+
const [mountParams] = React80.useState(() => url ? (url.adapter ?? historyUrlAdapter).read() : null);
|
|
16064
|
+
const address = React80.useRef(mountParams);
|
|
16065
|
+
const [query, setQuery] = React80.useState(() => url && mountParams ? readQueryFromUrl(mountParams, url.scope, base, paging) : base);
|
|
16066
|
+
const savePref = React80.useCallback((patch2) => {
|
|
16002
16067
|
const store = PREFS || window.PlannerPrefs;
|
|
16003
16068
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
16004
16069
|
}, [prefsKey]);
|
|
16005
|
-
const [res, setRes] =
|
|
16006
|
-
const [loading, setLoading] =
|
|
16007
|
-
const [loadingMore, setLoadingMore] =
|
|
16008
|
-
const [failure, setFailure] =
|
|
16009
|
-
const [reloadToken, setReloadToken] =
|
|
16010
|
-
const moreController =
|
|
16070
|
+
const [res, setRes] = React80.useState(null);
|
|
16071
|
+
const [loading, setLoading] = React80.useState(true);
|
|
16072
|
+
const [loadingMore, setLoadingMore] = React80.useState(false);
|
|
16073
|
+
const [failure, setFailure] = React80.useState(null);
|
|
16074
|
+
const [reloadToken, setReloadToken] = React80.useState(0);
|
|
16075
|
+
const moreController = React80.useRef(null);
|
|
16011
16076
|
const depKey = (deps || []).join("|");
|
|
16012
16077
|
const paramKey = JSON.stringify(params || {});
|
|
16013
16078
|
const queryKey = JSON.stringify(query);
|
|
16014
|
-
const lifetime =
|
|
16015
|
-
|
|
16079
|
+
const lifetime = React80.useRef(null);
|
|
16080
|
+
React80.useEffect(() => {
|
|
16016
16081
|
const controller = new AbortController();
|
|
16017
16082
|
lifetime.current = controller;
|
|
16018
16083
|
return () => controller.abort();
|
|
16019
16084
|
}, []);
|
|
16020
|
-
const latest =
|
|
16021
|
-
|
|
16085
|
+
const latest = React80.useRef({ res, loading, query, params, endpoint, url, base });
|
|
16086
|
+
React80.useLayoutEffect(() => {
|
|
16022
16087
|
latest.current = { res, loading, query, params, endpoint, url, base };
|
|
16023
16088
|
});
|
|
16024
|
-
|
|
16089
|
+
React80.useEffect(() => {
|
|
16025
16090
|
const controller = new AbortController();
|
|
16026
16091
|
const { signal } = controller;
|
|
16027
16092
|
setLoading(true);
|
|
@@ -16057,7 +16122,7 @@ function useServerTable({ endpoint, params, defaults, deps, prefsKey, paging = "
|
|
|
16057
16122
|
};
|
|
16058
16123
|
}, [endpoint, queryKey, paramKey, depKey, paging, reloadToken]);
|
|
16059
16124
|
const adapter = url ? url.adapter ?? historyUrlAdapter : null;
|
|
16060
|
-
|
|
16125
|
+
React80.useEffect(() => {
|
|
16061
16126
|
if (!adapter) return;
|
|
16062
16127
|
return adapter.subscribe((params2) => {
|
|
16063
16128
|
const { url: u, base: b } = latest.current;
|
|
@@ -16407,12 +16472,12 @@ function createVersionStore(initialState, options) {
|
|
|
16407
16472
|
}
|
|
16408
16473
|
|
|
16409
16474
|
// src/kits/documentTitle.ts
|
|
16410
|
-
var
|
|
16475
|
+
var React81 = __toESM(require("react"), 1);
|
|
16411
16476
|
function formatDocumentTitle(routeTitle, appName) {
|
|
16412
|
-
return [routeTitle, appName, "Flytedesk"].filter((
|
|
16477
|
+
return [routeTitle, appName, "Flytedesk"].filter((part2) => !!part2 && part2.length > 0).join(" \xB7 ");
|
|
16413
16478
|
}
|
|
16414
16479
|
function useDocumentTitle(routeTitle, appName) {
|
|
16415
|
-
|
|
16480
|
+
React81.useEffect(() => {
|
|
16416
16481
|
if (typeof document === "undefined") return;
|
|
16417
16482
|
document.title = formatDocumentTitle(routeTitle, appName);
|
|
16418
16483
|
}, [routeTitle, appName]);
|
|
@@ -16523,6 +16588,7 @@ function useDocumentTitle(routeTitle, appName) {
|
|
|
16523
16588
|
ModeSwitch,
|
|
16524
16589
|
ModelControls,
|
|
16525
16590
|
NumberInput,
|
|
16591
|
+
OVERLAY_BREAKPOINT,
|
|
16526
16592
|
OVERLAY_CEILING,
|
|
16527
16593
|
POPOVER_BODY_MIN,
|
|
16528
16594
|
PacketCard,
|
|
@@ -16647,6 +16713,7 @@ function useDocumentTitle(routeTitle, appName) {
|
|
|
16647
16713
|
useDocumentTitle,
|
|
16648
16714
|
useFeatureStatus,
|
|
16649
16715
|
useLayerZIndex,
|
|
16716
|
+
useOverlayLayout,
|
|
16650
16717
|
usePopoverPosition,
|
|
16651
16718
|
useResponsiveRail,
|
|
16652
16719
|
useRuntimeMode,
|