@glyphjs/components 0.4.0 → 0.5.1

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 CHANGED
@@ -87,6 +87,34 @@ var calloutDefinition = {
87
87
  schema: schemas.calloutSchema,
88
88
  render: Callout
89
89
  };
90
+
91
+ // src/utils/inlineToText.ts
92
+ function inlineToText(content) {
93
+ if (typeof content === "string") {
94
+ return content;
95
+ }
96
+ return content.map((node) => {
97
+ switch (node.type) {
98
+ case "text":
99
+ return node.value;
100
+ case "strong":
101
+ case "emphasis":
102
+ case "delete":
103
+ case "link":
104
+ return inlineToText(node.children);
105
+ case "inlineCode":
106
+ return node.value;
107
+ case "image":
108
+ return node.alt ?? "";
109
+ case "break":
110
+ return "\n";
111
+ default:
112
+ return "";
113
+ }
114
+ }).join("");
115
+ }
116
+
117
+ // src/chart/render.ts
90
118
  var DEFAULT_WIDTH = 600;
91
119
  var DEFAULT_HEIGHT = 400;
92
120
  var MARGIN = { top: 20, right: 30, bottom: 50, left: 60 };
@@ -134,7 +162,7 @@ function renderAxes(g, xScale, yScale, xAxisConfig, yAxisConfig, innerWidth, inn
134
162
  }
135
163
  xAxisG.selectAll("text, line, path").attr("fill", "var(--glyph-text, #1a2035)").attr("stroke", "var(--glyph-grid, #1a2035)");
136
164
  if (xAxisConfig?.label) {
137
- g.append("text").attr("class", "x-label").attr("x", innerWidth / 2).attr("y", innerHeight + MARGIN.bottom - 6).attr("text-anchor", "middle").attr("fill", "var(--glyph-text, #1a2035)").attr("font-size", "12px").text(xAxisConfig.label);
165
+ g.append("text").attr("class", "x-label").attr("x", innerWidth / 2).attr("y", innerHeight + MARGIN.bottom - 6).attr("text-anchor", "middle").attr("fill", "var(--glyph-text, #1a2035)").attr("font-size", "12px").text(inlineToText(xAxisConfig.label));
138
166
  }
139
167
  const yAxisG = g.append("g").attr("class", "y-axis");
140
168
  yAxisG.call(
@@ -142,7 +170,7 @@ function renderAxes(g, xScale, yScale, xAxisConfig, yAxisConfig, innerWidth, inn
142
170
  );
143
171
  yAxisG.selectAll("text, line, path").attr("fill", "var(--glyph-text, #1a2035)").attr("stroke", "var(--glyph-grid, #1a2035)");
144
172
  if (yAxisConfig?.label) {
145
- g.append("text").attr("class", "y-label").attr("transform", "rotate(-90)").attr("x", -innerHeight / 2).attr("y", -MARGIN.left + 14).attr("text-anchor", "middle").attr("fill", "var(--glyph-text, #1a2035)").attr("font-size", "12px").text(yAxisConfig.label);
173
+ g.append("text").attr("class", "y-label").attr("transform", "rotate(-90)").attr("x", -innerHeight / 2).attr("y", -MARGIN.left + 14).attr("text-anchor", "middle").attr("fill", "var(--glyph-text, #1a2035)").attr("font-size", "12px").text(inlineToText(yAxisConfig.label));
146
174
  }
147
175
  }
148
176
  function renderGridLines(g, yScale, innerWidth) {
@@ -198,7 +226,7 @@ function renderLegend(sel, series, marginLeft, marginTop, fontSize = "12px") {
198
226
  const color3 = COLOR_SCHEME[i % COLOR_SCHEME.length] ?? "var(--glyph-text, #1a2035)";
199
227
  const row = legendG.append("g").attr("transform", `translate(0,${String(i * 20)})`);
200
228
  row.append("rect").attr("width", 14).attr("height", 14).attr("fill", color3).attr("rx", 2);
201
- row.append("text").attr("x", 20).attr("y", 11).attr("fill", "var(--glyph-text, #1a2035)").attr("font-size", fontSize).text(s.name);
229
+ row.append("text").attr("x", 20).attr("y", 11).attr("fill", "var(--glyph-text, #1a2035)").attr("font-size", fontSize).text(inlineToText(s.name));
202
230
  });
203
231
  }
204
232
  function ChartAccessibleTable({
@@ -229,10 +257,10 @@ function ChartAccessibleTable({
229
257
  " chart data"
230
258
  ] }),
231
259
  series.map((s, si) => /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
232
- /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("th", { colSpan: 2, children: s.name }) }),
260
+ /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("th", { colSpan: 2, children: inlineToText(s.name) }) }),
233
261
  /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
234
- /* @__PURE__ */ jsxRuntime.jsx("th", { children: xLabel ?? xKey }),
235
- /* @__PURE__ */ jsxRuntime.jsx("th", { children: yLabel ?? yKey })
262
+ /* @__PURE__ */ jsxRuntime.jsx("th", { children: xLabel ? inlineToText(xLabel) : xKey }),
263
+ /* @__PURE__ */ jsxRuntime.jsx("th", { children: yLabel ? inlineToText(yLabel) : yKey })
236
264
  ] }),
237
265
  s.data.map((d, di) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
238
266
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: String(d[xKey] ?? "") }),
@@ -283,6 +311,7 @@ function renderAllSeries(g, type, series, scales, xKey, yKey, showTooltip, hideT
283
311
  const { xScale, xScalePoint, yScale, innerHeight } = scales;
284
312
  series.forEach((s, i) => {
285
313
  const color3 = COLOR_SCHEME[i % COLOR_SCHEME.length] ?? "#333";
314
+ const seriesName = inlineToText(s.name);
286
315
  switch (type) {
287
316
  case "line":
288
317
  renderLineSeries(
@@ -294,7 +323,7 @@ function renderAllSeries(g, type, series, scales, xKey, yKey, showTooltip, hideT
294
323
  xKey,
295
324
  color3,
296
325
  i,
297
- s.name,
326
+ seriesName,
298
327
  showTooltip,
299
328
  hideTooltip
300
329
  );
@@ -310,7 +339,7 @@ function renderAllSeries(g, type, series, scales, xKey, yKey, showTooltip, hideT
310
339
  innerHeight,
311
340
  color3,
312
341
  i,
313
- s.name,
342
+ seriesName,
314
343
  showTooltip,
315
344
  hideTooltip
316
345
  );
@@ -327,7 +356,7 @@ function renderAllSeries(g, type, series, scales, xKey, yKey, showTooltip, hideT
327
356
  i,
328
357
  series.length,
329
358
  innerHeight,
330
- s.name,
359
+ seriesName,
331
360
  showTooltip,
332
361
  hideTooltip
333
362
  );
@@ -340,7 +369,7 @@ function renderAllSeries(g, type, series, scales, xKey, yKey, showTooltip, hideT
340
369
  xScalePoint,
341
370
  yScale,
342
371
  scales.innerWidth,
343
- s.name,
372
+ seriesName,
344
373
  showTooltip,
345
374
  hideTooltip
346
375
  );
@@ -720,7 +749,7 @@ function TableHead({
720
749
  whiteSpace: "nowrap"
721
750
  },
722
751
  children: [
723
- col.label,
752
+ /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: col.label }),
724
753
  col.sortable ? sortIndicator(direction) : ""
725
754
  ]
726
755
  },
@@ -1046,7 +1075,7 @@ function Tabs({ data, block, onInteraction }) {
1046
1075
  outline: "revert",
1047
1076
  outlineOffset: "2px"
1048
1077
  },
1049
- children: tab.label
1078
+ children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: tab.label })
1050
1079
  },
1051
1080
  tabId
1052
1081
  );
@@ -1072,7 +1101,7 @@ function Tabs({ data, block, onInteraction }) {
1072
1101
  color: "var(--glyph-heading, #0a0e1a)",
1073
1102
  lineHeight: 1.6
1074
1103
  },
1075
- children: tab.content
1104
+ children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: tab.content })
1076
1105
  },
1077
1106
  panelId
1078
1107
  );
@@ -1323,6 +1352,92 @@ var timelineDefinition = {
1323
1352
  schema: schemas.timelineSchema,
1324
1353
  render: Timeline
1325
1354
  };
1355
+
1356
+ // src/utils/measureText.ts
1357
+ var measurementCache = /* @__PURE__ */ new WeakMap();
1358
+ function measurePlainText(text, style) {
1359
+ const canvas = document.createElement("canvas");
1360
+ const ctx = canvas.getContext("2d");
1361
+ if (!ctx) {
1362
+ const avgCharWidth = parseInt(style.fontSize) * 0.6;
1363
+ return {
1364
+ width: text.length * avgCharWidth,
1365
+ height: parseInt(style.fontSize) * 1.2
1366
+ };
1367
+ }
1368
+ const fontWeight = style.fontWeight ?? "normal";
1369
+ ctx.font = `${fontWeight} ${style.fontSize} ${style.fontFamily}`;
1370
+ const metrics = ctx.measureText(text);
1371
+ const width = metrics.width;
1372
+ const height = parseInt(style.fontSize) * 1.2;
1373
+ return { width, height };
1374
+ }
1375
+ function measureHtmlText(content, style) {
1376
+ const cached = measurementCache.get(content);
1377
+ if (cached) {
1378
+ return cached;
1379
+ }
1380
+ const container = document.createElement("div");
1381
+ container.style.position = "absolute";
1382
+ container.style.visibility = "hidden";
1383
+ container.style.left = "-9999px";
1384
+ container.style.top = "-9999px";
1385
+ container.style.fontSize = style.fontSize;
1386
+ container.style.fontFamily = style.fontFamily;
1387
+ container.style.fontWeight = style.fontWeight ?? "normal";
1388
+ container.style.whiteSpace = "pre-wrap";
1389
+ container.style.wordBreak = "break-word";
1390
+ if (style.maxWidth) {
1391
+ container.style.maxWidth = `${style.maxWidth}px`;
1392
+ }
1393
+ container.innerHTML = inlineNodesToHtml(content);
1394
+ document.body.appendChild(container);
1395
+ const rect = container.getBoundingClientRect();
1396
+ const dimensions = {
1397
+ width: Math.ceil(rect.width),
1398
+ height: Math.ceil(rect.height)
1399
+ };
1400
+ document.body.removeChild(container);
1401
+ measurementCache.set(content, dimensions);
1402
+ return dimensions;
1403
+ }
1404
+ function inlineNodesToHtml(nodes) {
1405
+ return nodes.map((node) => {
1406
+ switch (node.type) {
1407
+ case "text":
1408
+ return escapeHtml(node.value);
1409
+ case "strong":
1410
+ return `<strong>${inlineNodesToHtml(node.children)}</strong>`;
1411
+ case "emphasis":
1412
+ return `<em>${inlineNodesToHtml(node.children)}</em>`;
1413
+ case "delete":
1414
+ return `<del>${inlineNodesToHtml(node.children)}</del>`;
1415
+ case "inlineCode":
1416
+ return `<code>${escapeHtml(node.value)}</code>`;
1417
+ case "link":
1418
+ return `<a href="${escapeHtml(node.url)}">${inlineNodesToHtml(node.children)}</a>`;
1419
+ case "image":
1420
+ return `<img src="${escapeHtml(node.src)}" alt="${escapeHtml(node.alt ?? "")}" />`;
1421
+ case "break":
1422
+ return "<br />";
1423
+ default:
1424
+ return "";
1425
+ }
1426
+ }).join("");
1427
+ }
1428
+ function escapeHtml(str) {
1429
+ const div = document.createElement("div");
1430
+ div.textContent = str;
1431
+ return div.innerHTML;
1432
+ }
1433
+ function measureText(content, style) {
1434
+ if (typeof content === "string") {
1435
+ return measurePlainText(content, style);
1436
+ }
1437
+ return measureHtmlText(content, style);
1438
+ }
1439
+
1440
+ // src/graph/layout.ts
1326
1441
  var RANKDIR_MAP = {
1327
1442
  "top-down": "TB",
1328
1443
  "left-right": "LR",
@@ -1345,10 +1460,17 @@ function computeDagreLayout(nodes, edges, direction = "top-down") {
1345
1460
  });
1346
1461
  g.setDefaultEdgeLabel(() => ({}));
1347
1462
  for (const node of nodes) {
1463
+ const labelDimensions = measureText(node.label, {
1464
+ fontSize: "13px",
1465
+ fontFamily: "Inter, system-ui, sans-serif",
1466
+ maxWidth: 200
1467
+ });
1468
+ const nodeWidth = Math.max(120, Math.min(250, labelDimensions.width + 40));
1469
+ const nodeHeight = Math.max(40, labelDimensions.height + 20);
1348
1470
  g.setNode(node.id, {
1349
1471
  label: node.label,
1350
- width: DEFAULT_NODE_WIDTH,
1351
- height: DEFAULT_NODE_HEIGHT
1472
+ width: nodeWidth,
1473
+ height: nodeHeight
1352
1474
  });
1353
1475
  }
1354
1476
  for (const edge of edges) {
@@ -1851,7 +1973,7 @@ function renderGraph(svgElement, layout, groupIndex, outgoingRefs, onNavigate, z
1851
1973
  if (edge.label) {
1852
1974
  const mid = edge.points[Math.floor(edge.points.length / 2)];
1853
1975
  if (mid) {
1854
- edgeG.append("text").attr("x", mid.x).attr("y", mid.y - 8).attr("text-anchor", "middle").attr("font-size", "11px").attr("fill", "var(--glyph-edge-color, #6b7a94)").text(edge.label);
1976
+ edgeG.append("text").attr("x", mid.x).attr("y", mid.y - 8).attr("text-anchor", "middle").attr("font-size", "11px").attr("fill", "var(--glyph-edge-color, #6b7a94)").text(inlineToText(edge.label));
1855
1977
  }
1856
1978
  }
1857
1979
  }
@@ -1868,7 +1990,7 @@ function renderGraph(svgElement, layout, groupIndex, outgoingRefs, onNavigate, z
1868
1990
  } else {
1869
1991
  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);
1870
1992
  }
1871
- 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);
1993
+ 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(inlineToText(node.label));
1872
1994
  if (isNavigable || onNodeClick) {
1873
1995
  nodeG.attr("cursor", "pointer");
1874
1996
  nodeG.on("click", () => {
@@ -1876,7 +1998,7 @@ function renderGraph(svgElement, layout, groupIndex, outgoingRefs, onNavigate, z
1876
1998
  const ref = refByAnchor.get(node.id);
1877
1999
  if (ref) onNavigate(ref);
1878
2000
  }
1879
- onNodeClick?.(node.id, node.label);
2001
+ onNodeClick?.(node.id, inlineToText(node.label));
1880
2002
  });
1881
2003
  }
1882
2004
  }
@@ -1968,7 +2090,7 @@ function Graph({
1968
2090
  return `${dir} ${target}${e.label ? ` (${e.label})` : ""}`;
1969
2091
  }).join(", ");
1970
2092
  return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
1971
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: node.label }),
2093
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: inlineToText(node.label) }),
1972
2094
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: node.group ?? "" }),
1973
2095
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: connections })
1974
2096
  ] }, node.id);
@@ -2002,14 +2124,20 @@ var NODE_SEP2 = 60;
2002
2124
  var RANK_SEP2 = 80;
2003
2125
  var EDGE_SEP2 = 10;
2004
2126
  var LAYOUT_PADDING2 = 40;
2005
- var CHAR_WIDTH = 7.5;
2006
2127
  function computeEntitySize(entity) {
2007
2128
  const attrs = entity.attributes ?? [];
2008
2129
  const height = ENTITY_HEADER_HEIGHT + attrs.length * ENTITY_ATTR_HEIGHT + ENTITY_PADDING;
2009
- let maxTextWidth = entity.label.length * (CHAR_WIDTH + 1);
2130
+ const labelDimensions = measureText(entity.label, {
2131
+ fontSize: "14px",
2132
+ fontFamily: "Inter, system-ui, sans-serif"
2133
+ });
2134
+ let maxTextWidth = labelDimensions.width;
2010
2135
  for (const attr of attrs) {
2011
- const attrText = `${attr.name}: ${attr.type}`;
2012
- maxTextWidth = Math.max(maxTextWidth, attrText.length * CHAR_WIDTH);
2136
+ const attrNameDimensions = measureText(attr.name, {
2137
+ fontSize: "12px",
2138
+ fontFamily: "ui-monospace, monospace"
2139
+ });
2140
+ maxTextWidth = Math.max(maxTextWidth, attrNameDimensions.width + 100);
2013
2141
  }
2014
2142
  const width = Math.max(ENTITY_MIN_WIDTH, maxTextWidth + ENTITY_PADDING * 2 + 16);
2015
2143
  return { width, height };
@@ -2133,7 +2261,7 @@ function renderRelation(svgElement, layout, zoomBehavior) {
2133
2261
  if (rel.label) {
2134
2262
  const mid = rel.points[Math.floor(rel.points.length / 2)];
2135
2263
  if (mid) {
2136
- edgeG.append("text").attr("x", mid.x).attr("y", mid.y - 10).attr("text-anchor", "middle").attr("font-size", "11px").attr("font-family", "Inter, system-ui, sans-serif").attr("fill", "var(--glyph-relation-label, #6b7a94)").text(rel.label);
2264
+ edgeG.append("text").attr("x", mid.x).attr("y", mid.y - 10).attr("text-anchor", "middle").attr("font-size", "11px").attr("font-family", "Inter, system-ui, sans-serif").attr("fill", "var(--glyph-relation-label, #6b7a94)").text(inlineToText(rel.label));
2137
2265
  }
2138
2266
  }
2139
2267
  const pFirst = rel.points[0];
@@ -2161,7 +2289,7 @@ function renderRelation(svgElement, layout, zoomBehavior) {
2161
2289
  const headerHeight = ENTITY_HEADER_HEIGHT;
2162
2290
  entityG.append("rect").attr("x", x).attr("y", y).attr("width", entity.width).attr("height", headerHeight).attr("rx", 4).attr("ry", 4).attr("fill", "var(--glyph-relation-header-bg, #00d4aa)");
2163
2291
  entityG.append("rect").attr("x", x).attr("y", y + headerHeight - 4).attr("width", entity.width).attr("height", 4).attr("fill", "var(--glyph-relation-header-bg, #00d4aa)");
2164
- entityG.append("text").attr("x", entity.x).attr("y", y + headerHeight / 2).attr("dy", "0.35em").attr("text-anchor", "middle").attr("font-size", "13px").attr("font-weight", "bold").attr("font-family", "Inter, system-ui, sans-serif").attr("fill", "var(--glyph-relation-header-text, #fff)").text(entity.label);
2292
+ entityG.append("text").attr("x", entity.x).attr("y", y + headerHeight / 2).attr("dy", "0.35em").attr("text-anchor", "middle").attr("font-size", "13px").attr("font-weight", "bold").attr("font-family", "Inter, system-ui, sans-serif").attr("fill", "var(--glyph-relation-header-text, #fff)").text(inlineToText(entity.label));
2165
2293
  if (attrs.length > 0) {
2166
2294
  entityG.append("line").attr("x1", x).attr("y1", y + headerHeight).attr("x2", x + entity.width).attr("y2", y + headerHeight).attr("stroke", "var(--glyph-relation-entity-border, #a8b5c8)").attr("stroke-width", 1);
2167
2295
  }
@@ -2170,7 +2298,7 @@ function renderRelation(svgElement, layout, zoomBehavior) {
2170
2298
  if (!attr) continue;
2171
2299
  const attrY = y + headerHeight + i * ENTITY_ATTR_HEIGHT + ENTITY_ATTR_HEIGHT / 2 + 4;
2172
2300
  const textEl = entityG.append("text").attr("x", x + ENTITY_PADDING).attr("y", attrY).attr("dy", "0.35em").attr("font-size", "12px").attr("font-family", "system-ui, -apple-system, monospace").attr("fill", "var(--glyph-relation-attr-text, #1a2035)");
2173
- const nameSpan = textEl.append("tspan").text(attr.name);
2301
+ const nameSpan = textEl.append("tspan").text(inlineToText(attr.name));
2174
2302
  if (attr.primaryKey) {
2175
2303
  nameSpan.attr("font-weight", "bold").attr("text-decoration", "underline");
2176
2304
  }
@@ -2230,7 +2358,7 @@ function Relation({ data, block }) {
2230
2358
  return `${dir} ${target} [${r.cardinality}]${r.label ? ` (${r.label})` : ""}`;
2231
2359
  }).join(", ");
2232
2360
  return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2233
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: entity.label }),
2361
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: inlineToText(entity.label) }),
2234
2362
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: attrs }),
2235
2363
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: rels })
2236
2364
  ] }, entity.id);
@@ -2768,9 +2896,9 @@ function CodeDiff({ data, block }) {
2768
2896
  }
2769
2897
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { id: baseId, role: "region", "aria-label": summary, style: containerStyle11, children: [
2770
2898
  (beforeLabel || afterLabel) && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: labelBarStyle, children: [
2771
- beforeLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: beforeLabel }),
2899
+ beforeLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: beforeLabel }) }),
2772
2900
  beforeLabel && afterLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u2192" }),
2773
- afterLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: afterLabel })
2901
+ afterLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: afterLabel }) })
2774
2902
  ] }),
2775
2903
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx("table", { role: "grid", style: tableStyle2, children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: diffLines.map((line6, i) => /* @__PURE__ */ jsxRuntime.jsxs(
2776
2904
  "tr",
@@ -2895,7 +3023,7 @@ function renderFlowchart(svgElement, layout, zoomBehavior) {
2895
3023
  if (edge.label) {
2896
3024
  const mid = edge.points[Math.floor(edge.points.length / 2)];
2897
3025
  if (mid) {
2898
- edgeG.append("text").attr("x", mid.x).attr("y", mid.y - 8).attr("text-anchor", "middle").attr("font-size", "11px").attr("fill", "var(--glyph-text-muted, #6b7a94)").text(edge.label);
3026
+ edgeG.append("text").attr("x", mid.x).attr("y", mid.y - 8).attr("text-anchor", "middle").attr("font-size", "11px").attr("fill", "var(--glyph-text-muted, #6b7a94)").text(inlineToText(edge.label));
2899
3027
  }
2900
3028
  }
2901
3029
  }
@@ -2903,7 +3031,7 @@ function renderFlowchart(svgElement, layout, zoomBehavior) {
2903
3031
  for (const node of layout.nodes) {
2904
3032
  const nodeG = nodeGroup.append("g").attr("class", "glyph-flowchart-node");
2905
3033
  renderNodeShape(nodeG, node, nodeFillOpacity, nodeStrokeWidth);
2906
- nodeG.append("text").attr("x", node.x).attr("y", node.y).attr("dy", "0.35em").attr("text-anchor", "middle").attr("font-size", "13px").attr("font-family", "Inter, system-ui, sans-serif").attr("fill", "var(--glyph-node-label-color, #fff)").attr("pointer-events", "none").text(node.label);
3034
+ 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(inlineToText(node.label));
2907
3035
  }
2908
3036
  }
2909
3037
  function Flowchart({
@@ -2930,7 +3058,7 @@ function Flowchart({
2930
3058
  }, [layoutResult, zoomBehavior]);
2931
3059
  const nodeCount = data.nodes.length;
2932
3060
  const edgeCount = data.edges.length;
2933
- const ariaLabel = data.title ? `${data.title}: flowchart with ${nodeCount} nodes and ${edgeCount} edges` : `Flowchart with ${nodeCount} nodes and ${edgeCount} edges`;
3061
+ const ariaLabel = data.title ? `${inlineToText(data.title)}: flowchart with ${nodeCount} nodes and ${edgeCount} edges` : `Flowchart with ${nodeCount} nodes and ${edgeCount} edges`;
2934
3062
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "glyph-flowchart-container", children: [
2935
3063
  data.title && /* @__PURE__ */ jsxRuntime.jsx(
2936
3064
  "div",
@@ -2942,7 +3070,7 @@ function Flowchart({
2942
3070
  color: "var(--glyph-heading, #edf0f5)",
2943
3071
  marginBottom: "0.5rem"
2944
3072
  },
2945
- children: data.title
3073
+ children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: data.title })
2946
3074
  }
2947
3075
  ),
2948
3076
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
@@ -2975,10 +3103,10 @@ function Flowchart({
2975
3103
  const connections = data.edges.filter((e) => e.from === node.id || e.to === node.id).map((e) => {
2976
3104
  const target = e.from === node.id ? e.to : e.from;
2977
3105
  const dir = e.from === node.id ? "->" : "<-";
2978
- return `${dir} ${target}${e.label ? ` (${e.label})` : ""}`;
3106
+ return `${dir} ${target}${e.label ? ` (${inlineToText(e.label)})` : ""}`;
2979
3107
  }).join(", ");
2980
3108
  return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
2981
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: node.label }),
3109
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: inlineToText(node.label) }),
2982
3110
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: node.type }),
2983
3111
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: connections })
2984
3112
  ] }, node.id);
@@ -3400,20 +3528,24 @@ function renderActorBox(actor, cx, y, keyPrefix, width = ACTOR_WIDTH, height = A
3400
3528
  strokeWidth: 1.5
3401
3529
  }
3402
3530
  ),
3403
- /* @__PURE__ */ jsxRuntime.jsx(
3404
- "text",
3531
+ /* @__PURE__ */ jsxRuntime.jsx("foreignObject", { x: cx - width / 2, y, width, height, children: /* @__PURE__ */ jsxRuntime.jsx(
3532
+ "div",
3405
3533
  {
3406
- x: cx,
3407
- y: y + height / 2,
3408
- dy: "0.35em",
3409
- textAnchor: "middle",
3410
- fontSize,
3411
- fontFamily: "Inter, system-ui, sans-serif",
3412
- fontWeight: 600,
3413
- fill: "var(--glyph-text, #d4dae3)",
3414
- children: actor.label
3534
+ style: {
3535
+ display: "flex",
3536
+ alignItems: "center",
3537
+ justifyContent: "center",
3538
+ width: "100%",
3539
+ height: "100%",
3540
+ fontSize,
3541
+ fontFamily: "Inter, system-ui, sans-serif",
3542
+ fontWeight: 600,
3543
+ color: "var(--glyph-text, #d4dae3)",
3544
+ textAlign: "center"
3545
+ },
3546
+ children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: actor.label })
3415
3547
  }
3416
- )
3548
+ ) })
3417
3549
  ] }, `${keyPrefix}-${actor.id}`);
3418
3550
  }
3419
3551
  function renderSelfMessage(x, y, label, idx, fontSize = "12px") {
@@ -3428,18 +3560,19 @@ function renderSelfMessage(x, y, label, idx, fontSize = "12px") {
3428
3560
  markerEnd: "url(#seq-arrow-solid)"
3429
3561
  }
3430
3562
  ),
3431
- /* @__PURE__ */ jsxRuntime.jsx(
3432
- "text",
3563
+ /* @__PURE__ */ jsxRuntime.jsx("foreignObject", { x: x + SELF_ARC_WIDTH + 6, y, width: 150, height: SELF_ARC_HEIGHT, children: /* @__PURE__ */ jsxRuntime.jsx(
3564
+ "div",
3433
3565
  {
3434
- x: x + SELF_ARC_WIDTH + 6,
3435
- y: y + SELF_ARC_HEIGHT / 2,
3436
- dy: "0.35em",
3437
- fontSize,
3438
- fontFamily: "Inter, system-ui, sans-serif",
3439
- fill: "var(--glyph-text, #d4dae3)",
3440
- children: label
3566
+ style: {
3567
+ display: "flex",
3568
+ alignItems: "center",
3569
+ fontSize,
3570
+ fontFamily: "Inter, system-ui, sans-serif",
3571
+ color: "var(--glyph-text, #d4dae3)"
3572
+ },
3573
+ children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: label })
3441
3574
  }
3442
- )
3575
+ ) })
3443
3576
  ] }, `msg-${idx}`);
3444
3577
  }
3445
3578
  function renderStandardMessage(fromX, toX, y, label, isDashed, idx, fontSize = "12px") {
@@ -3459,18 +3592,20 @@ function renderStandardMessage(fromX, toX, y, label, isDashed, idx, fontSize = "
3459
3592
  markerEnd: `url(#${markerId})`
3460
3593
  }
3461
3594
  ),
3462
- /* @__PURE__ */ jsxRuntime.jsx(
3463
- "text",
3595
+ /* @__PURE__ */ jsxRuntime.jsx("foreignObject", { x: midX - 75, y: y - 22, width: 150, height: 20, children: /* @__PURE__ */ jsxRuntime.jsx(
3596
+ "div",
3464
3597
  {
3465
- x: midX,
3466
- y: y - 8,
3467
- textAnchor: "middle",
3468
- fontSize,
3469
- fontFamily: "Inter, system-ui, sans-serif",
3470
- fill: "var(--glyph-text, #d4dae3)",
3471
- children: label
3598
+ style: {
3599
+ display: "flex",
3600
+ justifyContent: "center",
3601
+ fontSize,
3602
+ fontFamily: "Inter, system-ui, sans-serif",
3603
+ color: "var(--glyph-text, #d4dae3)",
3604
+ textAlign: "center"
3605
+ },
3606
+ children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: label })
3472
3607
  }
3473
- )
3608
+ ) })
3474
3609
  ] }, `msg-${idx}`);
3475
3610
  }
3476
3611
  function Sequence({ data, container }) {
@@ -3495,7 +3630,7 @@ function Sequence({ data, container }) {
3495
3630
  const firstMsgY = lifelineStartY + MSG_SPACING;
3496
3631
  const lastMsgY = firstMsgY + (messageCount - 1) * MSG_SPACING;
3497
3632
  const svgHeight = lastMsgY + BOTTOM_PADDING + effectiveActorHeight;
3498
- const ariaLabel = data.title ? `${data.title}: sequence diagram with ${actorCount} actors and ${messageCount} messages` : `Sequence diagram with ${actorCount} actors and ${messageCount} messages`;
3633
+ const ariaLabel = data.title ? `${inlineToText(data.title)}: sequence diagram with ${actorCount} actors and ${messageCount} messages` : `Sequence diagram with ${actorCount} actors and ${messageCount} messages`;
3499
3634
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "glyph-sequence-container", children: [
3500
3635
  data.title && /* @__PURE__ */ jsxRuntime.jsx(
3501
3636
  "div",
@@ -3507,7 +3642,7 @@ function Sequence({ data, container }) {
3507
3642
  color: "var(--glyph-heading, #edf0f5)",
3508
3643
  marginBottom: "0.5rem"
3509
3644
  },
3510
- children: data.title
3645
+ children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: data.title })
3511
3646
  }
3512
3647
  ),
3513
3648
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3622,9 +3757,9 @@ function Sequence({ data, container }) {
3622
3757
  const toActor = data.actors.find((a) => a.id === msg.to);
3623
3758
  return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3624
3759
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: idx + 1 }),
3625
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: fromActor?.label ?? msg.from }),
3626
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: toActor?.label ?? msg.to }),
3627
- /* @__PURE__ */ jsxRuntime.jsx("td", { children: msg.label }),
3760
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: fromActor ? inlineToText(fromActor.label) : msg.from }),
3761
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: toActor ? inlineToText(toActor.label) : msg.to }),
3762
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: inlineToText(msg.label) }),
3628
3763
  /* @__PURE__ */ jsxRuntime.jsx("td", { children: msg.type })
3629
3764
  ] }, idx);
3630
3765
  }) })
@@ -4471,7 +4606,7 @@ function Equation({ data }) {
4471
4606
  const ariaLabel = `Equation: ${data.expression}`;
4472
4607
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, role: "math", "aria-label": ariaLabel, children: [
4473
4608
  error || html === "" ? /* @__PURE__ */ jsxRuntime.jsx("code", { style: fallbackStyle, children: data.expression }) : /* @__PURE__ */ jsxRuntime.jsx("span", { dangerouslySetInnerHTML: { __html: html } }),
4474
- data.label !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: labelStyle2, children: data.label })
4609
+ data.label !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: labelStyle2, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: data.label }) })
4475
4610
  ] });
4476
4611
  }
4477
4612
  if (data.steps !== void 0 && data.steps.length > 0) {
@@ -4482,10 +4617,10 @@ function Equation({ data }) {
4482
4617
  const { html, error } = renderLatex(step.expression);
4483
4618
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: stepRowStyle, children: [
4484
4619
  error || html === "" ? /* @__PURE__ */ jsxRuntime.jsx("code", { style: fallbackStyle, children: step.expression }) : /* @__PURE__ */ jsxRuntime.jsx("span", { dangerouslySetInnerHTML: { __html: html } }),
4485
- step.annotation !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: annotationStyle, children: step.annotation })
4620
+ step.annotation !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { style: annotationStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: step.annotation }) })
4486
4621
  ] }, idx);
4487
4622
  }) }),
4488
- data.label !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: labelStyle2, children: data.label })
4623
+ data.label !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: labelStyle2, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: data.label }) })
4489
4624
  ] });
4490
4625
  }
4491
4626
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: containerStyle, role: "math", "aria-label": "Empty equation", children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--glyph-text-muted, #6b7a94)" }, children: "No equation provided" }) });
@@ -6911,8 +7046,8 @@ function Kanban({
6911
7046
  style: cardStyle(isGrabbed, card.priority),
6912
7047
  onKeyDown: (e) => handleCardKeyDown(e, card.id, col.id, cardIndex),
6913
7048
  children: [
6914
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: cardTitleStyle, children: card.title }),
6915
- card.description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: cardDescStyle, children: card.description }),
7049
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: cardTitleStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: card.title }) }),
7050
+ card.description && /* @__PURE__ */ jsxRuntime.jsx("div", { style: cardDescStyle, children: /* @__PURE__ */ jsxRuntime.jsx(runtime.RichText, { content: card.description }) }),
6916
7051
  card.tags && card.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: tagContainerStyle, children: card.tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: tagStyle, children: tag }, tag)) })
6917
7052
  ]
6918
7053
  },