@flytedan/flytebot-design-system 0.73.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 +525 -505
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +525 -505
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -937,23 +937,48 @@ function Collapsible({
|
|
|
937
937
|
}
|
|
938
938
|
|
|
939
939
|
// src/components/surfaces/Drawer.tsx
|
|
940
|
-
import * as
|
|
940
|
+
import * as React7 from "react";
|
|
941
941
|
import { createPortal as createPortal2 } from "react-dom";
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
942
|
+
|
|
943
|
+
// src/kits/useClosingAnimation.ts
|
|
944
|
+
import * as React6 from "react";
|
|
945
|
+
function useClosingAnimation(open2, onClose, durationMs) {
|
|
945
946
|
const [closing, setClosing] = React6.useState(false);
|
|
947
|
+
const timer = React6.useRef(null);
|
|
948
|
+
const cancel = React6.useCallback(() => {
|
|
949
|
+
if (timer.current !== null) clearTimeout(timer.current);
|
|
950
|
+
timer.current = null;
|
|
951
|
+
}, []);
|
|
952
|
+
React6.useEffect(() => {
|
|
953
|
+
if (!open2) {
|
|
954
|
+
cancel();
|
|
955
|
+
setClosing(false);
|
|
956
|
+
}
|
|
957
|
+
}, [open2, cancel]);
|
|
958
|
+
React6.useEffect(() => cancel, [cancel]);
|
|
946
959
|
const close2 = React6.useCallback(() => {
|
|
947
960
|
if (!onClose) return;
|
|
961
|
+
cancel();
|
|
948
962
|
setClosing(true);
|
|
949
|
-
setTimeout(
|
|
950
|
-
|
|
963
|
+
timer.current = setTimeout(() => {
|
|
964
|
+
timer.current = null;
|
|
965
|
+
onClose();
|
|
966
|
+
}, durationMs);
|
|
967
|
+
}, [onClose, durationMs, cancel]);
|
|
968
|
+
return { closing, close: close2 };
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
// src/components/surfaces/Drawer.tsx
|
|
972
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
973
|
+
function Drawer({ open: open2 = true, title, label, onClose, footer, bare = false, children, className = "", ...rest }) {
|
|
974
|
+
const asideRef = React7.useRef(null);
|
|
975
|
+
const { closing, close: close2 } = useClosingAnimation(!!open2, onClose, 210);
|
|
951
976
|
const layer = useStackedLayer({ active: !!open2, containerRef: asideRef, trap: true, onEscape: onClose ? close2 : void 0 });
|
|
952
977
|
const zIndex = useLayerZIndex(layer);
|
|
953
|
-
const titleId =
|
|
978
|
+
const titleId = React7.useId();
|
|
954
979
|
const accessibleName = bare ? label ?? (typeof title === "string" ? title : void 0) : label;
|
|
955
980
|
const unnamed = !!open2 && bare && !accessibleName;
|
|
956
|
-
|
|
981
|
+
React7.useEffect(() => {
|
|
957
982
|
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.");
|
|
958
983
|
}, [unnamed]);
|
|
959
984
|
if (!open2) return null;
|
|
@@ -974,17 +999,12 @@ function Drawer({ open: open2 = true, title, label, onClose, footer, bare = fals
|
|
|
974
999
|
}
|
|
975
1000
|
|
|
976
1001
|
// src/components/surfaces/Modal.tsx
|
|
977
|
-
import * as
|
|
1002
|
+
import * as React8 from "react";
|
|
978
1003
|
import { createPortal as createPortal3 } from "react-dom";
|
|
979
1004
|
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
980
1005
|
function Modal({ open: open2 = true, title, description, onClose, footer, wide = false, children, className = "", ...rest }) {
|
|
981
|
-
const
|
|
982
|
-
const
|
|
983
|
-
const close2 = React7.useCallback(() => {
|
|
984
|
-
if (!onClose) return;
|
|
985
|
-
setClosing(true);
|
|
986
|
-
setTimeout(onClose, 190);
|
|
987
|
-
}, [onClose]);
|
|
1006
|
+
const boxRef = React8.useRef(null);
|
|
1007
|
+
const { closing, close: close2 } = useClosingAnimation(!!open2, onClose, 190);
|
|
988
1008
|
const layer = useStackedLayer({ active: !!open2, containerRef: boxRef, trap: true, onEscape: onClose ? close2 : void 0 });
|
|
989
1009
|
const zIndex = useLayerZIndex(layer);
|
|
990
1010
|
if (!open2) return null;
|
|
@@ -1067,13 +1087,13 @@ function ScreenHead({ kicker, title, lede, actions }) {
|
|
|
1067
1087
|
}
|
|
1068
1088
|
|
|
1069
1089
|
// src/components/layout/CardGrid.tsx
|
|
1070
|
-
import * as
|
|
1090
|
+
import * as React9 from "react";
|
|
1071
1091
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1072
1092
|
function flattenFragments(children) {
|
|
1073
1093
|
const out = [];
|
|
1074
|
-
|
|
1094
|
+
React9.Children.forEach(children, (child) => {
|
|
1075
1095
|
if (child === null || child === void 0 || typeof child === "boolean") return;
|
|
1076
|
-
if (
|
|
1096
|
+
if (React9.isValidElement(child) && child.type === React9.Fragment) {
|
|
1077
1097
|
const fragmentChildren = child.props.children;
|
|
1078
1098
|
out.push(...flattenFragments(fragmentChildren));
|
|
1079
1099
|
return;
|
|
@@ -1091,7 +1111,7 @@ function CardGrid({ children, minCardWidth = 280, gap = "lg", className = "", st
|
|
|
1091
1111
|
className: ["fd-card-grid", "fd-gap-" + gap, className].filter(Boolean).join(" "),
|
|
1092
1112
|
style: { ["--card-grid-min"]: minCardWidth + "px", ...style },
|
|
1093
1113
|
children: items.map((child, i) => {
|
|
1094
|
-
if (
|
|
1114
|
+
if (React9.isValidElement(child)) {
|
|
1095
1115
|
const existingRole = child.props.role;
|
|
1096
1116
|
if (existingRole) return child;
|
|
1097
1117
|
return /* @__PURE__ */ jsx12("div", { role: "listitem", children: child }, child.key ?? i);
|
|
@@ -1141,10 +1161,10 @@ function LoadingRegion({
|
|
|
1141
1161
|
}
|
|
1142
1162
|
|
|
1143
1163
|
// src/components/loading/JobTray.tsx
|
|
1144
|
-
import * as
|
|
1164
|
+
import * as React11 from "react";
|
|
1145
1165
|
|
|
1146
1166
|
// src/kits/cornerStack.tsx
|
|
1147
|
-
import * as
|
|
1167
|
+
import * as React10 from "react";
|
|
1148
1168
|
import { createPortal as createPortal4 } from "react-dom";
|
|
1149
1169
|
var CORNER_STACK_INSET_PROPERTY = "--fd-corner-stack-inset";
|
|
1150
1170
|
var SLOTS = ["jobs", "toasts"];
|
|
@@ -1194,9 +1214,9 @@ function release(slot) {
|
|
|
1194
1214
|
slotElements.clear();
|
|
1195
1215
|
}
|
|
1196
1216
|
}
|
|
1197
|
-
var useSlotEffect = typeof document === "undefined" ?
|
|
1217
|
+
var useSlotEffect = typeof document === "undefined" ? React10.useEffect : React10.useLayoutEffect;
|
|
1198
1218
|
function useCornerStackSlot(slot) {
|
|
1199
|
-
const [element, setElement] =
|
|
1219
|
+
const [element, setElement] = React10.useState(null);
|
|
1200
1220
|
useSlotEffect(() => {
|
|
1201
1221
|
setElement(acquire(slot));
|
|
1202
1222
|
return () => {
|
|
@@ -1253,9 +1273,9 @@ function announcementFor(job) {
|
|
|
1253
1273
|
return title + ": in progress";
|
|
1254
1274
|
}
|
|
1255
1275
|
function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
|
|
1256
|
-
const [announcement, setAnnouncement] =
|
|
1257
|
-
const prevStatuses =
|
|
1258
|
-
|
|
1276
|
+
const [announcement, setAnnouncement] = React11.useState("");
|
|
1277
|
+
const prevStatuses = React11.useRef({});
|
|
1278
|
+
React11.useEffect(() => {
|
|
1259
1279
|
let next = "";
|
|
1260
1280
|
for (const job of jobs2) {
|
|
1261
1281
|
if (prevStatuses.current[job.id] !== job.status) {
|
|
@@ -1306,7 +1326,7 @@ function JobCard({ job, onDismiss }) {
|
|
|
1306
1326
|
}
|
|
1307
1327
|
|
|
1308
1328
|
// src/components/loading/PhasedProgress.tsx
|
|
1309
|
-
import * as
|
|
1329
|
+
import * as React12 from "react";
|
|
1310
1330
|
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1311
1331
|
var ICON = {
|
|
1312
1332
|
pending: "ph-circle",
|
|
@@ -1319,9 +1339,9 @@ function textOf2(node) {
|
|
|
1319
1339
|
return "";
|
|
1320
1340
|
}
|
|
1321
1341
|
function PhasedProgress({ phases, summary, className = "" }) {
|
|
1322
|
-
const [announcement, setAnnouncement] =
|
|
1323
|
-
const prevStatuses =
|
|
1324
|
-
|
|
1342
|
+
const [announcement, setAnnouncement] = React12.useState("");
|
|
1343
|
+
const prevStatuses = React12.useRef({});
|
|
1344
|
+
React12.useEffect(() => {
|
|
1325
1345
|
let next = "";
|
|
1326
1346
|
for (const phase of phases) {
|
|
1327
1347
|
if (prevStatuses.current[phase.id] !== phase.status) {
|
|
@@ -1401,12 +1421,12 @@ function Spinner({ size = "md", label = "Loading", className = "", style, ...res
|
|
|
1401
1421
|
}
|
|
1402
1422
|
|
|
1403
1423
|
// src/components/navigation/SidebarNav.tsx
|
|
1404
|
-
import * as
|
|
1424
|
+
import * as React13 from "react";
|
|
1405
1425
|
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1406
1426
|
function Tip({ label, children }) {
|
|
1407
1427
|
return /* @__PURE__ */ jsx20("span", { title: label, style: { display: "inline-flex", flex: "none" }, children });
|
|
1408
1428
|
}
|
|
1409
|
-
var SidebarNav =
|
|
1429
|
+
var SidebarNav = React13.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open: open2 = false, className = "", ...rest }, ref) {
|
|
1410
1430
|
return /* @__PURE__ */ jsxs14(
|
|
1411
1431
|
"nav",
|
|
1412
1432
|
{
|
|
@@ -1445,15 +1465,15 @@ var SidebarNav = React12.forwardRef(function SidebarNav2({ brand, groups = [], c
|
|
|
1445
1465
|
});
|
|
1446
1466
|
|
|
1447
1467
|
// src/components/navigation/Topbar.tsx
|
|
1448
|
-
import * as
|
|
1468
|
+
import * as React15 from "react";
|
|
1449
1469
|
|
|
1450
1470
|
// src/kits/useIsNarrow.ts
|
|
1451
|
-
import * as
|
|
1471
|
+
import * as React14 from "react";
|
|
1452
1472
|
function useIsNarrow(breakpoint) {
|
|
1453
|
-
const [narrow, setNarrow] =
|
|
1473
|
+
const [narrow, setNarrow] = React14.useState(
|
|
1454
1474
|
() => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
1455
1475
|
);
|
|
1456
|
-
|
|
1476
|
+
React14.useEffect(() => {
|
|
1457
1477
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1458
1478
|
const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
1459
1479
|
const apply = () => setNarrow(mq.matches);
|
|
@@ -1477,11 +1497,11 @@ function Topbar({
|
|
|
1477
1497
|
...rest
|
|
1478
1498
|
}) {
|
|
1479
1499
|
const narrow = useIsNarrow(overflowBreakpoint);
|
|
1480
|
-
const [moreOpen, setMoreOpen] =
|
|
1481
|
-
const moreRef =
|
|
1500
|
+
const [moreOpen, setMoreOpen] = React15.useState(false);
|
|
1501
|
+
const moreRef = React15.useRef(null);
|
|
1482
1502
|
return /* @__PURE__ */ jsxs15("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
|
|
1483
1503
|
onMenu ? /* @__PURE__ */ jsx21("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ jsx21("i", { className: "ph ph-list" }) }) : null,
|
|
1484
|
-
/* @__PURE__ */ jsx21("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs15(
|
|
1504
|
+
/* @__PURE__ */ jsx21("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs15(React15.Fragment, { children: [
|
|
1485
1505
|
i > 0 ? /* @__PURE__ */ jsx21("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
|
|
1486
1506
|
i === crumbs.length - 1 ? (
|
|
1487
1507
|
// MP-141: the current crumb mixes a static route label with (usually) a
|
|
@@ -1534,7 +1554,7 @@ function Topbar({
|
|
|
1534
1554
|
}
|
|
1535
1555
|
|
|
1536
1556
|
// src/kits/useResponsiveRail.ts
|
|
1537
|
-
import * as
|
|
1557
|
+
import * as React16 from "react";
|
|
1538
1558
|
|
|
1539
1559
|
// src/kits/overlayLayout.ts
|
|
1540
1560
|
var OVERLAY_BREAKPOINT = 1024;
|
|
@@ -1545,26 +1565,26 @@ function useOverlayLayout() {
|
|
|
1545
1565
|
// src/kits/useResponsiveRail.ts
|
|
1546
1566
|
function useResponsiveRail(options = {}) {
|
|
1547
1567
|
const { breakpoint = OVERLAY_BREAKPOINT, initialOpen = true, onPersist } = options;
|
|
1548
|
-
const navRef =
|
|
1568
|
+
const navRef = React16.useRef(null);
|
|
1549
1569
|
const overlay = useIsNarrow(breakpoint);
|
|
1550
|
-
const [open2, setOpenRaw] =
|
|
1551
|
-
const setOpen =
|
|
1570
|
+
const [open2, setOpenRaw] = React16.useState(() => overlay ? false : initialOpen);
|
|
1571
|
+
const setOpen = React16.useCallback(
|
|
1552
1572
|
(value) => {
|
|
1553
1573
|
setOpenRaw(value);
|
|
1554
1574
|
if (!overlay) onPersist?.(value);
|
|
1555
1575
|
},
|
|
1556
1576
|
[overlay, onPersist]
|
|
1557
1577
|
);
|
|
1558
|
-
const toggle =
|
|
1559
|
-
const close2 =
|
|
1560
|
-
const lastOverlay =
|
|
1561
|
-
|
|
1578
|
+
const toggle = React16.useCallback(() => setOpen(!open2), [open2, setOpen]);
|
|
1579
|
+
const close2 = React16.useCallback(() => setOpenRaw(false), []);
|
|
1580
|
+
const lastOverlay = React16.useRef(overlay);
|
|
1581
|
+
React16.useEffect(() => {
|
|
1562
1582
|
if (lastOverlay.current === overlay) return;
|
|
1563
1583
|
lastOverlay.current = overlay;
|
|
1564
1584
|
setOpenRaw(!overlay);
|
|
1565
1585
|
}, [overlay]);
|
|
1566
1586
|
const layer = useStackedLayer({ active: overlay && open2, containerRef: navRef, trap: true, onEscape: close2 });
|
|
1567
|
-
|
|
1587
|
+
React16.useEffect(() => {
|
|
1568
1588
|
if (!overlay || !open2) return;
|
|
1569
1589
|
const previousOverflow = document.body.style.overflow;
|
|
1570
1590
|
document.body.style.overflow = "hidden";
|
|
@@ -1691,20 +1711,20 @@ function installFlytedeskFavicon(url) {
|
|
|
1691
1711
|
}
|
|
1692
1712
|
|
|
1693
1713
|
// src/components/navigation/Tabs.tsx
|
|
1694
|
-
import * as
|
|
1714
|
+
import * as React17 from "react";
|
|
1695
1715
|
import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1696
1716
|
var FADE_WIDTH = 32;
|
|
1697
1717
|
function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
1698
|
-
const strip =
|
|
1699
|
-
const [more, setMore] =
|
|
1700
|
-
const measure =
|
|
1718
|
+
const strip = React17.useRef(null);
|
|
1719
|
+
const [more, setMore] = React17.useState({ start: false, end: false });
|
|
1720
|
+
const measure = React17.useCallback(() => {
|
|
1701
1721
|
const el = strip.current;
|
|
1702
1722
|
if (!el) return;
|
|
1703
1723
|
const start = el.scrollLeft > 1;
|
|
1704
1724
|
const end = el.scrollLeft + el.clientWidth < el.scrollWidth - 1;
|
|
1705
1725
|
setMore((m) => m.start === start && m.end === end ? m : { start, end });
|
|
1706
1726
|
}, []);
|
|
1707
|
-
|
|
1727
|
+
React17.useLayoutEffect(() => {
|
|
1708
1728
|
const el = strip.current;
|
|
1709
1729
|
measure();
|
|
1710
1730
|
if (!el || typeof ResizeObserver === "undefined") return;
|
|
@@ -1712,7 +1732,7 @@ function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
|
1712
1732
|
observer.observe(el);
|
|
1713
1733
|
return () => observer.disconnect();
|
|
1714
1734
|
}, [measure, tabs]);
|
|
1715
|
-
const revealActive =
|
|
1735
|
+
const revealActive = React17.useCallback(() => {
|
|
1716
1736
|
const el = strip.current;
|
|
1717
1737
|
const active = el?.querySelector('[aria-selected="true"]');
|
|
1718
1738
|
if (!el || !active || el.scrollWidth <= el.clientWidth) return;
|
|
@@ -1722,9 +1742,9 @@ function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
|
|
|
1722
1742
|
else if (tab.right > box.right - FADE_WIDTH) el.scrollLeft += tab.right - box.right + FADE_WIDTH;
|
|
1723
1743
|
measure();
|
|
1724
1744
|
}, [measure]);
|
|
1725
|
-
|
|
1745
|
+
React17.useLayoutEffect(revealActive, [value, revealActive]);
|
|
1726
1746
|
const tabKeys = tabs.map((t) => typeof t === "string" ? t : t.value).join(",");
|
|
1727
|
-
|
|
1747
|
+
React17.useLayoutEffect(() => {
|
|
1728
1748
|
const el = strip.current;
|
|
1729
1749
|
if (!el || typeof ResizeObserver === "undefined") return;
|
|
1730
1750
|
const observer = new ResizeObserver(revealActive);
|
|
@@ -1979,15 +1999,15 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
|
|
|
1979
1999
|
}
|
|
1980
2000
|
|
|
1981
2001
|
// src/components/feedback/ToastProvider.tsx
|
|
1982
|
-
import * as
|
|
2002
|
+
import * as React18 from "react";
|
|
1983
2003
|
import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1984
2004
|
var DEFAULT_TOAST_DURATION_MS = 5e3;
|
|
1985
|
-
var ToastContext =
|
|
2005
|
+
var ToastContext = React18.createContext(null);
|
|
1986
2006
|
function ToastProvider({ children }) {
|
|
1987
|
-
const [items, setItems] =
|
|
1988
|
-
const timers =
|
|
1989
|
-
const nextId =
|
|
1990
|
-
const dismiss =
|
|
2007
|
+
const [items, setItems] = React18.useState([]);
|
|
2008
|
+
const timers = React18.useRef(/* @__PURE__ */ new Map());
|
|
2009
|
+
const nextId = React18.useRef(1);
|
|
2010
|
+
const dismiss = React18.useCallback((id) => {
|
|
1991
2011
|
setItems((current2) => current2.filter((item) => item.id !== id));
|
|
1992
2012
|
const timer = timers.current.get(id);
|
|
1993
2013
|
if (timer !== void 0) {
|
|
@@ -1995,7 +2015,7 @@ function ToastProvider({ children }) {
|
|
|
1995
2015
|
timers.current.delete(id);
|
|
1996
2016
|
}
|
|
1997
2017
|
}, []);
|
|
1998
|
-
const show =
|
|
2018
|
+
const show = React18.useCallback(
|
|
1999
2019
|
(title, options = {}) => {
|
|
2000
2020
|
const { tone = "success", duration = DEFAULT_TOAST_DURATION_MS } = options;
|
|
2001
2021
|
const id = nextId.current++;
|
|
@@ -2004,36 +2024,36 @@ function ToastProvider({ children }) {
|
|
|
2004
2024
|
},
|
|
2005
2025
|
[dismiss]
|
|
2006
2026
|
);
|
|
2007
|
-
|
|
2027
|
+
React18.useEffect(() => {
|
|
2008
2028
|
const pending = timers.current;
|
|
2009
2029
|
return () => {
|
|
2010
2030
|
pending.forEach(clearTimeout);
|
|
2011
2031
|
pending.clear();
|
|
2012
2032
|
};
|
|
2013
2033
|
}, []);
|
|
2014
|
-
const api =
|
|
2034
|
+
const api = React18.useMemo(() => ({ show }), [show]);
|
|
2015
2035
|
return /* @__PURE__ */ jsxs26(ToastContext.Provider, { value: api, children: [
|
|
2016
2036
|
children,
|
|
2017
2037
|
/* @__PURE__ */ jsx33(CornerStackPortal, { slot: "toasts", children: /* @__PURE__ */ jsx33("div", { className: "fd-toast-region", "aria-live": "polite", children: items.map((item) => /* @__PURE__ */ jsx33(Toast, { title: item.title, tone: item.tone, onDismiss: () => dismiss(item.id) }, item.id)) }) })
|
|
2018
2038
|
] });
|
|
2019
2039
|
}
|
|
2020
2040
|
function useToast() {
|
|
2021
|
-
const api =
|
|
2041
|
+
const api = React18.useContext(ToastContext);
|
|
2022
2042
|
if (!api) throw new Error("useToast must be used inside a <ToastProvider>");
|
|
2023
2043
|
return api;
|
|
2024
2044
|
}
|
|
2025
2045
|
|
|
2026
2046
|
// src/components/feedback/Tooltip.tsx
|
|
2027
|
-
import * as
|
|
2047
|
+
import * as React20 from "react";
|
|
2028
2048
|
|
|
2029
2049
|
// src/components/feedback/useTooltip.tsx
|
|
2030
|
-
import * as
|
|
2050
|
+
import * as React19 from "react";
|
|
2031
2051
|
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
2032
2052
|
var CLOSE_DELAY_MS = 120;
|
|
2033
2053
|
var isMouse = (e) => e.pointerType === "mouse";
|
|
2034
2054
|
function TooltipBubble({ open: open2, labels, placement, className, onHide, onEnter, onLeave }) {
|
|
2035
|
-
const anchorRef =
|
|
2036
|
-
const bubbleRef =
|
|
2055
|
+
const anchorRef = React19.useRef(open2.anchor);
|
|
2056
|
+
const bubbleRef = React19.useRef(null);
|
|
2037
2057
|
const pos = usePopoverPosition(true, anchorRef, {
|
|
2038
2058
|
placement: placement === "bottom" ? "bottom-center" : "top-center",
|
|
2039
2059
|
offset: 8,
|
|
@@ -2044,7 +2064,7 @@ function TooltipBubble({ open: open2, labels, placement, className, onHide, onEn
|
|
|
2044
2064
|
});
|
|
2045
2065
|
const layer = useStackedLayer({ active: true, containerRef: bubbleRef, onEscape: onHide, returnFocus: false });
|
|
2046
2066
|
const zIndex = useLayerZIndex(layer);
|
|
2047
|
-
|
|
2067
|
+
React19.useEffect(() => {
|
|
2048
2068
|
const away = (e) => {
|
|
2049
2069
|
const t = e.target;
|
|
2050
2070
|
if (open2.anchor.contains(t)) return;
|
|
@@ -2075,16 +2095,16 @@ function TooltipBubble({ open: open2, labels, placement, className, onHide, onEn
|
|
|
2075
2095
|
);
|
|
2076
2096
|
}
|
|
2077
2097
|
function useTooltip({ placement = "top", className = "" } = {}) {
|
|
2078
|
-
const [open2, setOpen] =
|
|
2079
|
-
const closeTimer =
|
|
2080
|
-
const focused =
|
|
2081
|
-
const cancelClose =
|
|
2098
|
+
const [open2, setOpen] = React19.useState(null);
|
|
2099
|
+
const closeTimer = React19.useRef(null);
|
|
2100
|
+
const focused = React19.useRef(null);
|
|
2101
|
+
const cancelClose = React19.useCallback(() => {
|
|
2082
2102
|
if (closeTimer.current) {
|
|
2083
2103
|
clearTimeout(closeTimer.current);
|
|
2084
2104
|
closeTimer.current = null;
|
|
2085
2105
|
}
|
|
2086
2106
|
}, []);
|
|
2087
|
-
const hide =
|
|
2107
|
+
const hide = React19.useCallback(() => {
|
|
2088
2108
|
cancelClose();
|
|
2089
2109
|
focused.current = null;
|
|
2090
2110
|
setOpen(null);
|
|
@@ -2104,7 +2124,7 @@ function useTooltip({ placement = "top", className = "" } = {}) {
|
|
|
2104
2124
|
setOpen((o) => o && o.reason === "hover" ? focused.current : o);
|
|
2105
2125
|
}, CLOSE_DELAY_MS);
|
|
2106
2126
|
};
|
|
2107
|
-
|
|
2127
|
+
React19.useEffect(() => cancelClose, [cancelClose]);
|
|
2108
2128
|
const labels = /* @__PURE__ */ new Map();
|
|
2109
2129
|
const bind = (id, label) => {
|
|
2110
2130
|
labels.set(id, label);
|
|
@@ -2157,17 +2177,17 @@ function useTooltip({ placement = "top", className = "" } = {}) {
|
|
|
2157
2177
|
// src/components/feedback/Tooltip.tsx
|
|
2158
2178
|
import { jsx as jsx35, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2159
2179
|
function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
2160
|
-
const id =
|
|
2180
|
+
const id = React20.useId();
|
|
2161
2181
|
const descId = id + "-desc";
|
|
2162
2182
|
const tip = useTooltip({ placement, className });
|
|
2163
|
-
const described =
|
|
2183
|
+
const described = React20.isValidElement(children) ? React20.cloneElement(children, {
|
|
2164
2184
|
"aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
|
|
2165
2185
|
}) : children;
|
|
2166
2186
|
return /* @__PURE__ */ jsxs27(
|
|
2167
2187
|
"span",
|
|
2168
2188
|
{
|
|
2169
2189
|
className: "fd-tooltip-anchor",
|
|
2170
|
-
"aria-describedby":
|
|
2190
|
+
"aria-describedby": React20.isValidElement(children) ? void 0 : descId,
|
|
2171
2191
|
...tip.bind(id, label),
|
|
2172
2192
|
children: [
|
|
2173
2193
|
described,
|
|
@@ -2179,16 +2199,16 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
2179
2199
|
}
|
|
2180
2200
|
|
|
2181
2201
|
// src/components/data/AnimNum.tsx
|
|
2182
|
-
import * as
|
|
2202
|
+
import * as React21 from "react";
|
|
2183
2203
|
import { Fragment as Fragment6, jsx as jsx36 } from "react/jsx-runtime";
|
|
2184
2204
|
function shouldSkipEasing() {
|
|
2185
2205
|
if (typeof document !== "undefined" && document.hidden) return true;
|
|
2186
2206
|
return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
|
|
2187
2207
|
}
|
|
2188
2208
|
function AnimNum({ value, format, duration = 550 }) {
|
|
2189
|
-
const [display, setDisplay] =
|
|
2190
|
-
const prev =
|
|
2191
|
-
|
|
2209
|
+
const [display, setDisplay] = React21.useState(value);
|
|
2210
|
+
const prev = React21.useRef(value);
|
|
2211
|
+
React21.useEffect(() => {
|
|
2192
2212
|
const from = prev.current;
|
|
2193
2213
|
const to = value;
|
|
2194
2214
|
prev.current = to;
|
|
@@ -2216,14 +2236,14 @@ function AnimNum({ value, format, duration = 550 }) {
|
|
|
2216
2236
|
}
|
|
2217
2237
|
|
|
2218
2238
|
// src/components/data/TrendChart.tsx
|
|
2219
|
-
import * as
|
|
2239
|
+
import * as React24 from "react";
|
|
2220
2240
|
|
|
2221
2241
|
// src/components/useMeasuredWidth.ts
|
|
2222
|
-
import * as
|
|
2242
|
+
import * as React22 from "react";
|
|
2223
2243
|
function useMeasuredWidth(fallback) {
|
|
2224
|
-
const [element, setElement] =
|
|
2225
|
-
const [width, setWidth] =
|
|
2226
|
-
|
|
2244
|
+
const [element, setElement] = React22.useState(null);
|
|
2245
|
+
const [width, setWidth] = React22.useState(fallback);
|
|
2246
|
+
React22.useLayoutEffect(() => {
|
|
2227
2247
|
if (!element || typeof ResizeObserver === "undefined") return;
|
|
2228
2248
|
const measure = () => {
|
|
2229
2249
|
const measured = Math.round(element.getBoundingClientRect().width);
|
|
@@ -2238,7 +2258,7 @@ function useMeasuredWidth(fallback) {
|
|
|
2238
2258
|
}
|
|
2239
2259
|
|
|
2240
2260
|
// src/components/data/SegmentedMeter.tsx
|
|
2241
|
-
import * as
|
|
2261
|
+
import * as React23 from "react";
|
|
2242
2262
|
|
|
2243
2263
|
// src/kits/files.ts
|
|
2244
2264
|
function formatBytes(n) {
|
|
@@ -2443,7 +2463,7 @@ function SegmentedMeter({
|
|
|
2443
2463
|
const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
|
|
2444
2464
|
const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
|
|
2445
2465
|
const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
|
|
2446
|
-
const generatedId =
|
|
2466
|
+
const generatedId = React23.useId();
|
|
2447
2467
|
const uid2 = id || generatedId;
|
|
2448
2468
|
return /* @__PURE__ */ jsxs28("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
|
|
2449
2469
|
label || showTotal ? /* @__PURE__ */ jsxs28("div", { className: "fd-segmeter-head", children: [
|
|
@@ -2594,8 +2614,8 @@ function TrendChart({
|
|
|
2594
2614
|
onRetry,
|
|
2595
2615
|
className = ""
|
|
2596
2616
|
}) {
|
|
2597
|
-
const [activeId, setActiveId] =
|
|
2598
|
-
const [pointTip, setPointTip] =
|
|
2617
|
+
const [activeId, setActiveId] = React24.useState(null);
|
|
2618
|
+
const [pointTip, setPointTip] = React24.useState(null);
|
|
2599
2619
|
const isEmpty = state === "ready" && (!categories.length || !series.length || series.every((s) => !s.values.length));
|
|
2600
2620
|
const effectiveState = isEmpty ? "empty" : state;
|
|
2601
2621
|
const [plotRef, VBW] = useMeasuredWidth(INITIAL_WIDTH);
|
|
@@ -2709,7 +2729,7 @@ function TrendChart({
|
|
|
2709
2729
|
}
|
|
2710
2730
|
|
|
2711
2731
|
// src/components/data/DonutChart.tsx
|
|
2712
|
-
import * as
|
|
2732
|
+
import * as React25 from "react";
|
|
2713
2733
|
import { jsx as jsx40, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2714
2734
|
function DonutChart({
|
|
2715
2735
|
segments,
|
|
@@ -2724,7 +2744,7 @@ function DonutChart({
|
|
|
2724
2744
|
onRetry,
|
|
2725
2745
|
className = ""
|
|
2726
2746
|
}) {
|
|
2727
|
-
const [activeId, setActiveId] =
|
|
2747
|
+
const [activeId, setActiveId] = React25.useState(null);
|
|
2728
2748
|
const items = segments.filter((s) => Number(s.value) > 0);
|
|
2729
2749
|
const total = items.reduce((n, s) => n + Number(s.value), 0);
|
|
2730
2750
|
const isEmpty = state === "ready" && (!items.length || total <= 0);
|
|
@@ -2816,7 +2836,7 @@ function DonutChart({
|
|
|
2816
2836
|
}
|
|
2817
2837
|
|
|
2818
2838
|
// src/components/data/BarList.tsx
|
|
2819
|
-
import * as
|
|
2839
|
+
import * as React26 from "react";
|
|
2820
2840
|
import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2821
2841
|
var wholePercent = (share) => formatPercent(Math.round(share * 100));
|
|
2822
2842
|
function BarList({
|
|
@@ -2833,7 +2853,7 @@ function BarList({
|
|
|
2833
2853
|
onRetry,
|
|
2834
2854
|
className = ""
|
|
2835
2855
|
}) {
|
|
2836
|
-
const ordered =
|
|
2856
|
+
const ordered = React26.useMemo(() => {
|
|
2837
2857
|
const list = sort ? [...rows].sort((a, b) => Number(b.value) - Number(a.value)) : rows;
|
|
2838
2858
|
return maxRows ? list.slice(0, maxRows) : list;
|
|
2839
2859
|
}, [rows, sort, maxRows]);
|
|
@@ -2975,7 +2995,7 @@ function FunnelChart({
|
|
|
2975
2995
|
}
|
|
2976
2996
|
|
|
2977
2997
|
// src/components/data/Clamp.tsx
|
|
2978
|
-
import * as
|
|
2998
|
+
import * as React27 from "react";
|
|
2979
2999
|
import { jsx as jsx43, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2980
3000
|
function Clamp({
|
|
2981
3001
|
children,
|
|
@@ -2987,16 +3007,16 @@ function Clamp({
|
|
|
2987
3007
|
onToggle,
|
|
2988
3008
|
className = ""
|
|
2989
3009
|
}) {
|
|
2990
|
-
const [open2, setOpen] =
|
|
2991
|
-
const [overflows, setOverflows] =
|
|
2992
|
-
const bodyRef =
|
|
2993
|
-
const charClamped =
|
|
3010
|
+
const [open2, setOpen] = React27.useState(false);
|
|
3011
|
+
const [overflows, setOverflows] = React27.useState(false);
|
|
3012
|
+
const bodyRef = React27.useRef(null);
|
|
3013
|
+
const charClamped = React27.useMemo(() => {
|
|
2994
3014
|
if (open2 || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
|
|
2995
3015
|
const cut = text.slice(0, maxChars);
|
|
2996
3016
|
const at = cut.lastIndexOf(" ");
|
|
2997
3017
|
return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
2998
3018
|
}, [text, maxChars, open2]);
|
|
2999
|
-
|
|
3019
|
+
React27.useLayoutEffect(() => {
|
|
3000
3020
|
const node = bodyRef.current;
|
|
3001
3021
|
if (maxChars || !node || !maxHeight) return;
|
|
3002
3022
|
const measure = () => {
|
|
@@ -3254,16 +3274,16 @@ function StackedRows({ columns, rows, rowKey, loading, stale, skeletonRows, sort
|
|
|
3254
3274
|
}
|
|
3255
3275
|
|
|
3256
3276
|
// src/components/data/FilterBar.tsx
|
|
3257
|
-
import * as
|
|
3277
|
+
import * as React33 from "react";
|
|
3258
3278
|
|
|
3259
3279
|
// src/components/forms/NumberInput.tsx
|
|
3260
|
-
import * as
|
|
3280
|
+
import * as React30 from "react";
|
|
3261
3281
|
|
|
3262
3282
|
// src/components/forms/field.tsx
|
|
3263
|
-
import * as
|
|
3283
|
+
import * as React28 from "react";
|
|
3264
3284
|
import { jsx as jsx46, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3265
3285
|
function useFieldId(id) {
|
|
3266
|
-
const generated =
|
|
3286
|
+
const generated = React28.useId();
|
|
3267
3287
|
return id || generated;
|
|
3268
3288
|
}
|
|
3269
3289
|
function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
|
|
@@ -3282,10 +3302,10 @@ function HiddenFieldLabel({ id, children }) {
|
|
|
3282
3302
|
}
|
|
3283
3303
|
|
|
3284
3304
|
// src/components/useLatest.ts
|
|
3285
|
-
import * as
|
|
3305
|
+
import * as React29 from "react";
|
|
3286
3306
|
function useLatest(value) {
|
|
3287
|
-
const ref =
|
|
3288
|
-
|
|
3307
|
+
const ref = React29.useRef(value);
|
|
3308
|
+
React29.useInsertionEffect(() => {
|
|
3289
3309
|
ref.current = value;
|
|
3290
3310
|
});
|
|
3291
3311
|
return ref;
|
|
@@ -3368,20 +3388,20 @@ function NumberInput({
|
|
|
3368
3388
|
const n = typeof v === "number" ? v : parseNumberText(v);
|
|
3369
3389
|
return n == null || Number.isNaN(n) ? null : n;
|
|
3370
3390
|
};
|
|
3371
|
-
const [text, setText] =
|
|
3372
|
-
const [editing, setEditing] =
|
|
3391
|
+
const [text, setText] = React30.useState(() => toText(value));
|
|
3392
|
+
const [editing, setEditing] = React30.useState(false);
|
|
3373
3393
|
const parsed = parseNumberText(text);
|
|
3374
3394
|
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;
|
|
3375
3395
|
const valid = invalidMessage == null;
|
|
3376
|
-
const committedRef =
|
|
3396
|
+
const committedRef = React30.useRef(toNumber(value));
|
|
3377
3397
|
const onChangeRef = useLatest(onChange);
|
|
3378
3398
|
const onValidityChangeRef = useLatest(onValidityChange);
|
|
3379
|
-
const focusedRef =
|
|
3380
|
-
|
|
3399
|
+
const focusedRef = React30.useRef(false);
|
|
3400
|
+
React30.useEffect(() => {
|
|
3381
3401
|
committedRef.current = toNumber(value);
|
|
3382
3402
|
if (!focusedRef.current) setText(toText(value));
|
|
3383
3403
|
}, [value]);
|
|
3384
|
-
|
|
3404
|
+
React30.useLayoutEffect(() => {
|
|
3385
3405
|
onValidityChangeRef.current?.(valid);
|
|
3386
3406
|
}, [valid, onValidityChangeRef]);
|
|
3387
3407
|
const fire = (n) => {
|
|
@@ -3397,7 +3417,7 @@ function NumberInput({
|
|
|
3397
3417
|
return true;
|
|
3398
3418
|
};
|
|
3399
3419
|
const bumpRef = useLatest(bump);
|
|
3400
|
-
const holdTimer =
|
|
3420
|
+
const holdTimer = React30.useRef(null);
|
|
3401
3421
|
const release2 = () => {
|
|
3402
3422
|
if (holdTimer.current) clearTimeout(holdTimer.current);
|
|
3403
3423
|
holdTimer.current = null;
|
|
@@ -3416,7 +3436,7 @@ function NumberInput({
|
|
|
3416
3436
|
};
|
|
3417
3437
|
holdTimer.current = setTimeout(tick, HOLD_DELAY_MS);
|
|
3418
3438
|
};
|
|
3419
|
-
|
|
3439
|
+
React30.useEffect(() => () => {
|
|
3420
3440
|
if (holdTimer.current) clearTimeout(holdTimer.current);
|
|
3421
3441
|
}, []);
|
|
3422
3442
|
const current2 = committedRef.current;
|
|
@@ -3519,7 +3539,7 @@ function NumberInput({
|
|
|
3519
3539
|
}
|
|
3520
3540
|
|
|
3521
3541
|
// src/components/forms/DatePicker.tsx
|
|
3522
|
-
import * as
|
|
3542
|
+
import * as React31 from "react";
|
|
3523
3543
|
import { jsx as jsx48, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3524
3544
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
3525
3545
|
var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
@@ -3552,10 +3572,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3552
3572
|
const today = /* @__PURE__ */ new Date();
|
|
3553
3573
|
const sel = range ? value || {} : { start: value, end: value };
|
|
3554
3574
|
const anchor = parse(sel.start) || parse(initialMonth) || today;
|
|
3555
|
-
const [vy, setVy] =
|
|
3556
|
-
const [vm, setVm] =
|
|
3557
|
-
const [mode2, setMode] =
|
|
3558
|
-
const [hover, setHover] =
|
|
3575
|
+
const [vy, setVy] = React31.useState(anchor.getFullYear());
|
|
3576
|
+
const [vm, setVm] = React31.useState(anchor.getMonth());
|
|
3577
|
+
const [mode2, setMode] = React31.useState("days");
|
|
3578
|
+
const [hover, setHover] = React31.useState(null);
|
|
3559
3579
|
const s = parse(sel.start), e = parse(sel.end);
|
|
3560
3580
|
const hoverEnd = range && s && !e && hover ? parse(hover) : null;
|
|
3561
3581
|
const inRange = (d) => {
|
|
@@ -3566,12 +3586,12 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3566
3586
|
const isEnd = (d) => !!e && iso(d) === iso(e);
|
|
3567
3587
|
const isEdge = (d) => isStart(d) || isEnd(d);
|
|
3568
3588
|
const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
|
|
3569
|
-
const [activeDate, setActiveDate] =
|
|
3589
|
+
const [activeDate, setActiveDate] = React31.useState(() => {
|
|
3570
3590
|
if (s) return s;
|
|
3571
3591
|
if (sameMonth(today, anchor.getFullYear(), anchor.getMonth())) return today;
|
|
3572
3592
|
return new Date(anchor.getFullYear(), anchor.getMonth(), 1);
|
|
3573
3593
|
});
|
|
3574
|
-
const calRef =
|
|
3594
|
+
const calRef = React31.useRef(null);
|
|
3575
3595
|
const pageToShow = (y, m) => {
|
|
3576
3596
|
const idx = y * 12 + m, firstIdx = vy * 12 + vm, secondIdx = firstIdx + 1;
|
|
3577
3597
|
if (idx === firstIdx || months > 1 && idx === secondIdx) return;
|
|
@@ -3588,7 +3608,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3588
3608
|
setActiveDate(next);
|
|
3589
3609
|
pageToShow(next.getFullYear(), next.getMonth());
|
|
3590
3610
|
};
|
|
3591
|
-
|
|
3611
|
+
React31.useEffect(() => {
|
|
3592
3612
|
const el = calRef.current?.querySelector('[data-iso="' + iso(activeDate) + '"]');
|
|
3593
3613
|
if (el) el.focus({ preventScroll: true });
|
|
3594
3614
|
}, [activeDate, vy, vm]);
|
|
@@ -3781,9 +3801,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3781
3801
|
}
|
|
3782
3802
|
function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, "aria-label": hiddenLabel, ...rest }) {
|
|
3783
3803
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
|
|
3784
|
-
const [open2, setOpen] =
|
|
3785
|
-
const rootRef =
|
|
3786
|
-
const boxRef =
|
|
3804
|
+
const [open2, setOpen] = React31.useState(false);
|
|
3805
|
+
const rootRef = React31.useRef(null);
|
|
3806
|
+
const boxRef = React31.useRef(null);
|
|
3787
3807
|
const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
|
|
3788
3808
|
const toggle = () => {
|
|
3789
3809
|
if (!disabled) setOpen(!open2);
|
|
@@ -3872,9 +3892,9 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
|
|
|
3872
3892
|
}
|
|
3873
3893
|
|
|
3874
3894
|
// src/components/forms/listbox.ts
|
|
3875
|
-
import * as
|
|
3895
|
+
import * as React32 from "react";
|
|
3876
3896
|
function useListboxNav({ count, onSelect }) {
|
|
3877
|
-
const [active, setActive] =
|
|
3897
|
+
const [active, setActive] = React32.useState(-1);
|
|
3878
3898
|
return {
|
|
3879
3899
|
active,
|
|
3880
3900
|
setActive,
|
|
@@ -3887,7 +3907,7 @@ function useListboxNav({ count, onSelect }) {
|
|
|
3887
3907
|
};
|
|
3888
3908
|
}
|
|
3889
3909
|
function useListboxScrollIntoView(active, listRef, enabled) {
|
|
3890
|
-
|
|
3910
|
+
React32.useEffect(() => {
|
|
3891
3911
|
if (!enabled || active < 0 || !listRef.current) return;
|
|
3892
3912
|
const list = listRef.current;
|
|
3893
3913
|
const el = list.querySelector('[data-i="' + active + '"]');
|
|
@@ -4108,13 +4128,13 @@ function MultiSelectPanel({
|
|
|
4108
4128
|
onClose
|
|
4109
4129
|
}) {
|
|
4110
4130
|
const allowedOps = operatorsFor(field);
|
|
4111
|
-
const [draftOperator, setDraftOperator] =
|
|
4131
|
+
const [draftOperator, setDraftOperator] = React33.useState(value?.operator ?? allowedOps[0]);
|
|
4112
4132
|
const operator = allowedOps.length === 1 ? allowedOps[0] : value?.operator ?? draftOperator;
|
|
4113
4133
|
const selected = value?.values ?? [];
|
|
4114
4134
|
const selectedRef = useLatest(selected);
|
|
4115
4135
|
const operatorRef = useLatest(operator);
|
|
4116
|
-
const mountedRef =
|
|
4117
|
-
|
|
4136
|
+
const mountedRef = React33.useRef(true);
|
|
4137
|
+
React33.useEffect(() => {
|
|
4118
4138
|
mountedRef.current = true;
|
|
4119
4139
|
return () => {
|
|
4120
4140
|
mountedRef.current = false;
|
|
@@ -4128,20 +4148,20 @@ function MultiSelectPanel({
|
|
|
4128
4148
|
if (selectedRef.current.length > 0) commit(selectedRef.current, op);
|
|
4129
4149
|
else setDraftOperator(op);
|
|
4130
4150
|
};
|
|
4131
|
-
const [mode2, setMode] =
|
|
4132
|
-
const [query, setQuery] =
|
|
4133
|
-
const [asyncState, setAsyncState] =
|
|
4151
|
+
const [mode2, setMode] = React33.useState("search");
|
|
4152
|
+
const [query, setQuery] = React33.useState("");
|
|
4153
|
+
const [asyncState, setAsyncState] = React33.useState(
|
|
4134
4154
|
{ options: null, loading: !!field.loadOptions, error: false }
|
|
4135
4155
|
);
|
|
4136
|
-
const [retryTick, setRetryTick] =
|
|
4137
|
-
const inputRef =
|
|
4138
|
-
const listRef =
|
|
4139
|
-
const listId =
|
|
4156
|
+
const [retryTick, setRetryTick] = React33.useState(0);
|
|
4157
|
+
const inputRef = React33.useRef(null);
|
|
4158
|
+
const listRef = React33.useRef(null);
|
|
4159
|
+
const listId = React33.useId();
|
|
4140
4160
|
const loadOptionsRef = useLatest(field.loadOptions);
|
|
4141
|
-
|
|
4161
|
+
React33.useEffect(() => {
|
|
4142
4162
|
inputRef.current?.focus();
|
|
4143
4163
|
}, []);
|
|
4144
|
-
|
|
4164
|
+
React33.useEffect(() => {
|
|
4145
4165
|
const load = loadOptionsRef.current;
|
|
4146
4166
|
if (!load) return;
|
|
4147
4167
|
const controller = new AbortController();
|
|
@@ -4174,17 +4194,17 @@ function MultiSelectPanel({
|
|
|
4174
4194
|
};
|
|
4175
4195
|
const nav = useListboxNav({ count: options.length, onSelect: (i) => toggle(options[i]) });
|
|
4176
4196
|
useListboxScrollIntoView(nav.active, listRef, hasListbox);
|
|
4177
|
-
|
|
4197
|
+
React33.useEffect(() => {
|
|
4178
4198
|
nav.setActive(0);
|
|
4179
4199
|
}, [query, options.length]);
|
|
4180
4200
|
const activeId = hasListbox && options[nav.active] ? listId + "-opt-" + nav.active : void 0;
|
|
4181
4201
|
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" : "";
|
|
4182
|
-
const [pasteText, setPasteText] =
|
|
4183
|
-
const [pasteLoading, setPasteLoading] =
|
|
4184
|
-
const [unmatchedTokens, setUnmatchedTokens] =
|
|
4185
|
-
const [pasteError, setPasteError] =
|
|
4186
|
-
const pasteWrapRef =
|
|
4187
|
-
|
|
4202
|
+
const [pasteText, setPasteText] = React33.useState("");
|
|
4203
|
+
const [pasteLoading, setPasteLoading] = React33.useState(false);
|
|
4204
|
+
const [unmatchedTokens, setUnmatchedTokens] = React33.useState([]);
|
|
4205
|
+
const [pasteError, setPasteError] = React33.useState(null);
|
|
4206
|
+
const pasteWrapRef = React33.useRef(null);
|
|
4207
|
+
React33.useEffect(() => {
|
|
4188
4208
|
if (mode2 === "paste") pasteWrapRef.current?.querySelector("textarea")?.focus();
|
|
4189
4209
|
}, [mode2]);
|
|
4190
4210
|
const doResolve = () => {
|
|
@@ -4357,8 +4377,8 @@ function MultiSelectPanel({
|
|
|
4357
4377
|
);
|
|
4358
4378
|
}
|
|
4359
4379
|
function useTextValidity(onFlip) {
|
|
4360
|
-
const invalidRef =
|
|
4361
|
-
const [, rerender] =
|
|
4380
|
+
const invalidRef = React33.useRef(/* @__PURE__ */ new Set());
|
|
4381
|
+
const [, rerender] = React33.useReducer((n) => n + 1, 0);
|
|
4362
4382
|
const onFlipRef = useLatest(onFlip);
|
|
4363
4383
|
const record = (name, valid) => {
|
|
4364
4384
|
const invalid = invalidRef.current;
|
|
@@ -4401,15 +4421,15 @@ function sameValue(a, b) {
|
|
|
4401
4421
|
return true;
|
|
4402
4422
|
}
|
|
4403
4423
|
function useReseedFromProps(value, applies, reseed) {
|
|
4404
|
-
const seen =
|
|
4405
|
-
|
|
4424
|
+
const seen = React33.useRef(value);
|
|
4425
|
+
React33.useLayoutEffect(() => {
|
|
4406
4426
|
if (seen.current === value) return;
|
|
4407
4427
|
seen.current = value;
|
|
4408
4428
|
if (!sameValue(value, applies())) reseed(value);
|
|
4409
4429
|
}, [value, applies, reseed]);
|
|
4410
4430
|
}
|
|
4411
4431
|
function usePreserveFocusAcrossRemount(seed, fields) {
|
|
4412
|
-
const pendingName =
|
|
4432
|
+
const pendingName = React33.useRef(null);
|
|
4413
4433
|
const fieldsRef = useLatest(fields);
|
|
4414
4434
|
const capture = () => {
|
|
4415
4435
|
const active = document.activeElement;
|
|
@@ -4422,7 +4442,7 @@ function usePreserveFocusAcrossRemount(seed, fields) {
|
|
|
4422
4442
|
}
|
|
4423
4443
|
}
|
|
4424
4444
|
};
|
|
4425
|
-
|
|
4445
|
+
React33.useLayoutEffect(() => {
|
|
4426
4446
|
const name = pendingName.current;
|
|
4427
4447
|
if (!name) return;
|
|
4428
4448
|
pendingName.current = null;
|
|
@@ -4438,14 +4458,14 @@ function RangePanel({
|
|
|
4438
4458
|
onCommit,
|
|
4439
4459
|
onClose
|
|
4440
4460
|
}) {
|
|
4441
|
-
const [draft, setDraft] =
|
|
4442
|
-
const [seed, setSeed] =
|
|
4443
|
-
const minId =
|
|
4444
|
-
const maxId =
|
|
4445
|
-
const minWrapRef =
|
|
4446
|
-
const maxWrapRef =
|
|
4461
|
+
const [draft, setDraft] = React33.useState(() => rangeDraft(value));
|
|
4462
|
+
const [seed, setSeed] = React33.useState(0);
|
|
4463
|
+
const minId = React33.useId();
|
|
4464
|
+
const maxId = React33.useId();
|
|
4465
|
+
const minWrapRef = React33.useRef(null);
|
|
4466
|
+
const maxWrapRef = React33.useRef(null);
|
|
4447
4467
|
const preserveFocus = usePreserveFocusAcrossRemount(seed, { min: minWrapRef, max: maxWrapRef });
|
|
4448
|
-
const draftRef =
|
|
4468
|
+
const draftRef = React33.useRef(draft);
|
|
4449
4469
|
const shown = () => {
|
|
4450
4470
|
const { min, max } = draftRef.current;
|
|
4451
4471
|
return applicable(field, min == null && max == null ? void 0 : { min, max }, validity.allValid());
|
|
@@ -4537,15 +4557,15 @@ function DatePanel({
|
|
|
4537
4557
|
onClose
|
|
4538
4558
|
}) {
|
|
4539
4559
|
const maxDays = effectiveMaxDays(field);
|
|
4540
|
-
const [initial] =
|
|
4541
|
-
const [kind, setKind] =
|
|
4542
|
-
const [daysDraft, setDaysDraft] =
|
|
4543
|
-
const daysRef =
|
|
4544
|
-
const daysConfirmed =
|
|
4545
|
-
const [between, setBetween] =
|
|
4546
|
-
const [seed, setSeed] =
|
|
4547
|
-
const daysId =
|
|
4548
|
-
const daysWrapRef =
|
|
4560
|
+
const [initial] = React33.useState(() => dateDraft(field, value));
|
|
4561
|
+
const [kind, setKind] = React33.useState(initial.kind);
|
|
4562
|
+
const [daysDraft, setDaysDraft] = React33.useState(initial.days);
|
|
4563
|
+
const daysRef = React33.useRef(daysDraft);
|
|
4564
|
+
const daysConfirmed = React33.useRef(value?.kind === "withinDays");
|
|
4565
|
+
const [between, setBetween] = React33.useState(initial.between);
|
|
4566
|
+
const [seed, setSeed] = React33.useState(0);
|
|
4567
|
+
const daysId = React33.useId();
|
|
4568
|
+
const daysWrapRef = React33.useRef(null);
|
|
4549
4569
|
const preserveFocus = usePreserveFocusAcrossRemount(seed, { days: daysWrapRef });
|
|
4550
4570
|
const shownWithinDays = () => {
|
|
4551
4571
|
const days = daysRef.current;
|
|
@@ -4663,11 +4683,11 @@ function FilterButton({ children, ...rest }) {
|
|
|
4663
4683
|
] });
|
|
4664
4684
|
}
|
|
4665
4685
|
function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", actions, onClearAll, showActiveCount = false, loading = false, loadingLabel = "Loading the filters", className = "", ...rest }) {
|
|
4666
|
-
const [panel, setPanel] =
|
|
4667
|
-
const editAnchorRef =
|
|
4668
|
-
const addAnchorRef =
|
|
4669
|
-
const textInputRef =
|
|
4670
|
-
const optionsRef =
|
|
4686
|
+
const [panel, setPanel] = React33.useState(null);
|
|
4687
|
+
const editAnchorRef = React33.useRef(null);
|
|
4688
|
+
const addAnchorRef = React33.useRef(null);
|
|
4689
|
+
const textInputRef = React33.useRef(null);
|
|
4690
|
+
const optionsRef = React33.useRef(null);
|
|
4671
4691
|
if (process.env.NODE_ENV !== "production") {
|
|
4672
4692
|
for (const f of fields) assertValidFieldDefinition(f);
|
|
4673
4693
|
}
|
|
@@ -4690,7 +4710,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
4690
4710
|
const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
|
|
4691
4711
|
const startEditing = (key) => setPanel({ kind: "edit", key });
|
|
4692
4712
|
const closeEditing = () => setPanel(null);
|
|
4693
|
-
|
|
4713
|
+
React33.useEffect(() => {
|
|
4694
4714
|
if (!panel || panel.kind !== "edit") return;
|
|
4695
4715
|
if (editingField?.type === "text") {
|
|
4696
4716
|
textInputRef.current?.focus();
|
|
@@ -4945,10 +4965,10 @@ function StatTile(props) {
|
|
|
4945
4965
|
}
|
|
4946
4966
|
|
|
4947
4967
|
// src/components/data/CodeBlock.tsx
|
|
4948
|
-
import * as
|
|
4968
|
+
import * as React35 from "react";
|
|
4949
4969
|
|
|
4950
4970
|
// src/kits/clipboard.ts
|
|
4951
|
-
import * as
|
|
4971
|
+
import * as React34 from "react";
|
|
4952
4972
|
var COPIED_FEEDBACK_MS = 1600;
|
|
4953
4973
|
function copyThroughSelection(text) {
|
|
4954
4974
|
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -4978,17 +4998,17 @@ async function copyToClipboard(text) {
|
|
|
4978
4998
|
return copyThroughSelection(text);
|
|
4979
4999
|
}
|
|
4980
5000
|
function useCopyToClipboard() {
|
|
4981
|
-
const [copied, setCopied] =
|
|
4982
|
-
const timer =
|
|
4983
|
-
const mounted =
|
|
4984
|
-
|
|
5001
|
+
const [copied, setCopied] = React34.useState(false);
|
|
5002
|
+
const timer = React34.useRef(null);
|
|
5003
|
+
const mounted = React34.useRef(true);
|
|
5004
|
+
React34.useEffect(() => {
|
|
4985
5005
|
mounted.current = true;
|
|
4986
5006
|
return () => {
|
|
4987
5007
|
mounted.current = false;
|
|
4988
5008
|
if (timer.current) clearTimeout(timer.current);
|
|
4989
5009
|
};
|
|
4990
5010
|
}, []);
|
|
4991
|
-
const copy =
|
|
5011
|
+
const copy = React34.useCallback(async (text) => {
|
|
4992
5012
|
const ok = await copyToClipboard(text);
|
|
4993
5013
|
if (ok && mounted.current) {
|
|
4994
5014
|
setCopied(true);
|
|
@@ -5156,7 +5176,7 @@ function tokenize(src, lang) {
|
|
|
5156
5176
|
return out;
|
|
5157
5177
|
}
|
|
5158
5178
|
function Highlighted({ code, lang }) {
|
|
5159
|
-
const toks =
|
|
5179
|
+
const toks = React35.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
5160
5180
|
return /* @__PURE__ */ jsx54(Fragment9, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx54("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
|
|
5161
5181
|
}
|
|
5162
5182
|
function CodeBlock({
|
|
@@ -5170,8 +5190,8 @@ function CodeBlock({
|
|
|
5170
5190
|
actions,
|
|
5171
5191
|
className = ""
|
|
5172
5192
|
}) {
|
|
5173
|
-
const [wrap, setWrap] =
|
|
5174
|
-
const [open2, setOpen] =
|
|
5193
|
+
const [wrap, setWrap] = React35.useState(!!wrapDefault);
|
|
5194
|
+
const [open2, setOpen] = React35.useState(false);
|
|
5175
5195
|
const [copied, copy] = useCopyToClipboard();
|
|
5176
5196
|
const body = String(code).replace(/\n$/, "");
|
|
5177
5197
|
const lines = body.split("\n");
|
|
@@ -5200,7 +5220,7 @@ function CodeBlock({
|
|
|
5200
5220
|
] });
|
|
5201
5221
|
}
|
|
5202
5222
|
function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
|
|
5203
|
-
const [open2, setOpen] =
|
|
5223
|
+
const [open2, setOpen] = React35.useState(false);
|
|
5204
5224
|
const [copied, copy] = useCopyToClipboard();
|
|
5205
5225
|
const raw = String(diff).replace(/\n$/, "");
|
|
5206
5226
|
const all = raw.split("\n").map((line) => {
|
|
@@ -5246,7 +5266,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
5246
5266
|
}
|
|
5247
5267
|
|
|
5248
5268
|
// src/components/data/Markdown.tsx
|
|
5249
|
-
import * as
|
|
5269
|
+
import * as React36 from "react";
|
|
5250
5270
|
import { jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
5251
5271
|
var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
|
|
5252
5272
|
var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
|
|
@@ -5289,7 +5309,7 @@ function hiddenInlineNodes(hidden, ctx, keyBase) {
|
|
|
5289
5309
|
const href = safeHref(d(g(2)));
|
|
5290
5310
|
out.push(href ? /* @__PURE__ */ jsx55("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__ */ jsx55("span", { children: d(g(1)) }, key()));
|
|
5291
5311
|
} else if (kind === "cite") {
|
|
5292
|
-
out.push(ctx.renderCitation ? /* @__PURE__ */ jsx55(
|
|
5312
|
+
out.push(ctx.renderCitation ? /* @__PURE__ */ jsx55(React36.Fragment, { children: ctx.renderCitation(d(g(1))) }, key()) : /* @__PURE__ */ jsx55("sup", { className: "fd-md-cite", children: d(g(1)) }, key()));
|
|
5293
5313
|
} else if (kind === "strongem") out.push(/* @__PURE__ */ jsx55("strong", { children: /* @__PURE__ */ jsx55("em", { children: hiddenInlineNodes(g(1), ctx, key()) }) }, key()));
|
|
5294
5314
|
else if (kind === "strong") out.push(/* @__PURE__ */ jsx55("strong", { children: hiddenInlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
5295
5315
|
else if (kind === "em") out.push(/* @__PURE__ */ jsx55("em", { children: hiddenInlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
@@ -5476,7 +5496,7 @@ function Markdown({
|
|
|
5476
5496
|
tone = "default"
|
|
5477
5497
|
}) {
|
|
5478
5498
|
const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
|
|
5479
|
-
const blocks =
|
|
5499
|
+
const blocks = React36.useMemo(() => parseBlocks(source), [source]);
|
|
5480
5500
|
return /* @__PURE__ */ jsx55("div", { className: mdClass("fd-md", size, tone, className), children: renderBlocks(blocks, ctx, "b") });
|
|
5481
5501
|
}
|
|
5482
5502
|
function MarkdownInline({ source = "", className = "", onLinkClick, size, tone }) {
|
|
@@ -5587,7 +5607,7 @@ function Pagination({
|
|
|
5587
5607
|
}
|
|
5588
5608
|
|
|
5589
5609
|
// src/components/data/RelativeTime.tsx
|
|
5590
|
-
import * as
|
|
5610
|
+
import * as React37 from "react";
|
|
5591
5611
|
import { jsxs as jsxs48 } from "react/jsx-runtime";
|
|
5592
5612
|
var MIN = 6e4;
|
|
5593
5613
|
var HOUR = 36e5;
|
|
@@ -5639,9 +5659,9 @@ function formatDuration(ms) {
|
|
|
5639
5659
|
return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
|
|
5640
5660
|
}
|
|
5641
5661
|
function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
|
|
5642
|
-
const [, force] =
|
|
5662
|
+
const [, force] = React37.useState(0);
|
|
5643
5663
|
const t = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
5644
|
-
|
|
5664
|
+
React37.useEffect(() => {
|
|
5645
5665
|
if (!refresh2 || !t || isNaN(t)) return;
|
|
5646
5666
|
const abs = Math.abs(t - Date.now());
|
|
5647
5667
|
if (abs > DAY) return;
|
|
@@ -5657,7 +5677,7 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
|
|
|
5657
5677
|
}
|
|
5658
5678
|
|
|
5659
5679
|
// src/components/data/ScoreMeter.tsx
|
|
5660
|
-
import * as
|
|
5680
|
+
import * as React38 from "react";
|
|
5661
5681
|
import { jsx as jsx58, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
5662
5682
|
function ScoreMeter({
|
|
5663
5683
|
score,
|
|
@@ -5672,10 +5692,10 @@ function ScoreMeter({
|
|
|
5672
5692
|
breakdownWidth = 280,
|
|
5673
5693
|
className = ""
|
|
5674
5694
|
}) {
|
|
5675
|
-
const [open2, setOpen] =
|
|
5676
|
-
const ref =
|
|
5695
|
+
const [open2, setOpen] = React38.useState(false);
|
|
5696
|
+
const ref = React38.useRef(null);
|
|
5677
5697
|
const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
5678
|
-
const body = /* @__PURE__ */ jsxs49(
|
|
5698
|
+
const body = /* @__PURE__ */ jsxs49(React38.Fragment, { children: [
|
|
5679
5699
|
/* @__PURE__ */ jsx58("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ jsx58(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
|
|
5680
5700
|
showScore ? /* @__PURE__ */ jsx58("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
|
|
5681
5701
|
] });
|
|
@@ -5694,7 +5714,7 @@ function ScoreMeter({
|
|
|
5694
5714
|
}
|
|
5695
5715
|
);
|
|
5696
5716
|
}
|
|
5697
|
-
return /* @__PURE__ */ jsxs49(
|
|
5717
|
+
return /* @__PURE__ */ jsxs49(React38.Fragment, { children: [
|
|
5698
5718
|
/* @__PURE__ */ jsx58(
|
|
5699
5719
|
"button",
|
|
5700
5720
|
{
|
|
@@ -5725,11 +5745,11 @@ function ScoreMeter({
|
|
|
5725
5745
|
}
|
|
5726
5746
|
|
|
5727
5747
|
// src/components/actions/inlinePanel.tsx
|
|
5728
|
-
import * as
|
|
5748
|
+
import * as React39 from "react";
|
|
5729
5749
|
import { jsx as jsx59 } from "react/jsx-runtime";
|
|
5730
5750
|
function useInlinePanel() {
|
|
5731
|
-
const [open2, setOpen] =
|
|
5732
|
-
const ref =
|
|
5751
|
+
const [open2, setOpen] = React39.useState(false);
|
|
5752
|
+
const ref = React39.useRef(null);
|
|
5733
5753
|
return { open: open2, setOpen, ref };
|
|
5734
5754
|
}
|
|
5735
5755
|
function InlinePanelSurface({ panel, align = "right", ...popover }) {
|
|
@@ -5900,7 +5920,7 @@ function SortMenu({
|
|
|
5900
5920
|
}
|
|
5901
5921
|
|
|
5902
5922
|
// src/components/data/StepList.tsx
|
|
5903
|
-
import * as
|
|
5923
|
+
import * as React40 from "react";
|
|
5904
5924
|
import { jsx as jsx61, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
5905
5925
|
var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
|
|
5906
5926
|
function StepList({
|
|
@@ -5914,9 +5934,9 @@ function StepList({
|
|
|
5914
5934
|
className = "",
|
|
5915
5935
|
active = false
|
|
5916
5936
|
}) {
|
|
5917
|
-
const [openState, setOpenState] =
|
|
5937
|
+
const [openState, setOpenState] = React40.useState(defaultOpen);
|
|
5918
5938
|
const open2 = openProp == null ? openState : openProp;
|
|
5919
|
-
const [expanded, setExpanded] =
|
|
5939
|
+
const [expanded, setExpanded] = React40.useState({});
|
|
5920
5940
|
if (!steps.length) return null;
|
|
5921
5941
|
const running = steps.some((s) => s.status === "running");
|
|
5922
5942
|
const failed = steps.filter((s) => s.status === "error").length;
|
|
@@ -5974,7 +5994,7 @@ function StepList({
|
|
|
5974
5994
|
}
|
|
5975
5995
|
|
|
5976
5996
|
// src/components/data/VirtualList.tsx
|
|
5977
|
-
import * as
|
|
5997
|
+
import * as React41 from "react";
|
|
5978
5998
|
import { jsx as jsx62, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
5979
5999
|
var VIRTUAL_LIST_BUFFER_ROWS = 20;
|
|
5980
6000
|
var VIRTUAL_LIST_ROW_GAP = 6;
|
|
@@ -6026,35 +6046,35 @@ function VirtualList({
|
|
|
6026
6046
|
className = "",
|
|
6027
6047
|
style
|
|
6028
6048
|
}) {
|
|
6029
|
-
const [scrollTop, setScrollTop] =
|
|
6030
|
-
const loaded =
|
|
6049
|
+
const [scrollTop, setScrollTop] = React41.useState(0);
|
|
6050
|
+
const loaded = React41.useMemo(
|
|
6031
6051
|
() => ({ firstItemIndex, count: items.length }),
|
|
6032
6052
|
[firstItemIndex, items.length]
|
|
6033
6053
|
);
|
|
6034
6054
|
const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
|
|
6035
6055
|
const bandKey = firstItemIndex + ":" + items.length;
|
|
6036
|
-
const win =
|
|
6056
|
+
const win = React41.useMemo(
|
|
6037
6057
|
() => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
|
|
6038
6058
|
[scrollTop, height, itemHeight, total, loaded]
|
|
6039
6059
|
);
|
|
6040
|
-
const need =
|
|
6060
|
+
const need = React41.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
|
|
6041
6061
|
const wantStart = need.start && hasMore?.start !== false;
|
|
6042
6062
|
const wantEnd = need.end && hasMore?.end !== false;
|
|
6043
6063
|
const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
|
|
6044
6064
|
const askKey = bandKey + "@" + bucket2;
|
|
6045
|
-
const asked =
|
|
6046
|
-
|
|
6065
|
+
const asked = React41.useRef({ start: null, end: null });
|
|
6066
|
+
React41.useEffect(() => {
|
|
6047
6067
|
if (loading || !wantStart || asked.current.start === askKey) return;
|
|
6048
6068
|
asked.current.start = askKey;
|
|
6049
6069
|
onNeedMore("start", win);
|
|
6050
6070
|
}, [wantStart, loading, askKey, onNeedMore, win]);
|
|
6051
|
-
|
|
6071
|
+
React41.useEffect(() => {
|
|
6052
6072
|
if (loading || !wantEnd || asked.current.end === askKey) return;
|
|
6053
6073
|
asked.current.end = askKey;
|
|
6054
6074
|
onNeedMore("end", win);
|
|
6055
6075
|
}, [wantEnd, loading, askKey, onNeedMore, win]);
|
|
6056
|
-
const lastKeysRef =
|
|
6057
|
-
const newKeys =
|
|
6076
|
+
const lastKeysRef = React41.useRef(null);
|
|
6077
|
+
const newKeys = React41.useMemo(() => {
|
|
6058
6078
|
const prev = lastKeysRef.current;
|
|
6059
6079
|
if (!prev) return /* @__PURE__ */ new Set();
|
|
6060
6080
|
const fresh = /* @__PURE__ */ new Set();
|
|
@@ -6064,7 +6084,7 @@ function VirtualList({
|
|
|
6064
6084
|
}
|
|
6065
6085
|
return fresh;
|
|
6066
6086
|
}, [items]);
|
|
6067
|
-
|
|
6087
|
+
React41.useEffect(() => {
|
|
6068
6088
|
lastKeysRef.current = new Set(items.map(keyOf));
|
|
6069
6089
|
}, [items]);
|
|
6070
6090
|
const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
|
|
@@ -6109,7 +6129,7 @@ function VirtualList({
|
|
|
6109
6129
|
}
|
|
6110
6130
|
|
|
6111
6131
|
// src/components/data/EntityRow.tsx
|
|
6112
|
-
import * as
|
|
6132
|
+
import * as React42 from "react";
|
|
6113
6133
|
import { jsx as jsx63, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
6114
6134
|
var ENTITY_ROW_METRIC_WIDTH = 74;
|
|
6115
6135
|
var METRIC_TONE_COLOR = {
|
|
@@ -6122,7 +6142,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
|
|
|
6122
6142
|
const key = m.id || m.label || i;
|
|
6123
6143
|
const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
|
|
6124
6144
|
const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
|
|
6125
|
-
const content = /* @__PURE__ */ jsxs53(
|
|
6145
|
+
const content = /* @__PURE__ */ jsxs53(React42.Fragment, { children: [
|
|
6126
6146
|
m.icon ? /* @__PURE__ */ jsx63("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
|
|
6127
6147
|
/* @__PURE__ */ jsx63("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
|
|
6128
6148
|
/* @__PURE__ */ jsx63("span", { className: "fd-sr", children: " " + m.label })
|
|
@@ -6214,7 +6234,7 @@ function EntityRow({
|
|
|
6214
6234
|
}
|
|
6215
6235
|
|
|
6216
6236
|
// src/components/data/TransferList.tsx
|
|
6217
|
-
import * as
|
|
6237
|
+
import * as React43 from "react";
|
|
6218
6238
|
import { createPortal as createPortal5 } from "react-dom";
|
|
6219
6239
|
|
|
6220
6240
|
// src/components/forms/Input.tsx
|
|
@@ -6320,12 +6340,12 @@ function TransferList({
|
|
|
6320
6340
|
listHeight = 440,
|
|
6321
6341
|
className = ""
|
|
6322
6342
|
}) {
|
|
6323
|
-
const [drag, setDrag] =
|
|
6324
|
-
const [dragOverSide, setDragOverSide] =
|
|
6325
|
-
const dragRef =
|
|
6326
|
-
const armedRef =
|
|
6327
|
-
const sideRefs =
|
|
6328
|
-
const hitTestSide =
|
|
6343
|
+
const [drag, setDrag] = React43.useState(null);
|
|
6344
|
+
const [dragOverSide, setDragOverSide] = React43.useState(null);
|
|
6345
|
+
const dragRef = React43.useRef(null);
|
|
6346
|
+
const armedRef = React43.useRef(null);
|
|
6347
|
+
const sideRefs = React43.useRef({ left: null, right: null });
|
|
6348
|
+
const hitTestSide = React43.useCallback((x, y) => {
|
|
6329
6349
|
for (const side of ["left", "right"]) {
|
|
6330
6350
|
const el = sideRefs.current[side];
|
|
6331
6351
|
if (!el) continue;
|
|
@@ -6334,7 +6354,7 @@ function TransferList({
|
|
|
6334
6354
|
}
|
|
6335
6355
|
return null;
|
|
6336
6356
|
}, []);
|
|
6337
|
-
const findItem =
|
|
6357
|
+
const findItem = React43.useCallback(
|
|
6338
6358
|
(side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
|
|
6339
6359
|
[left.items, right.items, keyOf]
|
|
6340
6360
|
);
|
|
@@ -6356,7 +6376,7 @@ function TransferList({
|
|
|
6356
6376
|
height: rect.height
|
|
6357
6377
|
};
|
|
6358
6378
|
};
|
|
6359
|
-
|
|
6379
|
+
React43.useEffect(() => {
|
|
6360
6380
|
const onMovePointer = (e) => {
|
|
6361
6381
|
const armed = armedRef.current;
|
|
6362
6382
|
if (!armed || e.pointerId !== armed.pointerId) return;
|
|
@@ -6409,7 +6429,7 @@ function TransferList({
|
|
|
6409
6429
|
window.removeEventListener("pointercancel", endDrag);
|
|
6410
6430
|
};
|
|
6411
6431
|
}, [hitTestSide, findItem, onMove]);
|
|
6412
|
-
|
|
6432
|
+
React43.useEffect(() => {
|
|
6413
6433
|
if (!drag || typeof document === "undefined") return;
|
|
6414
6434
|
const prev = document.body.style.userSelect;
|
|
6415
6435
|
document.body.style.userSelect = "none";
|
|
@@ -6526,7 +6546,7 @@ function FactList({ facts = [], className = "", ...rest }) {
|
|
|
6526
6546
|
}
|
|
6527
6547
|
|
|
6528
6548
|
// src/components/data/USChoropleth.tsx
|
|
6529
|
-
import * as
|
|
6549
|
+
import * as React45 from "react";
|
|
6530
6550
|
|
|
6531
6551
|
// src/components/data/usChoropleth/mapBox.ts
|
|
6532
6552
|
var MAP_WIDTH = 975;
|
|
@@ -6591,11 +6611,11 @@ function buildChoroplethModel(values, topN, givenTotal) {
|
|
|
6591
6611
|
}
|
|
6592
6612
|
|
|
6593
6613
|
// src/components/data/usChoropleth/useUsStateShapes.ts
|
|
6594
|
-
import * as
|
|
6614
|
+
import * as React44 from "react";
|
|
6595
6615
|
function useUsStateShapes() {
|
|
6596
|
-
const [token, setToken] =
|
|
6597
|
-
const [settled, setSettled] =
|
|
6598
|
-
|
|
6616
|
+
const [token, setToken] = React44.useState(0);
|
|
6617
|
+
const [settled, setSettled] = React44.useState(null);
|
|
6618
|
+
React44.useEffect(() => {
|
|
6599
6619
|
let current2 = true;
|
|
6600
6620
|
import("./usStateShapes-JJARDNLL.js").then(({ STATE_SHAPES }) => {
|
|
6601
6621
|
if (current2) setSettled({ token, state: { status: "ready", shapes: STATE_SHAPES } });
|
|
@@ -6637,7 +6657,7 @@ function nextCode(key, from) {
|
|
|
6637
6657
|
}
|
|
6638
6658
|
function StateMap({ shapes, model, figures, label, formatReadout }) {
|
|
6639
6659
|
const tip = useTooltip();
|
|
6640
|
-
const [stop, setStop] =
|
|
6660
|
+
const [stop, setStop] = React45.useState(US_STATE_CODES[0]);
|
|
6641
6661
|
const onKeyDown = (event) => {
|
|
6642
6662
|
const from = event.target.getAttribute("data-state");
|
|
6643
6663
|
const to = from && nextCode(event.key, from);
|
|
@@ -6685,8 +6705,8 @@ function StateTable({ model, valueLabel, formatValue }) {
|
|
|
6685
6705
|
return /* @__PURE__ */ jsx68(Collapsible, { title: TABLE_TITLE, children: /* @__PURE__ */ jsx68(DataTable, { columns, rows: model.rows, rowKey: "code", compact: true }) });
|
|
6686
6706
|
}
|
|
6687
6707
|
function USChoropleth({ values, label, valueLabel, formatValue, formatReadout, topN, total, className = "" }) {
|
|
6688
|
-
const model =
|
|
6689
|
-
const figures =
|
|
6708
|
+
const model = React45.useMemo(() => buildChoroplethModel(values, topN ?? 0, total), [values, topN, total]);
|
|
6709
|
+
const figures = React45.useMemo(() => new Map(model.rows.map((row) => [row.code, row])), [model]);
|
|
6690
6710
|
const { state, retry } = useUsStateShapes();
|
|
6691
6711
|
return /* @__PURE__ */ jsxs57("div", { className: ["fd-uschoro", className].filter(Boolean).join(" "), children: [
|
|
6692
6712
|
/* @__PURE__ */ jsxs57("div", { className: "fd-uschoro-layout", children: [
|
|
@@ -6721,11 +6741,11 @@ function USChoropleth({ values, label, valueLabel, formatValue, formatReadout, t
|
|
|
6721
6741
|
}
|
|
6722
6742
|
|
|
6723
6743
|
// src/components/forms/Checkbox.tsx
|
|
6724
|
-
import * as
|
|
6744
|
+
import * as React46 from "react";
|
|
6725
6745
|
import { jsx as jsx69, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
6726
6746
|
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
6727
|
-
const ref =
|
|
6728
|
-
|
|
6747
|
+
const ref = React46.useRef(null);
|
|
6748
|
+
React46.useEffect(() => {
|
|
6729
6749
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
6730
6750
|
}, [indeterminate]);
|
|
6731
6751
|
return /* @__PURE__ */ jsxs58("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
@@ -6772,7 +6792,7 @@ function Switch({ label, description, className = "", ...rest }) {
|
|
|
6772
6792
|
}
|
|
6773
6793
|
|
|
6774
6794
|
// src/components/forms/Select.tsx
|
|
6775
|
-
import * as
|
|
6795
|
+
import * as React47 from "react";
|
|
6776
6796
|
import { jsx as jsx72, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
6777
6797
|
var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
|
|
6778
6798
|
function Select({
|
|
@@ -6800,12 +6820,12 @@ function Select({
|
|
|
6800
6820
|
const isOn = (v) => multiple ? vals.includes(v) : v === value;
|
|
6801
6821
|
const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
|
|
6802
6822
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
|
|
6803
|
-
const [open2, setOpen] =
|
|
6804
|
-
const [q, setQ] =
|
|
6805
|
-
const rootRef =
|
|
6806
|
-
const boxRef =
|
|
6807
|
-
const listRef =
|
|
6808
|
-
const typeBuf =
|
|
6823
|
+
const [open2, setOpen] = React47.useState(false);
|
|
6824
|
+
const [q, setQ] = React47.useState("");
|
|
6825
|
+
const rootRef = React47.useRef(null);
|
|
6826
|
+
const boxRef = React47.useRef(null);
|
|
6827
|
+
const listRef = React47.useRef(null);
|
|
6828
|
+
const typeBuf = React47.useRef({ s: "", t: 0 });
|
|
6809
6829
|
const selected = multiple ? null : opts.find((o) => o.value === value);
|
|
6810
6830
|
const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
|
|
6811
6831
|
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;
|
|
@@ -6941,7 +6961,7 @@ function Select({
|
|
|
6941
6961
|
),
|
|
6942
6962
|
q ? /* @__PURE__ */ jsx72("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
|
|
6943
6963
|
] }) : void 0,
|
|
6944
|
-
footer: multiple ? /* @__PURE__ */ jsxs61(
|
|
6964
|
+
footer: multiple ? /* @__PURE__ */ jsxs61(React47.Fragment, { children: [
|
|
6945
6965
|
/* @__PURE__ */ jsx72(
|
|
6946
6966
|
"button",
|
|
6947
6967
|
{
|
|
@@ -6972,7 +6992,7 @@ function Select({
|
|
|
6972
6992
|
'Nothing matches "',
|
|
6973
6993
|
q,
|
|
6974
6994
|
'".'
|
|
6975
|
-
] }) : groups.map((grp) => /* @__PURE__ */ jsxs61(
|
|
6995
|
+
] }) : groups.map((grp) => /* @__PURE__ */ jsxs61(React47.Fragment, { children: [
|
|
6976
6996
|
grp.g ? /* @__PURE__ */ jsx72("div", { className: "fd-pop-group", children: grp.g }) : null,
|
|
6977
6997
|
grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs61(
|
|
6978
6998
|
"button",
|
|
@@ -7009,7 +7029,7 @@ function Select({
|
|
|
7009
7029
|
}
|
|
7010
7030
|
|
|
7011
7031
|
// src/components/forms/TimePicker.tsx
|
|
7012
|
-
import * as
|
|
7032
|
+
import * as React48 from "react";
|
|
7013
7033
|
import { jsx as jsx73, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
7014
7034
|
var pad = (n) => String(n).padStart(2, "0");
|
|
7015
7035
|
function ClockFace({ value = "09:00", onChange }) {
|
|
@@ -7018,9 +7038,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
7018
7038
|
if (isNaN(m)) m = 0;
|
|
7019
7039
|
const pm = h24 >= 12;
|
|
7020
7040
|
const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
|
|
7021
|
-
const [mode2, setMode] =
|
|
7022
|
-
const faceRef =
|
|
7023
|
-
const dragging =
|
|
7041
|
+
const [mode2, setMode] = React48.useState("h");
|
|
7042
|
+
const faceRef = React48.useRef(null);
|
|
7043
|
+
const dragging = React48.useRef(false);
|
|
7024
7044
|
const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
|
|
7025
7045
|
const R = 108, NR = 80;
|
|
7026
7046
|
const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
|
|
@@ -7093,9 +7113,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
7093
7113
|
}
|
|
7094
7114
|
function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
|
|
7095
7115
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
7096
|
-
const [open2, setOpen] =
|
|
7097
|
-
const rootRef =
|
|
7098
|
-
const boxRef =
|
|
7116
|
+
const [open2, setOpen] = React48.useState(false);
|
|
7117
|
+
const rootRef = React48.useRef(null);
|
|
7118
|
+
const boxRef = React48.useRef(null);
|
|
7099
7119
|
const disp = () => {
|
|
7100
7120
|
if (!value) return "";
|
|
7101
7121
|
const [h, m] = value.split(":").map(Number);
|
|
@@ -7138,7 +7158,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
7138
7158
|
offset: 6,
|
|
7139
7159
|
width: 262,
|
|
7140
7160
|
role: "presentation",
|
|
7141
|
-
footer: /* @__PURE__ */ jsxs62(
|
|
7161
|
+
footer: /* @__PURE__ */ jsxs62(React48.Fragment, { children: [
|
|
7142
7162
|
/* @__PURE__ */ jsx73(
|
|
7143
7163
|
"button",
|
|
7144
7164
|
{
|
|
@@ -7166,7 +7186,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
7166
7186
|
}
|
|
7167
7187
|
|
|
7168
7188
|
// src/components/forms/Slider.tsx
|
|
7169
|
-
import * as
|
|
7189
|
+
import * as React49 from "react";
|
|
7170
7190
|
import { jsx as jsx74, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
7171
7191
|
function Slider({
|
|
7172
7192
|
label,
|
|
@@ -7184,7 +7204,7 @@ function Slider({
|
|
|
7184
7204
|
...rest
|
|
7185
7205
|
}) {
|
|
7186
7206
|
const fieldId = useFieldId(id);
|
|
7187
|
-
const [dragging, setDragging] =
|
|
7207
|
+
const [dragging, setDragging] = React49.useState(false);
|
|
7188
7208
|
const v = value === void 0 ? min : Number(value);
|
|
7189
7209
|
const pct = max === min ? 0 : (v - min) / (max - min) * 100;
|
|
7190
7210
|
return /* @__PURE__ */ jsxs63("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
|
|
@@ -7218,7 +7238,7 @@ function Slider({
|
|
|
7218
7238
|
}
|
|
7219
7239
|
|
|
7220
7240
|
// src/components/forms/RangeSlider.tsx
|
|
7221
|
-
import * as
|
|
7241
|
+
import * as React50 from "react";
|
|
7222
7242
|
import { jsx as jsx75, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
7223
7243
|
function RangeSlider({
|
|
7224
7244
|
label,
|
|
@@ -7238,9 +7258,9 @@ function RangeSlider({
|
|
|
7238
7258
|
}) {
|
|
7239
7259
|
const fmt2 = format || ((v) => String(v));
|
|
7240
7260
|
const [a, b] = value || [min, max];
|
|
7241
|
-
const [drag, setDrag] =
|
|
7242
|
-
const [focus, setFocus] =
|
|
7243
|
-
const railRef =
|
|
7261
|
+
const [drag, setDrag] = React50.useState(null);
|
|
7262
|
+
const [focus, setFocus] = React50.useState(null);
|
|
7263
|
+
const railRef = React50.useRef(null);
|
|
7244
7264
|
const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
|
|
7245
7265
|
const clampPair = (i, v) => {
|
|
7246
7266
|
v = Math.min(max, Math.max(min, Math.round(v / step) * step));
|
|
@@ -7255,7 +7275,7 @@ function RangeSlider({
|
|
|
7255
7275
|
const r = railRef.current.getBoundingClientRect();
|
|
7256
7276
|
return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
|
|
7257
7277
|
};
|
|
7258
|
-
|
|
7278
|
+
React50.useEffect(() => {
|
|
7259
7279
|
if (drag === null) return;
|
|
7260
7280
|
const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
|
|
7261
7281
|
const upH = () => setDrag(null);
|
|
@@ -7336,7 +7356,7 @@ function RangeSlider({
|
|
|
7336
7356
|
/* @__PURE__ */ jsxs64("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
|
|
7337
7357
|
/* @__PURE__ */ jsx75("span", { className: "fd-range-rail", ref: railRef }),
|
|
7338
7358
|
/* @__PURE__ */ jsx75("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
|
|
7339
|
-
marks.map((m) => /* @__PURE__ */ jsxs64(
|
|
7359
|
+
marks.map((m) => /* @__PURE__ */ jsxs64(React50.Fragment, { children: [
|
|
7340
7360
|
/* @__PURE__ */ jsx75("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
|
|
7341
7361
|
m.label ? /* @__PURE__ */ jsx75("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
|
|
7342
7362
|
] }, m.value)),
|
|
@@ -7365,7 +7385,7 @@ function RangeSlider({
|
|
|
7365
7385
|
}
|
|
7366
7386
|
|
|
7367
7387
|
// src/components/forms/Dropzone.tsx
|
|
7368
|
-
import * as
|
|
7388
|
+
import * as React51 from "react";
|
|
7369
7389
|
import { jsx as jsx76, jsxs as jsxs65 } from "react/jsx-runtime";
|
|
7370
7390
|
function Dropzone({
|
|
7371
7391
|
onFiles,
|
|
@@ -7380,8 +7400,8 @@ function Dropzone({
|
|
|
7380
7400
|
className = "",
|
|
7381
7401
|
style
|
|
7382
7402
|
}) {
|
|
7383
|
-
const [over, setOver] =
|
|
7384
|
-
const depth =
|
|
7403
|
+
const [over, setOver] = React51.useState(false);
|
|
7404
|
+
const depth = React51.useRef(0);
|
|
7385
7405
|
const has = (e) => {
|
|
7386
7406
|
const dt = e.dataTransfer;
|
|
7387
7407
|
if (!dt) return false;
|
|
@@ -7443,8 +7463,8 @@ function FilePickButton({
|
|
|
7443
7463
|
className = "",
|
|
7444
7464
|
children
|
|
7445
7465
|
}) {
|
|
7446
|
-
const ref =
|
|
7447
|
-
return /* @__PURE__ */ jsxs65(
|
|
7466
|
+
const ref = React51.useRef(null);
|
|
7467
|
+
return /* @__PURE__ */ jsxs65(React51.Fragment, { children: [
|
|
7448
7468
|
/* @__PURE__ */ jsx76(
|
|
7449
7469
|
"button",
|
|
7450
7470
|
{
|
|
@@ -7477,10 +7497,10 @@ function FilePickButton({
|
|
|
7477
7497
|
}
|
|
7478
7498
|
function useStagedFiles(upload, opts) {
|
|
7479
7499
|
const o = opts || {};
|
|
7480
|
-
const [items, setItems] =
|
|
7481
|
-
const controllers =
|
|
7500
|
+
const [items, setItems] = React51.useState([]);
|
|
7501
|
+
const controllers = React51.useRef({});
|
|
7482
7502
|
const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
|
|
7483
|
-
const run =
|
|
7503
|
+
const run = React51.useCallback((att) => {
|
|
7484
7504
|
if (!upload) return;
|
|
7485
7505
|
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
7486
7506
|
controllers.current[att.id] = ac;
|
|
@@ -7497,14 +7517,14 @@ function useStagedFiles(upload, opts) {
|
|
|
7497
7517
|
delete controllers.current[att.id];
|
|
7498
7518
|
});
|
|
7499
7519
|
}, [upload]);
|
|
7500
|
-
const add =
|
|
7520
|
+
const add = React51.useCallback((files) => {
|
|
7501
7521
|
if (!upload) return [];
|
|
7502
7522
|
const atts = Array.from(files).map((f) => toAttachment(f));
|
|
7503
7523
|
setItems((list) => list.concat(atts));
|
|
7504
7524
|
atts.forEach(run);
|
|
7505
7525
|
return atts;
|
|
7506
7526
|
}, [upload, run]);
|
|
7507
|
-
const remove =
|
|
7527
|
+
const remove = React51.useCallback((att) => {
|
|
7508
7528
|
const ac = controllers.current[att.id];
|
|
7509
7529
|
if (ac) {
|
|
7510
7530
|
try {
|
|
@@ -7515,10 +7535,10 @@ function useStagedFiles(upload, opts) {
|
|
|
7515
7535
|
}
|
|
7516
7536
|
setItems((list) => list.filter((f) => f.id !== att.id));
|
|
7517
7537
|
}, []);
|
|
7518
|
-
const retry =
|
|
7538
|
+
const retry = React51.useCallback((att) => {
|
|
7519
7539
|
run(att);
|
|
7520
7540
|
}, [run]);
|
|
7521
|
-
const clear =
|
|
7541
|
+
const clear = React51.useCallback(() => {
|
|
7522
7542
|
Object.values(controllers.current).forEach((ac) => {
|
|
7523
7543
|
try {
|
|
7524
7544
|
ac && ac.abort();
|
|
@@ -7642,7 +7662,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
|
|
|
7642
7662
|
}
|
|
7643
7663
|
|
|
7644
7664
|
// src/components/forms/MarkdownEditor.tsx
|
|
7645
|
-
import * as
|
|
7665
|
+
import * as React52 from "react";
|
|
7646
7666
|
import { jsx as jsx78, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
7647
7667
|
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
|
|
7648
7668
|
var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
|
|
@@ -7856,7 +7876,7 @@ function syncDom(root, value) {
|
|
|
7856
7876
|
while (root.children.length > lines.length) root.removeChild(root.lastChild);
|
|
7857
7877
|
}
|
|
7858
7878
|
var LIST_CONT = RE_LI;
|
|
7859
|
-
var MarkdownEditor =
|
|
7879
|
+
var MarkdownEditor = React52.forwardRef(function MarkdownEditor2({
|
|
7860
7880
|
value = "",
|
|
7861
7881
|
onChange,
|
|
7862
7882
|
onSubmit,
|
|
@@ -7875,10 +7895,10 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
7875
7895
|
className = "",
|
|
7876
7896
|
id
|
|
7877
7897
|
}, ref) {
|
|
7878
|
-
const boxRef =
|
|
7879
|
-
const composing =
|
|
7880
|
-
const pendingCaret =
|
|
7881
|
-
|
|
7898
|
+
const boxRef = React52.useRef(null);
|
|
7899
|
+
const composing = React52.useRef(false);
|
|
7900
|
+
const pendingCaret = React52.useRef(null);
|
|
7901
|
+
React52.useLayoutEffect(() => {
|
|
7882
7902
|
const root = boxRef.current;
|
|
7883
7903
|
if (!root || composing.current) return;
|
|
7884
7904
|
const active = document.activeElement === root || root.contains(document.activeElement);
|
|
@@ -7887,7 +7907,7 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
7887
7907
|
pendingCaret.current = null;
|
|
7888
7908
|
if (active && caret != null) placeCaret(root, caret);
|
|
7889
7909
|
}, [value]);
|
|
7890
|
-
|
|
7910
|
+
React52.useEffect(() => {
|
|
7891
7911
|
if (autoFocus && boxRef.current) boxRef.current.focus();
|
|
7892
7912
|
}, [autoFocus]);
|
|
7893
7913
|
const caretNow = () => {
|
|
@@ -7954,8 +7974,8 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
7954
7974
|
api.replaceRange(from, to, next, from + next.length);
|
|
7955
7975
|
}
|
|
7956
7976
|
};
|
|
7957
|
-
|
|
7958
|
-
const caretAtKeydown =
|
|
7977
|
+
React52.useImperativeHandle(ref, () => api);
|
|
7978
|
+
const caretAtKeydown = React52.useRef(-1);
|
|
7959
7979
|
function detect(text, caret) {
|
|
7960
7980
|
if (!onTrigger) return;
|
|
7961
7981
|
const upto = text.slice(0, caret);
|
|
@@ -8108,7 +8128,7 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
8108
8128
|
});
|
|
8109
8129
|
|
|
8110
8130
|
// src/components/forms/CodeEditor.tsx
|
|
8111
|
-
import * as
|
|
8131
|
+
import * as React53 from "react";
|
|
8112
8132
|
import { EditorView, keymap, lineNumbers, placeholder as cmPlaceholder, drawSelection, Decoration } from "@codemirror/view";
|
|
8113
8133
|
import { EditorState, StateEffect, StateField, Compartment } from "@codemirror/state";
|
|
8114
8134
|
import { defaultKeymap, history, historyKeymap, indentMore, indentLess } from "@codemirror/commands";
|
|
@@ -8212,16 +8232,16 @@ function CodeEditor({
|
|
|
8212
8232
|
const fieldId = useFieldId(id);
|
|
8213
8233
|
const descId = fieldId + "-desc";
|
|
8214
8234
|
const liveId = fieldId + "-live";
|
|
8215
|
-
const hostRef =
|
|
8216
|
-
const viewRef =
|
|
8217
|
-
const valueRef =
|
|
8218
|
-
const onChangeRef =
|
|
8235
|
+
const hostRef = React53.useRef(null);
|
|
8236
|
+
const viewRef = React53.useRef(null);
|
|
8237
|
+
const valueRef = React53.useRef(value);
|
|
8238
|
+
const onChangeRef = React53.useRef(onChange);
|
|
8219
8239
|
onChangeRef.current = onChange;
|
|
8220
|
-
const editableCompartment =
|
|
8221
|
-
const attributesCompartment =
|
|
8222
|
-
const errorRef =
|
|
8240
|
+
const editableCompartment = React53.useRef(new Compartment()).current;
|
|
8241
|
+
const attributesCompartment = React53.useRef(new Compartment()).current;
|
|
8242
|
+
const errorRef = React53.useRef(error);
|
|
8223
8243
|
errorRef.current = error;
|
|
8224
|
-
const diagnosticsCountRef =
|
|
8244
|
+
const diagnosticsCountRef = React53.useRef(diagnostics.length);
|
|
8225
8245
|
diagnosticsCountRef.current = diagnostics.length;
|
|
8226
8246
|
function contentAttributes() {
|
|
8227
8247
|
return {
|
|
@@ -8231,7 +8251,7 @@ function CodeEditor({
|
|
|
8231
8251
|
...label ? { "aria-label": label } : {}
|
|
8232
8252
|
};
|
|
8233
8253
|
}
|
|
8234
|
-
|
|
8254
|
+
React53.useEffect(() => {
|
|
8235
8255
|
const host2 = hostRef.current;
|
|
8236
8256
|
if (!host2) return;
|
|
8237
8257
|
const updateListener = EditorView.updateListener.of((update) => {
|
|
@@ -8273,7 +8293,7 @@ function CodeEditor({
|
|
|
8273
8293
|
viewRef.current = null;
|
|
8274
8294
|
};
|
|
8275
8295
|
}, []);
|
|
8276
|
-
|
|
8296
|
+
React53.useEffect(() => {
|
|
8277
8297
|
const view = viewRef.current;
|
|
8278
8298
|
if (!view) return;
|
|
8279
8299
|
const current2 = view.state.doc.toString();
|
|
@@ -8282,12 +8302,12 @@ function CodeEditor({
|
|
|
8282
8302
|
}
|
|
8283
8303
|
valueRef.current = value;
|
|
8284
8304
|
}, [value]);
|
|
8285
|
-
|
|
8305
|
+
React53.useEffect(() => {
|
|
8286
8306
|
const view = viewRef.current;
|
|
8287
8307
|
if (!view) return;
|
|
8288
8308
|
view.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!disabled)) });
|
|
8289
8309
|
}, [disabled, editableCompartment]);
|
|
8290
|
-
|
|
8310
|
+
React53.useEffect(() => {
|
|
8291
8311
|
const view = viewRef.current;
|
|
8292
8312
|
if (!view) return;
|
|
8293
8313
|
view.dispatch({
|
|
@@ -8345,11 +8365,11 @@ function CodeEditor({
|
|
|
8345
8365
|
}
|
|
8346
8366
|
|
|
8347
8367
|
// src/components/forms/RadioGroup.tsx
|
|
8348
|
-
import * as
|
|
8368
|
+
import * as React54 from "react";
|
|
8349
8369
|
import { jsx as jsx80, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
8350
8370
|
function RadioGroup({ label, labelledBy, options, value, onChange, card = false, disabled = false, name, className = "" }) {
|
|
8351
|
-
const autoName =
|
|
8352
|
-
const labelId =
|
|
8371
|
+
const autoName = React54.useId();
|
|
8372
|
+
const labelId = React54.useId();
|
|
8353
8373
|
return /* @__PURE__ */ jsxs69("div", { role: "radiogroup", "aria-labelledby": labelledBy ?? labelId, "aria-disabled": disabled || void 0, className: ["fd-radiogroup", className].filter(Boolean).join(" "), children: [
|
|
8354
8374
|
labelledBy === void 0 && /* @__PURE__ */ jsx80("span", { id: labelId, className: "fd-radiogroup-label", children: label }),
|
|
8355
8375
|
options.map((o) => /* @__PURE__ */ jsx80(
|
|
@@ -8377,16 +8397,16 @@ function Fieldset({ busy = false, className = "", ...rest }) {
|
|
|
8377
8397
|
}
|
|
8378
8398
|
|
|
8379
8399
|
// src/components/platform/AccountMenu.tsx
|
|
8380
|
-
import * as
|
|
8400
|
+
import * as React56 from "react";
|
|
8381
8401
|
|
|
8382
8402
|
// src/kits/sessionContext.tsx
|
|
8383
|
-
import * as
|
|
8384
|
-
var SessionContext =
|
|
8403
|
+
import * as React55 from "react";
|
|
8404
|
+
var SessionContext = React55.createContext(null);
|
|
8385
8405
|
function SessionProvider({ value, children }) {
|
|
8386
|
-
return
|
|
8406
|
+
return React55.createElement(SessionContext.Provider, { value }, children);
|
|
8387
8407
|
}
|
|
8388
8408
|
function useSessionContext() {
|
|
8389
|
-
const ctx =
|
|
8409
|
+
const ctx = React55.useContext(SessionContext);
|
|
8390
8410
|
if (!ctx) {
|
|
8391
8411
|
throw new Error(
|
|
8392
8412
|
"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."
|
|
@@ -8426,11 +8446,11 @@ function AccountMenu({
|
|
|
8426
8446
|
...rest
|
|
8427
8447
|
}) {
|
|
8428
8448
|
const { user, roles, can: can2, signOut: ctxSignOut, demo, pending } = useSessionContext();
|
|
8429
|
-
const [open2, setOpen] =
|
|
8430
|
-
const [switching, setSwitching] =
|
|
8431
|
-
const [signingOut, setSigningOut] =
|
|
8432
|
-
const [signOutError, setSignOutError] =
|
|
8433
|
-
const ref =
|
|
8449
|
+
const [open2, setOpen] = React56.useState(false);
|
|
8450
|
+
const [switching, setSwitching] = React56.useState(false);
|
|
8451
|
+
const [signingOut, setSigningOut] = React56.useState(false);
|
|
8452
|
+
const [signOutError, setSignOutError] = React56.useState(null);
|
|
8453
|
+
const ref = React56.useRef(null);
|
|
8434
8454
|
const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
|
|
8435
8455
|
const visibleGroups = groups.map((g) => ({ label: g.label, links: g.links.filter((l) => !l.perm || !pending && can2(l.perm)) })).filter((g) => g.links.length);
|
|
8436
8456
|
const closeMenu = () => {
|
|
@@ -8555,13 +8575,13 @@ function AccountMenu({
|
|
|
8555
8575
|
}
|
|
8556
8576
|
|
|
8557
8577
|
// src/components/platform/AppSwitcher.tsx
|
|
8558
|
-
import * as
|
|
8578
|
+
import * as React57 from "react";
|
|
8559
8579
|
import { jsx as jsx83, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
8560
8580
|
function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
8561
8581
|
const { apps: contextApps } = useSessionContext();
|
|
8562
8582
|
const apps = appsProp ?? contextApps ?? [];
|
|
8563
|
-
const [open2, setOpen] =
|
|
8564
|
-
const anchorRef =
|
|
8583
|
+
const [open2, setOpen] = React57.useState(false);
|
|
8584
|
+
const anchorRef = React57.useRef(null);
|
|
8565
8585
|
if (!apps.length) return null;
|
|
8566
8586
|
const items = apps.map((app) => ({
|
|
8567
8587
|
id: app.key,
|
|
@@ -8575,7 +8595,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
8575
8595
|
window.location.href = app.url;
|
|
8576
8596
|
}
|
|
8577
8597
|
}));
|
|
8578
|
-
return /* @__PURE__ */ jsxs71(
|
|
8598
|
+
return /* @__PURE__ */ jsxs71(React57.Fragment, { children: [
|
|
8579
8599
|
/* @__PURE__ */ jsx83("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx83(
|
|
8580
8600
|
IconButton,
|
|
8581
8601
|
{
|
|
@@ -8604,10 +8624,10 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
8604
8624
|
}
|
|
8605
8625
|
|
|
8606
8626
|
// src/components/platform/AppearanceMenu.tsx
|
|
8607
|
-
import * as
|
|
8627
|
+
import * as React60 from "react";
|
|
8608
8628
|
|
|
8609
8629
|
// src/kits/appearance.ts
|
|
8610
|
-
import * as
|
|
8630
|
+
import * as React58 from "react";
|
|
8611
8631
|
var DEFAULT_STORAGE_KEY = "fd-appearance";
|
|
8612
8632
|
var DEFAULT_PREFS = {
|
|
8613
8633
|
theme: "system",
|
|
@@ -8719,8 +8739,8 @@ function watchAppearance(store, root = document.documentElement) {
|
|
|
8719
8739
|
};
|
|
8720
8740
|
}
|
|
8721
8741
|
function useAppearancePrefs(store) {
|
|
8722
|
-
const prefs =
|
|
8723
|
-
const update =
|
|
8742
|
+
const prefs = React58.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
8743
|
+
const update = React58.useCallback(
|
|
8724
8744
|
(patch) => {
|
|
8725
8745
|
store.write({ ...store.getSnapshot(), ...patch });
|
|
8726
8746
|
},
|
|
@@ -8730,15 +8750,15 @@ function useAppearancePrefs(store) {
|
|
|
8730
8750
|
}
|
|
8731
8751
|
|
|
8732
8752
|
// src/components/platform/AppearanceProvider.tsx
|
|
8733
|
-
import * as
|
|
8753
|
+
import * as React59 from "react";
|
|
8734
8754
|
import { jsx as jsx84 } from "react/jsx-runtime";
|
|
8735
|
-
var AppearanceStoreContext =
|
|
8755
|
+
var AppearanceStoreContext = React59.createContext(null);
|
|
8736
8756
|
function AppearanceProvider({ store, children }) {
|
|
8737
|
-
|
|
8757
|
+
React59.useLayoutEffect(() => watchAppearance(store), [store]);
|
|
8738
8758
|
return /* @__PURE__ */ jsx84(AppearanceStoreContext.Provider, { value: store, children });
|
|
8739
8759
|
}
|
|
8740
8760
|
function useAppearanceStore() {
|
|
8741
|
-
const store =
|
|
8761
|
+
const store = React59.useContext(AppearanceStoreContext);
|
|
8742
8762
|
if (!store) throw new Error("AppearanceMenu and useAppearanceStore must be rendered inside an <AppearanceProvider>.");
|
|
8743
8763
|
return store;
|
|
8744
8764
|
}
|
|
@@ -8758,10 +8778,10 @@ var TEXT_SCALE_OPTIONS = [
|
|
|
8758
8778
|
];
|
|
8759
8779
|
function AppearanceMenu({ className = "" }) {
|
|
8760
8780
|
const [prefs, update] = useAppearancePrefs(useAppearanceStore());
|
|
8761
|
-
const [open2, setOpen] =
|
|
8762
|
-
const anchorRef =
|
|
8781
|
+
const [open2, setOpen] = React60.useState(false);
|
|
8782
|
+
const anchorRef = React60.useRef(null);
|
|
8763
8783
|
const patch = (p) => update(p);
|
|
8764
|
-
return /* @__PURE__ */ jsxs72(
|
|
8784
|
+
return /* @__PURE__ */ jsxs72(React60.Fragment, { children: [
|
|
8765
8785
|
/* @__PURE__ */ jsx85("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx85(
|
|
8766
8786
|
IconButton,
|
|
8767
8787
|
{
|
|
@@ -8830,14 +8850,14 @@ function AppearanceMenu({ className = "" }) {
|
|
|
8830
8850
|
}
|
|
8831
8851
|
|
|
8832
8852
|
// src/components/platform/ApiSpecBrowser.tsx
|
|
8833
|
-
import * as
|
|
8853
|
+
import * as React61 from "react";
|
|
8834
8854
|
import { jsx as jsx86, jsxs as jsxs73 } from "react/jsx-runtime";
|
|
8835
8855
|
var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
|
|
8836
8856
|
function Json({ obj }) {
|
|
8837
8857
|
return /* @__PURE__ */ jsx86("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
|
|
8838
8858
|
}
|
|
8839
8859
|
function Endpoint({ s, onRequest }) {
|
|
8840
|
-
const [tried, setTried] =
|
|
8860
|
+
const [tried, setTried] = React61.useState(null);
|
|
8841
8861
|
const run = async () => {
|
|
8842
8862
|
setTried("busy");
|
|
8843
8863
|
const t0 = (window.performance || Date).now();
|
|
@@ -8910,10 +8930,10 @@ function ApiSpecBrowser({
|
|
|
8910
8930
|
className = "",
|
|
8911
8931
|
...rest
|
|
8912
8932
|
}) {
|
|
8913
|
-
const [q, setQ] =
|
|
8914
|
-
const [method, setMethod] =
|
|
8915
|
-
const [mod, setMod] =
|
|
8916
|
-
const [listOnly, setListOnly] =
|
|
8933
|
+
const [q, setQ] = React61.useState("");
|
|
8934
|
+
const [method, setMethod] = React61.useState(null);
|
|
8935
|
+
const [mod, setMod] = React61.useState(null);
|
|
8936
|
+
const [listOnly, setListOnly] = React61.useState(false);
|
|
8917
8937
|
const activeModule = modules && modules.find((m) => m.id === mod);
|
|
8918
8938
|
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())));
|
|
8919
8939
|
const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
|
|
@@ -8992,7 +9012,7 @@ function ApiSpecBrowser({
|
|
|
8992
9012
|
}
|
|
8993
9013
|
|
|
8994
9014
|
// src/components/platform/ProfilePage.tsx
|
|
8995
|
-
import * as
|
|
9015
|
+
import * as React62 from "react";
|
|
8996
9016
|
import { jsx as jsx87, jsxs as jsxs74 } from "react/jsx-runtime";
|
|
8997
9017
|
function fieldInitialValue(field, user) {
|
|
8998
9018
|
if (field.value) return field.value(user);
|
|
@@ -9028,21 +9048,21 @@ function ProfilePage({
|
|
|
9028
9048
|
}) {
|
|
9029
9049
|
const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
|
|
9030
9050
|
const user = userProp || sessionUser;
|
|
9031
|
-
const initialFieldValues =
|
|
9051
|
+
const initialFieldValues = React62.useMemo(() => {
|
|
9032
9052
|
const values2 = {};
|
|
9033
9053
|
for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
|
|
9034
9054
|
return values2;
|
|
9035
9055
|
}, [user.id, fields]);
|
|
9036
|
-
const initialNotify =
|
|
9056
|
+
const initialNotify = React62.useMemo(() => {
|
|
9037
9057
|
const values2 = {};
|
|
9038
9058
|
for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
|
|
9039
9059
|
return values2;
|
|
9040
9060
|
}, [user.id, notifications]);
|
|
9041
|
-
const [values, setValues] =
|
|
9042
|
-
const [notify, setNotify] =
|
|
9043
|
-
const [saving, setSaving] =
|
|
9044
|
-
const [saved, setSaved] =
|
|
9045
|
-
const [prevUserId, setPrevUserId] =
|
|
9061
|
+
const [values, setValues] = React62.useState(initialFieldValues);
|
|
9062
|
+
const [notify, setNotify] = React62.useState(initialNotify);
|
|
9063
|
+
const [saving, setSaving] = React62.useState(false);
|
|
9064
|
+
const [saved, setSaved] = React62.useState(false);
|
|
9065
|
+
const [prevUserId, setPrevUserId] = React62.useState(user.id);
|
|
9046
9066
|
if (user.id !== prevUserId) {
|
|
9047
9067
|
setPrevUserId(user.id);
|
|
9048
9068
|
setValues(initialFieldValues);
|
|
@@ -9230,7 +9250,7 @@ function ProfilePage({
|
|
|
9230
9250
|
}
|
|
9231
9251
|
|
|
9232
9252
|
// src/components/platform/SessionScreen.tsx
|
|
9233
|
-
import * as
|
|
9253
|
+
import * as React63 from "react";
|
|
9234
9254
|
import { Fragment as Fragment22, jsx as jsx88, jsxs as jsxs75 } from "react/jsx-runtime";
|
|
9235
9255
|
var COPY = {
|
|
9236
9256
|
"signing-in": { busy: "Signing you in\u2026" },
|
|
@@ -9244,13 +9264,13 @@ function SessionScreen({ kind, error, onRetry, productName }) {
|
|
|
9244
9264
|
const copy = COPY[kind];
|
|
9245
9265
|
const busyMessage = "busy" in copy ? copy.busy : null;
|
|
9246
9266
|
const failureTitle = "failure" in copy ? copy.failure : null;
|
|
9247
|
-
const [announced, setAnnounced] =
|
|
9248
|
-
|
|
9267
|
+
const [announced, setAnnounced] = React63.useState("");
|
|
9268
|
+
React63.useEffect(() => {
|
|
9249
9269
|
setAnnounced(busyMessage ?? "");
|
|
9250
9270
|
}, [busyMessage]);
|
|
9251
|
-
const titleRef =
|
|
9271
|
+
const titleRef = React63.useRef(null);
|
|
9252
9272
|
const failed = failureTitle !== null;
|
|
9253
|
-
|
|
9273
|
+
React63.useEffect(() => {
|
|
9254
9274
|
titleRef.current?.focus({ preventScroll: true });
|
|
9255
9275
|
}, [failed]);
|
|
9256
9276
|
return /* @__PURE__ */ jsx88("main", { className: "fd-session-screen", children: /* @__PURE__ */ jsxs75("div", { className: "fd-session-screen-inner", children: [
|
|
@@ -9273,10 +9293,10 @@ function SessionScreen({ kind, error, onRetry, productName }) {
|
|
|
9273
9293
|
}
|
|
9274
9294
|
|
|
9275
9295
|
// src/components/platform/RoadmapTimeline.tsx
|
|
9276
|
-
import * as
|
|
9296
|
+
import * as React66 from "react";
|
|
9277
9297
|
|
|
9278
9298
|
// src/kits/session.ts
|
|
9279
|
-
import * as
|
|
9299
|
+
import * as React64 from "react";
|
|
9280
9300
|
var PERMISSION_CATALOG = [
|
|
9281
9301
|
{ group: "Plans", items: [
|
|
9282
9302
|
{ key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
|
|
@@ -10843,8 +10863,8 @@ function roadmap(overrides) {
|
|
|
10843
10863
|
};
|
|
10844
10864
|
}
|
|
10845
10865
|
function useSession() {
|
|
10846
|
-
const [s, setS] =
|
|
10847
|
-
|
|
10866
|
+
const [s, setS] = React64.useState(getSession);
|
|
10867
|
+
React64.useEffect(() => subscribe(setS), []);
|
|
10848
10868
|
return s;
|
|
10849
10869
|
}
|
|
10850
10870
|
var SessionKit = {
|
|
@@ -10877,7 +10897,7 @@ var SessionKit = {
|
|
|
10877
10897
|
};
|
|
10878
10898
|
function DemoSessionProvider({ children }) {
|
|
10879
10899
|
const session = useSession();
|
|
10880
|
-
const value =
|
|
10900
|
+
const value = React64.useMemo(
|
|
10881
10901
|
() => ({
|
|
10882
10902
|
user: session.user,
|
|
10883
10903
|
roles: session.roles,
|
|
@@ -10893,11 +10913,11 @@ function DemoSessionProvider({ children }) {
|
|
|
10893
10913
|
}),
|
|
10894
10914
|
[session]
|
|
10895
10915
|
);
|
|
10896
|
-
return
|
|
10916
|
+
return React64.createElement(SessionProvider, { value }, children);
|
|
10897
10917
|
}
|
|
10898
10918
|
|
|
10899
10919
|
// src/kits/runtime.ts
|
|
10900
|
-
import * as
|
|
10920
|
+
import * as React65 from "react";
|
|
10901
10921
|
var WIRED_ENDPOINTS = [
|
|
10902
10922
|
// Nothing yet. Every id below would come from a real service:
|
|
10903
10923
|
// "plan.get", "placements.list", …
|
|
@@ -11068,8 +11088,8 @@ var RuntimeKit = {
|
|
|
11068
11088
|
};
|
|
11069
11089
|
RuntimeKit.declare(FEATURE_NEEDS);
|
|
11070
11090
|
function useRuntimeMode() {
|
|
11071
|
-
const [m, setM] =
|
|
11072
|
-
|
|
11091
|
+
const [m, setM] = React65.useState(RuntimeKit.getMode());
|
|
11092
|
+
React65.useEffect(() => RuntimeKit.subscribe(setM), []);
|
|
11073
11093
|
return m;
|
|
11074
11094
|
}
|
|
11075
11095
|
function useFeatureStatus(key) {
|
|
@@ -11152,12 +11172,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
11152
11172
|
}
|
|
11153
11173
|
function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
11154
11174
|
const session = SessionKit.useSession();
|
|
11155
|
-
const [project, setProject] =
|
|
11156
|
-
const [q, setQ] =
|
|
11157
|
-
const scrollRef =
|
|
11158
|
-
const nowRef =
|
|
11159
|
-
const rm =
|
|
11160
|
-
const byKey =
|
|
11175
|
+
const [project, setProject] = React66.useState("");
|
|
11176
|
+
const [q, setQ] = React66.useState("");
|
|
11177
|
+
const scrollRef = React66.useRef(null);
|
|
11178
|
+
const nowRef = React66.useRef(null);
|
|
11179
|
+
const rm = React66.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
|
|
11180
|
+
const byKey = React66.useMemo(() => {
|
|
11161
11181
|
const m = {};
|
|
11162
11182
|
rm.items.forEach((i) => {
|
|
11163
11183
|
m[i.key] = i;
|
|
@@ -11166,7 +11186,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
11166
11186
|
}, [rm]);
|
|
11167
11187
|
const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
|
|
11168
11188
|
const projects = [...new Set(rm.items.map((i) => i.project))];
|
|
11169
|
-
|
|
11189
|
+
React66.useEffect(() => {
|
|
11170
11190
|
let raf1 = 0, raf2 = 0;
|
|
11171
11191
|
const place = () => {
|
|
11172
11192
|
const box = scrollRef.current, mark = nowRef.current;
|
|
@@ -11240,7 +11260,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
11240
11260
|
lastPhase = item.phase;
|
|
11241
11261
|
const inPhase = items.filter((i) => i.phase === item.phase).length;
|
|
11242
11262
|
const isBoundary = n === firstPending;
|
|
11243
|
-
return /* @__PURE__ */ jsxs76(
|
|
11263
|
+
return /* @__PURE__ */ jsxs76(React66.Fragment, { children: [
|
|
11244
11264
|
showPhase ? /* @__PURE__ */ jsxs76("div", { className: "fd-rm-era", children: [
|
|
11245
11265
|
/* @__PURE__ */ jsxs76("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
|
|
11246
11266
|
/* @__PURE__ */ jsx89("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
|
|
@@ -11284,7 +11304,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
11284
11304
|
}
|
|
11285
11305
|
|
|
11286
11306
|
// src/components/platform/ComingSoon.tsx
|
|
11287
|
-
import * as
|
|
11307
|
+
import * as React67 from "react";
|
|
11288
11308
|
import { createPortal as createPortal6 } from "react-dom";
|
|
11289
11309
|
import { Fragment as Fragment24, jsx as jsx90, jsxs as jsxs77 } from "react/jsx-runtime";
|
|
11290
11310
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
@@ -11302,8 +11322,8 @@ function writeBypassed(list) {
|
|
|
11302
11322
|
}
|
|
11303
11323
|
}
|
|
11304
11324
|
function useBypass(key) {
|
|
11305
|
-
const [on, setOn] =
|
|
11306
|
-
|
|
11325
|
+
const [on, setOn] = React67.useState(() => !!key && readBypassed().indexOf(key) >= 0);
|
|
11326
|
+
React67.useEffect(() => {
|
|
11307
11327
|
setOn(!!key && readBypassed().indexOf(key) >= 0);
|
|
11308
11328
|
}, [key]);
|
|
11309
11329
|
const set = (next) => {
|
|
@@ -11350,9 +11370,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
|
|
|
11350
11370
|
] });
|
|
11351
11371
|
}
|
|
11352
11372
|
function useHoverCard(open2) {
|
|
11353
|
-
const anchor =
|
|
11354
|
-
const [pos, setPos] =
|
|
11355
|
-
|
|
11373
|
+
const anchor = React67.useRef(null);
|
|
11374
|
+
const [pos, setPos] = React67.useState(null);
|
|
11375
|
+
React67.useLayoutEffect(() => {
|
|
11356
11376
|
if (!open2 || !anchor.current) {
|
|
11357
11377
|
setPos(null);
|
|
11358
11378
|
return;
|
|
@@ -11479,12 +11499,12 @@ function ComingSoon({
|
|
|
11479
11499
|
] });
|
|
11480
11500
|
}
|
|
11481
11501
|
function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
|
|
11482
|
-
const [open2, setOpen] =
|
|
11502
|
+
const [open2, setOpen] = React67.useState(false);
|
|
11483
11503
|
const [anchor, pos] = useHoverCard(open2);
|
|
11484
|
-
const hoverCardRef =
|
|
11504
|
+
const hoverCardRef = React67.useRef(null);
|
|
11485
11505
|
const hoverLayer = useStackedLayer({ active: open2, containerRef: hoverCardRef, returnFocus: false });
|
|
11486
11506
|
const zIndex = useLayerZIndex(hoverLayer);
|
|
11487
|
-
const close2 =
|
|
11507
|
+
const close2 = React67.useRef(null);
|
|
11488
11508
|
const show = () => {
|
|
11489
11509
|
if (close2.current) {
|
|
11490
11510
|
clearTimeout(close2.current);
|
|
@@ -11500,7 +11520,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
11500
11520
|
setOpen(false);
|
|
11501
11521
|
}, 140);
|
|
11502
11522
|
};
|
|
11503
|
-
|
|
11523
|
+
React67.useEffect(() => () => {
|
|
11504
11524
|
if (close2.current) clearTimeout(close2.current);
|
|
11505
11525
|
}, []);
|
|
11506
11526
|
return /* @__PURE__ */ jsxs77(
|
|
@@ -11952,7 +11972,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
11952
11972
|
}
|
|
11953
11973
|
|
|
11954
11974
|
// src/components/planner/MixGap.tsx
|
|
11955
|
-
import * as
|
|
11975
|
+
import * as React68 from "react";
|
|
11956
11976
|
import { Fragment as Fragment26, jsx as jsx95, jsxs as jsxs82 } from "react/jsx-runtime";
|
|
11957
11977
|
var MIX_GAP_LAYOUT = {
|
|
11958
11978
|
trackHeight: 30,
|
|
@@ -11967,7 +11987,7 @@ function mixGapOffset(value, max) {
|
|
|
11967
11987
|
}
|
|
11968
11988
|
function MixGap({ rows = [], loading = false, className = "" }) {
|
|
11969
11989
|
const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
|
|
11970
|
-
const [hover, setHover] =
|
|
11990
|
+
const [hover, setHover] = React68.useState(null);
|
|
11971
11991
|
const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
|
|
11972
11992
|
const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
|
|
11973
11993
|
const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
|
|
@@ -12110,7 +12130,7 @@ function ChannelContribution({
|
|
|
12110
12130
|
}
|
|
12111
12131
|
|
|
12112
12132
|
// src/components/planner/BudgetReallocator.tsx
|
|
12113
|
-
import * as
|
|
12133
|
+
import * as React69 from "react";
|
|
12114
12134
|
import { Fragment as Fragment27, jsx as jsx97, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
12115
12135
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
12116
12136
|
function BudgetReallocator({
|
|
@@ -12126,8 +12146,8 @@ function BudgetReallocator({
|
|
|
12126
12146
|
onCancel,
|
|
12127
12147
|
className = ""
|
|
12128
12148
|
}) {
|
|
12129
|
-
const [draft, setDraft] =
|
|
12130
|
-
|
|
12149
|
+
const [draft, setDraft] = React69.useState(spend);
|
|
12150
|
+
React69.useEffect(() => setDraft(spend), [spend]);
|
|
12131
12151
|
const dirty = draft !== spend;
|
|
12132
12152
|
const nextCrp = scoreFor ? scoreFor(draft) : crp;
|
|
12133
12153
|
const nextBand = bandFor(nextCrp);
|
|
@@ -12142,10 +12162,10 @@ function BudgetReallocator({
|
|
|
12142
12162
|
setDraft(spend);
|
|
12143
12163
|
if (onCancel) onCancel();
|
|
12144
12164
|
};
|
|
12145
|
-
const trackRef =
|
|
12146
|
-
const chipRef =
|
|
12147
|
-
const [chipLeft, setChipLeft] =
|
|
12148
|
-
|
|
12165
|
+
const trackRef = React69.useRef(null);
|
|
12166
|
+
const chipRef = React69.useRef(null);
|
|
12167
|
+
const [chipLeft, setChipLeft] = React69.useState(null);
|
|
12168
|
+
React69.useLayoutEffect(() => {
|
|
12149
12169
|
const track = trackRef.current;
|
|
12150
12170
|
if (!dirty || !track) {
|
|
12151
12171
|
setChipLeft(null);
|
|
@@ -12333,7 +12353,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
|
|
|
12333
12353
|
}
|
|
12334
12354
|
|
|
12335
12355
|
// src/components/planner/PreferenceMeter.tsx
|
|
12336
|
-
import * as
|
|
12356
|
+
import * as React70 from "react";
|
|
12337
12357
|
import { jsx as jsx100, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
12338
12358
|
function preferenceScore(criteria) {
|
|
12339
12359
|
const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
|
|
@@ -12363,7 +12383,7 @@ function PreferenceMeter({
|
|
|
12363
12383
|
className = ""
|
|
12364
12384
|
}) {
|
|
12365
12385
|
const value = score == null ? preferenceScore(criteria) : score;
|
|
12366
|
-
const segments =
|
|
12386
|
+
const segments = React70.useMemo(() => preferenceSegments(criteria), [criteria]);
|
|
12367
12387
|
return /* @__PURE__ */ jsx100(
|
|
12368
12388
|
ScoreMeter,
|
|
12369
12389
|
{
|
|
@@ -12402,13 +12422,13 @@ function PreferenceMeter({
|
|
|
12402
12422
|
}
|
|
12403
12423
|
|
|
12404
12424
|
// src/components/chat/AgentChatPanel.tsx
|
|
12405
|
-
import * as
|
|
12425
|
+
import * as React77 from "react";
|
|
12406
12426
|
|
|
12407
12427
|
// src/components/chat/chatEngine.ts
|
|
12408
|
-
import * as
|
|
12428
|
+
import * as React72 from "react";
|
|
12409
12429
|
|
|
12410
12430
|
// src/components/chat/chatStore.ts
|
|
12411
|
-
import * as
|
|
12431
|
+
import * as React71 from "react";
|
|
12412
12432
|
var safeStore = {
|
|
12413
12433
|
get(k) {
|
|
12414
12434
|
try {
|
|
@@ -12437,13 +12457,13 @@ function useChatDraft(owner, contextType, contextId, store = safeStore) {
|
|
|
12437
12457
|
if (owner === "") throw new Error("useChatDraft: draftOwner is an empty string; pass the signed-in user's id, or null for no owner.");
|
|
12438
12458
|
const key = owner === null ? null : draftKey(owner, contextType, contextId);
|
|
12439
12459
|
const read2 = (k) => k ? store.get(k) || "" : "";
|
|
12440
|
-
const [state, setState] =
|
|
12460
|
+
const [state, setState] = React71.useState(() => ({ key, text: read2(key) }));
|
|
12441
12461
|
let current2 = state;
|
|
12442
12462
|
if (state.key !== key) {
|
|
12443
12463
|
current2 = { key, text: read2(key) };
|
|
12444
12464
|
setState(current2);
|
|
12445
12465
|
}
|
|
12446
|
-
const setText =
|
|
12466
|
+
const setText = React71.useCallback((text) => {
|
|
12447
12467
|
if (key) {
|
|
12448
12468
|
if (text) {
|
|
12449
12469
|
store.set(key, text);
|
|
@@ -12502,33 +12522,33 @@ function useChatEngine(opts) {
|
|
|
12502
12522
|
onClear,
|
|
12503
12523
|
onFeedback
|
|
12504
12524
|
} = opts || {};
|
|
12505
|
-
const [status, setStatus] =
|
|
12506
|
-
const [threadId, setThreadId] =
|
|
12507
|
-
const [messages, setMessages] =
|
|
12508
|
-
const [queue, setQueue] =
|
|
12509
|
-
const [fatal, setFatal] =
|
|
12510
|
-
const [busy, setBusy] =
|
|
12511
|
-
const [turnStartedAt, setTurnStartedAt] =
|
|
12512
|
-
const listRef =
|
|
12513
|
-
const queueRef =
|
|
12514
|
-
const busyRef =
|
|
12515
|
-
const loadedRef =
|
|
12516
|
-
const stoppedRef =
|
|
12517
|
-
const abortRef =
|
|
12518
|
-
const serverCount =
|
|
12519
|
-
const serverIds =
|
|
12520
|
-
const liveTurn =
|
|
12521
|
-
const lastTurnOwn =
|
|
12522
|
-
const retired =
|
|
12523
|
-
const threadRef =
|
|
12524
|
-
const mounted =
|
|
12525
|
-
|
|
12525
|
+
const [status, setStatus] = React72.useState("idle");
|
|
12526
|
+
const [threadId, setThreadId] = React72.useState(null);
|
|
12527
|
+
const [messages, setMessages] = React72.useState([]);
|
|
12528
|
+
const [queue, setQueue] = React72.useState([]);
|
|
12529
|
+
const [fatal, setFatal] = React72.useState(null);
|
|
12530
|
+
const [busy, setBusy] = React72.useState(false);
|
|
12531
|
+
const [turnStartedAt, setTurnStartedAt] = React72.useState(null);
|
|
12532
|
+
const listRef = React72.useRef([]);
|
|
12533
|
+
const queueRef = React72.useRef([]);
|
|
12534
|
+
const busyRef = React72.useRef(false);
|
|
12535
|
+
const loadedRef = React72.useRef(false);
|
|
12536
|
+
const stoppedRef = React72.useRef(false);
|
|
12537
|
+
const abortRef = React72.useRef(null);
|
|
12538
|
+
const serverCount = React72.useRef(0);
|
|
12539
|
+
const serverIds = React72.useRef(/* @__PURE__ */ new Set());
|
|
12540
|
+
const liveTurn = React72.useRef(null);
|
|
12541
|
+
const lastTurnOwn = React72.useRef(/* @__PURE__ */ new Set());
|
|
12542
|
+
const retired = React72.useRef(/* @__PURE__ */ new Set());
|
|
12543
|
+
const threadRef = React72.useRef(null);
|
|
12544
|
+
const mounted = React72.useRef(true);
|
|
12545
|
+
React72.useEffect(() => {
|
|
12526
12546
|
mounted.current = true;
|
|
12527
12547
|
return () => {
|
|
12528
12548
|
mounted.current = false;
|
|
12529
12549
|
};
|
|
12530
12550
|
}, []);
|
|
12531
|
-
const describeWaitingRef =
|
|
12551
|
+
const describeWaitingRef = React72.useRef(describeWaiting);
|
|
12532
12552
|
describeWaitingRef.current = describeWaiting;
|
|
12533
12553
|
const commit = (next) => {
|
|
12534
12554
|
const derived = withWaiting(next, (pending) => describeWaitingRef.current(pending));
|
|
@@ -12547,7 +12567,7 @@ function useChatEngine(opts) {
|
|
|
12547
12567
|
}
|
|
12548
12568
|
return false;
|
|
12549
12569
|
};
|
|
12550
|
-
const loadThread =
|
|
12570
|
+
const loadThread = React72.useCallback(async (id) => {
|
|
12551
12571
|
const data = await apiAdapter.getThread(id);
|
|
12552
12572
|
const list = [...data && data.messages || []];
|
|
12553
12573
|
serverCount.current = list.length;
|
|
@@ -12587,7 +12607,7 @@ function useChatEngine(opts) {
|
|
|
12587
12607
|
packet: progress.packet ?? holder.packet
|
|
12588
12608
|
});
|
|
12589
12609
|
}
|
|
12590
|
-
|
|
12610
|
+
React72.useEffect(() => {
|
|
12591
12611
|
if (!apiAdapter) {
|
|
12592
12612
|
setStatus("idle");
|
|
12593
12613
|
setFatal(null);
|
|
@@ -12819,7 +12839,7 @@ function useChatEngine(opts) {
|
|
|
12819
12839
|
await dispatchTurn(turn);
|
|
12820
12840
|
}
|
|
12821
12841
|
}
|
|
12822
|
-
const send =
|
|
12842
|
+
const send = React72.useCallback((text, attachments) => {
|
|
12823
12843
|
const body = (text || "").trim();
|
|
12824
12844
|
if (!body && !(attachments && attachments.length)) return;
|
|
12825
12845
|
if (status === "disconnected") return;
|
|
@@ -12829,7 +12849,7 @@ function useChatEngine(opts) {
|
|
|
12829
12849
|
stoppedRef.current = false;
|
|
12830
12850
|
drain();
|
|
12831
12851
|
}, [status]);
|
|
12832
|
-
const stop =
|
|
12852
|
+
const stop = React72.useCallback(() => {
|
|
12833
12853
|
stoppedRef.current = true;
|
|
12834
12854
|
const ac = abortRef.current;
|
|
12835
12855
|
if (ac) {
|
|
@@ -12848,11 +12868,11 @@ function useChatEngine(opts) {
|
|
|
12848
12868
|
store.del(jobKey(threadRef.current));
|
|
12849
12869
|
}
|
|
12850
12870
|
}, [apiAdapter]);
|
|
12851
|
-
const removeQueued =
|
|
12871
|
+
const removeQueued = React72.useCallback((id) => {
|
|
12852
12872
|
queueRef.current = queueRef.current.filter((t) => t.id !== id);
|
|
12853
12873
|
setQueue(queueRef.current.slice());
|
|
12854
12874
|
}, []);
|
|
12855
|
-
const retry =
|
|
12875
|
+
const retry = React72.useCallback(() => {
|
|
12856
12876
|
const list = listRef.current;
|
|
12857
12877
|
let at = -1;
|
|
12858
12878
|
for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
|
|
@@ -12869,19 +12889,19 @@ function useChatEngine(opts) {
|
|
|
12869
12889
|
setQueue(queueRef.current.slice());
|
|
12870
12890
|
drain();
|
|
12871
12891
|
}, []);
|
|
12872
|
-
const clear =
|
|
12892
|
+
const clear = React72.useCallback(() => {
|
|
12873
12893
|
commit([]);
|
|
12874
12894
|
serverCount.current = 0;
|
|
12875
12895
|
queueRef.current = [];
|
|
12876
12896
|
setQueue([]);
|
|
12877
12897
|
onClear && onClear();
|
|
12878
12898
|
}, [onClear]);
|
|
12879
|
-
const setFeedback =
|
|
12899
|
+
const setFeedback = React72.useCallback((id, value) => {
|
|
12880
12900
|
patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
|
|
12881
12901
|
const msg = listRef.current.find((m) => m.id === id);
|
|
12882
12902
|
onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
|
|
12883
12903
|
}, [onFeedback]);
|
|
12884
|
-
const reload =
|
|
12904
|
+
const reload = React72.useCallback(async () => {
|
|
12885
12905
|
if (!threadRef.current) return;
|
|
12886
12906
|
setStatus("loading");
|
|
12887
12907
|
try {
|
|
@@ -12919,10 +12939,10 @@ var ChatKit = {
|
|
|
12919
12939
|
};
|
|
12920
12940
|
|
|
12921
12941
|
// src/components/chat/ChatTranscript.tsx
|
|
12922
|
-
import * as
|
|
12942
|
+
import * as React74 from "react";
|
|
12923
12943
|
|
|
12924
12944
|
// src/components/chat/ChatTurn.tsx
|
|
12925
|
-
import * as
|
|
12945
|
+
import * as React73 from "react";
|
|
12926
12946
|
import { jsx as jsx101, jsxs as jsxs88 } from "react/jsx-runtime";
|
|
12927
12947
|
function JsonView({ value }) {
|
|
12928
12948
|
let text;
|
|
@@ -12959,7 +12979,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
|
12959
12979
|
] });
|
|
12960
12980
|
}
|
|
12961
12981
|
function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
12962
|
-
const [open2, setOpen] =
|
|
12982
|
+
const [open2, setOpen] = React73.useState(defaultOpen);
|
|
12963
12983
|
if (!text) return null;
|
|
12964
12984
|
return /* @__PURE__ */ jsxs88("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
|
|
12965
12985
|
/* @__PURE__ */ jsxs88("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -12976,7 +12996,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
|
12976
12996
|
] });
|
|
12977
12997
|
}
|
|
12978
12998
|
function Citations({ items = [], onOpen }) {
|
|
12979
|
-
const [open2, setOpen] =
|
|
12999
|
+
const [open2, setOpen] = React73.useState(false);
|
|
12980
13000
|
if (!items.length) return null;
|
|
12981
13001
|
return /* @__PURE__ */ jsxs88("div", { className: "fdc-cites", children: [
|
|
12982
13002
|
/* @__PURE__ */ jsxs88("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -13002,7 +13022,7 @@ function clampText(text, max) {
|
|
|
13002
13022
|
return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
13003
13023
|
}
|
|
13004
13024
|
function MessageBody({ message: m, ctx }) {
|
|
13005
|
-
const [expanded, setExpanded] =
|
|
13025
|
+
const [expanded, setExpanded] = React73.useState(false);
|
|
13006
13026
|
const isUser = m.role === "user";
|
|
13007
13027
|
const raw = m.text || "";
|
|
13008
13028
|
const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
|
|
@@ -13081,7 +13101,7 @@ function RunActions({ group, ctx }) {
|
|
|
13081
13101
|
] }),
|
|
13082
13102
|
isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx101("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx101("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
|
|
13083
13103
|
group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx101("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx101("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
|
|
13084
|
-
isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs88(
|
|
13104
|
+
isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs88(React73.Fragment, { children: [
|
|
13085
13105
|
/* @__PURE__ */ jsx101("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__ */ jsx101("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
|
|
13086
13106
|
/* @__PURE__ */ jsx101("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__ */ jsx101("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
|
|
13087
13107
|
] }) : null,
|
|
@@ -13176,10 +13196,10 @@ function ChatTranscript({
|
|
|
13176
13196
|
renderEmpty,
|
|
13177
13197
|
className = ""
|
|
13178
13198
|
}) {
|
|
13179
|
-
const scroller =
|
|
13180
|
-
const stick =
|
|
13181
|
-
const [pill, setPill] =
|
|
13182
|
-
const seen =
|
|
13199
|
+
const scroller = React74.useRef(null);
|
|
13200
|
+
const stick = React74.useRef(true);
|
|
13201
|
+
const [pill, setPill] = React74.useState(0);
|
|
13202
|
+
const seen = React74.useRef(0);
|
|
13183
13203
|
const toBottom = (smooth) => {
|
|
13184
13204
|
const el = scroller.current;
|
|
13185
13205
|
if (!el) return;
|
|
@@ -13198,7 +13218,7 @@ function ChatTranscript({
|
|
|
13198
13218
|
seen.current = messages.length;
|
|
13199
13219
|
}
|
|
13200
13220
|
};
|
|
13201
|
-
|
|
13221
|
+
React74.useLayoutEffect(() => {
|
|
13202
13222
|
const el = scroller.current;
|
|
13203
13223
|
if (!el) return;
|
|
13204
13224
|
if (stick.current) {
|
|
@@ -13206,7 +13226,7 @@ function ChatTranscript({
|
|
|
13206
13226
|
seen.current = messages.length;
|
|
13207
13227
|
} else setPill(Math.max(0, messages.length - seen.current));
|
|
13208
13228
|
}, [messages]);
|
|
13209
|
-
|
|
13229
|
+
React74.useEffect(() => {
|
|
13210
13230
|
const el = scroller.current;
|
|
13211
13231
|
const inner = el && el.firstChild;
|
|
13212
13232
|
if (!el || !inner || typeof ResizeObserver === "undefined") return;
|
|
@@ -13216,7 +13236,7 @@ function ChatTranscript({
|
|
|
13216
13236
|
ro.observe(inner);
|
|
13217
13237
|
return () => ro.disconnect();
|
|
13218
13238
|
}, []);
|
|
13219
|
-
const groups =
|
|
13239
|
+
const groups = React74.useMemo(() => groupMessages(messages), [messages]);
|
|
13220
13240
|
const empty = !messages.length && status === "ready";
|
|
13221
13241
|
return /* @__PURE__ */ jsxs89("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
|
|
13222
13242
|
/* @__PURE__ */ jsxs89("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
|
|
@@ -13240,7 +13260,7 @@ function ChatTranscript({
|
|
|
13240
13260
|
const prev = groups[i - 1];
|
|
13241
13261
|
const k = dayKey(g.messages[0].timestamp);
|
|
13242
13262
|
const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
|
|
13243
|
-
return /* @__PURE__ */ jsxs89(
|
|
13263
|
+
return /* @__PURE__ */ jsxs89(React74.Fragment, { children: [
|
|
13244
13264
|
showDay ? /* @__PURE__ */ jsx102("div", { className: "fdc-day", children: /* @__PURE__ */ jsx102("span", { children: dayLabel(k) }) }) : null,
|
|
13245
13265
|
/* @__PURE__ */ jsx102(ChatTurn, { group: g, ctx })
|
|
13246
13266
|
] }, g.key || i);
|
|
@@ -13257,7 +13277,7 @@ function ChatTranscript({
|
|
|
13257
13277
|
var TranscriptKit = { groupMessages };
|
|
13258
13278
|
|
|
13259
13279
|
// src/components/chat/ChatComposer.tsx
|
|
13260
|
-
import * as
|
|
13280
|
+
import * as React75 from "react";
|
|
13261
13281
|
import { jsx as jsx103, jsxs as jsxs90 } from "react/jsx-runtime";
|
|
13262
13282
|
function ChatComposer({
|
|
13263
13283
|
onSubmit,
|
|
@@ -13285,17 +13305,17 @@ function ChatComposer({
|
|
|
13285
13305
|
onReject,
|
|
13286
13306
|
onOpenAttachment
|
|
13287
13307
|
}) {
|
|
13288
|
-
const [text, setText] =
|
|
13289
|
-
const [trigger, setTrigger] =
|
|
13290
|
-
const [mentionItems, setMentionItems] =
|
|
13291
|
-
const [listening, setListening] =
|
|
13292
|
-
const [notice, setNotice] =
|
|
13293
|
-
const editor =
|
|
13294
|
-
const wrap =
|
|
13295
|
-
const stopVoice =
|
|
13308
|
+
const [text, setText] = React75.useState(draft || "");
|
|
13309
|
+
const [trigger, setTrigger] = React75.useState(null);
|
|
13310
|
+
const [mentionItems, setMentionItems] = React75.useState([]);
|
|
13311
|
+
const [listening, setListening] = React75.useState(false);
|
|
13312
|
+
const [notice, setNotice] = React75.useState(null);
|
|
13313
|
+
const editor = React75.useRef(null);
|
|
13314
|
+
const wrap = React75.useRef(null);
|
|
13315
|
+
const stopVoice = React75.useRef(null);
|
|
13296
13316
|
const staged = useStagedFiles(fileUploadHandler, { onError: () => {
|
|
13297
13317
|
} });
|
|
13298
|
-
|
|
13318
|
+
React75.useEffect(() => {
|
|
13299
13319
|
if (draft != null && draft !== text) setText(draft);
|
|
13300
13320
|
}, [draft]);
|
|
13301
13321
|
const change = (v) => {
|
|
@@ -13331,7 +13351,7 @@ function ChatComposer({
|
|
|
13331
13351
|
e.preventDefault();
|
|
13332
13352
|
staged.add(found.files);
|
|
13333
13353
|
};
|
|
13334
|
-
|
|
13354
|
+
React75.useEffect(() => {
|
|
13335
13355
|
if (!trigger || trigger.type !== "mention" || !mentionSources) {
|
|
13336
13356
|
setMentionItems([]);
|
|
13337
13357
|
return;
|
|
@@ -13349,7 +13369,7 @@ function ChatComposer({
|
|
|
13349
13369
|
const q = (trigger.query || "").toLowerCase();
|
|
13350
13370
|
setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
|
|
13351
13371
|
}, [trigger, mentionSources]);
|
|
13352
|
-
const slashItems =
|
|
13372
|
+
const slashItems = React75.useMemo(() => {
|
|
13353
13373
|
if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
|
|
13354
13374
|
const q = (trigger.query || "").toLowerCase();
|
|
13355
13375
|
return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
|
|
@@ -13519,12 +13539,12 @@ function ChatComposer({
|
|
|
13519
13539
|
}
|
|
13520
13540
|
|
|
13521
13541
|
// src/components/chat/ChatSessionBar.tsx
|
|
13522
|
-
import * as
|
|
13542
|
+
import * as React76 from "react";
|
|
13523
13543
|
import { jsx as jsx104, jsxs as jsxs91 } from "react/jsx-runtime";
|
|
13524
13544
|
var compact2 = meterFormats.compact;
|
|
13525
13545
|
function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
|
|
13526
|
-
const [open2, setOpen] =
|
|
13527
|
-
const anchor =
|
|
13546
|
+
const [open2, setOpen] = React76.useState(false);
|
|
13547
|
+
const anchor = React76.useRef(null);
|
|
13528
13548
|
const stats = sessionStats || null;
|
|
13529
13549
|
const cu = contextUsage || null;
|
|
13530
13550
|
const limits = usageLimits || null;
|
|
@@ -13539,7 +13559,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
13539
13559
|
if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
|
|
13540
13560
|
if (cu) bits.push(pct + "% context");
|
|
13541
13561
|
const expandable = !!(cu || limits);
|
|
13542
|
-
return /* @__PURE__ */ jsxs91(
|
|
13562
|
+
return /* @__PURE__ */ jsxs91(React76.Fragment, { children: [
|
|
13543
13563
|
/* @__PURE__ */ jsxs91("div", { className: "fdc-bar", children: [
|
|
13544
13564
|
/* @__PURE__ */ jsxs91(
|
|
13545
13565
|
"button",
|
|
@@ -13680,7 +13700,7 @@ function ModelControls({
|
|
|
13680
13700
|
] })
|
|
13681
13701
|
});
|
|
13682
13702
|
}
|
|
13683
|
-
return /* @__PURE__ */ jsxs91(
|
|
13703
|
+
return /* @__PURE__ */ jsxs91(React76.Fragment, { children: [
|
|
13684
13704
|
/* @__PURE__ */ jsx104(
|
|
13685
13705
|
MenuButton,
|
|
13686
13706
|
{
|
|
@@ -13800,11 +13820,11 @@ function AgentChatPanel({
|
|
|
13800
13820
|
onFeedback,
|
|
13801
13821
|
onEditMessage
|
|
13802
13822
|
}) {
|
|
13803
|
-
const [panelWidth, setPanelWidth] =
|
|
13804
|
-
const [applied, setApplied] =
|
|
13823
|
+
const [panelWidth, setPanelWidth] = React77.useState(width);
|
|
13824
|
+
const [applied, setApplied] = React77.useState({});
|
|
13805
13825
|
const [draft, setDraft] = useChatDraft(draftOwner, contextType, contextId);
|
|
13806
|
-
const dragging =
|
|
13807
|
-
|
|
13826
|
+
const dragging = React77.useRef(null);
|
|
13827
|
+
React77.useEffect(() => setPanelWidth(width), [width]);
|
|
13808
13828
|
const engine = useChatEngine({
|
|
13809
13829
|
contextType,
|
|
13810
13830
|
contextId,
|
|
@@ -14010,7 +14030,7 @@ function AgentChatPanel({
|
|
|
14010
14030
|
}
|
|
14011
14031
|
|
|
14012
14032
|
// src/components/files/FileViewer.tsx
|
|
14013
|
-
import * as
|
|
14033
|
+
import * as React78 from "react";
|
|
14014
14034
|
import { jsx as jsx106, jsxs as jsxs93 } from "react/jsx-runtime";
|
|
14015
14035
|
function previewKindOf(file) {
|
|
14016
14036
|
const mime = (file.mime || "").toLowerCase();
|
|
@@ -14067,13 +14087,13 @@ function parseDelimited(text, delimiter) {
|
|
|
14067
14087
|
return rows;
|
|
14068
14088
|
}
|
|
14069
14089
|
function usePreview(file, kind, resolveUrl) {
|
|
14070
|
-
const [state, setState] =
|
|
14071
|
-
const [attempt, setAttempt] =
|
|
14072
|
-
const resolveRef =
|
|
14073
|
-
|
|
14090
|
+
const [state, setState] = React78.useState({ status: "loading" });
|
|
14091
|
+
const [attempt, setAttempt] = React78.useState(0);
|
|
14092
|
+
const resolveRef = React78.useRef(resolveUrl);
|
|
14093
|
+
React78.useEffect(() => {
|
|
14074
14094
|
resolveRef.current = resolveUrl;
|
|
14075
14095
|
}, [resolveUrl]);
|
|
14076
|
-
|
|
14096
|
+
React78.useEffect(() => {
|
|
14077
14097
|
if (kind === "none") {
|
|
14078
14098
|
setState({ status: "ready" });
|
|
14079
14099
|
return;
|
|
@@ -14103,7 +14123,7 @@ function usePreview(file, kind, resolveUrl) {
|
|
|
14103
14123
|
if (ac) ac.abort();
|
|
14104
14124
|
};
|
|
14105
14125
|
}, [file.id, kind, attempt]);
|
|
14106
|
-
return { ...state, retry:
|
|
14126
|
+
return { ...state, retry: React78.useCallback(() => setAttempt((a) => a + 1), []) };
|
|
14107
14127
|
}
|
|
14108
14128
|
function PreviewBody({ file, kind, state }) {
|
|
14109
14129
|
if (kind === "image") return /* @__PURE__ */ jsx106("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
|
|
@@ -14148,13 +14168,13 @@ function PreviewBody({ file, kind, state }) {
|
|
|
14148
14168
|
] });
|
|
14149
14169
|
}
|
|
14150
14170
|
function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
|
|
14151
|
-
const kind =
|
|
14171
|
+
const kind = React78.useMemo(() => previewKindOf(file), [file]);
|
|
14152
14172
|
const preview = usePreview(file, kind, resolveUrl);
|
|
14153
|
-
const [tab, setTab] =
|
|
14154
|
-
const [downloading, setDownloading] =
|
|
14155
|
-
const [downloadError, setDownloadError] =
|
|
14173
|
+
const [tab, setTab] = React78.useState("preview");
|
|
14174
|
+
const [downloading, setDownloading] = React78.useState(false);
|
|
14175
|
+
const [downloadError, setDownloadError] = React78.useState(null);
|
|
14156
14176
|
const hasSide = sidePanel != null;
|
|
14157
|
-
|
|
14177
|
+
React78.useEffect(() => {
|
|
14158
14178
|
setTab("preview");
|
|
14159
14179
|
}, [file.id]);
|
|
14160
14180
|
const download = () => {
|
|
@@ -14221,7 +14241,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
14221
14241
|
}
|
|
14222
14242
|
|
|
14223
14243
|
// src/components/files/FileBrowser.tsx
|
|
14224
|
-
import * as
|
|
14244
|
+
import * as React79 from "react";
|
|
14225
14245
|
import { Fragment as Fragment31, jsx as jsx107, jsxs as jsxs94 } from "react/jsx-runtime";
|
|
14226
14246
|
function childrenOf(folders, parentId) {
|
|
14227
14247
|
return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -14331,8 +14351,8 @@ function FolderPickerMenu({
|
|
|
14331
14351
|
] });
|
|
14332
14352
|
}
|
|
14333
14353
|
function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
|
|
14334
|
-
const [over, setOver] =
|
|
14335
|
-
const dragCounter =
|
|
14354
|
+
const [over, setOver] = React79.useState(false);
|
|
14355
|
+
const dragCounter = React79.useRef(0);
|
|
14336
14356
|
const dropHandlers = isDropTarget ? {
|
|
14337
14357
|
onDragEnter: (e) => {
|
|
14338
14358
|
if (!hasInternalPayload(e)) return;
|
|
@@ -14380,8 +14400,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
|
|
|
14380
14400
|
}
|
|
14381
14401
|
function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
|
|
14382
14402
|
const kids = childrenOf(folders, folder.id);
|
|
14383
|
-
const [expanded, setExpanded] =
|
|
14384
|
-
|
|
14403
|
+
const [expanded, setExpanded] = React79.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
|
|
14404
|
+
React79.useEffect(() => {
|
|
14385
14405
|
if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
|
|
14386
14406
|
}, [currentFolderId, folder.id, folders]);
|
|
14387
14407
|
const isCurrent = folder.id === currentFolderId;
|
|
@@ -14447,15 +14467,15 @@ function FileBrowser({
|
|
|
14447
14467
|
const canUpload = perm.canUpload !== false && !!onUpload;
|
|
14448
14468
|
const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
|
|
14449
14469
|
const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
|
|
14450
|
-
const [createOpen, setCreateOpen] =
|
|
14451
|
-
const [createName, setCreateName] =
|
|
14452
|
-
const [renameTarget, setRenameTarget] =
|
|
14453
|
-
const [renameValue, setRenameValue] =
|
|
14454
|
-
const [deleteTarget, setDeleteTarget] =
|
|
14455
|
-
const uploadInputRef =
|
|
14456
|
-
const crumbFolders =
|
|
14457
|
-
const subfolders =
|
|
14458
|
-
const currentFiles =
|
|
14470
|
+
const [createOpen, setCreateOpen] = React79.useState(false);
|
|
14471
|
+
const [createName, setCreateName] = React79.useState("");
|
|
14472
|
+
const [renameTarget, setRenameTarget] = React79.useState(null);
|
|
14473
|
+
const [renameValue, setRenameValue] = React79.useState("");
|
|
14474
|
+
const [deleteTarget, setDeleteTarget] = React79.useState(null);
|
|
14475
|
+
const uploadInputRef = React79.useRef(null);
|
|
14476
|
+
const crumbFolders = React79.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
14477
|
+
const subfolders = React79.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
14478
|
+
const currentFiles = React79.useMemo(
|
|
14459
14479
|
() => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
|
|
14460
14480
|
[files, currentFolderId]
|
|
14461
14481
|
);
|
|
@@ -14687,8 +14707,8 @@ function BreadcrumbCrumb({
|
|
|
14687
14707
|
isDropTarget,
|
|
14688
14708
|
onDropPayload
|
|
14689
14709
|
}) {
|
|
14690
|
-
const [over, setOver] =
|
|
14691
|
-
const dragCounter =
|
|
14710
|
+
const [over, setOver] = React79.useState(false);
|
|
14711
|
+
const dragCounter = React79.useRef(0);
|
|
14692
14712
|
const dropHandlers = isDropTarget ? {
|
|
14693
14713
|
onDragEnter: (e) => {
|
|
14694
14714
|
if (!hasInternalPayload(e)) return;
|
|
@@ -14717,7 +14737,7 @@ function BreadcrumbCrumb({
|
|
|
14717
14737
|
}
|
|
14718
14738
|
|
|
14719
14739
|
// src/kits/query.ts
|
|
14720
|
-
import * as
|
|
14740
|
+
import * as React80 from "react";
|
|
14721
14741
|
|
|
14722
14742
|
// src/kits/queryUrl.ts
|
|
14723
14743
|
var historyUrlAdapter = {
|
|
@@ -14855,38 +14875,38 @@ function requestFor(params, query, paging, after) {
|
|
|
14855
14875
|
}
|
|
14856
14876
|
var toError = (e) => e instanceof Error ? e : new Error(String(e));
|
|
14857
14877
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey, paging = "page", url }) {
|
|
14858
|
-
const [base] =
|
|
14878
|
+
const [base] = React80.useState(() => {
|
|
14859
14879
|
const store = PREFS || window.PlannerPrefs;
|
|
14860
14880
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
14861
14881
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
14862
14882
|
});
|
|
14863
|
-
const [mountParams] =
|
|
14864
|
-
const address =
|
|
14865
|
-
const [query, setQuery] =
|
|
14866
|
-
const savePref =
|
|
14883
|
+
const [mountParams] = React80.useState(() => url ? (url.adapter ?? historyUrlAdapter).read() : null);
|
|
14884
|
+
const address = React80.useRef(mountParams);
|
|
14885
|
+
const [query, setQuery] = React80.useState(() => url && mountParams ? readQueryFromUrl(mountParams, url.scope, base, paging) : base);
|
|
14886
|
+
const savePref = React80.useCallback((patch2) => {
|
|
14867
14887
|
const store = PREFS || window.PlannerPrefs;
|
|
14868
14888
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
14869
14889
|
}, [prefsKey]);
|
|
14870
|
-
const [res, setRes] =
|
|
14871
|
-
const [loading, setLoading] =
|
|
14872
|
-
const [loadingMore, setLoadingMore] =
|
|
14873
|
-
const [failure, setFailure] =
|
|
14874
|
-
const [reloadToken, setReloadToken] =
|
|
14875
|
-
const moreController =
|
|
14890
|
+
const [res, setRes] = React80.useState(null);
|
|
14891
|
+
const [loading, setLoading] = React80.useState(true);
|
|
14892
|
+
const [loadingMore, setLoadingMore] = React80.useState(false);
|
|
14893
|
+
const [failure, setFailure] = React80.useState(null);
|
|
14894
|
+
const [reloadToken, setReloadToken] = React80.useState(0);
|
|
14895
|
+
const moreController = React80.useRef(null);
|
|
14876
14896
|
const depKey = (deps || []).join("|");
|
|
14877
14897
|
const paramKey = JSON.stringify(params || {});
|
|
14878
14898
|
const queryKey = JSON.stringify(query);
|
|
14879
|
-
const lifetime =
|
|
14880
|
-
|
|
14899
|
+
const lifetime = React80.useRef(null);
|
|
14900
|
+
React80.useEffect(() => {
|
|
14881
14901
|
const controller = new AbortController();
|
|
14882
14902
|
lifetime.current = controller;
|
|
14883
14903
|
return () => controller.abort();
|
|
14884
14904
|
}, []);
|
|
14885
|
-
const latest =
|
|
14886
|
-
|
|
14905
|
+
const latest = React80.useRef({ res, loading, query, params, endpoint, url, base });
|
|
14906
|
+
React80.useLayoutEffect(() => {
|
|
14887
14907
|
latest.current = { res, loading, query, params, endpoint, url, base };
|
|
14888
14908
|
});
|
|
14889
|
-
|
|
14909
|
+
React80.useEffect(() => {
|
|
14890
14910
|
const controller = new AbortController();
|
|
14891
14911
|
const { signal } = controller;
|
|
14892
14912
|
setLoading(true);
|
|
@@ -14922,7 +14942,7 @@ function useServerTable({ endpoint, params, defaults, deps, prefsKey, paging = "
|
|
|
14922
14942
|
};
|
|
14923
14943
|
}, [endpoint, queryKey, paramKey, depKey, paging, reloadToken]);
|
|
14924
14944
|
const adapter = url ? url.adapter ?? historyUrlAdapter : null;
|
|
14925
|
-
|
|
14945
|
+
React80.useEffect(() => {
|
|
14926
14946
|
if (!adapter) return;
|
|
14927
14947
|
return adapter.subscribe((params2) => {
|
|
14928
14948
|
const { url: u, base: b } = latest.current;
|
|
@@ -15272,12 +15292,12 @@ function createVersionStore(initialState, options) {
|
|
|
15272
15292
|
}
|
|
15273
15293
|
|
|
15274
15294
|
// src/kits/documentTitle.ts
|
|
15275
|
-
import * as
|
|
15295
|
+
import * as React81 from "react";
|
|
15276
15296
|
function formatDocumentTitle(routeTitle, appName) {
|
|
15277
15297
|
return [routeTitle, appName, "Flytedesk"].filter((part2) => !!part2 && part2.length > 0).join(" \xB7 ");
|
|
15278
15298
|
}
|
|
15279
15299
|
function useDocumentTitle(routeTitle, appName) {
|
|
15280
|
-
|
|
15300
|
+
React81.useEffect(() => {
|
|
15281
15301
|
if (typeof document === "undefined") return;
|
|
15282
15302
|
document.title = formatDocumentTitle(routeTitle, appName);
|
|
15283
15303
|
}, [routeTitle, appName]);
|