@glyphjs/components 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +548 -151
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -34
- package/dist/index.d.ts +53 -34
- package/dist/index.js +549 -152
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var schemas = require('@glyphjs/schemas');
|
|
4
|
+
var runtime = require('@glyphjs/runtime');
|
|
4
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
6
|
var react = require('react');
|
|
6
7
|
var d32 = require('d3');
|
|
@@ -74,8 +75,8 @@ function Callout({ data }) {
|
|
|
74
75
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "note", "aria-label": CALLOUT_LABELS[type], style: containerStyle11, children: [
|
|
75
76
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: iconStyle, "aria-hidden": "true", children: CALLOUT_ICONS[type] }),
|
|
76
77
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: bodyStyle3, children: [
|
|
77
|
-
title && /* @__PURE__ */ jsxRuntime.jsx("div", { style: titleStyle2, children: title }),
|
|
78
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children: content })
|
|
78
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("div", { style: titleStyle2, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: title }) }),
|
|
79
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content }) })
|
|
79
80
|
] })
|
|
80
81
|
] });
|
|
81
82
|
}
|
|
@@ -553,7 +554,7 @@ function Steps({ data }) {
|
|
|
553
554
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: indicatorStyle(status), children: status === "completed" ? "\u2713" : "" }),
|
|
554
555
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: bodyStyle, children: [
|
|
555
556
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: titleStyle(status), children: step.title }),
|
|
556
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyle(status), children: step.content })
|
|
557
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyle(status), children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: step.content }) })
|
|
557
558
|
] })
|
|
558
559
|
]
|
|
559
560
|
},
|
|
@@ -1212,7 +1213,7 @@ function Timeline({ data }) {
|
|
|
1212
1213
|
fontWeight: 700,
|
|
1213
1214
|
marginTop: 2
|
|
1214
1215
|
},
|
|
1215
|
-
children: pe.event.title
|
|
1216
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: pe.event.title })
|
|
1216
1217
|
}
|
|
1217
1218
|
),
|
|
1218
1219
|
pe.event.description && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1223,7 +1224,7 @@ function Timeline({ data }) {
|
|
|
1223
1224
|
color: "var(--glyph-timeline-desc-color, #7a8599)",
|
|
1224
1225
|
marginTop: 2
|
|
1225
1226
|
},
|
|
1226
|
-
children: pe.event.description
|
|
1227
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: pe.event.description })
|
|
1227
1228
|
}
|
|
1228
1229
|
)
|
|
1229
1230
|
] })
|
|
@@ -1241,12 +1242,16 @@ function Timeline({ data }) {
|
|
|
1241
1242
|
clipPath: "inset(50%)",
|
|
1242
1243
|
whiteSpace: "nowrap"
|
|
1243
1244
|
},
|
|
1244
|
-
children: sorted.map((e, idx) =>
|
|
1245
|
-
|
|
1246
|
-
"
|
|
1247
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1248
|
-
|
|
1249
|
-
|
|
1245
|
+
children: sorted.map((e, idx) => {
|
|
1246
|
+
const titleText = typeof e.title === "string" ? e.title : "Event";
|
|
1247
|
+
const descText = typeof e.description === "string" ? e.description : "";
|
|
1248
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
1249
|
+
/* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: isoDate(e.date), children: formatDate(e.date) }),
|
|
1250
|
+
" \u2014 ",
|
|
1251
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: titleText }),
|
|
1252
|
+
descText ? `: ${descText}` : ""
|
|
1253
|
+
] }, idx);
|
|
1254
|
+
})
|
|
1250
1255
|
}
|
|
1251
1256
|
)
|
|
1252
1257
|
]
|
|
@@ -1450,6 +1455,326 @@ function computeForceLayout(nodes, edges) {
|
|
|
1450
1455
|
height: maxY + LAYOUT_PADDING
|
|
1451
1456
|
};
|
|
1452
1457
|
}
|
|
1458
|
+
function useZoomInteraction({
|
|
1459
|
+
svgRef,
|
|
1460
|
+
rootRef,
|
|
1461
|
+
interactionMode
|
|
1462
|
+
}) {
|
|
1463
|
+
const [isActive, setIsActive] = react.useState(interactionMode === "always");
|
|
1464
|
+
const [hasAttemptedScroll, setHasAttemptedScroll] = react.useState(false);
|
|
1465
|
+
const containerRef = react.useRef(null);
|
|
1466
|
+
react.useEffect(() => {
|
|
1467
|
+
setIsActive(interactionMode === "always");
|
|
1468
|
+
setHasAttemptedScroll(false);
|
|
1469
|
+
}, [interactionMode]);
|
|
1470
|
+
const filterFunction = react.useCallback(
|
|
1471
|
+
(event) => {
|
|
1472
|
+
if (interactionMode === "always") {
|
|
1473
|
+
return true;
|
|
1474
|
+
}
|
|
1475
|
+
if (interactionMode === "modifier-key") {
|
|
1476
|
+
if (event.type === "mousedown") return true;
|
|
1477
|
+
if (event.type === "wheel") {
|
|
1478
|
+
const wheelEvent = event;
|
|
1479
|
+
const hasModifier = wheelEvent.altKey;
|
|
1480
|
+
if (!hasModifier && !hasAttemptedScroll) {
|
|
1481
|
+
setHasAttemptedScroll(true);
|
|
1482
|
+
setTimeout(() => setHasAttemptedScroll(false), 3e3);
|
|
1483
|
+
}
|
|
1484
|
+
return hasModifier;
|
|
1485
|
+
}
|
|
1486
|
+
return true;
|
|
1487
|
+
}
|
|
1488
|
+
if (interactionMode === "click-to-activate") {
|
|
1489
|
+
return isActive;
|
|
1490
|
+
}
|
|
1491
|
+
return true;
|
|
1492
|
+
},
|
|
1493
|
+
[interactionMode, isActive, hasAttemptedScroll]
|
|
1494
|
+
);
|
|
1495
|
+
react.useEffect(() => {
|
|
1496
|
+
if (interactionMode !== "modifier-key" || !svgRef.current) return;
|
|
1497
|
+
const svg = svgRef.current;
|
|
1498
|
+
const container = svg.parentElement;
|
|
1499
|
+
if (!container) return;
|
|
1500
|
+
const handleWheel = (event) => {
|
|
1501
|
+
const target = event.target;
|
|
1502
|
+
if (event.altKey && svg.contains(target)) {
|
|
1503
|
+
event.preventDefault();
|
|
1504
|
+
event.stopPropagation();
|
|
1505
|
+
}
|
|
1506
|
+
};
|
|
1507
|
+
container.addEventListener("wheel", handleWheel, { passive: false, capture: true });
|
|
1508
|
+
return () => {
|
|
1509
|
+
container.removeEventListener("wheel", handleWheel, { capture: true });
|
|
1510
|
+
};
|
|
1511
|
+
}, [interactionMode, svgRef]);
|
|
1512
|
+
const zoomBehavior = react.useMemo(() => {
|
|
1513
|
+
const zoom3 = d32__namespace.zoom().scaleExtent([0.1, 4]);
|
|
1514
|
+
if (typeof zoom3.filter === "function") {
|
|
1515
|
+
zoom3.filter(filterFunction);
|
|
1516
|
+
}
|
|
1517
|
+
zoom3.on("zoom", (event) => {
|
|
1518
|
+
if (rootRef.current) {
|
|
1519
|
+
d32__namespace.select(rootRef.current).attr("transform", event.transform.toString());
|
|
1520
|
+
}
|
|
1521
|
+
});
|
|
1522
|
+
return zoom3;
|
|
1523
|
+
}, [filterFunction, rootRef]);
|
|
1524
|
+
const handleActivate = react.useCallback(() => {
|
|
1525
|
+
if (interactionMode === "click-to-activate") {
|
|
1526
|
+
setIsActive(true);
|
|
1527
|
+
}
|
|
1528
|
+
}, [interactionMode]);
|
|
1529
|
+
react.useEffect(() => {
|
|
1530
|
+
if (interactionMode !== "click-to-activate" || !isActive) return;
|
|
1531
|
+
const handleKeyDown = (e) => {
|
|
1532
|
+
if (e.key === "Escape") {
|
|
1533
|
+
setIsActive(false);
|
|
1534
|
+
}
|
|
1535
|
+
};
|
|
1536
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1537
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
1538
|
+
}, [interactionMode, isActive]);
|
|
1539
|
+
react.useEffect(() => {
|
|
1540
|
+
if (interactionMode !== "click-to-activate" || !isActive) return;
|
|
1541
|
+
const handleClickOutside = (e) => {
|
|
1542
|
+
const container = svgRef.current?.parentElement;
|
|
1543
|
+
if (container && !container.contains(e.target)) {
|
|
1544
|
+
setIsActive(false);
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
document.addEventListener("click", handleClickOutside, true);
|
|
1548
|
+
return () => document.removeEventListener("click", handleClickOutside, true);
|
|
1549
|
+
}, [interactionMode, isActive, svgRef]);
|
|
1550
|
+
react.useEffect(() => {
|
|
1551
|
+
if (svgRef.current) {
|
|
1552
|
+
containerRef.current = svgRef.current.parentElement;
|
|
1553
|
+
}
|
|
1554
|
+
}, [svgRef]);
|
|
1555
|
+
const overlayProps = react.useMemo(() => {
|
|
1556
|
+
if (interactionMode === "always") return null;
|
|
1557
|
+
if (interactionMode === "modifier-key" && !hasAttemptedScroll) return null;
|
|
1558
|
+
if (interactionMode === "click-to-activate" && isActive) return null;
|
|
1559
|
+
return {
|
|
1560
|
+
mode: interactionMode,
|
|
1561
|
+
isActive,
|
|
1562
|
+
onActivate: handleActivate,
|
|
1563
|
+
width: "100%",
|
|
1564
|
+
height: "100%"
|
|
1565
|
+
};
|
|
1566
|
+
}, [interactionMode, isActive, hasAttemptedScroll, handleActivate]);
|
|
1567
|
+
const zoomIn = react.useCallback(() => {
|
|
1568
|
+
if (!svgRef.current) return;
|
|
1569
|
+
d32__namespace.select(svgRef.current).transition().duration(300).call(zoomBehavior.scaleBy, 1.3);
|
|
1570
|
+
}, [svgRef, zoomBehavior]);
|
|
1571
|
+
const zoomOut = react.useCallback(() => {
|
|
1572
|
+
if (!svgRef.current) return;
|
|
1573
|
+
d32__namespace.select(svgRef.current).transition().duration(300).call(zoomBehavior.scaleBy, 1 / 1.3);
|
|
1574
|
+
}, [svgRef, zoomBehavior]);
|
|
1575
|
+
const resetZoom = react.useCallback(() => {
|
|
1576
|
+
if (!svgRef.current) return;
|
|
1577
|
+
d32__namespace.select(svgRef.current).transition().duration(300).call(zoomBehavior.transform, d32__namespace.zoomIdentity);
|
|
1578
|
+
}, [svgRef, zoomBehavior]);
|
|
1579
|
+
return {
|
|
1580
|
+
isActive,
|
|
1581
|
+
overlayProps,
|
|
1582
|
+
zoomBehavior,
|
|
1583
|
+
zoomIn,
|
|
1584
|
+
zoomOut,
|
|
1585
|
+
resetZoom
|
|
1586
|
+
};
|
|
1587
|
+
}
|
|
1588
|
+
function InteractionOverlay({
|
|
1589
|
+
mode,
|
|
1590
|
+
isActive,
|
|
1591
|
+
onActivate,
|
|
1592
|
+
width,
|
|
1593
|
+
height
|
|
1594
|
+
}) {
|
|
1595
|
+
if (mode === "modifier-key") {
|
|
1596
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1597
|
+
"div",
|
|
1598
|
+
{
|
|
1599
|
+
className: "glyph-interaction-overlay",
|
|
1600
|
+
style: {
|
|
1601
|
+
...OVERLAY_BASE_STYLE,
|
|
1602
|
+
width,
|
|
1603
|
+
height,
|
|
1604
|
+
pointerEvents: "none"
|
|
1605
|
+
},
|
|
1606
|
+
"aria-hidden": "true",
|
|
1607
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: TOOLTIP_STYLE, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: TOOLTIP_TEXT_STYLE, children: "Alt + scroll to zoom" }) })
|
|
1608
|
+
}
|
|
1609
|
+
);
|
|
1610
|
+
}
|
|
1611
|
+
if (mode === "click-to-activate" && !isActive) {
|
|
1612
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1613
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1614
|
+
"div",
|
|
1615
|
+
{
|
|
1616
|
+
className: "glyph-interaction-overlay",
|
|
1617
|
+
style: {
|
|
1618
|
+
...OVERLAY_BASE_STYLE,
|
|
1619
|
+
...ACTIVATION_OVERLAY_STYLE,
|
|
1620
|
+
width,
|
|
1621
|
+
height
|
|
1622
|
+
},
|
|
1623
|
+
onClick: onActivate,
|
|
1624
|
+
role: "button",
|
|
1625
|
+
tabIndex: 0,
|
|
1626
|
+
"aria-label": "Click to activate graph interaction",
|
|
1627
|
+
onKeyDown: (e) => {
|
|
1628
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1629
|
+
e.preventDefault();
|
|
1630
|
+
onActivate();
|
|
1631
|
+
}
|
|
1632
|
+
},
|
|
1633
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: ACTIVATION_TEXT_STYLE, children: "Click to interact" })
|
|
1634
|
+
}
|
|
1635
|
+
),
|
|
1636
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: SR_ONLY_STYLE, role: "status", "aria-live": "polite", "aria-atomic": "true", children: "Graph interaction inactive. Click to activate." })
|
|
1637
|
+
] });
|
|
1638
|
+
}
|
|
1639
|
+
if (mode === "click-to-activate" && isActive) {
|
|
1640
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1641
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1642
|
+
"div",
|
|
1643
|
+
{
|
|
1644
|
+
style: {
|
|
1645
|
+
...OVERLAY_BASE_STYLE,
|
|
1646
|
+
width,
|
|
1647
|
+
height,
|
|
1648
|
+
pointerEvents: "none",
|
|
1649
|
+
border: "2px solid var(--glyph-interaction-active-border, #0a9d7c)",
|
|
1650
|
+
borderRadius: "4px"
|
|
1651
|
+
},
|
|
1652
|
+
"aria-hidden": "true"
|
|
1653
|
+
}
|
|
1654
|
+
),
|
|
1655
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: SR_ONLY_STYLE, role: "status", "aria-live": "polite", "aria-atomic": "true", children: "Graph interaction active. Press Escape to deactivate." })
|
|
1656
|
+
] });
|
|
1657
|
+
}
|
|
1658
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
1659
|
+
}
|
|
1660
|
+
var OVERLAY_BASE_STYLE = {
|
|
1661
|
+
position: "absolute",
|
|
1662
|
+
top: 0,
|
|
1663
|
+
left: 0,
|
|
1664
|
+
display: "flex",
|
|
1665
|
+
alignItems: "center",
|
|
1666
|
+
justifyContent: "center",
|
|
1667
|
+
zIndex: 10
|
|
1668
|
+
};
|
|
1669
|
+
var TOOLTIP_STYLE = {
|
|
1670
|
+
position: "absolute",
|
|
1671
|
+
bottom: "12px",
|
|
1672
|
+
right: "12px",
|
|
1673
|
+
padding: "6px 10px",
|
|
1674
|
+
backgroundColor: "var(--glyph-interaction-tooltip-bg, rgba(26, 32, 53, 0.9))",
|
|
1675
|
+
color: "var(--glyph-interaction-tooltip-text, #f4f6fa)",
|
|
1676
|
+
borderRadius: "4px",
|
|
1677
|
+
fontSize: "12px",
|
|
1678
|
+
fontFamily: "Inter, system-ui, sans-serif",
|
|
1679
|
+
fontWeight: 500,
|
|
1680
|
+
boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
|
|
1681
|
+
pointerEvents: "none"
|
|
1682
|
+
};
|
|
1683
|
+
var TOOLTIP_TEXT_STYLE = {
|
|
1684
|
+
display: "flex",
|
|
1685
|
+
alignItems: "center",
|
|
1686
|
+
gap: "4px"
|
|
1687
|
+
};
|
|
1688
|
+
var ACTIVATION_OVERLAY_STYLE = {
|
|
1689
|
+
backgroundColor: "var(--glyph-interaction-overlay-bg, rgba(244, 246, 250, 0.8))",
|
|
1690
|
+
cursor: "pointer",
|
|
1691
|
+
transition: "background-color 0.2s ease"
|
|
1692
|
+
};
|
|
1693
|
+
var ACTIVATION_TEXT_STYLE = {
|
|
1694
|
+
padding: "12px 20px",
|
|
1695
|
+
backgroundColor: "var(--glyph-interaction-tooltip-bg, rgba(26, 32, 53, 0.9))",
|
|
1696
|
+
color: "var(--glyph-interaction-tooltip-text, #f4f6fa)",
|
|
1697
|
+
borderRadius: "6px",
|
|
1698
|
+
fontSize: "14px",
|
|
1699
|
+
fontFamily: "Inter, system-ui, sans-serif",
|
|
1700
|
+
fontWeight: 500,
|
|
1701
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.2)"
|
|
1702
|
+
};
|
|
1703
|
+
var SR_ONLY_STYLE = {
|
|
1704
|
+
position: "absolute",
|
|
1705
|
+
width: "1px",
|
|
1706
|
+
height: "1px",
|
|
1707
|
+
padding: 0,
|
|
1708
|
+
margin: "-1px",
|
|
1709
|
+
overflow: "hidden",
|
|
1710
|
+
clip: "rect(0, 0, 0, 0)",
|
|
1711
|
+
whiteSpace: "nowrap",
|
|
1712
|
+
border: 0
|
|
1713
|
+
};
|
|
1714
|
+
function ZoomControls({ onZoomIn, onZoomOut, onReset }) {
|
|
1715
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: CONTROLS_CONTAINER_STYLE, children: [
|
|
1716
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1717
|
+
"button",
|
|
1718
|
+
{
|
|
1719
|
+
onClick: onZoomIn,
|
|
1720
|
+
style: BUTTON_STYLE,
|
|
1721
|
+
"aria-label": "Zoom in",
|
|
1722
|
+
title: "Zoom in",
|
|
1723
|
+
type: "button",
|
|
1724
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", children: [
|
|
1725
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "8", y1: "4", x2: "8", y2: "12", strokeWidth: "2" }),
|
|
1726
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4", y1: "8", x2: "12", y2: "8", strokeWidth: "2" })
|
|
1727
|
+
] })
|
|
1728
|
+
}
|
|
1729
|
+
),
|
|
1730
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1731
|
+
"button",
|
|
1732
|
+
{
|
|
1733
|
+
onClick: onZoomOut,
|
|
1734
|
+
style: BUTTON_STYLE,
|
|
1735
|
+
"aria-label": "Zoom out",
|
|
1736
|
+
title: "Zoom out",
|
|
1737
|
+
type: "button",
|
|
1738
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4", y1: "8", x2: "12", y2: "8", strokeWidth: "2" }) })
|
|
1739
|
+
}
|
|
1740
|
+
),
|
|
1741
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1742
|
+
"button",
|
|
1743
|
+
{
|
|
1744
|
+
onClick: onReset,
|
|
1745
|
+
style: BUTTON_STYLE,
|
|
1746
|
+
"aria-label": "Reset zoom",
|
|
1747
|
+
title: "Reset zoom",
|
|
1748
|
+
type: "button",
|
|
1749
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "3", width: "10", height: "10", strokeWidth: "2", rx: "1" }) })
|
|
1750
|
+
}
|
|
1751
|
+
)
|
|
1752
|
+
] });
|
|
1753
|
+
}
|
|
1754
|
+
var CONTROLS_CONTAINER_STYLE = {
|
|
1755
|
+
position: "absolute",
|
|
1756
|
+
top: "12px",
|
|
1757
|
+
right: "12px",
|
|
1758
|
+
display: "flex",
|
|
1759
|
+
flexDirection: "column",
|
|
1760
|
+
gap: "4px",
|
|
1761
|
+
zIndex: 10
|
|
1762
|
+
};
|
|
1763
|
+
var BUTTON_STYLE = {
|
|
1764
|
+
width: "32px",
|
|
1765
|
+
height: "32px",
|
|
1766
|
+
padding: "0",
|
|
1767
|
+
display: "flex",
|
|
1768
|
+
alignItems: "center",
|
|
1769
|
+
justifyContent: "center",
|
|
1770
|
+
backgroundColor: "var(--glyph-surface-raised, #f4f6fa)",
|
|
1771
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
1772
|
+
borderRadius: "4px",
|
|
1773
|
+
color: "var(--glyph-text, #1a2035)",
|
|
1774
|
+
cursor: "pointer",
|
|
1775
|
+
transition: "all 0.2s ease",
|
|
1776
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)"
|
|
1777
|
+
};
|
|
1453
1778
|
var GROUP_PALETTE = [
|
|
1454
1779
|
"#00d4aa",
|
|
1455
1780
|
// cyan-green
|
|
@@ -1496,7 +1821,7 @@ function getThemeVar(container, varName, fallback) {
|
|
|
1496
1821
|
return getComputedStyle(container).getPropertyValue(varName).trim() || fallback;
|
|
1497
1822
|
}
|
|
1498
1823
|
var ARROW_MARKER_ID = "glyph-graph-arrowhead";
|
|
1499
|
-
function renderGraph(svgElement, layout, groupIndex, outgoingRefs, onNavigate, onNodeClick) {
|
|
1824
|
+
function renderGraph(svgElement, layout, groupIndex, outgoingRefs, onNavigate, zoomBehavior, onNodeClick) {
|
|
1500
1825
|
const svg = d32__namespace.select(svgElement);
|
|
1501
1826
|
svg.selectAll("*").remove();
|
|
1502
1827
|
const width = Math.max(layout.width, 200);
|
|
@@ -1509,9 +1834,6 @@ function renderGraph(svgElement, layout, groupIndex, outgoingRefs, onNavigate, o
|
|
|
1509
1834
|
const nodeStrokeWidth = getThemeVar(container, "--glyph-node-stroke-width", "1.5");
|
|
1510
1835
|
const nodeFillOpacity = getThemeVar(container, "--glyph-node-fill-opacity", "0.85");
|
|
1511
1836
|
const root = svg.append("g").attr("class", "glyph-graph-root");
|
|
1512
|
-
const zoomBehavior = d32__namespace.zoom().scaleExtent([0.1, 4]).on("zoom", (event) => {
|
|
1513
|
-
root.attr("transform", event.transform.toString());
|
|
1514
|
-
});
|
|
1515
1837
|
svg.call(zoomBehavior);
|
|
1516
1838
|
const navigableNodes = /* @__PURE__ */ new Set();
|
|
1517
1839
|
const refByAnchor = /* @__PURE__ */ new Map();
|
|
@@ -1568,6 +1890,7 @@ function Graph({
|
|
|
1568
1890
|
container
|
|
1569
1891
|
}) {
|
|
1570
1892
|
const svgRef = react.useRef(null);
|
|
1893
|
+
const rootRef = react.useRef(null);
|
|
1571
1894
|
const groupIndex = react.useRef(/* @__PURE__ */ new Map());
|
|
1572
1895
|
const layoutResult = react.useMemo(() => {
|
|
1573
1896
|
const direction = resolveLayout(data);
|
|
@@ -1576,6 +1899,12 @@ function Graph({
|
|
|
1576
1899
|
}
|
|
1577
1900
|
return computeDagreLayout(data.nodes, data.edges, direction);
|
|
1578
1901
|
}, [data]);
|
|
1902
|
+
const { overlayProps, zoomBehavior, zoomIn, zoomOut, resetZoom } = useZoomInteraction({
|
|
1903
|
+
svgRef,
|
|
1904
|
+
rootRef,
|
|
1905
|
+
interactionMode: data.interactionMode ?? "modifier-key",
|
|
1906
|
+
blockId: block.id
|
|
1907
|
+
});
|
|
1579
1908
|
const handleNodeClick = react.useMemo(() => {
|
|
1580
1909
|
if (!onInteraction) return void 0;
|
|
1581
1910
|
return (nodeId, nodeLabel) => {
|
|
@@ -1596,27 +1925,36 @@ function Graph({
|
|
|
1596
1925
|
groupIndex.current,
|
|
1597
1926
|
outgoingRefs,
|
|
1598
1927
|
onNavigate,
|
|
1928
|
+
zoomBehavior,
|
|
1599
1929
|
handleNodeClick
|
|
1600
1930
|
);
|
|
1601
|
-
|
|
1931
|
+
const rootElement = svgRef.current.querySelector(".glyph-graph-root");
|
|
1932
|
+
if (rootElement) {
|
|
1933
|
+
rootRef.current = rootElement;
|
|
1934
|
+
}
|
|
1935
|
+
}, [layoutResult, outgoingRefs, onNavigate, zoomBehavior, handleNodeClick]);
|
|
1602
1936
|
const ariaLabel = `${data.type} graph with ${data.nodes.length} nodes and ${data.edges.length} edges`;
|
|
1603
1937
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "glyph-graph-container", children: [
|
|
1604
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1938
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
|
|
1939
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1940
|
+
"svg",
|
|
1941
|
+
{
|
|
1942
|
+
ref: svgRef,
|
|
1943
|
+
role: "img",
|
|
1944
|
+
"aria-label": ariaLabel,
|
|
1945
|
+
width: "100%",
|
|
1946
|
+
height: "100%",
|
|
1947
|
+
style: {
|
|
1948
|
+
minHeight: container.tier === "compact" ? 200 : 300,
|
|
1949
|
+
maxHeight: container.tier === "compact" ? 500 : 700,
|
|
1950
|
+
display: "block"
|
|
1951
|
+
}
|
|
1616
1952
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1953
|
+
),
|
|
1954
|
+
overlayProps && /* @__PURE__ */ jsxRuntime.jsx(InteractionOverlay, { ...overlayProps }),
|
|
1955
|
+
/* @__PURE__ */ jsxRuntime.jsx(ZoomControls, { onZoomIn: zoomIn, onZoomOut: zoomOut, onReset: resetZoom })
|
|
1956
|
+
] }),
|
|
1957
|
+
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "sr-only", "aria-label": "Graph data", style: SR_ONLY_STYLE2, children: [
|
|
1620
1958
|
/* @__PURE__ */ jsxRuntime.jsx("caption", { children: "Graph nodes and connections" }),
|
|
1621
1959
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1622
1960
|
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", children: "Node" }),
|
|
@@ -1638,7 +1976,7 @@ function Graph({
|
|
|
1638
1976
|
] })
|
|
1639
1977
|
] });
|
|
1640
1978
|
}
|
|
1641
|
-
var
|
|
1979
|
+
var SR_ONLY_STYLE2 = {
|
|
1642
1980
|
position: "absolute",
|
|
1643
1981
|
width: "1px",
|
|
1644
1982
|
height: "1px",
|
|
@@ -1762,16 +2100,13 @@ function drawCrowsFoot(g, x, y, angle, symbol) {
|
|
|
1762
2100
|
g.append("line").attr("x1", tx - Math.cos(perpAngle) * halfLen).attr("y1", ty - Math.sin(perpAngle) * halfLen).attr("x2", tx + Math.cos(perpAngle) * halfLen).attr("y2", ty + Math.sin(perpAngle) * halfLen).attr("stroke", "var(--glyph-relation-line, #6b7a94)").attr("stroke-width", "var(--glyph-node-stroke-width, 1.5)");
|
|
1763
2101
|
}
|
|
1764
2102
|
}
|
|
1765
|
-
function renderRelation(svgElement, layout) {
|
|
2103
|
+
function renderRelation(svgElement, layout, zoomBehavior) {
|
|
1766
2104
|
const svg = d32__namespace.select(svgElement);
|
|
1767
2105
|
svg.selectAll("*").remove();
|
|
1768
2106
|
const width = Math.max(layout.width, 200);
|
|
1769
2107
|
const height = Math.max(layout.height, 200);
|
|
1770
2108
|
svg.attr("viewBox", `0 0 ${width} ${height}`);
|
|
1771
2109
|
const root = svg.append("g").attr("class", "glyph-relation-root");
|
|
1772
|
-
const zoomBehavior = d32__namespace.zoom().scaleExtent([0.1, 4]).on("zoom", (event) => {
|
|
1773
|
-
root.attr("transform", event.transform.toString());
|
|
1774
|
-
});
|
|
1775
2110
|
svg.call(zoomBehavior);
|
|
1776
2111
|
const entityMap = /* @__PURE__ */ new Map();
|
|
1777
2112
|
for (const entity of layout.entities) {
|
|
@@ -1843,29 +2178,44 @@ function renderRelation(svgElement, layout) {
|
|
|
1843
2178
|
}
|
|
1844
2179
|
}
|
|
1845
2180
|
}
|
|
1846
|
-
function Relation({ data }) {
|
|
2181
|
+
function Relation({ data, block }) {
|
|
1847
2182
|
const svgRef = react.useRef(null);
|
|
2183
|
+
const rootRef = react.useRef(null);
|
|
1848
2184
|
const layoutResult = react.useMemo(() => {
|
|
1849
2185
|
return computeRelationLayout(data);
|
|
1850
2186
|
}, [data]);
|
|
2187
|
+
const { overlayProps, zoomBehavior, zoomIn, zoomOut, resetZoom } = useZoomInteraction({
|
|
2188
|
+
svgRef,
|
|
2189
|
+
rootRef,
|
|
2190
|
+
interactionMode: data.interactionMode ?? "modifier-key",
|
|
2191
|
+
blockId: block.id
|
|
2192
|
+
});
|
|
1851
2193
|
react.useEffect(() => {
|
|
1852
2194
|
if (!svgRef.current) return;
|
|
1853
|
-
renderRelation(svgRef.current, layoutResult);
|
|
1854
|
-
|
|
2195
|
+
renderRelation(svgRef.current, layoutResult, zoomBehavior);
|
|
2196
|
+
const rootElement = svgRef.current.querySelector(".glyph-relation-root");
|
|
2197
|
+
if (rootElement) {
|
|
2198
|
+
rootRef.current = rootElement;
|
|
2199
|
+
}
|
|
2200
|
+
}, [layoutResult, zoomBehavior]);
|
|
1855
2201
|
const ariaLabel = `Entity-relationship diagram with ${data.entities.length} entities and ${data.relationships.length} relationships`;
|
|
1856
2202
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "glyph-relation-container", children: [
|
|
1857
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
2203
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
|
|
2204
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2205
|
+
"svg",
|
|
2206
|
+
{
|
|
2207
|
+
ref: svgRef,
|
|
2208
|
+
role: "img",
|
|
2209
|
+
"aria-label": ariaLabel,
|
|
2210
|
+
width: "100%",
|
|
2211
|
+
height: "100%",
|
|
2212
|
+
style: { minHeight: 300, maxHeight: 700, display: "block" }
|
|
2213
|
+
}
|
|
2214
|
+
),
|
|
2215
|
+
overlayProps && /* @__PURE__ */ jsxRuntime.jsx(InteractionOverlay, { ...overlayProps }),
|
|
2216
|
+
/* @__PURE__ */ jsxRuntime.jsx(ZoomControls, { onZoomIn: zoomIn, onZoomOut: zoomOut, onReset: resetZoom })
|
|
2217
|
+
] }),
|
|
2218
|
+
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "sr-only", "aria-label": "Entity-relationship data", style: SR_ONLY_STYLE3, children: [
|
|
1869
2219
|
/* @__PURE__ */ jsxRuntime.jsx("caption", { children: "Entities and relationships" }),
|
|
1870
2220
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
1871
2221
|
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", children: "Entity" }),
|
|
@@ -1888,7 +2238,7 @@ function Relation({ data }) {
|
|
|
1888
2238
|
] })
|
|
1889
2239
|
] });
|
|
1890
2240
|
}
|
|
1891
|
-
var
|
|
2241
|
+
var SR_ONLY_STYLE3 = {
|
|
1892
2242
|
position: "absolute",
|
|
1893
2243
|
width: "1px",
|
|
1894
2244
|
height: "1px",
|
|
@@ -1918,7 +2268,8 @@ function resolveSentiment(metric) {
|
|
|
1918
2268
|
return "neutral";
|
|
1919
2269
|
}
|
|
1920
2270
|
function buildAriaLabel(metric) {
|
|
1921
|
-
|
|
2271
|
+
const labelText = typeof metric.label === "string" ? metric.label : "Metric";
|
|
2272
|
+
let label = `${labelText}: ${metric.value}`;
|
|
1922
2273
|
if (metric.unit) label += ` ${metric.unit}`;
|
|
1923
2274
|
if (metric.delta && metric.trend) {
|
|
1924
2275
|
label += `, ${metric.trend} ${metric.delta}`;
|
|
@@ -1990,7 +2341,7 @@ function Kpi({ data, block, container }) {
|
|
|
1990
2341
|
color: `var(--glyph-kpi-${sentiment}, inherit)`
|
|
1991
2342
|
};
|
|
1992
2343
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": buildAriaLabel(metric), style: cardStyle2, children: [
|
|
1993
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: labelStyle4, children: metric.label }),
|
|
2344
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: labelStyle4, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: metric.label }) }),
|
|
1994
2345
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: valueStyle, children: [
|
|
1995
2346
|
metric.value,
|
|
1996
2347
|
metric.unit && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.875rem", fontWeight: 400, marginLeft: "0.25rem" }, children: metric.unit })
|
|
@@ -2104,7 +2455,7 @@ function Accordion({
|
|
|
2104
2455
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: { fontSize: "0.75rem", width: "1rem", flexShrink: 0 }, children: "\u25B8" }),
|
|
2105
2456
|
section.title
|
|
2106
2457
|
] }),
|
|
2107
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyle2, children: section.content })
|
|
2458
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: contentStyle2, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: section.content }) })
|
|
2108
2459
|
]
|
|
2109
2460
|
},
|
|
2110
2461
|
i
|
|
@@ -2123,6 +2474,7 @@ var accordionDefinition = {
|
|
|
2123
2474
|
var YES_VALUES = /* @__PURE__ */ new Set(["yes", "true", "full"]);
|
|
2124
2475
|
var NO_VALUES = /* @__PURE__ */ new Set(["no", "false", "none"]);
|
|
2125
2476
|
function classifyValue(value) {
|
|
2477
|
+
if (typeof value !== "string") return "text";
|
|
2126
2478
|
const lower = value.toLowerCase().trim();
|
|
2127
2479
|
if (YES_VALUES.has(lower)) return "yes";
|
|
2128
2480
|
if (NO_VALUES.has(lower)) return "no";
|
|
@@ -2160,7 +2512,7 @@ function renderValue(value) {
|
|
|
2160
2512
|
}
|
|
2161
2513
|
);
|
|
2162
2514
|
default:
|
|
2163
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { children: value });
|
|
2515
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: value }) });
|
|
2164
2516
|
}
|
|
2165
2517
|
}
|
|
2166
2518
|
function Comparison({
|
|
@@ -2256,7 +2608,7 @@ function Comparison({
|
|
|
2256
2608
|
fontSize: "0.75rem",
|
|
2257
2609
|
color: "var(--glyph-text-muted, #6b7a94)"
|
|
2258
2610
|
},
|
|
2259
|
-
children: option.description
|
|
2611
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: option.description })
|
|
2260
2612
|
}
|
|
2261
2613
|
)
|
|
2262
2614
|
]
|
|
@@ -2277,8 +2629,8 @@ function Comparison({
|
|
|
2277
2629
|
}
|
|
2278
2630
|
),
|
|
2279
2631
|
options.map((_, colIndex) => {
|
|
2280
|
-
const value = feature.values[colIndex]
|
|
2281
|
-
return /* @__PURE__ */ jsxRuntime.jsx("td", { style: cellStyle2(rowIndex), children: value ? renderValue(value) : null }, colIndex);
|
|
2632
|
+
const value = feature.values[colIndex];
|
|
2633
|
+
return /* @__PURE__ */ jsxRuntime.jsx("td", { style: cellStyle2(rowIndex), children: value !== void 0 && value !== "" ? renderValue(value) : null }, colIndex);
|
|
2282
2634
|
})
|
|
2283
2635
|
] }, rowIndex)) })
|
|
2284
2636
|
] }) })
|
|
@@ -2522,7 +2874,7 @@ function renderNodeShape(nodeG, node, fillOpacity, strokeWidth) {
|
|
|
2522
2874
|
}
|
|
2523
2875
|
}
|
|
2524
2876
|
}
|
|
2525
|
-
function renderFlowchart(svgElement, layout) {
|
|
2877
|
+
function renderFlowchart(svgElement, layout, zoomBehavior) {
|
|
2526
2878
|
const svg = d32__namespace.select(svgElement);
|
|
2527
2879
|
svg.selectAll("*").remove();
|
|
2528
2880
|
const width = Math.max(layout.width, 200);
|
|
@@ -2534,9 +2886,6 @@ function renderFlowchart(svgElement, layout) {
|
|
|
2534
2886
|
const nodeStrokeWidth = getThemeVar2(container, "--glyph-node-stroke-width", "1.5");
|
|
2535
2887
|
const nodeFillOpacity = getThemeVar2(container, "--glyph-node-fill-opacity", "0.85");
|
|
2536
2888
|
const root = svg.append("g").attr("class", "glyph-flowchart-root");
|
|
2537
|
-
const zoomBehavior = d32__namespace.zoom().scaleExtent([0.1, 4]).on("zoom", (event) => {
|
|
2538
|
-
root.attr("transform", event.transform.toString());
|
|
2539
|
-
});
|
|
2540
2889
|
svg.call(zoomBehavior);
|
|
2541
2890
|
const lineGen = d32__namespace.line().x((d) => d.x).y((d) => d.y).curve(d32__namespace.curveBasis);
|
|
2542
2891
|
const edgeGroup = root.append("g").attr("class", "glyph-flowchart-edges");
|
|
@@ -2557,13 +2906,28 @@ function renderFlowchart(svgElement, layout) {
|
|
|
2557
2906
|
nodeG.append("text").attr("x", node.x).attr("y", node.y).attr("dy", "0.35em").attr("text-anchor", "middle").attr("font-size", "13px").attr("font-family", "Inter, system-ui, sans-serif").attr("fill", "var(--glyph-node-label-color, #fff)").attr("pointer-events", "none").text(node.label);
|
|
2558
2907
|
}
|
|
2559
2908
|
}
|
|
2560
|
-
function Flowchart({
|
|
2909
|
+
function Flowchart({
|
|
2910
|
+
data,
|
|
2911
|
+
block,
|
|
2912
|
+
container
|
|
2913
|
+
}) {
|
|
2561
2914
|
const svgRef = react.useRef(null);
|
|
2915
|
+
const rootRef = react.useRef(null);
|
|
2562
2916
|
const layoutResult = react.useMemo(() => computeLayout(data.nodes, data.edges, data.direction), [data]);
|
|
2917
|
+
const { overlayProps, zoomBehavior, zoomIn, zoomOut, resetZoom } = useZoomInteraction({
|
|
2918
|
+
svgRef,
|
|
2919
|
+
rootRef,
|
|
2920
|
+
interactionMode: data.interactionMode ?? "modifier-key",
|
|
2921
|
+
blockId: block.id
|
|
2922
|
+
});
|
|
2563
2923
|
react.useEffect(() => {
|
|
2564
2924
|
if (!svgRef.current) return;
|
|
2565
|
-
renderFlowchart(svgRef.current, layoutResult);
|
|
2566
|
-
|
|
2925
|
+
renderFlowchart(svgRef.current, layoutResult, zoomBehavior);
|
|
2926
|
+
const rootElement = svgRef.current.querySelector(".glyph-flowchart-root");
|
|
2927
|
+
if (rootElement) {
|
|
2928
|
+
rootRef.current = rootElement;
|
|
2929
|
+
}
|
|
2930
|
+
}, [layoutResult, zoomBehavior]);
|
|
2567
2931
|
const nodeCount = data.nodes.length;
|
|
2568
2932
|
const edgeCount = data.edges.length;
|
|
2569
2933
|
const ariaLabel = data.title ? `${data.title}: flowchart with ${nodeCount} nodes and ${edgeCount} edges` : `Flowchart with ${nodeCount} nodes and ${edgeCount} edges`;
|
|
@@ -2581,22 +2945,26 @@ function Flowchart({ data, container }) {
|
|
|
2581
2945
|
children: data.title
|
|
2582
2946
|
}
|
|
2583
2947
|
),
|
|
2584
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2948
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
|
|
2949
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2950
|
+
"svg",
|
|
2951
|
+
{
|
|
2952
|
+
ref: svgRef,
|
|
2953
|
+
role: "img",
|
|
2954
|
+
"aria-label": ariaLabel,
|
|
2955
|
+
width: "100%",
|
|
2956
|
+
height: "100%",
|
|
2957
|
+
style: {
|
|
2958
|
+
minHeight: container.tier === "compact" ? 200 : 300,
|
|
2959
|
+
maxHeight: container.tier === "compact" ? 500 : 700,
|
|
2960
|
+
display: "block"
|
|
2961
|
+
}
|
|
2596
2962
|
}
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2963
|
+
),
|
|
2964
|
+
overlayProps && /* @__PURE__ */ jsxRuntime.jsx(InteractionOverlay, { ...overlayProps }),
|
|
2965
|
+
/* @__PURE__ */ jsxRuntime.jsx(ZoomControls, { onZoomIn: zoomIn, onZoomOut: zoomOut, onReset: resetZoom })
|
|
2966
|
+
] }),
|
|
2967
|
+
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "sr-only", "aria-label": "Flowchart data", style: SR_ONLY_STYLE4, children: [
|
|
2600
2968
|
/* @__PURE__ */ jsxRuntime.jsx("caption", { children: "Flowchart nodes and connections" }),
|
|
2601
2969
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2602
2970
|
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", children: "Node" }),
|
|
@@ -2618,7 +2986,7 @@ function Flowchart({ data, container }) {
|
|
|
2618
2986
|
] })
|
|
2619
2987
|
] });
|
|
2620
2988
|
}
|
|
2621
|
-
var
|
|
2989
|
+
var SR_ONLY_STYLE4 = {
|
|
2622
2990
|
position: "absolute",
|
|
2623
2991
|
width: "1px",
|
|
2624
2992
|
height: "1px",
|
|
@@ -3240,7 +3608,7 @@ function Sequence({ data, container }) {
|
|
|
3240
3608
|
]
|
|
3241
3609
|
}
|
|
3242
3610
|
),
|
|
3243
|
-
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "sr-only", "aria-label": "Sequence data", style:
|
|
3611
|
+
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "sr-only", "aria-label": "Sequence data", style: SR_ONLY_STYLE5, children: [
|
|
3244
3612
|
/* @__PURE__ */ jsxRuntime.jsx("caption", { children: "Sequence messages in order" }),
|
|
3245
3613
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
3246
3614
|
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", children: "#" }),
|
|
@@ -3263,7 +3631,7 @@ function Sequence({ data, container }) {
|
|
|
3263
3631
|
] })
|
|
3264
3632
|
] });
|
|
3265
3633
|
}
|
|
3266
|
-
var
|
|
3634
|
+
var SR_ONLY_STYLE5 = {
|
|
3267
3635
|
position: "absolute",
|
|
3268
3636
|
width: "1px",
|
|
3269
3637
|
height: "1px",
|
|
@@ -3669,7 +4037,7 @@ function Architecture({
|
|
|
3669
4037
|
}
|
|
3670
4038
|
}
|
|
3671
4039
|
),
|
|
3672
|
-
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "sr-only", "aria-label": "Architecture data", style:
|
|
4040
|
+
/* @__PURE__ */ jsxRuntime.jsxs("table", { className: "sr-only", "aria-label": "Architecture data", style: SR_ONLY_STYLE6, children: [
|
|
3673
4041
|
/* @__PURE__ */ jsxRuntime.jsx("caption", { children: "Architecture nodes and connections" }),
|
|
3674
4042
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
3675
4043
|
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", children: "Node" }),
|
|
@@ -3713,7 +4081,7 @@ function countLeafNodes(children) {
|
|
|
3713
4081
|
}
|
|
3714
4082
|
return count;
|
|
3715
4083
|
}
|
|
3716
|
-
var
|
|
4084
|
+
var SR_ONLY_STYLE6 = {
|
|
3717
4085
|
position: "absolute",
|
|
3718
4086
|
width: "1px",
|
|
3719
4087
|
height: "1px",
|
|
@@ -3901,7 +4269,7 @@ function layoutTree(data) {
|
|
|
3901
4269
|
};
|
|
3902
4270
|
}
|
|
3903
4271
|
function renderAccessibleList(root, children) {
|
|
3904
|
-
return /* @__PURE__ */ jsxRuntime.jsx("ul", { style:
|
|
4272
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { style: SR_ONLY_STYLE7, role: "list", "aria-label": "Mind map structure", children: /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
3905
4273
|
root,
|
|
3906
4274
|
children.length > 0 && renderAccessibleChildren(children)
|
|
3907
4275
|
] }) });
|
|
@@ -4028,7 +4396,7 @@ function MindMap({ data, container }) {
|
|
|
4028
4396
|
renderAccessibleList(data.root, data.children)
|
|
4029
4397
|
] });
|
|
4030
4398
|
}
|
|
4031
|
-
var
|
|
4399
|
+
var SR_ONLY_STYLE7 = {
|
|
4032
4400
|
position: "absolute",
|
|
4033
4401
|
width: "1px",
|
|
4034
4402
|
height: "1px",
|
|
@@ -4229,7 +4597,8 @@ function isCorrect(question, selected) {
|
|
|
4229
4597
|
}
|
|
4230
4598
|
function renderMultipleChoice(question, qIndex, state, updateState, baseId) {
|
|
4231
4599
|
const selected = typeof state.selected === "number" ? state.selected : null;
|
|
4232
|
-
|
|
4600
|
+
const ariaLabel = typeof question.question === "string" ? question.question : "Question";
|
|
4601
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", "aria-label": ariaLabel, children: question.options.map((option, oIndex) => {
|
|
4233
4602
|
const isSelected = selected === oIndex;
|
|
4234
4603
|
const isCorrectOption = state.submitted && oIndex === question.answer;
|
|
4235
4604
|
const isIncorrectSelection = state.submitted && isSelected && oIndex !== question.answer;
|
|
@@ -4255,7 +4624,7 @@ function renderMultipleChoice(question, qIndex, state, updateState, baseId) {
|
|
|
4255
4624
|
"aria-checked": isSelected
|
|
4256
4625
|
}
|
|
4257
4626
|
),
|
|
4258
|
-
option
|
|
4627
|
+
/* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: option })
|
|
4259
4628
|
]
|
|
4260
4629
|
},
|
|
4261
4630
|
oIndex
|
|
@@ -4264,7 +4633,8 @@ function renderMultipleChoice(question, qIndex, state, updateState, baseId) {
|
|
|
4264
4633
|
}
|
|
4265
4634
|
function renderTrueFalse(question, qIndex, state, updateState, baseId) {
|
|
4266
4635
|
const selected = typeof state.selected === "boolean" ? state.selected : null;
|
|
4267
|
-
|
|
4636
|
+
const ariaLabel = typeof question.question === "string" ? question.question : "Question";
|
|
4637
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", "aria-label": ariaLabel, children: [true, false].map((value) => {
|
|
4268
4638
|
const isSelected = selected === value;
|
|
4269
4639
|
const isCorrectOption = state.submitted && value === question.answer;
|
|
4270
4640
|
const isIncorrectSelection = state.submitted && isSelected && value !== question.answer;
|
|
@@ -4328,7 +4698,7 @@ function renderMultiSelect(question, qIndex, state, updateState) {
|
|
|
4328
4698
|
"aria-checked": isSelected
|
|
4329
4699
|
}
|
|
4330
4700
|
),
|
|
4331
|
-
option
|
|
4701
|
+
/* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: option })
|
|
4332
4702
|
]
|
|
4333
4703
|
},
|
|
4334
4704
|
oIndex
|
|
@@ -4367,7 +4737,7 @@ function Quiz({ data, block, onInteraction }) {
|
|
|
4367
4737
|
children: [
|
|
4368
4738
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: questionTextStyle, children: [
|
|
4369
4739
|
questions.length > 1 ? `${String(qIndex + 1)}. ` : "",
|
|
4370
|
-
question.question
|
|
4740
|
+
/* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: question.question })
|
|
4371
4741
|
] }),
|
|
4372
4742
|
question.type === "multiple-choice" && renderMultipleChoice(question, qIndex, state, updateState, baseId),
|
|
4373
4743
|
question.type === "true-false" && renderTrueFalse(question, qIndex, state, updateState, baseId),
|
|
@@ -4391,15 +4761,24 @@ function Quiz({ data, block, onInteraction }) {
|
|
|
4391
4761
|
let selected;
|
|
4392
4762
|
switch (question.type) {
|
|
4393
4763
|
case "multiple-choice":
|
|
4394
|
-
|
|
4764
|
+
if (typeof state.selected === "number") {
|
|
4765
|
+
const opt = question.options[state.selected];
|
|
4766
|
+
selected = [typeof opt === "string" ? opt : String(state.selected)];
|
|
4767
|
+
} else {
|
|
4768
|
+
selected = [];
|
|
4769
|
+
}
|
|
4395
4770
|
break;
|
|
4396
4771
|
case "true-false":
|
|
4397
4772
|
selected = typeof state.selected === "boolean" ? [state.selected ? "True" : "False"] : [];
|
|
4398
4773
|
break;
|
|
4399
4774
|
case "multi-select":
|
|
4400
|
-
selected = Array.isArray(state.selected) ? state.selected.map((idx) =>
|
|
4775
|
+
selected = Array.isArray(state.selected) ? state.selected.map((idx) => {
|
|
4776
|
+
const opt = question.options[idx];
|
|
4777
|
+
return typeof opt === "string" ? opt : String(idx);
|
|
4778
|
+
}) : [];
|
|
4401
4779
|
break;
|
|
4402
4780
|
}
|
|
4781
|
+
const questionText = typeof question.question === "string" ? question.question : "Question";
|
|
4403
4782
|
onInteraction({
|
|
4404
4783
|
kind: "quiz-submit",
|
|
4405
4784
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -4407,7 +4786,7 @@ function Quiz({ data, block, onInteraction }) {
|
|
|
4407
4786
|
blockType: block.type,
|
|
4408
4787
|
payload: {
|
|
4409
4788
|
questionIndex: qIndex,
|
|
4410
|
-
question:
|
|
4789
|
+
question: questionText,
|
|
4411
4790
|
selected,
|
|
4412
4791
|
correct: correct2,
|
|
4413
4792
|
score: { correct: newScore, total: questions.length }
|
|
@@ -4420,7 +4799,7 @@ function Quiz({ data, block, onInteraction }) {
|
|
|
4420
4799
|
),
|
|
4421
4800
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-live": "polite", children: [
|
|
4422
4801
|
state.submitted && /* @__PURE__ */ jsxRuntime.jsx("div", { style: feedbackStyle(correct), children: correct ? "Correct!" : "Incorrect" }),
|
|
4423
|
-
state.submitted && question.explanation && /* @__PURE__ */ jsxRuntime.jsx("div", { style: explanationStyle, children: question.explanation })
|
|
4802
|
+
state.submitted && question.explanation && /* @__PURE__ */ jsxRuntime.jsx("div", { style: explanationStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: question.explanation }) })
|
|
4424
4803
|
] })
|
|
4425
4804
|
]
|
|
4426
4805
|
},
|
|
@@ -4558,8 +4937,8 @@ function Card({ data, block, container }) {
|
|
|
4558
4937
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: cardBodyStyle, children: [
|
|
4559
4938
|
card.icon && /* @__PURE__ */ jsxRuntime.jsx("div", { style: iconStyle, children: card.icon }),
|
|
4560
4939
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { style: titleStyle2, children: card.title }),
|
|
4561
|
-
card.subtitle && /* @__PURE__ */ jsxRuntime.jsx("div", { style: subtitleStyle, children: card.subtitle }),
|
|
4562
|
-
card.body && /* @__PURE__ */ jsxRuntime.jsx("div", { style: bodyStyle3, children: card.body }),
|
|
4940
|
+
card.subtitle && /* @__PURE__ */ jsxRuntime.jsx("div", { style: subtitleStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: card.subtitle }) }),
|
|
4941
|
+
card.body && /* @__PURE__ */ jsxRuntime.jsx("div", { style: bodyStyle3, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: card.body }) }),
|
|
4563
4942
|
card.actions && card.actions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: actionsStyle, children: card.actions.map((action, j) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
4564
4943
|
"a",
|
|
4565
4944
|
{
|
|
@@ -4666,7 +5045,7 @@ function renderStatGroup(items, keyPrefix) {
|
|
|
4666
5045
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: rowStyle, "data-group": "stat", children: items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: statStyle, children: [
|
|
4667
5046
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: valueStyle, children: item.value }),
|
|
4668
5047
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: labelStyle4, children: item.label }),
|
|
4669
|
-
item.description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: descStyle, children: item.description })
|
|
5048
|
+
item.description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: descStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: item.description }) })
|
|
4670
5049
|
] }, `${keyPrefix}-${String(i)}`)) }, keyPrefix);
|
|
4671
5050
|
}
|
|
4672
5051
|
function renderProgressGroup(items, keyPrefix, colorOffset) {
|
|
@@ -4759,7 +5138,7 @@ function renderFactGroup(items, keyPrefix) {
|
|
|
4759
5138
|
children: item.icon
|
|
4760
5139
|
}
|
|
4761
5140
|
),
|
|
4762
|
-
item.text
|
|
5141
|
+
/* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: item.text })
|
|
4763
5142
|
] }, `${keyPrefix}-${String(i)}`)) }, keyPrefix);
|
|
4764
5143
|
}
|
|
4765
5144
|
function renderTextGroup(items, keyPrefix) {
|
|
@@ -5241,17 +5620,21 @@ function Poll({ data, block, onInteraction }) {
|
|
|
5241
5620
|
blockId: block.id,
|
|
5242
5621
|
blockType: block.type,
|
|
5243
5622
|
payload: {
|
|
5244
|
-
selectedOptions: selected.map((i) =>
|
|
5623
|
+
selectedOptions: selected.map((i) => {
|
|
5624
|
+
const opt = options[i];
|
|
5625
|
+
return typeof opt === "string" ? opt : String(i);
|
|
5626
|
+
}),
|
|
5245
5627
|
selectedIndices: [...selected]
|
|
5246
5628
|
}
|
|
5247
5629
|
});
|
|
5248
5630
|
}
|
|
5249
5631
|
};
|
|
5250
5632
|
const totalVotes = votes.reduce((a, b) => a + b, 0);
|
|
5633
|
+
const questionAriaLabel = typeof question === "string" ? question : "Poll question";
|
|
5251
5634
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Poll", style: containerStyle3, children: [
|
|
5252
5635
|
title && /* @__PURE__ */ jsxRuntime.jsx("div", { style: headerStyle2, children: title }),
|
|
5253
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: questionStyle, children: question }),
|
|
5254
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "group", "aria-label":
|
|
5636
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: questionStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: question }) }),
|
|
5637
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "group", "aria-label": questionAriaLabel, style: optionsStyle, children: options.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs("label", { style: optionLabelStyle2(selected.includes(index)), children: [
|
|
5255
5638
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5256
5639
|
"input",
|
|
5257
5640
|
{
|
|
@@ -5263,7 +5646,7 @@ function Poll({ data, block, onInteraction }) {
|
|
|
5263
5646
|
"aria-checked": selected.includes(index)
|
|
5264
5647
|
}
|
|
5265
5648
|
),
|
|
5266
|
-
option
|
|
5649
|
+
/* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: option })
|
|
5267
5650
|
] }, index)) }),
|
|
5268
5651
|
!hasVoted && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5269
5652
|
"button",
|
|
@@ -5282,9 +5665,10 @@ function Poll({ data, block, onInteraction }) {
|
|
|
5282
5665
|
showResults && hasVoted && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "status", "aria-live": "polite", style: resultsStyle, children: options.map((option, index) => {
|
|
5283
5666
|
const count = votes[index] ?? 0;
|
|
5284
5667
|
const percentage = totalVotes > 0 ? count / totalVotes * 100 : 0;
|
|
5668
|
+
const optionLabel = typeof option === "string" ? option : "Option";
|
|
5285
5669
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: resultRowStyle, children: [
|
|
5286
5670
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: resultLabelStyle, children: [
|
|
5287
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: option }),
|
|
5671
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: option }) }),
|
|
5288
5672
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5289
5673
|
String(count),
|
|
5290
5674
|
" vote",
|
|
@@ -5302,7 +5686,7 @@ function Poll({ data, block, onInteraction }) {
|
|
|
5302
5686
|
"aria-valuenow": percentage,
|
|
5303
5687
|
"aria-valuemin": 0,
|
|
5304
5688
|
"aria-valuemax": 100,
|
|
5305
|
-
"aria-label": `${
|
|
5689
|
+
"aria-label": `${optionLabel}: ${String(Math.round(percentage))}%`,
|
|
5306
5690
|
children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: barFillStyle(percentage) })
|
|
5307
5691
|
}
|
|
5308
5692
|
)
|
|
@@ -5404,6 +5788,8 @@ function Rating({
|
|
|
5404
5788
|
newRatings[itemIndex] = value;
|
|
5405
5789
|
setRatings(newRatings);
|
|
5406
5790
|
if (onInteraction) {
|
|
5791
|
+
const item = items[itemIndex];
|
|
5792
|
+
const itemLabel = item ? typeof item.label === "string" ? item.label : "Item" : "";
|
|
5407
5793
|
onInteraction({
|
|
5408
5794
|
kind: "rating-change",
|
|
5409
5795
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -5411,10 +5797,10 @@ function Rating({
|
|
|
5411
5797
|
blockType: block.type,
|
|
5412
5798
|
payload: {
|
|
5413
5799
|
itemIndex,
|
|
5414
|
-
itemLabel
|
|
5800
|
+
itemLabel,
|
|
5415
5801
|
value,
|
|
5416
|
-
allRatings: items.map((
|
|
5417
|
-
label:
|
|
5802
|
+
allRatings: items.map((item2, i) => ({
|
|
5803
|
+
label: typeof item2.label === "string" ? item2.label : "Item",
|
|
5418
5804
|
value: i === itemIndex ? value : newRatings[i] ?? null
|
|
5419
5805
|
}))
|
|
5420
5806
|
}
|
|
@@ -5426,10 +5812,11 @@ function Rating({
|
|
|
5426
5812
|
items.map((item, itemIndex) => {
|
|
5427
5813
|
const currentRating = ratings[itemIndex] ?? null;
|
|
5428
5814
|
const isLast = itemIndex === items.length - 1;
|
|
5815
|
+
const itemLabelText = typeof item.label === "string" ? item.label : "Item";
|
|
5429
5816
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: itemStyle2(isLast), children: [
|
|
5430
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: itemLabelStyle, children: item.label }),
|
|
5431
|
-
item.description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: itemDescriptionStyle, children: item.description }),
|
|
5432
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", "aria-label": `Rate ${
|
|
5817
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: itemLabelStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: item.label }) }),
|
|
5818
|
+
item.description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: itemDescriptionStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: item.description }) }),
|
|
5819
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", "aria-label": `Rate ${itemLabelText}`, style: starsContainerStyle, children: Array.from({ length: scale }, (_, starIndex) => {
|
|
5433
5820
|
const value = starIndex + 1;
|
|
5434
5821
|
const isHovered = hoveredStar !== null && hoveredStar.itemIndex === itemIndex && value <= hoveredStar.value;
|
|
5435
5822
|
const isFilled = currentRating !== null && value <= currentRating;
|
|
@@ -5483,7 +5870,7 @@ function Rating({
|
|
|
5483
5870
|
whiteSpace: "nowrap",
|
|
5484
5871
|
border: 0
|
|
5485
5872
|
},
|
|
5486
|
-
children: currentRating !== null && `${
|
|
5873
|
+
children: currentRating !== null && `${itemLabelText} rated ${String(currentRating)} out of ${String(scale)}`
|
|
5487
5874
|
}
|
|
5488
5875
|
)
|
|
5489
5876
|
] }, itemIndex);
|
|
@@ -5590,12 +5977,12 @@ function Ranker({
|
|
|
5590
5977
|
payload: {
|
|
5591
5978
|
orderedItems: newItems.map((item, i) => ({
|
|
5592
5979
|
id: item.id,
|
|
5593
|
-
label: item.label,
|
|
5980
|
+
label: typeof item.label === "string" ? item.label : "Item",
|
|
5594
5981
|
rank: i + 1
|
|
5595
5982
|
})),
|
|
5596
5983
|
movedItem: {
|
|
5597
5984
|
id: moved.id,
|
|
5598
|
-
label: moved.label,
|
|
5985
|
+
label: typeof moved.label === "string" ? moved.label : "Item",
|
|
5599
5986
|
fromRank: fromIndex + 1,
|
|
5600
5987
|
toRank: toIndex + 1
|
|
5601
5988
|
}
|
|
@@ -5633,26 +6020,29 @@ function Ranker({
|
|
|
5633
6020
|
};
|
|
5634
6021
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Ranker", style: containerStyle5, children: [
|
|
5635
6022
|
title && /* @__PURE__ */ jsxRuntime.jsx("div", { style: headerStyle4, children: title }),
|
|
5636
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { role: "list", "aria-label": title ?? "Rank items", style: listStyle, children: items.map((item, index) =>
|
|
5637
|
-
"
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
6023
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { role: "list", "aria-label": title ?? "Rank items", style: listStyle, children: items.map((item, index) => {
|
|
6024
|
+
const itemLabelText = typeof item.label === "string" ? item.label : "Item";
|
|
6025
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6026
|
+
"li",
|
|
6027
|
+
{
|
|
6028
|
+
role: "listitem",
|
|
6029
|
+
"aria-grabbed": grabbedIndex === index,
|
|
6030
|
+
"aria-label": `${itemLabelText}, rank ${String(index + 1)}`,
|
|
6031
|
+
tabIndex: 0,
|
|
6032
|
+
style: itemStyle3(false, grabbedIndex === index),
|
|
6033
|
+
onKeyDown: (e) => handleKeyDown(e, index),
|
|
6034
|
+
children: [
|
|
6035
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: gripStyle, "aria-hidden": "true", children: "\u283F" }),
|
|
6036
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: rankBadgeStyle, children: String(index + 1) }),
|
|
6037
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: itemContentStyle, children: [
|
|
6038
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: itemLabelStyle2, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: item.label }) }),
|
|
6039
|
+
item.description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: itemDescriptionStyle2, children: item.description })
|
|
6040
|
+
] })
|
|
6041
|
+
]
|
|
6042
|
+
},
|
|
6043
|
+
item.id
|
|
6044
|
+
);
|
|
6045
|
+
}) }),
|
|
5656
6046
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5657
6047
|
"div",
|
|
5658
6048
|
{
|
|
@@ -5668,7 +6058,7 @@ function Ranker({
|
|
|
5668
6058
|
whiteSpace: "nowrap",
|
|
5669
6059
|
border: 0
|
|
5670
6060
|
},
|
|
5671
|
-
children: grabbedIndex !== null && `${items[grabbedIndex]
|
|
6061
|
+
children: grabbedIndex !== null && items[grabbedIndex] !== void 0 ? `${typeof items[grabbedIndex].label === "string" ? items[grabbedIndex].label : "Item"} grabbed, rank ${String(grabbedIndex + 1)} of ${String(items.length)}. Use arrow keys to move.` : ""
|
|
5672
6062
|
}
|
|
5673
6063
|
)
|
|
5674
6064
|
] });
|
|
@@ -5754,11 +6144,11 @@ function Slider({
|
|
|
5754
6144
|
blockType: block.type,
|
|
5755
6145
|
payload: {
|
|
5756
6146
|
parameterId: param.id,
|
|
5757
|
-
parameterLabel: param.label,
|
|
6147
|
+
parameterLabel: typeof param.label === "string" ? param.label : "Parameter",
|
|
5758
6148
|
value: newValue,
|
|
5759
6149
|
allValues: parameters.map((p, i) => ({
|
|
5760
6150
|
id: p.id,
|
|
5761
|
-
label: p.label,
|
|
6151
|
+
label: typeof p.label === "string" ? p.label : "Parameter",
|
|
5762
6152
|
value: i === paramIndex ? newValue : newValues[i] ?? 0
|
|
5763
6153
|
}))
|
|
5764
6154
|
}
|
|
@@ -5778,7 +6168,7 @@ function Slider({
|
|
|
5778
6168
|
const isLast = index === parameters.length - 1;
|
|
5779
6169
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: parameterStyle(isLast), children: [
|
|
5780
6170
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: parameterHeaderStyle, children: [
|
|
5781
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `${baseId}-${param.id}`, style: parameterLabelStyle, children: param.label }),
|
|
6171
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `${baseId}-${param.id}`, style: parameterLabelStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: param.label }) }),
|
|
5782
6172
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: parameterValueStyle, "aria-live": "polite", children: formatValue(currentValue, param.unit) })
|
|
5783
6173
|
] }),
|
|
5784
6174
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5891,7 +6281,8 @@ function computeWeightedTotals(rows, columns, values) {
|
|
|
5891
6281
|
const weight = col.weight ?? 1;
|
|
5892
6282
|
total += score * weight;
|
|
5893
6283
|
}
|
|
5894
|
-
|
|
6284
|
+
const rowLabel = typeof row.label === "string" ? row.label : "Row";
|
|
6285
|
+
return { rowId: row.id, rowLabel, total: Math.round(total * 100) / 100 };
|
|
5895
6286
|
});
|
|
5896
6287
|
}
|
|
5897
6288
|
function Matrix({
|
|
@@ -5934,9 +6325,9 @@ function Matrix({
|
|
|
5934
6325
|
blockType: block.type,
|
|
5935
6326
|
payload: {
|
|
5936
6327
|
rowId,
|
|
5937
|
-
rowLabel: row.label,
|
|
6328
|
+
rowLabel: typeof row.label === "string" ? row.label : "Row",
|
|
5938
6329
|
columnId,
|
|
5939
|
-
columnLabel: col.label,
|
|
6330
|
+
columnLabel: typeof col.label === "string" ? col.label : "Column",
|
|
5940
6331
|
value: clamped,
|
|
5941
6332
|
allValues: payloadValues,
|
|
5942
6333
|
weightedTotals: computeWeightedTotals(rows, columns, newValues)
|
|
@@ -5955,7 +6346,7 @@ function Matrix({
|
|
|
5955
6346
|
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
5956
6347
|
/* @__PURE__ */ jsxRuntime.jsx("th", { style: thStyle }),
|
|
5957
6348
|
columns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs("th", { style: thStyle, children: [
|
|
5958
|
-
col.label,
|
|
6349
|
+
/* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: col.label }),
|
|
5959
6350
|
(col.weight ?? 1) !== 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: weightStyle, children: [
|
|
5960
6351
|
"\xD7",
|
|
5961
6352
|
String(col.weight)
|
|
@@ -5965,10 +6356,12 @@ function Matrix({
|
|
|
5965
6356
|
] }) }),
|
|
5966
6357
|
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row) => {
|
|
5967
6358
|
const rowTotal = totals.find((t) => t.rowId === row.id)?.total ?? 0;
|
|
6359
|
+
const rowLabelText = typeof row.label === "string" ? row.label : "Row";
|
|
5968
6360
|
return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
5969
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "row", style: rowHeaderStyle, children: row.label }),
|
|
6361
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "row", style: rowHeaderStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: row.label }) }),
|
|
5970
6362
|
columns.map((col) => {
|
|
5971
6363
|
const cellValue = values[row.id]?.[col.id] ?? 0;
|
|
6364
|
+
const colLabelText = typeof col.label === "string" ? col.label : "Column";
|
|
5972
6365
|
return /* @__PURE__ */ jsxRuntime.jsx("td", { style: cellStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5973
6366
|
"input",
|
|
5974
6367
|
{
|
|
@@ -5977,7 +6370,7 @@ function Matrix({
|
|
|
5977
6370
|
max: scale,
|
|
5978
6371
|
value: cellValue,
|
|
5979
6372
|
onChange: (e) => handleChange(row.id, col.id, Number(e.target.value)),
|
|
5980
|
-
"aria-label": `Score for ${
|
|
6373
|
+
"aria-label": `Score for ${rowLabelText} on ${colLabelText}`,
|
|
5981
6374
|
style: inputStyle
|
|
5982
6375
|
}
|
|
5983
6376
|
) }, col.id);
|
|
@@ -6271,7 +6664,7 @@ function Form({ data, block, onInteraction }) {
|
|
|
6271
6664
|
};
|
|
6272
6665
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Form", style: containerStyle8, children: [
|
|
6273
6666
|
title && /* @__PURE__ */ jsxRuntime.jsx("div", { style: headerStyle7, children: title }),
|
|
6274
|
-
description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: descriptionStyle, children: description }),
|
|
6667
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: descriptionStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: description }) }),
|
|
6275
6668
|
/* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, style: formStyle, noValidate: true, children: [
|
|
6276
6669
|
fields.map(
|
|
6277
6670
|
(field) => renderField({ field, baseId, values, validation, submitted, updateValue })
|
|
@@ -6658,6 +7051,9 @@ var annotationNoteStyle = {
|
|
|
6658
7051
|
marginTop: "0.125rem"
|
|
6659
7052
|
};
|
|
6660
7053
|
function computeSegments(text, annotations) {
|
|
7054
|
+
if (typeof text !== "string") {
|
|
7055
|
+
return [{ text: "", start: 0, annotation: null }];
|
|
7056
|
+
}
|
|
6661
7057
|
if (annotations.length === 0) {
|
|
6662
7058
|
return [{ text, start: 0, annotation: null }];
|
|
6663
7059
|
}
|
|
@@ -6737,7 +7133,7 @@ function Annotate({
|
|
|
6737
7133
|
allAnnotations: newAnnotations.map((a) => ({
|
|
6738
7134
|
start: a.start,
|
|
6739
7135
|
end: a.end,
|
|
6740
|
-
text: text.slice(a.start, a.end),
|
|
7136
|
+
text: typeof text === "string" ? text.slice(a.start, a.end) : "",
|
|
6741
7137
|
label: a.label
|
|
6742
7138
|
}))
|
|
6743
7139
|
}
|
|
@@ -6763,7 +7159,7 @@ function Annotate({
|
|
|
6763
7159
|
title && /* @__PURE__ */ jsxRuntime.jsx("div", { style: headerStyle9, children: title }),
|
|
6764
7160
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: bodyStyle2, children: [
|
|
6765
7161
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: textRef, role: "document", style: textPaneStyle, onMouseUp: handleMouseUp, children: [
|
|
6766
|
-
segments.map((seg, i) => {
|
|
7162
|
+
typeof text === "string" ? segments.map((seg, i) => {
|
|
6767
7163
|
if (seg.annotation) {
|
|
6768
7164
|
const color3 = labelColorMap.get(seg.annotation.label) ?? "#888";
|
|
6769
7165
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6781,7 +7177,7 @@ function Annotate({
|
|
|
6781
7177
|
);
|
|
6782
7178
|
}
|
|
6783
7179
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { children: seg.text }, i);
|
|
6784
|
-
}),
|
|
7180
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: text }),
|
|
6785
7181
|
pickerPos && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6786
7182
|
"div",
|
|
6787
7183
|
{
|
|
@@ -6820,12 +7216,13 @@ function Annotate({
|
|
|
6820
7216
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { role: "list", children: [
|
|
6821
7217
|
annotations.map((ann, i) => {
|
|
6822
7218
|
const color3 = labelColorMap.get(ann.label) ?? "#888";
|
|
7219
|
+
const annotatedText = typeof text === "string" ? text.slice(ann.start, ann.end) : "";
|
|
6823
7220
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "listitem", style: annotationItemStyle(color3), children: [
|
|
6824
7221
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.375rem" }, children: [
|
|
6825
7222
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: colorDotStyle(color3) }),
|
|
6826
7223
|
/* @__PURE__ */ jsxRuntime.jsx("strong", { style: { fontSize: "0.75rem" }, children: ann.label })
|
|
6827
7224
|
] }),
|
|
6828
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: annotationTextStyle, children:
|
|
7225
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: annotationTextStyle, children: annotatedText }),
|
|
6829
7226
|
ann.note && /* @__PURE__ */ jsxRuntime.jsx("div", { style: annotationNoteStyle, children: ann.note })
|
|
6830
7227
|
] }, i);
|
|
6831
7228
|
}),
|