@glyphjs/components 0.1.0 → 0.3.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 +2402 -370
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +221 -32
- package/dist/index.d.ts +221 -32
- package/dist/index.js +2388 -372
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { accordionSchema, architectureSchema, calloutSchema, cardSchema, chartSchema, codediffSchema, comparisonSchema, equationSchema, filetreeSchema, flowchartSchema, graphSchema, infographicSchema, kpiSchema, mindmapSchema, quizSchema, relationSchema, sequenceSchema, stepsSchema, tableSchema, tabsSchema, timelineSchema } from '@glyphjs/schemas';
|
|
1
|
+
import { accordionSchema, annotateSchema, architectureSchema, calloutSchema, cardSchema, chartSchema, codediffSchema, comparisonSchema, equationSchema, filetreeSchema, flowchartSchema, formSchema, graphSchema, infographicSchema, kanbanSchema, kpiSchema, matrixSchema, mindmapSchema, pollSchema, quizSchema, rankerSchema, ratingSchema, relationSchema, sequenceSchema, sliderSchema, stepsSchema, tableSchema, tabsSchema, timelineSchema } from '@glyphjs/schemas';
|
|
2
|
+
import { RichText } from '@glyphjs/runtime';
|
|
2
3
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
4
|
import { useRef, useState, useEffect, useCallback, useMemo } from 'react';
|
|
4
5
|
import * as d32 from 'd3';
|
|
@@ -21,7 +22,7 @@ var CALLOUT_LABELS = {
|
|
|
21
22
|
};
|
|
22
23
|
function Callout({ data }) {
|
|
23
24
|
const { type, title, content } = data;
|
|
24
|
-
const
|
|
25
|
+
const containerStyle11 = {
|
|
25
26
|
backgroundColor: `var(--glyph-callout-${type}-bg)`,
|
|
26
27
|
borderLeft: `4px solid var(--glyph-callout-${type}-border)`,
|
|
27
28
|
borderRadius: "var(--glyph-radius-md, 0.1875rem)",
|
|
@@ -38,7 +39,7 @@ function Callout({ data }) {
|
|
|
38
39
|
fontSize: "1.25em",
|
|
39
40
|
lineHeight: 1
|
|
40
41
|
};
|
|
41
|
-
const
|
|
42
|
+
const bodyStyle3 = {
|
|
42
43
|
flex: 1,
|
|
43
44
|
minWidth: 0
|
|
44
45
|
};
|
|
@@ -46,11 +47,11 @@ function Callout({ data }) {
|
|
|
46
47
|
fontWeight: 700,
|
|
47
48
|
marginBottom: "var(--glyph-spacing-xs, 0.25rem)"
|
|
48
49
|
};
|
|
49
|
-
return /* @__PURE__ */ jsxs("div", { role: "note", "aria-label": CALLOUT_LABELS[type], style:
|
|
50
|
+
return /* @__PURE__ */ jsxs("div", { role: "note", "aria-label": CALLOUT_LABELS[type], style: containerStyle11, children: [
|
|
50
51
|
/* @__PURE__ */ jsx("span", { style: iconStyle, "aria-hidden": "true", children: CALLOUT_ICONS[type] }),
|
|
51
|
-
/* @__PURE__ */ jsxs("div", { style:
|
|
52
|
+
/* @__PURE__ */ jsxs("div", { style: bodyStyle3, children: [
|
|
52
53
|
title && /* @__PURE__ */ jsx("div", { style: titleStyle2, children: title }),
|
|
53
|
-
/* @__PURE__ */ jsx("div", { children: content })
|
|
54
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(RichText, { content }) })
|
|
54
55
|
] })
|
|
55
56
|
] });
|
|
56
57
|
}
|
|
@@ -253,9 +254,104 @@ function computeScales(width, height, type, series, xKey, yKey, margin) {
|
|
|
253
254
|
const yScale = d32.scaleLinear().domain([yMin, yMax]).nice().range([innerHeight, 0]);
|
|
254
255
|
return { xScale, xScalePoint, yScale, innerWidth, innerHeight };
|
|
255
256
|
}
|
|
257
|
+
function renderAllSeries(g, type, series, scales, xKey, yKey, showTooltip, hideTooltip) {
|
|
258
|
+
const { xScale, xScalePoint, yScale, innerHeight } = scales;
|
|
259
|
+
series.forEach((s, i) => {
|
|
260
|
+
const color3 = COLOR_SCHEME[i % COLOR_SCHEME.length] ?? "#333";
|
|
261
|
+
switch (type) {
|
|
262
|
+
case "line":
|
|
263
|
+
renderLineSeries(
|
|
264
|
+
g,
|
|
265
|
+
s.data,
|
|
266
|
+
xScalePoint,
|
|
267
|
+
yScale,
|
|
268
|
+
yKey,
|
|
269
|
+
xKey,
|
|
270
|
+
color3,
|
|
271
|
+
i,
|
|
272
|
+
s.name,
|
|
273
|
+
showTooltip,
|
|
274
|
+
hideTooltip
|
|
275
|
+
);
|
|
276
|
+
break;
|
|
277
|
+
case "area":
|
|
278
|
+
renderAreaSeries(
|
|
279
|
+
g,
|
|
280
|
+
s.data,
|
|
281
|
+
xScalePoint,
|
|
282
|
+
yScale,
|
|
283
|
+
yKey,
|
|
284
|
+
xKey,
|
|
285
|
+
innerHeight,
|
|
286
|
+
color3,
|
|
287
|
+
i,
|
|
288
|
+
s.name,
|
|
289
|
+
showTooltip,
|
|
290
|
+
hideTooltip
|
|
291
|
+
);
|
|
292
|
+
break;
|
|
293
|
+
case "bar":
|
|
294
|
+
renderBarSeries(
|
|
295
|
+
g,
|
|
296
|
+
s.data,
|
|
297
|
+
xScale,
|
|
298
|
+
yScale,
|
|
299
|
+
yKey,
|
|
300
|
+
xKey,
|
|
301
|
+
color3,
|
|
302
|
+
i,
|
|
303
|
+
series.length,
|
|
304
|
+
innerHeight,
|
|
305
|
+
s.name,
|
|
306
|
+
showTooltip,
|
|
307
|
+
hideTooltip
|
|
308
|
+
);
|
|
309
|
+
break;
|
|
310
|
+
case "ohlc":
|
|
311
|
+
renderOHLCSeries(
|
|
312
|
+
g,
|
|
313
|
+
s.data,
|
|
314
|
+
xScale,
|
|
315
|
+
xScalePoint,
|
|
316
|
+
yScale,
|
|
317
|
+
scales.innerWidth,
|
|
318
|
+
s.name,
|
|
319
|
+
showTooltip,
|
|
320
|
+
hideTooltip
|
|
321
|
+
);
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
function attachChartInteraction(g, type, series, xKey, yKey, block, onInteraction) {
|
|
327
|
+
if (!onInteraction) return;
|
|
328
|
+
series.forEach((s, seriesIdx) => {
|
|
329
|
+
const className = type === "bar" ? `bar-${String(seriesIdx)}` : `dot-${String(seriesIdx)}`;
|
|
330
|
+
g.selectAll(`.${className}`).on(
|
|
331
|
+
"click",
|
|
332
|
+
(_event, d) => {
|
|
333
|
+
const dataIdx = s.data.indexOf(d);
|
|
334
|
+
onInteraction({
|
|
335
|
+
kind: "chart-select",
|
|
336
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
337
|
+
blockId: block.id,
|
|
338
|
+
blockType: block.type,
|
|
339
|
+
payload: {
|
|
340
|
+
seriesIndex: seriesIdx,
|
|
341
|
+
dataIndex: dataIdx >= 0 ? dataIdx : 0,
|
|
342
|
+
label: String(d[xKey] ?? ""),
|
|
343
|
+
value: getNumericValue(d, yKey)
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
);
|
|
348
|
+
});
|
|
349
|
+
}
|
|
256
350
|
function Chart({
|
|
257
351
|
data,
|
|
258
|
-
|
|
352
|
+
block,
|
|
353
|
+
container: containerCtx,
|
|
354
|
+
onInteraction
|
|
259
355
|
}) {
|
|
260
356
|
const containerRef = useRef(null);
|
|
261
357
|
const svgRef = useRef(null);
|
|
@@ -308,76 +404,19 @@ function Chart({
|
|
|
308
404
|
if (!svg || series.length === 0) return;
|
|
309
405
|
const sel = d32.select(svg);
|
|
310
406
|
sel.selectAll("*").remove();
|
|
311
|
-
const { xScale, xScalePoint, yScale, innerWidth, innerHeight } = scales;
|
|
312
407
|
const g = sel.append("g").attr("transform", `translate(${String(margin.left)},${String(margin.top)})`);
|
|
313
|
-
renderAxes(
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
xKey,
|
|
326
|
-
color3,
|
|
327
|
-
i,
|
|
328
|
-
s.name,
|
|
329
|
-
showTooltip,
|
|
330
|
-
hideTooltip
|
|
331
|
-
);
|
|
332
|
-
break;
|
|
333
|
-
case "area":
|
|
334
|
-
renderAreaSeries(
|
|
335
|
-
g,
|
|
336
|
-
s.data,
|
|
337
|
-
xScalePoint,
|
|
338
|
-
yScale,
|
|
339
|
-
yKey,
|
|
340
|
-
xKey,
|
|
341
|
-
innerHeight,
|
|
342
|
-
color3,
|
|
343
|
-
i,
|
|
344
|
-
s.name,
|
|
345
|
-
showTooltip,
|
|
346
|
-
hideTooltip
|
|
347
|
-
);
|
|
348
|
-
break;
|
|
349
|
-
case "bar":
|
|
350
|
-
renderBarSeries(
|
|
351
|
-
g,
|
|
352
|
-
s.data,
|
|
353
|
-
xScale,
|
|
354
|
-
yScale,
|
|
355
|
-
yKey,
|
|
356
|
-
xKey,
|
|
357
|
-
color3,
|
|
358
|
-
i,
|
|
359
|
-
series.length,
|
|
360
|
-
innerHeight,
|
|
361
|
-
s.name,
|
|
362
|
-
showTooltip,
|
|
363
|
-
hideTooltip
|
|
364
|
-
);
|
|
365
|
-
break;
|
|
366
|
-
case "ohlc":
|
|
367
|
-
renderOHLCSeries(
|
|
368
|
-
g,
|
|
369
|
-
s.data,
|
|
370
|
-
xScale,
|
|
371
|
-
xScalePoint,
|
|
372
|
-
yScale,
|
|
373
|
-
innerWidth,
|
|
374
|
-
s.name,
|
|
375
|
-
showTooltip,
|
|
376
|
-
hideTooltip
|
|
377
|
-
);
|
|
378
|
-
break;
|
|
379
|
-
}
|
|
380
|
-
});
|
|
408
|
+
renderAxes(
|
|
409
|
+
g,
|
|
410
|
+
scales.xScale,
|
|
411
|
+
scales.yScale,
|
|
412
|
+
xAxis,
|
|
413
|
+
yAxis,
|
|
414
|
+
scales.innerWidth,
|
|
415
|
+
scales.innerHeight
|
|
416
|
+
);
|
|
417
|
+
renderGridLines(g, scales.yScale, scales.innerWidth);
|
|
418
|
+
renderAllSeries(g, type, series, scales, xKey, yKey, showTooltip, hideTooltip);
|
|
419
|
+
attachChartInteraction(g, type, series, xKey, yKey, block, onInteraction);
|
|
381
420
|
if (legend) {
|
|
382
421
|
renderLegend(sel, series, margin.left, margin.top, isCompact ? "10px" : void 0);
|
|
383
422
|
}
|
|
@@ -393,7 +432,9 @@ function Chart({
|
|
|
393
432
|
margin,
|
|
394
433
|
isCompact,
|
|
395
434
|
showTooltip,
|
|
396
|
-
hideTooltip
|
|
435
|
+
hideTooltip,
|
|
436
|
+
onInteraction,
|
|
437
|
+
block
|
|
397
438
|
]);
|
|
398
439
|
const ariaLabel = `${type} chart with ${String(series.length)} series: ${series.map((s) => s.name).join(", ")}`;
|
|
399
440
|
return /* @__PURE__ */ jsxs(
|
|
@@ -467,14 +508,14 @@ var STATUS_LABELS = {
|
|
|
467
508
|
};
|
|
468
509
|
function Steps({ data }) {
|
|
469
510
|
const { steps } = data;
|
|
470
|
-
const
|
|
511
|
+
const listStyle2 = {
|
|
471
512
|
listStyle: "none",
|
|
472
513
|
padding: 0,
|
|
473
514
|
margin: "var(--glyph-spacing-sm, 0.5rem) 0",
|
|
474
515
|
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
475
516
|
color: "var(--glyph-text, #1a2035)"
|
|
476
517
|
};
|
|
477
|
-
return /* @__PURE__ */ jsx("ol", { role: "list", style:
|
|
518
|
+
return /* @__PURE__ */ jsx("ol", { role: "list", style: listStyle2, children: steps.map((step, index) => {
|
|
478
519
|
const status = step.status ?? "pending";
|
|
479
520
|
const isLast = index === steps.length - 1;
|
|
480
521
|
return /* @__PURE__ */ jsxs(
|
|
@@ -488,7 +529,7 @@ function Steps({ data }) {
|
|
|
488
529
|
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: indicatorStyle(status), children: status === "completed" ? "\u2713" : "" }),
|
|
489
530
|
/* @__PURE__ */ jsxs("div", { style: bodyStyle, children: [
|
|
490
531
|
/* @__PURE__ */ jsx("div", { style: titleStyle(status), children: step.title }),
|
|
491
|
-
/* @__PURE__ */ jsx("div", { style: contentStyle(status), children: step.content })
|
|
532
|
+
/* @__PURE__ */ jsx("div", { style: contentStyle(status), children: /* @__PURE__ */ jsx(RichText, { content: step.content }) })
|
|
492
533
|
] })
|
|
493
534
|
]
|
|
494
535
|
},
|
|
@@ -621,7 +662,95 @@ function TableAggregationFooter({
|
|
|
621
662
|
);
|
|
622
663
|
}) }) });
|
|
623
664
|
}
|
|
624
|
-
function
|
|
665
|
+
function TableHead({
|
|
666
|
+
columns,
|
|
667
|
+
sort,
|
|
668
|
+
hasFilters,
|
|
669
|
+
filters,
|
|
670
|
+
onSort,
|
|
671
|
+
onHeaderKeyDown,
|
|
672
|
+
onFilterChange
|
|
673
|
+
}) {
|
|
674
|
+
return /* @__PURE__ */ jsxs("thead", { children: [
|
|
675
|
+
/* @__PURE__ */ jsx("tr", { children: columns.map((col) => {
|
|
676
|
+
const isSorted = sort.column === col.key;
|
|
677
|
+
const direction = isSorted ? sort.direction : "none";
|
|
678
|
+
return /* @__PURE__ */ jsxs(
|
|
679
|
+
"th",
|
|
680
|
+
{
|
|
681
|
+
scope: "col",
|
|
682
|
+
"aria-sort": col.sortable ? direction : void 0,
|
|
683
|
+
tabIndex: col.sortable ? 0 : void 0,
|
|
684
|
+
role: col.sortable ? "columnheader" : void 0,
|
|
685
|
+
onClick: col.sortable ? () => onSort(col.key) : void 0,
|
|
686
|
+
onKeyDown: col.sortable ? (e) => onHeaderKeyDown(e, col.key) : void 0,
|
|
687
|
+
style: {
|
|
688
|
+
padding: "var(--glyph-table-cell-padding, 8px 12px)",
|
|
689
|
+
textAlign: "left",
|
|
690
|
+
borderBottom: "2px solid var(--glyph-table-border, #d0d8e4)",
|
|
691
|
+
background: "var(--glyph-table-header-bg, #e8ecf3)",
|
|
692
|
+
color: "var(--glyph-table-header-color, inherit)",
|
|
693
|
+
cursor: col.sortable ? "pointer" : "default",
|
|
694
|
+
userSelect: col.sortable ? "none" : void 0,
|
|
695
|
+
whiteSpace: "nowrap"
|
|
696
|
+
},
|
|
697
|
+
children: [
|
|
698
|
+
col.label,
|
|
699
|
+
col.sortable ? sortIndicator(direction) : ""
|
|
700
|
+
]
|
|
701
|
+
},
|
|
702
|
+
col.key
|
|
703
|
+
);
|
|
704
|
+
}) }),
|
|
705
|
+
hasFilters && /* @__PURE__ */ jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsx(
|
|
706
|
+
"th",
|
|
707
|
+
{
|
|
708
|
+
scope: "col",
|
|
709
|
+
style: { padding: "4px 8px", fontWeight: "normal" },
|
|
710
|
+
children: col.filterable ? /* @__PURE__ */ jsx(
|
|
711
|
+
"input",
|
|
712
|
+
{
|
|
713
|
+
type: "text",
|
|
714
|
+
"aria-label": `Filter ${col.label}`,
|
|
715
|
+
placeholder: `Filter ${col.label}...`,
|
|
716
|
+
value: filters[col.key] ?? "",
|
|
717
|
+
onChange: (e) => onFilterChange(col.key, e.target.value),
|
|
718
|
+
style: {
|
|
719
|
+
width: "100%",
|
|
720
|
+
padding: "4px 6px",
|
|
721
|
+
border: "1px solid var(--glyph-table-border, #d0d8e4)",
|
|
722
|
+
borderRadius: "3px",
|
|
723
|
+
fontSize: "inherit",
|
|
724
|
+
boxSizing: "border-box",
|
|
725
|
+
background: "var(--glyph-surface, #e8ecf3)",
|
|
726
|
+
color: "var(--glyph-text, inherit)"
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
) : /* @__PURE__ */ jsx(
|
|
730
|
+
"span",
|
|
731
|
+
{
|
|
732
|
+
style: {
|
|
733
|
+
position: "absolute",
|
|
734
|
+
width: "1px",
|
|
735
|
+
height: "1px",
|
|
736
|
+
overflow: "hidden",
|
|
737
|
+
clip: "rect(0,0,0,0)",
|
|
738
|
+
whiteSpace: "nowrap"
|
|
739
|
+
},
|
|
740
|
+
children: `No filter for ${col.label}`
|
|
741
|
+
}
|
|
742
|
+
)
|
|
743
|
+
},
|
|
744
|
+
`filter-${col.key}`
|
|
745
|
+
)) })
|
|
746
|
+
] });
|
|
747
|
+
}
|
|
748
|
+
function Table({
|
|
749
|
+
data,
|
|
750
|
+
block,
|
|
751
|
+
container,
|
|
752
|
+
onInteraction
|
|
753
|
+
}) {
|
|
625
754
|
const { columns, rows, aggregation } = data;
|
|
626
755
|
const [sort, setSort] = useState({ column: "", direction: "none" });
|
|
627
756
|
const [filters, setFilters] = useState({});
|
|
@@ -654,12 +783,27 @@ function Table({ data, container }) {
|
|
|
654
783
|
});
|
|
655
784
|
}, [filteredRows, sort]);
|
|
656
785
|
const handleSort = (columnKey) => {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
786
|
+
const newDirection = sort.column === columnKey ? nextDirection(sort.direction) : "ascending";
|
|
787
|
+
setSort({ column: columnKey, direction: newDirection });
|
|
788
|
+
if (onInteraction) {
|
|
789
|
+
const eventDir = newDirection === "ascending" ? "asc" : newDirection === "descending" ? "desc" : "none";
|
|
790
|
+
onInteraction({
|
|
791
|
+
kind: "table-sort",
|
|
792
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
793
|
+
blockId: block.id,
|
|
794
|
+
blockType: block.type,
|
|
795
|
+
payload: {
|
|
796
|
+
column: columnKey,
|
|
797
|
+
direction: eventDir,
|
|
798
|
+
state: {
|
|
799
|
+
sort: newDirection === "none" ? null : { column: columnKey, direction: eventDir },
|
|
800
|
+
filters,
|
|
801
|
+
visibleRowCount: filteredRows.length,
|
|
802
|
+
totalRowCount: rows.length
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
}
|
|
663
807
|
};
|
|
664
808
|
const handleHeaderKeyDown = (e, columnKey) => {
|
|
665
809
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -668,7 +812,38 @@ function Table({ data, container }) {
|
|
|
668
812
|
}
|
|
669
813
|
};
|
|
670
814
|
const handleFilterChange = (columnKey, value) => {
|
|
671
|
-
|
|
815
|
+
const newFilters = { ...filters, [columnKey]: value };
|
|
816
|
+
setFilters(newFilters);
|
|
817
|
+
if (onInteraction) {
|
|
818
|
+
const newVisibleCount = rows.filter(
|
|
819
|
+
(row) => columns.every((col) => {
|
|
820
|
+
if (!col.filterable) return true;
|
|
821
|
+
const fv = newFilters[col.key];
|
|
822
|
+
if (!fv) return true;
|
|
823
|
+
return String(row[col.key] ?? "").toLowerCase().includes(fv.toLowerCase());
|
|
824
|
+
})
|
|
825
|
+
).length;
|
|
826
|
+
const eventSort = sort.direction === "none" || !sort.column ? null : {
|
|
827
|
+
column: sort.column,
|
|
828
|
+
direction: sort.direction === "ascending" ? "asc" : "desc"
|
|
829
|
+
};
|
|
830
|
+
onInteraction({
|
|
831
|
+
kind: "table-filter",
|
|
832
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
833
|
+
blockId: block.id,
|
|
834
|
+
blockType: block.type,
|
|
835
|
+
payload: {
|
|
836
|
+
column: columnKey,
|
|
837
|
+
value,
|
|
838
|
+
state: {
|
|
839
|
+
sort: eventSort,
|
|
840
|
+
filters: newFilters,
|
|
841
|
+
visibleRowCount: newVisibleCount,
|
|
842
|
+
totalRowCount: rows.length
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
}
|
|
672
847
|
};
|
|
673
848
|
const hasFilters = columns.some((c) => c.filterable);
|
|
674
849
|
const aggMap = useMemo(() => {
|
|
@@ -692,79 +867,18 @@ function Table({ data, container }) {
|
|
|
692
867
|
fontSize: isCompact ? "0.8125rem" : "var(--glyph-table-font-size, 0.9rem)"
|
|
693
868
|
},
|
|
694
869
|
children: [
|
|
695
|
-
/* @__PURE__ */
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
onKeyDown: col.sortable ? (e) => handleHeaderKeyDown(e, col.key) : void 0,
|
|
708
|
-
style: {
|
|
709
|
-
padding: "var(--glyph-table-cell-padding, 8px 12px)",
|
|
710
|
-
textAlign: "left",
|
|
711
|
-
borderBottom: "2px solid var(--glyph-table-border, #d0d8e4)",
|
|
712
|
-
background: "var(--glyph-table-header-bg, #e8ecf3)",
|
|
713
|
-
color: "var(--glyph-table-header-color, inherit)",
|
|
714
|
-
cursor: col.sortable ? "pointer" : "default",
|
|
715
|
-
userSelect: col.sortable ? "none" : void 0,
|
|
716
|
-
whiteSpace: "nowrap"
|
|
717
|
-
},
|
|
718
|
-
children: [
|
|
719
|
-
col.label,
|
|
720
|
-
col.sortable ? sortIndicator(direction) : ""
|
|
721
|
-
]
|
|
722
|
-
},
|
|
723
|
-
col.key
|
|
724
|
-
);
|
|
725
|
-
}) }),
|
|
726
|
-
hasFilters && /* @__PURE__ */ jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsx(
|
|
727
|
-
"th",
|
|
728
|
-
{
|
|
729
|
-
scope: "col",
|
|
730
|
-
style: { padding: "4px 8px", fontWeight: "normal" },
|
|
731
|
-
children: col.filterable ? /* @__PURE__ */ jsx(
|
|
732
|
-
"input",
|
|
733
|
-
{
|
|
734
|
-
type: "text",
|
|
735
|
-
"aria-label": `Filter ${col.label}`,
|
|
736
|
-
placeholder: `Filter ${col.label}...`,
|
|
737
|
-
value: filters[col.key] ?? "",
|
|
738
|
-
onChange: (e) => handleFilterChange(col.key, e.target.value),
|
|
739
|
-
style: {
|
|
740
|
-
width: "100%",
|
|
741
|
-
padding: "4px 6px",
|
|
742
|
-
border: "1px solid var(--glyph-table-border, #d0d8e4)",
|
|
743
|
-
borderRadius: "3px",
|
|
744
|
-
fontSize: "inherit",
|
|
745
|
-
boxSizing: "border-box",
|
|
746
|
-
background: "var(--glyph-surface, #e8ecf3)",
|
|
747
|
-
color: "var(--glyph-text, inherit)"
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
) : /* @__PURE__ */ jsx(
|
|
751
|
-
"span",
|
|
752
|
-
{
|
|
753
|
-
style: {
|
|
754
|
-
position: "absolute",
|
|
755
|
-
width: "1px",
|
|
756
|
-
height: "1px",
|
|
757
|
-
overflow: "hidden",
|
|
758
|
-
clip: "rect(0,0,0,0)",
|
|
759
|
-
whiteSpace: "nowrap"
|
|
760
|
-
},
|
|
761
|
-
children: `No filter for ${col.label}`
|
|
762
|
-
}
|
|
763
|
-
)
|
|
764
|
-
},
|
|
765
|
-
`filter-${col.key}`
|
|
766
|
-
)) })
|
|
767
|
-
] }),
|
|
870
|
+
/* @__PURE__ */ jsx(
|
|
871
|
+
TableHead,
|
|
872
|
+
{
|
|
873
|
+
columns,
|
|
874
|
+
sort,
|
|
875
|
+
hasFilters,
|
|
876
|
+
filters,
|
|
877
|
+
onSort: handleSort,
|
|
878
|
+
onHeaderKeyDown: handleHeaderKeyDown,
|
|
879
|
+
onFilterChange: handleFilterChange
|
|
880
|
+
}
|
|
881
|
+
),
|
|
768
882
|
/* @__PURE__ */ jsx("tbody", { children: sortedRows.map((row, rowIdx) => /* @__PURE__ */ jsx(
|
|
769
883
|
"tr",
|
|
770
884
|
{
|
|
@@ -802,18 +916,28 @@ var tableDefinition = {
|
|
|
802
916
|
schema: tableSchema,
|
|
803
917
|
render: Table
|
|
804
918
|
};
|
|
805
|
-
function Tabs({ data, block }) {
|
|
919
|
+
function Tabs({ data, block, onInteraction }) {
|
|
806
920
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
807
921
|
const tabRefs = useRef([]);
|
|
808
922
|
const tabs = data.tabs;
|
|
809
923
|
const baseId = `glyph-tabs-${block.id}`;
|
|
810
|
-
const
|
|
924
|
+
const selectTab = useCallback(
|
|
811
925
|
(index) => {
|
|
812
926
|
const clampedIndex = Math.max(0, Math.min(index, tabs.length - 1));
|
|
813
927
|
setActiveIndex(clampedIndex);
|
|
814
928
|
tabRefs.current[clampedIndex]?.focus();
|
|
929
|
+
const tab = tabs[clampedIndex];
|
|
930
|
+
if (tab) {
|
|
931
|
+
onInteraction?.({
|
|
932
|
+
kind: "tab-select",
|
|
933
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
934
|
+
blockId: block.id,
|
|
935
|
+
blockType: block.type,
|
|
936
|
+
payload: { tabIndex: clampedIndex, tabLabel: tab.label }
|
|
937
|
+
});
|
|
938
|
+
}
|
|
815
939
|
},
|
|
816
|
-
[tabs.
|
|
940
|
+
[tabs, block.id, block.type, onInteraction]
|
|
817
941
|
);
|
|
818
942
|
const handleKeyDown = useCallback(
|
|
819
943
|
(e) => {
|
|
@@ -821,28 +945,28 @@ function Tabs({ data, block }) {
|
|
|
821
945
|
case "ArrowRight": {
|
|
822
946
|
e.preventDefault();
|
|
823
947
|
const next = (activeIndex + 1) % tabs.length;
|
|
824
|
-
|
|
948
|
+
selectTab(next);
|
|
825
949
|
break;
|
|
826
950
|
}
|
|
827
951
|
case "ArrowLeft": {
|
|
828
952
|
e.preventDefault();
|
|
829
953
|
const prev = (activeIndex - 1 + tabs.length) % tabs.length;
|
|
830
|
-
|
|
954
|
+
selectTab(prev);
|
|
831
955
|
break;
|
|
832
956
|
}
|
|
833
957
|
case "Home": {
|
|
834
958
|
e.preventDefault();
|
|
835
|
-
|
|
959
|
+
selectTab(0);
|
|
836
960
|
break;
|
|
837
961
|
}
|
|
838
962
|
case "End": {
|
|
839
963
|
e.preventDefault();
|
|
840
|
-
|
|
964
|
+
selectTab(tabs.length - 1);
|
|
841
965
|
break;
|
|
842
966
|
}
|
|
843
967
|
}
|
|
844
968
|
},
|
|
845
|
-
[activeIndex,
|
|
969
|
+
[activeIndex, selectTab, tabs.length]
|
|
846
970
|
);
|
|
847
971
|
return /* @__PURE__ */ jsxs(
|
|
848
972
|
"div",
|
|
@@ -881,7 +1005,7 @@ function Tabs({ data, block }) {
|
|
|
881
1005
|
"aria-selected": isActive,
|
|
882
1006
|
"aria-controls": panelId,
|
|
883
1007
|
tabIndex: isActive ? 0 : -1,
|
|
884
|
-
onClick: () =>
|
|
1008
|
+
onClick: () => selectTab(index),
|
|
885
1009
|
onKeyDown: handleKeyDown,
|
|
886
1010
|
style: {
|
|
887
1011
|
padding: "10px 18px",
|
|
@@ -993,7 +1117,7 @@ function Timeline({ data }) {
|
|
|
993
1117
|
position: dates.length === 1 ? totalLength / 2 : timeScale(e._parsed),
|
|
994
1118
|
side: isVertical ? i % 2 === 0 ? "left" : "right" : i % 2 === 0 ? "top" : "bottom"
|
|
995
1119
|
}));
|
|
996
|
-
const
|
|
1120
|
+
const containerStyle11 = {
|
|
997
1121
|
position: "relative",
|
|
998
1122
|
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
999
1123
|
color: "var(--glyph-text, #1a2035)",
|
|
@@ -1020,7 +1144,7 @@ function Timeline({ data }) {
|
|
|
1020
1144
|
"div",
|
|
1021
1145
|
{
|
|
1022
1146
|
ref: containerRef,
|
|
1023
|
-
style:
|
|
1147
|
+
style: containerStyle11,
|
|
1024
1148
|
role: "img",
|
|
1025
1149
|
"aria-label": `Timeline with ${events.length} events`,
|
|
1026
1150
|
children: [
|
|
@@ -1064,7 +1188,7 @@ function Timeline({ data }) {
|
|
|
1064
1188
|
fontWeight: 700,
|
|
1065
1189
|
marginTop: 2
|
|
1066
1190
|
},
|
|
1067
|
-
children: pe.event.title
|
|
1191
|
+
children: /* @__PURE__ */ jsx(RichText, { content: pe.event.title })
|
|
1068
1192
|
}
|
|
1069
1193
|
),
|
|
1070
1194
|
pe.event.description && /* @__PURE__ */ jsx(
|
|
@@ -1075,7 +1199,7 @@ function Timeline({ data }) {
|
|
|
1075
1199
|
color: "var(--glyph-timeline-desc-color, #7a8599)",
|
|
1076
1200
|
marginTop: 2
|
|
1077
1201
|
},
|
|
1078
|
-
children: pe.event.description
|
|
1202
|
+
children: /* @__PURE__ */ jsx(RichText, { content: pe.event.description })
|
|
1079
1203
|
}
|
|
1080
1204
|
)
|
|
1081
1205
|
] })
|
|
@@ -1093,12 +1217,16 @@ function Timeline({ data }) {
|
|
|
1093
1217
|
clipPath: "inset(50%)",
|
|
1094
1218
|
whiteSpace: "nowrap"
|
|
1095
1219
|
},
|
|
1096
|
-
children: sorted.map((e, idx) =>
|
|
1097
|
-
|
|
1098
|
-
"
|
|
1099
|
-
/* @__PURE__ */
|
|
1100
|
-
|
|
1101
|
-
|
|
1220
|
+
children: sorted.map((e, idx) => {
|
|
1221
|
+
const titleText = typeof e.title === "string" ? e.title : "Event";
|
|
1222
|
+
const descText = typeof e.description === "string" ? e.description : "";
|
|
1223
|
+
return /* @__PURE__ */ jsxs("li", { children: [
|
|
1224
|
+
/* @__PURE__ */ jsx("time", { dateTime: isoDate(e.date), children: formatDate(e.date) }),
|
|
1225
|
+
" \u2014 ",
|
|
1226
|
+
/* @__PURE__ */ jsx("strong", { children: titleText }),
|
|
1227
|
+
descText ? `: ${descText}` : ""
|
|
1228
|
+
] }, idx);
|
|
1229
|
+
})
|
|
1102
1230
|
}
|
|
1103
1231
|
)
|
|
1104
1232
|
]
|
|
@@ -1348,7 +1476,7 @@ function getThemeVar(container, varName, fallback) {
|
|
|
1348
1476
|
return getComputedStyle(container).getPropertyValue(varName).trim() || fallback;
|
|
1349
1477
|
}
|
|
1350
1478
|
var ARROW_MARKER_ID = "glyph-graph-arrowhead";
|
|
1351
|
-
function renderGraph(svgElement, layout, groupIndex, outgoingRefs, onNavigate) {
|
|
1479
|
+
function renderGraph(svgElement, layout, groupIndex, outgoingRefs, onNavigate, onNodeClick) {
|
|
1352
1480
|
const svg = d32.select(svgElement);
|
|
1353
1481
|
svg.selectAll("*").remove();
|
|
1354
1482
|
const width = Math.max(layout.width, 200);
|
|
@@ -1399,19 +1527,24 @@ function renderGraph(svgElement, layout, groupIndex, outgoingRefs, onNavigate) {
|
|
|
1399
1527
|
nodeG.append("rect").attr("x", nodeX).attr("y", nodeY).attr("width", node.width).attr("height", node.height).attr("rx", nodeRadius).attr("ry", nodeRadius).attr("fill", node.style?.["fill"] ?? color3).attr("stroke", node.style?.["stroke"] ?? defaultStroke).attr("stroke-width", node.style?.["stroke-width"] ?? nodeStrokeWidth).attr("opacity", nodeFillOpacity);
|
|
1400
1528
|
}
|
|
1401
1529
|
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);
|
|
1402
|
-
if (isNavigable) {
|
|
1530
|
+
if (isNavigable || onNodeClick) {
|
|
1403
1531
|
nodeG.attr("cursor", "pointer");
|
|
1404
1532
|
nodeG.on("click", () => {
|
|
1405
|
-
|
|
1406
|
-
|
|
1533
|
+
if (isNavigable) {
|
|
1534
|
+
const ref = refByAnchor.get(node.id);
|
|
1535
|
+
if (ref) onNavigate(ref);
|
|
1536
|
+
}
|
|
1537
|
+
onNodeClick?.(node.id, node.label);
|
|
1407
1538
|
});
|
|
1408
1539
|
}
|
|
1409
1540
|
}
|
|
1410
1541
|
}
|
|
1411
1542
|
function Graph({
|
|
1412
1543
|
data,
|
|
1544
|
+
block,
|
|
1413
1545
|
outgoingRefs,
|
|
1414
1546
|
onNavigate,
|
|
1547
|
+
onInteraction,
|
|
1415
1548
|
container
|
|
1416
1549
|
}) {
|
|
1417
1550
|
const svgRef = useRef(null);
|
|
@@ -1423,10 +1556,29 @@ function Graph({
|
|
|
1423
1556
|
}
|
|
1424
1557
|
return computeDagreLayout(data.nodes, data.edges, direction);
|
|
1425
1558
|
}, [data]);
|
|
1559
|
+
const handleNodeClick = useMemo(() => {
|
|
1560
|
+
if (!onInteraction) return void 0;
|
|
1561
|
+
return (nodeId, nodeLabel) => {
|
|
1562
|
+
onInteraction({
|
|
1563
|
+
kind: "graph-node-click",
|
|
1564
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1565
|
+
blockId: block.id,
|
|
1566
|
+
blockType: block.type,
|
|
1567
|
+
payload: { nodeId, nodeLabel }
|
|
1568
|
+
});
|
|
1569
|
+
};
|
|
1570
|
+
}, [onInteraction, block.id, block.type]);
|
|
1426
1571
|
useEffect(() => {
|
|
1427
1572
|
if (!svgRef.current) return;
|
|
1428
|
-
renderGraph(
|
|
1429
|
-
|
|
1573
|
+
renderGraph(
|
|
1574
|
+
svgRef.current,
|
|
1575
|
+
layoutResult,
|
|
1576
|
+
groupIndex.current,
|
|
1577
|
+
outgoingRefs,
|
|
1578
|
+
onNavigate,
|
|
1579
|
+
handleNodeClick
|
|
1580
|
+
);
|
|
1581
|
+
}, [layoutResult, outgoingRefs, onNavigate, handleNodeClick]);
|
|
1430
1582
|
const ariaLabel = `${data.type} graph with ${data.nodes.length} nodes and ${data.edges.length} edges`;
|
|
1431
1583
|
return /* @__PURE__ */ jsxs("div", { className: "glyph-graph-container", children: [
|
|
1432
1584
|
/* @__PURE__ */ jsx(
|
|
@@ -1746,7 +1898,8 @@ function resolveSentiment(metric) {
|
|
|
1746
1898
|
return "neutral";
|
|
1747
1899
|
}
|
|
1748
1900
|
function buildAriaLabel(metric) {
|
|
1749
|
-
|
|
1901
|
+
const labelText = typeof metric.label === "string" ? metric.label : "Metric";
|
|
1902
|
+
let label = `${labelText}: ${metric.value}`;
|
|
1750
1903
|
if (metric.unit) label += ` ${metric.unit}`;
|
|
1751
1904
|
if (metric.delta && metric.trend) {
|
|
1752
1905
|
label += `, ${metric.trend} ${metric.delta}`;
|
|
@@ -1770,7 +1923,7 @@ function Kpi({ data, block, container }) {
|
|
|
1770
1923
|
default:
|
|
1771
1924
|
colCount = authorCols;
|
|
1772
1925
|
}
|
|
1773
|
-
const
|
|
1926
|
+
const containerStyle11 = {
|
|
1774
1927
|
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
1775
1928
|
color: "var(--glyph-text, #1a2035)"
|
|
1776
1929
|
};
|
|
@@ -1780,13 +1933,13 @@ function Kpi({ data, block, container }) {
|
|
|
1780
1933
|
gridTemplateColumns: `repeat(auto-fill, minmax(max(120px, calc((100% - ${String(gapCount)}rem) / ${String(colCount)})), 1fr))`,
|
|
1781
1934
|
gap: "var(--glyph-spacing-md, 1rem)"
|
|
1782
1935
|
};
|
|
1783
|
-
const
|
|
1936
|
+
const cardStyle2 = {
|
|
1784
1937
|
background: "var(--glyph-surface-raised, #f4f6fa)",
|
|
1785
1938
|
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
1786
1939
|
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
1787
1940
|
padding: "var(--glyph-spacing-md, 1rem)"
|
|
1788
1941
|
};
|
|
1789
|
-
const
|
|
1942
|
+
const labelStyle4 = {
|
|
1790
1943
|
fontSize: "0.8125rem",
|
|
1791
1944
|
color: "var(--glyph-text-muted, #6b7a94)",
|
|
1792
1945
|
marginBottom: "var(--glyph-spacing-xs, 0.25rem)"
|
|
@@ -1797,7 +1950,7 @@ function Kpi({ data, block, container }) {
|
|
|
1797
1950
|
color: "var(--glyph-heading, #0a0e1a)",
|
|
1798
1951
|
lineHeight: 1.2
|
|
1799
1952
|
};
|
|
1800
|
-
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Key metrics", style:
|
|
1953
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Key metrics", style: containerStyle11, children: [
|
|
1801
1954
|
title && /* @__PURE__ */ jsx(
|
|
1802
1955
|
"div",
|
|
1803
1956
|
{
|
|
@@ -1817,8 +1970,8 @@ function Kpi({ data, block, container }) {
|
|
|
1817
1970
|
marginTop: "var(--glyph-spacing-xs, 0.25rem)",
|
|
1818
1971
|
color: `var(--glyph-kpi-${sentiment}, inherit)`
|
|
1819
1972
|
};
|
|
1820
|
-
return /* @__PURE__ */ jsxs("div", { role: "group", "aria-label": buildAriaLabel(metric), style:
|
|
1821
|
-
/* @__PURE__ */ jsx("div", { style:
|
|
1973
|
+
return /* @__PURE__ */ jsxs("div", { role: "group", "aria-label": buildAriaLabel(metric), style: cardStyle2, children: [
|
|
1974
|
+
/* @__PURE__ */ jsx("div", { style: labelStyle4, children: /* @__PURE__ */ jsx(RichText, { content: metric.label }) }),
|
|
1822
1975
|
/* @__PURE__ */ jsxs("div", { style: valueStyle, children: [
|
|
1823
1976
|
metric.value,
|
|
1824
1977
|
metric.unit && /* @__PURE__ */ jsx("span", { style: { fontSize: "0.875rem", fontWeight: 400, marginLeft: "0.25rem" }, children: metric.unit })
|
|
@@ -1838,25 +1991,41 @@ var kpiDefinition = {
|
|
|
1838
1991
|
schema: kpiSchema,
|
|
1839
1992
|
render: Kpi
|
|
1840
1993
|
};
|
|
1841
|
-
function Accordion({
|
|
1994
|
+
function Accordion({
|
|
1995
|
+
data,
|
|
1996
|
+
block,
|
|
1997
|
+
onInteraction
|
|
1998
|
+
}) {
|
|
1842
1999
|
const { title, sections, defaultOpen = [], multiple = true } = data;
|
|
1843
2000
|
const baseId = `glyph-accordion-${block.id}`;
|
|
1844
2001
|
const containerRef = useRef(null);
|
|
1845
2002
|
const handleToggle = useCallback(
|
|
1846
|
-
(e) => {
|
|
1847
|
-
if (multiple) return;
|
|
2003
|
+
(e, sectionIndex) => {
|
|
1848
2004
|
const target = e.currentTarget;
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
details.open
|
|
2005
|
+
const expanded = target.open;
|
|
2006
|
+
if (!multiple && expanded && containerRef.current) {
|
|
2007
|
+
const allDetails = containerRef.current.querySelectorAll("details");
|
|
2008
|
+
for (const details of allDetails) {
|
|
2009
|
+
if (details !== target && details.open) {
|
|
2010
|
+
details.open = false;
|
|
2011
|
+
}
|
|
1854
2012
|
}
|
|
1855
2013
|
}
|
|
2014
|
+
onInteraction?.({
|
|
2015
|
+
kind: "accordion-toggle",
|
|
2016
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2017
|
+
blockId: block.id,
|
|
2018
|
+
blockType: block.type,
|
|
2019
|
+
payload: {
|
|
2020
|
+
sectionIndex,
|
|
2021
|
+
sectionTitle: sections[sectionIndex]?.title ?? "",
|
|
2022
|
+
expanded
|
|
2023
|
+
}
|
|
2024
|
+
});
|
|
1856
2025
|
},
|
|
1857
|
-
[multiple]
|
|
2026
|
+
[multiple, sections, block.id, block.type, onInteraction]
|
|
1858
2027
|
);
|
|
1859
|
-
const
|
|
2028
|
+
const containerStyle11 = {
|
|
1860
2029
|
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
1861
2030
|
color: "var(--glyph-text, #1a2035)",
|
|
1862
2031
|
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
@@ -1890,7 +2059,7 @@ function Accordion({ data, block }) {
|
|
|
1890
2059
|
ref: containerRef,
|
|
1891
2060
|
role: "region",
|
|
1892
2061
|
"aria-label": title ?? "Accordion",
|
|
1893
|
-
style:
|
|
2062
|
+
style: containerStyle11,
|
|
1894
2063
|
children: [
|
|
1895
2064
|
title && /* @__PURE__ */ jsx(
|
|
1896
2065
|
"div",
|
|
@@ -1909,14 +2078,14 @@ function Accordion({ data, block }) {
|
|
|
1909
2078
|
"details",
|
|
1910
2079
|
{
|
|
1911
2080
|
open: defaultOpen.includes(i),
|
|
1912
|
-
onToggle: handleToggle,
|
|
2081
|
+
onToggle: (e) => handleToggle(e, i),
|
|
1913
2082
|
style: sectionStyle(i === sections.length - 1),
|
|
1914
2083
|
children: [
|
|
1915
2084
|
/* @__PURE__ */ jsxs("summary", { style: summaryStyle, children: [
|
|
1916
2085
|
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { fontSize: "0.75rem", width: "1rem", flexShrink: 0 }, children: "\u25B8" }),
|
|
1917
2086
|
section.title
|
|
1918
2087
|
] }),
|
|
1919
|
-
/* @__PURE__ */ jsx("div", { style: contentStyle2, children: section.content })
|
|
2088
|
+
/* @__PURE__ */ jsx("div", { style: contentStyle2, children: /* @__PURE__ */ jsx(RichText, { content: section.content }) })
|
|
1920
2089
|
]
|
|
1921
2090
|
},
|
|
1922
2091
|
i
|
|
@@ -1935,6 +2104,7 @@ var accordionDefinition = {
|
|
|
1935
2104
|
var YES_VALUES = /* @__PURE__ */ new Set(["yes", "true", "full"]);
|
|
1936
2105
|
var NO_VALUES = /* @__PURE__ */ new Set(["no", "false", "none"]);
|
|
1937
2106
|
function classifyValue(value) {
|
|
2107
|
+
if (typeof value !== "string") return "text";
|
|
1938
2108
|
const lower = value.toLowerCase().trim();
|
|
1939
2109
|
if (YES_VALUES.has(lower)) return "yes";
|
|
1940
2110
|
if (NO_VALUES.has(lower)) return "no";
|
|
@@ -1972,23 +2142,24 @@ function renderValue(value) {
|
|
|
1972
2142
|
}
|
|
1973
2143
|
);
|
|
1974
2144
|
default:
|
|
1975
|
-
return /* @__PURE__ */ jsx("span", { children: value });
|
|
2145
|
+
return /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(RichText, { content: value }) });
|
|
1976
2146
|
}
|
|
1977
2147
|
}
|
|
1978
2148
|
function Comparison({
|
|
1979
2149
|
data,
|
|
1980
2150
|
block,
|
|
1981
|
-
container
|
|
2151
|
+
container,
|
|
2152
|
+
onInteraction
|
|
1982
2153
|
}) {
|
|
1983
2154
|
const { title, options, features } = data;
|
|
1984
2155
|
const baseId = `glyph-comparison-${block.id}`;
|
|
1985
2156
|
const isCompact = container.tier === "compact";
|
|
1986
2157
|
const cellPadding = isCompact ? "var(--glyph-spacing-xs, 0.25rem) var(--glyph-spacing-sm, 0.5rem)" : "var(--glyph-spacing-sm, 0.5rem) var(--glyph-spacing-md, 1rem)";
|
|
1987
|
-
const
|
|
2158
|
+
const containerStyle11 = {
|
|
1988
2159
|
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
1989
2160
|
color: "var(--glyph-text, #1a2035)"
|
|
1990
2161
|
};
|
|
1991
|
-
const
|
|
2162
|
+
const tableStyle2 = {
|
|
1992
2163
|
width: "100%",
|
|
1993
2164
|
borderCollapse: "collapse",
|
|
1994
2165
|
border: "1px solid var(--glyph-table-border, #d0d8e4)",
|
|
@@ -1996,7 +2167,7 @@ function Comparison({
|
|
|
1996
2167
|
overflow: "hidden",
|
|
1997
2168
|
fontSize: isCompact ? "0.8125rem" : "0.875rem"
|
|
1998
2169
|
};
|
|
1999
|
-
const
|
|
2170
|
+
const thStyle2 = {
|
|
2000
2171
|
padding: cellPadding,
|
|
2001
2172
|
textAlign: "center",
|
|
2002
2173
|
fontWeight: 600,
|
|
@@ -2005,7 +2176,7 @@ function Comparison({
|
|
|
2005
2176
|
color: "var(--glyph-heading, #0a0e1a)"
|
|
2006
2177
|
};
|
|
2007
2178
|
const featureThStyle = {
|
|
2008
|
-
...
|
|
2179
|
+
...thStyle2,
|
|
2009
2180
|
textAlign: "left"
|
|
2010
2181
|
};
|
|
2011
2182
|
const rowThStyle = {
|
|
@@ -2015,13 +2186,13 @@ function Comparison({
|
|
|
2015
2186
|
borderBottom: "1px solid var(--glyph-table-border, #d0d8e4)",
|
|
2016
2187
|
fontSize: "0.8125rem"
|
|
2017
2188
|
};
|
|
2018
|
-
const
|
|
2189
|
+
const cellStyle2 = (rowIndex) => ({
|
|
2019
2190
|
padding: cellPadding,
|
|
2020
2191
|
textAlign: "center",
|
|
2021
2192
|
borderBottom: "1px solid var(--glyph-table-border, #d0d8e4)",
|
|
2022
2193
|
background: rowIndex % 2 === 1 ? "var(--glyph-table-row-alt-bg, transparent)" : "transparent"
|
|
2023
2194
|
});
|
|
2024
|
-
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Comparison", style:
|
|
2195
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Comparison", style: containerStyle11, children: [
|
|
2025
2196
|
title && /* @__PURE__ */ jsx(
|
|
2026
2197
|
"div",
|
|
2027
2198
|
{
|
|
@@ -2034,23 +2205,46 @@ function Comparison({
|
|
|
2034
2205
|
children: title
|
|
2035
2206
|
}
|
|
2036
2207
|
),
|
|
2037
|
-
/* @__PURE__ */ jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxs("table", { role: "grid", style:
|
|
2208
|
+
/* @__PURE__ */ jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxs("table", { role: "grid", style: tableStyle2, children: [
|
|
2038
2209
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2039
2210
|
/* @__PURE__ */ jsx("th", { style: featureThStyle, scope: "col", children: "Feature" }),
|
|
2040
|
-
options.map((option, i) => /* @__PURE__ */ jsxs(
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2211
|
+
options.map((option, i) => /* @__PURE__ */ jsxs(
|
|
2212
|
+
"th",
|
|
2213
|
+
{
|
|
2214
|
+
style: {
|
|
2215
|
+
...thStyle2,
|
|
2216
|
+
...onInteraction ? { cursor: "pointer" } : {}
|
|
2217
|
+
},
|
|
2218
|
+
scope: "col",
|
|
2219
|
+
onClick: onInteraction ? () => {
|
|
2220
|
+
onInteraction({
|
|
2221
|
+
kind: "comparison-select",
|
|
2222
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2223
|
+
blockId: block.id,
|
|
2224
|
+
blockType: block.type,
|
|
2225
|
+
payload: {
|
|
2226
|
+
optionIndex: i,
|
|
2227
|
+
optionName: option.name
|
|
2228
|
+
}
|
|
2229
|
+
});
|
|
2230
|
+
} : void 0,
|
|
2231
|
+
children: [
|
|
2232
|
+
/* @__PURE__ */ jsx("div", { children: option.name }),
|
|
2233
|
+
option.description && /* @__PURE__ */ jsx(
|
|
2234
|
+
"div",
|
|
2235
|
+
{
|
|
2236
|
+
style: {
|
|
2237
|
+
fontWeight: 400,
|
|
2238
|
+
fontSize: "0.75rem",
|
|
2239
|
+
color: "var(--glyph-text-muted, #6b7a94)"
|
|
2240
|
+
},
|
|
2241
|
+
children: /* @__PURE__ */ jsx(RichText, { content: option.description })
|
|
2242
|
+
}
|
|
2243
|
+
)
|
|
2244
|
+
]
|
|
2245
|
+
},
|
|
2246
|
+
i
|
|
2247
|
+
))
|
|
2054
2248
|
] }) }),
|
|
2055
2249
|
/* @__PURE__ */ jsx("tbody", { children: features.map((feature, rowIndex) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
2056
2250
|
/* @__PURE__ */ jsx(
|
|
@@ -2065,8 +2259,8 @@ function Comparison({
|
|
|
2065
2259
|
}
|
|
2066
2260
|
),
|
|
2067
2261
|
options.map((_, colIndex) => {
|
|
2068
|
-
const value = feature.values[colIndex]
|
|
2069
|
-
return /* @__PURE__ */ jsx("td", { style:
|
|
2262
|
+
const value = feature.values[colIndex];
|
|
2263
|
+
return /* @__PURE__ */ jsx("td", { style: cellStyle2(rowIndex), children: value !== void 0 && value !== "" ? renderValue(value) : null }, colIndex);
|
|
2070
2264
|
})
|
|
2071
2265
|
] }, rowIndex)) })
|
|
2072
2266
|
] }) })
|
|
@@ -2144,7 +2338,7 @@ function CodeDiff({ data, block }) {
|
|
|
2144
2338
|
const baseId = `glyph-codediff-${block.id}`;
|
|
2145
2339
|
const diffLines = useMemo(() => computeDiff(before, after), [before, after]);
|
|
2146
2340
|
const summary = useMemo(() => summarizeDiff(diffLines), [diffLines]);
|
|
2147
|
-
const
|
|
2341
|
+
const containerStyle11 = {
|
|
2148
2342
|
fontFamily: 'var(--glyph-font-mono, ui-monospace, "Cascadia Code", "Fira Code", monospace)',
|
|
2149
2343
|
fontSize: "0.8125rem",
|
|
2150
2344
|
lineHeight: 1.5,
|
|
@@ -2163,7 +2357,7 @@ function CodeDiff({ data, block }) {
|
|
|
2163
2357
|
fontWeight: 600,
|
|
2164
2358
|
color: "var(--glyph-text-muted, #6b7a94)"
|
|
2165
2359
|
};
|
|
2166
|
-
const
|
|
2360
|
+
const tableStyle2 = {
|
|
2167
2361
|
width: "100%",
|
|
2168
2362
|
borderCollapse: "collapse",
|
|
2169
2363
|
tableLayout: "fixed"
|
|
@@ -2202,13 +2396,13 @@ function CodeDiff({ data, block }) {
|
|
|
2202
2396
|
if (kind === "del") return "var(--glyph-codediff-del-color, inherit)";
|
|
2203
2397
|
return void 0;
|
|
2204
2398
|
}
|
|
2205
|
-
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": summary, style:
|
|
2399
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": summary, style: containerStyle11, children: [
|
|
2206
2400
|
(beforeLabel || afterLabel) && /* @__PURE__ */ jsxs("div", { style: labelBarStyle, children: [
|
|
2207
2401
|
beforeLabel && /* @__PURE__ */ jsx("span", { children: beforeLabel }),
|
|
2208
2402
|
beforeLabel && afterLabel && /* @__PURE__ */ jsx("span", { children: "\u2192" }),
|
|
2209
2403
|
afterLabel && /* @__PURE__ */ jsx("span", { children: afterLabel })
|
|
2210
2404
|
] }),
|
|
2211
|
-
/* @__PURE__ */ jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsx("table", { role: "grid", style:
|
|
2405
|
+
/* @__PURE__ */ jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsx("table", { role: "grid", style: tableStyle2, children: /* @__PURE__ */ jsx("tbody", { children: diffLines.map((line6, i) => /* @__PURE__ */ jsxs(
|
|
2212
2406
|
"tr",
|
|
2213
2407
|
{
|
|
2214
2408
|
"aria-label": ARIA_LABELS[line6.kind],
|
|
@@ -2474,15 +2668,25 @@ function TreeItem({
|
|
|
2474
2668
|
setSize,
|
|
2475
2669
|
posInSet,
|
|
2476
2670
|
onFocusChange,
|
|
2477
|
-
flatItems
|
|
2671
|
+
flatItems,
|
|
2672
|
+
parentPath,
|
|
2673
|
+
onSelect
|
|
2478
2674
|
}) {
|
|
2479
2675
|
const [expanded, setExpanded] = useState(defaultExpanded);
|
|
2480
2676
|
const itemRef = useRef(null);
|
|
2481
2677
|
const isDir = Array.isArray(node.children) && node.children.length > 0;
|
|
2482
2678
|
const isFocused = flatIndex === focusedIndex;
|
|
2679
|
+
const path = parentPath ? `${parentPath}/${node.name}` : node.name;
|
|
2483
2680
|
const handleToggle = useCallback(() => {
|
|
2484
|
-
if (isDir)
|
|
2485
|
-
|
|
2681
|
+
if (isDir) {
|
|
2682
|
+
setExpanded((prev) => {
|
|
2683
|
+
onSelect?.(path, "directory", !prev);
|
|
2684
|
+
return !prev;
|
|
2685
|
+
});
|
|
2686
|
+
} else {
|
|
2687
|
+
onSelect?.(path, "file");
|
|
2688
|
+
}
|
|
2689
|
+
}, [isDir, path, onSelect]);
|
|
2486
2690
|
const handleKeyDown = useCallback(
|
|
2487
2691
|
(e) => {
|
|
2488
2692
|
let handled = true;
|
|
@@ -2614,7 +2818,9 @@ function TreeItem({
|
|
|
2614
2818
|
setSize: node.children?.length ?? 0,
|
|
2615
2819
|
posInSet: childIdx + 1,
|
|
2616
2820
|
onFocusChange,
|
|
2617
|
-
flatItems
|
|
2821
|
+
flatItems,
|
|
2822
|
+
parentPath: path,
|
|
2823
|
+
onSelect
|
|
2618
2824
|
},
|
|
2619
2825
|
child.name
|
|
2620
2826
|
);
|
|
@@ -2647,7 +2853,11 @@ function getChildFlatIndex(flatItems, parentFlatIndex, childIdx, children) {
|
|
|
2647
2853
|
}
|
|
2648
2854
|
return parentFlatIndex + childIdx + 1;
|
|
2649
2855
|
}
|
|
2650
|
-
function FileTree({
|
|
2856
|
+
function FileTree({
|
|
2857
|
+
data,
|
|
2858
|
+
block,
|
|
2859
|
+
onInteraction
|
|
2860
|
+
}) {
|
|
2651
2861
|
const [focusedIndex, setFocusedIndex] = useState(0);
|
|
2652
2862
|
const containerRef = useRef(null);
|
|
2653
2863
|
const flatItems = flattenTree(data.tree, data.root ? 1 : 0);
|
|
@@ -2658,6 +2868,18 @@ function FileTree({ data }) {
|
|
|
2658
2868
|
const el = container.querySelector(`[data-flat-index="${String(index)}"]`);
|
|
2659
2869
|
el?.focus();
|
|
2660
2870
|
}, []);
|
|
2871
|
+
const handleSelect = useCallback(
|
|
2872
|
+
(path, type, expanded) => {
|
|
2873
|
+
onInteraction?.({
|
|
2874
|
+
kind: "filetree-select",
|
|
2875
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2876
|
+
blockId: block.id,
|
|
2877
|
+
blockType: block.type,
|
|
2878
|
+
payload: { path, type, expanded }
|
|
2879
|
+
});
|
|
2880
|
+
},
|
|
2881
|
+
[onInteraction, block.id, block.type]
|
|
2882
|
+
);
|
|
2661
2883
|
return /* @__PURE__ */ jsx(
|
|
2662
2884
|
"div",
|
|
2663
2885
|
{
|
|
@@ -2714,7 +2936,9 @@ function FileTree({ data }) {
|
|
|
2714
2936
|
setSize: data.tree.length,
|
|
2715
2937
|
posInSet: idx + 1,
|
|
2716
2938
|
onFocusChange: handleFocusChange,
|
|
2717
|
-
flatItems
|
|
2939
|
+
flatItems,
|
|
2940
|
+
parentPath: data.root ?? "",
|
|
2941
|
+
onSelect: handleSelect
|
|
2718
2942
|
},
|
|
2719
2943
|
node.name
|
|
2720
2944
|
);
|
|
@@ -2735,7 +2959,9 @@ function FileTree({ data }) {
|
|
|
2735
2959
|
setSize: data.tree.length,
|
|
2736
2960
|
posInSet: idx + 1,
|
|
2737
2961
|
onFocusChange: handleFocusChange,
|
|
2738
|
-
flatItems
|
|
2962
|
+
flatItems,
|
|
2963
|
+
parentPath: "",
|
|
2964
|
+
onSelect: handleSelect
|
|
2739
2965
|
},
|
|
2740
2966
|
node.name
|
|
2741
2967
|
);
|
|
@@ -3983,7 +4209,117 @@ function isCorrect(question, selected) {
|
|
|
3983
4209
|
}
|
|
3984
4210
|
}
|
|
3985
4211
|
}
|
|
3986
|
-
function
|
|
4212
|
+
function renderMultipleChoice(question, qIndex, state, updateState, baseId) {
|
|
4213
|
+
const selected = typeof state.selected === "number" ? state.selected : null;
|
|
4214
|
+
const ariaLabel = typeof question.question === "string" ? question.question : "Question";
|
|
4215
|
+
return /* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": ariaLabel, children: question.options.map((option, oIndex) => {
|
|
4216
|
+
const isSelected = selected === oIndex;
|
|
4217
|
+
const isCorrectOption = state.submitted && oIndex === question.answer;
|
|
4218
|
+
const isIncorrectSelection = state.submitted && isSelected && oIndex !== question.answer;
|
|
4219
|
+
return /* @__PURE__ */ jsxs(
|
|
4220
|
+
"label",
|
|
4221
|
+
{
|
|
4222
|
+
style: optionLabelStyle(
|
|
4223
|
+
isSelected,
|
|
4224
|
+
state.submitted,
|
|
4225
|
+
isCorrectOption,
|
|
4226
|
+
isIncorrectSelection
|
|
4227
|
+
),
|
|
4228
|
+
children: [
|
|
4229
|
+
/* @__PURE__ */ jsx(
|
|
4230
|
+
"input",
|
|
4231
|
+
{
|
|
4232
|
+
type: "radio",
|
|
4233
|
+
role: "radio",
|
|
4234
|
+
name: `${baseId}-q${String(qIndex)}`,
|
|
4235
|
+
checked: isSelected,
|
|
4236
|
+
disabled: state.submitted,
|
|
4237
|
+
onChange: () => updateState(qIndex, { selected: oIndex }),
|
|
4238
|
+
"aria-checked": isSelected
|
|
4239
|
+
}
|
|
4240
|
+
),
|
|
4241
|
+
/* @__PURE__ */ jsx(RichText, { content: option })
|
|
4242
|
+
]
|
|
4243
|
+
},
|
|
4244
|
+
oIndex
|
|
4245
|
+
);
|
|
4246
|
+
}) });
|
|
4247
|
+
}
|
|
4248
|
+
function renderTrueFalse(question, qIndex, state, updateState, baseId) {
|
|
4249
|
+
const selected = typeof state.selected === "boolean" ? state.selected : null;
|
|
4250
|
+
const ariaLabel = typeof question.question === "string" ? question.question : "Question";
|
|
4251
|
+
return /* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": ariaLabel, children: [true, false].map((value) => {
|
|
4252
|
+
const isSelected = selected === value;
|
|
4253
|
+
const isCorrectOption = state.submitted && value === question.answer;
|
|
4254
|
+
const isIncorrectSelection = state.submitted && isSelected && value !== question.answer;
|
|
4255
|
+
return /* @__PURE__ */ jsxs(
|
|
4256
|
+
"label",
|
|
4257
|
+
{
|
|
4258
|
+
style: optionLabelStyle(
|
|
4259
|
+
isSelected,
|
|
4260
|
+
state.submitted,
|
|
4261
|
+
isCorrectOption,
|
|
4262
|
+
isIncorrectSelection
|
|
4263
|
+
),
|
|
4264
|
+
children: [
|
|
4265
|
+
/* @__PURE__ */ jsx(
|
|
4266
|
+
"input",
|
|
4267
|
+
{
|
|
4268
|
+
type: "radio",
|
|
4269
|
+
role: "radio",
|
|
4270
|
+
name: `${baseId}-q${String(qIndex)}`,
|
|
4271
|
+
checked: isSelected,
|
|
4272
|
+
disabled: state.submitted,
|
|
4273
|
+
onChange: () => updateState(qIndex, { selected: value }),
|
|
4274
|
+
"aria-checked": isSelected
|
|
4275
|
+
}
|
|
4276
|
+
),
|
|
4277
|
+
value ? "True" : "False"
|
|
4278
|
+
]
|
|
4279
|
+
},
|
|
4280
|
+
String(value)
|
|
4281
|
+
);
|
|
4282
|
+
}) });
|
|
4283
|
+
}
|
|
4284
|
+
function renderMultiSelect(question, qIndex, state, updateState) {
|
|
4285
|
+
const selected = Array.isArray(state.selected) ? state.selected : [];
|
|
4286
|
+
const toggleOption = (oIndex) => {
|
|
4287
|
+
const next = selected.includes(oIndex) ? selected.filter((v) => v !== oIndex) : [...selected, oIndex];
|
|
4288
|
+
updateState(qIndex, { selected: next });
|
|
4289
|
+
};
|
|
4290
|
+
return /* @__PURE__ */ jsx("div", { children: question.options.map((option, oIndex) => {
|
|
4291
|
+
const isSelected = selected.includes(oIndex);
|
|
4292
|
+
const isCorrectOption = state.submitted && question.answer.includes(oIndex);
|
|
4293
|
+
const isIncorrectSelection = state.submitted && isSelected && !question.answer.includes(oIndex);
|
|
4294
|
+
return /* @__PURE__ */ jsxs(
|
|
4295
|
+
"label",
|
|
4296
|
+
{
|
|
4297
|
+
style: optionLabelStyle(
|
|
4298
|
+
isSelected,
|
|
4299
|
+
state.submitted,
|
|
4300
|
+
isCorrectOption,
|
|
4301
|
+
isIncorrectSelection
|
|
4302
|
+
),
|
|
4303
|
+
children: [
|
|
4304
|
+
/* @__PURE__ */ jsx(
|
|
4305
|
+
"input",
|
|
4306
|
+
{
|
|
4307
|
+
type: "checkbox",
|
|
4308
|
+
role: "checkbox",
|
|
4309
|
+
checked: isSelected,
|
|
4310
|
+
disabled: state.submitted,
|
|
4311
|
+
onChange: () => toggleOption(oIndex),
|
|
4312
|
+
"aria-checked": isSelected
|
|
4313
|
+
}
|
|
4314
|
+
),
|
|
4315
|
+
/* @__PURE__ */ jsx(RichText, { content: option })
|
|
4316
|
+
]
|
|
4317
|
+
},
|
|
4318
|
+
oIndex
|
|
4319
|
+
);
|
|
4320
|
+
}) });
|
|
4321
|
+
}
|
|
4322
|
+
function Quiz({ data, block, onInteraction }) {
|
|
3987
4323
|
const { questions, showScore = true, title } = data;
|
|
3988
4324
|
const baseId = `glyph-quiz-${block.id}`;
|
|
3989
4325
|
const [states, setStates] = useState(
|
|
@@ -4001,114 +4337,6 @@ function Quiz({ data, block }) {
|
|
|
4001
4337
|
return acc + (isCorrect(q, s.selected) ? 1 : 0);
|
|
4002
4338
|
}, 0);
|
|
4003
4339
|
const submittedCount = states.filter((s) => s.submitted).length;
|
|
4004
|
-
function renderMultipleChoice(question, qIndex, state) {
|
|
4005
|
-
const selected = typeof state.selected === "number" ? state.selected : null;
|
|
4006
|
-
return /* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": question.question, children: question.options.map((option, oIndex) => {
|
|
4007
|
-
const isSelected = selected === oIndex;
|
|
4008
|
-
const isCorrectOption = state.submitted && oIndex === question.answer;
|
|
4009
|
-
const isIncorrectSelection = state.submitted && isSelected && oIndex !== question.answer;
|
|
4010
|
-
return /* @__PURE__ */ jsxs(
|
|
4011
|
-
"label",
|
|
4012
|
-
{
|
|
4013
|
-
style: optionLabelStyle(
|
|
4014
|
-
isSelected,
|
|
4015
|
-
state.submitted,
|
|
4016
|
-
isCorrectOption,
|
|
4017
|
-
isIncorrectSelection
|
|
4018
|
-
),
|
|
4019
|
-
children: [
|
|
4020
|
-
/* @__PURE__ */ jsx(
|
|
4021
|
-
"input",
|
|
4022
|
-
{
|
|
4023
|
-
type: "radio",
|
|
4024
|
-
role: "radio",
|
|
4025
|
-
name: `${baseId}-q${String(qIndex)}`,
|
|
4026
|
-
checked: isSelected,
|
|
4027
|
-
disabled: state.submitted,
|
|
4028
|
-
onChange: () => updateState(qIndex, { selected: oIndex }),
|
|
4029
|
-
"aria-checked": isSelected
|
|
4030
|
-
}
|
|
4031
|
-
),
|
|
4032
|
-
option
|
|
4033
|
-
]
|
|
4034
|
-
},
|
|
4035
|
-
oIndex
|
|
4036
|
-
);
|
|
4037
|
-
}) });
|
|
4038
|
-
}
|
|
4039
|
-
function renderTrueFalse(question, qIndex, state) {
|
|
4040
|
-
const selected = typeof state.selected === "boolean" ? state.selected : null;
|
|
4041
|
-
return /* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": question.question, children: [true, false].map((value) => {
|
|
4042
|
-
const isSelected = selected === value;
|
|
4043
|
-
const isCorrectOption = state.submitted && value === question.answer;
|
|
4044
|
-
const isIncorrectSelection = state.submitted && isSelected && value !== question.answer;
|
|
4045
|
-
return /* @__PURE__ */ jsxs(
|
|
4046
|
-
"label",
|
|
4047
|
-
{
|
|
4048
|
-
style: optionLabelStyle(
|
|
4049
|
-
isSelected,
|
|
4050
|
-
state.submitted,
|
|
4051
|
-
isCorrectOption,
|
|
4052
|
-
isIncorrectSelection
|
|
4053
|
-
),
|
|
4054
|
-
children: [
|
|
4055
|
-
/* @__PURE__ */ jsx(
|
|
4056
|
-
"input",
|
|
4057
|
-
{
|
|
4058
|
-
type: "radio",
|
|
4059
|
-
role: "radio",
|
|
4060
|
-
name: `${baseId}-q${String(qIndex)}`,
|
|
4061
|
-
checked: isSelected,
|
|
4062
|
-
disabled: state.submitted,
|
|
4063
|
-
onChange: () => updateState(qIndex, { selected: value }),
|
|
4064
|
-
"aria-checked": isSelected
|
|
4065
|
-
}
|
|
4066
|
-
),
|
|
4067
|
-
value ? "True" : "False"
|
|
4068
|
-
]
|
|
4069
|
-
},
|
|
4070
|
-
String(value)
|
|
4071
|
-
);
|
|
4072
|
-
}) });
|
|
4073
|
-
}
|
|
4074
|
-
function renderMultiSelect(question, qIndex, state) {
|
|
4075
|
-
const selected = Array.isArray(state.selected) ? state.selected : [];
|
|
4076
|
-
const toggleOption = (oIndex) => {
|
|
4077
|
-
const next = selected.includes(oIndex) ? selected.filter((v) => v !== oIndex) : [...selected, oIndex];
|
|
4078
|
-
updateState(qIndex, { selected: next });
|
|
4079
|
-
};
|
|
4080
|
-
return /* @__PURE__ */ jsx("div", { children: question.options.map((option, oIndex) => {
|
|
4081
|
-
const isSelected = selected.includes(oIndex);
|
|
4082
|
-
const isCorrectOption = state.submitted && question.answer.includes(oIndex);
|
|
4083
|
-
const isIncorrectSelection = state.submitted && isSelected && !question.answer.includes(oIndex);
|
|
4084
|
-
return /* @__PURE__ */ jsxs(
|
|
4085
|
-
"label",
|
|
4086
|
-
{
|
|
4087
|
-
style: optionLabelStyle(
|
|
4088
|
-
isSelected,
|
|
4089
|
-
state.submitted,
|
|
4090
|
-
isCorrectOption,
|
|
4091
|
-
isIncorrectSelection
|
|
4092
|
-
),
|
|
4093
|
-
children: [
|
|
4094
|
-
/* @__PURE__ */ jsx(
|
|
4095
|
-
"input",
|
|
4096
|
-
{
|
|
4097
|
-
type: "checkbox",
|
|
4098
|
-
role: "checkbox",
|
|
4099
|
-
checked: isSelected,
|
|
4100
|
-
disabled: state.submitted,
|
|
4101
|
-
onChange: () => toggleOption(oIndex),
|
|
4102
|
-
"aria-checked": isSelected
|
|
4103
|
-
}
|
|
4104
|
-
),
|
|
4105
|
-
option
|
|
4106
|
-
]
|
|
4107
|
-
},
|
|
4108
|
-
oIndex
|
|
4109
|
-
);
|
|
4110
|
-
}) });
|
|
4111
|
-
}
|
|
4112
4340
|
function renderQuestion(question, qIndex) {
|
|
4113
4341
|
const state = states[qIndex] ?? { selected: null, submitted: false };
|
|
4114
4342
|
const isLast = qIndex === questions.length - 1;
|
|
@@ -4123,24 +4351,69 @@ function Quiz({ data, block }) {
|
|
|
4123
4351
|
children: [
|
|
4124
4352
|
/* @__PURE__ */ jsxs("div", { style: questionTextStyle, children: [
|
|
4125
4353
|
questions.length > 1 ? `${String(qIndex + 1)}. ` : "",
|
|
4126
|
-
question.question
|
|
4354
|
+
/* @__PURE__ */ jsx(RichText, { content: question.question })
|
|
4127
4355
|
] }),
|
|
4128
|
-
question.type === "multiple-choice" && renderMultipleChoice(question, qIndex, state),
|
|
4129
|
-
question.type === "true-false" && renderTrueFalse(question, qIndex, state),
|
|
4130
|
-
question.type === "multi-select" && renderMultiSelect(question, qIndex, state),
|
|
4356
|
+
question.type === "multiple-choice" && renderMultipleChoice(question, qIndex, state, updateState, baseId),
|
|
4357
|
+
question.type === "true-false" && renderTrueFalse(question, qIndex, state, updateState, baseId),
|
|
4358
|
+
question.type === "multi-select" && renderMultiSelect(question, qIndex, state, updateState),
|
|
4131
4359
|
!state.submitted && /* @__PURE__ */ jsx(
|
|
4132
4360
|
"button",
|
|
4133
4361
|
{
|
|
4134
4362
|
type: "button",
|
|
4135
4363
|
disabled: !hasSelection,
|
|
4136
4364
|
style: buttonStyle(!hasSelection),
|
|
4137
|
-
onClick: () =>
|
|
4365
|
+
onClick: () => {
|
|
4366
|
+
updateState(qIndex, { submitted: true });
|
|
4367
|
+
if (onInteraction) {
|
|
4368
|
+
const correct2 = isCorrect(question, state.selected);
|
|
4369
|
+
const newScore = states.reduce((acc, s, i) => {
|
|
4370
|
+
if (i === qIndex) return acc + (correct2 ? 1 : 0);
|
|
4371
|
+
const q = questions[i];
|
|
4372
|
+
if (!q || !s.submitted) return acc;
|
|
4373
|
+
return acc + (isCorrect(q, s.selected) ? 1 : 0);
|
|
4374
|
+
}, 0);
|
|
4375
|
+
let selected;
|
|
4376
|
+
switch (question.type) {
|
|
4377
|
+
case "multiple-choice":
|
|
4378
|
+
if (typeof state.selected === "number") {
|
|
4379
|
+
const opt = question.options[state.selected];
|
|
4380
|
+
selected = [typeof opt === "string" ? opt : String(state.selected)];
|
|
4381
|
+
} else {
|
|
4382
|
+
selected = [];
|
|
4383
|
+
}
|
|
4384
|
+
break;
|
|
4385
|
+
case "true-false":
|
|
4386
|
+
selected = typeof state.selected === "boolean" ? [state.selected ? "True" : "False"] : [];
|
|
4387
|
+
break;
|
|
4388
|
+
case "multi-select":
|
|
4389
|
+
selected = Array.isArray(state.selected) ? state.selected.map((idx) => {
|
|
4390
|
+
const opt = question.options[idx];
|
|
4391
|
+
return typeof opt === "string" ? opt : String(idx);
|
|
4392
|
+
}) : [];
|
|
4393
|
+
break;
|
|
4394
|
+
}
|
|
4395
|
+
const questionText = typeof question.question === "string" ? question.question : "Question";
|
|
4396
|
+
onInteraction({
|
|
4397
|
+
kind: "quiz-submit",
|
|
4398
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4399
|
+
blockId: block.id,
|
|
4400
|
+
blockType: block.type,
|
|
4401
|
+
payload: {
|
|
4402
|
+
questionIndex: qIndex,
|
|
4403
|
+
question: questionText,
|
|
4404
|
+
selected,
|
|
4405
|
+
correct: correct2,
|
|
4406
|
+
score: { correct: newScore, total: questions.length }
|
|
4407
|
+
}
|
|
4408
|
+
});
|
|
4409
|
+
}
|
|
4410
|
+
},
|
|
4138
4411
|
children: "Submit"
|
|
4139
4412
|
}
|
|
4140
4413
|
),
|
|
4141
4414
|
/* @__PURE__ */ jsxs("div", { "aria-live": "polite", children: [
|
|
4142
4415
|
state.submitted && /* @__PURE__ */ jsx("div", { style: feedbackStyle(correct), children: correct ? "Correct!" : "Incorrect" }),
|
|
4143
|
-
state.submitted && question.explanation && /* @__PURE__ */ jsx("div", { style: explanationStyle, children: question.explanation })
|
|
4416
|
+
state.submitted && question.explanation && /* @__PURE__ */ jsx("div", { style: explanationStyle, children: /* @__PURE__ */ jsx(RichText, { content: question.explanation }) })
|
|
4144
4417
|
] })
|
|
4145
4418
|
]
|
|
4146
4419
|
},
|
|
@@ -4197,7 +4470,7 @@ function Card({ data, block, container }) {
|
|
|
4197
4470
|
default:
|
|
4198
4471
|
colCount = authorCols;
|
|
4199
4472
|
}
|
|
4200
|
-
const
|
|
4473
|
+
const containerStyle11 = {
|
|
4201
4474
|
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
4202
4475
|
color: "var(--glyph-text, #1a2035)"
|
|
4203
4476
|
};
|
|
@@ -4242,7 +4515,7 @@ function Card({ data, block, container }) {
|
|
|
4242
4515
|
color: "var(--glyph-text-muted, #6b7a94)",
|
|
4243
4516
|
marginTop: "var(--glyph-spacing-xs, 0.25rem)"
|
|
4244
4517
|
};
|
|
4245
|
-
const
|
|
4518
|
+
const bodyStyle3 = {
|
|
4246
4519
|
fontSize: "0.875rem",
|
|
4247
4520
|
lineHeight: 1.6,
|
|
4248
4521
|
marginTop: "var(--glyph-spacing-sm, 0.5rem)",
|
|
@@ -4260,7 +4533,7 @@ function Card({ data, block, container }) {
|
|
|
4260
4533
|
color: "var(--glyph-link, #0a9d7c)",
|
|
4261
4534
|
textDecoration: "none"
|
|
4262
4535
|
};
|
|
4263
|
-
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Cards", style:
|
|
4536
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Cards", style: containerStyle11, children: [
|
|
4264
4537
|
title && /* @__PURE__ */ jsx(
|
|
4265
4538
|
"div",
|
|
4266
4539
|
{
|
|
@@ -4278,8 +4551,8 @@ function Card({ data, block, container }) {
|
|
|
4278
4551
|
/* @__PURE__ */ jsxs("div", { style: cardBodyStyle, children: [
|
|
4279
4552
|
card.icon && /* @__PURE__ */ jsx("div", { style: iconStyle, children: card.icon }),
|
|
4280
4553
|
/* @__PURE__ */ jsx("h3", { style: titleStyle2, children: card.title }),
|
|
4281
|
-
card.subtitle && /* @__PURE__ */ jsx("div", { style: subtitleStyle, children: card.subtitle }),
|
|
4282
|
-
card.body && /* @__PURE__ */ jsx("div", { style:
|
|
4554
|
+
card.subtitle && /* @__PURE__ */ jsx("div", { style: subtitleStyle, children: /* @__PURE__ */ jsx(RichText, { content: card.subtitle }) }),
|
|
4555
|
+
card.body && /* @__PURE__ */ jsx("div", { style: bodyStyle3, children: /* @__PURE__ */ jsx(RichText, { content: card.body }) }),
|
|
4283
4556
|
card.actions && card.actions.length > 0 && /* @__PURE__ */ jsx("div", { style: actionsStyle, children: card.actions.map((action, j) => /* @__PURE__ */ jsx(
|
|
4284
4557
|
"a",
|
|
4285
4558
|
{
|
|
@@ -4369,7 +4642,7 @@ function renderStatGroup(items, keyPrefix) {
|
|
|
4369
4642
|
color: "var(--glyph-infographic-value-color, #1d4ed8)",
|
|
4370
4643
|
lineHeight: 1.2
|
|
4371
4644
|
};
|
|
4372
|
-
const
|
|
4645
|
+
const labelStyle4 = {
|
|
4373
4646
|
fontSize: "0.8125rem",
|
|
4374
4647
|
color: "var(--glyph-infographic-label-color, #475569)",
|
|
4375
4648
|
marginTop: "var(--glyph-spacing-xs, 0.25rem)",
|
|
@@ -4385,8 +4658,8 @@ function renderStatGroup(items, keyPrefix) {
|
|
|
4385
4658
|
};
|
|
4386
4659
|
return /* @__PURE__ */ jsx("div", { style: rowStyle, "data-group": "stat", children: items.map((item, i) => /* @__PURE__ */ jsxs("div", { style: statStyle, children: [
|
|
4387
4660
|
/* @__PURE__ */ jsx("div", { style: valueStyle, children: item.value }),
|
|
4388
|
-
/* @__PURE__ */ jsx("div", { style:
|
|
4389
|
-
item.description && /* @__PURE__ */ jsx("div", { style: descStyle, children: item.description })
|
|
4661
|
+
/* @__PURE__ */ jsx("div", { style: labelStyle4, children: item.label }),
|
|
4662
|
+
item.description && /* @__PURE__ */ jsx("div", { style: descStyle, children: /* @__PURE__ */ jsx(RichText, { content: item.description }) })
|
|
4390
4663
|
] }, `${keyPrefix}-${String(i)}`)) }, keyPrefix);
|
|
4391
4664
|
}
|
|
4392
4665
|
function renderProgressGroup(items, keyPrefix, colorOffset) {
|
|
@@ -4456,18 +4729,18 @@ function renderProgressGroup(items, keyPrefix, colorOffset) {
|
|
|
4456
4729
|
}) }, keyPrefix);
|
|
4457
4730
|
}
|
|
4458
4731
|
function renderFactGroup(items, keyPrefix) {
|
|
4459
|
-
const
|
|
4732
|
+
const listStyle2 = {
|
|
4460
4733
|
listStyle: "none",
|
|
4461
4734
|
margin: 0,
|
|
4462
4735
|
padding: 0
|
|
4463
4736
|
};
|
|
4464
|
-
const
|
|
4737
|
+
const itemStyle4 = {
|
|
4465
4738
|
padding: "var(--glyph-spacing-xs, 0.25rem) 0",
|
|
4466
4739
|
fontSize: "0.875rem",
|
|
4467
4740
|
color: "var(--glyph-text, #1a2035)",
|
|
4468
4741
|
fontWeight: 500
|
|
4469
4742
|
};
|
|
4470
|
-
return /* @__PURE__ */ jsx("ul", { style:
|
|
4743
|
+
return /* @__PURE__ */ jsx("ul", { style: listStyle2, "data-group": "fact", children: items.map((item, i) => /* @__PURE__ */ jsxs("li", { style: itemStyle4, children: [
|
|
4471
4744
|
item.icon && /* @__PURE__ */ jsx(
|
|
4472
4745
|
"span",
|
|
4473
4746
|
{
|
|
@@ -4479,7 +4752,7 @@ function renderFactGroup(items, keyPrefix) {
|
|
|
4479
4752
|
children: item.icon
|
|
4480
4753
|
}
|
|
4481
4754
|
),
|
|
4482
|
-
item.text
|
|
4755
|
+
/* @__PURE__ */ jsx(RichText, { content: item.text })
|
|
4483
4756
|
] }, `${keyPrefix}-${String(i)}`)) }, keyPrefix);
|
|
4484
4757
|
}
|
|
4485
4758
|
function renderTextGroup(items, keyPrefix) {
|
|
@@ -4744,7 +5017,7 @@ function Infographic({
|
|
|
4744
5017
|
const baseId = `glyph-infographic-${block.id}`;
|
|
4745
5018
|
const useGrid = sections.length >= 2 && container.tier !== "compact";
|
|
4746
5019
|
const sectionLayouts = useMemo(() => computeSectionLayout(sections), [sections]);
|
|
4747
|
-
const
|
|
5020
|
+
const containerStyle11 = {
|
|
4748
5021
|
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
4749
5022
|
color: "var(--glyph-text, #1a2035)",
|
|
4750
5023
|
background: "var(--glyph-surface, #e8ecf3)",
|
|
@@ -4789,7 +5062,7 @@ function Infographic({
|
|
|
4789
5062
|
};
|
|
4790
5063
|
const printCss = useGrid ? `@media print { #${CSS.escape(baseId)} [data-layout="grid"] { display: grid !important; grid-template-columns: repeat(2, 1fr) !important; gap: 0.5rem !important; } #${CSS.escape(baseId)} [data-layout="grid"] > div { break-inside: avoid; } }` : "";
|
|
4791
5064
|
let progressColorOffset = 0;
|
|
4792
|
-
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Infographic", style:
|
|
5065
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Infographic", style: containerStyle11, children: [
|
|
4793
5066
|
printCss && /* @__PURE__ */ jsx("style", { children: printCss }),
|
|
4794
5067
|
/* @__PURE__ */ jsxs("div", { "data-layout": useGrid ? "grid" : "stack", style: useGrid ? sectionsGridStyle : void 0, children: [
|
|
4795
5068
|
title && /* @__PURE__ */ jsx("div", { style: titleStyle2, children: title }),
|
|
@@ -4850,6 +5123,1749 @@ var infographicDefinition = {
|
|
|
4850
5123
|
render: Infographic
|
|
4851
5124
|
};
|
|
4852
5125
|
|
|
4853
|
-
|
|
5126
|
+
// src/poll/styles.ts
|
|
5127
|
+
var containerStyle3 = {
|
|
5128
|
+
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
5129
|
+
color: "var(--glyph-text, #1a2035)",
|
|
5130
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5131
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
5132
|
+
overflow: "hidden"
|
|
5133
|
+
};
|
|
5134
|
+
var headerStyle2 = {
|
|
5135
|
+
fontWeight: 700,
|
|
5136
|
+
fontSize: "1.125rem",
|
|
5137
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
5138
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5139
|
+
color: "var(--glyph-heading, #0a0e1a)"
|
|
5140
|
+
};
|
|
5141
|
+
var questionStyle = {
|
|
5142
|
+
fontWeight: 600,
|
|
5143
|
+
fontSize: "0.9375rem",
|
|
5144
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
5145
|
+
paddingBottom: "0.5rem"
|
|
5146
|
+
};
|
|
5147
|
+
var optionsStyle = {
|
|
5148
|
+
padding: "0 var(--glyph-spacing-md, 1rem)",
|
|
5149
|
+
paddingBottom: "var(--glyph-spacing-md, 1rem)"
|
|
5150
|
+
};
|
|
5151
|
+
function optionLabelStyle2(selected) {
|
|
5152
|
+
return {
|
|
5153
|
+
display: "flex",
|
|
5154
|
+
alignItems: "center",
|
|
5155
|
+
gap: "0.5rem",
|
|
5156
|
+
padding: "0.5rem 0.75rem",
|
|
5157
|
+
marginBottom: "0.375rem",
|
|
5158
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
5159
|
+
cursor: "pointer",
|
|
5160
|
+
background: selected ? "var(--glyph-surface, #e8ecf3)" : "transparent",
|
|
5161
|
+
border: "1px solid",
|
|
5162
|
+
borderColor: selected ? "var(--glyph-border, #d0d8e4)" : "transparent",
|
|
5163
|
+
fontSize: "0.875rem",
|
|
5164
|
+
lineHeight: 1.6
|
|
5165
|
+
};
|
|
5166
|
+
}
|
|
5167
|
+
var voteButtonStyle = {
|
|
5168
|
+
margin: "0 var(--glyph-spacing-md, 1rem) var(--glyph-spacing-md, 1rem)",
|
|
5169
|
+
padding: "0.5rem 1.25rem",
|
|
5170
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
5171
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5172
|
+
background: "var(--glyph-surface, #e8ecf3)",
|
|
5173
|
+
color: "var(--glyph-text, #1a2035)",
|
|
5174
|
+
cursor: "pointer",
|
|
5175
|
+
fontWeight: 600,
|
|
5176
|
+
fontSize: "0.875rem"
|
|
5177
|
+
};
|
|
5178
|
+
var resultsStyle = {
|
|
5179
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
5180
|
+
borderTop: "1px solid var(--glyph-border, #d0d8e4)"
|
|
5181
|
+
};
|
|
5182
|
+
var resultRowStyle = {
|
|
5183
|
+
marginBottom: "0.5rem"
|
|
5184
|
+
};
|
|
5185
|
+
var resultLabelStyle = {
|
|
5186
|
+
display: "flex",
|
|
5187
|
+
justifyContent: "space-between",
|
|
5188
|
+
fontSize: "0.8125rem",
|
|
5189
|
+
marginBottom: "0.25rem"
|
|
5190
|
+
};
|
|
5191
|
+
var barTrackStyle = {
|
|
5192
|
+
height: "0.5rem",
|
|
5193
|
+
borderRadius: "0.25rem",
|
|
5194
|
+
background: "var(--glyph-poll-bar-bg, var(--glyph-surface, #e8ecf3))",
|
|
5195
|
+
overflow: "hidden"
|
|
5196
|
+
};
|
|
5197
|
+
function barFillStyle(percentage) {
|
|
5198
|
+
return {
|
|
5199
|
+
height: "100%",
|
|
5200
|
+
width: `${String(percentage)}%`,
|
|
5201
|
+
borderRadius: "0.25rem",
|
|
5202
|
+
background: "var(--glyph-poll-bar-fill, var(--glyph-accent, #0a9d7c))",
|
|
5203
|
+
transition: "width 0.3s ease"
|
|
5204
|
+
};
|
|
5205
|
+
}
|
|
5206
|
+
function Poll({ data, block, onInteraction }) {
|
|
5207
|
+
const { question, options, multiple = false, showResults = true, title } = data;
|
|
5208
|
+
const baseId = `glyph-poll-${block.id}`;
|
|
5209
|
+
const [selected, setSelected] = useState([]);
|
|
5210
|
+
const [votes, setVotes] = useState(() => options.map(() => 0));
|
|
5211
|
+
const [hasVoted, setHasVoted] = useState(false);
|
|
5212
|
+
const toggleOption = (index) => {
|
|
5213
|
+
if (hasVoted) return;
|
|
5214
|
+
if (multiple) {
|
|
5215
|
+
setSelected(
|
|
5216
|
+
(prev) => prev.includes(index) ? prev.filter((i) => i !== index) : [...prev, index]
|
|
5217
|
+
);
|
|
5218
|
+
} else {
|
|
5219
|
+
setSelected([index]);
|
|
5220
|
+
}
|
|
5221
|
+
};
|
|
5222
|
+
const handleVote = () => {
|
|
5223
|
+
if (selected.length === 0 || hasVoted) return;
|
|
5224
|
+
const newVotes = [...votes];
|
|
5225
|
+
for (const idx of selected) {
|
|
5226
|
+
newVotes[idx] = (newVotes[idx] ?? 0) + 1;
|
|
5227
|
+
}
|
|
5228
|
+
setVotes(newVotes);
|
|
5229
|
+
setHasVoted(true);
|
|
5230
|
+
if (onInteraction) {
|
|
5231
|
+
onInteraction({
|
|
5232
|
+
kind: "poll-vote",
|
|
5233
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5234
|
+
blockId: block.id,
|
|
5235
|
+
blockType: block.type,
|
|
5236
|
+
payload: {
|
|
5237
|
+
selectedOptions: selected.map((i) => {
|
|
5238
|
+
const opt = options[i];
|
|
5239
|
+
return typeof opt === "string" ? opt : String(i);
|
|
5240
|
+
}),
|
|
5241
|
+
selectedIndices: [...selected]
|
|
5242
|
+
}
|
|
5243
|
+
});
|
|
5244
|
+
}
|
|
5245
|
+
};
|
|
5246
|
+
const totalVotes = votes.reduce((a, b) => a + b, 0);
|
|
5247
|
+
const questionAriaLabel = typeof question === "string" ? question : "Poll question";
|
|
5248
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Poll", style: containerStyle3, children: [
|
|
5249
|
+
title && /* @__PURE__ */ jsx("div", { style: headerStyle2, children: title }),
|
|
5250
|
+
/* @__PURE__ */ jsx("div", { style: questionStyle, children: /* @__PURE__ */ jsx(RichText, { content: question }) }),
|
|
5251
|
+
/* @__PURE__ */ jsx("div", { role: "group", "aria-label": questionAriaLabel, style: optionsStyle, children: options.map((option, index) => /* @__PURE__ */ jsxs("label", { style: optionLabelStyle2(selected.includes(index)), children: [
|
|
5252
|
+
/* @__PURE__ */ jsx(
|
|
5253
|
+
"input",
|
|
5254
|
+
{
|
|
5255
|
+
type: multiple ? "checkbox" : "radio",
|
|
5256
|
+
name: `${baseId}-option`,
|
|
5257
|
+
checked: selected.includes(index),
|
|
5258
|
+
disabled: hasVoted,
|
|
5259
|
+
onChange: () => toggleOption(index),
|
|
5260
|
+
"aria-checked": selected.includes(index)
|
|
5261
|
+
}
|
|
5262
|
+
),
|
|
5263
|
+
/* @__PURE__ */ jsx(RichText, { content: option })
|
|
5264
|
+
] }, index)) }),
|
|
5265
|
+
!hasVoted && /* @__PURE__ */ jsx(
|
|
5266
|
+
"button",
|
|
5267
|
+
{
|
|
5268
|
+
type: "button",
|
|
5269
|
+
disabled: selected.length === 0,
|
|
5270
|
+
style: {
|
|
5271
|
+
...voteButtonStyle,
|
|
5272
|
+
opacity: selected.length === 0 ? 0.5 : 1,
|
|
5273
|
+
cursor: selected.length === 0 ? "not-allowed" : "pointer"
|
|
5274
|
+
},
|
|
5275
|
+
onClick: handleVote,
|
|
5276
|
+
children: "Vote"
|
|
5277
|
+
}
|
|
5278
|
+
),
|
|
5279
|
+
showResults && hasVoted && /* @__PURE__ */ jsx("div", { role: "status", "aria-live": "polite", style: resultsStyle, children: options.map((option, index) => {
|
|
5280
|
+
const count = votes[index] ?? 0;
|
|
5281
|
+
const percentage = totalVotes > 0 ? count / totalVotes * 100 : 0;
|
|
5282
|
+
const optionLabel = typeof option === "string" ? option : "Option";
|
|
5283
|
+
return /* @__PURE__ */ jsxs("div", { style: resultRowStyle, children: [
|
|
5284
|
+
/* @__PURE__ */ jsxs("div", { style: resultLabelStyle, children: [
|
|
5285
|
+
/* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(RichText, { content: option }) }),
|
|
5286
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
5287
|
+
String(count),
|
|
5288
|
+
" vote",
|
|
5289
|
+
count !== 1 ? "s" : "",
|
|
5290
|
+
" (",
|
|
5291
|
+
String(Math.round(percentage)),
|
|
5292
|
+
"%)"
|
|
5293
|
+
] })
|
|
5294
|
+
] }),
|
|
5295
|
+
/* @__PURE__ */ jsx(
|
|
5296
|
+
"div",
|
|
5297
|
+
{
|
|
5298
|
+
style: barTrackStyle,
|
|
5299
|
+
role: "progressbar",
|
|
5300
|
+
"aria-valuenow": percentage,
|
|
5301
|
+
"aria-valuemin": 0,
|
|
5302
|
+
"aria-valuemax": 100,
|
|
5303
|
+
"aria-label": `${optionLabel}: ${String(Math.round(percentage))}%`,
|
|
5304
|
+
children: /* @__PURE__ */ jsx("div", { style: barFillStyle(percentage) })
|
|
5305
|
+
}
|
|
5306
|
+
)
|
|
5307
|
+
] }, index);
|
|
5308
|
+
}) })
|
|
5309
|
+
] });
|
|
5310
|
+
}
|
|
5311
|
+
|
|
5312
|
+
// src/poll/index.ts
|
|
5313
|
+
var pollDefinition = {
|
|
5314
|
+
type: "ui:poll",
|
|
5315
|
+
schema: pollSchema,
|
|
5316
|
+
render: Poll
|
|
5317
|
+
};
|
|
5318
|
+
|
|
5319
|
+
// src/rating/styles.ts
|
|
5320
|
+
var containerStyle4 = {
|
|
5321
|
+
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
5322
|
+
color: "var(--glyph-text, #1a2035)",
|
|
5323
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5324
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
5325
|
+
overflow: "hidden"
|
|
5326
|
+
};
|
|
5327
|
+
var headerStyle3 = {
|
|
5328
|
+
fontWeight: 700,
|
|
5329
|
+
fontSize: "1.125rem",
|
|
5330
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
5331
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5332
|
+
color: "var(--glyph-heading, #0a0e1a)"
|
|
5333
|
+
};
|
|
5334
|
+
function itemStyle2(isLast) {
|
|
5335
|
+
return {
|
|
5336
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
5337
|
+
borderBottom: isLast ? "none" : "1px solid var(--glyph-border, #d0d8e4)"
|
|
5338
|
+
};
|
|
5339
|
+
}
|
|
5340
|
+
var itemLabelStyle = {
|
|
5341
|
+
fontWeight: 600,
|
|
5342
|
+
fontSize: "0.9375rem",
|
|
5343
|
+
marginBottom: "0.25rem"
|
|
5344
|
+
};
|
|
5345
|
+
var itemDescriptionStyle = {
|
|
5346
|
+
fontSize: "0.8125rem",
|
|
5347
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
5348
|
+
marginBottom: "0.5rem"
|
|
5349
|
+
};
|
|
5350
|
+
var starsContainerStyle = {
|
|
5351
|
+
display: "flex",
|
|
5352
|
+
gap: "0.25rem",
|
|
5353
|
+
alignItems: "center"
|
|
5354
|
+
};
|
|
5355
|
+
function starButtonStyle(filled, hovered) {
|
|
5356
|
+
return {
|
|
5357
|
+
background: "none",
|
|
5358
|
+
border: "none",
|
|
5359
|
+
padding: "0.125rem",
|
|
5360
|
+
cursor: "pointer",
|
|
5361
|
+
fontSize: "1.25rem",
|
|
5362
|
+
lineHeight: 1,
|
|
5363
|
+
color: filled || hovered ? "var(--glyph-rating-star-fill, #f59e0b)" : "var(--glyph-rating-star-empty, var(--glyph-border, #d0d8e4))",
|
|
5364
|
+
transition: "color 0.15s ease"
|
|
5365
|
+
};
|
|
5366
|
+
}
|
|
5367
|
+
function numberButtonStyle(selected) {
|
|
5368
|
+
return {
|
|
5369
|
+
minWidth: "2rem",
|
|
5370
|
+
height: "2rem",
|
|
5371
|
+
display: "flex",
|
|
5372
|
+
alignItems: "center",
|
|
5373
|
+
justifyContent: "center",
|
|
5374
|
+
borderRadius: "var(--glyph-radius-sm, 0.375rem)",
|
|
5375
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5376
|
+
background: selected ? "var(--glyph-accent, #0a9d7c)" : "transparent",
|
|
5377
|
+
color: selected ? "#fff" : "var(--glyph-text, #1a2035)",
|
|
5378
|
+
cursor: "pointer",
|
|
5379
|
+
fontWeight: 600,
|
|
5380
|
+
fontSize: "0.875rem",
|
|
5381
|
+
transition: "background 0.15s ease, color 0.15s ease"
|
|
5382
|
+
};
|
|
5383
|
+
}
|
|
5384
|
+
var scaleLabelsStyle = {
|
|
5385
|
+
display: "flex",
|
|
5386
|
+
justifyContent: "space-between",
|
|
5387
|
+
fontSize: "0.75rem",
|
|
5388
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
5389
|
+
marginTop: "0.375rem"
|
|
5390
|
+
};
|
|
5391
|
+
function Rating({
|
|
5392
|
+
data,
|
|
5393
|
+
block,
|
|
5394
|
+
onInteraction
|
|
5395
|
+
}) {
|
|
5396
|
+
const { title, scale = 5, mode = "star", labels, items } = data;
|
|
5397
|
+
const baseId = `glyph-rating-${block.id}`;
|
|
5398
|
+
const [ratings, setRatings] = useState(() => items.map(() => null));
|
|
5399
|
+
const [hoveredStar, setHoveredStar] = useState(null);
|
|
5400
|
+
const handleRate = (itemIndex, value) => {
|
|
5401
|
+
const newRatings = [...ratings];
|
|
5402
|
+
newRatings[itemIndex] = value;
|
|
5403
|
+
setRatings(newRatings);
|
|
5404
|
+
if (onInteraction) {
|
|
5405
|
+
const item = items[itemIndex];
|
|
5406
|
+
const itemLabel = item ? typeof item.label === "string" ? item.label : "Item" : "";
|
|
5407
|
+
onInteraction({
|
|
5408
|
+
kind: "rating-change",
|
|
5409
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5410
|
+
blockId: block.id,
|
|
5411
|
+
blockType: block.type,
|
|
5412
|
+
payload: {
|
|
5413
|
+
itemIndex,
|
|
5414
|
+
itemLabel,
|
|
5415
|
+
value,
|
|
5416
|
+
allRatings: items.map((item2, i) => ({
|
|
5417
|
+
label: typeof item2.label === "string" ? item2.label : "Item",
|
|
5418
|
+
value: i === itemIndex ? value : newRatings[i] ?? null
|
|
5419
|
+
}))
|
|
5420
|
+
}
|
|
5421
|
+
});
|
|
5422
|
+
}
|
|
5423
|
+
};
|
|
5424
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Rating", style: containerStyle4, children: [
|
|
5425
|
+
title && /* @__PURE__ */ jsx("div", { style: headerStyle3, children: title }),
|
|
5426
|
+
items.map((item, itemIndex) => {
|
|
5427
|
+
const currentRating = ratings[itemIndex] ?? null;
|
|
5428
|
+
const isLast = itemIndex === items.length - 1;
|
|
5429
|
+
const itemLabelText = typeof item.label === "string" ? item.label : "Item";
|
|
5430
|
+
return /* @__PURE__ */ jsxs("div", { style: itemStyle2(isLast), children: [
|
|
5431
|
+
/* @__PURE__ */ jsx("div", { style: itemLabelStyle, children: /* @__PURE__ */ jsx(RichText, { content: item.label }) }),
|
|
5432
|
+
item.description && /* @__PURE__ */ jsx("div", { style: itemDescriptionStyle, children: /* @__PURE__ */ jsx(RichText, { content: item.description }) }),
|
|
5433
|
+
/* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": `Rate ${itemLabelText}`, style: starsContainerStyle, children: Array.from({ length: scale }, (_, starIndex) => {
|
|
5434
|
+
const value = starIndex + 1;
|
|
5435
|
+
const isHovered = hoveredStar !== null && hoveredStar.itemIndex === itemIndex && value <= hoveredStar.value;
|
|
5436
|
+
const isFilled = currentRating !== null && value <= currentRating;
|
|
5437
|
+
if (mode === "number") {
|
|
5438
|
+
return /* @__PURE__ */ jsx(
|
|
5439
|
+
"button",
|
|
5440
|
+
{
|
|
5441
|
+
type: "button",
|
|
5442
|
+
role: "radio",
|
|
5443
|
+
"aria-checked": currentRating === value,
|
|
5444
|
+
"aria-label": `${String(value)} out of ${String(scale)}`,
|
|
5445
|
+
style: numberButtonStyle(currentRating === value),
|
|
5446
|
+
onClick: () => handleRate(itemIndex, value),
|
|
5447
|
+
children: String(value)
|
|
5448
|
+
},
|
|
5449
|
+
starIndex
|
|
5450
|
+
);
|
|
5451
|
+
}
|
|
5452
|
+
return /* @__PURE__ */ jsx(
|
|
5453
|
+
"button",
|
|
5454
|
+
{
|
|
5455
|
+
type: "button",
|
|
5456
|
+
role: "radio",
|
|
5457
|
+
"aria-checked": currentRating === value,
|
|
5458
|
+
"aria-label": `${String(value)} out of ${String(scale)} stars`,
|
|
5459
|
+
style: starButtonStyle(isFilled, isHovered),
|
|
5460
|
+
onClick: () => handleRate(itemIndex, value),
|
|
5461
|
+
onMouseEnter: () => setHoveredStar({ itemIndex, value }),
|
|
5462
|
+
onMouseLeave: () => setHoveredStar(null),
|
|
5463
|
+
children: "\u2605"
|
|
5464
|
+
},
|
|
5465
|
+
starIndex
|
|
5466
|
+
);
|
|
5467
|
+
}) }),
|
|
5468
|
+
labels && /* @__PURE__ */ jsxs("div", { style: scaleLabelsStyle, children: [
|
|
5469
|
+
/* @__PURE__ */ jsx("span", { children: labels.low }),
|
|
5470
|
+
/* @__PURE__ */ jsx("span", { children: labels.high })
|
|
5471
|
+
] }),
|
|
5472
|
+
/* @__PURE__ */ jsx(
|
|
5473
|
+
"div",
|
|
5474
|
+
{
|
|
5475
|
+
"aria-live": "polite",
|
|
5476
|
+
style: {
|
|
5477
|
+
position: "absolute",
|
|
5478
|
+
width: "1px",
|
|
5479
|
+
height: "1px",
|
|
5480
|
+
padding: 0,
|
|
5481
|
+
margin: "-1px",
|
|
5482
|
+
overflow: "hidden",
|
|
5483
|
+
clip: "rect(0,0,0,0)",
|
|
5484
|
+
whiteSpace: "nowrap",
|
|
5485
|
+
border: 0
|
|
5486
|
+
},
|
|
5487
|
+
children: currentRating !== null && `${itemLabelText} rated ${String(currentRating)} out of ${String(scale)}`
|
|
5488
|
+
}
|
|
5489
|
+
)
|
|
5490
|
+
] }, itemIndex);
|
|
5491
|
+
})
|
|
5492
|
+
] });
|
|
5493
|
+
}
|
|
5494
|
+
|
|
5495
|
+
// src/rating/index.ts
|
|
5496
|
+
var ratingDefinition = {
|
|
5497
|
+
type: "ui:rating",
|
|
5498
|
+
schema: ratingSchema,
|
|
5499
|
+
render: Rating
|
|
5500
|
+
};
|
|
5501
|
+
|
|
5502
|
+
// src/ranker/styles.ts
|
|
5503
|
+
var containerStyle5 = {
|
|
5504
|
+
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
5505
|
+
color: "var(--glyph-text, #1a2035)",
|
|
5506
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5507
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
5508
|
+
overflow: "hidden"
|
|
5509
|
+
};
|
|
5510
|
+
var headerStyle4 = {
|
|
5511
|
+
fontWeight: 700,
|
|
5512
|
+
fontSize: "1.125rem",
|
|
5513
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
5514
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5515
|
+
color: "var(--glyph-heading, #0a0e1a)"
|
|
5516
|
+
};
|
|
5517
|
+
var listStyle = {
|
|
5518
|
+
listStyle: "none",
|
|
5519
|
+
margin: 0,
|
|
5520
|
+
padding: 0
|
|
5521
|
+
};
|
|
5522
|
+
function itemStyle3(isDragging, isGrabbed) {
|
|
5523
|
+
return {
|
|
5524
|
+
display: "flex",
|
|
5525
|
+
alignItems: "center",
|
|
5526
|
+
gap: "0.75rem",
|
|
5527
|
+
padding: "0.75rem var(--glyph-spacing-md, 1rem)",
|
|
5528
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5529
|
+
background: isDragging ? "var(--glyph-accent-subtle, #e6f6f2)" : "transparent",
|
|
5530
|
+
cursor: isGrabbed ? "grabbing" : "grab",
|
|
5531
|
+
userSelect: "none",
|
|
5532
|
+
transition: "background 0.15s ease",
|
|
5533
|
+
outline: isGrabbed ? "2px solid var(--glyph-accent, #0a9d7c)" : "none",
|
|
5534
|
+
outlineOffset: "-2px"
|
|
5535
|
+
};
|
|
5536
|
+
}
|
|
5537
|
+
var rankBadgeStyle = {
|
|
5538
|
+
minWidth: "1.75rem",
|
|
5539
|
+
height: "1.75rem",
|
|
5540
|
+
display: "flex",
|
|
5541
|
+
alignItems: "center",
|
|
5542
|
+
justifyContent: "center",
|
|
5543
|
+
borderRadius: "50%",
|
|
5544
|
+
background: "var(--glyph-surface, #e8ecf3)",
|
|
5545
|
+
fontWeight: 700,
|
|
5546
|
+
fontSize: "0.8125rem",
|
|
5547
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
5548
|
+
flexShrink: 0
|
|
5549
|
+
};
|
|
5550
|
+
var itemContentStyle = {
|
|
5551
|
+
flex: 1,
|
|
5552
|
+
minWidth: 0
|
|
5553
|
+
};
|
|
5554
|
+
var itemLabelStyle2 = {
|
|
5555
|
+
fontWeight: 600,
|
|
5556
|
+
fontSize: "0.9375rem"
|
|
5557
|
+
};
|
|
5558
|
+
var itemDescriptionStyle2 = {
|
|
5559
|
+
fontSize: "0.8125rem",
|
|
5560
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
5561
|
+
marginTop: "0.125rem"
|
|
5562
|
+
};
|
|
5563
|
+
var gripStyle = {
|
|
5564
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
5565
|
+
fontSize: "1rem",
|
|
5566
|
+
flexShrink: 0
|
|
5567
|
+
};
|
|
5568
|
+
function Ranker({
|
|
5569
|
+
data,
|
|
5570
|
+
block,
|
|
5571
|
+
onInteraction
|
|
5572
|
+
}) {
|
|
5573
|
+
const { title, items: initialItems } = data;
|
|
5574
|
+
const baseId = `glyph-ranker-${block.id}`;
|
|
5575
|
+
const [items, setItems] = useState(initialItems);
|
|
5576
|
+
const [grabbedIndex, setGrabbedIndex] = useState(null);
|
|
5577
|
+
const moveItem = useCallback(
|
|
5578
|
+
(fromIndex, toIndex) => {
|
|
5579
|
+
if (fromIndex === toIndex) return;
|
|
5580
|
+
setItems((prevItems) => {
|
|
5581
|
+
const newItems = [...prevItems];
|
|
5582
|
+
const [moved] = newItems.splice(fromIndex, 1);
|
|
5583
|
+
if (!moved) return prevItems;
|
|
5584
|
+
newItems.splice(toIndex, 0, moved);
|
|
5585
|
+
if (onInteraction) {
|
|
5586
|
+
onInteraction({
|
|
5587
|
+
kind: "ranker-reorder",
|
|
5588
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5589
|
+
blockId: block.id,
|
|
5590
|
+
blockType: block.type,
|
|
5591
|
+
payload: {
|
|
5592
|
+
orderedItems: newItems.map((item, i) => ({
|
|
5593
|
+
id: item.id,
|
|
5594
|
+
label: typeof item.label === "string" ? item.label : "Item",
|
|
5595
|
+
rank: i + 1
|
|
5596
|
+
})),
|
|
5597
|
+
movedItem: {
|
|
5598
|
+
id: moved.id,
|
|
5599
|
+
label: typeof moved.label === "string" ? moved.label : "Item",
|
|
5600
|
+
fromRank: fromIndex + 1,
|
|
5601
|
+
toRank: toIndex + 1
|
|
5602
|
+
}
|
|
5603
|
+
}
|
|
5604
|
+
});
|
|
5605
|
+
}
|
|
5606
|
+
return newItems;
|
|
5607
|
+
});
|
|
5608
|
+
},
|
|
5609
|
+
[block.id, block.type, onInteraction]
|
|
5610
|
+
);
|
|
5611
|
+
const handleKeyDown = (e, index) => {
|
|
5612
|
+
if (e.key === " " || e.key === "Enter") {
|
|
5613
|
+
e.preventDefault();
|
|
5614
|
+
if (grabbedIndex === null) {
|
|
5615
|
+
setGrabbedIndex(index);
|
|
5616
|
+
} else {
|
|
5617
|
+
setGrabbedIndex(null);
|
|
5618
|
+
}
|
|
5619
|
+
} else if (e.key === "Escape") {
|
|
5620
|
+
setGrabbedIndex(null);
|
|
5621
|
+
} else if (e.key === "ArrowUp" && grabbedIndex !== null) {
|
|
5622
|
+
e.preventDefault();
|
|
5623
|
+
if (grabbedIndex > 0) {
|
|
5624
|
+
moveItem(grabbedIndex, grabbedIndex - 1);
|
|
5625
|
+
setGrabbedIndex(grabbedIndex - 1);
|
|
5626
|
+
}
|
|
5627
|
+
} else if (e.key === "ArrowDown" && grabbedIndex !== null) {
|
|
5628
|
+
e.preventDefault();
|
|
5629
|
+
if (grabbedIndex < items.length - 1) {
|
|
5630
|
+
moveItem(grabbedIndex, grabbedIndex + 1);
|
|
5631
|
+
setGrabbedIndex(grabbedIndex + 1);
|
|
5632
|
+
}
|
|
5633
|
+
}
|
|
5634
|
+
};
|
|
5635
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Ranker", style: containerStyle5, children: [
|
|
5636
|
+
title && /* @__PURE__ */ jsx("div", { style: headerStyle4, children: title }),
|
|
5637
|
+
/* @__PURE__ */ jsx("ul", { role: "list", "aria-label": title ?? "Rank items", style: listStyle, children: items.map((item, index) => {
|
|
5638
|
+
const itemLabelText = typeof item.label === "string" ? item.label : "Item";
|
|
5639
|
+
return /* @__PURE__ */ jsxs(
|
|
5640
|
+
"li",
|
|
5641
|
+
{
|
|
5642
|
+
role: "listitem",
|
|
5643
|
+
"aria-grabbed": grabbedIndex === index,
|
|
5644
|
+
"aria-label": `${itemLabelText}, rank ${String(index + 1)}`,
|
|
5645
|
+
tabIndex: 0,
|
|
5646
|
+
style: itemStyle3(false, grabbedIndex === index),
|
|
5647
|
+
onKeyDown: (e) => handleKeyDown(e, index),
|
|
5648
|
+
children: [
|
|
5649
|
+
/* @__PURE__ */ jsx("span", { style: gripStyle, "aria-hidden": "true", children: "\u283F" }),
|
|
5650
|
+
/* @__PURE__ */ jsx("span", { style: rankBadgeStyle, children: String(index + 1) }),
|
|
5651
|
+
/* @__PURE__ */ jsxs("div", { style: itemContentStyle, children: [
|
|
5652
|
+
/* @__PURE__ */ jsx("div", { style: itemLabelStyle2, children: /* @__PURE__ */ jsx(RichText, { content: item.label }) }),
|
|
5653
|
+
item.description && /* @__PURE__ */ jsx("div", { style: itemDescriptionStyle2, children: item.description })
|
|
5654
|
+
] })
|
|
5655
|
+
]
|
|
5656
|
+
},
|
|
5657
|
+
item.id
|
|
5658
|
+
);
|
|
5659
|
+
}) }),
|
|
5660
|
+
/* @__PURE__ */ jsx(
|
|
5661
|
+
"div",
|
|
5662
|
+
{
|
|
5663
|
+
"aria-live": "assertive",
|
|
5664
|
+
style: {
|
|
5665
|
+
position: "absolute",
|
|
5666
|
+
width: "1px",
|
|
5667
|
+
height: "1px",
|
|
5668
|
+
padding: 0,
|
|
5669
|
+
margin: "-1px",
|
|
5670
|
+
overflow: "hidden",
|
|
5671
|
+
clip: "rect(0,0,0,0)",
|
|
5672
|
+
whiteSpace: "nowrap",
|
|
5673
|
+
border: 0
|
|
5674
|
+
},
|
|
5675
|
+
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.` : ""
|
|
5676
|
+
}
|
|
5677
|
+
)
|
|
5678
|
+
] });
|
|
5679
|
+
}
|
|
5680
|
+
|
|
5681
|
+
// src/ranker/index.ts
|
|
5682
|
+
var rankerDefinition = {
|
|
5683
|
+
type: "ui:ranker",
|
|
5684
|
+
schema: rankerSchema,
|
|
5685
|
+
render: Ranker
|
|
5686
|
+
};
|
|
5687
|
+
|
|
5688
|
+
// src/slider/styles.ts
|
|
5689
|
+
var containerStyle6 = {
|
|
5690
|
+
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
5691
|
+
color: "var(--glyph-text, #1a2035)",
|
|
5692
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5693
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
5694
|
+
overflow: "hidden"
|
|
5695
|
+
};
|
|
5696
|
+
var headerStyle5 = {
|
|
5697
|
+
fontWeight: 700,
|
|
5698
|
+
fontSize: "1.125rem",
|
|
5699
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
5700
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5701
|
+
color: "var(--glyph-heading, #0a0e1a)"
|
|
5702
|
+
};
|
|
5703
|
+
function parameterStyle(isLast) {
|
|
5704
|
+
return {
|
|
5705
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
5706
|
+
borderBottom: isLast ? "none" : "1px solid var(--glyph-border, #d0d8e4)"
|
|
5707
|
+
};
|
|
5708
|
+
}
|
|
5709
|
+
var parameterHeaderStyle = {
|
|
5710
|
+
display: "flex",
|
|
5711
|
+
justifyContent: "space-between",
|
|
5712
|
+
alignItems: "center",
|
|
5713
|
+
marginBottom: "0.5rem"
|
|
5714
|
+
};
|
|
5715
|
+
var parameterLabelStyle = {
|
|
5716
|
+
fontWeight: 600,
|
|
5717
|
+
fontSize: "0.9375rem"
|
|
5718
|
+
};
|
|
5719
|
+
var parameterValueStyle = {
|
|
5720
|
+
fontSize: "0.9375rem",
|
|
5721
|
+
fontWeight: 600,
|
|
5722
|
+
color: "var(--glyph-accent, #0a9d7c)",
|
|
5723
|
+
fontVariantNumeric: "tabular-nums"
|
|
5724
|
+
};
|
|
5725
|
+
var rangeInputStyle = {
|
|
5726
|
+
width: "100%",
|
|
5727
|
+
margin: 0,
|
|
5728
|
+
accentColor: "var(--glyph-slider-fill, var(--glyph-accent, #0a9d7c))"
|
|
5729
|
+
};
|
|
5730
|
+
var rangeLabelsStyle = {
|
|
5731
|
+
display: "flex",
|
|
5732
|
+
justifyContent: "space-between",
|
|
5733
|
+
fontSize: "0.75rem",
|
|
5734
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
5735
|
+
marginTop: "0.25rem"
|
|
5736
|
+
};
|
|
5737
|
+
function Slider({
|
|
5738
|
+
data,
|
|
5739
|
+
block,
|
|
5740
|
+
onInteraction
|
|
5741
|
+
}) {
|
|
5742
|
+
const { title, parameters } = data;
|
|
5743
|
+
const baseId = `glyph-slider-${block.id}`;
|
|
5744
|
+
const [values, setValues] = useState(
|
|
5745
|
+
() => parameters.map((p) => p.value ?? p.min ?? 0)
|
|
5746
|
+
);
|
|
5747
|
+
const handleChange = (paramIndex, newValue) => {
|
|
5748
|
+
const newValues = [...values];
|
|
5749
|
+
newValues[paramIndex] = newValue;
|
|
5750
|
+
setValues(newValues);
|
|
5751
|
+
const param = parameters[paramIndex];
|
|
5752
|
+
if (!param) return;
|
|
5753
|
+
if (onInteraction) {
|
|
5754
|
+
onInteraction({
|
|
5755
|
+
kind: "slider-change",
|
|
5756
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5757
|
+
blockId: block.id,
|
|
5758
|
+
blockType: block.type,
|
|
5759
|
+
payload: {
|
|
5760
|
+
parameterId: param.id,
|
|
5761
|
+
parameterLabel: typeof param.label === "string" ? param.label : "Parameter",
|
|
5762
|
+
value: newValue,
|
|
5763
|
+
allValues: parameters.map((p, i) => ({
|
|
5764
|
+
id: p.id,
|
|
5765
|
+
label: typeof p.label === "string" ? p.label : "Parameter",
|
|
5766
|
+
value: i === paramIndex ? newValue : newValues[i] ?? 0
|
|
5767
|
+
}))
|
|
5768
|
+
}
|
|
5769
|
+
});
|
|
5770
|
+
}
|
|
5771
|
+
};
|
|
5772
|
+
const formatValue = (value, unit) => {
|
|
5773
|
+
return unit ? `${String(value)}${unit}` : String(value);
|
|
5774
|
+
};
|
|
5775
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Slider", style: containerStyle6, children: [
|
|
5776
|
+
title && /* @__PURE__ */ jsx("div", { style: headerStyle5, children: title }),
|
|
5777
|
+
parameters.map((param, index) => {
|
|
5778
|
+
const min2 = param.min ?? 0;
|
|
5779
|
+
const max2 = param.max ?? 100;
|
|
5780
|
+
const step = param.step ?? 1;
|
|
5781
|
+
const currentValue = values[index] ?? min2;
|
|
5782
|
+
const isLast = index === parameters.length - 1;
|
|
5783
|
+
return /* @__PURE__ */ jsxs("div", { style: parameterStyle(isLast), children: [
|
|
5784
|
+
/* @__PURE__ */ jsxs("div", { style: parameterHeaderStyle, children: [
|
|
5785
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `${baseId}-${param.id}`, style: parameterLabelStyle, children: /* @__PURE__ */ jsx(RichText, { content: param.label }) }),
|
|
5786
|
+
/* @__PURE__ */ jsx("span", { style: parameterValueStyle, "aria-live": "polite", children: formatValue(currentValue, param.unit) })
|
|
5787
|
+
] }),
|
|
5788
|
+
/* @__PURE__ */ jsx(
|
|
5789
|
+
"input",
|
|
5790
|
+
{
|
|
5791
|
+
id: `${baseId}-${param.id}`,
|
|
5792
|
+
type: "range",
|
|
5793
|
+
min: min2,
|
|
5794
|
+
max: max2,
|
|
5795
|
+
step,
|
|
5796
|
+
value: currentValue,
|
|
5797
|
+
onChange: (e) => handleChange(index, Number(e.target.value)),
|
|
5798
|
+
"aria-valuemin": min2,
|
|
5799
|
+
"aria-valuemax": max2,
|
|
5800
|
+
"aria-valuenow": currentValue,
|
|
5801
|
+
"aria-valuetext": formatValue(currentValue, param.unit),
|
|
5802
|
+
style: rangeInputStyle
|
|
5803
|
+
}
|
|
5804
|
+
),
|
|
5805
|
+
/* @__PURE__ */ jsxs("div", { style: rangeLabelsStyle, children: [
|
|
5806
|
+
/* @__PURE__ */ jsx("span", { children: formatValue(min2, param.unit) }),
|
|
5807
|
+
/* @__PURE__ */ jsx("span", { children: formatValue(max2, param.unit) })
|
|
5808
|
+
] })
|
|
5809
|
+
] }, param.id);
|
|
5810
|
+
})
|
|
5811
|
+
] });
|
|
5812
|
+
}
|
|
5813
|
+
|
|
5814
|
+
// src/slider/index.ts
|
|
5815
|
+
var sliderDefinition = {
|
|
5816
|
+
type: "ui:slider",
|
|
5817
|
+
schema: sliderSchema,
|
|
5818
|
+
render: Slider
|
|
5819
|
+
};
|
|
5820
|
+
|
|
5821
|
+
// src/matrix/styles.ts
|
|
5822
|
+
var containerStyle7 = {
|
|
5823
|
+
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
5824
|
+
color: "var(--glyph-text, #1a2035)",
|
|
5825
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5826
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
5827
|
+
overflow: "auto"
|
|
5828
|
+
};
|
|
5829
|
+
var headerStyle6 = {
|
|
5830
|
+
fontWeight: 700,
|
|
5831
|
+
fontSize: "1.125rem",
|
|
5832
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
5833
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5834
|
+
color: "var(--glyph-heading, #0a0e1a)"
|
|
5835
|
+
};
|
|
5836
|
+
var tableStyle = {
|
|
5837
|
+
width: "100%",
|
|
5838
|
+
borderCollapse: "collapse",
|
|
5839
|
+
fontSize: "0.875rem"
|
|
5840
|
+
};
|
|
5841
|
+
var thStyle = {
|
|
5842
|
+
padding: "0.625rem 0.75rem",
|
|
5843
|
+
textAlign: "center",
|
|
5844
|
+
fontWeight: 600,
|
|
5845
|
+
borderBottom: "2px solid var(--glyph-border, #d0d8e4)",
|
|
5846
|
+
background: "var(--glyph-table-header-bg, var(--glyph-surface, #e8ecf3))",
|
|
5847
|
+
whiteSpace: "nowrap"
|
|
5848
|
+
};
|
|
5849
|
+
var rowHeaderStyle = {
|
|
5850
|
+
padding: "0.625rem 0.75rem",
|
|
5851
|
+
textAlign: "left",
|
|
5852
|
+
fontWeight: 600,
|
|
5853
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5854
|
+
borderRight: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5855
|
+
whiteSpace: "nowrap"
|
|
5856
|
+
};
|
|
5857
|
+
var cellStyle = {
|
|
5858
|
+
padding: "0.375rem 0.5rem",
|
|
5859
|
+
textAlign: "center",
|
|
5860
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)"
|
|
5861
|
+
};
|
|
5862
|
+
var inputStyle = {
|
|
5863
|
+
width: "3.5rem",
|
|
5864
|
+
padding: "0.25rem 0.375rem",
|
|
5865
|
+
textAlign: "center",
|
|
5866
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5867
|
+
borderRadius: "var(--glyph-radius-sm, 0.375rem)",
|
|
5868
|
+
background: "transparent",
|
|
5869
|
+
color: "var(--glyph-text, #1a2035)",
|
|
5870
|
+
fontSize: "0.875rem",
|
|
5871
|
+
fontVariantNumeric: "tabular-nums"
|
|
5872
|
+
};
|
|
5873
|
+
var weightStyle = {
|
|
5874
|
+
fontSize: "0.6875rem",
|
|
5875
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
5876
|
+
fontWeight: 400
|
|
5877
|
+
};
|
|
5878
|
+
var totalCellStyle = {
|
|
5879
|
+
padding: "0.625rem 0.75rem",
|
|
5880
|
+
textAlign: "center",
|
|
5881
|
+
fontWeight: 700,
|
|
5882
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
5883
|
+
background: "var(--glyph-surface, #e8ecf3)",
|
|
5884
|
+
fontVariantNumeric: "tabular-nums"
|
|
5885
|
+
};
|
|
5886
|
+
var totalHeaderStyle = {
|
|
5887
|
+
...thStyle,
|
|
5888
|
+
borderLeft: "2px solid var(--glyph-border, #d0d8e4)"
|
|
5889
|
+
};
|
|
5890
|
+
function computeWeightedTotals(rows, columns, values) {
|
|
5891
|
+
return rows.map((row) => {
|
|
5892
|
+
let total = 0;
|
|
5893
|
+
for (const col of columns) {
|
|
5894
|
+
const score = values[row.id]?.[col.id] ?? 0;
|
|
5895
|
+
const weight = col.weight ?? 1;
|
|
5896
|
+
total += score * weight;
|
|
5897
|
+
}
|
|
5898
|
+
const rowLabel = typeof row.label === "string" ? row.label : "Row";
|
|
5899
|
+
return { rowId: row.id, rowLabel, total: Math.round(total * 100) / 100 };
|
|
5900
|
+
});
|
|
5901
|
+
}
|
|
5902
|
+
function Matrix({
|
|
5903
|
+
data,
|
|
5904
|
+
block,
|
|
5905
|
+
onInteraction
|
|
5906
|
+
}) {
|
|
5907
|
+
const { title, scale = 5, showTotals = true, columns, rows } = data;
|
|
5908
|
+
const baseId = `glyph-matrix-${block.id}`;
|
|
5909
|
+
const [values, setValues] = useState(() => {
|
|
5910
|
+
const init = {};
|
|
5911
|
+
for (const row of rows) {
|
|
5912
|
+
const rowMap = {};
|
|
5913
|
+
for (const col of columns) {
|
|
5914
|
+
rowMap[col.id] = 0;
|
|
5915
|
+
}
|
|
5916
|
+
init[row.id] = rowMap;
|
|
5917
|
+
}
|
|
5918
|
+
return init;
|
|
5919
|
+
});
|
|
5920
|
+
const handleChange = useCallback(
|
|
5921
|
+
(rowId, columnId, value) => {
|
|
5922
|
+
const clamped = Math.max(0, Math.min(scale, value));
|
|
5923
|
+
setValues((prevValues) => {
|
|
5924
|
+
const newValues = Object.fromEntries(
|
|
5925
|
+
Object.entries(prevValues).map(([k, v]) => [k, { ...v }])
|
|
5926
|
+
);
|
|
5927
|
+
if (!newValues[rowId]) newValues[rowId] = {};
|
|
5928
|
+
newValues[rowId] = { ...newValues[rowId], [columnId]: clamped };
|
|
5929
|
+
const row = rows.find((r) => r.id === rowId);
|
|
5930
|
+
const col = columns.find((c) => c.id === columnId);
|
|
5931
|
+
if (onInteraction && row && col) {
|
|
5932
|
+
const payloadValues = Object.fromEntries(
|
|
5933
|
+
Object.entries(newValues).map(([k, v]) => [k, { ...v }])
|
|
5934
|
+
);
|
|
5935
|
+
onInteraction({
|
|
5936
|
+
kind: "matrix-change",
|
|
5937
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5938
|
+
blockId: block.id,
|
|
5939
|
+
blockType: block.type,
|
|
5940
|
+
payload: {
|
|
5941
|
+
rowId,
|
|
5942
|
+
rowLabel: typeof row.label === "string" ? row.label : "Row",
|
|
5943
|
+
columnId,
|
|
5944
|
+
columnLabel: typeof col.label === "string" ? col.label : "Column",
|
|
5945
|
+
value: clamped,
|
|
5946
|
+
allValues: payloadValues,
|
|
5947
|
+
weightedTotals: computeWeightedTotals(rows, columns, newValues)
|
|
5948
|
+
}
|
|
5949
|
+
});
|
|
5950
|
+
}
|
|
5951
|
+
return newValues;
|
|
5952
|
+
});
|
|
5953
|
+
},
|
|
5954
|
+
[scale, rows, columns, block.id, block.type, onInteraction]
|
|
5955
|
+
);
|
|
5956
|
+
const totals = computeWeightedTotals(rows, columns, values);
|
|
5957
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Decision Matrix", style: containerStyle7, children: [
|
|
5958
|
+
title && /* @__PURE__ */ jsx("div", { style: headerStyle6, children: title }),
|
|
5959
|
+
/* @__PURE__ */ jsxs("table", { role: "grid", style: tableStyle, children: [
|
|
5960
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
5961
|
+
/* @__PURE__ */ jsx("th", { style: thStyle }),
|
|
5962
|
+
columns.map((col) => /* @__PURE__ */ jsxs("th", { style: thStyle, children: [
|
|
5963
|
+
/* @__PURE__ */ jsx(RichText, { content: col.label }),
|
|
5964
|
+
(col.weight ?? 1) !== 1 && /* @__PURE__ */ jsxs("div", { style: weightStyle, children: [
|
|
5965
|
+
"\xD7",
|
|
5966
|
+
String(col.weight)
|
|
5967
|
+
] })
|
|
5968
|
+
] }, col.id)),
|
|
5969
|
+
showTotals && /* @__PURE__ */ jsx("th", { style: totalHeaderStyle, children: "Total" })
|
|
5970
|
+
] }) }),
|
|
5971
|
+
/* @__PURE__ */ jsx("tbody", { children: rows.map((row) => {
|
|
5972
|
+
const rowTotal = totals.find((t) => t.rowId === row.id)?.total ?? 0;
|
|
5973
|
+
const rowLabelText = typeof row.label === "string" ? row.label : "Row";
|
|
5974
|
+
return /* @__PURE__ */ jsxs("tr", { children: [
|
|
5975
|
+
/* @__PURE__ */ jsx("th", { scope: "row", style: rowHeaderStyle, children: /* @__PURE__ */ jsx(RichText, { content: row.label }) }),
|
|
5976
|
+
columns.map((col) => {
|
|
5977
|
+
const cellValue = values[row.id]?.[col.id] ?? 0;
|
|
5978
|
+
const colLabelText = typeof col.label === "string" ? col.label : "Column";
|
|
5979
|
+
return /* @__PURE__ */ jsx("td", { style: cellStyle, children: /* @__PURE__ */ jsx(
|
|
5980
|
+
"input",
|
|
5981
|
+
{
|
|
5982
|
+
type: "number",
|
|
5983
|
+
min: 0,
|
|
5984
|
+
max: scale,
|
|
5985
|
+
value: cellValue,
|
|
5986
|
+
onChange: (e) => handleChange(row.id, col.id, Number(e.target.value)),
|
|
5987
|
+
"aria-label": `Score for ${rowLabelText} on ${colLabelText}`,
|
|
5988
|
+
style: inputStyle
|
|
5989
|
+
}
|
|
5990
|
+
) }, col.id);
|
|
5991
|
+
}),
|
|
5992
|
+
showTotals && /* @__PURE__ */ jsx("td", { style: totalCellStyle, children: String(rowTotal) })
|
|
5993
|
+
] }, row.id);
|
|
5994
|
+
}) })
|
|
5995
|
+
] })
|
|
5996
|
+
] });
|
|
5997
|
+
}
|
|
5998
|
+
|
|
5999
|
+
// src/matrix/index.ts
|
|
6000
|
+
var matrixDefinition = {
|
|
6001
|
+
type: "ui:matrix",
|
|
6002
|
+
schema: matrixSchema,
|
|
6003
|
+
render: Matrix
|
|
6004
|
+
};
|
|
6005
|
+
|
|
6006
|
+
// src/form/styles.ts
|
|
6007
|
+
var containerStyle8 = {
|
|
6008
|
+
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
6009
|
+
color: "var(--glyph-text, #1a2035)",
|
|
6010
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6011
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
6012
|
+
overflow: "hidden"
|
|
6013
|
+
};
|
|
6014
|
+
var headerStyle7 = {
|
|
6015
|
+
fontWeight: 700,
|
|
6016
|
+
fontSize: "1.125rem",
|
|
6017
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
6018
|
+
paddingBottom: "0.25rem",
|
|
6019
|
+
color: "var(--glyph-heading, #0a0e1a)"
|
|
6020
|
+
};
|
|
6021
|
+
var descriptionStyle = {
|
|
6022
|
+
fontSize: "0.875rem",
|
|
6023
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
6024
|
+
padding: "0 var(--glyph-spacing-md, 1rem)",
|
|
6025
|
+
paddingBottom: "var(--glyph-spacing-sm, 0.5rem)"
|
|
6026
|
+
};
|
|
6027
|
+
var formStyle = {
|
|
6028
|
+
padding: "var(--glyph-spacing-md, 1rem)"
|
|
6029
|
+
};
|
|
6030
|
+
var fieldStyle = {
|
|
6031
|
+
marginBottom: "var(--glyph-spacing-md, 1rem)"
|
|
6032
|
+
};
|
|
6033
|
+
var labelStyle3 = {
|
|
6034
|
+
display: "block",
|
|
6035
|
+
fontWeight: 600,
|
|
6036
|
+
fontSize: "0.875rem",
|
|
6037
|
+
marginBottom: "0.375rem"
|
|
6038
|
+
};
|
|
6039
|
+
var requiredStyle = {
|
|
6040
|
+
color: "var(--glyph-form-error, #dc2626)",
|
|
6041
|
+
marginLeft: "0.25rem"
|
|
6042
|
+
};
|
|
6043
|
+
var textInputStyle = {
|
|
6044
|
+
width: "100%",
|
|
6045
|
+
padding: "0.5rem 0.75rem",
|
|
6046
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6047
|
+
borderRadius: "var(--glyph-radius-sm, 0.375rem)",
|
|
6048
|
+
background: "transparent",
|
|
6049
|
+
color: "var(--glyph-text, #1a2035)",
|
|
6050
|
+
fontSize: "0.875rem",
|
|
6051
|
+
fontFamily: "inherit",
|
|
6052
|
+
boxSizing: "border-box"
|
|
6053
|
+
};
|
|
6054
|
+
var selectInputStyle = {
|
|
6055
|
+
...textInputStyle,
|
|
6056
|
+
appearance: "auto"
|
|
6057
|
+
};
|
|
6058
|
+
var checkboxLabelStyle = {
|
|
6059
|
+
display: "flex",
|
|
6060
|
+
alignItems: "center",
|
|
6061
|
+
gap: "0.5rem",
|
|
6062
|
+
fontSize: "0.875rem",
|
|
6063
|
+
cursor: "pointer"
|
|
6064
|
+
};
|
|
6065
|
+
var rangeValueStyle = {
|
|
6066
|
+
fontSize: "0.875rem",
|
|
6067
|
+
fontWeight: 600,
|
|
6068
|
+
color: "var(--glyph-accent, #0a9d7c)",
|
|
6069
|
+
marginLeft: "0.5rem",
|
|
6070
|
+
fontVariantNumeric: "tabular-nums"
|
|
6071
|
+
};
|
|
6072
|
+
var submitButtonStyle = {
|
|
6073
|
+
padding: "0.625rem 1.5rem",
|
|
6074
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
6075
|
+
border: "1px solid var(--glyph-accent, #0a9d7c)",
|
|
6076
|
+
background: "var(--glyph-accent, #0a9d7c)",
|
|
6077
|
+
color: "#fff",
|
|
6078
|
+
cursor: "pointer",
|
|
6079
|
+
fontWeight: 600,
|
|
6080
|
+
fontSize: "0.875rem",
|
|
6081
|
+
marginTop: "var(--glyph-spacing-sm, 0.5rem)"
|
|
6082
|
+
};
|
|
6083
|
+
function invalidStyle(isInvalid) {
|
|
6084
|
+
if (!isInvalid) return {};
|
|
6085
|
+
return {
|
|
6086
|
+
borderColor: "var(--glyph-form-error, #dc2626)"
|
|
6087
|
+
};
|
|
6088
|
+
}
|
|
6089
|
+
function renderField({
|
|
6090
|
+
field,
|
|
6091
|
+
baseId,
|
|
6092
|
+
values,
|
|
6093
|
+
validation,
|
|
6094
|
+
submitted,
|
|
6095
|
+
updateValue
|
|
6096
|
+
}) {
|
|
6097
|
+
const isInvalid = validation[field.id] === true;
|
|
6098
|
+
const fieldId = `${baseId}-${field.id}`;
|
|
6099
|
+
switch (field.type) {
|
|
6100
|
+
case "text":
|
|
6101
|
+
return /* @__PURE__ */ jsxs("div", { style: fieldStyle, children: [
|
|
6102
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: fieldId, style: labelStyle3, children: [
|
|
6103
|
+
field.label,
|
|
6104
|
+
field.required && /* @__PURE__ */ jsx("span", { style: requiredStyle, "aria-hidden": "true", children: "*" })
|
|
6105
|
+
] }),
|
|
6106
|
+
/* @__PURE__ */ jsx(
|
|
6107
|
+
"input",
|
|
6108
|
+
{
|
|
6109
|
+
id: fieldId,
|
|
6110
|
+
type: "text",
|
|
6111
|
+
value: values[field.id] ?? "",
|
|
6112
|
+
onChange: (e) => updateValue(field.id, e.target.value),
|
|
6113
|
+
placeholder: field.placeholder,
|
|
6114
|
+
disabled: submitted,
|
|
6115
|
+
"aria-required": field.required,
|
|
6116
|
+
"aria-invalid": isInvalid,
|
|
6117
|
+
style: { ...textInputStyle, ...invalidStyle(isInvalid) }
|
|
6118
|
+
}
|
|
6119
|
+
)
|
|
6120
|
+
] }, field.id);
|
|
6121
|
+
case "textarea":
|
|
6122
|
+
return /* @__PURE__ */ jsxs("div", { style: fieldStyle, children: [
|
|
6123
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: fieldId, style: labelStyle3, children: [
|
|
6124
|
+
field.label,
|
|
6125
|
+
field.required && /* @__PURE__ */ jsx("span", { style: requiredStyle, "aria-hidden": "true", children: "*" })
|
|
6126
|
+
] }),
|
|
6127
|
+
/* @__PURE__ */ jsx(
|
|
6128
|
+
"textarea",
|
|
6129
|
+
{
|
|
6130
|
+
id: fieldId,
|
|
6131
|
+
value: values[field.id] ?? "",
|
|
6132
|
+
onChange: (e) => updateValue(field.id, e.target.value),
|
|
6133
|
+
placeholder: field.placeholder,
|
|
6134
|
+
rows: field.rows ?? 4,
|
|
6135
|
+
disabled: submitted,
|
|
6136
|
+
"aria-required": field.required,
|
|
6137
|
+
"aria-invalid": isInvalid,
|
|
6138
|
+
style: {
|
|
6139
|
+
...textInputStyle,
|
|
6140
|
+
...invalidStyle(isInvalid),
|
|
6141
|
+
resize: "vertical",
|
|
6142
|
+
fontFamily: "inherit"
|
|
6143
|
+
}
|
|
6144
|
+
}
|
|
6145
|
+
)
|
|
6146
|
+
] }, field.id);
|
|
6147
|
+
case "select":
|
|
6148
|
+
return /* @__PURE__ */ jsxs("div", { style: fieldStyle, children: [
|
|
6149
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: fieldId, style: labelStyle3, children: [
|
|
6150
|
+
field.label,
|
|
6151
|
+
field.required && /* @__PURE__ */ jsx("span", { style: requiredStyle, "aria-hidden": "true", children: "*" })
|
|
6152
|
+
] }),
|
|
6153
|
+
/* @__PURE__ */ jsx(
|
|
6154
|
+
"select",
|
|
6155
|
+
{
|
|
6156
|
+
id: fieldId,
|
|
6157
|
+
value: values[field.id] ?? "",
|
|
6158
|
+
onChange: (e) => updateValue(field.id, e.target.value),
|
|
6159
|
+
disabled: submitted,
|
|
6160
|
+
"aria-required": field.required,
|
|
6161
|
+
style: selectInputStyle,
|
|
6162
|
+
children: field.options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt, children: opt }, opt))
|
|
6163
|
+
}
|
|
6164
|
+
)
|
|
6165
|
+
] }, field.id);
|
|
6166
|
+
case "checkbox":
|
|
6167
|
+
return /* @__PURE__ */ jsx("div", { style: fieldStyle, children: /* @__PURE__ */ jsxs("label", { style: checkboxLabelStyle, children: [
|
|
6168
|
+
/* @__PURE__ */ jsx(
|
|
6169
|
+
"input",
|
|
6170
|
+
{
|
|
6171
|
+
id: fieldId,
|
|
6172
|
+
type: "checkbox",
|
|
6173
|
+
checked: values[field.id] ?? false,
|
|
6174
|
+
onChange: (e) => updateValue(field.id, e.target.checked),
|
|
6175
|
+
disabled: submitted
|
|
6176
|
+
}
|
|
6177
|
+
),
|
|
6178
|
+
field.label
|
|
6179
|
+
] }) }, field.id);
|
|
6180
|
+
case "range": {
|
|
6181
|
+
const min2 = field.min ?? 0;
|
|
6182
|
+
const max2 = field.max ?? 100;
|
|
6183
|
+
const step = field.step ?? 1;
|
|
6184
|
+
const currentValue = values[field.id] ?? min2;
|
|
6185
|
+
const displayValue = field.unit ? `${String(currentValue)}${field.unit}` : String(currentValue);
|
|
6186
|
+
return /* @__PURE__ */ jsxs("div", { style: fieldStyle, children: [
|
|
6187
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: fieldId, style: labelStyle3, children: [
|
|
6188
|
+
field.label,
|
|
6189
|
+
/* @__PURE__ */ jsx("span", { style: rangeValueStyle, children: displayValue })
|
|
6190
|
+
] }),
|
|
6191
|
+
/* @__PURE__ */ jsx(
|
|
6192
|
+
"input",
|
|
6193
|
+
{
|
|
6194
|
+
id: fieldId,
|
|
6195
|
+
type: "range",
|
|
6196
|
+
min: min2,
|
|
6197
|
+
max: max2,
|
|
6198
|
+
step,
|
|
6199
|
+
value: currentValue,
|
|
6200
|
+
onChange: (e) => updateValue(field.id, Number(e.target.value)),
|
|
6201
|
+
disabled: submitted,
|
|
6202
|
+
"aria-valuemin": min2,
|
|
6203
|
+
"aria-valuemax": max2,
|
|
6204
|
+
"aria-valuenow": currentValue,
|
|
6205
|
+
"aria-valuetext": displayValue,
|
|
6206
|
+
style: { width: "100%", accentColor: "var(--glyph-accent, #0a9d7c)" }
|
|
6207
|
+
}
|
|
6208
|
+
)
|
|
6209
|
+
] }, field.id);
|
|
6210
|
+
}
|
|
6211
|
+
}
|
|
6212
|
+
}
|
|
6213
|
+
function Form({ data, block, onInteraction }) {
|
|
6214
|
+
const { title, description, submitLabel = "Submit", fields } = data;
|
|
6215
|
+
const baseId = `glyph-form-${block.id}`;
|
|
6216
|
+
const [values, setValues] = useState(() => {
|
|
6217
|
+
const init = {};
|
|
6218
|
+
for (const field of fields) {
|
|
6219
|
+
switch (field.type) {
|
|
6220
|
+
case "text":
|
|
6221
|
+
case "textarea":
|
|
6222
|
+
init[field.id] = field.default ?? "";
|
|
6223
|
+
break;
|
|
6224
|
+
case "select":
|
|
6225
|
+
init[field.id] = field.default ?? field.options[0] ?? "";
|
|
6226
|
+
break;
|
|
6227
|
+
case "checkbox":
|
|
6228
|
+
init[field.id] = field.default ?? false;
|
|
6229
|
+
break;
|
|
6230
|
+
case "range":
|
|
6231
|
+
init[field.id] = field.default ?? field.min ?? 0;
|
|
6232
|
+
break;
|
|
6233
|
+
}
|
|
6234
|
+
}
|
|
6235
|
+
return init;
|
|
6236
|
+
});
|
|
6237
|
+
const [submitted, setSubmitted] = useState(false);
|
|
6238
|
+
const [validation, setValidation] = useState({});
|
|
6239
|
+
const updateValue = (fieldId, value) => {
|
|
6240
|
+
setValues((prev) => ({ ...prev, [fieldId]: value }));
|
|
6241
|
+
if (validation[fieldId]) {
|
|
6242
|
+
setValidation((prev) => ({ ...prev, [fieldId]: false }));
|
|
6243
|
+
}
|
|
6244
|
+
};
|
|
6245
|
+
const handleSubmit = (e) => {
|
|
6246
|
+
e.preventDefault();
|
|
6247
|
+
const errors = {};
|
|
6248
|
+
for (const field of fields) {
|
|
6249
|
+
if ("required" in field && field.required) {
|
|
6250
|
+
const val = values[field.id];
|
|
6251
|
+
if (val === "" || val === void 0) {
|
|
6252
|
+
errors[field.id] = true;
|
|
6253
|
+
}
|
|
6254
|
+
}
|
|
6255
|
+
}
|
|
6256
|
+
if (Object.keys(errors).length > 0) {
|
|
6257
|
+
setValidation(errors);
|
|
6258
|
+
return;
|
|
6259
|
+
}
|
|
6260
|
+
setSubmitted(true);
|
|
6261
|
+
if (onInteraction) {
|
|
6262
|
+
onInteraction({
|
|
6263
|
+
kind: "form-submit",
|
|
6264
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6265
|
+
blockId: block.id,
|
|
6266
|
+
blockType: block.type,
|
|
6267
|
+
payload: {
|
|
6268
|
+
values: { ...values },
|
|
6269
|
+
fields: fields.map((f) => ({
|
|
6270
|
+
id: f.id,
|
|
6271
|
+
label: f.label,
|
|
6272
|
+
type: f.type,
|
|
6273
|
+
value: values[f.id] !== void 0 ? values[f.id] : ""
|
|
6274
|
+
}))
|
|
6275
|
+
}
|
|
6276
|
+
});
|
|
6277
|
+
}
|
|
6278
|
+
};
|
|
6279
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Form", style: containerStyle8, children: [
|
|
6280
|
+
title && /* @__PURE__ */ jsx("div", { style: headerStyle7, children: title }),
|
|
6281
|
+
description && /* @__PURE__ */ jsx("div", { style: descriptionStyle, children: /* @__PURE__ */ jsx(RichText, { content: description }) }),
|
|
6282
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, style: formStyle, noValidate: true, children: [
|
|
6283
|
+
fields.map(
|
|
6284
|
+
(field) => renderField({ field, baseId, values, validation, submitted, updateValue })
|
|
6285
|
+
),
|
|
6286
|
+
/* @__PURE__ */ jsx(
|
|
6287
|
+
"button",
|
|
6288
|
+
{
|
|
6289
|
+
type: "submit",
|
|
6290
|
+
disabled: submitted,
|
|
6291
|
+
style: {
|
|
6292
|
+
...submitButtonStyle,
|
|
6293
|
+
opacity: submitted ? 0.5 : 1,
|
|
6294
|
+
cursor: submitted ? "default" : "pointer"
|
|
6295
|
+
},
|
|
6296
|
+
children: submitted ? "Submitted" : submitLabel
|
|
6297
|
+
}
|
|
6298
|
+
)
|
|
6299
|
+
] })
|
|
6300
|
+
] });
|
|
6301
|
+
}
|
|
6302
|
+
|
|
6303
|
+
// src/form/index.ts
|
|
6304
|
+
var formDefinition = {
|
|
6305
|
+
type: "ui:form",
|
|
6306
|
+
schema: formSchema,
|
|
6307
|
+
render: Form
|
|
6308
|
+
};
|
|
6309
|
+
|
|
6310
|
+
// src/kanban/styles.ts
|
|
6311
|
+
var containerStyle9 = {
|
|
6312
|
+
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
6313
|
+
color: "var(--glyph-text, #1a2035)",
|
|
6314
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6315
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
6316
|
+
overflow: "hidden"
|
|
6317
|
+
};
|
|
6318
|
+
var headerStyle8 = {
|
|
6319
|
+
fontWeight: 700,
|
|
6320
|
+
fontSize: "1.125rem",
|
|
6321
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
6322
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6323
|
+
color: "var(--glyph-heading, #0a0e1a)"
|
|
6324
|
+
};
|
|
6325
|
+
var boardStyle = {
|
|
6326
|
+
display: "flex",
|
|
6327
|
+
gap: "var(--glyph-spacing-sm, 0.5rem)",
|
|
6328
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
6329
|
+
overflowX: "auto",
|
|
6330
|
+
minHeight: "200px"
|
|
6331
|
+
};
|
|
6332
|
+
function columnStyle(isOver) {
|
|
6333
|
+
return {
|
|
6334
|
+
flex: "1 1 0",
|
|
6335
|
+
minWidth: "180px",
|
|
6336
|
+
background: isOver ? "var(--glyph-accent-subtle, #e6f6f2)" : "var(--glyph-kanban-column-bg, var(--glyph-surface, #e8ecf3))",
|
|
6337
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
6338
|
+
padding: "var(--glyph-spacing-sm, 0.5rem)",
|
|
6339
|
+
display: "flex",
|
|
6340
|
+
flexDirection: "column",
|
|
6341
|
+
transition: "background 0.15s ease"
|
|
6342
|
+
};
|
|
6343
|
+
}
|
|
6344
|
+
var columnHeaderStyle = {
|
|
6345
|
+
fontWeight: 700,
|
|
6346
|
+
fontSize: "0.8125rem",
|
|
6347
|
+
textTransform: "uppercase",
|
|
6348
|
+
letterSpacing: "0.5px",
|
|
6349
|
+
padding: "0.375rem 0.5rem",
|
|
6350
|
+
marginBottom: "0.375rem",
|
|
6351
|
+
display: "flex",
|
|
6352
|
+
justifyContent: "space-between",
|
|
6353
|
+
alignItems: "center"
|
|
6354
|
+
};
|
|
6355
|
+
var columnCountStyle = {
|
|
6356
|
+
fontSize: "0.6875rem",
|
|
6357
|
+
fontWeight: 400,
|
|
6358
|
+
color: "var(--glyph-text-muted, #6b7a94)"
|
|
6359
|
+
};
|
|
6360
|
+
function cardStyle(isGrabbed, priority) {
|
|
6361
|
+
const priorityColors = {
|
|
6362
|
+
high: "var(--glyph-kanban-priority-high, #dc2626)",
|
|
6363
|
+
medium: "var(--glyph-kanban-priority-medium, #f59e0b)",
|
|
6364
|
+
low: "var(--glyph-kanban-priority-low, #22c55e)"
|
|
6365
|
+
};
|
|
6366
|
+
return {
|
|
6367
|
+
background: "var(--glyph-kanban-card-bg, var(--glyph-surface-raised, #f4f6fa))",
|
|
6368
|
+
border: `1px solid var(--glyph-kanban-card-border, var(--glyph-border, #d0d8e4))`,
|
|
6369
|
+
borderRadius: "var(--glyph-radius-sm, 0.375rem)",
|
|
6370
|
+
padding: "0.625rem 0.75rem",
|
|
6371
|
+
marginBottom: "0.375rem",
|
|
6372
|
+
cursor: isGrabbed ? "grabbing" : "grab",
|
|
6373
|
+
userSelect: "none",
|
|
6374
|
+
boxShadow: isGrabbed ? "var(--glyph-kanban-drag-shadow, var(--glyph-shadow-md, 0 4px 12px rgba(0,0,0,0.15)))" : "none",
|
|
6375
|
+
borderLeft: priority && priorityColors[priority] ? `3px solid ${priorityColors[priority]}` : void 0,
|
|
6376
|
+
outline: isGrabbed ? "2px solid var(--glyph-accent, #0a9d7c)" : "none",
|
|
6377
|
+
outlineOffset: "-2px"
|
|
6378
|
+
};
|
|
6379
|
+
}
|
|
6380
|
+
var cardTitleStyle = {
|
|
6381
|
+
fontWeight: 600,
|
|
6382
|
+
fontSize: "0.875rem",
|
|
6383
|
+
marginBottom: "0.25rem"
|
|
6384
|
+
};
|
|
6385
|
+
var cardDescStyle = {
|
|
6386
|
+
fontSize: "0.75rem",
|
|
6387
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
6388
|
+
lineHeight: 1.4
|
|
6389
|
+
};
|
|
6390
|
+
var tagContainerStyle = {
|
|
6391
|
+
display: "flex",
|
|
6392
|
+
flexWrap: "wrap",
|
|
6393
|
+
gap: "0.25rem",
|
|
6394
|
+
marginTop: "0.375rem"
|
|
6395
|
+
};
|
|
6396
|
+
var tagStyle = {
|
|
6397
|
+
fontSize: "0.625rem",
|
|
6398
|
+
fontWeight: 600,
|
|
6399
|
+
padding: "0.125rem 0.375rem",
|
|
6400
|
+
borderRadius: "9999px",
|
|
6401
|
+
background: "var(--glyph-accent-subtle, #e6f6f2)",
|
|
6402
|
+
color: "var(--glyph-accent, #0a9d7c)"
|
|
6403
|
+
};
|
|
6404
|
+
var limitStyle = {
|
|
6405
|
+
fontSize: "0.625rem",
|
|
6406
|
+
color: "var(--glyph-text-muted, #6b7a94)"
|
|
6407
|
+
};
|
|
6408
|
+
function Kanban({
|
|
6409
|
+
data,
|
|
6410
|
+
block,
|
|
6411
|
+
onInteraction
|
|
6412
|
+
}) {
|
|
6413
|
+
const { title } = data;
|
|
6414
|
+
const baseId = `glyph-kanban-${block.id}`;
|
|
6415
|
+
const [columns, setColumns] = useState(
|
|
6416
|
+
() => data.columns.map((col) => ({ ...col, cards: [...col.cards] }))
|
|
6417
|
+
);
|
|
6418
|
+
const [grabbed, setGrabbed] = useState(null);
|
|
6419
|
+
const moveCard = (cardId, sourceColId, destColId, destIndex) => {
|
|
6420
|
+
const newColumns = columns.map((col) => ({
|
|
6421
|
+
...col,
|
|
6422
|
+
cards: [...col.cards]
|
|
6423
|
+
}));
|
|
6424
|
+
const sourceCol = newColumns.find((c) => c.id === sourceColId);
|
|
6425
|
+
const destCol = newColumns.find((c) => c.id === destColId);
|
|
6426
|
+
if (!sourceCol || !destCol) return;
|
|
6427
|
+
const cardIndex = sourceCol.cards.findIndex((c) => c.id === cardId);
|
|
6428
|
+
if (cardIndex === -1) return;
|
|
6429
|
+
const [card] = sourceCol.cards.splice(cardIndex, 1);
|
|
6430
|
+
if (!card) return;
|
|
6431
|
+
destCol.cards.splice(destIndex, 0, card);
|
|
6432
|
+
setColumns(newColumns);
|
|
6433
|
+
if (onInteraction) {
|
|
6434
|
+
onInteraction({
|
|
6435
|
+
kind: "kanban-move",
|
|
6436
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6437
|
+
blockId: block.id,
|
|
6438
|
+
blockType: block.type,
|
|
6439
|
+
payload: {
|
|
6440
|
+
cardId: card.id,
|
|
6441
|
+
cardTitle: card.title,
|
|
6442
|
+
sourceColumnId: sourceColId,
|
|
6443
|
+
sourceColumnTitle: sourceCol.title,
|
|
6444
|
+
destinationColumnId: destColId,
|
|
6445
|
+
destinationColumnTitle: destCol.title,
|
|
6446
|
+
position: destIndex,
|
|
6447
|
+
allColumns: newColumns.map((c) => ({
|
|
6448
|
+
id: c.id,
|
|
6449
|
+
title: c.title,
|
|
6450
|
+
cardIds: c.cards.map((card2) => card2.id)
|
|
6451
|
+
}))
|
|
6452
|
+
}
|
|
6453
|
+
});
|
|
6454
|
+
}
|
|
6455
|
+
};
|
|
6456
|
+
const handleCardKeyDown = (e, cardId, columnId, cardIndex) => {
|
|
6457
|
+
if (e.key === " " || e.key === "Enter") {
|
|
6458
|
+
e.preventDefault();
|
|
6459
|
+
if (grabbed === null) {
|
|
6460
|
+
setGrabbed({ cardId, columnId, cardIndex });
|
|
6461
|
+
} else {
|
|
6462
|
+
setGrabbed(null);
|
|
6463
|
+
}
|
|
6464
|
+
} else if (e.key === "Escape") {
|
|
6465
|
+
setGrabbed(null);
|
|
6466
|
+
} else if (grabbed && grabbed.cardId === cardId) {
|
|
6467
|
+
const colIndex = columns.findIndex((c) => c.id === grabbed.columnId);
|
|
6468
|
+
const col = columns[colIndex];
|
|
6469
|
+
if (!col) return;
|
|
6470
|
+
if (e.key === "ArrowUp") {
|
|
6471
|
+
e.preventDefault();
|
|
6472
|
+
if (grabbed.cardIndex > 0) {
|
|
6473
|
+
moveCard(cardId, grabbed.columnId, grabbed.columnId, grabbed.cardIndex - 1);
|
|
6474
|
+
setGrabbed({ ...grabbed, cardIndex: grabbed.cardIndex - 1 });
|
|
6475
|
+
}
|
|
6476
|
+
} else if (e.key === "ArrowDown") {
|
|
6477
|
+
e.preventDefault();
|
|
6478
|
+
if (grabbed.cardIndex < col.cards.length - 1) {
|
|
6479
|
+
moveCard(cardId, grabbed.columnId, grabbed.columnId, grabbed.cardIndex + 1);
|
|
6480
|
+
setGrabbed({ ...grabbed, cardIndex: grabbed.cardIndex + 1 });
|
|
6481
|
+
}
|
|
6482
|
+
} else if (e.key === "ArrowLeft") {
|
|
6483
|
+
e.preventDefault();
|
|
6484
|
+
if (colIndex > 0) {
|
|
6485
|
+
const prevCol = columns[colIndex - 1];
|
|
6486
|
+
if (!prevCol) return;
|
|
6487
|
+
const newIndex = prevCol.cards.length;
|
|
6488
|
+
moveCard(cardId, grabbed.columnId, prevCol.id, newIndex);
|
|
6489
|
+
setGrabbed({ cardId, columnId: prevCol.id, cardIndex: newIndex });
|
|
6490
|
+
}
|
|
6491
|
+
} else if (e.key === "ArrowRight") {
|
|
6492
|
+
e.preventDefault();
|
|
6493
|
+
if (colIndex < columns.length - 1) {
|
|
6494
|
+
const nextCol = columns[colIndex + 1];
|
|
6495
|
+
if (!nextCol) return;
|
|
6496
|
+
const newIndex = nextCol.cards.length;
|
|
6497
|
+
moveCard(cardId, grabbed.columnId, nextCol.id, newIndex);
|
|
6498
|
+
setGrabbed({ cardId, columnId: nextCol.id, cardIndex: newIndex });
|
|
6499
|
+
}
|
|
6500
|
+
}
|
|
6501
|
+
}
|
|
6502
|
+
};
|
|
6503
|
+
return /* @__PURE__ */ jsxs("div", { id: baseId, role: "region", "aria-label": title ?? "Kanban Board", style: containerStyle9, children: [
|
|
6504
|
+
title && /* @__PURE__ */ jsx("div", { style: headerStyle8, children: title }),
|
|
6505
|
+
/* @__PURE__ */ jsx("div", { style: boardStyle, children: columns.map((col) => /* @__PURE__ */ jsxs("div", { style: columnStyle(false), children: [
|
|
6506
|
+
/* @__PURE__ */ jsxs("div", { style: columnHeaderStyle, children: [
|
|
6507
|
+
/* @__PURE__ */ jsx("span", { children: col.title }),
|
|
6508
|
+
/* @__PURE__ */ jsxs("span", { style: columnCountStyle, children: [
|
|
6509
|
+
String(col.cards.length),
|
|
6510
|
+
col.limit !== void 0 && /* @__PURE__ */ jsxs("span", { style: limitStyle, children: [
|
|
6511
|
+
" / ",
|
|
6512
|
+
String(col.limit)
|
|
6513
|
+
] })
|
|
6514
|
+
] })
|
|
6515
|
+
] }),
|
|
6516
|
+
/* @__PURE__ */ jsx("div", { role: "list", "aria-label": col.title, children: col.cards.map((card, cardIndex) => {
|
|
6517
|
+
const isGrabbed = grabbed !== null && grabbed.cardId === card.id;
|
|
6518
|
+
return /* @__PURE__ */ jsxs(
|
|
6519
|
+
"div",
|
|
6520
|
+
{
|
|
6521
|
+
role: "listitem",
|
|
6522
|
+
"aria-grabbed": isGrabbed,
|
|
6523
|
+
"aria-label": `${card.title}${card.priority ? `, ${card.priority} priority` : ""}`,
|
|
6524
|
+
tabIndex: 0,
|
|
6525
|
+
style: cardStyle(isGrabbed, card.priority),
|
|
6526
|
+
onKeyDown: (e) => handleCardKeyDown(e, card.id, col.id, cardIndex),
|
|
6527
|
+
children: [
|
|
6528
|
+
/* @__PURE__ */ jsx("div", { style: cardTitleStyle, children: card.title }),
|
|
6529
|
+
card.description && /* @__PURE__ */ jsx("div", { style: cardDescStyle, children: card.description }),
|
|
6530
|
+
card.tags && card.tags.length > 0 && /* @__PURE__ */ jsx("div", { style: tagContainerStyle, children: card.tags.map((tag) => /* @__PURE__ */ jsx("span", { style: tagStyle, children: tag }, tag)) })
|
|
6531
|
+
]
|
|
6532
|
+
},
|
|
6533
|
+
card.id
|
|
6534
|
+
);
|
|
6535
|
+
}) })
|
|
6536
|
+
] }, col.id)) }),
|
|
6537
|
+
/* @__PURE__ */ jsx(
|
|
6538
|
+
"div",
|
|
6539
|
+
{
|
|
6540
|
+
"aria-live": "assertive",
|
|
6541
|
+
style: {
|
|
6542
|
+
position: "absolute",
|
|
6543
|
+
width: "1px",
|
|
6544
|
+
height: "1px",
|
|
6545
|
+
padding: 0,
|
|
6546
|
+
margin: "-1px",
|
|
6547
|
+
overflow: "hidden",
|
|
6548
|
+
clip: "rect(0,0,0,0)",
|
|
6549
|
+
whiteSpace: "nowrap",
|
|
6550
|
+
border: 0
|
|
6551
|
+
},
|
|
6552
|
+
children: grabbed !== null && `${columns.find((c) => c.id === grabbed.columnId)?.cards[grabbed.cardIndex]?.title ?? "Card"} grabbed in ${columns.find((c) => c.id === grabbed.columnId)?.title ?? "column"}. Use arrow keys to move.`
|
|
6553
|
+
}
|
|
6554
|
+
)
|
|
6555
|
+
] });
|
|
6556
|
+
}
|
|
6557
|
+
|
|
6558
|
+
// src/kanban/index.ts
|
|
6559
|
+
var kanbanDefinition = {
|
|
6560
|
+
type: "ui:kanban",
|
|
6561
|
+
schema: kanbanSchema,
|
|
6562
|
+
render: Kanban
|
|
6563
|
+
};
|
|
6564
|
+
|
|
6565
|
+
// src/annotate/styles.ts
|
|
6566
|
+
var containerStyle10 = {
|
|
6567
|
+
fontFamily: "var(--glyph-font-body, system-ui, sans-serif)",
|
|
6568
|
+
color: "var(--glyph-text, #1a2035)",
|
|
6569
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6570
|
+
borderRadius: "var(--glyph-radius-md, 0.5rem)",
|
|
6571
|
+
overflow: "hidden"
|
|
6572
|
+
};
|
|
6573
|
+
var headerStyle9 = {
|
|
6574
|
+
fontWeight: 700,
|
|
6575
|
+
fontSize: "1.125rem",
|
|
6576
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
6577
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6578
|
+
color: "var(--glyph-heading, #0a0e1a)"
|
|
6579
|
+
};
|
|
6580
|
+
var bodyStyle2 = {
|
|
6581
|
+
display: "flex",
|
|
6582
|
+
minHeight: "200px"
|
|
6583
|
+
};
|
|
6584
|
+
var textPaneStyle = {
|
|
6585
|
+
flex: 1,
|
|
6586
|
+
padding: "var(--glyph-spacing-md, 1rem)",
|
|
6587
|
+
fontFamily: "var(--glyph-font-mono, ui-monospace, monospace)",
|
|
6588
|
+
fontSize: "0.8125rem",
|
|
6589
|
+
lineHeight: 1.8,
|
|
6590
|
+
whiteSpace: "pre-wrap",
|
|
6591
|
+
wordBreak: "break-word",
|
|
6592
|
+
position: "relative",
|
|
6593
|
+
cursor: "text"
|
|
6594
|
+
};
|
|
6595
|
+
var labelPickerStyle = {
|
|
6596
|
+
position: "absolute",
|
|
6597
|
+
zIndex: 10,
|
|
6598
|
+
background: "var(--glyph-surface-raised, #f4f6fa)",
|
|
6599
|
+
border: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6600
|
+
borderRadius: "var(--glyph-radius-sm, 0.375rem)",
|
|
6601
|
+
boxShadow: "var(--glyph-shadow-md, 0 4px 12px rgba(0,0,0,0.15))",
|
|
6602
|
+
padding: "0.25rem 0",
|
|
6603
|
+
minWidth: "120px"
|
|
6604
|
+
};
|
|
6605
|
+
function labelOptionStyle() {
|
|
6606
|
+
return {
|
|
6607
|
+
display: "flex",
|
|
6608
|
+
alignItems: "center",
|
|
6609
|
+
gap: "0.5rem",
|
|
6610
|
+
padding: "0.375rem 0.75rem",
|
|
6611
|
+
cursor: "pointer",
|
|
6612
|
+
fontSize: "0.8125rem",
|
|
6613
|
+
background: "transparent",
|
|
6614
|
+
border: "none",
|
|
6615
|
+
width: "100%",
|
|
6616
|
+
textAlign: "left",
|
|
6617
|
+
color: "var(--glyph-text, #1a2035)"
|
|
6618
|
+
};
|
|
6619
|
+
}
|
|
6620
|
+
function colorDotStyle(color3) {
|
|
6621
|
+
return {
|
|
6622
|
+
width: "0.625rem",
|
|
6623
|
+
height: "0.625rem",
|
|
6624
|
+
borderRadius: "50%",
|
|
6625
|
+
background: color3,
|
|
6626
|
+
flexShrink: 0
|
|
6627
|
+
};
|
|
6628
|
+
}
|
|
6629
|
+
var sidebarStyle = {
|
|
6630
|
+
width: "220px",
|
|
6631
|
+
borderLeft: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6632
|
+
background: "var(--glyph-annotate-sidebar-bg, var(--glyph-surface, #e8ecf3))",
|
|
6633
|
+
overflow: "auto"
|
|
6634
|
+
};
|
|
6635
|
+
var sidebarHeaderStyle = {
|
|
6636
|
+
fontWeight: 700,
|
|
6637
|
+
fontSize: "0.75rem",
|
|
6638
|
+
textTransform: "uppercase",
|
|
6639
|
+
letterSpacing: "0.5px",
|
|
6640
|
+
padding: "0.75rem",
|
|
6641
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6642
|
+
color: "var(--glyph-text-muted, #6b7a94)"
|
|
6643
|
+
};
|
|
6644
|
+
function annotationItemStyle(color3) {
|
|
6645
|
+
return {
|
|
6646
|
+
padding: "0.5rem 0.75rem",
|
|
6647
|
+
borderBottom: "1px solid var(--glyph-border, #d0d8e4)",
|
|
6648
|
+
borderLeft: `3px solid ${color3}`,
|
|
6649
|
+
fontSize: "0.75rem"
|
|
6650
|
+
};
|
|
6651
|
+
}
|
|
6652
|
+
var annotationTextStyle = {
|
|
6653
|
+
fontFamily: "var(--glyph-font-mono, ui-monospace, monospace)",
|
|
6654
|
+
fontSize: "0.6875rem",
|
|
6655
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
6656
|
+
marginTop: "0.25rem",
|
|
6657
|
+
overflow: "hidden",
|
|
6658
|
+
textOverflow: "ellipsis",
|
|
6659
|
+
whiteSpace: "nowrap"
|
|
6660
|
+
};
|
|
6661
|
+
var annotationNoteStyle = {
|
|
6662
|
+
fontSize: "0.6875rem",
|
|
6663
|
+
fontStyle: "italic",
|
|
6664
|
+
color: "var(--glyph-text-muted, #6b7a94)",
|
|
6665
|
+
marginTop: "0.125rem"
|
|
6666
|
+
};
|
|
6667
|
+
function computeSegments(text, annotations) {
|
|
6668
|
+
if (typeof text !== "string") {
|
|
6669
|
+
return [{ text: "", start: 0, annotation: null }];
|
|
6670
|
+
}
|
|
6671
|
+
if (annotations.length === 0) {
|
|
6672
|
+
return [{ text, start: 0, annotation: null }];
|
|
6673
|
+
}
|
|
6674
|
+
const sorted = [...annotations].sort((a, b) => a.start - b.start);
|
|
6675
|
+
const segments = [];
|
|
6676
|
+
let cursor = 0;
|
|
6677
|
+
for (const ann of sorted) {
|
|
6678
|
+
if (ann.start > cursor) {
|
|
6679
|
+
segments.push({ text: text.slice(cursor, ann.start), start: cursor, annotation: null });
|
|
6680
|
+
}
|
|
6681
|
+
segments.push({
|
|
6682
|
+
text: text.slice(ann.start, ann.end),
|
|
6683
|
+
start: ann.start,
|
|
6684
|
+
annotation: ann
|
|
6685
|
+
});
|
|
6686
|
+
cursor = ann.end;
|
|
6687
|
+
}
|
|
6688
|
+
if (cursor < text.length) {
|
|
6689
|
+
segments.push({ text: text.slice(cursor), start: cursor, annotation: null });
|
|
6690
|
+
}
|
|
6691
|
+
return segments;
|
|
6692
|
+
}
|
|
6693
|
+
function Annotate({
|
|
6694
|
+
data,
|
|
6695
|
+
block,
|
|
6696
|
+
onInteraction
|
|
6697
|
+
}) {
|
|
6698
|
+
const { title, labels, text } = data;
|
|
6699
|
+
const baseId = `glyph-annotate-${block.id}`;
|
|
6700
|
+
const [annotations, setAnnotations] = useState(data.annotations ?? []);
|
|
6701
|
+
const [pickerPos, setPickerPos] = useState(null);
|
|
6702
|
+
const [pendingSelection, setPendingSelection] = useState(null);
|
|
6703
|
+
const textRef = useRef(null);
|
|
6704
|
+
const handleMouseUp = useCallback(() => {
|
|
6705
|
+
const selection = window.getSelection();
|
|
6706
|
+
if (!selection || selection.isCollapsed || !textRef.current) return;
|
|
6707
|
+
const range = selection.getRangeAt(0);
|
|
6708
|
+
if (!range || !textRef.current.contains(range.commonAncestorContainer)) return;
|
|
6709
|
+
const selectedText = selection.toString();
|
|
6710
|
+
if (!selectedText.trim()) return;
|
|
6711
|
+
const preCaretRange = document.createRange();
|
|
6712
|
+
preCaretRange.selectNodeContents(textRef.current);
|
|
6713
|
+
preCaretRange.setEnd(range.startContainer, range.startOffset);
|
|
6714
|
+
const startOffset = preCaretRange.toString().length;
|
|
6715
|
+
const endOffset = startOffset + selectedText.length;
|
|
6716
|
+
const rect = range.getBoundingClientRect();
|
|
6717
|
+
const containerRect = textRef.current.getBoundingClientRect();
|
|
6718
|
+
setPendingSelection({ start: startOffset, end: endOffset, text: selectedText });
|
|
6719
|
+
setPickerPos({
|
|
6720
|
+
x: rect.left - containerRect.left,
|
|
6721
|
+
y: rect.bottom - containerRect.top + 4
|
|
6722
|
+
});
|
|
6723
|
+
}, []);
|
|
6724
|
+
const selectLabel = (labelName) => {
|
|
6725
|
+
if (!pendingSelection) return;
|
|
6726
|
+
const newAnnotation = {
|
|
6727
|
+
start: pendingSelection.start,
|
|
6728
|
+
end: pendingSelection.end,
|
|
6729
|
+
label: labelName
|
|
6730
|
+
};
|
|
6731
|
+
const newAnnotations = [...annotations, newAnnotation];
|
|
6732
|
+
setAnnotations(newAnnotations);
|
|
6733
|
+
setPickerPos(null);
|
|
6734
|
+
setPendingSelection(null);
|
|
6735
|
+
window.getSelection()?.removeAllRanges();
|
|
6736
|
+
if (onInteraction) {
|
|
6737
|
+
onInteraction({
|
|
6738
|
+
kind: "annotate-create",
|
|
6739
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6740
|
+
blockId: block.id,
|
|
6741
|
+
blockType: block.type,
|
|
6742
|
+
payload: {
|
|
6743
|
+
start: newAnnotation.start,
|
|
6744
|
+
end: newAnnotation.end,
|
|
6745
|
+
selectedText: pendingSelection.text,
|
|
6746
|
+
label: labelName,
|
|
6747
|
+
allAnnotations: newAnnotations.map((a) => ({
|
|
6748
|
+
start: a.start,
|
|
6749
|
+
end: a.end,
|
|
6750
|
+
text: typeof text === "string" ? text.slice(a.start, a.end) : "",
|
|
6751
|
+
label: a.label
|
|
6752
|
+
}))
|
|
6753
|
+
}
|
|
6754
|
+
});
|
|
6755
|
+
}
|
|
6756
|
+
};
|
|
6757
|
+
const closePicker = (e) => {
|
|
6758
|
+
if (e.target.closest("[data-label-picker]")) return;
|
|
6759
|
+
setPickerPos(null);
|
|
6760
|
+
setPendingSelection(null);
|
|
6761
|
+
};
|
|
6762
|
+
const segments = computeSegments(text, annotations);
|
|
6763
|
+
const labelColorMap = new Map(labels.map((l) => [l.name, l.color]));
|
|
6764
|
+
return /* @__PURE__ */ jsxs(
|
|
6765
|
+
"div",
|
|
6766
|
+
{
|
|
6767
|
+
id: baseId,
|
|
6768
|
+
role: "region",
|
|
6769
|
+
"aria-label": title ?? "Annotate",
|
|
6770
|
+
style: containerStyle10,
|
|
6771
|
+
onClick: closePicker,
|
|
6772
|
+
children: [
|
|
6773
|
+
title && /* @__PURE__ */ jsx("div", { style: headerStyle9, children: title }),
|
|
6774
|
+
/* @__PURE__ */ jsxs("div", { style: bodyStyle2, children: [
|
|
6775
|
+
/* @__PURE__ */ jsxs("div", { ref: textRef, role: "document", style: textPaneStyle, onMouseUp: handleMouseUp, children: [
|
|
6776
|
+
typeof text === "string" ? segments.map((seg, i) => {
|
|
6777
|
+
if (seg.annotation) {
|
|
6778
|
+
const color3 = labelColorMap.get(seg.annotation.label) ?? "#888";
|
|
6779
|
+
return /* @__PURE__ */ jsx(
|
|
6780
|
+
"mark",
|
|
6781
|
+
{
|
|
6782
|
+
style: {
|
|
6783
|
+
backgroundColor: `${color3}33`,
|
|
6784
|
+
borderBottom: `2px solid ${color3}`,
|
|
6785
|
+
padding: "0 1px"
|
|
6786
|
+
},
|
|
6787
|
+
title: `${seg.annotation.label}${seg.annotation.note ? `: ${seg.annotation.note}` : ""}`,
|
|
6788
|
+
children: seg.text
|
|
6789
|
+
},
|
|
6790
|
+
i
|
|
6791
|
+
);
|
|
6792
|
+
}
|
|
6793
|
+
return /* @__PURE__ */ jsx("span", { children: seg.text }, i);
|
|
6794
|
+
}) : /* @__PURE__ */ jsx(RichText, { content: text }),
|
|
6795
|
+
pickerPos && /* @__PURE__ */ jsx(
|
|
6796
|
+
"div",
|
|
6797
|
+
{
|
|
6798
|
+
role: "menu",
|
|
6799
|
+
"data-label-picker": true,
|
|
6800
|
+
style: {
|
|
6801
|
+
...labelPickerStyle,
|
|
6802
|
+
left: `${String(pickerPos.x)}px`,
|
|
6803
|
+
top: `${String(pickerPos.y)}px`
|
|
6804
|
+
},
|
|
6805
|
+
children: labels.map((label) => /* @__PURE__ */ jsxs(
|
|
6806
|
+
"button",
|
|
6807
|
+
{
|
|
6808
|
+
role: "menuitem",
|
|
6809
|
+
style: labelOptionStyle(),
|
|
6810
|
+
onClick: (e) => {
|
|
6811
|
+
e.stopPropagation();
|
|
6812
|
+
selectLabel(label.name);
|
|
6813
|
+
},
|
|
6814
|
+
children: [
|
|
6815
|
+
/* @__PURE__ */ jsx("span", { style: colorDotStyle(label.color) }),
|
|
6816
|
+
label.name
|
|
6817
|
+
]
|
|
6818
|
+
},
|
|
6819
|
+
label.name
|
|
6820
|
+
))
|
|
6821
|
+
}
|
|
6822
|
+
)
|
|
6823
|
+
] }),
|
|
6824
|
+
/* @__PURE__ */ jsxs("div", { style: sidebarStyle, role: "complementary", "aria-label": "Annotations", children: [
|
|
6825
|
+
/* @__PURE__ */ jsxs("div", { style: sidebarHeaderStyle, children: [
|
|
6826
|
+
"Annotations (",
|
|
6827
|
+
String(annotations.length),
|
|
6828
|
+
")"
|
|
6829
|
+
] }),
|
|
6830
|
+
/* @__PURE__ */ jsxs("div", { role: "list", children: [
|
|
6831
|
+
annotations.map((ann, i) => {
|
|
6832
|
+
const color3 = labelColorMap.get(ann.label) ?? "#888";
|
|
6833
|
+
const annotatedText = typeof text === "string" ? text.slice(ann.start, ann.end) : "";
|
|
6834
|
+
return /* @__PURE__ */ jsxs("div", { role: "listitem", style: annotationItemStyle(color3), children: [
|
|
6835
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.375rem" }, children: [
|
|
6836
|
+
/* @__PURE__ */ jsx("span", { style: colorDotStyle(color3) }),
|
|
6837
|
+
/* @__PURE__ */ jsx("strong", { style: { fontSize: "0.75rem" }, children: ann.label })
|
|
6838
|
+
] }),
|
|
6839
|
+
/* @__PURE__ */ jsx("div", { style: annotationTextStyle, children: annotatedText }),
|
|
6840
|
+
ann.note && /* @__PURE__ */ jsx("div", { style: annotationNoteStyle, children: ann.note })
|
|
6841
|
+
] }, i);
|
|
6842
|
+
}),
|
|
6843
|
+
annotations.length === 0 && /* @__PURE__ */ jsx(
|
|
6844
|
+
"div",
|
|
6845
|
+
{
|
|
6846
|
+
style: {
|
|
6847
|
+
padding: "0.75rem",
|
|
6848
|
+
fontSize: "0.75rem",
|
|
6849
|
+
color: "var(--glyph-text-muted, #6b7a94)"
|
|
6850
|
+
},
|
|
6851
|
+
children: "Select text to add annotations."
|
|
6852
|
+
}
|
|
6853
|
+
)
|
|
6854
|
+
] })
|
|
6855
|
+
] })
|
|
6856
|
+
] })
|
|
6857
|
+
]
|
|
6858
|
+
}
|
|
6859
|
+
);
|
|
6860
|
+
}
|
|
6861
|
+
|
|
6862
|
+
// src/annotate/index.ts
|
|
6863
|
+
var annotateDefinition = {
|
|
6864
|
+
type: "ui:annotate",
|
|
6865
|
+
schema: annotateSchema,
|
|
6866
|
+
render: Annotate
|
|
6867
|
+
};
|
|
6868
|
+
|
|
6869
|
+
export { Accordion, Annotate, Architecture, Callout, Card, Chart, CodeDiff, Comparison, Equation, FileTree, Flowchart, Form, Graph, Infographic, Kanban, Kpi, Matrix, MindMap, Poll, Quiz, Ranker, Rating, Relation, Sequence, Slider, Steps, Table, Tabs, Timeline, accordionDefinition, annotateDefinition, architectureDefinition, calloutDefinition, cardDefinition, chartDefinition, codeDiffDefinition, comparisonDefinition, computeArchitectureLayout, computeDagreLayout, computeDiff, computeForceLayout, equationDefinition, fileTreeDefinition, flowchartDefinition, formDefinition, graphDefinition, infographicDefinition, kanbanDefinition, kpiDefinition, matrixDefinition, mindMapDefinition, pollDefinition, quizDefinition, rankerDefinition, ratingDefinition, relationDefinition, sequenceDefinition, sliderDefinition, stepsDefinition, tableDefinition, tabsDefinition, timelineDefinition };
|
|
4854
6870
|
//# sourceMappingURL=index.js.map
|
|
4855
6871
|
//# sourceMappingURL=index.js.map
|