@flytedan/flytebot-design-system 0.51.3 → 0.51.5
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 +514 -457
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -7
- package/dist/index.d.ts +27 -7
- package/dist/index.js +512 -457
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components.css +61 -36
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();
|
|
@@ -4591,10 +4644,10 @@ function StatTile({ label, value, sub, delta, invert = false, loading = false, c
|
|
|
4591
4644
|
}
|
|
4592
4645
|
|
|
4593
4646
|
// src/components/data/CodeBlock.tsx
|
|
4594
|
-
import * as
|
|
4647
|
+
import * as React31 from "react";
|
|
4595
4648
|
|
|
4596
4649
|
// src/kits/clipboard.ts
|
|
4597
|
-
import * as
|
|
4650
|
+
import * as React30 from "react";
|
|
4598
4651
|
var COPIED_FEEDBACK_MS = 1600;
|
|
4599
4652
|
function copyThroughSelection(text) {
|
|
4600
4653
|
const previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -4624,17 +4677,17 @@ async function copyToClipboard(text) {
|
|
|
4624
4677
|
return copyThroughSelection(text);
|
|
4625
4678
|
}
|
|
4626
4679
|
function useCopyToClipboard() {
|
|
4627
|
-
const [copied, setCopied] =
|
|
4628
|
-
const timer =
|
|
4629
|
-
const mounted =
|
|
4630
|
-
|
|
4680
|
+
const [copied, setCopied] = React30.useState(false);
|
|
4681
|
+
const timer = React30.useRef(null);
|
|
4682
|
+
const mounted = React30.useRef(true);
|
|
4683
|
+
React30.useEffect(() => {
|
|
4631
4684
|
mounted.current = true;
|
|
4632
4685
|
return () => {
|
|
4633
4686
|
mounted.current = false;
|
|
4634
4687
|
if (timer.current) clearTimeout(timer.current);
|
|
4635
4688
|
};
|
|
4636
4689
|
}, []);
|
|
4637
|
-
const copy =
|
|
4690
|
+
const copy = React30.useCallback(async (text) => {
|
|
4638
4691
|
const ok = await copyToClipboard(text);
|
|
4639
4692
|
if (ok && mounted.current) {
|
|
4640
4693
|
setCopied(true);
|
|
@@ -4802,7 +4855,7 @@ function tokenize(src, lang) {
|
|
|
4802
4855
|
return out;
|
|
4803
4856
|
}
|
|
4804
4857
|
function Highlighted({ code, lang }) {
|
|
4805
|
-
const toks =
|
|
4858
|
+
const toks = React31.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
4806
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) });
|
|
4807
4860
|
}
|
|
4808
4861
|
function CodeBlock({
|
|
@@ -4816,8 +4869,8 @@ function CodeBlock({
|
|
|
4816
4869
|
actions,
|
|
4817
4870
|
className = ""
|
|
4818
4871
|
}) {
|
|
4819
|
-
const [wrap, setWrap] =
|
|
4820
|
-
const [open2, setOpen] =
|
|
4872
|
+
const [wrap, setWrap] = React31.useState(!!wrapDefault);
|
|
4873
|
+
const [open2, setOpen] = React31.useState(false);
|
|
4821
4874
|
const [copied, copy] = useCopyToClipboard();
|
|
4822
4875
|
const body = String(code).replace(/\n$/, "");
|
|
4823
4876
|
const lines = body.split("\n");
|
|
@@ -4846,7 +4899,7 @@ function CodeBlock({
|
|
|
4846
4899
|
] });
|
|
4847
4900
|
}
|
|
4848
4901
|
function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
|
|
4849
|
-
const [open2, setOpen] =
|
|
4902
|
+
const [open2, setOpen] = React31.useState(false);
|
|
4850
4903
|
const [copied, copy] = useCopyToClipboard();
|
|
4851
4904
|
const raw = String(diff).replace(/\n$/, "");
|
|
4852
4905
|
const all = raw.split("\n").map((line) => {
|
|
@@ -4892,7 +4945,7 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
4892
4945
|
}
|
|
4893
4946
|
|
|
4894
4947
|
// src/components/data/Markdown.tsx
|
|
4895
|
-
import * as
|
|
4948
|
+
import * as React32 from "react";
|
|
4896
4949
|
import { jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
4897
4950
|
var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
|
|
4898
4951
|
var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
|
|
@@ -4931,7 +4984,7 @@ function inlineNodes(src, ctx, keyBase) {
|
|
|
4931
4984
|
const href = safeHref(g(2));
|
|
4932
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()));
|
|
4933
4986
|
} else if (kind === "cite") {
|
|
4934
|
-
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()));
|
|
4935
4988
|
} else if (kind === "strongem") out.push(/* @__PURE__ */ jsx52("strong", { children: /* @__PURE__ */ jsx52("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
|
|
4936
4989
|
else if (kind === "strong") out.push(/* @__PURE__ */ jsx52("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
4937
4990
|
else if (kind === "em") out.push(/* @__PURE__ */ jsx52("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
@@ -5096,7 +5149,7 @@ function Markdown({
|
|
|
5096
5149
|
onLinkClick
|
|
5097
5150
|
}) {
|
|
5098
5151
|
const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
|
|
5099
|
-
const blocks =
|
|
5152
|
+
const blocks = React32.useMemo(() => parseBlocks(source), [source]);
|
|
5100
5153
|
return /* @__PURE__ */ jsx52("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
|
|
5101
5154
|
}
|
|
5102
5155
|
function MarkdownInline({ source = "", className = "", onLinkClick }) {
|
|
@@ -5210,7 +5263,7 @@ function Pagination({
|
|
|
5210
5263
|
}
|
|
5211
5264
|
|
|
5212
5265
|
// src/components/data/RelativeTime.tsx
|
|
5213
|
-
import * as
|
|
5266
|
+
import * as React33 from "react";
|
|
5214
5267
|
import { jsxs as jsxs47 } from "react/jsx-runtime";
|
|
5215
5268
|
var MIN = 6e4;
|
|
5216
5269
|
var HOUR = 36e5;
|
|
@@ -5262,9 +5315,9 @@ function formatDuration(ms) {
|
|
|
5262
5315
|
return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
|
|
5263
5316
|
}
|
|
5264
5317
|
function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
|
|
5265
|
-
const [, force] =
|
|
5318
|
+
const [, force] = React33.useState(0);
|
|
5266
5319
|
const t = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
5267
|
-
|
|
5320
|
+
React33.useEffect(() => {
|
|
5268
5321
|
if (!refresh2 || !t || isNaN(t)) return;
|
|
5269
5322
|
const abs = Math.abs(t - Date.now());
|
|
5270
5323
|
if (abs > DAY) return;
|
|
@@ -5280,7 +5333,7 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
|
|
|
5280
5333
|
}
|
|
5281
5334
|
|
|
5282
5335
|
// src/components/data/ScoreMeter.tsx
|
|
5283
|
-
import * as
|
|
5336
|
+
import * as React34 from "react";
|
|
5284
5337
|
import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
5285
5338
|
function ScoreMeter({
|
|
5286
5339
|
score,
|
|
@@ -5295,10 +5348,10 @@ function ScoreMeter({
|
|
|
5295
5348
|
breakdownWidth = 280,
|
|
5296
5349
|
className = ""
|
|
5297
5350
|
}) {
|
|
5298
|
-
const [open2, setOpen] =
|
|
5299
|
-
const ref =
|
|
5351
|
+
const [open2, setOpen] = React34.useState(false);
|
|
5352
|
+
const ref = React34.useRef(null);
|
|
5300
5353
|
const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
5301
|
-
const body = /* @__PURE__ */ jsxs48(
|
|
5354
|
+
const body = /* @__PURE__ */ jsxs48(React34.Fragment, { children: [
|
|
5302
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 }) }),
|
|
5303
5356
|
showScore ? /* @__PURE__ */ jsx55("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
|
|
5304
5357
|
] });
|
|
@@ -5317,7 +5370,7 @@ function ScoreMeter({
|
|
|
5317
5370
|
}
|
|
5318
5371
|
);
|
|
5319
5372
|
}
|
|
5320
|
-
return /* @__PURE__ */ jsxs48(
|
|
5373
|
+
return /* @__PURE__ */ jsxs48(React34.Fragment, { children: [
|
|
5321
5374
|
/* @__PURE__ */ jsx55(
|
|
5322
5375
|
"button",
|
|
5323
5376
|
{
|
|
@@ -5348,14 +5401,14 @@ function ScoreMeter({
|
|
|
5348
5401
|
}
|
|
5349
5402
|
|
|
5350
5403
|
// src/components/actions/inlinePanel.tsx
|
|
5351
|
-
import * as
|
|
5404
|
+
import * as React35 from "react";
|
|
5352
5405
|
import { jsx as jsx56 } from "react/jsx-runtime";
|
|
5353
5406
|
function useInlinePanel() {
|
|
5354
|
-
const [open2, setOpen] =
|
|
5355
|
-
const ref =
|
|
5407
|
+
const [open2, setOpen] = React35.useState(false);
|
|
5408
|
+
const ref = React35.useRef(null);
|
|
5356
5409
|
const layer = useStackedLayer({ active: open2, containerRef: ref, onEscape: () => setOpen(false) });
|
|
5357
5410
|
const zIndex = useLayerZIndex(layer);
|
|
5358
|
-
|
|
5411
|
+
React35.useEffect(() => {
|
|
5359
5412
|
if (!open2) return;
|
|
5360
5413
|
const away = (e) => {
|
|
5361
5414
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -5421,7 +5474,7 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
|
|
|
5421
5474
|
}
|
|
5422
5475
|
|
|
5423
5476
|
// src/components/data/StepList.tsx
|
|
5424
|
-
import * as
|
|
5477
|
+
import * as React36 from "react";
|
|
5425
5478
|
import { jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
5426
5479
|
var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
|
|
5427
5480
|
function StepList({
|
|
@@ -5434,9 +5487,9 @@ function StepList({
|
|
|
5434
5487
|
dense = false,
|
|
5435
5488
|
className = ""
|
|
5436
5489
|
}) {
|
|
5437
|
-
const [openState, setOpenState] =
|
|
5490
|
+
const [openState, setOpenState] = React36.useState(defaultOpen);
|
|
5438
5491
|
const open2 = openProp == null ? openState : openProp;
|
|
5439
|
-
const [expanded, setExpanded] =
|
|
5492
|
+
const [expanded, setExpanded] = React36.useState({});
|
|
5440
5493
|
if (!steps.length) return null;
|
|
5441
5494
|
const running = steps.some((s) => s.status === "running");
|
|
5442
5495
|
const failed = steps.filter((s) => s.status === "error").length;
|
|
@@ -5494,7 +5547,7 @@ function StepList({
|
|
|
5494
5547
|
}
|
|
5495
5548
|
|
|
5496
5549
|
// src/components/data/VirtualList.tsx
|
|
5497
|
-
import * as
|
|
5550
|
+
import * as React37 from "react";
|
|
5498
5551
|
import { jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
5499
5552
|
var VIRTUAL_LIST_BUFFER_ROWS = 20;
|
|
5500
5553
|
var VIRTUAL_LIST_ROW_GAP = 6;
|
|
@@ -5546,35 +5599,35 @@ function VirtualList({
|
|
|
5546
5599
|
className = "",
|
|
5547
5600
|
style
|
|
5548
5601
|
}) {
|
|
5549
|
-
const [scrollTop, setScrollTop] =
|
|
5550
|
-
const loaded =
|
|
5602
|
+
const [scrollTop, setScrollTop] = React37.useState(0);
|
|
5603
|
+
const loaded = React37.useMemo(
|
|
5551
5604
|
() => ({ firstItemIndex, count: items.length }),
|
|
5552
5605
|
[firstItemIndex, items.length]
|
|
5553
5606
|
);
|
|
5554
5607
|
const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
|
|
5555
5608
|
const bandKey = firstItemIndex + ":" + items.length;
|
|
5556
|
-
const win =
|
|
5609
|
+
const win = React37.useMemo(
|
|
5557
5610
|
() => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
|
|
5558
5611
|
[scrollTop, height, itemHeight, total, loaded]
|
|
5559
5612
|
);
|
|
5560
|
-
const need =
|
|
5613
|
+
const need = React37.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
|
|
5561
5614
|
const wantStart = need.start && hasMore?.start !== false;
|
|
5562
5615
|
const wantEnd = need.end && hasMore?.end !== false;
|
|
5563
5616
|
const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
|
|
5564
5617
|
const askKey = bandKey + "@" + bucket2;
|
|
5565
|
-
const asked =
|
|
5566
|
-
|
|
5618
|
+
const asked = React37.useRef({ start: null, end: null });
|
|
5619
|
+
React37.useEffect(() => {
|
|
5567
5620
|
if (loading || !wantStart || asked.current.start === askKey) return;
|
|
5568
5621
|
asked.current.start = askKey;
|
|
5569
5622
|
onNeedMore("start", win);
|
|
5570
5623
|
}, [wantStart, loading, askKey, onNeedMore, win]);
|
|
5571
|
-
|
|
5624
|
+
React37.useEffect(() => {
|
|
5572
5625
|
if (loading || !wantEnd || asked.current.end === askKey) return;
|
|
5573
5626
|
asked.current.end = askKey;
|
|
5574
5627
|
onNeedMore("end", win);
|
|
5575
5628
|
}, [wantEnd, loading, askKey, onNeedMore, win]);
|
|
5576
|
-
const lastKeysRef =
|
|
5577
|
-
const newKeys =
|
|
5629
|
+
const lastKeysRef = React37.useRef(null);
|
|
5630
|
+
const newKeys = React37.useMemo(() => {
|
|
5578
5631
|
const prev = lastKeysRef.current;
|
|
5579
5632
|
if (!prev) return /* @__PURE__ */ new Set();
|
|
5580
5633
|
const fresh = /* @__PURE__ */ new Set();
|
|
@@ -5584,7 +5637,7 @@ function VirtualList({
|
|
|
5584
5637
|
}
|
|
5585
5638
|
return fresh;
|
|
5586
5639
|
}, [items]);
|
|
5587
|
-
|
|
5640
|
+
React37.useEffect(() => {
|
|
5588
5641
|
lastKeysRef.current = new Set(items.map(keyOf));
|
|
5589
5642
|
}, [items]);
|
|
5590
5643
|
const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
|
|
@@ -5629,7 +5682,7 @@ function VirtualList({
|
|
|
5629
5682
|
}
|
|
5630
5683
|
|
|
5631
5684
|
// src/components/data/EntityRow.tsx
|
|
5632
|
-
import * as
|
|
5685
|
+
import * as React38 from "react";
|
|
5633
5686
|
import { jsx as jsx60, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
5634
5687
|
var ENTITY_ROW_METRIC_WIDTH = 74;
|
|
5635
5688
|
var METRIC_TONE_COLOR = {
|
|
@@ -5642,7 +5695,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
|
|
|
5642
5695
|
const key = m.id || m.label || i;
|
|
5643
5696
|
const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
|
|
5644
5697
|
const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
|
|
5645
|
-
const content = /* @__PURE__ */ jsxs52(
|
|
5698
|
+
const content = /* @__PURE__ */ jsxs52(React38.Fragment, { children: [
|
|
5646
5699
|
m.icon ? /* @__PURE__ */ jsx60("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
|
|
5647
5700
|
/* @__PURE__ */ jsx60("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
|
|
5648
5701
|
/* @__PURE__ */ jsx60("span", { className: "fd-sr", children: " " + m.label })
|
|
@@ -5734,8 +5787,8 @@ function EntityRow({
|
|
|
5734
5787
|
}
|
|
5735
5788
|
|
|
5736
5789
|
// src/components/data/TransferList.tsx
|
|
5737
|
-
import * as
|
|
5738
|
-
import { createPortal as
|
|
5790
|
+
import * as React39 from "react";
|
|
5791
|
+
import { createPortal as createPortal5 } from "react-dom";
|
|
5739
5792
|
|
|
5740
5793
|
// src/components/forms/Input.tsx
|
|
5741
5794
|
import { jsx as jsx61, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
@@ -5840,12 +5893,12 @@ function TransferList({
|
|
|
5840
5893
|
listHeight = 440,
|
|
5841
5894
|
className = ""
|
|
5842
5895
|
}) {
|
|
5843
|
-
const [drag, setDrag] =
|
|
5844
|
-
const [dragOverSide, setDragOverSide] =
|
|
5845
|
-
const dragRef =
|
|
5846
|
-
const armedRef =
|
|
5847
|
-
const sideRefs =
|
|
5848
|
-
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) => {
|
|
5849
5902
|
for (const side of ["left", "right"]) {
|
|
5850
5903
|
const el = sideRefs.current[side];
|
|
5851
5904
|
if (!el) continue;
|
|
@@ -5854,7 +5907,7 @@ function TransferList({
|
|
|
5854
5907
|
}
|
|
5855
5908
|
return null;
|
|
5856
5909
|
}, []);
|
|
5857
|
-
const findItem =
|
|
5910
|
+
const findItem = React39.useCallback(
|
|
5858
5911
|
(side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
|
|
5859
5912
|
[left.items, right.items, keyOf]
|
|
5860
5913
|
);
|
|
@@ -5876,7 +5929,7 @@ function TransferList({
|
|
|
5876
5929
|
height: rect.height
|
|
5877
5930
|
};
|
|
5878
5931
|
};
|
|
5879
|
-
|
|
5932
|
+
React39.useEffect(() => {
|
|
5880
5933
|
const onMovePointer = (e) => {
|
|
5881
5934
|
const armed = armedRef.current;
|
|
5882
5935
|
if (!armed || e.pointerId !== armed.pointerId) return;
|
|
@@ -5929,7 +5982,7 @@ function TransferList({
|
|
|
5929
5982
|
window.removeEventListener("pointercancel", endDrag);
|
|
5930
5983
|
};
|
|
5931
5984
|
}, [hitTestSide, findItem, onMove]);
|
|
5932
|
-
|
|
5985
|
+
React39.useEffect(() => {
|
|
5933
5986
|
if (!drag || typeof document === "undefined") return;
|
|
5934
5987
|
const prev = document.body.style.userSelect;
|
|
5935
5988
|
document.body.style.userSelect = "none";
|
|
@@ -6012,7 +6065,7 @@ function TransferList({
|
|
|
6012
6065
|
renderSide("left", left, "right"),
|
|
6013
6066
|
renderSide("right", right, "left")
|
|
6014
6067
|
] }),
|
|
6015
|
-
drag ?
|
|
6068
|
+
drag ? createPortal5(
|
|
6016
6069
|
/* @__PURE__ */ jsx63(
|
|
6017
6070
|
"div",
|
|
6018
6071
|
{
|
|
@@ -6037,11 +6090,11 @@ function TransferList({
|
|
|
6037
6090
|
}
|
|
6038
6091
|
|
|
6039
6092
|
// src/components/forms/Checkbox.tsx
|
|
6040
|
-
import * as
|
|
6093
|
+
import * as React40 from "react";
|
|
6041
6094
|
import { jsx as jsx64, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
6042
6095
|
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
6043
|
-
const ref =
|
|
6044
|
-
|
|
6096
|
+
const ref = React40.useRef(null);
|
|
6097
|
+
React40.useEffect(() => {
|
|
6045
6098
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
6046
6099
|
}, [indeterminate]);
|
|
6047
6100
|
return /* @__PURE__ */ jsxs55("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
@@ -6085,7 +6138,7 @@ function Switch({ label, description, className = "", ...rest }) {
|
|
|
6085
6138
|
}
|
|
6086
6139
|
|
|
6087
6140
|
// src/components/forms/Select.tsx
|
|
6088
|
-
import * as
|
|
6141
|
+
import * as React41 from "react";
|
|
6089
6142
|
import { jsx as jsx67, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
6090
6143
|
var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
|
|
6091
6144
|
function Select({
|
|
@@ -6113,12 +6166,12 @@ function Select({
|
|
|
6113
6166
|
const isOn = (v) => multiple ? vals.includes(v) : v === value;
|
|
6114
6167
|
const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
|
|
6115
6168
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id, hiddenLabel);
|
|
6116
|
-
const [open2, setOpen] =
|
|
6117
|
-
const [q, setQ] =
|
|
6118
|
-
const rootRef =
|
|
6119
|
-
const boxRef =
|
|
6120
|
-
const listRef =
|
|
6121
|
-
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 });
|
|
6122
6175
|
const selected = multiple ? null : opts.find((o) => o.value === value);
|
|
6123
6176
|
const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
|
|
6124
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;
|
|
@@ -6254,7 +6307,7 @@ function Select({
|
|
|
6254
6307
|
),
|
|
6255
6308
|
q ? /* @__PURE__ */ jsx67("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
|
|
6256
6309
|
] }) : void 0,
|
|
6257
|
-
footer: multiple ? /* @__PURE__ */ jsxs58(
|
|
6310
|
+
footer: multiple ? /* @__PURE__ */ jsxs58(React41.Fragment, { children: [
|
|
6258
6311
|
/* @__PURE__ */ jsx67(
|
|
6259
6312
|
"button",
|
|
6260
6313
|
{
|
|
@@ -6285,7 +6338,7 @@ function Select({
|
|
|
6285
6338
|
'Nothing matches "',
|
|
6286
6339
|
q,
|
|
6287
6340
|
'".'
|
|
6288
|
-
] }) : groups.map((grp) => /* @__PURE__ */ jsxs58(
|
|
6341
|
+
] }) : groups.map((grp) => /* @__PURE__ */ jsxs58(React41.Fragment, { children: [
|
|
6289
6342
|
grp.g ? /* @__PURE__ */ jsx67("div", { className: "fd-pop-group", children: grp.g }) : null,
|
|
6290
6343
|
grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs58(
|
|
6291
6344
|
"button",
|
|
@@ -6322,7 +6375,7 @@ function Select({
|
|
|
6322
6375
|
}
|
|
6323
6376
|
|
|
6324
6377
|
// src/components/forms/TimePicker.tsx
|
|
6325
|
-
import * as
|
|
6378
|
+
import * as React42 from "react";
|
|
6326
6379
|
import { jsx as jsx68, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
6327
6380
|
var pad = (n) => String(n).padStart(2, "0");
|
|
6328
6381
|
function ClockFace({ value = "09:00", onChange }) {
|
|
@@ -6331,9 +6384,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
6331
6384
|
if (isNaN(m)) m = 0;
|
|
6332
6385
|
const pm = h24 >= 12;
|
|
6333
6386
|
const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
|
|
6334
|
-
const [mode2, setMode] =
|
|
6335
|
-
const faceRef =
|
|
6336
|
-
const dragging =
|
|
6387
|
+
const [mode2, setMode] = React42.useState("h");
|
|
6388
|
+
const faceRef = React42.useRef(null);
|
|
6389
|
+
const dragging = React42.useRef(false);
|
|
6337
6390
|
const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
|
|
6338
6391
|
const R = 108, NR = 80;
|
|
6339
6392
|
const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
|
|
@@ -6406,9 +6459,9 @@ function ClockFace({ value = "09:00", onChange }) {
|
|
|
6406
6459
|
}
|
|
6407
6460
|
function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
|
|
6408
6461
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
6409
|
-
const [open2, setOpen] =
|
|
6410
|
-
const rootRef =
|
|
6411
|
-
const boxRef =
|
|
6462
|
+
const [open2, setOpen] = React42.useState(false);
|
|
6463
|
+
const rootRef = React42.useRef(null);
|
|
6464
|
+
const boxRef = React42.useRef(null);
|
|
6412
6465
|
const disp = () => {
|
|
6413
6466
|
if (!value) return "";
|
|
6414
6467
|
const [h, m] = value.split(":").map(Number);
|
|
@@ -6451,7 +6504,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
6451
6504
|
offset: 6,
|
|
6452
6505
|
width: 262,
|
|
6453
6506
|
role: "presentation",
|
|
6454
|
-
footer: /* @__PURE__ */ jsxs59(
|
|
6507
|
+
footer: /* @__PURE__ */ jsxs59(React42.Fragment, { children: [
|
|
6455
6508
|
/* @__PURE__ */ jsx68(
|
|
6456
6509
|
"button",
|
|
6457
6510
|
{
|
|
@@ -6479,7 +6532,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
|
|
|
6479
6532
|
}
|
|
6480
6533
|
|
|
6481
6534
|
// src/components/forms/Slider.tsx
|
|
6482
|
-
import * as
|
|
6535
|
+
import * as React43 from "react";
|
|
6483
6536
|
import { jsx as jsx69, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
6484
6537
|
function Slider({
|
|
6485
6538
|
label,
|
|
@@ -6497,7 +6550,7 @@ function Slider({
|
|
|
6497
6550
|
...rest
|
|
6498
6551
|
}) {
|
|
6499
6552
|
const fieldId = useFieldId(id);
|
|
6500
|
-
const [dragging, setDragging] =
|
|
6553
|
+
const [dragging, setDragging] = React43.useState(false);
|
|
6501
6554
|
const v = value === void 0 ? min : Number(value);
|
|
6502
6555
|
const pct = max === min ? 0 : (v - min) / (max - min) * 100;
|
|
6503
6556
|
return /* @__PURE__ */ jsxs60("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
|
|
@@ -6531,7 +6584,7 @@ function Slider({
|
|
|
6531
6584
|
}
|
|
6532
6585
|
|
|
6533
6586
|
// src/components/forms/RangeSlider.tsx
|
|
6534
|
-
import * as
|
|
6587
|
+
import * as React44 from "react";
|
|
6535
6588
|
import { jsx as jsx70, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
6536
6589
|
function RangeSlider({
|
|
6537
6590
|
label,
|
|
@@ -6551,9 +6604,9 @@ function RangeSlider({
|
|
|
6551
6604
|
}) {
|
|
6552
6605
|
const fmt2 = format || ((v) => String(v));
|
|
6553
6606
|
const [a, b] = value || [min, max];
|
|
6554
|
-
const [drag, setDrag] =
|
|
6555
|
-
const [focus, setFocus] =
|
|
6556
|
-
const railRef =
|
|
6607
|
+
const [drag, setDrag] = React44.useState(null);
|
|
6608
|
+
const [focus, setFocus] = React44.useState(null);
|
|
6609
|
+
const railRef = React44.useRef(null);
|
|
6557
6610
|
const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
|
|
6558
6611
|
const clampPair = (i, v) => {
|
|
6559
6612
|
v = Math.min(max, Math.max(min, Math.round(v / step) * step));
|
|
@@ -6568,7 +6621,7 @@ function RangeSlider({
|
|
|
6568
6621
|
const r = railRef.current.getBoundingClientRect();
|
|
6569
6622
|
return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
|
|
6570
6623
|
};
|
|
6571
|
-
|
|
6624
|
+
React44.useEffect(() => {
|
|
6572
6625
|
if (drag === null) return;
|
|
6573
6626
|
const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
|
|
6574
6627
|
const upH = () => setDrag(null);
|
|
@@ -6649,7 +6702,7 @@ function RangeSlider({
|
|
|
6649
6702
|
/* @__PURE__ */ jsxs61("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
|
|
6650
6703
|
/* @__PURE__ */ jsx70("span", { className: "fd-range-rail", ref: railRef }),
|
|
6651
6704
|
/* @__PURE__ */ jsx70("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
|
|
6652
|
-
marks.map((m) => /* @__PURE__ */ jsxs61(
|
|
6705
|
+
marks.map((m) => /* @__PURE__ */ jsxs61(React44.Fragment, { children: [
|
|
6653
6706
|
/* @__PURE__ */ jsx70("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
|
|
6654
6707
|
m.label ? /* @__PURE__ */ jsx70("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
|
|
6655
6708
|
] }, m.value)),
|
|
@@ -6678,7 +6731,7 @@ function RangeSlider({
|
|
|
6678
6731
|
}
|
|
6679
6732
|
|
|
6680
6733
|
// src/components/forms/Dropzone.tsx
|
|
6681
|
-
import * as
|
|
6734
|
+
import * as React45 from "react";
|
|
6682
6735
|
import { jsx as jsx71, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
6683
6736
|
function Dropzone({
|
|
6684
6737
|
onFiles,
|
|
@@ -6693,8 +6746,8 @@ function Dropzone({
|
|
|
6693
6746
|
className = "",
|
|
6694
6747
|
style
|
|
6695
6748
|
}) {
|
|
6696
|
-
const [over, setOver] =
|
|
6697
|
-
const depth =
|
|
6749
|
+
const [over, setOver] = React45.useState(false);
|
|
6750
|
+
const depth = React45.useRef(0);
|
|
6698
6751
|
const has = (e) => {
|
|
6699
6752
|
const dt = e.dataTransfer;
|
|
6700
6753
|
if (!dt) return false;
|
|
@@ -6756,8 +6809,8 @@ function FilePickButton({
|
|
|
6756
6809
|
className = "",
|
|
6757
6810
|
children
|
|
6758
6811
|
}) {
|
|
6759
|
-
const ref =
|
|
6760
|
-
return /* @__PURE__ */ jsxs62(
|
|
6812
|
+
const ref = React45.useRef(null);
|
|
6813
|
+
return /* @__PURE__ */ jsxs62(React45.Fragment, { children: [
|
|
6761
6814
|
/* @__PURE__ */ jsx71(
|
|
6762
6815
|
"button",
|
|
6763
6816
|
{
|
|
@@ -6790,10 +6843,10 @@ function FilePickButton({
|
|
|
6790
6843
|
}
|
|
6791
6844
|
function useStagedFiles(upload, opts) {
|
|
6792
6845
|
const o = opts || {};
|
|
6793
|
-
const [items, setItems] =
|
|
6794
|
-
const controllers =
|
|
6846
|
+
const [items, setItems] = React45.useState([]);
|
|
6847
|
+
const controllers = React45.useRef({});
|
|
6795
6848
|
const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
|
|
6796
|
-
const run =
|
|
6849
|
+
const run = React45.useCallback((att) => {
|
|
6797
6850
|
if (!upload) return;
|
|
6798
6851
|
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
6799
6852
|
controllers.current[att.id] = ac;
|
|
@@ -6810,14 +6863,14 @@ function useStagedFiles(upload, opts) {
|
|
|
6810
6863
|
delete controllers.current[att.id];
|
|
6811
6864
|
});
|
|
6812
6865
|
}, [upload]);
|
|
6813
|
-
const add =
|
|
6866
|
+
const add = React45.useCallback((files) => {
|
|
6814
6867
|
if (!upload) return [];
|
|
6815
6868
|
const atts = Array.from(files).map((f) => toAttachment(f));
|
|
6816
6869
|
setItems((list) => list.concat(atts));
|
|
6817
6870
|
atts.forEach(run);
|
|
6818
6871
|
return atts;
|
|
6819
6872
|
}, [upload, run]);
|
|
6820
|
-
const remove =
|
|
6873
|
+
const remove = React45.useCallback((att) => {
|
|
6821
6874
|
const ac = controllers.current[att.id];
|
|
6822
6875
|
if (ac) {
|
|
6823
6876
|
try {
|
|
@@ -6828,10 +6881,10 @@ function useStagedFiles(upload, opts) {
|
|
|
6828
6881
|
}
|
|
6829
6882
|
setItems((list) => list.filter((f) => f.id !== att.id));
|
|
6830
6883
|
}, []);
|
|
6831
|
-
const retry =
|
|
6884
|
+
const retry = React45.useCallback((att) => {
|
|
6832
6885
|
run(att);
|
|
6833
6886
|
}, [run]);
|
|
6834
|
-
const clear =
|
|
6887
|
+
const clear = React45.useCallback(() => {
|
|
6835
6888
|
Object.values(controllers.current).forEach((ac) => {
|
|
6836
6889
|
try {
|
|
6837
6890
|
ac && ac.abort();
|
|
@@ -6955,7 +7008,7 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
|
|
|
6955
7008
|
}
|
|
6956
7009
|
|
|
6957
7010
|
// src/components/forms/MarkdownEditor.tsx
|
|
6958
|
-
import * as
|
|
7011
|
+
import * as React46 from "react";
|
|
6959
7012
|
import { jsx as jsx73, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
6960
7013
|
var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
|
|
6961
7014
|
var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
|
|
@@ -7169,7 +7222,7 @@ function syncDom(root, value) {
|
|
|
7169
7222
|
while (root.children.length > lines.length) root.removeChild(root.lastChild);
|
|
7170
7223
|
}
|
|
7171
7224
|
var LIST_CONT = RE_LI;
|
|
7172
|
-
var MarkdownEditor =
|
|
7225
|
+
var MarkdownEditor = React46.forwardRef(function MarkdownEditor2({
|
|
7173
7226
|
value = "",
|
|
7174
7227
|
onChange,
|
|
7175
7228
|
onSubmit,
|
|
@@ -7188,10 +7241,10 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
|
|
|
7188
7241
|
className = "",
|
|
7189
7242
|
id
|
|
7190
7243
|
}, ref) {
|
|
7191
|
-
const boxRef =
|
|
7192
|
-
const composing =
|
|
7193
|
-
const pendingCaret =
|
|
7194
|
-
|
|
7244
|
+
const boxRef = React46.useRef(null);
|
|
7245
|
+
const composing = React46.useRef(false);
|
|
7246
|
+
const pendingCaret = React46.useRef(null);
|
|
7247
|
+
React46.useLayoutEffect(() => {
|
|
7195
7248
|
const root = boxRef.current;
|
|
7196
7249
|
if (!root || composing.current) return;
|
|
7197
7250
|
const active = document.activeElement === root || root.contains(document.activeElement);
|
|
@@ -7200,7 +7253,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
|
|
|
7200
7253
|
pendingCaret.current = null;
|
|
7201
7254
|
if (active && caret != null) placeCaret(root, caret);
|
|
7202
7255
|
}, [value]);
|
|
7203
|
-
|
|
7256
|
+
React46.useEffect(() => {
|
|
7204
7257
|
if (autoFocus && boxRef.current) boxRef.current.focus();
|
|
7205
7258
|
}, [autoFocus]);
|
|
7206
7259
|
const caretNow = () => {
|
|
@@ -7267,8 +7320,8 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
|
|
|
7267
7320
|
api.replaceRange(from, to, next, from + next.length);
|
|
7268
7321
|
}
|
|
7269
7322
|
};
|
|
7270
|
-
|
|
7271
|
-
const caretAtKeydown =
|
|
7323
|
+
React46.useImperativeHandle(ref, () => api);
|
|
7324
|
+
const caretAtKeydown = React46.useRef(-1);
|
|
7272
7325
|
function detect(text, caret) {
|
|
7273
7326
|
if (!onTrigger) return;
|
|
7274
7327
|
const upto = text.slice(0, caret);
|
|
@@ -7421,7 +7474,7 @@ var MarkdownEditor = React45.forwardRef(function MarkdownEditor2({
|
|
|
7421
7474
|
});
|
|
7422
7475
|
|
|
7423
7476
|
// src/components/forms/CodeEditor.tsx
|
|
7424
|
-
import * as
|
|
7477
|
+
import * as React47 from "react";
|
|
7425
7478
|
import { EditorView, keymap, lineNumbers, placeholder as cmPlaceholder, drawSelection, Decoration } from "@codemirror/view";
|
|
7426
7479
|
import { EditorState, StateEffect, StateField, Compartment } from "@codemirror/state";
|
|
7427
7480
|
import { defaultKeymap, history, historyKeymap, indentMore, indentLess } from "@codemirror/commands";
|
|
@@ -7525,16 +7578,16 @@ function CodeEditor({
|
|
|
7525
7578
|
const fieldId = useFieldId(id);
|
|
7526
7579
|
const descId = fieldId + "-desc";
|
|
7527
7580
|
const liveId = fieldId + "-live";
|
|
7528
|
-
const hostRef =
|
|
7529
|
-
const viewRef =
|
|
7530
|
-
const valueRef =
|
|
7531
|
-
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);
|
|
7532
7585
|
onChangeRef.current = onChange;
|
|
7533
|
-
const editableCompartment =
|
|
7534
|
-
const attributesCompartment =
|
|
7535
|
-
const errorRef =
|
|
7586
|
+
const editableCompartment = React47.useRef(new Compartment()).current;
|
|
7587
|
+
const attributesCompartment = React47.useRef(new Compartment()).current;
|
|
7588
|
+
const errorRef = React47.useRef(error);
|
|
7536
7589
|
errorRef.current = error;
|
|
7537
|
-
const diagnosticsCountRef =
|
|
7590
|
+
const diagnosticsCountRef = React47.useRef(diagnostics.length);
|
|
7538
7591
|
diagnosticsCountRef.current = diagnostics.length;
|
|
7539
7592
|
function contentAttributes() {
|
|
7540
7593
|
return {
|
|
@@ -7544,9 +7597,9 @@ function CodeEditor({
|
|
|
7544
7597
|
...label ? { "aria-label": label } : {}
|
|
7545
7598
|
};
|
|
7546
7599
|
}
|
|
7547
|
-
|
|
7548
|
-
const
|
|
7549
|
-
if (!
|
|
7600
|
+
React47.useEffect(() => {
|
|
7601
|
+
const host2 = hostRef.current;
|
|
7602
|
+
if (!host2) return;
|
|
7550
7603
|
const updateListener = EditorView.updateListener.of((update) => {
|
|
7551
7604
|
if (!update.docChanged) return;
|
|
7552
7605
|
const next = update.state.doc.toString();
|
|
@@ -7578,7 +7631,7 @@ function CodeEditor({
|
|
|
7578
7631
|
attributesCompartment.of(EditorView.contentAttributes.of(contentAttributes()))
|
|
7579
7632
|
]
|
|
7580
7633
|
});
|
|
7581
|
-
const view = new EditorView({ state, parent:
|
|
7634
|
+
const view = new EditorView({ state, parent: host2 });
|
|
7582
7635
|
viewRef.current = view;
|
|
7583
7636
|
if (autoFocus) view.focus();
|
|
7584
7637
|
return () => {
|
|
@@ -7586,7 +7639,7 @@ function CodeEditor({
|
|
|
7586
7639
|
viewRef.current = null;
|
|
7587
7640
|
};
|
|
7588
7641
|
}, []);
|
|
7589
|
-
|
|
7642
|
+
React47.useEffect(() => {
|
|
7590
7643
|
const view = viewRef.current;
|
|
7591
7644
|
if (!view) return;
|
|
7592
7645
|
const current2 = view.state.doc.toString();
|
|
@@ -7595,12 +7648,12 @@ function CodeEditor({
|
|
|
7595
7648
|
}
|
|
7596
7649
|
valueRef.current = value;
|
|
7597
7650
|
}, [value]);
|
|
7598
|
-
|
|
7651
|
+
React47.useEffect(() => {
|
|
7599
7652
|
const view = viewRef.current;
|
|
7600
7653
|
if (!view) return;
|
|
7601
7654
|
view.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!disabled)) });
|
|
7602
7655
|
}, [disabled, editableCompartment]);
|
|
7603
|
-
|
|
7656
|
+
React47.useEffect(() => {
|
|
7604
7657
|
const view = viewRef.current;
|
|
7605
7658
|
if (!view) return;
|
|
7606
7659
|
view.dispatch({
|
|
@@ -7658,16 +7711,16 @@ function CodeEditor({
|
|
|
7658
7711
|
}
|
|
7659
7712
|
|
|
7660
7713
|
// src/components/platform/AccountMenu.tsx
|
|
7661
|
-
import * as
|
|
7714
|
+
import * as React49 from "react";
|
|
7662
7715
|
|
|
7663
7716
|
// src/kits/sessionContext.tsx
|
|
7664
|
-
import * as
|
|
7665
|
-
var SessionContext =
|
|
7717
|
+
import * as React48 from "react";
|
|
7718
|
+
var SessionContext = React48.createContext(null);
|
|
7666
7719
|
function SessionProvider({ value, children }) {
|
|
7667
|
-
return
|
|
7720
|
+
return React48.createElement(SessionContext.Provider, { value }, children);
|
|
7668
7721
|
}
|
|
7669
7722
|
function useSessionContext() {
|
|
7670
|
-
const ctx =
|
|
7723
|
+
const ctx = React48.useContext(SessionContext);
|
|
7671
7724
|
if (!ctx) {
|
|
7672
7725
|
throw new Error(
|
|
7673
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."
|
|
@@ -7707,11 +7760,11 @@ function AccountMenu({
|
|
|
7707
7760
|
...rest
|
|
7708
7761
|
}) {
|
|
7709
7762
|
const { user, roles, can: can2, signOut: ctxSignOut, demo, pending } = useSessionContext();
|
|
7710
|
-
const [open2, setOpen] =
|
|
7711
|
-
const [switching, setSwitching] =
|
|
7712
|
-
const [signingOut, setSigningOut] =
|
|
7713
|
-
const [signOutError, setSignOutError] =
|
|
7714
|
-
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);
|
|
7715
7768
|
const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
|
|
7716
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);
|
|
7717
7770
|
const closeMenu = () => {
|
|
@@ -7836,13 +7889,13 @@ function AccountMenu({
|
|
|
7836
7889
|
}
|
|
7837
7890
|
|
|
7838
7891
|
// src/components/platform/AppSwitcher.tsx
|
|
7839
|
-
import * as
|
|
7892
|
+
import * as React50 from "react";
|
|
7840
7893
|
import { jsx as jsx76, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
7841
7894
|
function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
7842
7895
|
const { apps: contextApps } = useSessionContext();
|
|
7843
7896
|
const apps = appsProp ?? contextApps ?? [];
|
|
7844
|
-
const [open2, setOpen] =
|
|
7845
|
-
const anchorRef =
|
|
7897
|
+
const [open2, setOpen] = React50.useState(false);
|
|
7898
|
+
const anchorRef = React50.useRef(null);
|
|
7846
7899
|
if (!apps.length) return null;
|
|
7847
7900
|
const items = apps.map((app) => ({
|
|
7848
7901
|
id: app.key,
|
|
@@ -7856,7 +7909,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
7856
7909
|
window.location.href = app.url;
|
|
7857
7910
|
}
|
|
7858
7911
|
}));
|
|
7859
|
-
return /* @__PURE__ */ jsxs67(
|
|
7912
|
+
return /* @__PURE__ */ jsxs67(React50.Fragment, { children: [
|
|
7860
7913
|
/* @__PURE__ */ jsx76("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx76(
|
|
7861
7914
|
IconButton,
|
|
7862
7915
|
{
|
|
@@ -7885,10 +7938,10 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
|
|
|
7885
7938
|
}
|
|
7886
7939
|
|
|
7887
7940
|
// src/components/platform/AppearanceMenu.tsx
|
|
7888
|
-
import * as
|
|
7941
|
+
import * as React52 from "react";
|
|
7889
7942
|
|
|
7890
7943
|
// src/kits/appearance.ts
|
|
7891
|
-
import * as
|
|
7944
|
+
import * as React51 from "react";
|
|
7892
7945
|
var DEFAULT_STORAGE_KEY = "fd-appearance";
|
|
7893
7946
|
var DEFAULT_PREFS = {
|
|
7894
7947
|
theme: "system",
|
|
@@ -7983,11 +8036,11 @@ function applyPrefs(prefs, root = document.documentElement) {
|
|
|
7983
8036
|
else root.removeAttribute("data-motion");
|
|
7984
8037
|
}
|
|
7985
8038
|
function useAppearancePrefs(store) {
|
|
7986
|
-
const prefs =
|
|
7987
|
-
|
|
8039
|
+
const prefs = React51.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
8040
|
+
React51.useEffect(() => {
|
|
7988
8041
|
applyPrefs(prefs);
|
|
7989
8042
|
}, [prefs]);
|
|
7990
|
-
|
|
8043
|
+
React51.useEffect(() => {
|
|
7991
8044
|
if (prefs.theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
7992
8045
|
return;
|
|
7993
8046
|
}
|
|
@@ -7996,7 +8049,7 @@ function useAppearancePrefs(store) {
|
|
|
7996
8049
|
mq.addEventListener("change", onChange);
|
|
7997
8050
|
return () => mq.removeEventListener("change", onChange);
|
|
7998
8051
|
}, [prefs]);
|
|
7999
|
-
const update =
|
|
8052
|
+
const update = React51.useCallback(
|
|
8000
8053
|
(patch) => {
|
|
8001
8054
|
store.write({ ...store.getSnapshot(), ...patch });
|
|
8002
8055
|
},
|
|
@@ -8019,15 +8072,15 @@ var TEXT_SCALE_OPTIONS = [
|
|
|
8019
8072
|
{ value: "xl", label: "XL" }
|
|
8020
8073
|
];
|
|
8021
8074
|
function AppearanceMenu({ className = "", store: storeProp, storageKey, storage, defaults }) {
|
|
8022
|
-
const store =
|
|
8075
|
+
const store = React52.useMemo(
|
|
8023
8076
|
() => storeProp ?? createLocalStorageAppearanceStore({ storageKey, storage, defaults }),
|
|
8024
8077
|
[storeProp, storageKey, storage, defaults]
|
|
8025
8078
|
);
|
|
8026
8079
|
const [prefs, update] = useAppearancePrefs(store);
|
|
8027
|
-
const [open2, setOpen] =
|
|
8028
|
-
const anchorRef =
|
|
8080
|
+
const [open2, setOpen] = React52.useState(false);
|
|
8081
|
+
const anchorRef = React52.useRef(null);
|
|
8029
8082
|
const patch = (p) => update(p);
|
|
8030
|
-
return /* @__PURE__ */ jsxs68(
|
|
8083
|
+
return /* @__PURE__ */ jsxs68(React52.Fragment, { children: [
|
|
8031
8084
|
/* @__PURE__ */ jsx77("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx77(
|
|
8032
8085
|
IconButton,
|
|
8033
8086
|
{
|
|
@@ -8096,14 +8149,14 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
|
|
|
8096
8149
|
}
|
|
8097
8150
|
|
|
8098
8151
|
// src/components/platform/ApiSpecBrowser.tsx
|
|
8099
|
-
import * as
|
|
8152
|
+
import * as React53 from "react";
|
|
8100
8153
|
import { jsx as jsx78, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
8101
8154
|
var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
|
|
8102
8155
|
function Json({ obj }) {
|
|
8103
8156
|
return /* @__PURE__ */ jsx78("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
|
|
8104
8157
|
}
|
|
8105
8158
|
function Endpoint({ s, onRequest }) {
|
|
8106
|
-
const [tried, setTried] =
|
|
8159
|
+
const [tried, setTried] = React53.useState(null);
|
|
8107
8160
|
const run = async () => {
|
|
8108
8161
|
setTried("busy");
|
|
8109
8162
|
const t0 = (window.performance || Date).now();
|
|
@@ -8176,10 +8229,10 @@ function ApiSpecBrowser({
|
|
|
8176
8229
|
className = "",
|
|
8177
8230
|
...rest
|
|
8178
8231
|
}) {
|
|
8179
|
-
const [q, setQ] =
|
|
8180
|
-
const [method, setMethod] =
|
|
8181
|
-
const [mod, setMod] =
|
|
8182
|
-
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);
|
|
8183
8236
|
const activeModule = modules && modules.find((m) => m.id === mod);
|
|
8184
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())));
|
|
8185
8238
|
const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
|
|
@@ -8258,7 +8311,7 @@ function ApiSpecBrowser({
|
|
|
8258
8311
|
}
|
|
8259
8312
|
|
|
8260
8313
|
// src/components/platform/ProfilePage.tsx
|
|
8261
|
-
import * as
|
|
8314
|
+
import * as React54 from "react";
|
|
8262
8315
|
import { jsx as jsx79, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
8263
8316
|
function fieldInitialValue(field, user) {
|
|
8264
8317
|
if (field.value) return field.value(user);
|
|
@@ -8294,21 +8347,21 @@ function ProfilePage({
|
|
|
8294
8347
|
}) {
|
|
8295
8348
|
const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
|
|
8296
8349
|
const user = userProp || sessionUser;
|
|
8297
|
-
const initialFieldValues =
|
|
8350
|
+
const initialFieldValues = React54.useMemo(() => {
|
|
8298
8351
|
const values2 = {};
|
|
8299
8352
|
for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
|
|
8300
8353
|
return values2;
|
|
8301
8354
|
}, [user.id, fields]);
|
|
8302
|
-
const initialNotify =
|
|
8355
|
+
const initialNotify = React54.useMemo(() => {
|
|
8303
8356
|
const values2 = {};
|
|
8304
8357
|
for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
|
|
8305
8358
|
return values2;
|
|
8306
8359
|
}, [user.id, notifications]);
|
|
8307
|
-
const [values, setValues] =
|
|
8308
|
-
const [notify, setNotify] =
|
|
8309
|
-
const [saving, setSaving] =
|
|
8310
|
-
const [saved, setSaved] =
|
|
8311
|
-
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);
|
|
8312
8365
|
if (user.id !== prevUserId) {
|
|
8313
8366
|
setPrevUserId(user.id);
|
|
8314
8367
|
setValues(initialFieldValues);
|
|
@@ -8496,11 +8549,11 @@ function ProfilePage({
|
|
|
8496
8549
|
}
|
|
8497
8550
|
|
|
8498
8551
|
// src/components/platform/SignInPage.tsx
|
|
8499
|
-
import * as
|
|
8552
|
+
import * as React55 from "react";
|
|
8500
8553
|
import { Fragment as Fragment19, jsx as jsx80, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
8501
8554
|
function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
8502
|
-
const [signingIn, setSigningIn] =
|
|
8503
|
-
const [resuming, setResuming] =
|
|
8555
|
+
const [signingIn, setSigningIn] = React55.useState(false);
|
|
8556
|
+
const [resuming, setResuming] = React55.useState(false);
|
|
8504
8557
|
function handleSignIn() {
|
|
8505
8558
|
setSigningIn(true);
|
|
8506
8559
|
onSignIn();
|
|
@@ -8689,10 +8742,10 @@ function GoogleGlyph() {
|
|
|
8689
8742
|
}
|
|
8690
8743
|
|
|
8691
8744
|
// src/components/platform/RoadmapTimeline.tsx
|
|
8692
|
-
import * as
|
|
8745
|
+
import * as React58 from "react";
|
|
8693
8746
|
|
|
8694
8747
|
// src/kits/session.ts
|
|
8695
|
-
import * as
|
|
8748
|
+
import * as React56 from "react";
|
|
8696
8749
|
var PERMISSION_CATALOG = [
|
|
8697
8750
|
{ group: "Plans", items: [
|
|
8698
8751
|
{ key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
|
|
@@ -10259,8 +10312,8 @@ function roadmap(overrides) {
|
|
|
10259
10312
|
};
|
|
10260
10313
|
}
|
|
10261
10314
|
function useSession() {
|
|
10262
|
-
const [s, setS] =
|
|
10263
|
-
|
|
10315
|
+
const [s, setS] = React56.useState(getSession);
|
|
10316
|
+
React56.useEffect(() => subscribe(setS), []);
|
|
10264
10317
|
return s;
|
|
10265
10318
|
}
|
|
10266
10319
|
var SessionKit = {
|
|
@@ -10293,7 +10346,7 @@ var SessionKit = {
|
|
|
10293
10346
|
};
|
|
10294
10347
|
function DemoSessionProvider({ children }) {
|
|
10295
10348
|
const session = useSession();
|
|
10296
|
-
const value =
|
|
10349
|
+
const value = React56.useMemo(
|
|
10297
10350
|
() => ({
|
|
10298
10351
|
user: session.user,
|
|
10299
10352
|
roles: session.roles,
|
|
@@ -10309,11 +10362,11 @@ function DemoSessionProvider({ children }) {
|
|
|
10309
10362
|
}),
|
|
10310
10363
|
[session]
|
|
10311
10364
|
);
|
|
10312
|
-
return
|
|
10365
|
+
return React56.createElement(SessionProvider, { value }, children);
|
|
10313
10366
|
}
|
|
10314
10367
|
|
|
10315
10368
|
// src/kits/runtime.ts
|
|
10316
|
-
import * as
|
|
10369
|
+
import * as React57 from "react";
|
|
10317
10370
|
var WIRED_ENDPOINTS = [
|
|
10318
10371
|
// Nothing yet. Every id below would come from a real service:
|
|
10319
10372
|
// "plan.get", "placements.list", …
|
|
@@ -10484,8 +10537,8 @@ var RuntimeKit = {
|
|
|
10484
10537
|
};
|
|
10485
10538
|
RuntimeKit.declare(FEATURE_NEEDS);
|
|
10486
10539
|
function useRuntimeMode() {
|
|
10487
|
-
const [m, setM] =
|
|
10488
|
-
|
|
10540
|
+
const [m, setM] = React57.useState(RuntimeKit.getMode());
|
|
10541
|
+
React57.useEffect(() => RuntimeKit.subscribe(setM), []);
|
|
10489
10542
|
return m;
|
|
10490
10543
|
}
|
|
10491
10544
|
function useFeatureStatus(key) {
|
|
@@ -10568,12 +10621,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
|
|
|
10568
10621
|
}
|
|
10569
10622
|
function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
10570
10623
|
const session = SessionKit.useSession();
|
|
10571
|
-
const [project, setProject] =
|
|
10572
|
-
const [q, setQ] =
|
|
10573
|
-
const scrollRef =
|
|
10574
|
-
const nowRef =
|
|
10575
|
-
const rm =
|
|
10576
|
-
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(() => {
|
|
10577
10630
|
const m = {};
|
|
10578
10631
|
rm.items.forEach((i) => {
|
|
10579
10632
|
m[i.key] = i;
|
|
@@ -10582,7 +10635,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10582
10635
|
}, [rm]);
|
|
10583
10636
|
const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
|
|
10584
10637
|
const projects = [...new Set(rm.items.map((i) => i.project))];
|
|
10585
|
-
|
|
10638
|
+
React58.useEffect(() => {
|
|
10586
10639
|
let raf1 = 0, raf2 = 0;
|
|
10587
10640
|
const place = () => {
|
|
10588
10641
|
const box = scrollRef.current, mark = nowRef.current;
|
|
@@ -10656,7 +10709,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10656
10709
|
lastPhase = item.phase;
|
|
10657
10710
|
const inPhase = items.filter((i) => i.phase === item.phase).length;
|
|
10658
10711
|
const isBoundary = n === firstPending;
|
|
10659
|
-
return /* @__PURE__ */ jsxs72(
|
|
10712
|
+
return /* @__PURE__ */ jsxs72(React58.Fragment, { children: [
|
|
10660
10713
|
showPhase ? /* @__PURE__ */ jsxs72("div", { className: "fd-rm-era", children: [
|
|
10661
10714
|
/* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
|
|
10662
10715
|
/* @__PURE__ */ jsx81("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
|
|
@@ -10700,8 +10753,8 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10700
10753
|
}
|
|
10701
10754
|
|
|
10702
10755
|
// src/components/platform/ComingSoon.tsx
|
|
10703
|
-
import * as
|
|
10704
|
-
import { createPortal as
|
|
10756
|
+
import * as React59 from "react";
|
|
10757
|
+
import { createPortal as createPortal6 } from "react-dom";
|
|
10705
10758
|
import { Fragment as Fragment21, jsx as jsx82, jsxs as jsxs73 } from "react/jsx-runtime";
|
|
10706
10759
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
10707
10760
|
function readBypassed() {
|
|
@@ -10718,8 +10771,8 @@ function writeBypassed(list) {
|
|
|
10718
10771
|
}
|
|
10719
10772
|
}
|
|
10720
10773
|
function useBypass(key) {
|
|
10721
|
-
const [on, setOn] =
|
|
10722
|
-
|
|
10774
|
+
const [on, setOn] = React59.useState(() => !!key && readBypassed().indexOf(key) >= 0);
|
|
10775
|
+
React59.useEffect(() => {
|
|
10723
10776
|
setOn(!!key && readBypassed().indexOf(key) >= 0);
|
|
10724
10777
|
}, [key]);
|
|
10725
10778
|
const set = (next) => {
|
|
@@ -10766,9 +10819,9 @@ function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onB
|
|
|
10766
10819
|
] });
|
|
10767
10820
|
}
|
|
10768
10821
|
function useHoverCard(open2) {
|
|
10769
|
-
const anchor =
|
|
10770
|
-
const [pos, setPos] =
|
|
10771
|
-
|
|
10822
|
+
const anchor = React59.useRef(null);
|
|
10823
|
+
const [pos, setPos] = React59.useState(null);
|
|
10824
|
+
React59.useLayoutEffect(() => {
|
|
10772
10825
|
if (!open2 || !anchor.current) {
|
|
10773
10826
|
setPos(null);
|
|
10774
10827
|
return;
|
|
@@ -10895,12 +10948,12 @@ function ComingSoon({
|
|
|
10895
10948
|
] });
|
|
10896
10949
|
}
|
|
10897
10950
|
function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
|
|
10898
|
-
const [open2, setOpen] =
|
|
10951
|
+
const [open2, setOpen] = React59.useState(false);
|
|
10899
10952
|
const [anchor, pos] = useHoverCard(open2);
|
|
10900
|
-
const hoverCardRef =
|
|
10953
|
+
const hoverCardRef = React59.useRef(null);
|
|
10901
10954
|
const hoverLayer = useStackedLayer({ active: open2, containerRef: hoverCardRef, returnFocus: false });
|
|
10902
10955
|
const zIndex = useLayerZIndex(hoverLayer);
|
|
10903
|
-
const close2 =
|
|
10956
|
+
const close2 = React59.useRef(null);
|
|
10904
10957
|
const show = () => {
|
|
10905
10958
|
if (close2.current) {
|
|
10906
10959
|
clearTimeout(close2.current);
|
|
@@ -10916,7 +10969,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
10916
10969
|
setOpen(false);
|
|
10917
10970
|
}, 140);
|
|
10918
10971
|
};
|
|
10919
|
-
|
|
10972
|
+
React59.useEffect(() => () => {
|
|
10920
10973
|
if (close2.current) clearTimeout(close2.current);
|
|
10921
10974
|
}, []);
|
|
10922
10975
|
return /* @__PURE__ */ jsxs73(
|
|
@@ -10945,7 +10998,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
|
|
|
10945
10998
|
children: /* @__PURE__ */ jsx82("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
|
|
10946
10999
|
}
|
|
10947
11000
|
),
|
|
10948
|
-
open2 && pos ?
|
|
11001
|
+
open2 && pos ? createPortal6(
|
|
10949
11002
|
/* @__PURE__ */ jsx82(
|
|
10950
11003
|
"div",
|
|
10951
11004
|
{
|
|
@@ -11368,7 +11421,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
11368
11421
|
}
|
|
11369
11422
|
|
|
11370
11423
|
// src/components/planner/MixGap.tsx
|
|
11371
|
-
import * as
|
|
11424
|
+
import * as React60 from "react";
|
|
11372
11425
|
import { Fragment as Fragment23, jsx as jsx87, jsxs as jsxs78 } from "react/jsx-runtime";
|
|
11373
11426
|
var MIX_GAP_LAYOUT = {
|
|
11374
11427
|
trackHeight: 30,
|
|
@@ -11383,7 +11436,7 @@ function mixGapOffset(value, max) {
|
|
|
11383
11436
|
}
|
|
11384
11437
|
function MixGap({ rows = [], loading = false, className = "" }) {
|
|
11385
11438
|
const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
|
|
11386
|
-
const [hover, setHover] =
|
|
11439
|
+
const [hover, setHover] = React60.useState(null);
|
|
11387
11440
|
const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
|
|
11388
11441
|
const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
|
|
11389
11442
|
const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
|
|
@@ -11526,7 +11579,7 @@ function ChannelContribution({
|
|
|
11526
11579
|
}
|
|
11527
11580
|
|
|
11528
11581
|
// src/components/planner/BudgetReallocator.tsx
|
|
11529
|
-
import * as
|
|
11582
|
+
import * as React61 from "react";
|
|
11530
11583
|
import { Fragment as Fragment24, jsx as jsx89, jsxs as jsxs80 } from "react/jsx-runtime";
|
|
11531
11584
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
11532
11585
|
function BudgetReallocator({
|
|
@@ -11542,8 +11595,8 @@ function BudgetReallocator({
|
|
|
11542
11595
|
onCancel,
|
|
11543
11596
|
className = ""
|
|
11544
11597
|
}) {
|
|
11545
|
-
const [draft, setDraft] =
|
|
11546
|
-
|
|
11598
|
+
const [draft, setDraft] = React61.useState(spend);
|
|
11599
|
+
React61.useEffect(() => setDraft(spend), [spend]);
|
|
11547
11600
|
const dirty = draft !== spend;
|
|
11548
11601
|
const nextCrp = scoreFor ? scoreFor(draft) : crp;
|
|
11549
11602
|
const nextBand = bandFor(nextCrp);
|
|
@@ -11558,10 +11611,10 @@ function BudgetReallocator({
|
|
|
11558
11611
|
setDraft(spend);
|
|
11559
11612
|
if (onCancel) onCancel();
|
|
11560
11613
|
};
|
|
11561
|
-
const trackRef =
|
|
11562
|
-
const chipRef =
|
|
11563
|
-
const [chipLeft, setChipLeft] =
|
|
11564
|
-
|
|
11614
|
+
const trackRef = React61.useRef(null);
|
|
11615
|
+
const chipRef = React61.useRef(null);
|
|
11616
|
+
const [chipLeft, setChipLeft] = React61.useState(null);
|
|
11617
|
+
React61.useLayoutEffect(() => {
|
|
11565
11618
|
const track = trackRef.current;
|
|
11566
11619
|
if (!dirty || !track) {
|
|
11567
11620
|
setChipLeft(null);
|
|
@@ -11749,7 +11802,7 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
|
|
|
11749
11802
|
}
|
|
11750
11803
|
|
|
11751
11804
|
// src/components/planner/PreferenceMeter.tsx
|
|
11752
|
-
import * as
|
|
11805
|
+
import * as React62 from "react";
|
|
11753
11806
|
import { jsx as jsx92, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
11754
11807
|
function preferenceScore(criteria) {
|
|
11755
11808
|
const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
|
|
@@ -11779,7 +11832,7 @@ function PreferenceMeter({
|
|
|
11779
11832
|
className = ""
|
|
11780
11833
|
}) {
|
|
11781
11834
|
const value = score == null ? preferenceScore(criteria) : score;
|
|
11782
|
-
const segments =
|
|
11835
|
+
const segments = React62.useMemo(() => preferenceSegments(criteria), [criteria]);
|
|
11783
11836
|
return /* @__PURE__ */ jsx92(
|
|
11784
11837
|
ScoreMeter,
|
|
11785
11838
|
{
|
|
@@ -11818,10 +11871,10 @@ function PreferenceMeter({
|
|
|
11818
11871
|
}
|
|
11819
11872
|
|
|
11820
11873
|
// src/components/chat/AgentChatPanel.tsx
|
|
11821
|
-
import * as
|
|
11874
|
+
import * as React68 from "react";
|
|
11822
11875
|
|
|
11823
11876
|
// src/components/chat/chatEngine.ts
|
|
11824
|
-
import * as
|
|
11877
|
+
import * as React63 from "react";
|
|
11825
11878
|
var CHAT_UNAVAILABLE = "chat_unavailable";
|
|
11826
11879
|
var JOB_PENDING = ["queued", "running"];
|
|
11827
11880
|
var JOB_SUCCESS = ["completed", "recovered"];
|
|
@@ -11875,22 +11928,22 @@ function useChatEngine(opts) {
|
|
|
11875
11928
|
onClear,
|
|
11876
11929
|
onFeedback
|
|
11877
11930
|
} = opts || {};
|
|
11878
|
-
const [status, setStatus] =
|
|
11879
|
-
const [threadId, setThreadId] =
|
|
11880
|
-
const [messages, setMessages] =
|
|
11881
|
-
const [queue, setQueue] =
|
|
11882
|
-
const [fatal, setFatal] =
|
|
11883
|
-
const [busy, setBusy] =
|
|
11884
|
-
const [turnStartedAt, setTurnStartedAt] =
|
|
11885
|
-
const listRef =
|
|
11886
|
-
const queueRef =
|
|
11887
|
-
const busyRef =
|
|
11888
|
-
const stoppedRef =
|
|
11889
|
-
const abortRef =
|
|
11890
|
-
const serverCount =
|
|
11891
|
-
const threadRef =
|
|
11892
|
-
const mounted =
|
|
11893
|
-
|
|
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(() => {
|
|
11894
11947
|
mounted.current = true;
|
|
11895
11948
|
return () => {
|
|
11896
11949
|
mounted.current = false;
|
|
@@ -11912,14 +11965,14 @@ function useChatEngine(opts) {
|
|
|
11912
11965
|
}
|
|
11913
11966
|
return false;
|
|
11914
11967
|
};
|
|
11915
|
-
const loadThread =
|
|
11968
|
+
const loadThread = React63.useCallback(async (id) => {
|
|
11916
11969
|
const data = await apiAdapter.getThread(id);
|
|
11917
11970
|
const list = [...data && data.messages || []];
|
|
11918
11971
|
serverCount.current = list.length;
|
|
11919
11972
|
commit(list);
|
|
11920
11973
|
return list;
|
|
11921
11974
|
}, [apiAdapter]);
|
|
11922
|
-
|
|
11975
|
+
React63.useEffect(() => {
|
|
11923
11976
|
if (!apiAdapter) {
|
|
11924
11977
|
setStatus("idle");
|
|
11925
11978
|
setFatal(null);
|
|
@@ -12132,7 +12185,7 @@ function useChatEngine(opts) {
|
|
|
12132
12185
|
await dispatchTurn(turn);
|
|
12133
12186
|
}
|
|
12134
12187
|
}
|
|
12135
|
-
const send =
|
|
12188
|
+
const send = React63.useCallback((text, attachments) => {
|
|
12136
12189
|
const body = (text || "").trim();
|
|
12137
12190
|
if (!body && !(attachments && attachments.length)) return;
|
|
12138
12191
|
if (status === "disconnected") return;
|
|
@@ -12142,7 +12195,7 @@ function useChatEngine(opts) {
|
|
|
12142
12195
|
stoppedRef.current = false;
|
|
12143
12196
|
drain();
|
|
12144
12197
|
}, [status]);
|
|
12145
|
-
const stop =
|
|
12198
|
+
const stop = React63.useCallback(() => {
|
|
12146
12199
|
stoppedRef.current = true;
|
|
12147
12200
|
const ac = abortRef.current;
|
|
12148
12201
|
if (ac) {
|
|
@@ -12161,11 +12214,11 @@ function useChatEngine(opts) {
|
|
|
12161
12214
|
store.del(STORAGE_PREFIX + threadRef.current);
|
|
12162
12215
|
}
|
|
12163
12216
|
}, [apiAdapter]);
|
|
12164
|
-
const removeQueued =
|
|
12217
|
+
const removeQueued = React63.useCallback((id) => {
|
|
12165
12218
|
queueRef.current = queueRef.current.filter((t) => t.id !== id);
|
|
12166
12219
|
setQueue(queueRef.current.slice());
|
|
12167
12220
|
}, []);
|
|
12168
|
-
const retry =
|
|
12221
|
+
const retry = React63.useCallback(() => {
|
|
12169
12222
|
const list = listRef.current;
|
|
12170
12223
|
let at = -1;
|
|
12171
12224
|
for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
|
|
@@ -12181,19 +12234,19 @@ function useChatEngine(opts) {
|
|
|
12181
12234
|
setQueue(queueRef.current.slice());
|
|
12182
12235
|
drain();
|
|
12183
12236
|
}, []);
|
|
12184
|
-
const clear =
|
|
12237
|
+
const clear = React63.useCallback(() => {
|
|
12185
12238
|
commit([]);
|
|
12186
12239
|
serverCount.current = 0;
|
|
12187
12240
|
queueRef.current = [];
|
|
12188
12241
|
setQueue([]);
|
|
12189
12242
|
onClear && onClear();
|
|
12190
12243
|
}, [onClear]);
|
|
12191
|
-
const setFeedback =
|
|
12244
|
+
const setFeedback = React63.useCallback((id, value) => {
|
|
12192
12245
|
patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
|
|
12193
12246
|
const msg = listRef.current.find((m) => m.id === id);
|
|
12194
12247
|
onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
|
|
12195
12248
|
}, [onFeedback]);
|
|
12196
|
-
const reload =
|
|
12249
|
+
const reload = React63.useCallback(async () => {
|
|
12197
12250
|
if (!threadRef.current) return;
|
|
12198
12251
|
setStatus("loading");
|
|
12199
12252
|
try {
|
|
@@ -12231,10 +12284,10 @@ var ChatKit = {
|
|
|
12231
12284
|
};
|
|
12232
12285
|
|
|
12233
12286
|
// src/components/chat/ChatTranscript.tsx
|
|
12234
|
-
import * as
|
|
12287
|
+
import * as React65 from "react";
|
|
12235
12288
|
|
|
12236
12289
|
// src/components/chat/ChatTurn.tsx
|
|
12237
|
-
import * as
|
|
12290
|
+
import * as React64 from "react";
|
|
12238
12291
|
import { jsx as jsx93, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
12239
12292
|
function JsonView({ value }) {
|
|
12240
12293
|
let text;
|
|
@@ -12271,7 +12324,7 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
|
|
|
12271
12324
|
] });
|
|
12272
12325
|
}
|
|
12273
12326
|
function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
12274
|
-
const [open2, setOpen] =
|
|
12327
|
+
const [open2, setOpen] = React64.useState(defaultOpen);
|
|
12275
12328
|
if (!text) return null;
|
|
12276
12329
|
return /* @__PURE__ */ jsxs84("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
|
|
12277
12330
|
/* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -12288,7 +12341,7 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
|
|
|
12288
12341
|
] });
|
|
12289
12342
|
}
|
|
12290
12343
|
function Citations({ items = [], onOpen }) {
|
|
12291
|
-
const [open2, setOpen] =
|
|
12344
|
+
const [open2, setOpen] = React64.useState(false);
|
|
12292
12345
|
if (!items.length) return null;
|
|
12293
12346
|
return /* @__PURE__ */ jsxs84("div", { className: "fdc-cites", children: [
|
|
12294
12347
|
/* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
|
|
@@ -12314,7 +12367,7 @@ function clampText(text, max) {
|
|
|
12314
12367
|
return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
|
|
12315
12368
|
}
|
|
12316
12369
|
function MessageBody({ message: m, ctx }) {
|
|
12317
|
-
const [expanded, setExpanded] =
|
|
12370
|
+
const [expanded, setExpanded] = React64.useState(false);
|
|
12318
12371
|
const isUser = m.role === "user";
|
|
12319
12372
|
const raw = m.text || "";
|
|
12320
12373
|
const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
|
|
@@ -12394,7 +12447,7 @@ function RunActions({ group, ctx }) {
|
|
|
12394
12447
|
] }),
|
|
12395
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,
|
|
12396
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,
|
|
12397
|
-
isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs84(
|
|
12450
|
+
isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs84(React64.Fragment, { children: [
|
|
12398
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" }) }),
|
|
12399
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" }) })
|
|
12400
12453
|
] }) : null,
|
|
@@ -12489,10 +12542,10 @@ function ChatTranscript({
|
|
|
12489
12542
|
renderEmpty,
|
|
12490
12543
|
className = ""
|
|
12491
12544
|
}) {
|
|
12492
|
-
const scroller =
|
|
12493
|
-
const stick =
|
|
12494
|
-
const [pill, setPill] =
|
|
12495
|
-
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);
|
|
12496
12549
|
const toBottom = (smooth) => {
|
|
12497
12550
|
const el = scroller.current;
|
|
12498
12551
|
if (!el) return;
|
|
@@ -12511,7 +12564,7 @@ function ChatTranscript({
|
|
|
12511
12564
|
seen.current = messages.length;
|
|
12512
12565
|
}
|
|
12513
12566
|
};
|
|
12514
|
-
|
|
12567
|
+
React65.useLayoutEffect(() => {
|
|
12515
12568
|
const el = scroller.current;
|
|
12516
12569
|
if (!el) return;
|
|
12517
12570
|
if (stick.current) {
|
|
@@ -12519,7 +12572,7 @@ function ChatTranscript({
|
|
|
12519
12572
|
seen.current = messages.length;
|
|
12520
12573
|
} else setPill(Math.max(0, messages.length - seen.current));
|
|
12521
12574
|
}, [messages]);
|
|
12522
|
-
|
|
12575
|
+
React65.useEffect(() => {
|
|
12523
12576
|
const el = scroller.current;
|
|
12524
12577
|
const inner = el && el.firstChild;
|
|
12525
12578
|
if (!el || !inner || typeof ResizeObserver === "undefined") return;
|
|
@@ -12529,7 +12582,7 @@ function ChatTranscript({
|
|
|
12529
12582
|
ro.observe(inner);
|
|
12530
12583
|
return () => ro.disconnect();
|
|
12531
12584
|
}, []);
|
|
12532
|
-
const groups =
|
|
12585
|
+
const groups = React65.useMemo(() => groupMessages(messages), [messages]);
|
|
12533
12586
|
const empty = !messages.length && status === "ready";
|
|
12534
12587
|
return /* @__PURE__ */ jsxs85("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
|
|
12535
12588
|
/* @__PURE__ */ jsxs85("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
|
|
@@ -12553,7 +12606,7 @@ function ChatTranscript({
|
|
|
12553
12606
|
const prev = groups[i - 1];
|
|
12554
12607
|
const k = dayKey(g.messages[0].timestamp);
|
|
12555
12608
|
const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
|
|
12556
|
-
return /* @__PURE__ */ jsxs85(
|
|
12609
|
+
return /* @__PURE__ */ jsxs85(React65.Fragment, { children: [
|
|
12557
12610
|
showDay ? /* @__PURE__ */ jsx94("div", { className: "fdc-day", children: /* @__PURE__ */ jsx94("span", { children: dayLabel(k) }) }) : null,
|
|
12558
12611
|
/* @__PURE__ */ jsx94(ChatTurn, { group: g, ctx })
|
|
12559
12612
|
] }, g.key || i);
|
|
@@ -12570,7 +12623,7 @@ function ChatTranscript({
|
|
|
12570
12623
|
var TranscriptKit = { groupMessages };
|
|
12571
12624
|
|
|
12572
12625
|
// src/components/chat/ChatComposer.tsx
|
|
12573
|
-
import * as
|
|
12626
|
+
import * as React66 from "react";
|
|
12574
12627
|
import { jsx as jsx95, jsxs as jsxs86 } from "react/jsx-runtime";
|
|
12575
12628
|
function ChatComposer({
|
|
12576
12629
|
onSubmit,
|
|
@@ -12598,17 +12651,17 @@ function ChatComposer({
|
|
|
12598
12651
|
onReject,
|
|
12599
12652
|
onOpenAttachment
|
|
12600
12653
|
}) {
|
|
12601
|
-
const [text, setText] =
|
|
12602
|
-
const [trigger, setTrigger] =
|
|
12603
|
-
const [mentionItems, setMentionItems] =
|
|
12604
|
-
const [listening, setListening] =
|
|
12605
|
-
const [notice, setNotice] =
|
|
12606
|
-
const editor =
|
|
12607
|
-
const wrap =
|
|
12608
|
-
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);
|
|
12609
12662
|
const staged = useStagedFiles(fileUploadHandler, { onError: () => {
|
|
12610
12663
|
} });
|
|
12611
|
-
|
|
12664
|
+
React66.useEffect(() => {
|
|
12612
12665
|
if (draft != null && draft !== text) setText(draft);
|
|
12613
12666
|
}, [draft]);
|
|
12614
12667
|
const change = (v) => {
|
|
@@ -12644,7 +12697,7 @@ function ChatComposer({
|
|
|
12644
12697
|
e.preventDefault();
|
|
12645
12698
|
staged.add(found.files);
|
|
12646
12699
|
};
|
|
12647
|
-
|
|
12700
|
+
React66.useEffect(() => {
|
|
12648
12701
|
if (!trigger || trigger.type !== "mention" || !mentionSources) {
|
|
12649
12702
|
setMentionItems([]);
|
|
12650
12703
|
return;
|
|
@@ -12662,7 +12715,7 @@ function ChatComposer({
|
|
|
12662
12715
|
const q = (trigger.query || "").toLowerCase();
|
|
12663
12716
|
setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
|
|
12664
12717
|
}, [trigger, mentionSources]);
|
|
12665
|
-
const slashItems =
|
|
12718
|
+
const slashItems = React66.useMemo(() => {
|
|
12666
12719
|
if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
|
|
12667
12720
|
const q = (trigger.query || "").toLowerCase();
|
|
12668
12721
|
return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
|
|
@@ -12832,12 +12885,12 @@ function ChatComposer({
|
|
|
12832
12885
|
}
|
|
12833
12886
|
|
|
12834
12887
|
// src/components/chat/ChatSessionBar.tsx
|
|
12835
|
-
import * as
|
|
12888
|
+
import * as React67 from "react";
|
|
12836
12889
|
import { jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
12837
12890
|
var compact2 = meterFormats.compact;
|
|
12838
12891
|
function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
|
|
12839
|
-
const [open2, setOpen] =
|
|
12840
|
-
const anchor =
|
|
12892
|
+
const [open2, setOpen] = React67.useState(false);
|
|
12893
|
+
const anchor = React67.useRef(null);
|
|
12841
12894
|
const stats = sessionStats || null;
|
|
12842
12895
|
const cu = contextUsage || null;
|
|
12843
12896
|
const limits = usageLimits || null;
|
|
@@ -12852,7 +12905,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
|
|
|
12852
12905
|
if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
|
|
12853
12906
|
if (cu) bits.push(pct + "% context");
|
|
12854
12907
|
const expandable = !!(cu || limits);
|
|
12855
|
-
return /* @__PURE__ */ jsxs87(
|
|
12908
|
+
return /* @__PURE__ */ jsxs87(React67.Fragment, { children: [
|
|
12856
12909
|
/* @__PURE__ */ jsxs87("div", { className: "fdc-bar", children: [
|
|
12857
12910
|
/* @__PURE__ */ jsxs87(
|
|
12858
12911
|
"button",
|
|
@@ -12993,7 +13046,7 @@ function ModelControls({
|
|
|
12993
13046
|
] })
|
|
12994
13047
|
});
|
|
12995
13048
|
}
|
|
12996
|
-
return /* @__PURE__ */ jsxs87(
|
|
13049
|
+
return /* @__PURE__ */ jsxs87(React67.Fragment, { children: [
|
|
12997
13050
|
/* @__PURE__ */ jsx96(
|
|
12998
13051
|
MenuButton,
|
|
12999
13052
|
{
|
|
@@ -13110,11 +13163,11 @@ function AgentChatPanel({
|
|
|
13110
13163
|
onFeedback,
|
|
13111
13164
|
onEditMessage
|
|
13112
13165
|
}) {
|
|
13113
|
-
const [panelWidth, setPanelWidth] =
|
|
13114
|
-
const [applied, setApplied] =
|
|
13115
|
-
const [draft, setDraft] =
|
|
13116
|
-
const dragging =
|
|
13117
|
-
|
|
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]);
|
|
13118
13171
|
const engine = useChatEngine({
|
|
13119
13172
|
contextType,
|
|
13120
13173
|
contextId,
|
|
@@ -13318,7 +13371,7 @@ function AgentChatPanel({
|
|
|
13318
13371
|
}
|
|
13319
13372
|
|
|
13320
13373
|
// src/components/files/FileViewer.tsx
|
|
13321
|
-
import * as
|
|
13374
|
+
import * as React69 from "react";
|
|
13322
13375
|
import { jsx as jsx98, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
13323
13376
|
function previewKindOf(file) {
|
|
13324
13377
|
const mime = (file.mime || "").toLowerCase();
|
|
@@ -13375,13 +13428,13 @@ function parseDelimited(text, delimiter) {
|
|
|
13375
13428
|
return rows;
|
|
13376
13429
|
}
|
|
13377
13430
|
function usePreview(file, kind, resolveUrl) {
|
|
13378
|
-
const [state, setState] =
|
|
13379
|
-
const [attempt, setAttempt] =
|
|
13380
|
-
const resolveRef =
|
|
13381
|
-
|
|
13431
|
+
const [state, setState] = React69.useState({ status: "loading" });
|
|
13432
|
+
const [attempt, setAttempt] = React69.useState(0);
|
|
13433
|
+
const resolveRef = React69.useRef(resolveUrl);
|
|
13434
|
+
React69.useEffect(() => {
|
|
13382
13435
|
resolveRef.current = resolveUrl;
|
|
13383
13436
|
}, [resolveUrl]);
|
|
13384
|
-
|
|
13437
|
+
React69.useEffect(() => {
|
|
13385
13438
|
if (kind === "none") {
|
|
13386
13439
|
setState({ status: "ready" });
|
|
13387
13440
|
return;
|
|
@@ -13411,7 +13464,7 @@ function usePreview(file, kind, resolveUrl) {
|
|
|
13411
13464
|
if (ac) ac.abort();
|
|
13412
13465
|
};
|
|
13413
13466
|
}, [file.id, kind, attempt]);
|
|
13414
|
-
return { ...state, retry:
|
|
13467
|
+
return { ...state, retry: React69.useCallback(() => setAttempt((a) => a + 1), []) };
|
|
13415
13468
|
}
|
|
13416
13469
|
function PreviewBody({ file, kind, state }) {
|
|
13417
13470
|
if (kind === "image") return /* @__PURE__ */ jsx98("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
|
|
@@ -13456,13 +13509,13 @@ function PreviewBody({ file, kind, state }) {
|
|
|
13456
13509
|
] });
|
|
13457
13510
|
}
|
|
13458
13511
|
function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
|
|
13459
|
-
const kind =
|
|
13512
|
+
const kind = React69.useMemo(() => previewKindOf(file), [file]);
|
|
13460
13513
|
const preview = usePreview(file, kind, resolveUrl);
|
|
13461
|
-
const [tab, setTab] =
|
|
13462
|
-
const [downloading, setDownloading] =
|
|
13463
|
-
const [downloadError, setDownloadError] =
|
|
13514
|
+
const [tab, setTab] = React69.useState("preview");
|
|
13515
|
+
const [downloading, setDownloading] = React69.useState(false);
|
|
13516
|
+
const [downloadError, setDownloadError] = React69.useState(null);
|
|
13464
13517
|
const hasSide = sidePanel != null;
|
|
13465
|
-
|
|
13518
|
+
React69.useEffect(() => {
|
|
13466
13519
|
setTab("preview");
|
|
13467
13520
|
}, [file.id]);
|
|
13468
13521
|
const download = () => {
|
|
@@ -13529,7 +13582,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
13529
13582
|
}
|
|
13530
13583
|
|
|
13531
13584
|
// src/components/files/FileBrowser.tsx
|
|
13532
|
-
import * as
|
|
13585
|
+
import * as React70 from "react";
|
|
13533
13586
|
import { Fragment as Fragment28, jsx as jsx99, jsxs as jsxs90 } from "react/jsx-runtime";
|
|
13534
13587
|
function childrenOf(folders, parentId) {
|
|
13535
13588
|
return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -13639,8 +13692,8 @@ function FolderPickerMenu({
|
|
|
13639
13692
|
] });
|
|
13640
13693
|
}
|
|
13641
13694
|
function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
|
|
13642
|
-
const [over, setOver] =
|
|
13643
|
-
const dragCounter =
|
|
13695
|
+
const [over, setOver] = React70.useState(false);
|
|
13696
|
+
const dragCounter = React70.useRef(0);
|
|
13644
13697
|
const dropHandlers = isDropTarget ? {
|
|
13645
13698
|
onDragEnter: (e) => {
|
|
13646
13699
|
if (!hasInternalPayload(e)) return;
|
|
@@ -13688,8 +13741,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
|
|
|
13688
13741
|
}
|
|
13689
13742
|
function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
|
|
13690
13743
|
const kids = childrenOf(folders, folder.id);
|
|
13691
|
-
const [expanded, setExpanded] =
|
|
13692
|
-
|
|
13744
|
+
const [expanded, setExpanded] = React70.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
|
|
13745
|
+
React70.useEffect(() => {
|
|
13693
13746
|
if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
|
|
13694
13747
|
}, [currentFolderId, folder.id, folders]);
|
|
13695
13748
|
const isCurrent = folder.id === currentFolderId;
|
|
@@ -13755,15 +13808,15 @@ function FileBrowser({
|
|
|
13755
13808
|
const canUpload = perm.canUpload !== false && !!onUpload;
|
|
13756
13809
|
const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
|
|
13757
13810
|
const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
|
|
13758
|
-
const [createOpen, setCreateOpen] =
|
|
13759
|
-
const [createName, setCreateName] =
|
|
13760
|
-
const [renameTarget, setRenameTarget] =
|
|
13761
|
-
const [renameValue, setRenameValue] =
|
|
13762
|
-
const [deleteTarget, setDeleteTarget] =
|
|
13763
|
-
const uploadInputRef =
|
|
13764
|
-
const crumbFolders =
|
|
13765
|
-
const subfolders =
|
|
13766
|
-
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(
|
|
13767
13820
|
() => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
|
|
13768
13821
|
[files, currentFolderId]
|
|
13769
13822
|
);
|
|
@@ -13995,8 +14048,8 @@ function BreadcrumbCrumb({
|
|
|
13995
14048
|
isDropTarget,
|
|
13996
14049
|
onDropPayload
|
|
13997
14050
|
}) {
|
|
13998
|
-
const [over, setOver] =
|
|
13999
|
-
const dragCounter =
|
|
14051
|
+
const [over, setOver] = React70.useState(false);
|
|
14052
|
+
const dragCounter = React70.useRef(0);
|
|
14000
14053
|
const dropHandlers = isDropTarget ? {
|
|
14001
14054
|
onDragEnter: (e) => {
|
|
14002
14055
|
if (!hasInternalPayload(e)) return;
|
|
@@ -14025,7 +14078,7 @@ function BreadcrumbCrumb({
|
|
|
14025
14078
|
}
|
|
14026
14079
|
|
|
14027
14080
|
// src/kits/query.ts
|
|
14028
|
-
import * as
|
|
14081
|
+
import * as React71 from "react";
|
|
14029
14082
|
var isMultiSelectShaped = (v) => !!v && typeof v === "object" && Array.isArray(v.values);
|
|
14030
14083
|
var isRangeShaped = (v) => !!v && typeof v === "object" && ("min" in v || "max" in v);
|
|
14031
14084
|
var isDateShaped = (v) => !!v && typeof v === "object" && "kind" in v;
|
|
@@ -14080,22 +14133,22 @@ function compare(a, b, dir) {
|
|
|
14080
14133
|
var API = null;
|
|
14081
14134
|
var PREFS = null;
|
|
14082
14135
|
function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
|
|
14083
|
-
const [query, setQuery] =
|
|
14136
|
+
const [query, setQuery] = React71.useState(() => {
|
|
14084
14137
|
const store = PREFS || window.PlannerPrefs;
|
|
14085
14138
|
const saved = prefsKey && store ? store.getTable(prefsKey) : {};
|
|
14086
14139
|
return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
|
|
14087
14140
|
});
|
|
14088
|
-
const savePref =
|
|
14141
|
+
const savePref = React71.useCallback((patch2) => {
|
|
14089
14142
|
const store = PREFS || window.PlannerPrefs;
|
|
14090
14143
|
if (prefsKey && store) store.setTable(prefsKey, patch2);
|
|
14091
14144
|
}, [prefsKey]);
|
|
14092
|
-
const [res, setRes] =
|
|
14093
|
-
const [loading, setLoading] =
|
|
14094
|
-
const seq2 =
|
|
14145
|
+
const [res, setRes] = React71.useState(null);
|
|
14146
|
+
const [loading, setLoading] = React71.useState(true);
|
|
14147
|
+
const seq2 = React71.useRef(0);
|
|
14095
14148
|
const depKey = (deps || []).join("|");
|
|
14096
14149
|
const paramKey = JSON.stringify(params || {});
|
|
14097
14150
|
const queryKey = JSON.stringify(query);
|
|
14098
|
-
|
|
14151
|
+
React71.useEffect(() => {
|
|
14099
14152
|
const id = ++seq2.current;
|
|
14100
14153
|
setLoading(true);
|
|
14101
14154
|
const t = setTimeout(() => {
|
|
@@ -14414,12 +14467,12 @@ function createVersionStore(initialState, options) {
|
|
|
14414
14467
|
}
|
|
14415
14468
|
|
|
14416
14469
|
// src/kits/documentTitle.ts
|
|
14417
|
-
import * as
|
|
14470
|
+
import * as React72 from "react";
|
|
14418
14471
|
function formatDocumentTitle(routeTitle, appName) {
|
|
14419
14472
|
return [routeTitle, appName, "Flytedesk"].filter((part) => !!part && part.length > 0).join(" \xB7 ");
|
|
14420
14473
|
}
|
|
14421
14474
|
function useDocumentTitle(routeTitle, appName) {
|
|
14422
|
-
|
|
14475
|
+
React72.useEffect(() => {
|
|
14423
14476
|
if (typeof document === "undefined") return;
|
|
14424
14477
|
document.title = formatDocumentTitle(routeTitle, appName);
|
|
14425
14478
|
}, [routeTitle, appName]);
|
|
@@ -14465,6 +14518,7 @@ export {
|
|
|
14465
14518
|
CodeEditor,
|
|
14466
14519
|
Collapsible,
|
|
14467
14520
|
ComingSoon,
|
|
14521
|
+
CornerStackPortal,
|
|
14468
14522
|
CsiBadge,
|
|
14469
14523
|
CsiHero,
|
|
14470
14524
|
CsiMeter,
|
|
@@ -14633,6 +14687,7 @@ export {
|
|
|
14633
14687
|
useAppearancePrefs,
|
|
14634
14688
|
useChatEngine,
|
|
14635
14689
|
useCopyToClipboard,
|
|
14690
|
+
useCornerStackSlot,
|
|
14636
14691
|
useDocumentTitle,
|
|
14637
14692
|
useFeatureStatus,
|
|
14638
14693
|
useLayerZIndex,
|