@flytedan/flytebot-design-system 0.51.2 → 0.51.4
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 +518 -459
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -6
- package/dist/index.d.ts +27 -6
- package/dist/index.js +516 -459
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components.css +28 -24
package/dist/index.js
CHANGED
|
@@ -1123,7 +1123,60 @@ function LoadingRegion({
|
|
|
1123
1123
|
}
|
|
1124
1124
|
|
|
1125
1125
|
// src/components/loading/JobTray.tsx
|
|
1126
|
+
import * as React10 from "react";
|
|
1127
|
+
|
|
1128
|
+
// src/kits/cornerStack.tsx
|
|
1126
1129
|
import * as React9 from "react";
|
|
1130
|
+
import { createPortal as createPortal4 } from "react-dom";
|
|
1131
|
+
var SLOTS = ["jobs", "toasts"];
|
|
1132
|
+
var references = /* @__PURE__ */ new Map();
|
|
1133
|
+
var host = null;
|
|
1134
|
+
var slotElements = /* @__PURE__ */ new Map();
|
|
1135
|
+
function createHost() {
|
|
1136
|
+
const stack = document.createElement("div");
|
|
1137
|
+
stack.className = "fd-corner-stack";
|
|
1138
|
+
stack.style.zIndex = String(OVERLAY_CEILING);
|
|
1139
|
+
for (const slot of SLOTS) {
|
|
1140
|
+
const element = document.createElement("div");
|
|
1141
|
+
element.className = "fd-corner-stack-slot";
|
|
1142
|
+
element.dataset.cornerStackSlot = slot;
|
|
1143
|
+
stack.appendChild(element);
|
|
1144
|
+
slotElements.set(slot, element);
|
|
1145
|
+
}
|
|
1146
|
+
document.body.appendChild(stack);
|
|
1147
|
+
return stack;
|
|
1148
|
+
}
|
|
1149
|
+
function acquire(slot) {
|
|
1150
|
+
host ??= createHost();
|
|
1151
|
+
references.set(slot, (references.get(slot) ?? 0) + 1);
|
|
1152
|
+
return slotElements.get(slot);
|
|
1153
|
+
}
|
|
1154
|
+
function release(slot) {
|
|
1155
|
+
const remaining = (references.get(slot) ?? 1) - 1;
|
|
1156
|
+
if (remaining > 0) references.set(slot, remaining);
|
|
1157
|
+
else references.delete(slot);
|
|
1158
|
+
if (references.size === 0 && host) {
|
|
1159
|
+
host.remove();
|
|
1160
|
+
host = null;
|
|
1161
|
+
slotElements.clear();
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
var useSlotEffect = typeof document === "undefined" ? React9.useEffect : React9.useLayoutEffect;
|
|
1165
|
+
function useCornerStackSlot(slot) {
|
|
1166
|
+
const [element, setElement] = React9.useState(null);
|
|
1167
|
+
useSlotEffect(() => {
|
|
1168
|
+
setElement(acquire(slot));
|
|
1169
|
+
return () => {
|
|
1170
|
+
release(slot);
|
|
1171
|
+
setElement(null);
|
|
1172
|
+
};
|
|
1173
|
+
}, [slot]);
|
|
1174
|
+
return element;
|
|
1175
|
+
}
|
|
1176
|
+
function CornerStackPortal({ slot, children }) {
|
|
1177
|
+
const element = useCornerStackSlot(slot);
|
|
1178
|
+
return element ? createPortal4(children, element) : null;
|
|
1179
|
+
}
|
|
1127
1180
|
|
|
1128
1181
|
// src/components/loading/ProgressBar.tsx
|
|
1129
1182
|
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
@@ -1167,9 +1220,9 @@ function announcementFor(job) {
|
|
|
1167
1220
|
return title + ": in progress";
|
|
1168
1221
|
}
|
|
1169
1222
|
function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
|
|
1170
|
-
const [announcement, setAnnouncement] =
|
|
1171
|
-
const prevStatuses =
|
|
1172
|
-
|
|
1223
|
+
const [announcement, setAnnouncement] = React10.useState("");
|
|
1224
|
+
const prevStatuses = React10.useRef({});
|
|
1225
|
+
React10.useEffect(() => {
|
|
1173
1226
|
let next = "";
|
|
1174
1227
|
for (const job of jobs2) {
|
|
1175
1228
|
if (prevStatuses.current[job.id] !== job.status) {
|
|
@@ -1182,10 +1235,10 @@ function JobTray({ jobs: jobs2, onDismiss, className = "" }) {
|
|
|
1182
1235
|
if (next) setAnnouncement(next);
|
|
1183
1236
|
}, [jobs2]);
|
|
1184
1237
|
if (jobs2.length === 0) return null;
|
|
1185
|
-
return /* @__PURE__ */ jsxs11("div", { className: ["fd-job-tray", className].filter(Boolean).join(" "), children: [
|
|
1238
|
+
return /* @__PURE__ */ jsx15(CornerStackPortal, { slot: "jobs", children: /* @__PURE__ */ jsxs11("div", { className: ["fd-job-tray", className].filter(Boolean).join(" "), children: [
|
|
1186
1239
|
/* @__PURE__ */ jsx15("span", { className: "fd-sr", role: "status", "aria-live": "polite", children: announcement }),
|
|
1187
1240
|
jobs2.map((job) => /* @__PURE__ */ jsx15(JobCard, { job, onDismiss }, job.id))
|
|
1188
|
-
] });
|
|
1241
|
+
] }) });
|
|
1189
1242
|
}
|
|
1190
1243
|
function JobCard({ job, onDismiss }) {
|
|
1191
1244
|
const title = textOf(job.title) || "Job";
|
|
@@ -1220,7 +1273,7 @@ function JobCard({ job, onDismiss }) {
|
|
|
1220
1273
|
}
|
|
1221
1274
|
|
|
1222
1275
|
// src/components/loading/PhasedProgress.tsx
|
|
1223
|
-
import * as
|
|
1276
|
+
import * as React11 from "react";
|
|
1224
1277
|
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1225
1278
|
var ICON = {
|
|
1226
1279
|
pending: "ph-circle",
|
|
@@ -1233,9 +1286,9 @@ function textOf2(node) {
|
|
|
1233
1286
|
return "";
|
|
1234
1287
|
}
|
|
1235
1288
|
function PhasedProgress({ phases, summary, className = "" }) {
|
|
1236
|
-
const [announcement, setAnnouncement] =
|
|
1237
|
-
const prevStatuses =
|
|
1238
|
-
|
|
1289
|
+
const [announcement, setAnnouncement] = React11.useState("");
|
|
1290
|
+
const prevStatuses = React11.useRef({});
|
|
1291
|
+
React11.useEffect(() => {
|
|
1239
1292
|
let next = "";
|
|
1240
1293
|
for (const phase of phases) {
|
|
1241
1294
|
if (prevStatuses.current[phase.id] !== phase.status) {
|
|
@@ -1305,12 +1358,12 @@ function Spinner({ size = "md", label = "Loading", className = "", style, ...res
|
|
|
1305
1358
|
}
|
|
1306
1359
|
|
|
1307
1360
|
// src/components/navigation/SidebarNav.tsx
|
|
1308
|
-
import * as
|
|
1361
|
+
import * as React12 from "react";
|
|
1309
1362
|
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1310
1363
|
function Tip({ label, children }) {
|
|
1311
1364
|
return /* @__PURE__ */ jsx19("span", { title: label, style: { display: "inline-flex", flex: "none" }, children });
|
|
1312
1365
|
}
|
|
1313
|
-
var SidebarNav =
|
|
1366
|
+
var SidebarNav = React12.forwardRef(function SidebarNav2({ brand, groups = [], current: current2, onNavigate, footer, open: open2 = false, className = "", ...rest }, ref) {
|
|
1314
1367
|
return /* @__PURE__ */ jsxs13(
|
|
1315
1368
|
"nav",
|
|
1316
1369
|
{
|
|
@@ -1349,13 +1402,13 @@ var SidebarNav = React11.forwardRef(function SidebarNav2({ brand, groups = [], c
|
|
|
1349
1402
|
});
|
|
1350
1403
|
|
|
1351
1404
|
// src/components/navigation/Topbar.tsx
|
|
1352
|
-
import * as
|
|
1405
|
+
import * as React13 from "react";
|
|
1353
1406
|
import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1354
1407
|
function useIsNarrow(breakpoint) {
|
|
1355
|
-
const [narrow, setNarrow] =
|
|
1408
|
+
const [narrow, setNarrow] = React13.useState(
|
|
1356
1409
|
() => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
1357
1410
|
);
|
|
1358
|
-
|
|
1411
|
+
React13.useEffect(() => {
|
|
1359
1412
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1360
1413
|
const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
1361
1414
|
const apply = () => setNarrow(mq.matches);
|
|
@@ -1376,11 +1429,11 @@ function Topbar({
|
|
|
1376
1429
|
...rest
|
|
1377
1430
|
}) {
|
|
1378
1431
|
const narrow = useIsNarrow(overflowBreakpoint);
|
|
1379
|
-
const [moreOpen, setMoreOpen] =
|
|
1380
|
-
const moreRef =
|
|
1432
|
+
const [moreOpen, setMoreOpen] = React13.useState(false);
|
|
1433
|
+
const moreRef = React13.useRef(null);
|
|
1381
1434
|
return /* @__PURE__ */ jsxs14("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
|
|
1382
1435
|
onMenu ? /* @__PURE__ */ jsx20("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ jsx20("i", { className: "ph ph-list" }) }) : null,
|
|
1383
|
-
/* @__PURE__ */ jsx20("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs14(
|
|
1436
|
+
/* @__PURE__ */ jsx20("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs14(React13.Fragment, { children: [
|
|
1384
1437
|
i > 0 ? /* @__PURE__ */ jsx20("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
|
|
1385
1438
|
i === crumbs.length - 1 ? (
|
|
1386
1439
|
// MP-141: the current crumb mixes a static route label with (usually) a
|
|
@@ -1433,25 +1486,25 @@ function Topbar({
|
|
|
1433
1486
|
}
|
|
1434
1487
|
|
|
1435
1488
|
// src/kits/useResponsiveRail.ts
|
|
1436
|
-
import * as
|
|
1489
|
+
import * as React14 from "react";
|
|
1437
1490
|
function matchesBreakpoint(breakpoint) {
|
|
1438
1491
|
return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches;
|
|
1439
1492
|
}
|
|
1440
1493
|
function useResponsiveRail(options = {}) {
|
|
1441
1494
|
const { breakpoint = 1024, initialOpen = true, onPersist } = options;
|
|
1442
|
-
const navRef =
|
|
1443
|
-
const [overlay, setOverlay] =
|
|
1444
|
-
const [open2, setOpenRaw] =
|
|
1445
|
-
const setOpen =
|
|
1495
|
+
const navRef = React14.useRef(null);
|
|
1496
|
+
const [overlay, setOverlay] = React14.useState(() => matchesBreakpoint(breakpoint));
|
|
1497
|
+
const [open2, setOpenRaw] = React14.useState(() => matchesBreakpoint(breakpoint) ? false : initialOpen);
|
|
1498
|
+
const setOpen = React14.useCallback(
|
|
1446
1499
|
(value) => {
|
|
1447
1500
|
setOpenRaw(value);
|
|
1448
1501
|
if (!matchesBreakpoint(breakpoint)) onPersist?.(value);
|
|
1449
1502
|
},
|
|
1450
1503
|
[breakpoint, onPersist]
|
|
1451
1504
|
);
|
|
1452
|
-
const toggle =
|
|
1453
|
-
const close2 =
|
|
1454
|
-
|
|
1505
|
+
const toggle = React14.useCallback(() => setOpen(!open2), [open2, setOpen]);
|
|
1506
|
+
const close2 = React14.useCallback(() => setOpenRaw(false), []);
|
|
1507
|
+
React14.useEffect(() => {
|
|
1455
1508
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1456
1509
|
const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
1457
1510
|
const handler = (e) => {
|
|
@@ -1462,7 +1515,7 @@ function useResponsiveRail(options = {}) {
|
|
|
1462
1515
|
return () => mq.removeEventListener("change", handler);
|
|
1463
1516
|
}, [breakpoint]);
|
|
1464
1517
|
const layer = useStackedLayer({ active: overlay && open2, containerRef: navRef, trap: true, onEscape: close2 });
|
|
1465
|
-
|
|
1518
|
+
React14.useEffect(() => {
|
|
1466
1519
|
if (!overlay || !open2) return;
|
|
1467
1520
|
const previousOverflow = document.body.style.overflow;
|
|
1468
1521
|
document.body.style.overflow = "hidden";
|
|
@@ -1820,15 +1873,15 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
|
|
|
1820
1873
|
}
|
|
1821
1874
|
|
|
1822
1875
|
// src/components/feedback/ToastProvider.tsx
|
|
1823
|
-
import * as
|
|
1876
|
+
import * as React15 from "react";
|
|
1824
1877
|
import { jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1825
1878
|
var DEFAULT_TOAST_DURATION_MS = 5e3;
|
|
1826
|
-
var ToastContext =
|
|
1879
|
+
var ToastContext = React15.createContext(null);
|
|
1827
1880
|
function ToastProvider({ children }) {
|
|
1828
|
-
const [items, setItems] =
|
|
1829
|
-
const timers =
|
|
1830
|
-
const nextId =
|
|
1831
|
-
const dismiss =
|
|
1881
|
+
const [items, setItems] = React15.useState([]);
|
|
1882
|
+
const timers = React15.useRef(/* @__PURE__ */ new Map());
|
|
1883
|
+
const nextId = React15.useRef(1);
|
|
1884
|
+
const dismiss = React15.useCallback((id) => {
|
|
1832
1885
|
setItems((current2) => current2.filter((item) => item.id !== id));
|
|
1833
1886
|
const timer = timers.current.get(id);
|
|
1834
1887
|
if (timer !== void 0) {
|
|
@@ -1836,7 +1889,7 @@ function ToastProvider({ children }) {
|
|
|
1836
1889
|
timers.current.delete(id);
|
|
1837
1890
|
}
|
|
1838
1891
|
}, []);
|
|
1839
|
-
const show =
|
|
1892
|
+
const show = React15.useCallback(
|
|
1840
1893
|
(title, options = {}) => {
|
|
1841
1894
|
const { tone = "success", duration = DEFAULT_TOAST_DURATION_MS } = options;
|
|
1842
1895
|
const id = nextId.current++;
|
|
@@ -1845,38 +1898,38 @@ function ToastProvider({ children }) {
|
|
|
1845
1898
|
},
|
|
1846
1899
|
[dismiss]
|
|
1847
1900
|
);
|
|
1848
|
-
|
|
1901
|
+
React15.useEffect(() => {
|
|
1849
1902
|
const pending = timers.current;
|
|
1850
1903
|
return () => {
|
|
1851
1904
|
pending.forEach(clearTimeout);
|
|
1852
1905
|
pending.clear();
|
|
1853
1906
|
};
|
|
1854
1907
|
}, []);
|
|
1855
|
-
const api =
|
|
1908
|
+
const api = React15.useMemo(() => ({ show }), [show]);
|
|
1856
1909
|
return /* @__PURE__ */ jsxs25(ToastContext.Provider, { value: api, children: [
|
|
1857
1910
|
children,
|
|
1858
|
-
/* @__PURE__ */ jsx32("div", { className: "fd-toast-region", "aria-live": "polite",
|
|
1911
|
+
/* @__PURE__ */ jsx32(CornerStackPortal, { slot: "toasts", children: /* @__PURE__ */ jsx32("div", { className: "fd-toast-region", "aria-live": "polite", children: items.map((item) => /* @__PURE__ */ jsx32(Toast, { title: item.title, tone: item.tone, onDismiss: () => dismiss(item.id) }, item.id)) }) })
|
|
1859
1912
|
] });
|
|
1860
1913
|
}
|
|
1861
1914
|
function useToast() {
|
|
1862
|
-
const api =
|
|
1915
|
+
const api = React15.useContext(ToastContext);
|
|
1863
1916
|
if (!api) throw new Error("useToast must be used inside a <ToastProvider>");
|
|
1864
1917
|
return api;
|
|
1865
1918
|
}
|
|
1866
1919
|
|
|
1867
1920
|
// src/components/feedback/Tooltip.tsx
|
|
1868
|
-
import * as
|
|
1921
|
+
import * as React16 from "react";
|
|
1869
1922
|
import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1870
1923
|
var CLOSE_DELAY_MS = 120;
|
|
1871
1924
|
function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
1872
|
-
const anchorRef =
|
|
1873
|
-
const bubbleRef =
|
|
1874
|
-
const [reason, setReason] =
|
|
1875
|
-
const closeTimer =
|
|
1876
|
-
const id =
|
|
1925
|
+
const anchorRef = React16.useRef(null);
|
|
1926
|
+
const bubbleRef = React16.useRef(null);
|
|
1927
|
+
const [reason, setReason] = React16.useState(null);
|
|
1928
|
+
const closeTimer = React16.useRef(null);
|
|
1929
|
+
const id = React16.useId();
|
|
1877
1930
|
const descId = id + "-desc";
|
|
1878
1931
|
const open2 = reason != null;
|
|
1879
|
-
const cancelClose =
|
|
1932
|
+
const cancelClose = React16.useCallback(() => {
|
|
1880
1933
|
if (closeTimer.current) {
|
|
1881
1934
|
clearTimeout(closeTimer.current);
|
|
1882
1935
|
closeTimer.current = null;
|
|
@@ -1886,7 +1939,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1886
1939
|
cancelClose();
|
|
1887
1940
|
setReason(why);
|
|
1888
1941
|
};
|
|
1889
|
-
const hide =
|
|
1942
|
+
const hide = React16.useCallback(() => {
|
|
1890
1943
|
cancelClose();
|
|
1891
1944
|
setReason(null);
|
|
1892
1945
|
}, [cancelClose]);
|
|
@@ -1901,7 +1954,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1901
1954
|
setReason((r) => r === "hover" ? null : r);
|
|
1902
1955
|
}, CLOSE_DELAY_MS);
|
|
1903
1956
|
};
|
|
1904
|
-
|
|
1957
|
+
React16.useEffect(() => cancelClose, [cancelClose]);
|
|
1905
1958
|
const pos = usePopoverPosition(open2, anchorRef, {
|
|
1906
1959
|
placement: placement === "bottom" ? "bottom-center" : "top-center",
|
|
1907
1960
|
offset: 8,
|
|
@@ -1912,7 +1965,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1912
1965
|
});
|
|
1913
1966
|
const layer = useStackedLayer({ active: open2, containerRef: bubbleRef, onEscape: hide, returnFocus: false });
|
|
1914
1967
|
const zIndex = useLayerZIndex(layer);
|
|
1915
|
-
|
|
1968
|
+
React16.useEffect(() => {
|
|
1916
1969
|
if (!open2) return;
|
|
1917
1970
|
const away = (e) => {
|
|
1918
1971
|
const t = e.target;
|
|
@@ -1933,7 +1986,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1933
1986
|
}
|
|
1934
1987
|
if (keyboard) show("focus");
|
|
1935
1988
|
};
|
|
1936
|
-
const described =
|
|
1989
|
+
const described = React16.isValidElement(children) ? React16.cloneElement(children, {
|
|
1937
1990
|
"aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
|
|
1938
1991
|
}) : children;
|
|
1939
1992
|
return /* @__PURE__ */ jsxs26(
|
|
@@ -1941,7 +1994,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1941
1994
|
{
|
|
1942
1995
|
ref: anchorRef,
|
|
1943
1996
|
className: "fd-tooltip-anchor",
|
|
1944
|
-
"aria-describedby":
|
|
1997
|
+
"aria-describedby": React16.isValidElement(children) ? void 0 : descId,
|
|
1945
1998
|
onPointerEnter: (e) => {
|
|
1946
1999
|
if (isMouse(e)) hover();
|
|
1947
2000
|
},
|
|
@@ -1985,16 +2038,16 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1985
2038
|
}
|
|
1986
2039
|
|
|
1987
2040
|
// src/components/data/AnimNum.tsx
|
|
1988
|
-
import * as
|
|
2041
|
+
import * as React17 from "react";
|
|
1989
2042
|
import { Fragment as Fragment6, jsx as jsx34 } from "react/jsx-runtime";
|
|
1990
2043
|
function shouldSkipEasing() {
|
|
1991
2044
|
if (typeof document !== "undefined" && document.hidden) return true;
|
|
1992
2045
|
return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
|
|
1993
2046
|
}
|
|
1994
2047
|
function AnimNum({ value, format, duration = 550 }) {
|
|
1995
|
-
const [display, setDisplay] =
|
|
1996
|
-
const prev =
|
|
1997
|
-
|
|
2048
|
+
const [display, setDisplay] = React17.useState(value);
|
|
2049
|
+
const prev = React17.useRef(value);
|
|
2050
|
+
React17.useEffect(() => {
|
|
1998
2051
|
const from = prev.current;
|
|
1999
2052
|
const to = value;
|
|
2000
2053
|
prev.current = to;
|
|
@@ -2022,14 +2075,14 @@ function AnimNum({ value, format, duration = 550 }) {
|
|
|
2022
2075
|
}
|
|
2023
2076
|
|
|
2024
2077
|
// src/components/data/TrendChart.tsx
|
|
2025
|
-
import * as
|
|
2078
|
+
import * as React20 from "react";
|
|
2026
2079
|
|
|
2027
2080
|
// src/components/useMeasuredWidth.ts
|
|
2028
|
-
import * as
|
|
2081
|
+
import * as React18 from "react";
|
|
2029
2082
|
function useMeasuredWidth(fallback) {
|
|
2030
|
-
const [element, setElement] =
|
|
2031
|
-
const [width, setWidth] =
|
|
2032
|
-
|
|
2083
|
+
const [element, setElement] = React18.useState(null);
|
|
2084
|
+
const [width, setWidth] = React18.useState(fallback);
|
|
2085
|
+
React18.useLayoutEffect(() => {
|
|
2033
2086
|
if (!element || typeof ResizeObserver === "undefined") return;
|
|
2034
2087
|
const measure = () => {
|
|
2035
2088
|
const measured = Math.round(element.getBoundingClientRect().width);
|
|
@@ -2044,7 +2097,7 @@ function useMeasuredWidth(fallback) {
|
|
|
2044
2097
|
}
|
|
2045
2098
|
|
|
2046
2099
|
// src/components/data/SegmentedMeter.tsx
|
|
2047
|
-
import * as
|
|
2100
|
+
import * as React19 from "react";
|
|
2048
2101
|
|
|
2049
2102
|
// src/kits/files.ts
|
|
2050
2103
|
function formatBytes(n) {
|
|
@@ -2249,7 +2302,7 @@ function SegmentedMeter({
|
|
|
2249
2302
|
const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
|
|
2250
2303
|
const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
|
|
2251
2304
|
const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
|
|
2252
|
-
const generatedId =
|
|
2305
|
+
const generatedId = React19.useId();
|
|
2253
2306
|
const uid2 = id || generatedId;
|
|
2254
2307
|
return /* @__PURE__ */ jsxs27("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
|
|
2255
2308
|
label || showTotal ? /* @__PURE__ */ jsxs27("div", { className: "fd-segmeter-head", children: [
|
|
@@ -2400,8 +2453,8 @@ function TrendChart({
|
|
|
2400
2453
|
onRetry,
|
|
2401
2454
|
className = ""
|
|
2402
2455
|
}) {
|
|
2403
|
-
const [activeId, setActiveId] =
|
|
2404
|
-
const [pointTip, setPointTip] =
|
|
2456
|
+
const [activeId, setActiveId] = React20.useState(null);
|
|
2457
|
+
const [pointTip, setPointTip] = React20.useState(null);
|
|
2405
2458
|
const isEmpty = state === "ready" && (!categories.length || !series.length || series.every((s) => !s.values.length));
|
|
2406
2459
|
const effectiveState = isEmpty ? "empty" : state;
|
|
2407
2460
|
const [plotRef, VBW] = useMeasuredWidth(INITIAL_WIDTH);
|
|
@@ -2515,7 +2568,7 @@ function TrendChart({
|
|
|
2515
2568
|
}
|
|
2516
2569
|
|
|
2517
2570
|
// src/components/data/DonutChart.tsx
|
|
2518
|
-
import * as
|
|
2571
|
+
import * as React21 from "react";
|
|
2519
2572
|
import { jsx as jsx38, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2520
2573
|
function DonutChart({
|
|
2521
2574
|
segments,
|
|
@@ -2530,7 +2583,7 @@ function DonutChart({
|
|
|
2530
2583
|
onRetry,
|
|
2531
2584
|
className = ""
|
|
2532
2585
|
}) {
|
|
2533
|
-
const [activeId, setActiveId] =
|
|
2586
|
+
const [activeId, setActiveId] = React21.useState(null);
|
|
2534
2587
|
const items = segments.filter((s) => Number(s.value) > 0);
|
|
2535
2588
|
const total = items.reduce((n, s) => n + Number(s.value), 0);
|
|
2536
2589
|
const isEmpty = state === "ready" && (!items.length || total <= 0);
|
|
@@ -2622,7 +2675,7 @@ function DonutChart({
|
|
|
2622
2675
|
}
|
|
2623
2676
|
|
|
2624
2677
|
// src/components/data/BarList.tsx
|
|
2625
|
-
import * as
|
|
2678
|
+
import * as React22 from "react";
|
|
2626
2679
|
import { jsx as jsx39, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2627
2680
|
function BarList({
|
|
2628
2681
|
rows,
|
|
@@ -2637,7 +2690,7 @@ function BarList({
|
|
|
2637
2690
|
onRetry,
|
|
2638
2691
|
className = ""
|
|
2639
2692
|
}) {
|
|
2640
|
-
const ordered =
|
|
2693
|
+
const ordered = React22.useMemo(() => {
|
|
2641
2694
|
const list = sort ? [...rows].sort((a, b) => Number(b.value) - Number(a.value)) : rows;
|
|
2642
2695
|
return maxRows ? list.slice(0, maxRows) : list;
|
|
2643
2696
|
}, [rows, sort, maxRows]);
|
|
@@ -2779,7 +2832,7 @@ function FunnelChart({
|
|
|
2779
2832
|
}
|
|
2780
2833
|
|
|
2781
2834
|
// src/components/data/Clamp.tsx
|
|
2782
|
-
import * as
|
|
2835
|
+
import * as React23 from "react";
|
|
2783
2836
|
import { jsx as jsx41, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2784
2837
|
function Clamp({
|
|
2785
2838
|
children,
|
|
@@ -2791,16 +2844,16 @@ function Clamp({
|
|
|
2791
2844
|
onToggle,
|
|
2792
2845
|
className = ""
|
|
2793
2846
|
}) {
|
|
2794
|
-
const [open2, setOpen] =
|
|
2795
|
-
const [overflows, setOverflows] =
|
|
2796
|
-
const bodyRef =
|
|
2797
|
-
const charClamped =
|
|
2847
|
+
const [open2, setOpen] = React23.useState(false);
|
|
2848
|
+
const [overflows, setOverflows] = React23.useState(false);
|
|
2849
|
+
const bodyRef = React23.useRef(null);
|
|
2850
|
+
const charClamped = React23.useMemo(() => {
|
|
2798
2851
|
if (open2 || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
|
|
2799
2852
|
const cut = text.slice(0, maxChars);
|
|
2800
2853
|
const at = cut.lastIndexOf(" ");
|
|
2801
2854
|
return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
2802
2855
|
}, [text, maxChars, open2]);
|
|
2803
|
-
|
|
2856
|
+
React23.useLayoutEffect(() => {
|
|
2804
2857
|
const node = bodyRef.current;
|
|
2805
2858
|
if (maxChars || !node || !maxHeight) return;
|
|
2806
2859
|
const measure = () => {
|
|
@@ -2939,16 +2992,16 @@ function DataTable({
|
|
|
2939
2992
|
}
|
|
2940
2993
|
|
|
2941
2994
|
// src/components/data/FilterBar.tsx
|
|
2942
|
-
import * as
|
|
2995
|
+
import * as React29 from "react";
|
|
2943
2996
|
|
|
2944
2997
|
// src/components/forms/NumberInput.tsx
|
|
2945
|
-
import * as
|
|
2998
|
+
import * as React26 from "react";
|
|
2946
2999
|
|
|
2947
3000
|
// src/components/forms/field.tsx
|
|
2948
|
-
import * as
|
|
3001
|
+
import * as React24 from "react";
|
|
2949
3002
|
import { jsx as jsx44, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
2950
3003
|
function useFieldId(id) {
|
|
2951
|
-
const generated =
|
|
3004
|
+
const generated = React24.useId();
|
|
2952
3005
|
return id || generated;
|
|
2953
3006
|
}
|
|
2954
3007
|
function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
|
|
@@ -2967,10 +3020,10 @@ function HiddenFieldLabel({ id, children }) {
|
|
|
2967
3020
|
}
|
|
2968
3021
|
|
|
2969
3022
|
// src/components/useLatest.ts
|
|
2970
|
-
import * as
|
|
3023
|
+
import * as React25 from "react";
|
|
2971
3024
|
function useLatest(value) {
|
|
2972
|
-
const ref =
|
|
2973
|
-
|
|
3025
|
+
const ref = React25.useRef(value);
|
|
3026
|
+
React25.useInsertionEffect(() => {
|
|
2974
3027
|
ref.current = value;
|
|
2975
3028
|
});
|
|
2976
3029
|
return ref;
|
|
@@ -3053,20 +3106,20 @@ function NumberInput({
|
|
|
3053
3106
|
const n = typeof v === "number" ? v : parseNumberText(v);
|
|
3054
3107
|
return n == null || Number.isNaN(n) ? null : n;
|
|
3055
3108
|
};
|
|
3056
|
-
const [text, setText] =
|
|
3057
|
-
const [editing, setEditing] =
|
|
3109
|
+
const [text, setText] = React26.useState(() => toText(value));
|
|
3110
|
+
const [editing, setEditing] = React26.useState(false);
|
|
3058
3111
|
const parsed = parseNumberText(text);
|
|
3059
3112
|
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;
|
|
3060
3113
|
const valid = invalidMessage == null;
|
|
3061
|
-
const committedRef =
|
|
3114
|
+
const committedRef = React26.useRef(toNumber(value));
|
|
3062
3115
|
const onChangeRef = useLatest(onChange);
|
|
3063
3116
|
const onValidityChangeRef = useLatest(onValidityChange);
|
|
3064
|
-
const focusedRef =
|
|
3065
|
-
|
|
3117
|
+
const focusedRef = React26.useRef(false);
|
|
3118
|
+
React26.useEffect(() => {
|
|
3066
3119
|
committedRef.current = toNumber(value);
|
|
3067
3120
|
if (!focusedRef.current) setText(toText(value));
|
|
3068
3121
|
}, [value]);
|
|
3069
|
-
|
|
3122
|
+
React26.useLayoutEffect(() => {
|
|
3070
3123
|
onValidityChangeRef.current?.(valid);
|
|
3071
3124
|
}, [valid, onValidityChangeRef]);
|
|
3072
3125
|
const fire = (n) => {
|
|
@@ -3082,26 +3135,26 @@ function NumberInput({
|
|
|
3082
3135
|
return true;
|
|
3083
3136
|
};
|
|
3084
3137
|
const bumpRef = useLatest(bump);
|
|
3085
|
-
const holdTimer =
|
|
3086
|
-
const
|
|
3138
|
+
const holdTimer = React26.useRef(null);
|
|
3139
|
+
const release2 = () => {
|
|
3087
3140
|
if (holdTimer.current) clearTimeout(holdTimer.current);
|
|
3088
3141
|
holdTimer.current = null;
|
|
3089
3142
|
};
|
|
3090
3143
|
const hold = (direction) => {
|
|
3091
|
-
|
|
3144
|
+
release2();
|
|
3092
3145
|
bump(direction, step);
|
|
3093
3146
|
let repeats = 0;
|
|
3094
3147
|
const tick = () => {
|
|
3095
3148
|
repeats++;
|
|
3096
3149
|
if (!bumpRef.current(direction, repeats > HOLD_BIG_AFTER ? big : step)) {
|
|
3097
|
-
|
|
3150
|
+
release2();
|
|
3098
3151
|
return;
|
|
3099
3152
|
}
|
|
3100
3153
|
holdTimer.current = setTimeout(tick, holdInterval(repeats));
|
|
3101
3154
|
};
|
|
3102
3155
|
holdTimer.current = setTimeout(tick, HOLD_DELAY_MS);
|
|
3103
3156
|
};
|
|
3104
|
-
|
|
3157
|
+
React26.useEffect(() => () => {
|
|
3105
3158
|
if (holdTimer.current) clearTimeout(holdTimer.current);
|
|
3106
3159
|
}, []);
|
|
3107
3160
|
const current2 = committedRef.current;
|
|
@@ -3167,9 +3220,9 @@ function NumberInput({
|
|
|
3167
3220
|
"aria-label": stepperName("Decrease"),
|
|
3168
3221
|
disabled: disabled || noRange || current2 != null && current2 <= lo,
|
|
3169
3222
|
onPointerDown: () => hold(-1),
|
|
3170
|
-
onPointerUp:
|
|
3171
|
-
onPointerLeave:
|
|
3172
|
-
onPointerCancel:
|
|
3223
|
+
onPointerUp: release2,
|
|
3224
|
+
onPointerLeave: release2,
|
|
3225
|
+
onPointerCancel: release2,
|
|
3173
3226
|
onClick: (e) => {
|
|
3174
3227
|
if (e.detail === 0) bump(-1, step);
|
|
3175
3228
|
},
|
|
@@ -3184,9 +3237,9 @@ function NumberInput({
|
|
|
3184
3237
|
"aria-label": stepperName("Increase"),
|
|
3185
3238
|
disabled: disabled || noRange || current2 != null && current2 >= hi,
|
|
3186
3239
|
onPointerDown: () => hold(1),
|
|
3187
|
-
onPointerUp:
|
|
3188
|
-
onPointerLeave:
|
|
3189
|
-
onPointerCancel:
|
|
3240
|
+
onPointerUp: release2,
|
|
3241
|
+
onPointerLeave: release2,
|
|
3242
|
+
onPointerCancel: release2,
|
|
3190
3243
|
onClick: (e) => {
|
|
3191
3244
|
if (e.detail === 0) bump(1, step);
|
|
3192
3245
|
},
|
|
@@ -3204,7 +3257,7 @@ function NumberInput({
|
|
|
3204
3257
|
}
|
|
3205
3258
|
|
|
3206
3259
|
// src/components/forms/DatePicker.tsx
|
|
3207
|
-
import * as
|
|
3260
|
+
import * as React27 from "react";
|
|
3208
3261
|
import { jsx as jsx46, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3209
3262
|
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
3210
3263
|
var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
@@ -3237,10 +3290,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3237
3290
|
const today = /* @__PURE__ */ new Date();
|
|
3238
3291
|
const sel = range ? value || {} : { start: value, end: value };
|
|
3239
3292
|
const anchor = parse(sel.start) || parse(initialMonth) || today;
|
|
3240
|
-
const [vy, setVy] =
|
|
3241
|
-
const [vm, setVm] =
|
|
3242
|
-
const [mode2, setMode] =
|
|
3243
|
-
const [hover, setHover] =
|
|
3293
|
+
const [vy, setVy] = React27.useState(anchor.getFullYear());
|
|
3294
|
+
const [vm, setVm] = React27.useState(anchor.getMonth());
|
|
3295
|
+
const [mode2, setMode] = React27.useState("days");
|
|
3296
|
+
const [hover, setHover] = React27.useState(null);
|
|
3244
3297
|
const s = parse(sel.start), e = parse(sel.end);
|
|
3245
3298
|
const hoverEnd = range && s && !e && hover ? parse(hover) : null;
|
|
3246
3299
|
const inRange = (d) => {
|
|
@@ -3251,12 +3304,12 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3251
3304
|
const isEnd = (d) => !!e && iso(d) === iso(e);
|
|
3252
3305
|
const isEdge = (d) => isStart(d) || isEnd(d);
|
|
3253
3306
|
const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
|
|
3254
|
-
const [activeDate, setActiveDate] =
|
|
3307
|
+
const [activeDate, setActiveDate] = React27.useState(() => {
|
|
3255
3308
|
if (s) return s;
|
|
3256
3309
|
if (sameMonth(today, anchor.getFullYear(), anchor.getMonth())) return today;
|
|
3257
3310
|
return new Date(anchor.getFullYear(), anchor.getMonth(), 1);
|
|
3258
3311
|
});
|
|
3259
|
-
const calRef =
|
|
3312
|
+
const calRef = React27.useRef(null);
|
|
3260
3313
|
const pageToShow = (y, m) => {
|
|
3261
3314
|
const idx = y * 12 + m, firstIdx = vy * 12 + vm, secondIdx = firstIdx + 1;
|
|
3262
3315
|
if (idx === firstIdx || months > 1 && idx === secondIdx) return;
|
|
@@ -3273,7 +3326,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3273
3326
|
setActiveDate(next);
|
|
3274
3327
|
pageToShow(next.getFullYear(), next.getMonth());
|
|
3275
3328
|
};
|
|
3276
|
-
|
|
3329
|
+
React27.useEffect(() => {
|
|
3277
3330
|
const el = calRef.current?.querySelector('[data-iso="' + iso(activeDate) + '"]');
|
|
3278
3331
|
if (el) el.focus({ preventScroll: true });
|
|
3279
3332
|
}, [activeDate, vy, vm]);
|
|
@@ -3466,9 +3519,9 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
|
3466
3519
|
}
|
|
3467
3520
|
function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, "aria-label": hiddenLabel, ...rest }) {
|
|
3468
3521
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
|
|
3469
|
-
const [open2, setOpen] =
|
|
3470
|
-
const rootRef =
|
|
3471
|
-
const boxRef =
|
|
3522
|
+
const [open2, setOpen] = React27.useState(false);
|
|
3523
|
+
const rootRef = React27.useRef(null);
|
|
3524
|
+
const boxRef = React27.useRef(null);
|
|
3472
3525
|
const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
|
|
3473
3526
|
const toggle = () => {
|
|
3474
3527
|
if (!disabled) setOpen(!open2);
|
|
@@ -3557,9 +3610,9 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
|
|
|
3557
3610
|
}
|
|
3558
3611
|
|
|
3559
3612
|
// src/components/forms/listbox.ts
|
|
3560
|
-
import * as
|
|
3613
|
+
import * as React28 from "react";
|
|
3561
3614
|
function useListboxNav({ count, onSelect }) {
|
|
3562
|
-
const [active, setActive] =
|
|
3615
|
+
const [active, setActive] = React28.useState(-1);
|
|
3563
3616
|
return {
|
|
3564
3617
|
active,
|
|
3565
3618
|
setActive,
|
|
@@ -3572,7 +3625,7 @@ function useListboxNav({ count, onSelect }) {
|
|
|
3572
3625
|
};
|
|
3573
3626
|
}
|
|
3574
3627
|
function useListboxScrollIntoView(active, listRef, enabled) {
|
|
3575
|
-
|
|
3628
|
+
React28.useEffect(() => {
|
|
3576
3629
|
if (!enabled || active < 0 || !listRef.current) return;
|
|
3577
3630
|
const list = listRef.current;
|
|
3578
3631
|
const el = list.querySelector('[data-i="' + active + '"]');
|
|
@@ -3785,13 +3838,13 @@ function MultiSelectPanel({
|
|
|
3785
3838
|
onClose
|
|
3786
3839
|
}) {
|
|
3787
3840
|
const allowedOps = operatorsFor(field);
|
|
3788
|
-
const [draftOperator, setDraftOperator] =
|
|
3841
|
+
const [draftOperator, setDraftOperator] = React29.useState(value?.operator ?? allowedOps[0]);
|
|
3789
3842
|
const operator = allowedOps.length === 1 ? allowedOps[0] : value?.operator ?? draftOperator;
|
|
3790
3843
|
const selected = value?.values ?? [];
|
|
3791
3844
|
const selectedRef = useLatest(selected);
|
|
3792
3845
|
const operatorRef = useLatest(operator);
|
|
3793
|
-
const mountedRef =
|
|
3794
|
-
|
|
3846
|
+
const mountedRef = React29.useRef(true);
|
|
3847
|
+
React29.useEffect(() => {
|
|
3795
3848
|
mountedRef.current = true;
|
|
3796
3849
|
return () => {
|
|
3797
3850
|
mountedRef.current = false;
|
|
@@ -3805,20 +3858,20 @@ function MultiSelectPanel({
|
|
|
3805
3858
|
if (selectedRef.current.length > 0) commit(selectedRef.current, op);
|
|
3806
3859
|
else setDraftOperator(op);
|
|
3807
3860
|
};
|
|
3808
|
-
const [mode2, setMode] =
|
|
3809
|
-
const [query, setQuery] =
|
|
3810
|
-
const [asyncState, setAsyncState] =
|
|
3861
|
+
const [mode2, setMode] = React29.useState("search");
|
|
3862
|
+
const [query, setQuery] = React29.useState("");
|
|
3863
|
+
const [asyncState, setAsyncState] = React29.useState(
|
|
3811
3864
|
{ options: null, loading: !!field.loadOptions, error: false }
|
|
3812
3865
|
);
|
|
3813
|
-
const [retryTick, setRetryTick] =
|
|
3814
|
-
const inputRef =
|
|
3815
|
-
const listRef =
|
|
3816
|
-
const listId =
|
|
3866
|
+
const [retryTick, setRetryTick] = React29.useState(0);
|
|
3867
|
+
const inputRef = React29.useRef(null);
|
|
3868
|
+
const listRef = React29.useRef(null);
|
|
3869
|
+
const listId = React29.useId();
|
|
3817
3870
|
const loadOptionsRef = useLatest(field.loadOptions);
|
|
3818
|
-
|
|
3871
|
+
React29.useEffect(() => {
|
|
3819
3872
|
inputRef.current?.focus();
|
|
3820
3873
|
}, []);
|
|
3821
|
-
|
|
3874
|
+
React29.useEffect(() => {
|
|
3822
3875
|
const load = loadOptionsRef.current;
|
|
3823
3876
|
if (!load) return;
|
|
3824
3877
|
const controller = new AbortController();
|
|
@@ -3851,17 +3904,17 @@ function MultiSelectPanel({
|
|
|
3851
3904
|
};
|
|
3852
3905
|
const nav = useListboxNav({ count: options.length, onSelect: (i) => toggle(options[i]) });
|
|
3853
3906
|
useListboxScrollIntoView(nav.active, listRef, hasListbox);
|
|
3854
|
-
|
|
3907
|
+
React29.useEffect(() => {
|
|
3855
3908
|
nav.setActive(0);
|
|
3856
3909
|
}, [query, options.length]);
|
|
3857
3910
|
const activeId = hasListbox && options[nav.active] ? listId + "-opt-" + nav.active : void 0;
|
|
3858
3911
|
const liveMessage = showLoading ? "Loading\u2026" : showError ? "Couldn't load options." : options.length === 0 ? "No matches" : atLimit ? "Limit reached: at most " + field.maxValues + " values" : "";
|
|
3859
|
-
const [pasteText, setPasteText] =
|
|
3860
|
-
const [pasteLoading, setPasteLoading] =
|
|
3861
|
-
const [unmatchedTokens, setUnmatchedTokens] =
|
|
3862
|
-
const [pasteError, setPasteError] =
|
|
3863
|
-
const pasteWrapRef =
|
|
3864
|
-
|
|
3912
|
+
const [pasteText, setPasteText] = React29.useState("");
|
|
3913
|
+
const [pasteLoading, setPasteLoading] = React29.useState(false);
|
|
3914
|
+
const [unmatchedTokens, setUnmatchedTokens] = React29.useState([]);
|
|
3915
|
+
const [pasteError, setPasteError] = React29.useState(null);
|
|
3916
|
+
const pasteWrapRef = React29.useRef(null);
|
|
3917
|
+
React29.useEffect(() => {
|
|
3865
3918
|
if (mode2 === "paste") pasteWrapRef.current?.querySelector("textarea")?.focus();
|
|
3866
3919
|
}, [mode2]);
|
|
3867
3920
|
const doResolve = () => {
|
|
@@ -4034,8 +4087,8 @@ function MultiSelectPanel({
|
|
|
4034
4087
|
);
|
|
4035
4088
|
}
|
|
4036
4089
|
function useTextValidity(onFlip) {
|
|
4037
|
-
const invalidRef =
|
|
4038
|
-
const [, rerender] =
|
|
4090
|
+
const invalidRef = React29.useRef(/* @__PURE__ */ new Set());
|
|
4091
|
+
const [, rerender] = React29.useReducer((n) => n + 1, 0);
|
|
4039
4092
|
const onFlipRef = useLatest(onFlip);
|
|
4040
4093
|
const record = (name, valid) => {
|
|
4041
4094
|
const invalid = invalidRef.current;
|
|
@@ -4078,15 +4131,15 @@ function sameValue(a, b) {
|
|
|
4078
4131
|
return true;
|
|
4079
4132
|
}
|
|
4080
4133
|
function useReseedFromProps(value, applies, reseed) {
|
|
4081
|
-
const seen =
|
|
4082
|
-
|
|
4134
|
+
const seen = React29.useRef(value);
|
|
4135
|
+
React29.useLayoutEffect(() => {
|
|
4083
4136
|
if (seen.current === value) return;
|
|
4084
4137
|
seen.current = value;
|
|
4085
4138
|
if (!sameValue(value, applies())) reseed(value);
|
|
4086
4139
|
}, [value, applies, reseed]);
|
|
4087
4140
|
}
|
|
4088
4141
|
function usePreserveFocusAcrossRemount(seed, fields) {
|
|
4089
|
-
const pendingName =
|
|
4142
|
+
const pendingName = React29.useRef(null);
|
|
4090
4143
|
const fieldsRef = useLatest(fields);
|
|
4091
4144
|
const capture = () => {
|
|
4092
4145
|
const active = document.activeElement;
|
|
@@ -4099,7 +4152,7 @@ function usePreserveFocusAcrossRemount(seed, fields) {
|
|
|
4099
4152
|
}
|
|
4100
4153
|
}
|
|
4101
4154
|
};
|
|
4102
|
-
|
|
4155
|
+
React29.useLayoutEffect(() => {
|
|
4103
4156
|
const name = pendingName.current;
|
|
4104
4157
|
if (!name) return;
|
|
4105
4158
|
pendingName.current = null;
|
|
@@ -4115,14 +4168,14 @@ function RangePanel({
|
|
|
4115
4168
|
onCommit,
|
|
4116
4169
|
onClose
|
|
4117
4170
|
}) {
|
|
4118
|
-
const [draft, setDraft] =
|
|
4119
|
-
const [seed, setSeed] =
|
|
4120
|
-
const minId =
|
|
4121
|
-
const maxId =
|
|
4122
|
-
const minWrapRef =
|
|
4123
|
-
const maxWrapRef =
|
|
4171
|
+
const [draft, setDraft] = React29.useState(() => rangeDraft(value));
|
|
4172
|
+
const [seed, setSeed] = React29.useState(0);
|
|
4173
|
+
const minId = React29.useId();
|
|
4174
|
+
const maxId = React29.useId();
|
|
4175
|
+
const minWrapRef = React29.useRef(null);
|
|
4176
|
+
const maxWrapRef = React29.useRef(null);
|
|
4124
4177
|
const preserveFocus = usePreserveFocusAcrossRemount(seed, { min: minWrapRef, max: maxWrapRef });
|
|
4125
|
-
const draftRef =
|
|
4178
|
+
const draftRef = React29.useRef(draft);
|
|
4126
4179
|
const shown = () => {
|
|
4127
4180
|
const { min, max } = draftRef.current;
|
|
4128
4181
|
return applicable(field, min == null && max == null ? void 0 : { min, max }, validity.allValid());
|
|
@@ -4214,15 +4267,15 @@ function DatePanel({
|
|
|
4214
4267
|
onClose
|
|
4215
4268
|
}) {
|
|
4216
4269
|
const maxDays = effectiveMaxDays(field);
|
|
4217
|
-
const [initial] =
|
|
4218
|
-
const [kind, setKind] =
|
|
4219
|
-
const [daysDraft, setDaysDraft] =
|
|
4220
|
-
const daysRef =
|
|
4221
|
-
const daysConfirmed =
|
|
4222
|
-
const [between, setBetween] =
|
|
4223
|
-
const [seed, setSeed] =
|
|
4224
|
-
const daysId =
|
|
4225
|
-
const daysWrapRef =
|
|
4270
|
+
const [initial] = React29.useState(() => dateDraft(field, value));
|
|
4271
|
+
const [kind, setKind] = React29.useState(initial.kind);
|
|
4272
|
+
const [daysDraft, setDaysDraft] = React29.useState(initial.days);
|
|
4273
|
+
const daysRef = React29.useRef(daysDraft);
|
|
4274
|
+
const daysConfirmed = React29.useRef(value?.kind === "withinDays");
|
|
4275
|
+
const [between, setBetween] = React29.useState(initial.between);
|
|
4276
|
+
const [seed, setSeed] = React29.useState(0);
|
|
4277
|
+
const daysId = React29.useId();
|
|
4278
|
+
const daysWrapRef = React29.useRef(null);
|
|
4226
4279
|
const preserveFocus = usePreserveFocusAcrossRemount(seed, { days: daysWrapRef });
|
|
4227
4280
|
const shownWithinDays = () => {
|
|
4228
4281
|
const days = daysRef.current;
|
|
@@ -4334,11 +4387,11 @@ function DatePanel({
|
|
|
4334
4387
|
);
|
|
4335
4388
|
}
|
|
4336
4389
|
function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", actions, onClearAll, showActiveCount = false, className = "", ...rest }) {
|
|
4337
|
-
const [panel, setPanel] =
|
|
4338
|
-
const editAnchorRef =
|
|
4339
|
-
const addAnchorRef =
|
|
4340
|
-
const textInputRef =
|
|
4341
|
-
const optionsRef =
|
|
4390
|
+
const [panel, setPanel] = React29.useState(null);
|
|
4391
|
+
const editAnchorRef = React29.useRef(null);
|
|
4392
|
+
const addAnchorRef = React29.useRef(null);
|
|
4393
|
+
const textInputRef = React29.useRef(null);
|
|
4394
|
+
const optionsRef = React29.useRef(null);
|
|
4342
4395
|
if (process.env.NODE_ENV !== "production") {
|
|
4343
4396
|
for (const f of fields) assertValidFieldDefinition(f);
|
|
4344
4397
|
}
|
|
@@ -4361,7 +4414,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
4361
4414
|
const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
|
|
4362
4415
|
const startEditing = (key) => setPanel({ kind: "edit", key });
|
|
4363
4416
|
const closeEditing = () => setPanel(null);
|
|
4364
|
-
|
|
4417
|
+
React29.useEffect(() => {
|
|
4365
4418
|
if (!panel || panel.kind !== "edit") return;
|
|
4366
4419
|
if (editingField?.type === "text") {
|
|
4367
4420
|
textInputRef.current?.focus();
|
|
@@ -4470,8 +4523,10 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
4470
4523
|
removeField(field);
|
|
4471
4524
|
closeEditing();
|
|
4472
4525
|
};
|
|
4473
|
-
const
|
|
4474
|
-
const
|
|
4526
|
+
const valueText = set ? chipLabel(field, value) : "";
|
|
4527
|
+
const chipText = set ? field.label + ": " + valueText : field.label;
|
|
4528
|
+
const paintedText = field.icon && set ? valueText : chipText;
|
|
4529
|
+
const chip = /* @__PURE__ */ jsx49(Tag, { icon: field.icon, selected: true, onClick: toggleOrClose, onRemove: remove, title: chipText, "aria-label": chipText, children: /* @__PURE__ */ jsx49(MiddleEllipsis, { text: paintedText }) });
|
|
4475
4530
|
if (field.type === "text") {
|
|
4476
4531
|
return /* @__PURE__ */ jsx49("span", { className: "fd-filterbar-chip", children: chip }, field.key);
|
|
4477
4532
|
}
|
|
@@ -4589,10 +4644,10 @@ function StatTile({ label, value, sub, delta, invert = false, loading = false, c
|
|
|
4589
4644
|
}
|
|
4590
4645
|
|
|
4591
4646
|
// src/components/data/CodeBlock.tsx
|
|
4592
|
-
import * as
|
|
4647
|
+
import * as React31 from "react";
|
|
4593
4648
|
|
|
4594
4649
|
// src/kits/clipboard.ts
|
|
4595
|
-
import * as
|
|
4650
|
+
import * as React30 from "react";
|
|
4596
4651
|
var COPIED_FEEDBACK_MS = 1600;
|
|
4597
4652
|
function copyThroughSelection(text) {
|
|
4598
4653
|
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -4622,17 +4677,17 @@ async function copyToClipboard(text) {
|
|
|
4622
4677
|
return copyThroughSelection(text);
|
|
4623
4678
|
}
|
|
4624
4679
|
function useCopyToClipboard() {
|
|
4625
|
-
const [copied, setCopied] =
|
|
4626
|
-
const timer =
|
|
4627
|
-
const mounted =
|
|
4628
|
-
|
|
4680
|
+
const [copied, setCopied] = React30.useState(false);
|
|
4681
|
+
const timer = React30.useRef(null);
|
|
4682
|
+
const mounted = React30.useRef(true);
|
|
4683
|
+
React30.useEffect(() => {
|
|
4629
4684
|
mounted.current = true;
|
|
4630
4685
|
return () => {
|
|
4631
4686
|
mounted.current = false;
|
|
4632
4687
|
if (timer.current) clearTimeout(timer.current);
|
|
4633
4688
|
};
|
|
4634
4689
|
}, []);
|
|
4635
|
-
const copy =
|
|
4690
|
+
const copy = React30.useCallback(async (text) => {
|
|
4636
4691
|
const ok = await copyToClipboard(text);
|
|
4637
4692
|
if (ok && mounted.current) {
|
|
4638
4693
|
setCopied(true);
|
|
@@ -4800,7 +4855,7 @@ function tokenize(src, lang) {
|
|
|
4800
4855
|
return out;
|
|
4801
4856
|
}
|
|
4802
4857
|
function Highlighted({ code, lang }) {
|
|
4803
|
-
const toks =
|
|
4858
|
+
const toks = React31.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
4804
4859
|
return /* @__PURE__ */ jsx51(Fragment7, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx51("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
|
|
4805
4860
|
}
|
|
4806
4861
|
function CodeBlock({
|
|
@@ -4814,8 +4869,8 @@ function CodeBlock({
|
|
|
4814
4869
|
actions,
|
|
4815
4870
|
className = ""
|
|
4816
4871
|
}) {
|
|
4817
|
-
const [wrap, setWrap] =
|
|
4818
|
-
const [open2, setOpen] =
|
|
4872
|
+
const [wrap, setWrap] = React31.useState(!!wrapDefault);
|
|
4873
|
+
const [open2, setOpen] = React31.useState(false);
|
|
4819
4874
|
const [copied, copy] = useCopyToClipboard();
|
|
4820
4875
|
const body = String(code).replace(/\n$/, "");
|
|
4821
4876
|
const lines = body.split("\n");
|
|
@@ -4844,7 +4899,7 @@ function CodeBlock({
|
|
|
4844
4899
|
] });
|
|
4845
4900
|
}
|
|
4846
4901
|
function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
|
|
4847
|
-
const [open2, setOpen] =
|
|
4902
|
+
const [open2, setOpen] = React31.useState(false);
|
|
4848
4903
|
const [copied, copy] = useCopyToClipboard();
|
|
4849
4904
|
const raw = String(diff).replace(/\n$/, "");
|
|
4850
4905
|
const all = raw.split("\n").map((line) => {
|
|
@@ -4890,7 +4945,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
4890
4945
|
}
|
|
4891
4946
|
|
|
4892
4947
|
// src/components/data/Markdown.tsx
|
|
4893
|
-
import * as
|
|
4948
|
+
import * as React32 from "react";
|
|
4894
4949
|
import { jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
4895
4950
|
var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
|
|
4896
4951
|
var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
|
|
@@ -4929,7 +4984,7 @@ function inlineNodes(src, ctx, keyBase) {
|
|
|
4929
4984
|
const href = safeHref(g(2));
|
|
4930
4985
|
out.push(href ? /* @__PURE__ */ jsx52("a", { href, title: g(3) || void 0, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: inlineNodes(g(1), ctx, key()) }, key()) : /* @__PURE__ */ jsx52("span", { children: g(1) }, key()));
|
|
4931
4986
|
} else if (kind === "cite") {
|
|
4932
|
-
out.push(ctx.renderCitation ? /* @__PURE__ */ jsx52(
|
|
4987
|
+
out.push(ctx.renderCitation ? /* @__PURE__ */ jsx52(React32.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx52("sup", { className: "fd-md-cite", children: g(1) }, key()));
|
|
4933
4988
|
} else if (kind === "strongem") out.push(/* @__PURE__ */ jsx52("strong", { children: /* @__PURE__ */ jsx52("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
|
|
4934
4989
|
else if (kind === "strong") out.push(/* @__PURE__ */ jsx52("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
4935
4990
|
else if (kind === "em") out.push(/* @__PURE__ */ jsx52("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
@@ -5094,7 +5149,7 @@ function Markdown({
|
|
|
5094
5149
|
onLinkClick
|
|
5095
5150
|
}) {
|
|
5096
5151
|
const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
|
|
5097
|
-
const blocks =
|
|
5152
|
+
const blocks = React32.useMemo(() => parseBlocks(source), [source]);
|
|
5098
5153
|
return /* @__PURE__ */ jsx52("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
|
|
5099
5154
|
}
|
|
5100
5155
|
function MarkdownInline({ source = "", className = "", onLinkClick }) {
|
|
@@ -5208,7 +5263,7 @@ function Pagination({
|
|
|
5208
5263
|
}
|
|
5209
5264
|
|
|
5210
5265
|
// src/components/data/RelativeTime.tsx
|
|
5211
|
-
import * as
|
|
5266
|
+
import * as React33 from "react";
|
|
5212
5267
|
import { jsxs as jsxs47 } from "react/jsx-runtime";
|
|
5213
5268
|
var MIN = 6e4;
|
|
5214
5269
|
var HOUR = 36e5;
|
|
@@ -5260,9 +5315,9 @@ function formatDuration(ms) {
|
|
|
5260
5315
|
return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
|
|
5261
5316
|
}
|
|
5262
5317
|
function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
|
|
5263
|
-
const [, force] =
|
|
5318
|
+
const [, force] = React33.useState(0);
|
|
5264
5319
|
const t = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
5265
|
-
|
|
5320
|
+
React33.useEffect(() => {
|
|
5266
5321
|
if (!refresh2 || !t || isNaN(t)) return;
|
|
5267
5322
|
const abs = Math.abs(t - Date.now());
|
|
5268
5323
|
if (abs > DAY) return;
|
|
@@ -5278,7 +5333,7 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
|
|
|
5278
5333
|
}
|
|
5279
5334
|
|
|
5280
5335
|
// src/components/data/ScoreMeter.tsx
|
|
5281
|
-
import * as
|
|
5336
|
+
import * as React34 from "react";
|
|
5282
5337
|
import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
5283
5338
|
function ScoreMeter({
|
|
5284
5339
|
score,
|
|
@@ -5293,10 +5348,10 @@ function ScoreMeter({
|
|
|
5293
5348
|
breakdownWidth = 280,
|
|
5294
5349
|
className = ""
|
|
5295
5350
|
}) {
|
|
5296
|
-
const [open2, setOpen] =
|
|
5297
|
-
const ref =
|
|
5351
|
+
const [open2, setOpen] = React34.useState(false);
|
|
5352
|
+
const ref = React34.useRef(null);
|
|
5298
5353
|
const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
5299
|
-
const body = /* @__PURE__ */ jsxs48(
|
|
5354
|
+
const body = /* @__PURE__ */ jsxs48(React34.Fragment, { children: [
|
|
5300
5355
|
/* @__PURE__ */ jsx55("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ jsx55(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
|
|
5301
5356
|
showScore ? /* @__PURE__ */ jsx55("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
|
|
5302
5357
|
] });
|
|
@@ -5315,7 +5370,7 @@ function ScoreMeter({
|
|
|
5315
5370
|
}
|
|
5316
5371
|
);
|
|
5317
5372
|
}
|
|
5318
|
-
return /* @__PURE__ */ jsxs48(
|
|
5373
|
+
return /* @__PURE__ */ jsxs48(React34.Fragment, { children: [
|
|
5319
5374
|
/* @__PURE__ */ jsx55(
|
|
5320
5375
|
"button",
|
|
5321
5376
|
{
|
|
@@ -5346,14 +5401,14 @@ function ScoreMeter({
|
|
|
5346
5401
|
}
|
|
5347
5402
|
|
|
5348
5403
|
// src/components/actions/inlinePanel.tsx
|
|
5349
|
-
import * as
|
|
5404
|
+
import * as React35 from "react";
|
|
5350
5405
|
import { jsx as jsx56 } from "react/jsx-runtime";
|
|
5351
5406
|
function useInlinePanel() {
|
|
5352
|
-
const [open2, setOpen] =
|
|
5353
|
-
const ref =
|
|
5407
|
+
const [open2, setOpen] = React35.useState(false);
|
|
5408
|
+
const ref = React35.useRef(null);
|
|
5354
5409
|
const layer = useStackedLayer({ active: open2, containerRef: ref, onEscape: () => setOpen(false) });
|
|
5355
5410
|
const zIndex = useLayerZIndex(layer);
|
|
5356
|
-
|
|
5411
|
+
React35.useEffect(() => {
|
|
5357
5412
|
if (!open2) return;
|
|
5358
5413
|
const away = (e) => {
|
|
5359
5414
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -5419,7 +5474,7 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
|
|
|
5419
5474
|
}
|
|
5420
5475
|
|
|
5421
5476
|
// src/components/data/StepList.tsx
|
|
5422
|
-
import * as
|
|
5477
|
+
import * as React36 from "react";
|
|
5423
5478
|
import { jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
5424
5479
|
var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
|
|
5425
5480
|
function StepList({
|
|
@@ -5432,9 +5487,9 @@ function StepList({
|
|
|
5432
5487
|
dense = false,
|
|
5433
5488
|
className = ""
|
|
5434
5489
|
}) {
|
|
5435
|
-
const [openState, setOpenState] =
|
|
5490
|
+
const [openState, setOpenState] = React36.useState(defaultOpen);
|
|
5436
5491
|
const open2 = openProp == null ? openState : openProp;
|
|
5437
|
-
const [expanded, setExpanded] =
|
|
5492
|
+
const [expanded, setExpanded] = React36.useState({});
|
|
5438
5493
|
if (!steps.length) return null;
|
|
5439
5494
|
const running = steps.some((s) => s.status === "running");
|
|
5440
5495
|
const failed = steps.filter((s) => s.status === "error").length;
|
|
@@ -5492,7 +5547,7 @@ function StepList({
|
|
|
5492
5547
|
}
|
|
5493
5548
|
|
|
5494
5549
|
// src/components/data/VirtualList.tsx
|
|
5495
|
-
import * as
|
|
5550
|
+
import * as React37 from "react";
|
|
5496
5551
|
import { jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
5497
5552
|
var VIRTUAL_LIST_BUFFER_ROWS = 20;
|
|
5498
5553
|
var VIRTUAL_LIST_ROW_GAP = 6;
|
|
@@ -5544,35 +5599,35 @@ function VirtualList({
|
|
|
5544
5599
|
className = "",
|
|
5545
5600
|
style
|
|
5546
5601
|
}) {
|
|
5547
|
-
const [scrollTop, setScrollTop] =
|
|
5548
|
-
const loaded =
|
|
5602
|
+
const [scrollTop, setScrollTop] = React37.useState(0);
|
|
5603
|
+
const loaded = React37.useMemo(
|
|
5549
5604
|
() => ({ firstItemIndex, count: items.length }),
|
|
5550
5605
|
[firstItemIndex, items.length]
|
|
5551
5606
|
);
|
|
5552
5607
|
const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
|
|
5553
5608
|
const bandKey = firstItemIndex + ":" + items.length;
|
|
5554
|
-
const win =
|
|
5609
|
+
const win = React37.useMemo(
|
|
5555
5610
|
() => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
|
|
5556
5611
|
[scrollTop, height, itemHeight, total, loaded]
|
|
5557
5612
|
);
|
|
5558
|
-
const need =
|
|
5613
|
+
const need = React37.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
|
|
5559
5614
|
const wantStart = need.start && hasMore?.start !== false;
|
|
5560
5615
|
const wantEnd = need.end && hasMore?.end !== false;
|
|
5561
5616
|
const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
|
|
5562
5617
|
const askKey = bandKey + "@" + bucket2;
|
|
5563
|
-
const asked =
|
|
5564
|
-
|
|
5618
|
+
const asked = React37.useRef({ start: null, end: null });
|
|
5619
|
+
React37.useEffect(() => {
|
|
5565
5620
|
if (loading || !wantStart || asked.current.start === askKey) return;
|
|
5566
5621
|
asked.current.start = askKey;
|
|
5567
5622
|
onNeedMore("start", win);
|
|
5568
5623
|
}, [wantStart, loading, askKey, onNeedMore, win]);
|
|
5569
|
-
|
|
5624
|
+
React37.useEffect(() => {
|
|
5570
5625
|
if (loading || !wantEnd || asked.current.end === askKey) return;
|
|
5571
5626
|
asked.current.end = askKey;
|
|
5572
5627
|
onNeedMore("end", win);
|
|
5573
5628
|
}, [wantEnd, loading, askKey, onNeedMore, win]);
|
|
5574
|
-
const lastKeysRef =
|
|
5575
|
-
const newKeys =
|
|
5629
|
+
const lastKeysRef = React37.useRef(null);
|
|
5630
|
+
const newKeys = React37.useMemo(() => {
|
|
5576
5631
|
const prev = lastKeysRef.current;
|
|
5577
5632
|
if (!prev) return /* @__PURE__ */ new Set();
|
|
5578
5633
|
const fresh = /* @__PURE__ */ new Set();
|
|
@@ -5582,7 +5637,7 @@ function VirtualList({
|
|
|
5582
5637
|
}
|
|
5583
5638
|
return fresh;
|
|
5584
5639
|
}, [items]);
|
|
5585
|
-
|
|
5640
|
+
React37.useEffect(() => {
|
|
5586
5641
|
lastKeysRef.current = new Set(items.map(keyOf));
|
|
5587
5642
|
}, [items]);
|
|
5588
5643
|
const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
|
|
@@ -5627,7 +5682,7 @@ function VirtualList({
|
|
|
5627
5682
|
}
|
|
5628
5683
|
|
|
5629
5684
|
// src/components/data/EntityRow.tsx
|
|
5630
|
-
import * as
|
|
5685
|
+
import * as React38 from "react";
|
|
5631
5686
|
import { jsx as jsx60, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
5632
5687
|
var ENTITY_ROW_METRIC_WIDTH = 74;
|
|
5633
5688
|
var METRIC_TONE_COLOR = {
|
|
@@ -5640,7 +5695,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
|
|
|
5640
5695
|
const key = m.id || m.label || i;
|
|
5641
5696
|
const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
|
|
5642
5697
|
const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
|
|
5643
|
-
const content = /* @__PURE__ */ jsxs52(
|
|
5698
|
+
const content = /* @__PURE__ */ jsxs52(React38.Fragment, { children: [
|
|
5644
5699
|
m.icon ? /* @__PURE__ */ jsx60("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
|
|
5645
5700
|
/* @__PURE__ */ jsx60("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
|
|
5646
5701
|
/* @__PURE__ */ jsx60("span", { className: "fd-sr", children: " " + m.label })
|
|
@@ -5732,8 +5787,8 @@ function EntityRow({
|
|
|
5732
5787
|
}
|
|
5733
5788
|
|
|
5734
5789
|
// src/components/data/TransferList.tsx
|
|
5735
|
-
import * as
|
|
5736
|
-
import { createPortal as
|
|
5790
|
+
import * as React39 from "react";
|
|
5791
|
+
import { createPortal as createPortal5 } from "react-dom";
|
|
5737
5792
|
|
|
5738
5793
|
// src/components/forms/Input.tsx
|
|
5739
5794
|
import { jsx as jsx61, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
@@ -5838,12 +5893,12 @@ function TransferList({
|
|
|
5838
5893
|
listHeight = 440,
|
|
5839
5894
|
className = ""
|
|
5840
5895
|
}) {
|
|
5841
|
-
const [drag, setDrag] =
|
|
5842
|
-
const [dragOverSide, setDragOverSide] =
|
|
5843
|
-
const dragRef =
|
|
5844
|
-
const armedRef =
|
|
5845
|
-
const sideRefs =
|
|
5846
|
-
const hitTestSide =
|
|
5896
|
+
const [drag, setDrag] = React39.useState(null);
|
|
5897
|
+
const [dragOverSide, setDragOverSide] = React39.useState(null);
|
|
5898
|
+
const dragRef = React39.useRef(null);
|
|
5899
|
+
const armedRef = React39.useRef(null);
|
|
5900
|
+
const sideRefs = React39.useRef({ left: null, right: null });
|
|
5901
|
+
const hitTestSide = React39.useCallback((x, y) => {
|
|
5847
5902
|
for (const side of ["left", "right"]) {
|
|
5848
5903
|
const el = sideRefs.current[side];
|
|
5849
5904
|
if (!el) continue;
|
|
@@ -5852,7 +5907,7 @@ function TransferList({
|
|
|
5852
5907
|
}
|
|
5853
5908
|
return null;
|
|
5854
5909
|
}, []);
|
|
5855
|
-
const findItem =
|
|
5910
|
+
const findItem = React39.useCallback(
|
|
5856
5911
|
(side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
|
|
5857
5912
|
[left.items, right.items, keyOf]
|
|
5858
5913
|
);
|
|
@@ -5874,7 +5929,7 @@ function TransferList({
|
|
|
5874
5929
|
height: rect.height
|
|
5875
5930
|
};
|
|
5876
5931
|
};
|
|
5877
|
-
|
|
5932
|
+
React39.useEffect(() => {
|
|
5878
5933
|
const onMovePointer = (e) => {
|
|
5879
5934
|
const armed = armedRef.current;
|
|
5880
5935
|
if (!armed || e.pointerId !== armed.pointerId) return;
|
|
@@ -5927,7 +5982,7 @@ function TransferList({
|
|
|
5927
5982
|
window.removeEventListener("pointercancel", endDrag);
|
|
5928
5983
|
};
|
|
5929
5984
|
}, [hitTestSide, findItem, onMove]);
|
|
5930
|
-
|
|
5985
|
+
React39.useEffect(() => {
|
|
5931
5986
|
if (!drag || typeof document === "undefined") return;
|
|
5932
5987
|
const prev = document.body.style.userSelect;
|
|
5933
5988
|
document.body.style.userSelect = "none";
|
|
@@ -6010,7 +6065,7 @@ function TransferList({
|
|
|
6010
6065
|
renderSide("left", left, "right"),
|
|
6011
6066
|
renderSide("right", right, "left")
|
|
6012
6067
|
] }),
|
|
6013
|
-
drag ?
|
|
6068
|
+
drag ? createPortal5(
|
|
6014
6069
|
/* @__PURE__ */ jsx63(
|
|
6015
6070
|
"div",
|
|
6016
6071
|
{
|
|
@@ -6035,11 +6090,11 @@ function TransferList({
|
|
|
6035
6090
|
}
|
|
6036
6091
|
|
|
6037
6092
|
// src/components/forms/Checkbox.tsx
|
|
6038
|
-
import * as
|
|
6093
|
+
import * as React40 from "react";
|
|
6039
6094
|
import { jsx as jsx64, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
6040
6095
|
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
6041
|
-
const ref =
|
|
6042
|
-
|
|
6096
|
+
const ref = React40.useRef(null);
|
|
6097
|
+
React40.useEffect(() => {
|
|
6043
6098
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
6044
6099
|
}, [indeterminate]);
|
|
6045
6100
|
return /* @__PURE__ */ jsxs55("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
@@ -6083,7 +6138,7 @@ function Switch({ label, description, className = "", ...rest }) {
|
|
|
6083
6138
|
}
|
|
6084
6139
|
|
|
6085
6140
|
// src/components/forms/Select.tsx
|
|
6086
|
-
import * as
|
|
6141
|
+
import * as React41 from "react";
|
|
6087
6142
|
import { jsx as jsx67, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
6088
6143
|
var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
|
|
6089
6144
|
function Select({
|
|
@@ -6111,12 +6166,12 @@ function Select({
|
|
|
6111
6166
|
const isOn = (v) => multiple ? vals.includes(v) : v === value;
|
|
6112
6167
|
const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
|
|
6113
6168
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
|
|
6114
|
-
const [open2, setOpen] =
|
|
6115
|
-
const [q, setQ] =
|
|
6116
|
-
const rootRef =
|
|
6117
|
-
const boxRef =
|
|
6118
|
-
const listRef =
|
|
6119
|
-
const typeBuf =
|
|
6169
|
+
const [open2, setOpen] = React41.useState(false);
|
|
6170
|
+
const [q, setQ] = React41.useState("");
|
|
6171
|
+
const rootRef = React41.useRef(null);
|
|
6172
|
+
const boxRef = React41.useRef(null);
|
|
6173
|
+
const listRef = React41.useRef(null);
|
|
6174
|
+
const typeBuf = React41.useRef({ s: "", t: 0 });
|
|
6120
6175
|
const selected = multiple ? null : opts.find((o) => o.value === value);
|
|
6121
6176
|
const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
|
|
6122
6177
|
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;
|
|
@@ -6252,7 +6307,7 @@ function Select({
|
|
|
6252
6307
|
),
|
|
6253
6308
|
q ? /* @__PURE__ */ jsx67("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
|
|
6254
6309
|
] }) : void 0,
|
|
6255
|
-
footer: multiple ? /* @__PURE__ */ jsxs58(
|
|
6310
|
+
footer: multiple ? /* @__PURE__ */ jsxs58(React41.Fragment, { children: [
|
|
6256
6311
|
/* @__PURE__ */ jsx67(
|
|
6257
6312
|
"button",
|
|
6258
6313
|
{
|
|
@@ -6283,7 +6338,7 @@ function Select({
|
|
|
6283
6338
|
'Nothing matches "',
|
|
6284
6339
|
q,
|
|
6285
6340
|
'".'
|
|
6286
|
-
] }) : groups.map((grp) => /* @__PURE__ */ jsxs58(
|
|
6341
|
+
] }) : groups.map((grp) => /* @__PURE__ */ jsxs58(React41.Fragment, { children: [
|
|
6287
6342
|
grp.g ? /* @__PURE__ */ jsx67("div", { className: "fd-pop-group", children: grp.g }) : null,
|
|
6288
6343
|
grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs58(
|
|
6289
6344
|
"button",
|
|
@@ -6320,7 +6375,7 @@ function Select({
|
|
|
6320
6375
|
}
|
|
6321
6376
|
|
|
6322
6377
|
// src/components/forms/TimePicker.tsx
|
|
6323
|
-
import * as
|
|
6378
|
+
import * as React42 from "react";
|
|
6324
6379
|
import { jsx as jsx68, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
6325
6380
|
var pad = (n) => String(n).padStart(2, "0");
|
|
6326
6381
|
function ClockFace({ value = "09:00", onChange }) {
|
|
@@ -6329,9 +6384,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
6329
6384
|
if (isNaN(m)) m = 0;
|
|
6330
6385
|
const pm = h24 >= 12;
|
|
6331
6386
|
const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
|
|
6332
|
-
const [mode2, setMode] =
|
|
6333
|
-
const faceRef =
|
|
6334
|
-
const dragging =
|
|
6387
|
+
const [mode2, setMode] = React42.useState("h");
|
|
6388
|
+
const faceRef = React42.useRef(null);
|
|
6389
|
+
const dragging = React42.useRef(false);
|
|
6335
6390
|
const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
|
|
6336
6391
|
const R = 108, NR = 80;
|
|
6337
6392
|
const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
|
|
@@ -6404,9 +6459,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
6404
6459
|
}
|
|
6405
6460
|
function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
|
|
6406
6461
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
6407
|
-
const [open2, setOpen] =
|
|
6408
|
-
const rootRef =
|
|
6409
|
-
const boxRef =
|
|
6462
|
+
const [open2, setOpen] = React42.useState(false);
|
|
6463
|
+
const rootRef = React42.useRef(null);
|
|
6464
|
+
const boxRef = React42.useRef(null);
|
|
6410
6465
|
const disp = () => {
|
|
6411
6466
|
if (!value) return "";
|
|
6412
6467
|
const [h, m] = value.split(":").map(Number);
|
|
@@ -6449,7 +6504,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
6449
6504
|
offset: 6,
|
|
6450
6505
|
width: 262,
|
|
6451
6506
|
role: "presentation",
|
|
6452
|
-
footer: /* @__PURE__ */ jsxs59(
|
|
6507
|
+
footer: /* @__PURE__ */ jsxs59(React42.Fragment, { children: [
|
|
6453
6508
|
/* @__PURE__ */ jsx68(
|
|
6454
6509
|
"button",
|
|
6455
6510
|
{
|
|
@@ -6477,7 +6532,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
6477
6532
|
}
|
|
6478
6533
|
|
|
6479
6534
|
// src/components/forms/Slider.tsx
|
|
6480
|
-
import * as
|
|
6535
|
+
import * as React43 from "react";
|
|
6481
6536
|
import { jsx as jsx69, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
6482
6537
|
function Slider({
|
|
6483
6538
|
label,
|
|
@@ -6495,7 +6550,7 @@ function Slider({
|
|
|
6495
6550
|
...rest
|
|
6496
6551
|
}) {
|
|
6497
6552
|
const fieldId = useFieldId(id);
|
|
6498
|
-
const [dragging, setDragging] =
|
|
6553
|
+
const [dragging, setDragging] = React43.useState(false);
|
|
6499
6554
|
const v = value === void 0 ? min : Number(value);
|
|
6500
6555
|
const pct = max === min ? 0 : (v - min) / (max - min) * 100;
|
|
6501
6556
|
return /* @__PURE__ */ jsxs60("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
|
|
@@ -6529,7 +6584,7 @@ function Slider({
|
|
|
6529
6584
|
}
|
|
6530
6585
|
|
|
6531
6586
|
// src/components/forms/RangeSlider.tsx
|
|
6532
|
-
import * as
|
|
6587
|
+
import * as React44 from "react";
|
|
6533
6588
|
import { jsx as jsx70, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
6534
6589
|
function RangeSlider({
|
|
6535
6590
|
label,
|
|
@@ -6549,9 +6604,9 @@ function RangeSlider({
|
|
|
6549
6604
|
}) {
|
|
6550
6605
|
const fmt2 = format || ((v) => String(v));
|
|
6551
6606
|
const [a, b] = value || [min, max];
|
|
6552
|
-
const [drag, setDrag] =
|
|
6553
|
-
const [focus, setFocus] =
|
|
6554
|
-
const railRef =
|
|
6607
|
+
const [drag, setDrag] = React44.useState(null);
|
|
6608
|
+
const [focus, setFocus] = React44.useState(null);
|
|
6609
|
+
const railRef = React44.useRef(null);
|
|
6555
6610
|
const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
|
|
6556
6611
|
const clampPair = (i, v) => {
|
|
6557
6612
|
v = Math.min(max, Math.max(min, Math.round(v / step) * step));
|
|
@@ -6566,7 +6621,7 @@ function RangeSlider({
|
|
|
6566
6621
|
const r = railRef.current.getBoundingClientRect();
|
|
6567
6622
|
return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
|
|
6568
6623
|
};
|
|
6569
|
-
|
|
6624
|
+
React44.useEffect(() => {
|
|
6570
6625
|
if (drag === null) return;
|
|
6571
6626
|
const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
|
|
6572
6627
|
const upH = () => setDrag(null);
|
|
@@ -6647,7 +6702,7 @@ function RangeSlider({
|
|
|
6647
6702
|
/* @__PURE__ */ jsxs61("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
|
|
6648
6703
|
/* @__PURE__ */ jsx70("span", { className: "fd-range-rail", ref: railRef }),
|
|
6649
6704
|
/* @__PURE__ */ jsx70("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
|
|
6650
|
-
marks.map((m) => /* @__PURE__ */ jsxs61(
|
|
6705
|
+
marks.map((m) => /* @__PURE__ */ jsxs61(React44.Fragment, { children: [
|
|
6651
6706
|
/* @__PURE__ */ jsx70("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
|
|
6652
6707
|
m.label ? /* @__PURE__ */ jsx70("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
|
|
6653
6708
|
] }, m.value)),
|
|
@@ -6676,7 +6731,7 @@ function RangeSlider({
|
|
|
6676
6731
|
}
|
|
6677
6732
|
|
|
6678
6733
|
// src/components/forms/Dropzone.tsx
|
|
6679
|
-
import * as
|
|
6734
|
+
import * as React45 from "react";
|
|
6680
6735
|
import { jsx as jsx71, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
6681
6736
|
function Dropzone({
|
|
6682
6737
|
onFiles,
|
|
@@ -6691,8 +6746,8 @@ function Dropzone({
|
|
|
6691
6746
|
className = "",
|
|
6692
6747
|
style
|
|
6693
6748
|
}) {
|
|
6694
|
-
const [over, setOver] =
|
|
6695
|
-
const depth =
|
|
6749
|
+
const [over, setOver] = React45.useState(false);
|
|
6750
|
+
const depth = React45.useRef(0);
|
|
6696
6751
|
const has = (e) => {
|
|
6697
6752
|
const dt = e.dataTransfer;
|
|
6698
6753
|
if (!dt) return false;
|
|
@@ -6754,8 +6809,8 @@ function FilePickButton({
|
|
|
6754
6809
|
className = "",
|
|
6755
6810
|
children
|
|
6756
6811
|
}) {
|
|
6757
|
-
const ref =
|
|
6758
|
-
return /* @__PURE__ */ jsxs62(
|
|
6812
|
+
const ref = React45.useRef(null);
|
|
6813
|
+
return /* @__PURE__ */ jsxs62(React45.Fragment, { children: [
|
|
6759
6814
|
/* @__PURE__ */ jsx71(
|
|
6760
6815
|
"button",
|
|
6761
6816
|
{
|
|
@@ -6788,10 +6843,10 @@ function FilePickButton({
|
|
|
6788
6843
|
}
|
|
6789
6844
|
function useStagedFiles(upload, opts) {
|
|
6790
6845
|
const o = opts || {};
|
|
6791
|
-
const [items, setItems] =
|
|
6792
|
-
const controllers =
|
|
6846
|
+
const [items, setItems] = React45.useState([]);
|
|
6847
|
+
const controllers = React45.useRef({});
|
|
6793
6848
|
const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
|
|
6794
|
-
const run =
|
|
6849
|
+
const run = React45.useCallback((att) => {
|
|
6795
6850
|
if (!upload) return;
|
|
6796
6851
|
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
6797
6852
|
controllers.current[att.id] = ac;
|
|
@@ -6808,14 +6863,14 @@ function useStagedFiles(upload, opts) {
|
|
|
6808
6863
|
delete controllers.current[att.id];
|
|
6809
6864
|
});
|
|
6810
6865
|
}, [upload]);
|
|
6811
|
-
const add =
|
|
6866
|
+
const add = React45.useCallback((files) => {
|
|
6812
6867
|
if (!upload) return [];
|
|
6813
6868
|
const atts = Array.from(files).map((f) => toAttachment(f));
|
|
6814
6869
|
setItems((list) => list.concat(atts));
|
|
6815
6870
|
atts.forEach(run);
|
|
6816
6871
|
return atts;
|
|
6817
6872
|
}, [upload, run]);
|
|
6818
|
-
const remove =
|
|
6873
|
+
const remove = React45.useCallback((att) => {
|
|
6819
6874
|
const ac = controllers.current[att.id];
|
|
6820
6875
|
if (ac) {
|
|
6821
6876
|
try {
|
|
@@ -6826,10 +6881,10 @@ function useStagedFiles(upload, opts) {
|
|
|
6826
6881
|
}
|
|
6827
6882
|
setItems((list) => list.filter((f) => f.id !== att.id));
|
|
6828
6883
|
}, []);
|
|
6829
|
-
const retry =
|
|
6884
|
+
const retry = React45.useCallback((att) => {
|
|
6830
6885
|
run(att);
|
|
6831
6886
|
}, [run]);
|
|
6832
|
-
const clear =
|
|
6887
|
+
const clear = React45.useCallback(() => {
|
|
6833
6888
|
Object.values(controllers.current).forEach((ac) => {
|
|
6834
6889
|
try {
|
|
6835
6890
|
ac && ac.abort();
|
|
@@ -6953,7 +7008,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
|
|
|
6953
7008
|
}
|
|
6954
7009
|
|
|
6955
7010
|
// src/components/forms/MarkdownEditor.tsx
|
|
6956
|
-
import * as
|
|
7011
|
+
import * as React46 from "react";
|
|
6957
7012
|
import { jsx as jsx73, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
6958
7013
|
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
|
|
6959
7014
|
var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
|
|
@@ -7167,7 +7222,7 @@ function syncDom(root, value) {
|
|
|
7167
7222
|
while (root.children.length > lines.length) root.removeChild(root.lastChild);
|
|
7168
7223
|
}
|
|
7169
7224
|
var LIST_CONT = RE_LI;
|
|
7170
|
-
var MarkdownEditor =
|
|
7225
|
+
var MarkdownEditor = React46.forwardRef(function MarkdownEditor2({
|
|
7171
7226
|
value = "",
|
|
7172
7227
|
onChange,
|
|
7173
7228
|
onSubmit,
|
|
@@ -7186,10 +7241,10 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
|
|
|
7186
7241
|
className = "",
|
|
7187
7242
|
id
|
|
7188
7243
|
}, ref) {
|
|
7189
|
-
const boxRef =
|
|
7190
|
-
const composing =
|
|
7191
|
-
const pendingCaret =
|
|
7192
|
-
|
|
7244
|
+
const boxRef = React46.useRef(null);
|
|
7245
|
+
const composing = React46.useRef(false);
|
|
7246
|
+
const pendingCaret = React46.useRef(null);
|
|
7247
|
+
React46.useLayoutEffect(() => {
|
|
7193
7248
|
const root = boxRef.current;
|
|
7194
7249
|
if (!root || composing.current) return;
|
|
7195
7250
|
const active = document.activeElement === root || root.contains(document.activeElement);
|
|
@@ -7198,7 +7253,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
|
|
|
7198
7253
|
pendingCaret.current = null;
|
|
7199
7254
|
if (active && caret != null) placeCaret(root, caret);
|
|
7200
7255
|
}, [value]);
|
|
7201
|
-
|
|
7256
|
+
React46.useEffect(() => {
|
|
7202
7257
|
if (autoFocus && boxRef.current) boxRef.current.focus();
|
|
7203
7258
|
}, [autoFocus]);
|
|
7204
7259
|
const caretNow = () => {
|
|
@@ -7265,8 +7320,8 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
|
|
|
7265
7320
|
api.replaceRange(from, to, next, from + next.length);
|
|
7266
7321
|
}
|
|
7267
7322
|
};
|
|
7268
|
-
|
|
7269
|
-
const caretAtKeydown =
|
|
7323
|
+
React46.useImperativeHandle(ref, () => api);
|
|
7324
|
+
const caretAtKeydown = React46.useRef(-1);
|
|
7270
7325
|
function detect(text, caret) {
|
|
7271
7326
|
if (!onTrigger) return;
|
|
7272
7327
|
const upto = text.slice(0, caret);
|
|
@@ -7419,7 +7474,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
|
|
|
7419
7474
|
});
|
|
7420
7475
|
|
|
7421
7476
|
// src/components/forms/CodeEditor.tsx
|
|
7422
|
-
import * as
|
|
7477
|
+
import * as React47 from "react";
|
|
7423
7478
|
import { EditorView, keymap, lineNumbers, placeholder as cmPlaceholder, drawSelection, Decoration } from "@codemirror/view";
|
|
7424
7479
|
import { EditorState, StateEffect, StateField, Compartment } from "@codemirror/state";
|
|
7425
7480
|
import { defaultKeymap, history, historyKeymap, indentMore, indentLess } from "@codemirror/commands";
|
|
@@ -7523,16 +7578,16 @@ function CodeEditor({
|
|
|
7523
7578
|
const fieldId = useFieldId(id);
|
|
7524
7579
|
const descId = fieldId + "-desc";
|
|
7525
7580
|
const liveId = fieldId + "-live";
|
|
7526
|
-
const hostRef =
|
|
7527
|
-
const viewRef =
|
|
7528
|
-
const valueRef =
|
|
7529
|
-
const onChangeRef =
|
|
7581
|
+
const hostRef = React47.useRef(null);
|
|
7582
|
+
const viewRef = React47.useRef(null);
|
|
7583
|
+
const valueRef = React47.useRef(value);
|
|
7584
|
+
const onChangeRef = React47.useRef(onChange);
|
|
7530
7585
|
onChangeRef.current = onChange;
|
|
7531
|
-
const editableCompartment =
|
|
7532
|
-
const attributesCompartment =
|
|
7533
|
-
const errorRef =
|
|
7586
|
+
const editableCompartment = React47.useRef(new Compartment()).current;
|
|
7587
|
+
const attributesCompartment = React47.useRef(new Compartment()).current;
|
|
7588
|
+
const errorRef = React47.useRef(error);
|
|
7534
7589
|
errorRef.current = error;
|
|
7535
|
-
const diagnosticsCountRef =
|
|
7590
|
+
const diagnosticsCountRef = React47.useRef(diagnostics.length);
|
|
7536
7591
|
diagnosticsCountRef.current = diagnostics.length;
|
|
7537
7592
|
function contentAttributes() {
|
|
7538
7593
|
return {
|
|
@@ -7542,9 +7597,9 @@ function CodeEditor({
|
|
|
7542
7597
|
...label ? { "aria-label": label } : {}
|
|
7543
7598
|
};
|
|
7544
7599
|
}
|
|
7545
|
-
|
|
7546
|
-
const
|
|
7547
|
-
if (!
|
|
7600
|
+
React47.useEffect(() => {
|
|
7601
|
+
const host2 = hostRef.current;
|
|
7602
|
+
if (!host2) return;
|
|
7548
7603
|
const updateListener = EditorView.updateListener.of((update) => {
|
|
7549
7604
|
if (!update.docChanged) return;
|
|
7550
7605
|
const next = update.state.doc.toString();
|
|
@@ -7576,7 +7631,7 @@ function CodeEditor({
|
|
|
7576
7631
|
attributesCompartment.of(EditorView.contentAttributes.of(contentAttributes()))
|
|
7577
7632
|
]
|
|
7578
7633
|
});
|
|
7579
|
-
const view = new EditorView({ state, parent:
|
|
7634
|
+
const view = new EditorView({ state, parent: host2 });
|
|
7580
7635
|
viewRef.current = view;
|
|
7581
7636
|
if (autoFocus) view.focus();
|
|
7582
7637
|
return () => {
|
|
@@ -7584,7 +7639,7 @@ function CodeEditor({
|
|
|
7584
7639
|
viewRef.current = null;
|
|
7585
7640
|
};
|
|
7586
7641
|
}, []);
|
|
7587
|
-
|
|
7642
|
+
React47.useEffect(() => {
|
|
7588
7643
|
const view = viewRef.current;
|
|
7589
7644
|
if (!view) return;
|
|
7590
7645
|
const current2 = view.state.doc.toString();
|
|
@@ -7593,12 +7648,12 @@ function CodeEditor({
|
|
|
7593
7648
|
}
|
|
7594
7649
|
valueRef.current = value;
|
|
7595
7650
|
}, [value]);
|
|
7596
|
-
|
|
7651
|
+
React47.useEffect(() => {
|
|
7597
7652
|
const view = viewRef.current;
|
|
7598
7653
|
if (!view) return;
|
|
7599
7654
|
view.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!disabled)) });
|
|
7600
7655
|
}, [disabled, editableCompartment]);
|
|
7601
|
-
|
|
7656
|
+
React47.useEffect(() => {
|
|
7602
7657
|
const view = viewRef.current;
|
|
7603
7658
|
if (!view) return;
|
|
7604
7659
|
view.dispatch({
|
|
@@ -7656,16 +7711,16 @@ function CodeEditor({
|
|
|
7656
7711
|
}
|
|
7657
7712
|
|
|
7658
7713
|
// src/components/platform/AccountMenu.tsx
|
|
7659
|
-
import * as
|
|
7714
|
+
import * as React49 from "react";
|
|
7660
7715
|
|
|
7661
7716
|
// src/kits/sessionContext.tsx
|
|
7662
|
-
import * as
|
|
7663
|
-
var SessionContext =
|
|
7717
|
+
import * as React48 from "react";
|
|
7718
|
+
var SessionContext = React48.createContext(null);
|
|
7664
7719
|
function SessionProvider({ value, children }) {
|
|
7665
|
-
return
|
|
7720
|
+
return React48.createElement(SessionContext.Provider, { value }, children);
|
|
7666
7721
|
}
|
|
7667
7722
|
function useSessionContext() {
|
|
7668
|
-
const ctx =
|
|
7723
|
+
const ctx = React48.useContext(SessionContext);
|
|
7669
7724
|
if (!ctx) {
|
|
7670
7725
|
throw new Error(
|
|
7671
7726
|
"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."
|
|
@@ -7705,11 +7760,11 @@ function AccountMenu({
|
|
|
7705
7760
|
...rest
|
|
7706
7761
|
}) {
|
|
7707
7762
|
const { user, roles, can: can2, signOut: ctxSignOut, demo, pending } = useSessionContext();
|
|
7708
|
-
const [open2, setOpen] =
|
|
7709
|
-
const [switching, setSwitching] =
|
|
7710
|
-
const [signingOut, setSigningOut] =
|
|
7711
|
-
const [signOutError, setSignOutError] =
|
|
7712
|
-
const ref =
|
|
7763
|
+
const [open2, setOpen] = React49.useState(false);
|
|
7764
|
+
const [switching, setSwitching] = React49.useState(false);
|
|
7765
|
+
const [signingOut, setSigningOut] = React49.useState(false);
|
|
7766
|
+
const [signOutError, setSignOutError] = React49.useState(null);
|
|
7767
|
+
const ref = React49.useRef(null);
|
|
7713
7768
|
const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
|
|
7714
7769
|
const visibleGroups = groups.map((g) => ({ label: g.label, links: g.links.filter((l) => !l.perm || !pending && can2(l.perm)) })).filter((g) => g.links.length);
|
|
7715
7770
|
const closeMenu = () => {
|
|
@@ -7834,13 +7889,13 @@ function AccountMenu({
|
|
|
7834
7889
|
}
|
|
7835
7890
|
|
|
7836
7891
|
// src/components/platform/AppSwitcher.tsx
|
|
7837
|
-
import * as
|
|
7892
|
+
import * as React50 from "react";
|
|
7838
7893
|
import { jsx as jsx76, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
7839
7894
|
function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
7840
7895
|
const { apps: contextApps } = useSessionContext();
|
|
7841
7896
|
const apps = appsProp ?? contextApps ?? [];
|
|
7842
|
-
const [open2, setOpen] =
|
|
7843
|
-
const anchorRef =
|
|
7897
|
+
const [open2, setOpen] = React50.useState(false);
|
|
7898
|
+
const anchorRef = React50.useRef(null);
|
|
7844
7899
|
if (!apps.length) return null;
|
|
7845
7900
|
const items = apps.map((app) => ({
|
|
7846
7901
|
id: app.key,
|
|
@@ -7854,7 +7909,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
7854
7909
|
window.location.href = app.url;
|
|
7855
7910
|
}
|
|
7856
7911
|
}));
|
|
7857
|
-
return /* @__PURE__ */ jsxs67(
|
|
7912
|
+
return /* @__PURE__ */ jsxs67(React50.Fragment, { children: [
|
|
7858
7913
|
/* @__PURE__ */ jsx76("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx76(
|
|
7859
7914
|
IconButton,
|
|
7860
7915
|
{
|
|
@@ -7883,10 +7938,10 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
7883
7938
|
}
|
|
7884
7939
|
|
|
7885
7940
|
// src/components/platform/AppearanceMenu.tsx
|
|
7886
|
-
import * as
|
|
7941
|
+
import * as React52 from "react";
|
|
7887
7942
|
|
|
7888
7943
|
// src/kits/appearance.ts
|
|
7889
|
-
import * as
|
|
7944
|
+
import * as React51 from "react";
|
|
7890
7945
|
var DEFAULT_STORAGE_KEY = "fd-appearance";
|
|
7891
7946
|
var DEFAULT_PREFS = {
|
|
7892
7947
|
theme: "system",
|
|
@@ -7981,11 +8036,11 @@ function applyPrefs(prefs, root = document.documentElement) {
|
|
|
7981
8036
|
else root.removeAttribute("data-motion");
|
|
7982
8037
|
}
|
|
7983
8038
|
function useAppearancePrefs(store) {
|
|
7984
|
-
const prefs =
|
|
7985
|
-
|
|
8039
|
+
const prefs = React51.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
8040
|
+
React51.useEffect(() => {
|
|
7986
8041
|
applyPrefs(prefs);
|
|
7987
8042
|
}, [prefs]);
|
|
7988
|
-
|
|
8043
|
+
React51.useEffect(() => {
|
|
7989
8044
|
if (prefs.theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
7990
8045
|
return;
|
|
7991
8046
|
}
|
|
@@ -7994,7 +8049,7 @@ function useAppearancePrefs(store) {
|
|
|
7994
8049
|
mq.addEventListener("change", onChange);
|
|
7995
8050
|
return () => mq.removeEventListener("change", onChange);
|
|
7996
8051
|
}, [prefs]);
|
|
7997
|
-
const update =
|
|
8052
|
+
const update = React51.useCallback(
|
|
7998
8053
|
(patch) => {
|
|
7999
8054
|
store.write({ ...store.getSnapshot(), ...patch });
|
|
8000
8055
|
},
|
|
@@ -8017,15 +8072,15 @@ var TEXT_SCALE_OPTIONS = [
|
|
|
8017
8072
|
{ value: "xl", label: "XL" }
|
|
8018
8073
|
];
|
|
8019
8074
|
function AppearanceMenu({ className = "", store: storeProp, storageKey, storage, defaults }) {
|
|
8020
|
-
const store =
|
|
8075
|
+
const store = React52.useMemo(
|
|
8021
8076
|
() => storeProp ?? createLocalStorageAppearanceStore({ storageKey, storage, defaults }),
|
|
8022
8077
|
[storeProp, storageKey, storage, defaults]
|
|
8023
8078
|
);
|
|
8024
8079
|
const [prefs, update] = useAppearancePrefs(store);
|
|
8025
|
-
const [open2, setOpen] =
|
|
8026
|
-
const anchorRef =
|
|
8080
|
+
const [open2, setOpen] = React52.useState(false);
|
|
8081
|
+
const anchorRef = React52.useRef(null);
|
|
8027
8082
|
const patch = (p) => update(p);
|
|
8028
|
-
return /* @__PURE__ */ jsxs68(
|
|
8083
|
+
return /* @__PURE__ */ jsxs68(React52.Fragment, { children: [
|
|
8029
8084
|
/* @__PURE__ */ jsx77("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx77(
|
|
8030
8085
|
IconButton,
|
|
8031
8086
|
{
|
|
@@ -8094,14 +8149,14 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
|
|
|
8094
8149
|
}
|
|
8095
8150
|
|
|
8096
8151
|
// src/components/platform/ApiSpecBrowser.tsx
|
|
8097
|
-
import * as
|
|
8152
|
+
import * as React53 from "react";
|
|
8098
8153
|
import { jsx as jsx78, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
8099
8154
|
var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
|
|
8100
8155
|
function Json({ obj }) {
|
|
8101
8156
|
return /* @__PURE__ */ jsx78("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
|
|
8102
8157
|
}
|
|
8103
8158
|
function Endpoint({ s, onRequest }) {
|
|
8104
|
-
const [tried, setTried] =
|
|
8159
|
+
const [tried, setTried] = React53.useState(null);
|
|
8105
8160
|
const run = async () => {
|
|
8106
8161
|
setTried("busy");
|
|
8107
8162
|
const t0 = (window.performance || Date).now();
|
|
@@ -8174,10 +8229,10 @@ function ApiSpecBrowser({
|
|
|
8174
8229
|
className = "",
|
|
8175
8230
|
...rest
|
|
8176
8231
|
}) {
|
|
8177
|
-
const [q, setQ] =
|
|
8178
|
-
const [method, setMethod] =
|
|
8179
|
-
const [mod, setMod] =
|
|
8180
|
-
const [listOnly, setListOnly] =
|
|
8232
|
+
const [q, setQ] = React53.useState("");
|
|
8233
|
+
const [method, setMethod] = React53.useState(null);
|
|
8234
|
+
const [mod, setMod] = React53.useState(null);
|
|
8235
|
+
const [listOnly, setListOnly] = React53.useState(false);
|
|
8181
8236
|
const activeModule = modules && modules.find((m) => m.id === mod);
|
|
8182
8237
|
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())));
|
|
8183
8238
|
const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
|
|
@@ -8256,7 +8311,7 @@ function ApiSpecBrowser({
|
|
|
8256
8311
|
}
|
|
8257
8312
|
|
|
8258
8313
|
// src/components/platform/ProfilePage.tsx
|
|
8259
|
-
import * as
|
|
8314
|
+
import * as React54 from "react";
|
|
8260
8315
|
import { jsx as jsx79, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
8261
8316
|
function fieldInitialValue(field, user) {
|
|
8262
8317
|
if (field.value) return field.value(user);
|
|
@@ -8292,21 +8347,21 @@ function ProfilePage({
|
|
|
8292
8347
|
}) {
|
|
8293
8348
|
const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
|
|
8294
8349
|
const user = userProp || sessionUser;
|
|
8295
|
-
const initialFieldValues =
|
|
8350
|
+
const initialFieldValues = React54.useMemo(() => {
|
|
8296
8351
|
const values2 = {};
|
|
8297
8352
|
for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
|
|
8298
8353
|
return values2;
|
|
8299
8354
|
}, [user.id, fields]);
|
|
8300
|
-
const initialNotify =
|
|
8355
|
+
const initialNotify = React54.useMemo(() => {
|
|
8301
8356
|
const values2 = {};
|
|
8302
8357
|
for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
|
|
8303
8358
|
return values2;
|
|
8304
8359
|
}, [user.id, notifications]);
|
|
8305
|
-
const [values, setValues] =
|
|
8306
|
-
const [notify, setNotify] =
|
|
8307
|
-
const [saving, setSaving] =
|
|
8308
|
-
const [saved, setSaved] =
|
|
8309
|
-
const [prevUserId, setPrevUserId] =
|
|
8360
|
+
const [values, setValues] = React54.useState(initialFieldValues);
|
|
8361
|
+
const [notify, setNotify] = React54.useState(initialNotify);
|
|
8362
|
+
const [saving, setSaving] = React54.useState(false);
|
|
8363
|
+
const [saved, setSaved] = React54.useState(false);
|
|
8364
|
+
const [prevUserId, setPrevUserId] = React54.useState(user.id);
|
|
8310
8365
|
if (user.id !== prevUserId) {
|
|
8311
8366
|
setPrevUserId(user.id);
|
|
8312
8367
|
setValues(initialFieldValues);
|
|
@@ -8494,11 +8549,11 @@ function ProfilePage({
|
|
|
8494
8549
|
}
|
|
8495
8550
|
|
|
8496
8551
|
// src/components/platform/SignInPage.tsx
|
|
8497
|
-
import * as
|
|
8552
|
+
import * as React55 from "react";
|
|
8498
8553
|
import { Fragment as Fragment19, jsx as jsx80, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
8499
8554
|
function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
8500
|
-
const [signingIn, setSigningIn] =
|
|
8501
|
-
const [resuming, setResuming] =
|
|
8555
|
+
const [signingIn, setSigningIn] = React55.useState(false);
|
|
8556
|
+
const [resuming, setResuming] = React55.useState(false);
|
|
8502
8557
|
function handleSignIn() {
|
|
8503
8558
|
setSigningIn(true);
|
|
8504
8559
|
onSignIn();
|
|
@@ -8687,10 +8742,10 @@ function GoogleGlyph() {
|
|
|
8687
8742
|
}
|
|
8688
8743
|
|
|
8689
8744
|
// src/components/platform/RoadmapTimeline.tsx
|
|
8690
|
-
import * as
|
|
8745
|
+
import * as React58 from "react";
|
|
8691
8746
|
|
|
8692
8747
|
// src/kits/session.ts
|
|
8693
|
-
import * as
|
|
8748
|
+
import * as React56 from "react";
|
|
8694
8749
|
var PERMISSION_CATALOG = [
|
|
8695
8750
|
{ group: "Plans", items: [
|
|
8696
8751
|
{ key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
|
|
@@ -10257,8 +10312,8 @@ function roadmap(overrides) {
|
|
|
10257
10312
|
};
|
|
10258
10313
|
}
|
|
10259
10314
|
function useSession() {
|
|
10260
|
-
const [s, setS] =
|
|
10261
|
-
|
|
10315
|
+
const [s, setS] = React56.useState(getSession);
|
|
10316
|
+
React56.useEffect(() => subscribe(setS), []);
|
|
10262
10317
|
return s;
|
|
10263
10318
|
}
|
|
10264
10319
|
var SessionKit = {
|
|
@@ -10291,7 +10346,7 @@ var SessionKit = {
|
|
|
10291
10346
|
};
|
|
10292
10347
|
function DemoSessionProvider({ children }) {
|
|
10293
10348
|
const session = useSession();
|
|
10294
|
-
const value =
|
|
10349
|
+
const value = React56.useMemo(
|
|
10295
10350
|
() => ({
|
|
10296
10351
|
user: session.user,
|
|
10297
10352
|
roles: session.roles,
|
|
@@ -10307,11 +10362,11 @@ function DemoSessionProvider({ children }) {
|
|
|
10307
10362
|
}),
|
|
10308
10363
|
[session]
|
|
10309
10364
|
);
|
|
10310
|
-
return
|
|
10365
|
+
return React56.createElement(SessionProvider, { value }, children);
|
|
10311
10366
|
}
|
|
10312
10367
|
|
|
10313
10368
|
// src/kits/runtime.ts
|
|
10314
|
-
import * as
|
|
10369
|
+
import * as React57 from "react";
|
|
10315
10370
|
var WIRED_ENDPOINTS = [
|
|
10316
10371
|
// Nothing yet. Every id below would come from a real service:
|
|
10317
10372
|
// "plan.get", "placements.list", …
|
|
@@ -10482,8 +10537,8 @@ var RuntimeKit = {
|
|
|
10482
10537
|
};
|
|
10483
10538
|
RuntimeKit.declare(FEATURE_NEEDS);
|
|
10484
10539
|
function useRuntimeMode() {
|
|
10485
|
-
const [m, setM] =
|
|
10486
|
-
|
|
10540
|
+
const [m, setM] = React57.useState(RuntimeKit.getMode());
|
|
10541
|
+
React57.useEffect(() => RuntimeKit.subscribe(setM), []);
|
|
10487
10542
|
return m;
|
|
10488
10543
|
}
|
|
10489
10544
|
function useFeatureStatus(key) {
|
|
@@ -10566,12 +10621,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
10566
10621
|
}
|
|
10567
10622
|
function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
10568
10623
|
const session = SessionKit.useSession();
|
|
10569
|
-
const [project, setProject] =
|
|
10570
|
-
const [q, setQ] =
|
|
10571
|
-
const scrollRef =
|
|
10572
|
-
const nowRef =
|
|
10573
|
-
const rm =
|
|
10574
|
-
const byKey =
|
|
10624
|
+
const [project, setProject] = React58.useState("");
|
|
10625
|
+
const [q, setQ] = React58.useState("");
|
|
10626
|
+
const scrollRef = React58.useRef(null);
|
|
10627
|
+
const nowRef = React58.useRef(null);
|
|
10628
|
+
const rm = React58.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
|
|
10629
|
+
const byKey = React58.useMemo(() => {
|
|
10575
10630
|
const m = {};
|
|
10576
10631
|
rm.items.forEach((i) => {
|
|
10577
10632
|
m[i.key] = i;
|
|
@@ -10580,7 +10635,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10580
10635
|
}, [rm]);
|
|
10581
10636
|
const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
|
|
10582
10637
|
const projects = [...new Set(rm.items.map((i) => i.project))];
|
|
10583
|
-
|
|
10638
|
+
React58.useEffect(() => {
|
|
10584
10639
|
let raf1 = 0, raf2 = 0;
|
|
10585
10640
|
const place = () => {
|
|
10586
10641
|
const box = scrollRef.current, mark = nowRef.current;
|
|
@@ -10654,7 +10709,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10654
10709
|
lastPhase = item.phase;
|
|
10655
10710
|
const inPhase = items.filter((i) => i.phase === item.phase).length;
|
|
10656
10711
|
const isBoundary = n === firstPending;
|
|
10657
|
-
return /* @__PURE__ */ jsxs72(
|
|
10712
|
+
return /* @__PURE__ */ jsxs72(React58.Fragment, { children: [
|
|
10658
10713
|
showPhase ? /* @__PURE__ */ jsxs72("div", { className: "fd-rm-era", children: [
|
|
10659
10714
|
/* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
|
|
10660
10715
|
/* @__PURE__ */ jsx81("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
|
|
@@ -10698,8 +10753,8 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10698
10753
|
}
|
|
10699
10754
|
|
|
10700
10755
|
// src/components/platform/ComingSoon.tsx
|
|
10701
|
-
import * as
|
|
10702
|
-
import { createPortal as
|
|
10756
|
+
import * as React59 from "react";
|
|
10757
|
+
import { createPortal as createPortal6 } from "react-dom";
|
|
10703
10758
|
import { Fragment as Fragment21, jsx as jsx82, jsxs as jsxs73 } from "react/jsx-runtime";
|
|
10704
10759
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
10705
10760
|
function readBypassed() {
|
|
@@ -10716,8 +10771,8 @@ function writeBypassed(list) {
|
|
|
10716
10771
|
}
|
|
10717
10772
|
}
|
|
10718
10773
|
function useBypass(key) {
|
|
10719
|
-
const [on, setOn] =
|
|
10720
|
-
|
|
10774
|
+
const [on, setOn] = React59.useState(() => !!key && readBypassed().indexOf(key) >= 0);
|
|
10775
|
+
React59.useEffect(() => {
|
|
10721
10776
|
setOn(!!key && readBypassed().indexOf(key) >= 0);
|
|
10722
10777
|
}, [key]);
|
|
10723
10778
|
const set = (next) => {
|
|
@@ -10764,9 +10819,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
|
|
|
10764
10819
|
] });
|
|
10765
10820
|
}
|
|
10766
10821
|
function useHoverCard(open2) {
|
|
10767
|
-
const anchor =
|
|
10768
|
-
const [pos, setPos] =
|
|
10769
|
-
|
|
10822
|
+
const anchor = React59.useRef(null);
|
|
10823
|
+
const [pos, setPos] = React59.useState(null);
|
|
10824
|
+
React59.useLayoutEffect(() => {
|
|
10770
10825
|
if (!open2 || !anchor.current) {
|
|
10771
10826
|
setPos(null);
|
|
10772
10827
|
return;
|
|
@@ -10893,12 +10948,12 @@ function ComingSoon({
|
|
|
10893
10948
|
] });
|
|
10894
10949
|
}
|
|
10895
10950
|
function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
|
|
10896
|
-
const [open2, setOpen] =
|
|
10951
|
+
const [open2, setOpen] = React59.useState(false);
|
|
10897
10952
|
const [anchor, pos] = useHoverCard(open2);
|
|
10898
|
-
const hoverCardRef =
|
|
10953
|
+
const hoverCardRef = React59.useRef(null);
|
|
10899
10954
|
const hoverLayer = useStackedLayer({ active: open2, containerRef: hoverCardRef, returnFocus: false });
|
|
10900
10955
|
const zIndex = useLayerZIndex(hoverLayer);
|
|
10901
|
-
const close2 =
|
|
10956
|
+
const close2 = React59.useRef(null);
|
|
10902
10957
|
const show = () => {
|
|
10903
10958
|
if (close2.current) {
|
|
10904
10959
|
clearTimeout(close2.current);
|
|
@@ -10914,7 +10969,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
10914
10969
|
setOpen(false);
|
|
10915
10970
|
}, 140);
|
|
10916
10971
|
};
|
|
10917
|
-
|
|
10972
|
+
React59.useEffect(() => () => {
|
|
10918
10973
|
if (close2.current) clearTimeout(close2.current);
|
|
10919
10974
|
}, []);
|
|
10920
10975
|
return /* @__PURE__ */ jsxs73(
|
|
@@ -10943,7 +10998,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
10943
10998
|
children: /* @__PURE__ */ jsx82("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
|
|
10944
10999
|
}
|
|
10945
11000
|
),
|
|
10946
|
-
open2 && pos ?
|
|
11001
|
+
open2 && pos ? createPortal6(
|
|
10947
11002
|
/* @__PURE__ */ jsx82(
|
|
10948
11003
|
"div",
|
|
10949
11004
|
{
|
|
@@ -11366,7 +11421,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
11366
11421
|
}
|
|
11367
11422
|
|
|
11368
11423
|
// src/components/planner/MixGap.tsx
|
|
11369
|
-
import * as
|
|
11424
|
+
import * as React60 from "react";
|
|
11370
11425
|
import { Fragment as Fragment23, jsx as jsx87, jsxs as jsxs78 } from "react/jsx-runtime";
|
|
11371
11426
|
var MIX_GAP_LAYOUT = {
|
|
11372
11427
|
trackHeight: 30,
|
|
@@ -11381,7 +11436,7 @@ function mixGapOffset(value, max) {
|
|
|
11381
11436
|
}
|
|
11382
11437
|
function MixGap({ rows = [], loading = false, className = "" }) {
|
|
11383
11438
|
const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
|
|
11384
|
-
const [hover, setHover] =
|
|
11439
|
+
const [hover, setHover] = React60.useState(null);
|
|
11385
11440
|
const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
|
|
11386
11441
|
const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
|
|
11387
11442
|
const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
|
|
@@ -11524,7 +11579,7 @@ function ChannelContribution({
|
|
|
11524
11579
|
}
|
|
11525
11580
|
|
|
11526
11581
|
// src/components/planner/BudgetReallocator.tsx
|
|
11527
|
-
import * as
|
|
11582
|
+
import * as React61 from "react";
|
|
11528
11583
|
import { Fragment as Fragment24, jsx as jsx89, jsxs as jsxs80 } from "react/jsx-runtime";
|
|
11529
11584
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
11530
11585
|
function BudgetReallocator({
|
|
@@ -11540,8 +11595,8 @@ function BudgetReallocator({
|
|
|
11540
11595
|
onCancel,
|
|
11541
11596
|
className = ""
|
|
11542
11597
|
}) {
|
|
11543
|
-
const [draft, setDraft] =
|
|
11544
|
-
|
|
11598
|
+
const [draft, setDraft] = React61.useState(spend);
|
|
11599
|
+
React61.useEffect(() => setDraft(spend), [spend]);
|
|
11545
11600
|
const dirty = draft !== spend;
|
|
11546
11601
|
const nextCrp = scoreFor ? scoreFor(draft) : crp;
|
|
11547
11602
|
const nextBand = bandFor(nextCrp);
|
|
@@ -11556,10 +11611,10 @@ function BudgetReallocator({
|
|
|
11556
11611
|
setDraft(spend);
|
|
11557
11612
|
if (onCancel) onCancel();
|
|
11558
11613
|
};
|
|
11559
|
-
const trackRef =
|
|
11560
|
-
const chipRef =
|
|
11561
|
-
const [chipLeft, setChipLeft] =
|
|
11562
|
-
|
|
11614
|
+
const trackRef = React61.useRef(null);
|
|
11615
|
+
const chipRef = React61.useRef(null);
|
|
11616
|
+
const [chipLeft, setChipLeft] = React61.useState(null);
|
|
11617
|
+
React61.useLayoutEffect(() => {
|
|
11563
11618
|
const track = trackRef.current;
|
|
11564
11619
|
if (!dirty || !track) {
|
|
11565
11620
|
setChipLeft(null);
|
|
@@ -11747,7 +11802,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
|
|
|
11747
11802
|
}
|
|
11748
11803
|
|
|
11749
11804
|
// src/components/planner/PreferenceMeter.tsx
|
|
11750
|
-
import * as
|
|
11805
|
+
import * as React62 from "react";
|
|
11751
11806
|
import { jsx as jsx92, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
11752
11807
|
function preferenceScore(criteria) {
|
|
11753
11808
|
const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
|
|
@@ -11777,7 +11832,7 @@ function PreferenceMeter({
|
|
|
11777
11832
|
className = ""
|
|
11778
11833
|
}) {
|
|
11779
11834
|
const value = score == null ? preferenceScore(criteria) : score;
|
|
11780
|
-
const segments =
|
|
11835
|
+
const segments = React62.useMemo(() => preferenceSegments(criteria), [criteria]);
|
|
11781
11836
|
return /* @__PURE__ */ jsx92(
|
|
11782
11837
|
ScoreMeter,
|
|
11783
11838
|
{
|
|
@@ -11816,10 +11871,10 @@ function PreferenceMeter({
|
|
|
11816
11871
|
}
|
|
11817
11872
|
|
|
11818
11873
|
// src/components/chat/AgentChatPanel.tsx
|
|
11819
|
-
import * as
|
|
11874
|
+
import * as React68 from "react";
|
|
11820
11875
|
|
|
11821
11876
|
// src/components/chat/chatEngine.ts
|
|
11822
|
-
import * as
|
|
11877
|
+
import * as React63 from "react";
|
|
11823
11878
|
var CHAT_UNAVAILABLE = "chat_unavailable";
|
|
11824
11879
|
var JOB_PENDING = ["queued", "running"];
|
|
11825
11880
|
var JOB_SUCCESS = ["completed", "recovered"];
|
|
@@ -11873,22 +11928,22 @@ function useChatEngine(opts) {
|
|
|
11873
11928
|
onClear,
|
|
11874
11929
|
onFeedback
|
|
11875
11930
|
} = opts || {};
|
|
11876
|
-
const [status, setStatus] =
|
|
11877
|
-
const [threadId, setThreadId] =
|
|
11878
|
-
const [messages, setMessages] =
|
|
11879
|
-
const [queue, setQueue] =
|
|
11880
|
-
const [fatal, setFatal] =
|
|
11881
|
-
const [busy, setBusy] =
|
|
11882
|
-
const [turnStartedAt, setTurnStartedAt] =
|
|
11883
|
-
const listRef =
|
|
11884
|
-
const queueRef =
|
|
11885
|
-
const busyRef =
|
|
11886
|
-
const stoppedRef =
|
|
11887
|
-
const abortRef =
|
|
11888
|
-
const serverCount =
|
|
11889
|
-
const threadRef =
|
|
11890
|
-
const mounted =
|
|
11891
|
-
|
|
11931
|
+
const [status, setStatus] = React63.useState("idle");
|
|
11932
|
+
const [threadId, setThreadId] = React63.useState(null);
|
|
11933
|
+
const [messages, setMessages] = React63.useState([]);
|
|
11934
|
+
const [queue, setQueue] = React63.useState([]);
|
|
11935
|
+
const [fatal, setFatal] = React63.useState(null);
|
|
11936
|
+
const [busy, setBusy] = React63.useState(false);
|
|
11937
|
+
const [turnStartedAt, setTurnStartedAt] = React63.useState(null);
|
|
11938
|
+
const listRef = React63.useRef([]);
|
|
11939
|
+
const queueRef = React63.useRef([]);
|
|
11940
|
+
const busyRef = React63.useRef(false);
|
|
11941
|
+
const stoppedRef = React63.useRef(false);
|
|
11942
|
+
const abortRef = React63.useRef(null);
|
|
11943
|
+
const serverCount = React63.useRef(0);
|
|
11944
|
+
const threadRef = React63.useRef(null);
|
|
11945
|
+
const mounted = React63.useRef(true);
|
|
11946
|
+
React63.useEffect(() => {
|
|
11892
11947
|
mounted.current = true;
|
|
11893
11948
|
return () => {
|
|
11894
11949
|
mounted.current = false;
|
|
@@ -11910,14 +11965,14 @@ function useChatEngine(opts) {
|
|
|
11910
11965
|
}
|
|
11911
11966
|
return false;
|
|
11912
11967
|
};
|
|
11913
|
-
const loadThread =
|
|
11968
|
+
const loadThread = React63.useCallback(async (id) => {
|
|
11914
11969
|
const data = await apiAdapter.getThread(id);
|
|
11915
11970
|
const list = [...data && data.messages || []];
|
|
11916
11971
|
serverCount.current = list.length;
|
|
11917
11972
|
commit(list);
|
|
11918
11973
|
return list;
|
|
11919
11974
|
}, [apiAdapter]);
|
|
11920
|
-
|
|
11975
|
+
React63.useEffect(() => {
|
|
11921
11976
|
if (!apiAdapter) {
|
|
11922
11977
|
setStatus("idle");
|
|
11923
11978
|
setFatal(null);
|
|
@@ -12130,7 +12185,7 @@ function useChatEngine(opts) {
|
|
|
12130
12185
|
await dispatchTurn(turn);
|
|
12131
12186
|
}
|
|
12132
12187
|
}
|
|
12133
|
-
const send =
|
|
12188
|
+
const send = React63.useCallback((text, attachments) => {
|
|
12134
12189
|
const body = (text || "").trim();
|
|
12135
12190
|
if (!body && !(attachments && attachments.length)) return;
|
|
12136
12191
|
if (status === "disconnected") return;
|
|
@@ -12140,7 +12195,7 @@ function useChatEngine(opts) {
|
|
|
12140
12195
|
stoppedRef.current = false;
|
|
12141
12196
|
drain();
|
|
12142
12197
|
}, [status]);
|
|
12143
|
-
const stop =
|
|
12198
|
+
const stop = React63.useCallback(() => {
|
|
12144
12199
|
stoppedRef.current = true;
|
|
12145
12200
|
const ac = abortRef.current;
|
|
12146
12201
|
if (ac) {
|
|
@@ -12159,11 +12214,11 @@ function useChatEngine(opts) {
|
|
|
12159
12214
|
store.del(STORAGE_PREFIX + threadRef.current);
|
|
12160
12215
|
}
|
|
12161
12216
|
}, [apiAdapter]);
|
|
12162
|
-
const removeQueued =
|
|
12217
|
+
const removeQueued = React63.useCallback((id) => {
|
|
12163
12218
|
queueRef.current = queueRef.current.filter((t) => t.id !== id);
|
|
12164
12219
|
setQueue(queueRef.current.slice());
|
|
12165
12220
|
}, []);
|
|
12166
|
-
const retry =
|
|
12221
|
+
const retry = React63.useCallback(() => {
|
|
12167
12222
|
const list = listRef.current;
|
|
12168
12223
|
let at = -1;
|
|
12169
12224
|
for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
|
|
@@ -12179,19 +12234,19 @@ function useChatEngine(opts) {
|
|
|
12179
12234
|
setQueue(queueRef.current.slice());
|
|
12180
12235
|
drain();
|
|
12181
12236
|
}, []);
|
|
12182
|
-
const clear =
|
|
12237
|
+
const clear = React63.useCallback(() => {
|
|
12183
12238
|
commit([]);
|
|
12184
12239
|
serverCount.current = 0;
|
|
12185
12240
|
queueRef.current = [];
|
|
12186
12241
|
setQueue([]);
|
|
12187
12242
|
onClear && onClear();
|
|
12188
12243
|
}, [onClear]);
|
|
12189
|
-
const setFeedback =
|
|
12244
|
+
const setFeedback = React63.useCallback((id, value) => {
|
|
12190
12245
|
patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
|
|
12191
12246
|
const msg = listRef.current.find((m) => m.id === id);
|
|
12192
12247
|
onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
|
|
12193
12248
|
}, [onFeedback]);
|
|
12194
|
-
const reload =
|
|
12249
|
+
const reload = React63.useCallback(async () => {
|
|
12195
12250
|
if (!threadRef.current) return;
|
|
12196
12251
|
setStatus("loading");
|
|
12197
12252
|
try {
|
|
@@ -12229,10 +12284,10 @@ var ChatKit = {
|
|
|
12229
12284
|
};
|
|
12230
12285
|
|
|
12231
12286
|
// src/components/chat/ChatTranscript.tsx
|
|
12232
|
-
import * as
|
|
12287
|
+
import * as React65 from "react";
|
|
12233
12288
|
|
|
12234
12289
|
// src/components/chat/ChatTurn.tsx
|
|
12235
|
-
import * as
|
|
12290
|
+
import * as React64 from "react";
|
|
12236
12291
|
import { jsx as jsx93, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
12237
12292
|
function JsonView({ value }) {
|
|
12238
12293
|
let text;
|
|
@@ -12269,7 +12324,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
|
12269
12324
|
] });
|
|
12270
12325
|
}
|
|
12271
12326
|
function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
12272
|
-
const [open2, setOpen] =
|
|
12327
|
+
const [open2, setOpen] = React64.useState(defaultOpen);
|
|
12273
12328
|
if (!text) return null;
|
|
12274
12329
|
return /* @__PURE__ */ jsxs84("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
|
|
12275
12330
|
/* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -12286,7 +12341,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
|
12286
12341
|
] });
|
|
12287
12342
|
}
|
|
12288
12343
|
function Citations({ items = [], onOpen }) {
|
|
12289
|
-
const [open2, setOpen] =
|
|
12344
|
+
const [open2, setOpen] = React64.useState(false);
|
|
12290
12345
|
if (!items.length) return null;
|
|
12291
12346
|
return /* @__PURE__ */ jsxs84("div", { className: "fdc-cites", children: [
|
|
12292
12347
|
/* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -12312,7 +12367,7 @@ function clampText(text, max) {
|
|
|
12312
12367
|
return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
12313
12368
|
}
|
|
12314
12369
|
function MessageBody({ message: m, ctx }) {
|
|
12315
|
-
const [expanded, setExpanded] =
|
|
12370
|
+
const [expanded, setExpanded] = React64.useState(false);
|
|
12316
12371
|
const isUser = m.role === "user";
|
|
12317
12372
|
const raw = m.text || "";
|
|
12318
12373
|
const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
|
|
@@ -12392,7 +12447,7 @@ function RunActions({ group, ctx }) {
|
|
|
12392
12447
|
] }),
|
|
12393
12448
|
isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
|
|
12394
12449
|
group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
|
|
12395
|
-
isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs84(
|
|
12450
|
+
isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs84(React64.Fragment, { children: [
|
|
12396
12451
|
/* @__PURE__ */ jsx93("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__ */ jsx93("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
|
|
12397
12452
|
/* @__PURE__ */ jsx93("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__ */ jsx93("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
|
|
12398
12453
|
] }) : null,
|
|
@@ -12487,10 +12542,10 @@ function ChatTranscript({
|
|
|
12487
12542
|
renderEmpty,
|
|
12488
12543
|
className = ""
|
|
12489
12544
|
}) {
|
|
12490
|
-
const scroller =
|
|
12491
|
-
const stick =
|
|
12492
|
-
const [pill, setPill] =
|
|
12493
|
-
const seen =
|
|
12545
|
+
const scroller = React65.useRef(null);
|
|
12546
|
+
const stick = React65.useRef(true);
|
|
12547
|
+
const [pill, setPill] = React65.useState(0);
|
|
12548
|
+
const seen = React65.useRef(0);
|
|
12494
12549
|
const toBottom = (smooth) => {
|
|
12495
12550
|
const el = scroller.current;
|
|
12496
12551
|
if (!el) return;
|
|
@@ -12509,7 +12564,7 @@ function ChatTranscript({
|
|
|
12509
12564
|
seen.current = messages.length;
|
|
12510
12565
|
}
|
|
12511
12566
|
};
|
|
12512
|
-
|
|
12567
|
+
React65.useLayoutEffect(() => {
|
|
12513
12568
|
const el = scroller.current;
|
|
12514
12569
|
if (!el) return;
|
|
12515
12570
|
if (stick.current) {
|
|
@@ -12517,7 +12572,7 @@ function ChatTranscript({
|
|
|
12517
12572
|
seen.current = messages.length;
|
|
12518
12573
|
} else setPill(Math.max(0, messages.length - seen.current));
|
|
12519
12574
|
}, [messages]);
|
|
12520
|
-
|
|
12575
|
+
React65.useEffect(() => {
|
|
12521
12576
|
const el = scroller.current;
|
|
12522
12577
|
const inner = el && el.firstChild;
|
|
12523
12578
|
if (!el || !inner || typeof ResizeObserver === "undefined") return;
|
|
@@ -12527,7 +12582,7 @@ function ChatTranscript({
|
|
|
12527
12582
|
ro.observe(inner);
|
|
12528
12583
|
return () => ro.disconnect();
|
|
12529
12584
|
}, []);
|
|
12530
|
-
const groups =
|
|
12585
|
+
const groups = React65.useMemo(() => groupMessages(messages), [messages]);
|
|
12531
12586
|
const empty = !messages.length && status === "ready";
|
|
12532
12587
|
return /* @__PURE__ */ jsxs85("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
|
|
12533
12588
|
/* @__PURE__ */ jsxs85("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
|
|
@@ -12551,7 +12606,7 @@ function ChatTranscript({
|
|
|
12551
12606
|
const prev = groups[i - 1];
|
|
12552
12607
|
const k = dayKey(g.messages[0].timestamp);
|
|
12553
12608
|
const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
|
|
12554
|
-
return /* @__PURE__ */ jsxs85(
|
|
12609
|
+
return /* @__PURE__ */ jsxs85(React65.Fragment, { children: [
|
|
12555
12610
|
showDay ? /* @__PURE__ */ jsx94("div", { className: "fdc-day", children: /* @__PURE__ */ jsx94("span", { children: dayLabel(k) }) }) : null,
|
|
12556
12611
|
/* @__PURE__ */ jsx94(ChatTurn, { group: g, ctx })
|
|
12557
12612
|
] }, g.key || i);
|
|
@@ -12568,7 +12623,7 @@ function ChatTranscript({
|
|
|
12568
12623
|
var TranscriptKit = { groupMessages };
|
|
12569
12624
|
|
|
12570
12625
|
// src/components/chat/ChatComposer.tsx
|
|
12571
|
-
import * as
|
|
12626
|
+
import * as React66 from "react";
|
|
12572
12627
|
import { jsx as jsx95, jsxs as jsxs86 } from "react/jsx-runtime";
|
|
12573
12628
|
function ChatComposer({
|
|
12574
12629
|
onSubmit,
|
|
@@ -12596,17 +12651,17 @@ function ChatComposer({
|
|
|
12596
12651
|
onReject,
|
|
12597
12652
|
onOpenAttachment
|
|
12598
12653
|
}) {
|
|
12599
|
-
const [text, setText] =
|
|
12600
|
-
const [trigger, setTrigger] =
|
|
12601
|
-
const [mentionItems, setMentionItems] =
|
|
12602
|
-
const [listening, setListening] =
|
|
12603
|
-
const [notice, setNotice] =
|
|
12604
|
-
const editor =
|
|
12605
|
-
const wrap =
|
|
12606
|
-
const stopVoice =
|
|
12654
|
+
const [text, setText] = React66.useState(draft || "");
|
|
12655
|
+
const [trigger, setTrigger] = React66.useState(null);
|
|
12656
|
+
const [mentionItems, setMentionItems] = React66.useState([]);
|
|
12657
|
+
const [listening, setListening] = React66.useState(false);
|
|
12658
|
+
const [notice, setNotice] = React66.useState(null);
|
|
12659
|
+
const editor = React66.useRef(null);
|
|
12660
|
+
const wrap = React66.useRef(null);
|
|
12661
|
+
const stopVoice = React66.useRef(null);
|
|
12607
12662
|
const staged = useStagedFiles(fileUploadHandler, { onError: () => {
|
|
12608
12663
|
} });
|
|
12609
|
-
|
|
12664
|
+
React66.useEffect(() => {
|
|
12610
12665
|
if (draft != null && draft !== text) setText(draft);
|
|
12611
12666
|
}, [draft]);
|
|
12612
12667
|
const change = (v) => {
|
|
@@ -12642,7 +12697,7 @@ function ChatComposer({
|
|
|
12642
12697
|
e.preventDefault();
|
|
12643
12698
|
staged.add(found.files);
|
|
12644
12699
|
};
|
|
12645
|
-
|
|
12700
|
+
React66.useEffect(() => {
|
|
12646
12701
|
if (!trigger || trigger.type !== "mention" || !mentionSources) {
|
|
12647
12702
|
setMentionItems([]);
|
|
12648
12703
|
return;
|
|
@@ -12660,7 +12715,7 @@ function ChatComposer({
|
|
|
12660
12715
|
const q = (trigger.query || "").toLowerCase();
|
|
12661
12716
|
setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
|
|
12662
12717
|
}, [trigger, mentionSources]);
|
|
12663
|
-
const slashItems =
|
|
12718
|
+
const slashItems = React66.useMemo(() => {
|
|
12664
12719
|
if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
|
|
12665
12720
|
const q = (trigger.query || "").toLowerCase();
|
|
12666
12721
|
return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
|
|
@@ -12830,12 +12885,12 @@ function ChatComposer({
|
|
|
12830
12885
|
}
|
|
12831
12886
|
|
|
12832
12887
|
// src/components/chat/ChatSessionBar.tsx
|
|
12833
|
-
import * as
|
|
12888
|
+
import * as React67 from "react";
|
|
12834
12889
|
import { jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
12835
12890
|
var compact2 = meterFormats.compact;
|
|
12836
12891
|
function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
|
|
12837
|
-
const [open2, setOpen] =
|
|
12838
|
-
const anchor =
|
|
12892
|
+
const [open2, setOpen] = React67.useState(false);
|
|
12893
|
+
const anchor = React67.useRef(null);
|
|
12839
12894
|
const stats = sessionStats || null;
|
|
12840
12895
|
const cu = contextUsage || null;
|
|
12841
12896
|
const limits = usageLimits || null;
|
|
@@ -12850,7 +12905,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
12850
12905
|
if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
|
|
12851
12906
|
if (cu) bits.push(pct + "% context");
|
|
12852
12907
|
const expandable = !!(cu || limits);
|
|
12853
|
-
return /* @__PURE__ */ jsxs87(
|
|
12908
|
+
return /* @__PURE__ */ jsxs87(React67.Fragment, { children: [
|
|
12854
12909
|
/* @__PURE__ */ jsxs87("div", { className: "fdc-bar", children: [
|
|
12855
12910
|
/* @__PURE__ */ jsxs87(
|
|
12856
12911
|
"button",
|
|
@@ -12991,7 +13046,7 @@ function ModelControls({
|
|
|
12991
13046
|
] })
|
|
12992
13047
|
});
|
|
12993
13048
|
}
|
|
12994
|
-
return /* @__PURE__ */ jsxs87(
|
|
13049
|
+
return /* @__PURE__ */ jsxs87(React67.Fragment, { children: [
|
|
12995
13050
|
/* @__PURE__ */ jsx96(
|
|
12996
13051
|
MenuButton,
|
|
12997
13052
|
{
|
|
@@ -13108,11 +13163,11 @@ function AgentChatPanel({
|
|
|
13108
13163
|
onFeedback,
|
|
13109
13164
|
onEditMessage
|
|
13110
13165
|
}) {
|
|
13111
|
-
const [panelWidth, setPanelWidth] =
|
|
13112
|
-
const [applied, setApplied] =
|
|
13113
|
-
const [draft, setDraft] =
|
|
13114
|
-
const dragging =
|
|
13115
|
-
|
|
13166
|
+
const [panelWidth, setPanelWidth] = React68.useState(width);
|
|
13167
|
+
const [applied, setApplied] = React68.useState({});
|
|
13168
|
+
const [draft, setDraft] = React68.useState("");
|
|
13169
|
+
const dragging = React68.useRef(null);
|
|
13170
|
+
React68.useEffect(() => setPanelWidth(width), [width]);
|
|
13116
13171
|
const engine = useChatEngine({
|
|
13117
13172
|
contextType,
|
|
13118
13173
|
contextId,
|
|
@@ -13316,7 +13371,7 @@ function AgentChatPanel({
|
|
|
13316
13371
|
}
|
|
13317
13372
|
|
|
13318
13373
|
// src/components/files/FileViewer.tsx
|
|
13319
|
-
import * as
|
|
13374
|
+
import * as React69 from "react";
|
|
13320
13375
|
import { jsx as jsx98, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
13321
13376
|
function previewKindOf(file) {
|
|
13322
13377
|
const mime = (file.mime || "").toLowerCase();
|
|
@@ -13373,13 +13428,13 @@ function parseDelimited(text, delimiter) {
|
|
|
13373
13428
|
return rows;
|
|
13374
13429
|
}
|
|
13375
13430
|
function usePreview(file, kind, resolveUrl) {
|
|
13376
|
-
const [state, setState] =
|
|
13377
|
-
const [attempt, setAttempt] =
|
|
13378
|
-
const resolveRef =
|
|
13379
|
-
|
|
13431
|
+
const [state, setState] = React69.useState({ status: "loading" });
|
|
13432
|
+
const [attempt, setAttempt] = React69.useState(0);
|
|
13433
|
+
const resolveRef = React69.useRef(resolveUrl);
|
|
13434
|
+
React69.useEffect(() => {
|
|
13380
13435
|
resolveRef.current = resolveUrl;
|
|
13381
13436
|
}, [resolveUrl]);
|
|
13382
|
-
|
|
13437
|
+
React69.useEffect(() => {
|
|
13383
13438
|
if (kind === "none") {
|
|
13384
13439
|
setState({ status: "ready" });
|
|
13385
13440
|
return;
|
|
@@ -13409,7 +13464,7 @@ function usePreview(file, kind, resolveUrl) {
|
|
|
13409
13464
|
if (ac) ac.abort();
|
|
13410
13465
|
};
|
|
13411
13466
|
}, [file.id, kind, attempt]);
|
|
13412
|
-
return { ...state, retry:
|
|
13467
|
+
return { ...state, retry: React69.useCallback(() => setAttempt((a) => a + 1), []) };
|
|
13413
13468
|
}
|
|
13414
13469
|
function PreviewBody({ file, kind, state }) {
|
|
13415
13470
|
if (kind === "image") return /* @__PURE__ */ jsx98("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
|
|
@@ -13454,13 +13509,13 @@ function PreviewBody({ file, kind, state }) {
|
|
|
13454
13509
|
] });
|
|
13455
13510
|
}
|
|
13456
13511
|
function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
|
|
13457
|
-
const kind =
|
|
13512
|
+
const kind = React69.useMemo(() => previewKindOf(file), [file]);
|
|
13458
13513
|
const preview = usePreview(file, kind, resolveUrl);
|
|
13459
|
-
const [tab, setTab] =
|
|
13460
|
-
const [downloading, setDownloading] =
|
|
13461
|
-
const [downloadError, setDownloadError] =
|
|
13514
|
+
const [tab, setTab] = React69.useState("preview");
|
|
13515
|
+
const [downloading, setDownloading] = React69.useState(false);
|
|
13516
|
+
const [downloadError, setDownloadError] = React69.useState(null);
|
|
13462
13517
|
const hasSide = sidePanel != null;
|
|
13463
|
-
|
|
13518
|
+
React69.useEffect(() => {
|
|
13464
13519
|
setTab("preview");
|
|
13465
13520
|
}, [file.id]);
|
|
13466
13521
|
const download = () => {
|
|
@@ -13527,7 +13582,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
13527
13582
|
}
|
|
13528
13583
|
|
|
13529
13584
|
// src/components/files/FileBrowser.tsx
|
|
13530
|
-
import * as
|
|
13585
|
+
import * as React70 from "react";
|
|
13531
13586
|
import { Fragment as Fragment28, jsx as jsx99, jsxs as jsxs90 } from "react/jsx-runtime";
|
|
13532
13587
|
function childrenOf(folders, parentId) {
|
|
13533
13588
|
return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -13637,8 +13692,8 @@ function FolderPickerMenu({
|
|
|
13637
13692
|
] });
|
|
13638
13693
|
}
|
|
13639
13694
|
function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
|
|
13640
|
-
const [over, setOver] =
|
|
13641
|
-
const dragCounter =
|
|
13695
|
+
const [over, setOver] = React70.useState(false);
|
|
13696
|
+
const dragCounter = React70.useRef(0);
|
|
13642
13697
|
const dropHandlers = isDropTarget ? {
|
|
13643
13698
|
onDragEnter: (e) => {
|
|
13644
13699
|
if (!hasInternalPayload(e)) return;
|
|
@@ -13686,8 +13741,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
|
|
|
13686
13741
|
}
|
|
13687
13742
|
function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
|
|
13688
13743
|
const kids = childrenOf(folders, folder.id);
|
|
13689
|
-
const [expanded, setExpanded] =
|
|
13690
|
-
|
|
13744
|
+
const [expanded, setExpanded] = React70.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
|
|
13745
|
+
React70.useEffect(() => {
|
|
13691
13746
|
if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
|
|
13692
13747
|
}, [currentFolderId, folder.id, folders]);
|
|
13693
13748
|
const isCurrent = folder.id === currentFolderId;
|
|
@@ -13753,15 +13808,15 @@ function FileBrowser({
|
|
|
13753
13808
|
const canUpload = perm.canUpload !== false && !!onUpload;
|
|
13754
13809
|
const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
|
|
13755
13810
|
const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
|
|
13756
|
-
const [createOpen, setCreateOpen] =
|
|
13757
|
-
const [createName, setCreateName] =
|
|
13758
|
-
const [renameTarget, setRenameTarget] =
|
|
13759
|
-
const [renameValue, setRenameValue] =
|
|
13760
|
-
const [deleteTarget, setDeleteTarget] =
|
|
13761
|
-
const uploadInputRef =
|
|
13762
|
-
const crumbFolders =
|
|
13763
|
-
const subfolders =
|
|
13764
|
-
const currentFiles =
|
|
13811
|
+
const [createOpen, setCreateOpen] = React70.useState(false);
|
|
13812
|
+
const [createName, setCreateName] = React70.useState("");
|
|
13813
|
+
const [renameTarget, setRenameTarget] = React70.useState(null);
|
|
13814
|
+
const [renameValue, setRenameValue] = React70.useState("");
|
|
13815
|
+
const [deleteTarget, setDeleteTarget] = React70.useState(null);
|
|
13816
|
+
const uploadInputRef = React70.useRef(null);
|
|
13817
|
+
const crumbFolders = React70.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
13818
|
+
const subfolders = React70.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
|
|
13819
|
+
const currentFiles = React70.useMemo(
|
|
13765
13820
|
() => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
|
|
13766
13821
|
[files, currentFolderId]
|
|
13767
13822
|
);
|
|
@@ -13993,8 +14048,8 @@ function BreadcrumbCrumb({
|
|
|
13993
14048
|
isDropTarget,
|
|
13994
14049
|
onDropPayload
|
|
13995
14050
|
}) {
|
|
13996
|
-
const [over, setOver] =
|
|
13997
|
-
const dragCounter =
|
|
14051
|
+
const [over, setOver] = React70.useState(false);
|
|
14052
|
+
const dragCounter = React70.useRef(0);
|
|
13998
14053
|
const dropHandlers = isDropTarget ? {
|
|
13999
14054
|
onDragEnter: (e) => {
|
|
14000
14055
|
if (!hasInternalPayload(e)) return;
|
|
@@ -14023,7 +14078,7 @@ function BreadcrumbCrumb({
|
|
|
14023
14078
|
}
|
|
14024
14079
|
|
|
14025
14080
|
// src/kits/query.ts
|
|
14026
|
-
import * as
|
|
14081
|
+
import * as React71 from "react";
|
|
14027
14082
|
var isMultiSelectShaped = (v) => !!v && typeof v === "object" && Array.isArray(v.values);
|
|
14028
14083
|
var isRangeShaped = (v) => !!v && typeof v === "object" && ("min" in v || "max" in v);
|
|
14029
14084
|
var isDateShaped = (v) => !!v && typeof v === "object" && "kind" in v;
|
|
@@ -14078,22 +14133,22 @@ function compare(a, b, dir) {
|
|
|
14078
14133
|
var API = null;
|
|
14079
14134
|
var PREFS = null;
|
|
14080
14135
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
|
|
14081
|
-
const [query, setQuery] =
|
|
14136
|
+
const [query, setQuery] = React71.useState(() => {
|
|
14082
14137
|
const store = PREFS || window.PlannerPrefs;
|
|
14083
14138
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
14084
14139
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
14085
14140
|
});
|
|
14086
|
-
const savePref =
|
|
14141
|
+
const savePref = React71.useCallback((patch2) => {
|
|
14087
14142
|
const store = PREFS || window.PlannerPrefs;
|
|
14088
14143
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
14089
14144
|
}, [prefsKey]);
|
|
14090
|
-
const [res, setRes] =
|
|
14091
|
-
const [loading, setLoading] =
|
|
14092
|
-
const seq2 =
|
|
14145
|
+
const [res, setRes] = React71.useState(null);
|
|
14146
|
+
const [loading, setLoading] = React71.useState(true);
|
|
14147
|
+
const seq2 = React71.useRef(0);
|
|
14093
14148
|
const depKey = (deps || []).join("|");
|
|
14094
14149
|
const paramKey = JSON.stringify(params || {});
|
|
14095
14150
|
const queryKey = JSON.stringify(query);
|
|
14096
|
-
|
|
14151
|
+
React71.useEffect(() => {
|
|
14097
14152
|
const id = ++seq2.current;
|
|
14098
14153
|
setLoading(true);
|
|
14099
14154
|
const t = setTimeout(() => {
|
|
@@ -14412,12 +14467,12 @@ function createVersionStore(initialState, options) {
|
|
|
14412
14467
|
}
|
|
14413
14468
|
|
|
14414
14469
|
// src/kits/documentTitle.ts
|
|
14415
|
-
import * as
|
|
14470
|
+
import * as React72 from "react";
|
|
14416
14471
|
function formatDocumentTitle(routeTitle, appName) {
|
|
14417
14472
|
return [routeTitle, appName, "Flytedesk"].filter((part) => !!part && part.length > 0).join(" \xB7 ");
|
|
14418
14473
|
}
|
|
14419
14474
|
function useDocumentTitle(routeTitle, appName) {
|
|
14420
|
-
|
|
14475
|
+
React72.useEffect(() => {
|
|
14421
14476
|
if (typeof document === "undefined") return;
|
|
14422
14477
|
document.title = formatDocumentTitle(routeTitle, appName);
|
|
14423
14478
|
}, [routeTitle, appName]);
|
|
@@ -14463,6 +14518,7 @@ export {
|
|
|
14463
14518
|
CodeEditor,
|
|
14464
14519
|
Collapsible,
|
|
14465
14520
|
ComingSoon,
|
|
14521
|
+
CornerStackPortal,
|
|
14466
14522
|
CsiBadge,
|
|
14467
14523
|
CsiHero,
|
|
14468
14524
|
CsiMeter,
|
|
@@ -14631,6 +14687,7 @@ export {
|
|
|
14631
14687
|
useAppearancePrefs,
|
|
14632
14688
|
useChatEngine,
|
|
14633
14689
|
useCopyToClipboard,
|
|
14690
|
+
useCornerStackSlot,
|
|
14634
14691
|
useDocumentTitle,
|
|
14635
14692
|
useFeatureStatus,
|
|
14636
14693
|
useLayerZIndex,
|