@flytedan/flytebot-design-system 0.73.0 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +528 -507
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +528 -507
- 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 = () => {
|
|
@@ -3096,6 +3116,7 @@ function RowActionCell({ action }) {
|
|
|
3096
3116
|
return /* @__PURE__ */ jsx45("td", { className: "fd-table-action", children: action ? /* @__PURE__ */ jsx45(RowActionButton, { action, size: "sm" }) : null });
|
|
3097
3117
|
}
|
|
3098
3118
|
var cellOf = (c, row) => c.render ? c.render(row) : row[c.key];
|
|
3119
|
+
var cardCellOf = (c, row) => c.phoneRender ? c.phoneRender(row) : cellOf(c, row);
|
|
3099
3120
|
function rowInteraction(row, onRowClick) {
|
|
3100
3121
|
if (!onRowClick) return {};
|
|
3101
3122
|
return {
|
|
@@ -3238,11 +3259,11 @@ function StackedRows({ columns, rows, rowKey, loading, stale, skeletonRows, sort
|
|
|
3238
3259
|
...semantics,
|
|
3239
3260
|
...rowInteraction(r, onRowClick),
|
|
3240
3261
|
children: [
|
|
3241
|
-
/* @__PURE__ */ jsx45("div", { className: "fd-dt-card-title", children: primary.map((c) => /* @__PURE__ */ jsx45("span", { className: c.numeric ? "is-num" : void 0, children:
|
|
3262
|
+
/* @__PURE__ */ jsx45("div", { className: "fd-dt-card-title", children: primary.map((c) => /* @__PURE__ */ jsx45("span", { className: c.numeric ? "is-num" : void 0, children: cardCellOf(c, r) }, c.key)) }),
|
|
3242
3263
|
secondary.length ? /* @__PURE__ */ jsx45("div", { className: "fd-dt-card-meta", children: secondary.map((c) => /* @__PURE__ */ jsxs36("span", { className: c.numeric ? "is-num" : void 0, children: [
|
|
3243
3264
|
/* @__PURE__ */ jsx45("span", { className: "fd-dt-card-label", children: c.label }),
|
|
3244
3265
|
" ",
|
|
3245
|
-
|
|
3266
|
+
cardCellOf(c, r)
|
|
3246
3267
|
] }, c.key)) }) : null
|
|
3247
3268
|
]
|
|
3248
3269
|
}
|
|
@@ -3254,16 +3275,16 @@ function StackedRows({ columns, rows, rowKey, loading, stale, skeletonRows, sort
|
|
|
3254
3275
|
}
|
|
3255
3276
|
|
|
3256
3277
|
// src/components/data/FilterBar.tsx
|
|
3257
|
-
import * as
|
|
3278
|
+
import * as React33 from "react";
|
|
3258
3279
|
|
|
3259
3280
|
// src/components/forms/NumberInput.tsx
|
|
3260
|
-
import * as
|
|
3281
|
+
import * as React30 from "react";
|
|
3261
3282
|
|
|
3262
3283
|
// src/components/forms/field.tsx
|
|
3263
|
-
import * as
|
|
3284
|
+
import * as React28 from "react";
|
|
3264
3285
|
import { jsx as jsx46, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3265
3286
|
function useFieldId(id) {
|
|
3266
|
-
const generated =
|
|
3287
|
+
const generated = React28.useId();
|
|
3267
3288
|
return id || generated;
|
|
3268
3289
|
}
|
|
3269
3290
|
function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
|
|
@@ -3282,10 +3303,10 @@ function HiddenFieldLabel({ id, children }) {
|
|
|
3282
3303
|
}
|
|
3283
3304
|
|
|
3284
3305
|
// src/components/useLatest.ts
|
|
3285
|
-
import * as
|
|
3306
|
+
import * as React29 from "react";
|
|
3286
3307
|
function useLatest(value) {
|
|
3287
|
-
const ref =
|
|
3288
|
-
|
|
3308
|
+
const ref = React29.useRef(value);
|
|
3309
|
+
React29.useInsertionEffect(() => {
|
|
3289
3310
|
ref.current = value;
|
|
3290
3311
|
});
|
|
3291
3312
|
return ref;
|
|
@@ -3368,20 +3389,20 @@ function NumberInput({
|
|
|
3368
3389
|
const n = typeof v === "number" ? v : parseNumberText(v);
|
|
3369
3390
|
return n == null || Number.isNaN(n) ? null : n;
|
|
3370
3391
|
};
|
|
3371
|
-
const [text, setText] =
|
|
3372
|
-
const [editing, setEditing] =
|
|
3392
|
+
const [text, setText] = React30.useState(() => toText(value));
|
|
3393
|
+
const [editing, setEditing] = React30.useState(false);
|
|
3373
3394
|
const parsed = parseNumberText(text);
|
|
3374
3395
|
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
3396
|
const valid = invalidMessage == null;
|
|
3376
|
-
const committedRef =
|
|
3397
|
+
const committedRef = React30.useRef(toNumber(value));
|
|
3377
3398
|
const onChangeRef = useLatest(onChange);
|
|
3378
3399
|
const onValidityChangeRef = useLatest(onValidityChange);
|
|
3379
|
-
const focusedRef =
|
|
3380
|
-
|
|
3400
|
+
const focusedRef = React30.useRef(false);
|
|
3401
|
+
React30.useEffect(() => {
|
|
3381
3402
|
committedRef.current = toNumber(value);
|
|
3382
3403
|
if (!focusedRef.current) setText(toText(value));
|
|
3383
3404
|
}, [value]);
|
|
3384
|
-
|
|
3405
|
+
React30.useLayoutEffect(() => {
|
|
3385
3406
|
onValidityChangeRef.current?.(valid);
|
|
3386
3407
|
}, [valid, onValidityChangeRef]);
|
|
3387
3408
|
const fire = (n) => {
|
|
@@ -3397,7 +3418,7 @@ function NumberInput({
|
|
|
3397
3418
|
return true;
|
|
3398
3419
|
};
|
|
3399
3420
|
const bumpRef = useLatest(bump);
|
|
3400
|
-
const holdTimer =
|
|
3421
|
+
const holdTimer = React30.useRef(null);
|
|
3401
3422
|
const release2 = () => {
|
|
3402
3423
|
if (holdTimer.current) clearTimeout(holdTimer.current);
|
|
3403
3424
|
holdTimer.current = null;
|
|
@@ -3416,7 +3437,7 @@ function NumberInput({
|
|
|
3416
3437
|
};
|
|
3417
3438
|
holdTimer.current = setTimeout(tick, HOLD_DELAY_MS);
|
|
3418
3439
|
};
|
|
3419
|
-
|
|
3440
|
+
React30.useEffect(() => () => {
|
|
3420
3441
|
if (holdTimer.current) clearTimeout(holdTimer.current);
|
|
3421
3442
|
}, []);
|
|
3422
3443
|
const current2 = committedRef.current;
|
|
@@ -3519,7 +3540,7 @@ function NumberInput({
|
|
|
3519
3540
|
}
|
|
3520
3541
|
|
|
3521
3542
|
// src/components/forms/DatePicker.tsx
|
|
3522
|
-
import * as
|
|
3543
|
+
import * as React31 from "react";
|
|
3523
3544
|
import { jsx as jsx48, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3524
3545
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
3525
3546
|
var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
@@ -3552,10 +3573,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3552
3573
|
const today = /* @__PURE__ */ new Date();
|
|
3553
3574
|
const sel = range ? value || {} : { start: value, end: value };
|
|
3554
3575
|
const anchor = parse(sel.start) || parse(initialMonth) || today;
|
|
3555
|
-
const [vy, setVy] =
|
|
3556
|
-
const [vm, setVm] =
|
|
3557
|
-
const [mode2, setMode] =
|
|
3558
|
-
const [hover, setHover] =
|
|
3576
|
+
const [vy, setVy] = React31.useState(anchor.getFullYear());
|
|
3577
|
+
const [vm, setVm] = React31.useState(anchor.getMonth());
|
|
3578
|
+
const [mode2, setMode] = React31.useState("days");
|
|
3579
|
+
const [hover, setHover] = React31.useState(null);
|
|
3559
3580
|
const s = parse(sel.start), e = parse(sel.end);
|
|
3560
3581
|
const hoverEnd = range && s && !e && hover ? parse(hover) : null;
|
|
3561
3582
|
const inRange = (d) => {
|
|
@@ -3566,12 +3587,12 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3566
3587
|
const isEnd = (d) => !!e && iso(d) === iso(e);
|
|
3567
3588
|
const isEdge = (d) => isStart(d) || isEnd(d);
|
|
3568
3589
|
const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
|
|
3569
|
-
const [activeDate, setActiveDate] =
|
|
3590
|
+
const [activeDate, setActiveDate] = React31.useState(() => {
|
|
3570
3591
|
if (s) return s;
|
|
3571
3592
|
if (sameMonth(today, anchor.getFullYear(), anchor.getMonth())) return today;
|
|
3572
3593
|
return new Date(anchor.getFullYear(), anchor.getMonth(), 1);
|
|
3573
3594
|
});
|
|
3574
|
-
const calRef =
|
|
3595
|
+
const calRef = React31.useRef(null);
|
|
3575
3596
|
const pageToShow = (y, m) => {
|
|
3576
3597
|
const idx = y * 12 + m, firstIdx = vy * 12 + vm, secondIdx = firstIdx + 1;
|
|
3577
3598
|
if (idx === firstIdx || months > 1 && idx === secondIdx) return;
|
|
@@ -3588,7 +3609,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3588
3609
|
setActiveDate(next);
|
|
3589
3610
|
pageToShow(next.getFullYear(), next.getMonth());
|
|
3590
3611
|
};
|
|
3591
|
-
|
|
3612
|
+
React31.useEffect(() => {
|
|
3592
3613
|
const el = calRef.current?.querySelector('[data-iso="' + iso(activeDate) + '"]');
|
|
3593
3614
|
if (el) el.focus({ preventScroll: true });
|
|
3594
3615
|
}, [activeDate, vy, vm]);
|
|
@@ -3781,9 +3802,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3781
3802
|
}
|
|
3782
3803
|
function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, "aria-label": hiddenLabel, ...rest }) {
|
|
3783
3804
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
|
|
3784
|
-
const [open2, setOpen] =
|
|
3785
|
-
const rootRef =
|
|
3786
|
-
const boxRef =
|
|
3805
|
+
const [open2, setOpen] = React31.useState(false);
|
|
3806
|
+
const rootRef = React31.useRef(null);
|
|
3807
|
+
const boxRef = React31.useRef(null);
|
|
3787
3808
|
const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
|
|
3788
3809
|
const toggle = () => {
|
|
3789
3810
|
if (!disabled) setOpen(!open2);
|
|
@@ -3872,9 +3893,9 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
|
|
|
3872
3893
|
}
|
|
3873
3894
|
|
|
3874
3895
|
// src/components/forms/listbox.ts
|
|
3875
|
-
import * as
|
|
3896
|
+
import * as React32 from "react";
|
|
3876
3897
|
function useListboxNav({ count, onSelect }) {
|
|
3877
|
-
const [active, setActive] =
|
|
3898
|
+
const [active, setActive] = React32.useState(-1);
|
|
3878
3899
|
return {
|
|
3879
3900
|
active,
|
|
3880
3901
|
setActive,
|
|
@@ -3887,7 +3908,7 @@ function useListboxNav({ count, onSelect }) {
|
|
|
3887
3908
|
};
|
|
3888
3909
|
}
|
|
3889
3910
|
function useListboxScrollIntoView(active, listRef, enabled) {
|
|
3890
|
-
|
|
3911
|
+
React32.useEffect(() => {
|
|
3891
3912
|
if (!enabled || active < 0 || !listRef.current) return;
|
|
3892
3913
|
const list = listRef.current;
|
|
3893
3914
|
const el = list.querySelector('[data-i="' + active + '"]');
|
|
@@ -4108,13 +4129,13 @@ function MultiSelectPanel({
|
|
|
4108
4129
|
onClose
|
|
4109
4130
|
}) {
|
|
4110
4131
|
const allowedOps = operatorsFor(field);
|
|
4111
|
-
const [draftOperator, setDraftOperator] =
|
|
4132
|
+
const [draftOperator, setDraftOperator] = React33.useState(value?.operator ?? allowedOps[0]);
|
|
4112
4133
|
const operator = allowedOps.length === 1 ? allowedOps[0] : value?.operator ?? draftOperator;
|
|
4113
4134
|
const selected = value?.values ?? [];
|
|
4114
4135
|
const selectedRef = useLatest(selected);
|
|
4115
4136
|
const operatorRef = useLatest(operator);
|
|
4116
|
-
const mountedRef =
|
|
4117
|
-
|
|
4137
|
+
const mountedRef = React33.useRef(true);
|
|
4138
|
+
React33.useEffect(() => {
|
|
4118
4139
|
mountedRef.current = true;
|
|
4119
4140
|
return () => {
|
|
4120
4141
|
mountedRef.current = false;
|
|
@@ -4128,20 +4149,20 @@ function MultiSelectPanel({
|
|
|
4128
4149
|
if (selectedRef.current.length > 0) commit(selectedRef.current, op);
|
|
4129
4150
|
else setDraftOperator(op);
|
|
4130
4151
|
};
|
|
4131
|
-
const [mode2, setMode] =
|
|
4132
|
-
const [query, setQuery] =
|
|
4133
|
-
const [asyncState, setAsyncState] =
|
|
4152
|
+
const [mode2, setMode] = React33.useState("search");
|
|
4153
|
+
const [query, setQuery] = React33.useState("");
|
|
4154
|
+
const [asyncState, setAsyncState] = React33.useState(
|
|
4134
4155
|
{ options: null, loading: !!field.loadOptions, error: false }
|
|
4135
4156
|
);
|
|
4136
|
-
const [retryTick, setRetryTick] =
|
|
4137
|
-
const inputRef =
|
|
4138
|
-
const listRef =
|
|
4139
|
-
const listId =
|
|
4157
|
+
const [retryTick, setRetryTick] = React33.useState(0);
|
|
4158
|
+
const inputRef = React33.useRef(null);
|
|
4159
|
+
const listRef = React33.useRef(null);
|
|
4160
|
+
const listId = React33.useId();
|
|
4140
4161
|
const loadOptionsRef = useLatest(field.loadOptions);
|
|
4141
|
-
|
|
4162
|
+
React33.useEffect(() => {
|
|
4142
4163
|
inputRef.current?.focus();
|
|
4143
4164
|
}, []);
|
|
4144
|
-
|
|
4165
|
+
React33.useEffect(() => {
|
|
4145
4166
|
const load = loadOptionsRef.current;
|
|
4146
4167
|
if (!load) return;
|
|
4147
4168
|
const controller = new AbortController();
|
|
@@ -4174,17 +4195,17 @@ function MultiSelectPanel({
|
|
|
4174
4195
|
};
|
|
4175
4196
|
const nav = useListboxNav({ count: options.length, onSelect: (i) => toggle(options[i]) });
|
|
4176
4197
|
useListboxScrollIntoView(nav.active, listRef, hasListbox);
|
|
4177
|
-
|
|
4198
|
+
React33.useEffect(() => {
|
|
4178
4199
|
nav.setActive(0);
|
|
4179
4200
|
}, [query, options.length]);
|
|
4180
4201
|
const activeId = hasListbox && options[nav.active] ? listId + "-opt-" + nav.active : void 0;
|
|
4181
4202
|
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
|
-
|
|
4203
|
+
const [pasteText, setPasteText] = React33.useState("");
|
|
4204
|
+
const [pasteLoading, setPasteLoading] = React33.useState(false);
|
|
4205
|
+
const [unmatchedTokens, setUnmatchedTokens] = React33.useState([]);
|
|
4206
|
+
const [pasteError, setPasteError] = React33.useState(null);
|
|
4207
|
+
const pasteWrapRef = React33.useRef(null);
|
|
4208
|
+
React33.useEffect(() => {
|
|
4188
4209
|
if (mode2 === "paste") pasteWrapRef.current?.querySelector("textarea")?.focus();
|
|
4189
4210
|
}, [mode2]);
|
|
4190
4211
|
const doResolve = () => {
|
|
@@ -4357,8 +4378,8 @@ function MultiSelectPanel({
|
|
|
4357
4378
|
);
|
|
4358
4379
|
}
|
|
4359
4380
|
function useTextValidity(onFlip) {
|
|
4360
|
-
const invalidRef =
|
|
4361
|
-
const [, rerender] =
|
|
4381
|
+
const invalidRef = React33.useRef(/* @__PURE__ */ new Set());
|
|
4382
|
+
const [, rerender] = React33.useReducer((n) => n + 1, 0);
|
|
4362
4383
|
const onFlipRef = useLatest(onFlip);
|
|
4363
4384
|
const record = (name, valid) => {
|
|
4364
4385
|
const invalid = invalidRef.current;
|
|
@@ -4401,15 +4422,15 @@ function sameValue(a, b) {
|
|
|
4401
4422
|
return true;
|
|
4402
4423
|
}
|
|
4403
4424
|
function useReseedFromProps(value, applies, reseed) {
|
|
4404
|
-
const seen =
|
|
4405
|
-
|
|
4425
|
+
const seen = React33.useRef(value);
|
|
4426
|
+
React33.useLayoutEffect(() => {
|
|
4406
4427
|
if (seen.current === value) return;
|
|
4407
4428
|
seen.current = value;
|
|
4408
4429
|
if (!sameValue(value, applies())) reseed(value);
|
|
4409
4430
|
}, [value, applies, reseed]);
|
|
4410
4431
|
}
|
|
4411
4432
|
function usePreserveFocusAcrossRemount(seed, fields) {
|
|
4412
|
-
const pendingName =
|
|
4433
|
+
const pendingName = React33.useRef(null);
|
|
4413
4434
|
const fieldsRef = useLatest(fields);
|
|
4414
4435
|
const capture = () => {
|
|
4415
4436
|
const active = document.activeElement;
|
|
@@ -4422,7 +4443,7 @@ function usePreserveFocusAcrossRemount(seed, fields) {
|
|
|
4422
4443
|
}
|
|
4423
4444
|
}
|
|
4424
4445
|
};
|
|
4425
|
-
|
|
4446
|
+
React33.useLayoutEffect(() => {
|
|
4426
4447
|
const name = pendingName.current;
|
|
4427
4448
|
if (!name) return;
|
|
4428
4449
|
pendingName.current = null;
|
|
@@ -4438,14 +4459,14 @@ function RangePanel({
|
|
|
4438
4459
|
onCommit,
|
|
4439
4460
|
onClose
|
|
4440
4461
|
}) {
|
|
4441
|
-
const [draft, setDraft] =
|
|
4442
|
-
const [seed, setSeed] =
|
|
4443
|
-
const minId =
|
|
4444
|
-
const maxId =
|
|
4445
|
-
const minWrapRef =
|
|
4446
|
-
const maxWrapRef =
|
|
4462
|
+
const [draft, setDraft] = React33.useState(() => rangeDraft(value));
|
|
4463
|
+
const [seed, setSeed] = React33.useState(0);
|
|
4464
|
+
const minId = React33.useId();
|
|
4465
|
+
const maxId = React33.useId();
|
|
4466
|
+
const minWrapRef = React33.useRef(null);
|
|
4467
|
+
const maxWrapRef = React33.useRef(null);
|
|
4447
4468
|
const preserveFocus = usePreserveFocusAcrossRemount(seed, { min: minWrapRef, max: maxWrapRef });
|
|
4448
|
-
const draftRef =
|
|
4469
|
+
const draftRef = React33.useRef(draft);
|
|
4449
4470
|
const shown = () => {
|
|
4450
4471
|
const { min, max } = draftRef.current;
|
|
4451
4472
|
return applicable(field, min == null && max == null ? void 0 : { min, max }, validity.allValid());
|
|
@@ -4537,15 +4558,15 @@ function DatePanel({
|
|
|
4537
4558
|
onClose
|
|
4538
4559
|
}) {
|
|
4539
4560
|
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 =
|
|
4561
|
+
const [initial] = React33.useState(() => dateDraft(field, value));
|
|
4562
|
+
const [kind, setKind] = React33.useState(initial.kind);
|
|
4563
|
+
const [daysDraft, setDaysDraft] = React33.useState(initial.days);
|
|
4564
|
+
const daysRef = React33.useRef(daysDraft);
|
|
4565
|
+
const daysConfirmed = React33.useRef(value?.kind === "withinDays");
|
|
4566
|
+
const [between, setBetween] = React33.useState(initial.between);
|
|
4567
|
+
const [seed, setSeed] = React33.useState(0);
|
|
4568
|
+
const daysId = React33.useId();
|
|
4569
|
+
const daysWrapRef = React33.useRef(null);
|
|
4549
4570
|
const preserveFocus = usePreserveFocusAcrossRemount(seed, { days: daysWrapRef });
|
|
4550
4571
|
const shownWithinDays = () => {
|
|
4551
4572
|
const days = daysRef.current;
|
|
@@ -4663,11 +4684,11 @@ function FilterButton({ children, ...rest }) {
|
|
|
4663
4684
|
] });
|
|
4664
4685
|
}
|
|
4665
4686
|
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 =
|
|
4687
|
+
const [panel, setPanel] = React33.useState(null);
|
|
4688
|
+
const editAnchorRef = React33.useRef(null);
|
|
4689
|
+
const addAnchorRef = React33.useRef(null);
|
|
4690
|
+
const textInputRef = React33.useRef(null);
|
|
4691
|
+
const optionsRef = React33.useRef(null);
|
|
4671
4692
|
if (process.env.NODE_ENV !== "production") {
|
|
4672
4693
|
for (const f of fields) assertValidFieldDefinition(f);
|
|
4673
4694
|
}
|
|
@@ -4690,7 +4711,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
4690
4711
|
const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
|
|
4691
4712
|
const startEditing = (key) => setPanel({ kind: "edit", key });
|
|
4692
4713
|
const closeEditing = () => setPanel(null);
|
|
4693
|
-
|
|
4714
|
+
React33.useEffect(() => {
|
|
4694
4715
|
if (!panel || panel.kind !== "edit") return;
|
|
4695
4716
|
if (editingField?.type === "text") {
|
|
4696
4717
|
textInputRef.current?.focus();
|
|
@@ -4945,10 +4966,10 @@ function StatTile(props) {
|
|
|
4945
4966
|
}
|
|
4946
4967
|
|
|
4947
4968
|
// src/components/data/CodeBlock.tsx
|
|
4948
|
-
import * as
|
|
4969
|
+
import * as React35 from "react";
|
|
4949
4970
|
|
|
4950
4971
|
// src/kits/clipboard.ts
|
|
4951
|
-
import * as
|
|
4972
|
+
import * as React34 from "react";
|
|
4952
4973
|
var COPIED_FEEDBACK_MS = 1600;
|
|
4953
4974
|
function copyThroughSelection(text) {
|
|
4954
4975
|
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -4978,17 +4999,17 @@ async function copyToClipboard(text) {
|
|
|
4978
4999
|
return copyThroughSelection(text);
|
|
4979
5000
|
}
|
|
4980
5001
|
function useCopyToClipboard() {
|
|
4981
|
-
const [copied, setCopied] =
|
|
4982
|
-
const timer =
|
|
4983
|
-
const mounted =
|
|
4984
|
-
|
|
5002
|
+
const [copied, setCopied] = React34.useState(false);
|
|
5003
|
+
const timer = React34.useRef(null);
|
|
5004
|
+
const mounted = React34.useRef(true);
|
|
5005
|
+
React34.useEffect(() => {
|
|
4985
5006
|
mounted.current = true;
|
|
4986
5007
|
return () => {
|
|
4987
5008
|
mounted.current = false;
|
|
4988
5009
|
if (timer.current) clearTimeout(timer.current);
|
|
4989
5010
|
};
|
|
4990
5011
|
}, []);
|
|
4991
|
-
const copy =
|
|
5012
|
+
const copy = React34.useCallback(async (text) => {
|
|
4992
5013
|
const ok = await copyToClipboard(text);
|
|
4993
5014
|
if (ok && mounted.current) {
|
|
4994
5015
|
setCopied(true);
|
|
@@ -5156,7 +5177,7 @@ function tokenize(src, lang) {
|
|
|
5156
5177
|
return out;
|
|
5157
5178
|
}
|
|
5158
5179
|
function Highlighted({ code, lang }) {
|
|
5159
|
-
const toks =
|
|
5180
|
+
const toks = React35.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
5160
5181
|
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
5182
|
}
|
|
5162
5183
|
function CodeBlock({
|
|
@@ -5170,8 +5191,8 @@ function CodeBlock({
|
|
|
5170
5191
|
actions,
|
|
5171
5192
|
className = ""
|
|
5172
5193
|
}) {
|
|
5173
|
-
const [wrap, setWrap] =
|
|
5174
|
-
const [open2, setOpen] =
|
|
5194
|
+
const [wrap, setWrap] = React35.useState(!!wrapDefault);
|
|
5195
|
+
const [open2, setOpen] = React35.useState(false);
|
|
5175
5196
|
const [copied, copy] = useCopyToClipboard();
|
|
5176
5197
|
const body = String(code).replace(/\n$/, "");
|
|
5177
5198
|
const lines = body.split("\n");
|
|
@@ -5200,7 +5221,7 @@ function CodeBlock({
|
|
|
5200
5221
|
] });
|
|
5201
5222
|
}
|
|
5202
5223
|
function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
|
|
5203
|
-
const [open2, setOpen] =
|
|
5224
|
+
const [open2, setOpen] = React35.useState(false);
|
|
5204
5225
|
const [copied, copy] = useCopyToClipboard();
|
|
5205
5226
|
const raw = String(diff).replace(/\n$/, "");
|
|
5206
5227
|
const all = raw.split("\n").map((line) => {
|
|
@@ -5246,7 +5267,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
5246
5267
|
}
|
|
5247
5268
|
|
|
5248
5269
|
// src/components/data/Markdown.tsx
|
|
5249
|
-
import * as
|
|
5270
|
+
import * as React36 from "react";
|
|
5250
5271
|
import { jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
5251
5272
|
var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
|
|
5252
5273
|
var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
|
|
@@ -5289,7 +5310,7 @@ function hiddenInlineNodes(hidden, ctx, keyBase) {
|
|
|
5289
5310
|
const href = safeHref(d(g(2)));
|
|
5290
5311
|
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
5312
|
} else if (kind === "cite") {
|
|
5292
|
-
out.push(ctx.renderCitation ? /* @__PURE__ */ jsx55(
|
|
5313
|
+
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
5314
|
} else if (kind === "strongem") out.push(/* @__PURE__ */ jsx55("strong", { children: /* @__PURE__ */ jsx55("em", { children: hiddenInlineNodes(g(1), ctx, key()) }) }, key()));
|
|
5294
5315
|
else if (kind === "strong") out.push(/* @__PURE__ */ jsx55("strong", { children: hiddenInlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
5295
5316
|
else if (kind === "em") out.push(/* @__PURE__ */ jsx55("em", { children: hiddenInlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
@@ -5476,7 +5497,7 @@ function Markdown({
|
|
|
5476
5497
|
tone = "default"
|
|
5477
5498
|
}) {
|
|
5478
5499
|
const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
|
|
5479
|
-
const blocks =
|
|
5500
|
+
const blocks = React36.useMemo(() => parseBlocks(source), [source]);
|
|
5480
5501
|
return /* @__PURE__ */ jsx55("div", { className: mdClass("fd-md", size, tone, className), children: renderBlocks(blocks, ctx, "b") });
|
|
5481
5502
|
}
|
|
5482
5503
|
function MarkdownInline({ source = "", className = "", onLinkClick, size, tone }) {
|
|
@@ -5587,7 +5608,7 @@ function Pagination({
|
|
|
5587
5608
|
}
|
|
5588
5609
|
|
|
5589
5610
|
// src/components/data/RelativeTime.tsx
|
|
5590
|
-
import * as
|
|
5611
|
+
import * as React37 from "react";
|
|
5591
5612
|
import { jsxs as jsxs48 } from "react/jsx-runtime";
|
|
5592
5613
|
var MIN = 6e4;
|
|
5593
5614
|
var HOUR = 36e5;
|
|
@@ -5639,9 +5660,9 @@ function formatDuration(ms) {
|
|
|
5639
5660
|
return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
|
|
5640
5661
|
}
|
|
5641
5662
|
function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
|
|
5642
|
-
const [, force] =
|
|
5663
|
+
const [, force] = React37.useState(0);
|
|
5643
5664
|
const t = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
5644
|
-
|
|
5665
|
+
React37.useEffect(() => {
|
|
5645
5666
|
if (!refresh2 || !t || isNaN(t)) return;
|
|
5646
5667
|
const abs = Math.abs(t - Date.now());
|
|
5647
5668
|
if (abs > DAY) return;
|
|
@@ -5657,7 +5678,7 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
|
|
|
5657
5678
|
}
|
|
5658
5679
|
|
|
5659
5680
|
// src/components/data/ScoreMeter.tsx
|
|
5660
|
-
import * as
|
|
5681
|
+
import * as React38 from "react";
|
|
5661
5682
|
import { jsx as jsx58, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
5662
5683
|
function ScoreMeter({
|
|
5663
5684
|
score,
|
|
@@ -5672,10 +5693,10 @@ function ScoreMeter({
|
|
|
5672
5693
|
breakdownWidth = 280,
|
|
5673
5694
|
className = ""
|
|
5674
5695
|
}) {
|
|
5675
|
-
const [open2, setOpen] =
|
|
5676
|
-
const ref =
|
|
5696
|
+
const [open2, setOpen] = React38.useState(false);
|
|
5697
|
+
const ref = React38.useRef(null);
|
|
5677
5698
|
const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
5678
|
-
const body = /* @__PURE__ */ jsxs49(
|
|
5699
|
+
const body = /* @__PURE__ */ jsxs49(React38.Fragment, { children: [
|
|
5679
5700
|
/* @__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
5701
|
showScore ? /* @__PURE__ */ jsx58("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
|
|
5681
5702
|
] });
|
|
@@ -5694,7 +5715,7 @@ function ScoreMeter({
|
|
|
5694
5715
|
}
|
|
5695
5716
|
);
|
|
5696
5717
|
}
|
|
5697
|
-
return /* @__PURE__ */ jsxs49(
|
|
5718
|
+
return /* @__PURE__ */ jsxs49(React38.Fragment, { children: [
|
|
5698
5719
|
/* @__PURE__ */ jsx58(
|
|
5699
5720
|
"button",
|
|
5700
5721
|
{
|
|
@@ -5725,11 +5746,11 @@ function ScoreMeter({
|
|
|
5725
5746
|
}
|
|
5726
5747
|
|
|
5727
5748
|
// src/components/actions/inlinePanel.tsx
|
|
5728
|
-
import * as
|
|
5749
|
+
import * as React39 from "react";
|
|
5729
5750
|
import { jsx as jsx59 } from "react/jsx-runtime";
|
|
5730
5751
|
function useInlinePanel() {
|
|
5731
|
-
const [open2, setOpen] =
|
|
5732
|
-
const ref =
|
|
5752
|
+
const [open2, setOpen] = React39.useState(false);
|
|
5753
|
+
const ref = React39.useRef(null);
|
|
5733
5754
|
return { open: open2, setOpen, ref };
|
|
5734
5755
|
}
|
|
5735
5756
|
function InlinePanelSurface({ panel, align = "right", ...popover }) {
|
|
@@ -5900,7 +5921,7 @@ function SortMenu({
|
|
|
5900
5921
|
}
|
|
5901
5922
|
|
|
5902
5923
|
// src/components/data/StepList.tsx
|
|
5903
|
-
import * as
|
|
5924
|
+
import * as React40 from "react";
|
|
5904
5925
|
import { jsx as jsx61, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
5905
5926
|
var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
|
|
5906
5927
|
function StepList({
|
|
@@ -5914,9 +5935,9 @@ function StepList({
|
|
|
5914
5935
|
className = "",
|
|
5915
5936
|
active = false
|
|
5916
5937
|
}) {
|
|
5917
|
-
const [openState, setOpenState] =
|
|
5938
|
+
const [openState, setOpenState] = React40.useState(defaultOpen);
|
|
5918
5939
|
const open2 = openProp == null ? openState : openProp;
|
|
5919
|
-
const [expanded, setExpanded] =
|
|
5940
|
+
const [expanded, setExpanded] = React40.useState({});
|
|
5920
5941
|
if (!steps.length) return null;
|
|
5921
5942
|
const running = steps.some((s) => s.status === "running");
|
|
5922
5943
|
const failed = steps.filter((s) => s.status === "error").length;
|
|
@@ -5974,7 +5995,7 @@ function StepList({
|
|
|
5974
5995
|
}
|
|
5975
5996
|
|
|
5976
5997
|
// src/components/data/VirtualList.tsx
|
|
5977
|
-
import * as
|
|
5998
|
+
import * as React41 from "react";
|
|
5978
5999
|
import { jsx as jsx62, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
5979
6000
|
var VIRTUAL_LIST_BUFFER_ROWS = 20;
|
|
5980
6001
|
var VIRTUAL_LIST_ROW_GAP = 6;
|
|
@@ -6026,35 +6047,35 @@ function VirtualList({
|
|
|
6026
6047
|
className = "",
|
|
6027
6048
|
style
|
|
6028
6049
|
}) {
|
|
6029
|
-
const [scrollTop, setScrollTop] =
|
|
6030
|
-
const loaded =
|
|
6050
|
+
const [scrollTop, setScrollTop] = React41.useState(0);
|
|
6051
|
+
const loaded = React41.useMemo(
|
|
6031
6052
|
() => ({ firstItemIndex, count: items.length }),
|
|
6032
6053
|
[firstItemIndex, items.length]
|
|
6033
6054
|
);
|
|
6034
6055
|
const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
|
|
6035
6056
|
const bandKey = firstItemIndex + ":" + items.length;
|
|
6036
|
-
const win =
|
|
6057
|
+
const win = React41.useMemo(
|
|
6037
6058
|
() => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
|
|
6038
6059
|
[scrollTop, height, itemHeight, total, loaded]
|
|
6039
6060
|
);
|
|
6040
|
-
const need =
|
|
6061
|
+
const need = React41.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
|
|
6041
6062
|
const wantStart = need.start && hasMore?.start !== false;
|
|
6042
6063
|
const wantEnd = need.end && hasMore?.end !== false;
|
|
6043
6064
|
const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
|
|
6044
6065
|
const askKey = bandKey + "@" + bucket2;
|
|
6045
|
-
const asked =
|
|
6046
|
-
|
|
6066
|
+
const asked = React41.useRef({ start: null, end: null });
|
|
6067
|
+
React41.useEffect(() => {
|
|
6047
6068
|
if (loading || !wantStart || asked.current.start === askKey) return;
|
|
6048
6069
|
asked.current.start = askKey;
|
|
6049
6070
|
onNeedMore("start", win);
|
|
6050
6071
|
}, [wantStart, loading, askKey, onNeedMore, win]);
|
|
6051
|
-
|
|
6072
|
+
React41.useEffect(() => {
|
|
6052
6073
|
if (loading || !wantEnd || asked.current.end === askKey) return;
|
|
6053
6074
|
asked.current.end = askKey;
|
|
6054
6075
|
onNeedMore("end", win);
|
|
6055
6076
|
}, [wantEnd, loading, askKey, onNeedMore, win]);
|
|
6056
|
-
const lastKeysRef =
|
|
6057
|
-
const newKeys =
|
|
6077
|
+
const lastKeysRef = React41.useRef(null);
|
|
6078
|
+
const newKeys = React41.useMemo(() => {
|
|
6058
6079
|
const prev = lastKeysRef.current;
|
|
6059
6080
|
if (!prev) return /* @__PURE__ */ new Set();
|
|
6060
6081
|
const fresh = /* @__PURE__ */ new Set();
|
|
@@ -6064,7 +6085,7 @@ function VirtualList({
|
|
|
6064
6085
|
}
|
|
6065
6086
|
return fresh;
|
|
6066
6087
|
}, [items]);
|
|
6067
|
-
|
|
6088
|
+
React41.useEffect(() => {
|
|
6068
6089
|
lastKeysRef.current = new Set(items.map(keyOf));
|
|
6069
6090
|
}, [items]);
|
|
6070
6091
|
const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
|
|
@@ -6109,7 +6130,7 @@ function VirtualList({
|
|
|
6109
6130
|
}
|
|
6110
6131
|
|
|
6111
6132
|
// src/components/data/EntityRow.tsx
|
|
6112
|
-
import * as
|
|
6133
|
+
import * as React42 from "react";
|
|
6113
6134
|
import { jsx as jsx63, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
6114
6135
|
var ENTITY_ROW_METRIC_WIDTH = 74;
|
|
6115
6136
|
var METRIC_TONE_COLOR = {
|
|
@@ -6122,7 +6143,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
|
|
|
6122
6143
|
const key = m.id || m.label || i;
|
|
6123
6144
|
const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
|
|
6124
6145
|
const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
|
|
6125
|
-
const content = /* @__PURE__ */ jsxs53(
|
|
6146
|
+
const content = /* @__PURE__ */ jsxs53(React42.Fragment, { children: [
|
|
6126
6147
|
m.icon ? /* @__PURE__ */ jsx63("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
|
|
6127
6148
|
/* @__PURE__ */ jsx63("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
|
|
6128
6149
|
/* @__PURE__ */ jsx63("span", { className: "fd-sr", children: " " + m.label })
|
|
@@ -6214,7 +6235,7 @@ function EntityRow({
|
|
|
6214
6235
|
}
|
|
6215
6236
|
|
|
6216
6237
|
// src/components/data/TransferList.tsx
|
|
6217
|
-
import * as
|
|
6238
|
+
import * as React43 from "react";
|
|
6218
6239
|
import { createPortal as createPortal5 } from "react-dom";
|
|
6219
6240
|
|
|
6220
6241
|
// src/components/forms/Input.tsx
|
|
@@ -6320,12 +6341,12 @@ function TransferList({
|
|
|
6320
6341
|
listHeight = 440,
|
|
6321
6342
|
className = ""
|
|
6322
6343
|
}) {
|
|
6323
|
-
const [drag, setDrag] =
|
|
6324
|
-
const [dragOverSide, setDragOverSide] =
|
|
6325
|
-
const dragRef =
|
|
6326
|
-
const armedRef =
|
|
6327
|
-
const sideRefs =
|
|
6328
|
-
const hitTestSide =
|
|
6344
|
+
const [drag, setDrag] = React43.useState(null);
|
|
6345
|
+
const [dragOverSide, setDragOverSide] = React43.useState(null);
|
|
6346
|
+
const dragRef = React43.useRef(null);
|
|
6347
|
+
const armedRef = React43.useRef(null);
|
|
6348
|
+
const sideRefs = React43.useRef({ left: null, right: null });
|
|
6349
|
+
const hitTestSide = React43.useCallback((x, y) => {
|
|
6329
6350
|
for (const side of ["left", "right"]) {
|
|
6330
6351
|
const el = sideRefs.current[side];
|
|
6331
6352
|
if (!el) continue;
|
|
@@ -6334,7 +6355,7 @@ function TransferList({
|
|
|
6334
6355
|
}
|
|
6335
6356
|
return null;
|
|
6336
6357
|
}, []);
|
|
6337
|
-
const findItem =
|
|
6358
|
+
const findItem = React43.useCallback(
|
|
6338
6359
|
(side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
|
|
6339
6360
|
[left.items, right.items, keyOf]
|
|
6340
6361
|
);
|
|
@@ -6356,7 +6377,7 @@ function TransferList({
|
|
|
6356
6377
|
height: rect.height
|
|
6357
6378
|
};
|
|
6358
6379
|
};
|
|
6359
|
-
|
|
6380
|
+
React43.useEffect(() => {
|
|
6360
6381
|
const onMovePointer = (e) => {
|
|
6361
6382
|
const armed = armedRef.current;
|
|
6362
6383
|
if (!armed || e.pointerId !== armed.pointerId) return;
|
|
@@ -6409,7 +6430,7 @@ function TransferList({
|
|
|
6409
6430
|
window.removeEventListener("pointercancel", endDrag);
|
|
6410
6431
|
};
|
|
6411
6432
|
}, [hitTestSide, findItem, onMove]);
|
|
6412
|
-
|
|
6433
|
+
React43.useEffect(() => {
|
|
6413
6434
|
if (!drag || typeof document === "undefined") return;
|
|
6414
6435
|
const prev = document.body.style.userSelect;
|
|
6415
6436
|
document.body.style.userSelect = "none";
|
|
@@ -6526,7 +6547,7 @@ function FactList({ facts = [], className = "", ...rest }) {
|
|
|
6526
6547
|
}
|
|
6527
6548
|
|
|
6528
6549
|
// src/components/data/USChoropleth.tsx
|
|
6529
|
-
import * as
|
|
6550
|
+
import * as React45 from "react";
|
|
6530
6551
|
|
|
6531
6552
|
// src/components/data/usChoropleth/mapBox.ts
|
|
6532
6553
|
var MAP_WIDTH = 975;
|
|
@@ -6591,11 +6612,11 @@ function buildChoroplethModel(values, topN, givenTotal) {
|
|
|
6591
6612
|
}
|
|
6592
6613
|
|
|
6593
6614
|
// src/components/data/usChoropleth/useUsStateShapes.ts
|
|
6594
|
-
import * as
|
|
6615
|
+
import * as React44 from "react";
|
|
6595
6616
|
function useUsStateShapes() {
|
|
6596
|
-
const [token, setToken] =
|
|
6597
|
-
const [settled, setSettled] =
|
|
6598
|
-
|
|
6617
|
+
const [token, setToken] = React44.useState(0);
|
|
6618
|
+
const [settled, setSettled] = React44.useState(null);
|
|
6619
|
+
React44.useEffect(() => {
|
|
6599
6620
|
let current2 = true;
|
|
6600
6621
|
import("./usStateShapes-JJARDNLL.js").then(({ STATE_SHAPES }) => {
|
|
6601
6622
|
if (current2) setSettled({ token, state: { status: "ready", shapes: STATE_SHAPES } });
|
|
@@ -6637,7 +6658,7 @@ function nextCode(key, from) {
|
|
|
6637
6658
|
}
|
|
6638
6659
|
function StateMap({ shapes, model, figures, label, formatReadout }) {
|
|
6639
6660
|
const tip = useTooltip();
|
|
6640
|
-
const [stop, setStop] =
|
|
6661
|
+
const [stop, setStop] = React45.useState(US_STATE_CODES[0]);
|
|
6641
6662
|
const onKeyDown = (event) => {
|
|
6642
6663
|
const from = event.target.getAttribute("data-state");
|
|
6643
6664
|
const to = from && nextCode(event.key, from);
|
|
@@ -6685,8 +6706,8 @@ function StateTable({ model, valueLabel, formatValue }) {
|
|
|
6685
6706
|
return /* @__PURE__ */ jsx68(Collapsible, { title: TABLE_TITLE, children: /* @__PURE__ */ jsx68(DataTable, { columns, rows: model.rows, rowKey: "code", compact: true }) });
|
|
6686
6707
|
}
|
|
6687
6708
|
function USChoropleth({ values, label, valueLabel, formatValue, formatReadout, topN, total, className = "" }) {
|
|
6688
|
-
const model =
|
|
6689
|
-
const figures =
|
|
6709
|
+
const model = React45.useMemo(() => buildChoroplethModel(values, topN ?? 0, total), [values, topN, total]);
|
|
6710
|
+
const figures = React45.useMemo(() => new Map(model.rows.map((row) => [row.code, row])), [model]);
|
|
6690
6711
|
const { state, retry } = useUsStateShapes();
|
|
6691
6712
|
return /* @__PURE__ */ jsxs57("div", { className: ["fd-uschoro", className].filter(Boolean).join(" "), children: [
|
|
6692
6713
|
/* @__PURE__ */ jsxs57("div", { className: "fd-uschoro-layout", children: [
|
|
@@ -6721,11 +6742,11 @@ function USChoropleth({ values, label, valueLabel, formatValue, formatReadout, t
|
|
|
6721
6742
|
}
|
|
6722
6743
|
|
|
6723
6744
|
// src/components/forms/Checkbox.tsx
|
|
6724
|
-
import * as
|
|
6745
|
+
import * as React46 from "react";
|
|
6725
6746
|
import { jsx as jsx69, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
6726
6747
|
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
6727
|
-
const ref =
|
|
6728
|
-
|
|
6748
|
+
const ref = React46.useRef(null);
|
|
6749
|
+
React46.useEffect(() => {
|
|
6729
6750
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
6730
6751
|
}, [indeterminate]);
|
|
6731
6752
|
return /* @__PURE__ */ jsxs58("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
@@ -6772,7 +6793,7 @@ function Switch({ label, description, className = "", ...rest }) {
|
|
|
6772
6793
|
}
|
|
6773
6794
|
|
|
6774
6795
|
// src/components/forms/Select.tsx
|
|
6775
|
-
import * as
|
|
6796
|
+
import * as React47 from "react";
|
|
6776
6797
|
import { jsx as jsx72, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
6777
6798
|
var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
|
|
6778
6799
|
function Select({
|
|
@@ -6800,12 +6821,12 @@ function Select({
|
|
|
6800
6821
|
const isOn = (v) => multiple ? vals.includes(v) : v === value;
|
|
6801
6822
|
const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
|
|
6802
6823
|
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 =
|
|
6824
|
+
const [open2, setOpen] = React47.useState(false);
|
|
6825
|
+
const [q, setQ] = React47.useState("");
|
|
6826
|
+
const rootRef = React47.useRef(null);
|
|
6827
|
+
const boxRef = React47.useRef(null);
|
|
6828
|
+
const listRef = React47.useRef(null);
|
|
6829
|
+
const typeBuf = React47.useRef({ s: "", t: 0 });
|
|
6809
6830
|
const selected = multiple ? null : opts.find((o) => o.value === value);
|
|
6810
6831
|
const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
|
|
6811
6832
|
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 +6962,7 @@ function Select({
|
|
|
6941
6962
|
),
|
|
6942
6963
|
q ? /* @__PURE__ */ jsx72("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
|
|
6943
6964
|
] }) : void 0,
|
|
6944
|
-
footer: multiple ? /* @__PURE__ */ jsxs61(
|
|
6965
|
+
footer: multiple ? /* @__PURE__ */ jsxs61(React47.Fragment, { children: [
|
|
6945
6966
|
/* @__PURE__ */ jsx72(
|
|
6946
6967
|
"button",
|
|
6947
6968
|
{
|
|
@@ -6972,7 +6993,7 @@ function Select({
|
|
|
6972
6993
|
'Nothing matches "',
|
|
6973
6994
|
q,
|
|
6974
6995
|
'".'
|
|
6975
|
-
] }) : groups.map((grp) => /* @__PURE__ */ jsxs61(
|
|
6996
|
+
] }) : groups.map((grp) => /* @__PURE__ */ jsxs61(React47.Fragment, { children: [
|
|
6976
6997
|
grp.g ? /* @__PURE__ */ jsx72("div", { className: "fd-pop-group", children: grp.g }) : null,
|
|
6977
6998
|
grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs61(
|
|
6978
6999
|
"button",
|
|
@@ -7009,7 +7030,7 @@ function Select({
|
|
|
7009
7030
|
}
|
|
7010
7031
|
|
|
7011
7032
|
// src/components/forms/TimePicker.tsx
|
|
7012
|
-
import * as
|
|
7033
|
+
import * as React48 from "react";
|
|
7013
7034
|
import { jsx as jsx73, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
7014
7035
|
var pad = (n) => String(n).padStart(2, "0");
|
|
7015
7036
|
function ClockFace({ value = "09:00", onChange }) {
|
|
@@ -7018,9 +7039,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
7018
7039
|
if (isNaN(m)) m = 0;
|
|
7019
7040
|
const pm = h24 >= 12;
|
|
7020
7041
|
const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
|
|
7021
|
-
const [mode2, setMode] =
|
|
7022
|
-
const faceRef =
|
|
7023
|
-
const dragging =
|
|
7042
|
+
const [mode2, setMode] = React48.useState("h");
|
|
7043
|
+
const faceRef = React48.useRef(null);
|
|
7044
|
+
const dragging = React48.useRef(false);
|
|
7024
7045
|
const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
|
|
7025
7046
|
const R = 108, NR = 80;
|
|
7026
7047
|
const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
|
|
@@ -7093,9 +7114,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
7093
7114
|
}
|
|
7094
7115
|
function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
|
|
7095
7116
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
7096
|
-
const [open2, setOpen] =
|
|
7097
|
-
const rootRef =
|
|
7098
|
-
const boxRef =
|
|
7117
|
+
const [open2, setOpen] = React48.useState(false);
|
|
7118
|
+
const rootRef = React48.useRef(null);
|
|
7119
|
+
const boxRef = React48.useRef(null);
|
|
7099
7120
|
const disp = () => {
|
|
7100
7121
|
if (!value) return "";
|
|
7101
7122
|
const [h, m] = value.split(":").map(Number);
|
|
@@ -7138,7 +7159,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
7138
7159
|
offset: 6,
|
|
7139
7160
|
width: 262,
|
|
7140
7161
|
role: "presentation",
|
|
7141
|
-
footer: /* @__PURE__ */ jsxs62(
|
|
7162
|
+
footer: /* @__PURE__ */ jsxs62(React48.Fragment, { children: [
|
|
7142
7163
|
/* @__PURE__ */ jsx73(
|
|
7143
7164
|
"button",
|
|
7144
7165
|
{
|
|
@@ -7166,7 +7187,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
7166
7187
|
}
|
|
7167
7188
|
|
|
7168
7189
|
// src/components/forms/Slider.tsx
|
|
7169
|
-
import * as
|
|
7190
|
+
import * as React49 from "react";
|
|
7170
7191
|
import { jsx as jsx74, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
7171
7192
|
function Slider({
|
|
7172
7193
|
label,
|
|
@@ -7184,7 +7205,7 @@ function Slider({
|
|
|
7184
7205
|
...rest
|
|
7185
7206
|
}) {
|
|
7186
7207
|
const fieldId = useFieldId(id);
|
|
7187
|
-
const [dragging, setDragging] =
|
|
7208
|
+
const [dragging, setDragging] = React49.useState(false);
|
|
7188
7209
|
const v = value === void 0 ? min : Number(value);
|
|
7189
7210
|
const pct = max === min ? 0 : (v - min) / (max - min) * 100;
|
|
7190
7211
|
return /* @__PURE__ */ jsxs63("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
|
|
@@ -7218,7 +7239,7 @@ function Slider({
|
|
|
7218
7239
|
}
|
|
7219
7240
|
|
|
7220
7241
|
// src/components/forms/RangeSlider.tsx
|
|
7221
|
-
import * as
|
|
7242
|
+
import * as React50 from "react";
|
|
7222
7243
|
import { jsx as jsx75, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
7223
7244
|
function RangeSlider({
|
|
7224
7245
|
label,
|
|
@@ -7238,9 +7259,9 @@ function RangeSlider({
|
|
|
7238
7259
|
}) {
|
|
7239
7260
|
const fmt2 = format || ((v) => String(v));
|
|
7240
7261
|
const [a, b] = value || [min, max];
|
|
7241
|
-
const [drag, setDrag] =
|
|
7242
|
-
const [focus, setFocus] =
|
|
7243
|
-
const railRef =
|
|
7262
|
+
const [drag, setDrag] = React50.useState(null);
|
|
7263
|
+
const [focus, setFocus] = React50.useState(null);
|
|
7264
|
+
const railRef = React50.useRef(null);
|
|
7244
7265
|
const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
|
|
7245
7266
|
const clampPair = (i, v) => {
|
|
7246
7267
|
v = Math.min(max, Math.max(min, Math.round(v / step) * step));
|
|
@@ -7255,7 +7276,7 @@ function RangeSlider({
|
|
|
7255
7276
|
const r = railRef.current.getBoundingClientRect();
|
|
7256
7277
|
return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
|
|
7257
7278
|
};
|
|
7258
|
-
|
|
7279
|
+
React50.useEffect(() => {
|
|
7259
7280
|
if (drag === null) return;
|
|
7260
7281
|
const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
|
|
7261
7282
|
const upH = () => setDrag(null);
|
|
@@ -7336,7 +7357,7 @@ function RangeSlider({
|
|
|
7336
7357
|
/* @__PURE__ */ jsxs64("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
|
|
7337
7358
|
/* @__PURE__ */ jsx75("span", { className: "fd-range-rail", ref: railRef }),
|
|
7338
7359
|
/* @__PURE__ */ jsx75("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
|
|
7339
|
-
marks.map((m) => /* @__PURE__ */ jsxs64(
|
|
7360
|
+
marks.map((m) => /* @__PURE__ */ jsxs64(React50.Fragment, { children: [
|
|
7340
7361
|
/* @__PURE__ */ jsx75("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
|
|
7341
7362
|
m.label ? /* @__PURE__ */ jsx75("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
|
|
7342
7363
|
] }, m.value)),
|
|
@@ -7365,7 +7386,7 @@ function RangeSlider({
|
|
|
7365
7386
|
}
|
|
7366
7387
|
|
|
7367
7388
|
// src/components/forms/Dropzone.tsx
|
|
7368
|
-
import * as
|
|
7389
|
+
import * as React51 from "react";
|
|
7369
7390
|
import { jsx as jsx76, jsxs as jsxs65 } from "react/jsx-runtime";
|
|
7370
7391
|
function Dropzone({
|
|
7371
7392
|
onFiles,
|
|
@@ -7380,8 +7401,8 @@ function Dropzone({
|
|
|
7380
7401
|
className = "",
|
|
7381
7402
|
style
|
|
7382
7403
|
}) {
|
|
7383
|
-
const [over, setOver] =
|
|
7384
|
-
const depth =
|
|
7404
|
+
const [over, setOver] = React51.useState(false);
|
|
7405
|
+
const depth = React51.useRef(0);
|
|
7385
7406
|
const has = (e) => {
|
|
7386
7407
|
const dt = e.dataTransfer;
|
|
7387
7408
|
if (!dt) return false;
|
|
@@ -7443,8 +7464,8 @@ function FilePickButton({
|
|
|
7443
7464
|
className = "",
|
|
7444
7465
|
children
|
|
7445
7466
|
}) {
|
|
7446
|
-
const ref =
|
|
7447
|
-
return /* @__PURE__ */ jsxs65(
|
|
7467
|
+
const ref = React51.useRef(null);
|
|
7468
|
+
return /* @__PURE__ */ jsxs65(React51.Fragment, { children: [
|
|
7448
7469
|
/* @__PURE__ */ jsx76(
|
|
7449
7470
|
"button",
|
|
7450
7471
|
{
|
|
@@ -7477,10 +7498,10 @@ function FilePickButton({
|
|
|
7477
7498
|
}
|
|
7478
7499
|
function useStagedFiles(upload, opts) {
|
|
7479
7500
|
const o = opts || {};
|
|
7480
|
-
const [items, setItems] =
|
|
7481
|
-
const controllers =
|
|
7501
|
+
const [items, setItems] = React51.useState([]);
|
|
7502
|
+
const controllers = React51.useRef({});
|
|
7482
7503
|
const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
|
|
7483
|
-
const run =
|
|
7504
|
+
const run = React51.useCallback((att) => {
|
|
7484
7505
|
if (!upload) return;
|
|
7485
7506
|
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
7486
7507
|
controllers.current[att.id] = ac;
|
|
@@ -7497,14 +7518,14 @@ function useStagedFiles(upload, opts) {
|
|
|
7497
7518
|
delete controllers.current[att.id];
|
|
7498
7519
|
});
|
|
7499
7520
|
}, [upload]);
|
|
7500
|
-
const add =
|
|
7521
|
+
const add = React51.useCallback((files) => {
|
|
7501
7522
|
if (!upload) return [];
|
|
7502
7523
|
const atts = Array.from(files).map((f) => toAttachment(f));
|
|
7503
7524
|
setItems((list) => list.concat(atts));
|
|
7504
7525
|
atts.forEach(run);
|
|
7505
7526
|
return atts;
|
|
7506
7527
|
}, [upload, run]);
|
|
7507
|
-
const remove =
|
|
7528
|
+
const remove = React51.useCallback((att) => {
|
|
7508
7529
|
const ac = controllers.current[att.id];
|
|
7509
7530
|
if (ac) {
|
|
7510
7531
|
try {
|
|
@@ -7515,10 +7536,10 @@ function useStagedFiles(upload, opts) {
|
|
|
7515
7536
|
}
|
|
7516
7537
|
setItems((list) => list.filter((f) => f.id !== att.id));
|
|
7517
7538
|
}, []);
|
|
7518
|
-
const retry =
|
|
7539
|
+
const retry = React51.useCallback((att) => {
|
|
7519
7540
|
run(att);
|
|
7520
7541
|
}, [run]);
|
|
7521
|
-
const clear =
|
|
7542
|
+
const clear = React51.useCallback(() => {
|
|
7522
7543
|
Object.values(controllers.current).forEach((ac) => {
|
|
7523
7544
|
try {
|
|
7524
7545
|
ac && ac.abort();
|
|
@@ -7642,7 +7663,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
|
|
|
7642
7663
|
}
|
|
7643
7664
|
|
|
7644
7665
|
// src/components/forms/MarkdownEditor.tsx
|
|
7645
|
-
import * as
|
|
7666
|
+
import * as React52 from "react";
|
|
7646
7667
|
import { jsx as jsx78, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
7647
7668
|
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
|
|
7648
7669
|
var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
|
|
@@ -7856,7 +7877,7 @@ function syncDom(root, value) {
|
|
|
7856
7877
|
while (root.children.length > lines.length) root.removeChild(root.lastChild);
|
|
7857
7878
|
}
|
|
7858
7879
|
var LIST_CONT = RE_LI;
|
|
7859
|
-
var MarkdownEditor =
|
|
7880
|
+
var MarkdownEditor = React52.forwardRef(function MarkdownEditor2({
|
|
7860
7881
|
value = "",
|
|
7861
7882
|
onChange,
|
|
7862
7883
|
onSubmit,
|
|
@@ -7875,10 +7896,10 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
7875
7896
|
className = "",
|
|
7876
7897
|
id
|
|
7877
7898
|
}, ref) {
|
|
7878
|
-
const boxRef =
|
|
7879
|
-
const composing =
|
|
7880
|
-
const pendingCaret =
|
|
7881
|
-
|
|
7899
|
+
const boxRef = React52.useRef(null);
|
|
7900
|
+
const composing = React52.useRef(false);
|
|
7901
|
+
const pendingCaret = React52.useRef(null);
|
|
7902
|
+
React52.useLayoutEffect(() => {
|
|
7882
7903
|
const root = boxRef.current;
|
|
7883
7904
|
if (!root || composing.current) return;
|
|
7884
7905
|
const active = document.activeElement === root || root.contains(document.activeElement);
|
|
@@ -7887,7 +7908,7 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
7887
7908
|
pendingCaret.current = null;
|
|
7888
7909
|
if (active && caret != null) placeCaret(root, caret);
|
|
7889
7910
|
}, [value]);
|
|
7890
|
-
|
|
7911
|
+
React52.useEffect(() => {
|
|
7891
7912
|
if (autoFocus && boxRef.current) boxRef.current.focus();
|
|
7892
7913
|
}, [autoFocus]);
|
|
7893
7914
|
const caretNow = () => {
|
|
@@ -7954,8 +7975,8 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
7954
7975
|
api.replaceRange(from, to, next, from + next.length);
|
|
7955
7976
|
}
|
|
7956
7977
|
};
|
|
7957
|
-
|
|
7958
|
-
const caretAtKeydown =
|
|
7978
|
+
React52.useImperativeHandle(ref, () => api);
|
|
7979
|
+
const caretAtKeydown = React52.useRef(-1);
|
|
7959
7980
|
function detect(text, caret) {
|
|
7960
7981
|
if (!onTrigger) return;
|
|
7961
7982
|
const upto = text.slice(0, caret);
|
|
@@ -8108,7 +8129,7 @@ var MarkdownEditor = React51.forwardRef(function MarkdownEditor2({
|
|
|
8108
8129
|
});
|
|
8109
8130
|
|
|
8110
8131
|
// src/components/forms/CodeEditor.tsx
|
|
8111
|
-
import * as
|
|
8132
|
+
import * as React53 from "react";
|
|
8112
8133
|
import { EditorView, keymap, lineNumbers, placeholder as cmPlaceholder, drawSelection, Decoration } from "@codemirror/view";
|
|
8113
8134
|
import { EditorState, StateEffect, StateField, Compartment } from "@codemirror/state";
|
|
8114
8135
|
import { defaultKeymap, history, historyKeymap, indentMore, indentLess } from "@codemirror/commands";
|
|
@@ -8212,16 +8233,16 @@ function CodeEditor({
|
|
|
8212
8233
|
const fieldId = useFieldId(id);
|
|
8213
8234
|
const descId = fieldId + "-desc";
|
|
8214
8235
|
const liveId = fieldId + "-live";
|
|
8215
|
-
const hostRef =
|
|
8216
|
-
const viewRef =
|
|
8217
|
-
const valueRef =
|
|
8218
|
-
const onChangeRef =
|
|
8236
|
+
const hostRef = React53.useRef(null);
|
|
8237
|
+
const viewRef = React53.useRef(null);
|
|
8238
|
+
const valueRef = React53.useRef(value);
|
|
8239
|
+
const onChangeRef = React53.useRef(onChange);
|
|
8219
8240
|
onChangeRef.current = onChange;
|
|
8220
|
-
const editableCompartment =
|
|
8221
|
-
const attributesCompartment =
|
|
8222
|
-
const errorRef =
|
|
8241
|
+
const editableCompartment = React53.useRef(new Compartment()).current;
|
|
8242
|
+
const attributesCompartment = React53.useRef(new Compartment()).current;
|
|
8243
|
+
const errorRef = React53.useRef(error);
|
|
8223
8244
|
errorRef.current = error;
|
|
8224
|
-
const diagnosticsCountRef =
|
|
8245
|
+
const diagnosticsCountRef = React53.useRef(diagnostics.length);
|
|
8225
8246
|
diagnosticsCountRef.current = diagnostics.length;
|
|
8226
8247
|
function contentAttributes() {
|
|
8227
8248
|
return {
|
|
@@ -8231,7 +8252,7 @@ function CodeEditor({
|
|
|
8231
8252
|
...label ? { "aria-label": label } : {}
|
|
8232
8253
|
};
|
|
8233
8254
|
}
|
|
8234
|
-
|
|
8255
|
+
React53.useEffect(() => {
|
|
8235
8256
|
const host2 = hostRef.current;
|
|
8236
8257
|
if (!host2) return;
|
|
8237
8258
|
const updateListener = EditorView.updateListener.of((update) => {
|
|
@@ -8273,7 +8294,7 @@ function CodeEditor({
|
|
|
8273
8294
|
viewRef.current = null;
|
|
8274
8295
|
};
|
|
8275
8296
|
}, []);
|
|
8276
|
-
|
|
8297
|
+
React53.useEffect(() => {
|
|
8277
8298
|
const view = viewRef.current;
|
|
8278
8299
|
if (!view) return;
|
|
8279
8300
|
const current2 = view.state.doc.toString();
|
|
@@ -8282,12 +8303,12 @@ function CodeEditor({
|
|
|
8282
8303
|
}
|
|
8283
8304
|
valueRef.current = value;
|
|
8284
8305
|
}, [value]);
|
|
8285
|
-
|
|
8306
|
+
React53.useEffect(() => {
|
|
8286
8307
|
const view = viewRef.current;
|
|
8287
8308
|
if (!view) return;
|
|
8288
8309
|
view.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!disabled)) });
|
|
8289
8310
|
}, [disabled, editableCompartment]);
|
|
8290
|
-
|
|
8311
|
+
React53.useEffect(() => {
|
|
8291
8312
|
const view = viewRef.current;
|
|
8292
8313
|
if (!view) return;
|
|
8293
8314
|
view.dispatch({
|
|
@@ -8345,11 +8366,11 @@ function CodeEditor({
|
|
|
8345
8366
|
}
|
|
8346
8367
|
|
|
8347
8368
|
// src/components/forms/RadioGroup.tsx
|
|
8348
|
-
import * as
|
|
8369
|
+
import * as React54 from "react";
|
|
8349
8370
|
import { jsx as jsx80, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
8350
8371
|
function RadioGroup({ label, labelledBy, options, value, onChange, card = false, disabled = false, name, className = "" }) {
|
|
8351
|
-
const autoName =
|
|
8352
|
-
const labelId =
|
|
8372
|
+
const autoName = React54.useId();
|
|
8373
|
+
const labelId = React54.useId();
|
|
8353
8374
|
return /* @__PURE__ */ jsxs69("div", { role: "radiogroup", "aria-labelledby": labelledBy ?? labelId, "aria-disabled": disabled || void 0, className: ["fd-radiogroup", className].filter(Boolean).join(" "), children: [
|
|
8354
8375
|
labelledBy === void 0 && /* @__PURE__ */ jsx80("span", { id: labelId, className: "fd-radiogroup-label", children: label }),
|
|
8355
8376
|
options.map((o) => /* @__PURE__ */ jsx80(
|
|
@@ -8377,16 +8398,16 @@ function Fieldset({ busy = false, className = "", ...rest }) {
|
|
|
8377
8398
|
}
|
|
8378
8399
|
|
|
8379
8400
|
// src/components/platform/AccountMenu.tsx
|
|
8380
|
-
import * as
|
|
8401
|
+
import * as React56 from "react";
|
|
8381
8402
|
|
|
8382
8403
|
// src/kits/sessionContext.tsx
|
|
8383
|
-
import * as
|
|
8384
|
-
var SessionContext =
|
|
8404
|
+
import * as React55 from "react";
|
|
8405
|
+
var SessionContext = React55.createContext(null);
|
|
8385
8406
|
function SessionProvider({ value, children }) {
|
|
8386
|
-
return
|
|
8407
|
+
return React55.createElement(SessionContext.Provider, { value }, children);
|
|
8387
8408
|
}
|
|
8388
8409
|
function useSessionContext() {
|
|
8389
|
-
const ctx =
|
|
8410
|
+
const ctx = React55.useContext(SessionContext);
|
|
8390
8411
|
if (!ctx) {
|
|
8391
8412
|
throw new Error(
|
|
8392
8413
|
"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 +8447,11 @@ function AccountMenu({
|
|
|
8426
8447
|
...rest
|
|
8427
8448
|
}) {
|
|
8428
8449
|
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 =
|
|
8450
|
+
const [open2, setOpen] = React56.useState(false);
|
|
8451
|
+
const [switching, setSwitching] = React56.useState(false);
|
|
8452
|
+
const [signingOut, setSigningOut] = React56.useState(false);
|
|
8453
|
+
const [signOutError, setSignOutError] = React56.useState(null);
|
|
8454
|
+
const ref = React56.useRef(null);
|
|
8434
8455
|
const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
|
|
8435
8456
|
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
8457
|
const closeMenu = () => {
|
|
@@ -8555,13 +8576,13 @@ function AccountMenu({
|
|
|
8555
8576
|
}
|
|
8556
8577
|
|
|
8557
8578
|
// src/components/platform/AppSwitcher.tsx
|
|
8558
|
-
import * as
|
|
8579
|
+
import * as React57 from "react";
|
|
8559
8580
|
import { jsx as jsx83, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
8560
8581
|
function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
8561
8582
|
const { apps: contextApps } = useSessionContext();
|
|
8562
8583
|
const apps = appsProp ?? contextApps ?? [];
|
|
8563
|
-
const [open2, setOpen] =
|
|
8564
|
-
const anchorRef =
|
|
8584
|
+
const [open2, setOpen] = React57.useState(false);
|
|
8585
|
+
const anchorRef = React57.useRef(null);
|
|
8565
8586
|
if (!apps.length) return null;
|
|
8566
8587
|
const items = apps.map((app) => ({
|
|
8567
8588
|
id: app.key,
|
|
@@ -8575,7 +8596,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
8575
8596
|
window.location.href = app.url;
|
|
8576
8597
|
}
|
|
8577
8598
|
}));
|
|
8578
|
-
return /* @__PURE__ */ jsxs71(
|
|
8599
|
+
return /* @__PURE__ */ jsxs71(React57.Fragment, { children: [
|
|
8579
8600
|
/* @__PURE__ */ jsx83("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx83(
|
|
8580
8601
|
IconButton,
|
|
8581
8602
|
{
|
|
@@ -8604,10 +8625,10 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
8604
8625
|
}
|
|
8605
8626
|
|
|
8606
8627
|
// src/components/platform/AppearanceMenu.tsx
|
|
8607
|
-
import * as
|
|
8628
|
+
import * as React60 from "react";
|
|
8608
8629
|
|
|
8609
8630
|
// src/kits/appearance.ts
|
|
8610
|
-
import * as
|
|
8631
|
+
import * as React58 from "react";
|
|
8611
8632
|
var DEFAULT_STORAGE_KEY = "fd-appearance";
|
|
8612
8633
|
var DEFAULT_PREFS = {
|
|
8613
8634
|
theme: "system",
|
|
@@ -8719,8 +8740,8 @@ function watchAppearance(store, root = document.documentElement) {
|
|
|
8719
8740
|
};
|
|
8720
8741
|
}
|
|
8721
8742
|
function useAppearancePrefs(store) {
|
|
8722
|
-
const prefs =
|
|
8723
|
-
const update =
|
|
8743
|
+
const prefs = React58.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
8744
|
+
const update = React58.useCallback(
|
|
8724
8745
|
(patch) => {
|
|
8725
8746
|
store.write({ ...store.getSnapshot(), ...patch });
|
|
8726
8747
|
},
|
|
@@ -8730,15 +8751,15 @@ function useAppearancePrefs(store) {
|
|
|
8730
8751
|
}
|
|
8731
8752
|
|
|
8732
8753
|
// src/components/platform/AppearanceProvider.tsx
|
|
8733
|
-
import * as
|
|
8754
|
+
import * as React59 from "react";
|
|
8734
8755
|
import { jsx as jsx84 } from "react/jsx-runtime";
|
|
8735
|
-
var AppearanceStoreContext =
|
|
8756
|
+
var AppearanceStoreContext = React59.createContext(null);
|
|
8736
8757
|
function AppearanceProvider({ store, children }) {
|
|
8737
|
-
|
|
8758
|
+
React59.useLayoutEffect(() => watchAppearance(store), [store]);
|
|
8738
8759
|
return /* @__PURE__ */ jsx84(AppearanceStoreContext.Provider, { value: store, children });
|
|
8739
8760
|
}
|
|
8740
8761
|
function useAppearanceStore() {
|
|
8741
|
-
const store =
|
|
8762
|
+
const store = React59.useContext(AppearanceStoreContext);
|
|
8742
8763
|
if (!store) throw new Error("AppearanceMenu and useAppearanceStore must be rendered inside an <AppearanceProvider>.");
|
|
8743
8764
|
return store;
|
|
8744
8765
|
}
|
|
@@ -8758,10 +8779,10 @@ var TEXT_SCALE_OPTIONS = [
|
|
|
8758
8779
|
];
|
|
8759
8780
|
function AppearanceMenu({ className = "" }) {
|
|
8760
8781
|
const [prefs, update] = useAppearancePrefs(useAppearanceStore());
|
|
8761
|
-
const [open2, setOpen] =
|
|
8762
|
-
const anchorRef =
|
|
8782
|
+
const [open2, setOpen] = React60.useState(false);
|
|
8783
|
+
const anchorRef = React60.useRef(null);
|
|
8763
8784
|
const patch = (p) => update(p);
|
|
8764
|
-
return /* @__PURE__ */ jsxs72(
|
|
8785
|
+
return /* @__PURE__ */ jsxs72(React60.Fragment, { children: [
|
|
8765
8786
|
/* @__PURE__ */ jsx85("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx85(
|
|
8766
8787
|
IconButton,
|
|
8767
8788
|
{
|
|
@@ -8830,14 +8851,14 @@ function AppearanceMenu({ className = "" }) {
|
|
|
8830
8851
|
}
|
|
8831
8852
|
|
|
8832
8853
|
// src/components/platform/ApiSpecBrowser.tsx
|
|
8833
|
-
import * as
|
|
8854
|
+
import * as React61 from "react";
|
|
8834
8855
|
import { jsx as jsx86, jsxs as jsxs73 } from "react/jsx-runtime";
|
|
8835
8856
|
var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
|
|
8836
8857
|
function Json({ obj }) {
|
|
8837
8858
|
return /* @__PURE__ */ jsx86("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
|
|
8838
8859
|
}
|
|
8839
8860
|
function Endpoint({ s, onRequest }) {
|
|
8840
|
-
const [tried, setTried] =
|
|
8861
|
+
const [tried, setTried] = React61.useState(null);
|
|
8841
8862
|
const run = async () => {
|
|
8842
8863
|
setTried("busy");
|
|
8843
8864
|
const t0 = (window.performance || Date).now();
|
|
@@ -8910,10 +8931,10 @@ function ApiSpecBrowser({
|
|
|
8910
8931
|
className = "",
|
|
8911
8932
|
...rest
|
|
8912
8933
|
}) {
|
|
8913
|
-
const [q, setQ] =
|
|
8914
|
-
const [method, setMethod] =
|
|
8915
|
-
const [mod, setMod] =
|
|
8916
|
-
const [listOnly, setListOnly] =
|
|
8934
|
+
const [q, setQ] = React61.useState("");
|
|
8935
|
+
const [method, setMethod] = React61.useState(null);
|
|
8936
|
+
const [mod, setMod] = React61.useState(null);
|
|
8937
|
+
const [listOnly, setListOnly] = React61.useState(false);
|
|
8917
8938
|
const activeModule = modules && modules.find((m) => m.id === mod);
|
|
8918
8939
|
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
8940
|
const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
|
|
@@ -8992,7 +9013,7 @@ function ApiSpecBrowser({
|
|
|
8992
9013
|
}
|
|
8993
9014
|
|
|
8994
9015
|
// src/components/platform/ProfilePage.tsx
|
|
8995
|
-
import * as
|
|
9016
|
+
import * as React62 from "react";
|
|
8996
9017
|
import { jsx as jsx87, jsxs as jsxs74 } from "react/jsx-runtime";
|
|
8997
9018
|
function fieldInitialValue(field, user) {
|
|
8998
9019
|
if (field.value) return field.value(user);
|
|
@@ -9028,21 +9049,21 @@ function ProfilePage({
|
|
|
9028
9049
|
}) {
|
|
9029
9050
|
const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
|
|
9030
9051
|
const user = userProp || sessionUser;
|
|
9031
|
-
const initialFieldValues =
|
|
9052
|
+
const initialFieldValues = React62.useMemo(() => {
|
|
9032
9053
|
const values2 = {};
|
|
9033
9054
|
for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
|
|
9034
9055
|
return values2;
|
|
9035
9056
|
}, [user.id, fields]);
|
|
9036
|
-
const initialNotify =
|
|
9057
|
+
const initialNotify = React62.useMemo(() => {
|
|
9037
9058
|
const values2 = {};
|
|
9038
9059
|
for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
|
|
9039
9060
|
return values2;
|
|
9040
9061
|
}, [user.id, notifications]);
|
|
9041
|
-
const [values, setValues] =
|
|
9042
|
-
const [notify, setNotify] =
|
|
9043
|
-
const [saving, setSaving] =
|
|
9044
|
-
const [saved, setSaved] =
|
|
9045
|
-
const [prevUserId, setPrevUserId] =
|
|
9062
|
+
const [values, setValues] = React62.useState(initialFieldValues);
|
|
9063
|
+
const [notify, setNotify] = React62.useState(initialNotify);
|
|
9064
|
+
const [saving, setSaving] = React62.useState(false);
|
|
9065
|
+
const [saved, setSaved] = React62.useState(false);
|
|
9066
|
+
const [prevUserId, setPrevUserId] = React62.useState(user.id);
|
|
9046
9067
|
if (user.id !== prevUserId) {
|
|
9047
9068
|
setPrevUserId(user.id);
|
|
9048
9069
|
setValues(initialFieldValues);
|
|
@@ -9230,7 +9251,7 @@ function ProfilePage({
|
|
|
9230
9251
|
}
|
|
9231
9252
|
|
|
9232
9253
|
// src/components/platform/SessionScreen.tsx
|
|
9233
|
-
import * as
|
|
9254
|
+
import * as React63 from "react";
|
|
9234
9255
|
import { Fragment as Fragment22, jsx as jsx88, jsxs as jsxs75 } from "react/jsx-runtime";
|
|
9235
9256
|
var COPY = {
|
|
9236
9257
|
"signing-in": { busy: "Signing you in\u2026" },
|
|
@@ -9244,13 +9265,13 @@ function SessionScreen({ kind, error, onRetry, productName }) {
|
|
|
9244
9265
|
const copy = COPY[kind];
|
|
9245
9266
|
const busyMessage = "busy" in copy ? copy.busy : null;
|
|
9246
9267
|
const failureTitle = "failure" in copy ? copy.failure : null;
|
|
9247
|
-
const [announced, setAnnounced] =
|
|
9248
|
-
|
|
9268
|
+
const [announced, setAnnounced] = React63.useState("");
|
|
9269
|
+
React63.useEffect(() => {
|
|
9249
9270
|
setAnnounced(busyMessage ?? "");
|
|
9250
9271
|
}, [busyMessage]);
|
|
9251
|
-
const titleRef =
|
|
9272
|
+
const titleRef = React63.useRef(null);
|
|
9252
9273
|
const failed = failureTitle !== null;
|
|
9253
|
-
|
|
9274
|
+
React63.useEffect(() => {
|
|
9254
9275
|
titleRef.current?.focus({ preventScroll: true });
|
|
9255
9276
|
}, [failed]);
|
|
9256
9277
|
return /* @__PURE__ */ jsx88("main", { className: "fd-session-screen", children: /* @__PURE__ */ jsxs75("div", { className: "fd-session-screen-inner", children: [
|
|
@@ -9273,10 +9294,10 @@ function SessionScreen({ kind, error, onRetry, productName }) {
|
|
|
9273
9294
|
}
|
|
9274
9295
|
|
|
9275
9296
|
// src/components/platform/RoadmapTimeline.tsx
|
|
9276
|
-
import * as
|
|
9297
|
+
import * as React66 from "react";
|
|
9277
9298
|
|
|
9278
9299
|
// src/kits/session.ts
|
|
9279
|
-
import * as
|
|
9300
|
+
import * as React64 from "react";
|
|
9280
9301
|
var PERMISSION_CATALOG = [
|
|
9281
9302
|
{ group: "Plans", items: [
|
|
9282
9303
|
{ key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
|
|
@@ -10843,8 +10864,8 @@ function roadmap(overrides) {
|
|
|
10843
10864
|
};
|
|
10844
10865
|
}
|
|
10845
10866
|
function useSession() {
|
|
10846
|
-
const [s, setS] =
|
|
10847
|
-
|
|
10867
|
+
const [s, setS] = React64.useState(getSession);
|
|
10868
|
+
React64.useEffect(() => subscribe(setS), []);
|
|
10848
10869
|
return s;
|
|
10849
10870
|
}
|
|
10850
10871
|
var SessionKit = {
|
|
@@ -10877,7 +10898,7 @@ var SessionKit = {
|
|
|
10877
10898
|
};
|
|
10878
10899
|
function DemoSessionProvider({ children }) {
|
|
10879
10900
|
const session = useSession();
|
|
10880
|
-
const value =
|
|
10901
|
+
const value = React64.useMemo(
|
|
10881
10902
|
() => ({
|
|
10882
10903
|
user: session.user,
|
|
10883
10904
|
roles: session.roles,
|
|
@@ -10893,11 +10914,11 @@ function DemoSessionProvider({ children }) {
|
|
|
10893
10914
|
}),
|
|
10894
10915
|
[session]
|
|
10895
10916
|
);
|
|
10896
|
-
return
|
|
10917
|
+
return React64.createElement(SessionProvider, { value }, children);
|
|
10897
10918
|
}
|
|
10898
10919
|
|
|
10899
10920
|
// src/kits/runtime.ts
|
|
10900
|
-
import * as
|
|
10921
|
+
import * as React65 from "react";
|
|
10901
10922
|
var WIRED_ENDPOINTS = [
|
|
10902
10923
|
// Nothing yet. Every id below would come from a real service:
|
|
10903
10924
|
// "plan.get", "placements.list", …
|
|
@@ -11068,8 +11089,8 @@ var RuntimeKit = {
|
|
|
11068
11089
|
};
|
|
11069
11090
|
RuntimeKit.declare(FEATURE_NEEDS);
|
|
11070
11091
|
function useRuntimeMode() {
|
|
11071
|
-
const [m, setM] =
|
|
11072
|
-
|
|
11092
|
+
const [m, setM] = React65.useState(RuntimeKit.getMode());
|
|
11093
|
+
React65.useEffect(() => RuntimeKit.subscribe(setM), []);
|
|
11073
11094
|
return m;
|
|
11074
11095
|
}
|
|
11075
11096
|
function useFeatureStatus(key) {
|
|
@@ -11152,12 +11173,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
11152
11173
|
}
|
|
11153
11174
|
function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
11154
11175
|
const session = SessionKit.useSession();
|
|
11155
|
-
const [project, setProject] =
|
|
11156
|
-
const [q, setQ] =
|
|
11157
|
-
const scrollRef =
|
|
11158
|
-
const nowRef =
|
|
11159
|
-
const rm =
|
|
11160
|
-
const byKey =
|
|
11176
|
+
const [project, setProject] = React66.useState("");
|
|
11177
|
+
const [q, setQ] = React66.useState("");
|
|
11178
|
+
const scrollRef = React66.useRef(null);
|
|
11179
|
+
const nowRef = React66.useRef(null);
|
|
11180
|
+
const rm = React66.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
|
|
11181
|
+
const byKey = React66.useMemo(() => {
|
|
11161
11182
|
const m = {};
|
|
11162
11183
|
rm.items.forEach((i) => {
|
|
11163
11184
|
m[i.key] = i;
|
|
@@ -11166,7 +11187,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
11166
11187
|
}, [rm]);
|
|
11167
11188
|
const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
|
|
11168
11189
|
const projects = [...new Set(rm.items.map((i) => i.project))];
|
|
11169
|
-
|
|
11190
|
+
React66.useEffect(() => {
|
|
11170
11191
|
let raf1 = 0, raf2 = 0;
|
|
11171
11192
|
const place = () => {
|
|
11172
11193
|
const box = scrollRef.current, mark = nowRef.current;
|
|
@@ -11240,7 +11261,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
11240
11261
|
lastPhase = item.phase;
|
|
11241
11262
|
const inPhase = items.filter((i) => i.phase === item.phase).length;
|
|
11242
11263
|
const isBoundary = n === firstPending;
|
|
11243
|
-
return /* @__PURE__ */ jsxs76(
|
|
11264
|
+
return /* @__PURE__ */ jsxs76(React66.Fragment, { children: [
|
|
11244
11265
|
showPhase ? /* @__PURE__ */ jsxs76("div", { className: "fd-rm-era", children: [
|
|
11245
11266
|
/* @__PURE__ */ jsxs76("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
|
|
11246
11267
|
/* @__PURE__ */ jsx89("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
|
|
@@ -11284,7 +11305,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
11284
11305
|
}
|
|
11285
11306
|
|
|
11286
11307
|
// src/components/platform/ComingSoon.tsx
|
|
11287
|
-
import * as
|
|
11308
|
+
import * as React67 from "react";
|
|
11288
11309
|
import { createPortal as createPortal6 } from "react-dom";
|
|
11289
11310
|
import { Fragment as Fragment24, jsx as jsx90, jsxs as jsxs77 } from "react/jsx-runtime";
|
|
11290
11311
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
@@ -11302,8 +11323,8 @@ function writeBypassed(list) {
|
|
|
11302
11323
|
}
|
|
11303
11324
|
}
|
|
11304
11325
|
function useBypass(key) {
|
|
11305
|
-
const [on, setOn] =
|
|
11306
|
-
|
|
11326
|
+
const [on, setOn] = React67.useState(() => !!key && readBypassed().indexOf(key) >= 0);
|
|
11327
|
+
React67.useEffect(() => {
|
|
11307
11328
|
setOn(!!key && readBypassed().indexOf(key) >= 0);
|
|
11308
11329
|
}, [key]);
|
|
11309
11330
|
const set = (next) => {
|
|
@@ -11350,9 +11371,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
|
|
|
11350
11371
|
] });
|
|
11351
11372
|
}
|
|
11352
11373
|
function useHoverCard(open2) {
|
|
11353
|
-
const anchor =
|
|
11354
|
-
const [pos, setPos] =
|
|
11355
|
-
|
|
11374
|
+
const anchor = React67.useRef(null);
|
|
11375
|
+
const [pos, setPos] = React67.useState(null);
|
|
11376
|
+
React67.useLayoutEffect(() => {
|
|
11356
11377
|
if (!open2 || !anchor.current) {
|
|
11357
11378
|
setPos(null);
|
|
11358
11379
|
return;
|
|
@@ -11479,12 +11500,12 @@ function ComingSoon({
|
|
|
11479
11500
|
] });
|
|
11480
11501
|
}
|
|
11481
11502
|
function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
|
|
11482
|
-
const [open2, setOpen] =
|
|
11503
|
+
const [open2, setOpen] = React67.useState(false);
|
|
11483
11504
|
const [anchor, pos] = useHoverCard(open2);
|
|
11484
|
-
const hoverCardRef =
|
|
11505
|
+
const hoverCardRef = React67.useRef(null);
|
|
11485
11506
|
const hoverLayer = useStackedLayer({ active: open2, containerRef: hoverCardRef, returnFocus: false });
|
|
11486
11507
|
const zIndex = useLayerZIndex(hoverLayer);
|
|
11487
|
-
const close2 =
|
|
11508
|
+
const close2 = React67.useRef(null);
|
|
11488
11509
|
const show = () => {
|
|
11489
11510
|
if (close2.current) {
|
|
11490
11511
|
clearTimeout(close2.current);
|
|
@@ -11500,7 +11521,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
11500
11521
|
setOpen(false);
|
|
11501
11522
|
}, 140);
|
|
11502
11523
|
};
|
|
11503
|
-
|
|
11524
|
+
React67.useEffect(() => () => {
|
|
11504
11525
|
if (close2.current) clearTimeout(close2.current);
|
|
11505
11526
|
}, []);
|
|
11506
11527
|
return /* @__PURE__ */ jsxs77(
|
|
@@ -11952,7 +11973,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
11952
11973
|
}
|
|
11953
11974
|
|
|
11954
11975
|
// src/components/planner/MixGap.tsx
|
|
11955
|
-
import * as
|
|
11976
|
+
import * as React68 from "react";
|
|
11956
11977
|
import { Fragment as Fragment26, jsx as jsx95, jsxs as jsxs82 } from "react/jsx-runtime";
|
|
11957
11978
|
var MIX_GAP_LAYOUT = {
|
|
11958
11979
|
trackHeight: 30,
|
|
@@ -11967,7 +11988,7 @@ function mixGapOffset(value, max) {
|
|
|
11967
11988
|
}
|
|
11968
11989
|
function MixGap({ rows = [], loading = false, className = "" }) {
|
|
11969
11990
|
const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
|
|
11970
|
-
const [hover, setHover] =
|
|
11991
|
+
const [hover, setHover] = React68.useState(null);
|
|
11971
11992
|
const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
|
|
11972
11993
|
const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
|
|
11973
11994
|
const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
|
|
@@ -12110,7 +12131,7 @@ function ChannelContribution({
|
|
|
12110
12131
|
}
|
|
12111
12132
|
|
|
12112
12133
|
// src/components/planner/BudgetReallocator.tsx
|
|
12113
|
-
import * as
|
|
12134
|
+
import * as React69 from "react";
|
|
12114
12135
|
import { Fragment as Fragment27, jsx as jsx97, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
12115
12136
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
12116
12137
|
function BudgetReallocator({
|
|
@@ -12126,8 +12147,8 @@ function BudgetReallocator({
|
|
|
12126
12147
|
onCancel,
|
|
12127
12148
|
className = ""
|
|
12128
12149
|
}) {
|
|
12129
|
-
const [draft, setDraft] =
|
|
12130
|
-
|
|
12150
|
+
const [draft, setDraft] = React69.useState(spend);
|
|
12151
|
+
React69.useEffect(() => setDraft(spend), [spend]);
|
|
12131
12152
|
const dirty = draft !== spend;
|
|
12132
12153
|
const nextCrp = scoreFor ? scoreFor(draft) : crp;
|
|
12133
12154
|
const nextBand = bandFor(nextCrp);
|
|
@@ -12142,10 +12163,10 @@ function BudgetReallocator({
|
|
|
12142
12163
|
setDraft(spend);
|
|
12143
12164
|
if (onCancel) onCancel();
|
|
12144
12165
|
};
|
|
12145
|
-
const trackRef =
|
|
12146
|
-
const chipRef =
|
|
12147
|
-
const [chipLeft, setChipLeft] =
|
|
12148
|
-
|
|
12166
|
+
const trackRef = React69.useRef(null);
|
|
12167
|
+
const chipRef = React69.useRef(null);
|
|
12168
|
+
const [chipLeft, setChipLeft] = React69.useState(null);
|
|
12169
|
+
React69.useLayoutEffect(() => {
|
|
12149
12170
|
const track = trackRef.current;
|
|
12150
12171
|
if (!dirty || !track) {
|
|
12151
12172
|
setChipLeft(null);
|
|
@@ -12333,7 +12354,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
|
|
|
12333
12354
|
}
|
|
12334
12355
|
|
|
12335
12356
|
// src/components/planner/PreferenceMeter.tsx
|
|
12336
|
-
import * as
|
|
12357
|
+
import * as React70 from "react";
|
|
12337
12358
|
import { jsx as jsx100, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
12338
12359
|
function preferenceScore(criteria) {
|
|
12339
12360
|
const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
|
|
@@ -12363,7 +12384,7 @@ function PreferenceMeter({
|
|
|
12363
12384
|
className = ""
|
|
12364
12385
|
}) {
|
|
12365
12386
|
const value = score == null ? preferenceScore(criteria) : score;
|
|
12366
|
-
const segments =
|
|
12387
|
+
const segments = React70.useMemo(() => preferenceSegments(criteria), [criteria]);
|
|
12367
12388
|
return /* @__PURE__ */ jsx100(
|
|
12368
12389
|
ScoreMeter,
|
|
12369
12390
|
{
|
|
@@ -12402,13 +12423,13 @@ function PreferenceMeter({
|
|
|
12402
12423
|
}
|
|
12403
12424
|
|
|
12404
12425
|
// src/components/chat/AgentChatPanel.tsx
|
|
12405
|
-
import * as
|
|
12426
|
+
import * as React77 from "react";
|
|
12406
12427
|
|
|
12407
12428
|
// src/components/chat/chatEngine.ts
|
|
12408
|
-
import * as
|
|
12429
|
+
import * as React72 from "react";
|
|
12409
12430
|
|
|
12410
12431
|
// src/components/chat/chatStore.ts
|
|
12411
|
-
import * as
|
|
12432
|
+
import * as React71 from "react";
|
|
12412
12433
|
var safeStore = {
|
|
12413
12434
|
get(k) {
|
|
12414
12435
|
try {
|
|
@@ -12437,13 +12458,13 @@ function useChatDraft(owner, contextType, contextId, store = safeStore) {
|
|
|
12437
12458
|
if (owner === "") throw new Error("useChatDraft: draftOwner is an empty string; pass the signed-in user's id, or null for no owner.");
|
|
12438
12459
|
const key = owner === null ? null : draftKey(owner, contextType, contextId);
|
|
12439
12460
|
const read2 = (k) => k ? store.get(k) || "" : "";
|
|
12440
|
-
const [state, setState] =
|
|
12461
|
+
const [state, setState] = React71.useState(() => ({ key, text: read2(key) }));
|
|
12441
12462
|
let current2 = state;
|
|
12442
12463
|
if (state.key !== key) {
|
|
12443
12464
|
current2 = { key, text: read2(key) };
|
|
12444
12465
|
setState(current2);
|
|
12445
12466
|
}
|
|
12446
|
-
const setText =
|
|
12467
|
+
const setText = React71.useCallback((text) => {
|
|
12447
12468
|
if (key) {
|
|
12448
12469
|
if (text) {
|
|
12449
12470
|
store.set(key, text);
|
|
@@ -12502,33 +12523,33 @@ function useChatEngine(opts) {
|
|
|
12502
12523
|
onClear,
|
|
12503
12524
|
onFeedback
|
|
12504
12525
|
} = 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
|
-
|
|
12526
|
+
const [status, setStatus] = React72.useState("idle");
|
|
12527
|
+
const [threadId, setThreadId] = React72.useState(null);
|
|
12528
|
+
const [messages, setMessages] = React72.useState([]);
|
|
12529
|
+
const [queue, setQueue] = React72.useState([]);
|
|
12530
|
+
const [fatal, setFatal] = React72.useState(null);
|
|
12531
|
+
const [busy, setBusy] = React72.useState(false);
|
|
12532
|
+
const [turnStartedAt, setTurnStartedAt] = React72.useState(null);
|
|
12533
|
+
const listRef = React72.useRef([]);
|
|
12534
|
+
const queueRef = React72.useRef([]);
|
|
12535
|
+
const busyRef = React72.useRef(false);
|
|
12536
|
+
const loadedRef = React72.useRef(false);
|
|
12537
|
+
const stoppedRef = React72.useRef(false);
|
|
12538
|
+
const abortRef = React72.useRef(null);
|
|
12539
|
+
const serverCount = React72.useRef(0);
|
|
12540
|
+
const serverIds = React72.useRef(/* @__PURE__ */ new Set());
|
|
12541
|
+
const liveTurn = React72.useRef(null);
|
|
12542
|
+
const lastTurnOwn = React72.useRef(/* @__PURE__ */ new Set());
|
|
12543
|
+
const retired = React72.useRef(/* @__PURE__ */ new Set());
|
|
12544
|
+
const threadRef = React72.useRef(null);
|
|
12545
|
+
const mounted = React72.useRef(true);
|
|
12546
|
+
React72.useEffect(() => {
|
|
12526
12547
|
mounted.current = true;
|
|
12527
12548
|
return () => {
|
|
12528
12549
|
mounted.current = false;
|
|
12529
12550
|
};
|
|
12530
12551
|
}, []);
|
|
12531
|
-
const describeWaitingRef =
|
|
12552
|
+
const describeWaitingRef = React72.useRef(describeWaiting);
|
|
12532
12553
|
describeWaitingRef.current = describeWaiting;
|
|
12533
12554
|
const commit = (next) => {
|
|
12534
12555
|
const derived = withWaiting(next, (pending) => describeWaitingRef.current(pending));
|
|
@@ -12547,7 +12568,7 @@ function useChatEngine(opts) {
|
|
|
12547
12568
|
}
|
|
12548
12569
|
return false;
|
|
12549
12570
|
};
|
|
12550
|
-
const loadThread =
|
|
12571
|
+
const loadThread = React72.useCallback(async (id) => {
|
|
12551
12572
|
const data = await apiAdapter.getThread(id);
|
|
12552
12573
|
const list = [...data && data.messages || []];
|
|
12553
12574
|
serverCount.current = list.length;
|
|
@@ -12587,7 +12608,7 @@ function useChatEngine(opts) {
|
|
|
12587
12608
|
packet: progress.packet ?? holder.packet
|
|
12588
12609
|
});
|
|
12589
12610
|
}
|
|
12590
|
-
|
|
12611
|
+
React72.useEffect(() => {
|
|
12591
12612
|
if (!apiAdapter) {
|
|
12592
12613
|
setStatus("idle");
|
|
12593
12614
|
setFatal(null);
|
|
@@ -12819,7 +12840,7 @@ function useChatEngine(opts) {
|
|
|
12819
12840
|
await dispatchTurn(turn);
|
|
12820
12841
|
}
|
|
12821
12842
|
}
|
|
12822
|
-
const send =
|
|
12843
|
+
const send = React72.useCallback((text, attachments) => {
|
|
12823
12844
|
const body = (text || "").trim();
|
|
12824
12845
|
if (!body && !(attachments && attachments.length)) return;
|
|
12825
12846
|
if (status === "disconnected") return;
|
|
@@ -12829,7 +12850,7 @@ function useChatEngine(opts) {
|
|
|
12829
12850
|
stoppedRef.current = false;
|
|
12830
12851
|
drain();
|
|
12831
12852
|
}, [status]);
|
|
12832
|
-
const stop =
|
|
12853
|
+
const stop = React72.useCallback(() => {
|
|
12833
12854
|
stoppedRef.current = true;
|
|
12834
12855
|
const ac = abortRef.current;
|
|
12835
12856
|
if (ac) {
|
|
@@ -12848,11 +12869,11 @@ function useChatEngine(opts) {
|
|
|
12848
12869
|
store.del(jobKey(threadRef.current));
|
|
12849
12870
|
}
|
|
12850
12871
|
}, [apiAdapter]);
|
|
12851
|
-
const removeQueued =
|
|
12872
|
+
const removeQueued = React72.useCallback((id) => {
|
|
12852
12873
|
queueRef.current = queueRef.current.filter((t) => t.id !== id);
|
|
12853
12874
|
setQueue(queueRef.current.slice());
|
|
12854
12875
|
}, []);
|
|
12855
|
-
const retry =
|
|
12876
|
+
const retry = React72.useCallback(() => {
|
|
12856
12877
|
const list = listRef.current;
|
|
12857
12878
|
let at = -1;
|
|
12858
12879
|
for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
|
|
@@ -12869,19 +12890,19 @@ function useChatEngine(opts) {
|
|
|
12869
12890
|
setQueue(queueRef.current.slice());
|
|
12870
12891
|
drain();
|
|
12871
12892
|
}, []);
|
|
12872
|
-
const clear =
|
|
12893
|
+
const clear = React72.useCallback(() => {
|
|
12873
12894
|
commit([]);
|
|
12874
12895
|
serverCount.current = 0;
|
|
12875
12896
|
queueRef.current = [];
|
|
12876
12897
|
setQueue([]);
|
|
12877
12898
|
onClear && onClear();
|
|
12878
12899
|
}, [onClear]);
|
|
12879
|
-
const setFeedback =
|
|
12900
|
+
const setFeedback = React72.useCallback((id, value) => {
|
|
12880
12901
|
patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
|
|
12881
12902
|
const msg = listRef.current.find((m) => m.id === id);
|
|
12882
12903
|
onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
|
|
12883
12904
|
}, [onFeedback]);
|
|
12884
|
-
const reload =
|
|
12905
|
+
const reload = React72.useCallback(async () => {
|
|
12885
12906
|
if (!threadRef.current) return;
|
|
12886
12907
|
setStatus("loading");
|
|
12887
12908
|
try {
|
|
@@ -12919,10 +12940,10 @@ var ChatKit = {
|
|
|
12919
12940
|
};
|
|
12920
12941
|
|
|
12921
12942
|
// src/components/chat/ChatTranscript.tsx
|
|
12922
|
-
import * as
|
|
12943
|
+
import * as React74 from "react";
|
|
12923
12944
|
|
|
12924
12945
|
// src/components/chat/ChatTurn.tsx
|
|
12925
|
-
import * as
|
|
12946
|
+
import * as React73 from "react";
|
|
12926
12947
|
import { jsx as jsx101, jsxs as jsxs88 } from "react/jsx-runtime";
|
|
12927
12948
|
function JsonView({ value }) {
|
|
12928
12949
|
let text;
|
|
@@ -12959,7 +12980,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
|
12959
12980
|
] });
|
|
12960
12981
|
}
|
|
12961
12982
|
function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
12962
|
-
const [open2, setOpen] =
|
|
12983
|
+
const [open2, setOpen] = React73.useState(defaultOpen);
|
|
12963
12984
|
if (!text) return null;
|
|
12964
12985
|
return /* @__PURE__ */ jsxs88("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
|
|
12965
12986
|
/* @__PURE__ */ jsxs88("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -12976,7 +12997,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
|
12976
12997
|
] });
|
|
12977
12998
|
}
|
|
12978
12999
|
function Citations({ items = [], onOpen }) {
|
|
12979
|
-
const [open2, setOpen] =
|
|
13000
|
+
const [open2, setOpen] = React73.useState(false);
|
|
12980
13001
|
if (!items.length) return null;
|
|
12981
13002
|
return /* @__PURE__ */ jsxs88("div", { className: "fdc-cites", children: [
|
|
12982
13003
|
/* @__PURE__ */ jsxs88("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -13002,7 +13023,7 @@ function clampText(text, max) {
|
|
|
13002
13023
|
return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
13003
13024
|
}
|
|
13004
13025
|
function MessageBody({ message: m, ctx }) {
|
|
13005
|
-
const [expanded, setExpanded] =
|
|
13026
|
+
const [expanded, setExpanded] = React73.useState(false);
|
|
13006
13027
|
const isUser = m.role === "user";
|
|
13007
13028
|
const raw = m.text || "";
|
|
13008
13029
|
const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
|
|
@@ -13081,7 +13102,7 @@ function RunActions({ group, ctx }) {
|
|
|
13081
13102
|
] }),
|
|
13082
13103
|
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
13104
|
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(
|
|
13105
|
+
isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs88(React73.Fragment, { children: [
|
|
13085
13106
|
/* @__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
13107
|
/* @__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
13108
|
] }) : null,
|
|
@@ -13176,10 +13197,10 @@ function ChatTranscript({
|
|
|
13176
13197
|
renderEmpty,
|
|
13177
13198
|
className = ""
|
|
13178
13199
|
}) {
|
|
13179
|
-
const scroller =
|
|
13180
|
-
const stick =
|
|
13181
|
-
const [pill, setPill] =
|
|
13182
|
-
const seen =
|
|
13200
|
+
const scroller = React74.useRef(null);
|
|
13201
|
+
const stick = React74.useRef(true);
|
|
13202
|
+
const [pill, setPill] = React74.useState(0);
|
|
13203
|
+
const seen = React74.useRef(0);
|
|
13183
13204
|
const toBottom = (smooth) => {
|
|
13184
13205
|
const el = scroller.current;
|
|
13185
13206
|
if (!el) return;
|
|
@@ -13198,7 +13219,7 @@ function ChatTranscript({
|
|
|
13198
13219
|
seen.current = messages.length;
|
|
13199
13220
|
}
|
|
13200
13221
|
};
|
|
13201
|
-
|
|
13222
|
+
React74.useLayoutEffect(() => {
|
|
13202
13223
|
const el = scroller.current;
|
|
13203
13224
|
if (!el) return;
|
|
13204
13225
|
if (stick.current) {
|
|
@@ -13206,7 +13227,7 @@ function ChatTranscript({
|
|
|
13206
13227
|
seen.current = messages.length;
|
|
13207
13228
|
} else setPill(Math.max(0, messages.length - seen.current));
|
|
13208
13229
|
}, [messages]);
|
|
13209
|
-
|
|
13230
|
+
React74.useEffect(() => {
|
|
13210
13231
|
const el = scroller.current;
|
|
13211
13232
|
const inner = el && el.firstChild;
|
|
13212
13233
|
if (!el || !inner || typeof ResizeObserver === "undefined") return;
|
|
@@ -13216,7 +13237,7 @@ function ChatTranscript({
|
|
|
13216
13237
|
ro.observe(inner);
|
|
13217
13238
|
return () => ro.disconnect();
|
|
13218
13239
|
}, []);
|
|
13219
|
-
const groups =
|
|
13240
|
+
const groups = React74.useMemo(() => groupMessages(messages), [messages]);
|
|
13220
13241
|
const empty = !messages.length && status === "ready";
|
|
13221
13242
|
return /* @__PURE__ */ jsxs89("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
|
|
13222
13243
|
/* @__PURE__ */ jsxs89("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
|
|
@@ -13240,7 +13261,7 @@ function ChatTranscript({
|
|
|
13240
13261
|
const prev = groups[i - 1];
|
|
13241
13262
|
const k = dayKey(g.messages[0].timestamp);
|
|
13242
13263
|
const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
|
|
13243
|
-
return /* @__PURE__ */ jsxs89(
|
|
13264
|
+
return /* @__PURE__ */ jsxs89(React74.Fragment, { children: [
|
|
13244
13265
|
showDay ? /* @__PURE__ */ jsx102("div", { className: "fdc-day", children: /* @__PURE__ */ jsx102("span", { children: dayLabel(k) }) }) : null,
|
|
13245
13266
|
/* @__PURE__ */ jsx102(ChatTurn, { group: g, ctx })
|
|
13246
13267
|
] }, g.key || i);
|
|
@@ -13257,7 +13278,7 @@ function ChatTranscript({
|
|
|
13257
13278
|
var TranscriptKit = { groupMessages };
|
|
13258
13279
|
|
|
13259
13280
|
// src/components/chat/ChatComposer.tsx
|
|
13260
|
-
import * as
|
|
13281
|
+
import * as React75 from "react";
|
|
13261
13282
|
import { jsx as jsx103, jsxs as jsxs90 } from "react/jsx-runtime";
|
|
13262
13283
|
function ChatComposer({
|
|
13263
13284
|
onSubmit,
|
|
@@ -13285,17 +13306,17 @@ function ChatComposer({
|
|
|
13285
13306
|
onReject,
|
|
13286
13307
|
onOpenAttachment
|
|
13287
13308
|
}) {
|
|
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 =
|
|
13309
|
+
const [text, setText] = React75.useState(draft || "");
|
|
13310
|
+
const [trigger, setTrigger] = React75.useState(null);
|
|
13311
|
+
const [mentionItems, setMentionItems] = React75.useState([]);
|
|
13312
|
+
const [listening, setListening] = React75.useState(false);
|
|
13313
|
+
const [notice, setNotice] = React75.useState(null);
|
|
13314
|
+
const editor = React75.useRef(null);
|
|
13315
|
+
const wrap = React75.useRef(null);
|
|
13316
|
+
const stopVoice = React75.useRef(null);
|
|
13296
13317
|
const staged = useStagedFiles(fileUploadHandler, { onError: () => {
|
|
13297
13318
|
} });
|
|
13298
|
-
|
|
13319
|
+
React75.useEffect(() => {
|
|
13299
13320
|
if (draft != null && draft !== text) setText(draft);
|
|
13300
13321
|
}, [draft]);
|
|
13301
13322
|
const change = (v) => {
|
|
@@ -13331,7 +13352,7 @@ function ChatComposer({
|
|
|
13331
13352
|
e.preventDefault();
|
|
13332
13353
|
staged.add(found.files);
|
|
13333
13354
|
};
|
|
13334
|
-
|
|
13355
|
+
React75.useEffect(() => {
|
|
13335
13356
|
if (!trigger || trigger.type !== "mention" || !mentionSources) {
|
|
13336
13357
|
setMentionItems([]);
|
|
13337
13358
|
return;
|
|
@@ -13349,7 +13370,7 @@ function ChatComposer({
|
|
|
13349
13370
|
const q = (trigger.query || "").toLowerCase();
|
|
13350
13371
|
setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
|
|
13351
13372
|
}, [trigger, mentionSources]);
|
|
13352
|
-
const slashItems =
|
|
13373
|
+
const slashItems = React75.useMemo(() => {
|
|
13353
13374
|
if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
|
|
13354
13375
|
const q = (trigger.query || "").toLowerCase();
|
|
13355
13376
|
return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
|
|
@@ -13519,12 +13540,12 @@ function ChatComposer({
|
|
|
13519
13540
|
}
|
|
13520
13541
|
|
|
13521
13542
|
// src/components/chat/ChatSessionBar.tsx
|
|
13522
|
-
import * as
|
|
13543
|
+
import * as React76 from "react";
|
|
13523
13544
|
import { jsx as jsx104, jsxs as jsxs91 } from "react/jsx-runtime";
|
|
13524
13545
|
var compact2 = meterFormats.compact;
|
|
13525
13546
|
function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
|
|
13526
|
-
const [open2, setOpen] =
|
|
13527
|
-
const anchor =
|
|
13547
|
+
const [open2, setOpen] = React76.useState(false);
|
|
13548
|
+
const anchor = React76.useRef(null);
|
|
13528
13549
|
const stats = sessionStats || null;
|
|
13529
13550
|
const cu = contextUsage || null;
|
|
13530
13551
|
const limits = usageLimits || null;
|
|
@@ -13539,7 +13560,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
13539
13560
|
if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
|
|
13540
13561
|
if (cu) bits.push(pct + "% context");
|
|
13541
13562
|
const expandable = !!(cu || limits);
|
|
13542
|
-
return /* @__PURE__ */ jsxs91(
|
|
13563
|
+
return /* @__PURE__ */ jsxs91(React76.Fragment, { children: [
|
|
13543
13564
|
/* @__PURE__ */ jsxs91("div", { className: "fdc-bar", children: [
|
|
13544
13565
|
/* @__PURE__ */ jsxs91(
|
|
13545
13566
|
"button",
|
|
@@ -13680,7 +13701,7 @@ function ModelControls({
|
|
|
13680
13701
|
] })
|
|
13681
13702
|
});
|
|
13682
13703
|
}
|
|
13683
|
-
return /* @__PURE__ */ jsxs91(
|
|
13704
|
+
return /* @__PURE__ */ jsxs91(React76.Fragment, { children: [
|
|
13684
13705
|
/* @__PURE__ */ jsx104(
|
|
13685
13706
|
MenuButton,
|
|
13686
13707
|
{
|
|
@@ -13800,11 +13821,11 @@ function AgentChatPanel({
|
|
|
13800
13821
|
onFeedback,
|
|
13801
13822
|
onEditMessage
|
|
13802
13823
|
}) {
|
|
13803
|
-
const [panelWidth, setPanelWidth] =
|
|
13804
|
-
const [applied, setApplied] =
|
|
13824
|
+
const [panelWidth, setPanelWidth] = React77.useState(width);
|
|
13825
|
+
const [applied, setApplied] = React77.useState({});
|
|
13805
13826
|
const [draft, setDraft] = useChatDraft(draftOwner, contextType, contextId);
|
|
13806
|
-
const dragging =
|
|
13807
|
-
|
|
13827
|
+
const dragging = React77.useRef(null);
|
|
13828
|
+
React77.useEffect(() => setPanelWidth(width), [width]);
|
|
13808
13829
|
const engine = useChatEngine({
|
|
13809
13830
|
contextType,
|
|
13810
13831
|
contextId,
|
|
@@ -14010,7 +14031,7 @@ function AgentChatPanel({
|
|
|
14010
14031
|
}
|
|
14011
14032
|
|
|
14012
14033
|
// src/components/files/FileViewer.tsx
|
|
14013
|
-
import * as
|
|
14034
|
+
import * as React78 from "react";
|
|
14014
14035
|
import { jsx as jsx106, jsxs as jsxs93 } from "react/jsx-runtime";
|
|
14015
14036
|
function previewKindOf(file) {
|
|
14016
14037
|
const mime = (file.mime || "").toLowerCase();
|
|
@@ -14067,13 +14088,13 @@ function parseDelimited(text, delimiter) {
|
|
|
14067
14088
|
return rows;
|
|
14068
14089
|
}
|
|
14069
14090
|
function usePreview(file, kind, resolveUrl) {
|
|
14070
|
-
const [state, setState] =
|
|
14071
|
-
const [attempt, setAttempt] =
|
|
14072
|
-
const resolveRef =
|
|
14073
|
-
|
|
14091
|
+
const [state, setState] = React78.useState({ status: "loading" });
|
|
14092
|
+
const [attempt, setAttempt] = React78.useState(0);
|
|
14093
|
+
const resolveRef = React78.useRef(resolveUrl);
|
|
14094
|
+
React78.useEffect(() => {
|
|
14074
14095
|
resolveRef.current = resolveUrl;
|
|
14075
14096
|
}, [resolveUrl]);
|
|
14076
|
-
|
|
14097
|
+
React78.useEffect(() => {
|
|
14077
14098
|
if (kind === "none") {
|
|
14078
14099
|
setState({ status: "ready" });
|
|
14079
14100
|
return;
|
|
@@ -14103,7 +14124,7 @@ function usePreview(file, kind, resolveUrl) {
|
|
|
14103
14124
|
if (ac) ac.abort();
|
|
14104
14125
|
};
|
|
14105
14126
|
}, [file.id, kind, attempt]);
|
|
14106
|
-
return { ...state, retry:
|
|
14127
|
+
return { ...state, retry: React78.useCallback(() => setAttempt((a) => a + 1), []) };
|
|
14107
14128
|
}
|
|
14108
14129
|
function PreviewBody({ file, kind, state }) {
|
|
14109
14130
|
if (kind === "image") return /* @__PURE__ */ jsx106("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
|
|
@@ -14148,13 +14169,13 @@ function PreviewBody({ file, kind, state }) {
|
|
|
14148
14169
|
] });
|
|
14149
14170
|
}
|
|
14150
14171
|
function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
|
|
14151
|
-
const kind =
|
|
14172
|
+
const kind = React78.useMemo(() => previewKindOf(file), [file]);
|
|
14152
14173
|
const preview = usePreview(file, kind, resolveUrl);
|
|
14153
|
-
const [tab, setTab] =
|
|
14154
|
-
const [downloading, setDownloading] =
|
|
14155
|
-
const [downloadError, setDownloadError] =
|
|
14174
|
+
const [tab, setTab] = React78.useState("preview");
|
|
14175
|
+
const [downloading, setDownloading] = React78.useState(false);
|
|
14176
|
+
const [downloadError, setDownloadError] = React78.useState(null);
|
|
14156
14177
|
const hasSide = sidePanel != null;
|
|
14157
|
-
|
|
14178
|
+
React78.useEffect(() => {
|
|
14158
14179
|
setTab("preview");
|
|
14159
14180
|
}, [file.id]);
|
|
14160
14181
|
const download = () => {
|
|
@@ -14221,7 +14242,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
14221
14242
|
}
|
|
14222
14243
|
|
|
14223
14244
|
// src/components/files/FileBrowser.tsx
|
|
14224
|
-
import * as
|
|
14245
|
+
import * as React79 from "react";
|
|
14225
14246
|
import { Fragment as Fragment31, jsx as jsx107, jsxs as jsxs94 } from "react/jsx-runtime";
|
|
14226
14247
|
function childrenOf(folders, parentId) {
|
|
14227
14248
|
return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -14331,8 +14352,8 @@ function FolderPickerMenu({
|
|
|
14331
14352
|
] });
|
|
14332
14353
|
}
|
|
14333
14354
|
function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
|
|
14334
|
-
const [over, setOver] =
|
|
14335
|
-
const dragCounter =
|
|
14355
|
+
const [over, setOver] = React79.useState(false);
|
|
14356
|
+
const dragCounter = React79.useRef(0);
|
|
14336
14357
|
const dropHandlers = isDropTarget ? {
|
|
14337
14358
|
onDragEnter: (e) => {
|
|
14338
14359
|
if (!hasInternalPayload(e)) return;
|
|
@@ -14380,8 +14401,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
|
|
|
14380
14401
|
}
|
|
14381
14402
|
function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
|
|
14382
14403
|
const kids = childrenOf(folders, folder.id);
|
|
14383
|
-
const [expanded, setExpanded] =
|
|
14384
|
-
|
|
14404
|
+
const [expanded, setExpanded] = React79.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
|
|
14405
|
+
React79.useEffect(() => {
|
|
14385
14406
|
if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
|
|
14386
14407
|
}, [currentFolderId, folder.id, folders]);
|
|
14387
14408
|
const isCurrent = folder.id === currentFolderId;
|
|
@@ -14447,15 +14468,15 @@ function FileBrowser({
|
|
|
14447
14468
|
const canUpload = perm.canUpload !== false && !!onUpload;
|
|
14448
14469
|
const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
|
|
14449
14470
|
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 =
|
|
14471
|
+
const [createOpen, setCreateOpen] = React79.useState(false);
|
|
14472
|
+
const [createName, setCreateName] = React79.useState("");
|
|
14473
|
+
const [renameTarget, setRenameTarget] = React79.useState(null);
|
|
14474
|
+
const [renameValue, setRenameValue] = React79.useState("");
|
|
14475
|
+
const [deleteTarget, setDeleteTarget] = React79.useState(null);
|
|
14476
|
+
const uploadInputRef = React79.useRef(null);
|
|
14477
|
+
const crumbFolders = React79.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
14478
|
+
const subfolders = React79.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
14479
|
+
const currentFiles = React79.useMemo(
|
|
14459
14480
|
() => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
|
|
14460
14481
|
[files, currentFolderId]
|
|
14461
14482
|
);
|
|
@@ -14687,8 +14708,8 @@ function BreadcrumbCrumb({
|
|
|
14687
14708
|
isDropTarget,
|
|
14688
14709
|
onDropPayload
|
|
14689
14710
|
}) {
|
|
14690
|
-
const [over, setOver] =
|
|
14691
|
-
const dragCounter =
|
|
14711
|
+
const [over, setOver] = React79.useState(false);
|
|
14712
|
+
const dragCounter = React79.useRef(0);
|
|
14692
14713
|
const dropHandlers = isDropTarget ? {
|
|
14693
14714
|
onDragEnter: (e) => {
|
|
14694
14715
|
if (!hasInternalPayload(e)) return;
|
|
@@ -14717,7 +14738,7 @@ function BreadcrumbCrumb({
|
|
|
14717
14738
|
}
|
|
14718
14739
|
|
|
14719
14740
|
// src/kits/query.ts
|
|
14720
|
-
import * as
|
|
14741
|
+
import * as React80 from "react";
|
|
14721
14742
|
|
|
14722
14743
|
// src/kits/queryUrl.ts
|
|
14723
14744
|
var historyUrlAdapter = {
|
|
@@ -14855,38 +14876,38 @@ function requestFor(params, query, paging, after) {
|
|
|
14855
14876
|
}
|
|
14856
14877
|
var toError = (e) => e instanceof Error ? e : new Error(String(e));
|
|
14857
14878
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey, paging = "page", url }) {
|
|
14858
|
-
const [base] =
|
|
14879
|
+
const [base] = React80.useState(() => {
|
|
14859
14880
|
const store = PREFS || window.PlannerPrefs;
|
|
14860
14881
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
14861
14882
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
14862
14883
|
});
|
|
14863
|
-
const [mountParams] =
|
|
14864
|
-
const address =
|
|
14865
|
-
const [query, setQuery] =
|
|
14866
|
-
const savePref =
|
|
14884
|
+
const [mountParams] = React80.useState(() => url ? (url.adapter ?? historyUrlAdapter).read() : null);
|
|
14885
|
+
const address = React80.useRef(mountParams);
|
|
14886
|
+
const [query, setQuery] = React80.useState(() => url && mountParams ? readQueryFromUrl(mountParams, url.scope, base, paging) : base);
|
|
14887
|
+
const savePref = React80.useCallback((patch2) => {
|
|
14867
14888
|
const store = PREFS || window.PlannerPrefs;
|
|
14868
14889
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
14869
14890
|
}, [prefsKey]);
|
|
14870
|
-
const [res, setRes] =
|
|
14871
|
-
const [loading, setLoading] =
|
|
14872
|
-
const [loadingMore, setLoadingMore] =
|
|
14873
|
-
const [failure, setFailure] =
|
|
14874
|
-
const [reloadToken, setReloadToken] =
|
|
14875
|
-
const moreController =
|
|
14891
|
+
const [res, setRes] = React80.useState(null);
|
|
14892
|
+
const [loading, setLoading] = React80.useState(true);
|
|
14893
|
+
const [loadingMore, setLoadingMore] = React80.useState(false);
|
|
14894
|
+
const [failure, setFailure] = React80.useState(null);
|
|
14895
|
+
const [reloadToken, setReloadToken] = React80.useState(0);
|
|
14896
|
+
const moreController = React80.useRef(null);
|
|
14876
14897
|
const depKey = (deps || []).join("|");
|
|
14877
14898
|
const paramKey = JSON.stringify(params || {});
|
|
14878
14899
|
const queryKey = JSON.stringify(query);
|
|
14879
|
-
const lifetime =
|
|
14880
|
-
|
|
14900
|
+
const lifetime = React80.useRef(null);
|
|
14901
|
+
React80.useEffect(() => {
|
|
14881
14902
|
const controller = new AbortController();
|
|
14882
14903
|
lifetime.current = controller;
|
|
14883
14904
|
return () => controller.abort();
|
|
14884
14905
|
}, []);
|
|
14885
|
-
const latest =
|
|
14886
|
-
|
|
14906
|
+
const latest = React80.useRef({ res, loading, query, params, endpoint, url, base });
|
|
14907
|
+
React80.useLayoutEffect(() => {
|
|
14887
14908
|
latest.current = { res, loading, query, params, endpoint, url, base };
|
|
14888
14909
|
});
|
|
14889
|
-
|
|
14910
|
+
React80.useEffect(() => {
|
|
14890
14911
|
const controller = new AbortController();
|
|
14891
14912
|
const { signal } = controller;
|
|
14892
14913
|
setLoading(true);
|
|
@@ -14922,7 +14943,7 @@ function useServerTable({ endpoint, params, defaults, deps, prefsKey, paging = "
|
|
|
14922
14943
|
};
|
|
14923
14944
|
}, [endpoint, queryKey, paramKey, depKey, paging, reloadToken]);
|
|
14924
14945
|
const adapter = url ? url.adapter ?? historyUrlAdapter : null;
|
|
14925
|
-
|
|
14946
|
+
React80.useEffect(() => {
|
|
14926
14947
|
if (!adapter) return;
|
|
14927
14948
|
return adapter.subscribe((params2) => {
|
|
14928
14949
|
const { url: u, base: b } = latest.current;
|
|
@@ -15272,12 +15293,12 @@ function createVersionStore(initialState, options) {
|
|
|
15272
15293
|
}
|
|
15273
15294
|
|
|
15274
15295
|
// src/kits/documentTitle.ts
|
|
15275
|
-
import * as
|
|
15296
|
+
import * as React81 from "react";
|
|
15276
15297
|
function formatDocumentTitle(routeTitle, appName) {
|
|
15277
15298
|
return [routeTitle, appName, "Flytedesk"].filter((part2) => !!part2 && part2.length > 0).join(" \xB7 ");
|
|
15278
15299
|
}
|
|
15279
15300
|
function useDocumentTitle(routeTitle, appName) {
|
|
15280
|
-
|
|
15301
|
+
React81.useEffect(() => {
|
|
15281
15302
|
if (typeof document === "undefined") return;
|
|
15282
15303
|
document.title = formatDocumentTitle(routeTitle, appName);
|
|
15283
15304
|
}, [routeTitle, appName]);
|