@cardenelabs/cdl 0.50.0 → 0.51.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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CdlDiagram, S as Signal, a as CdlInput, b as CdlLane, c as CdlNode, T as Tone, d as Side, E as EdgeStyle, e as EdgeRole, f as EdgeHead, g as EdgeHeadFill, h as CdlState, i as CdlEventTarget, j as Computed, k as CdlDerivedValue, l as CdlScrollTrigger, L as LaidDiagram, m as CdlDiagramViewProps, n as LaidEdge, o as LaidNode, p as CdlEdge, B as BBox, R as RowMark, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-C53-PeJZ.cjs';
2
- export { q as CdlDiagramView, r as CdlEventBinding, s as CdlEventKind, t as CdlFormula, u as CdlPhase, v as ChartPieForm, w as ChartSlopeForm, x as EDGE_HEADS, y as EDGE_HEAD_DEFAULT, z as EDGE_HEAD_FILLS, A as EDGE_HEAD_FILL_DEFAULT, D as EDGE_REVEALS, F as EDGE_REVEAL_DEFAULT, G as EDGE_STYLES, H as EdgeReveal, I as InteractiveHandlerMap, K as InteractiveSignalsAccessor, M as LaidLane, O as NODE_KINDS, P as RELATION_FOCUSES, U as RELATION_FOCUS_DEFAULT, V as RelationFocus, W as ScrollProgressHandle, X as TONES, Y as computeEventBindingKey, Z as computeFormulaKey, _ as computeInputSignalKey, $ as computeScrollTriggerKey, a0 as computed, a1 as createInteractiveSignalsAccessor, a2 as createScrollProgressHandle, a3 as createScrollProgressSignals, a4 as hasInteractivePrimitives, a5 as sequenceBoardMetrics, a6 as sequenceStepId, a7 as signal } from './render-C53-PeJZ.cjs';
1
+ import { C as CdlDiagram, S as Signal, a as CdlInput, b as CdlLane, c as CdlNode, T as Tone, d as Side, E as EdgeStyle, e as EdgeRole, f as EdgeHead, g as EdgeHeadFill, h as CdlState, i as CdlEventTarget, j as Computed, k as CdlDerivedValue, l as CdlScrollTrigger, L as LaidDiagram, m as CdlDiagramViewProps, n as LaidEdge, o as LaidNode, p as CdlEdge, B as BBox, R as RowMark, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-BoBEyCu-.cjs';
2
+ export { q as CdlDiagramView, r as CdlEventBinding, s as CdlEventKind, t as CdlFormula, u as CdlPhase, v as ChartPieForm, w as ChartSlopeForm, x as EDGE_HEADS, y as EDGE_HEAD_DEFAULT, z as EDGE_HEAD_FILLS, A as EDGE_HEAD_FILL_DEFAULT, D as EDGE_REVEALS, F as EDGE_REVEAL_DEFAULT, G as EDGE_STYLES, H as EdgeReveal, I as InteractiveHandlerMap, K as InteractiveSignalsAccessor, M as LaidLane, O as NODE_KINDS, P as RELATION_FOCUSES, U as RELATION_FOCUS_DEFAULT, V as RelationFocus, W as ScrollProgressHandle, X as TONES, Y as computeEventBindingKey, Z as computeFormulaKey, _ as computeInputSignalKey, $ as computeScrollTriggerKey, a0 as computed, a1 as createInteractiveSignalsAccessor, a2 as createScrollProgressHandle, a3 as createScrollProgressSignals, a4 as hasInteractivePrimitives, a5 as sequenceBoardMetrics, a6 as sequenceStepId, a7 as signal } from './render-BoBEyCu-.cjs';
3
3
  import { JSX } from 'react';
4
4
 
5
5
  declare function effect(fn: () => void | (() => void)): () => void;
@@ -1046,6 +1046,8 @@ type DiagramBuilder = {
1046
1046
  guard?: string;
1047
1047
  /** ER 関係 cardinality、 text-dsl v0.5 inline option (`cardinality: "1:N"`) を CdlEdge.cardinality へ透過 */
1048
1048
  cardinality?: string;
1049
+ /** 行き先の端に添える字 (#821)。 クラス図の多重度に使う */
1050
+ headLabel?: string;
1049
1051
  labelOffsetX?: number;
1050
1052
  labelOffsetY?: number;
1051
1053
  routing?: "default" | "back-detour";
@@ -1136,6 +1138,8 @@ type DiagramBuilder = {
1136
1138
  tailHeadFill?: EdgeHeadFill;
1137
1139
  guard?: string;
1138
1140
  cardinality?: string;
1141
+ /** 行き先の端に添える字 (#821)。 クラス図の多重度に使う */
1142
+ headLabel?: string;
1139
1143
  labelOffsetX?: number;
1140
1144
  labelOffsetY?: number;
1141
1145
  routing?: "default" | "back-detour";
@@ -3406,7 +3410,7 @@ type UmlRelation = {
3406
3410
  type: ClassRelationType;
3407
3411
  /** 関係 label (default は type 名) */
3408
3412
  label?: string;
3409
- /** 多重度 (例 "1..*" / "0..1") */
3413
+ /** 多重度 (例 "1..*" / "0..1")。 行き先 (`to`) の端に添える (#821) */
3410
3414
  cardinality?: string;
3411
3415
  tone?: Tone;
3412
3416
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CdlDiagram, S as Signal, a as CdlInput, b as CdlLane, c as CdlNode, T as Tone, d as Side, E as EdgeStyle, e as EdgeRole, f as EdgeHead, g as EdgeHeadFill, h as CdlState, i as CdlEventTarget, j as Computed, k as CdlDerivedValue, l as CdlScrollTrigger, L as LaidDiagram, m as CdlDiagramViewProps, n as LaidEdge, o as LaidNode, p as CdlEdge, B as BBox, R as RowMark, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-C53-PeJZ.js';
2
- export { q as CdlDiagramView, r as CdlEventBinding, s as CdlEventKind, t as CdlFormula, u as CdlPhase, v as ChartPieForm, w as ChartSlopeForm, x as EDGE_HEADS, y as EDGE_HEAD_DEFAULT, z as EDGE_HEAD_FILLS, A as EDGE_HEAD_FILL_DEFAULT, D as EDGE_REVEALS, F as EDGE_REVEAL_DEFAULT, G as EDGE_STYLES, H as EdgeReveal, I as InteractiveHandlerMap, K as InteractiveSignalsAccessor, M as LaidLane, O as NODE_KINDS, P as RELATION_FOCUSES, U as RELATION_FOCUS_DEFAULT, V as RelationFocus, W as ScrollProgressHandle, X as TONES, Y as computeEventBindingKey, Z as computeFormulaKey, _ as computeInputSignalKey, $ as computeScrollTriggerKey, a0 as computed, a1 as createInteractiveSignalsAccessor, a2 as createScrollProgressHandle, a3 as createScrollProgressSignals, a4 as hasInteractivePrimitives, a5 as sequenceBoardMetrics, a6 as sequenceStepId, a7 as signal } from './render-C53-PeJZ.js';
1
+ import { C as CdlDiagram, S as Signal, a as CdlInput, b as CdlLane, c as CdlNode, T as Tone, d as Side, E as EdgeStyle, e as EdgeRole, f as EdgeHead, g as EdgeHeadFill, h as CdlState, i as CdlEventTarget, j as Computed, k as CdlDerivedValue, l as CdlScrollTrigger, L as LaidDiagram, m as CdlDiagramViewProps, n as LaidEdge, o as LaidNode, p as CdlEdge, B as BBox, R as RowMark, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-BoBEyCu-.js';
2
+ export { q as CdlDiagramView, r as CdlEventBinding, s as CdlEventKind, t as CdlFormula, u as CdlPhase, v as ChartPieForm, w as ChartSlopeForm, x as EDGE_HEADS, y as EDGE_HEAD_DEFAULT, z as EDGE_HEAD_FILLS, A as EDGE_HEAD_FILL_DEFAULT, D as EDGE_REVEALS, F as EDGE_REVEAL_DEFAULT, G as EDGE_STYLES, H as EdgeReveal, I as InteractiveHandlerMap, K as InteractiveSignalsAccessor, M as LaidLane, O as NODE_KINDS, P as RELATION_FOCUSES, U as RELATION_FOCUS_DEFAULT, V as RelationFocus, W as ScrollProgressHandle, X as TONES, Y as computeEventBindingKey, Z as computeFormulaKey, _ as computeInputSignalKey, $ as computeScrollTriggerKey, a0 as computed, a1 as createInteractiveSignalsAccessor, a2 as createScrollProgressHandle, a3 as createScrollProgressSignals, a4 as hasInteractivePrimitives, a5 as sequenceBoardMetrics, a6 as sequenceStepId, a7 as signal } from './render-BoBEyCu-.js';
3
3
  import { JSX } from 'react';
4
4
 
5
5
  declare function effect(fn: () => void | (() => void)): () => void;
@@ -1046,6 +1046,8 @@ type DiagramBuilder = {
1046
1046
  guard?: string;
1047
1047
  /** ER 関係 cardinality、 text-dsl v0.5 inline option (`cardinality: "1:N"`) を CdlEdge.cardinality へ透過 */
1048
1048
  cardinality?: string;
1049
+ /** 行き先の端に添える字 (#821)。 クラス図の多重度に使う */
1050
+ headLabel?: string;
1049
1051
  labelOffsetX?: number;
1050
1052
  labelOffsetY?: number;
1051
1053
  routing?: "default" | "back-detour";
@@ -1136,6 +1138,8 @@ type DiagramBuilder = {
1136
1138
  tailHeadFill?: EdgeHeadFill;
1137
1139
  guard?: string;
1138
1140
  cardinality?: string;
1141
+ /** 行き先の端に添える字 (#821)。 クラス図の多重度に使う */
1142
+ headLabel?: string;
1139
1143
  labelOffsetX?: number;
1140
1144
  labelOffsetY?: number;
1141
1145
  routing?: "default" | "back-detour";
@@ -3406,7 +3410,7 @@ type UmlRelation = {
3406
3410
  type: ClassRelationType;
3407
3411
  /** 関係 label (default は type 名) */
3408
3412
  label?: string;
3409
- /** 多重度 (例 "1..*" / "0..1") */
3413
+ /** 多重度 (例 "1..*" / "0..1")。 行き先 (`to`) の端に添える (#821) */
3410
3414
  cardinality?: string;
3411
3415
  tone?: Tone;
3412
3416
  /**
package/dist/index.js CHANGED
@@ -9499,6 +9499,7 @@ function diagram(id, options) {
9499
9499
  tailHeadFill: opts.tailHeadFill,
9500
9500
  guard: opts.guard,
9501
9501
  cardinality: opts.cardinality,
9502
+ headLabel: opts.headLabel,
9502
9503
  labelOffsetX: opts.labelOffsetX,
9503
9504
  labelOffsetY: opts.labelOffsetY,
9504
9505
  routing: opts.routing,
@@ -9625,6 +9626,7 @@ function diagram(id, options) {
9625
9626
  tailHeadFill: d.tailHeadFill,
9626
9627
  guard: d.guard,
9627
9628
  cardinality: d.cardinality,
9629
+ headLabel: d.headLabel,
9628
9630
  labelOffsetX: d.labelOffsetX,
9629
9631
  labelOffsetY: d.labelOffsetY,
9630
9632
  routing: d.routing,
@@ -14103,10 +14105,10 @@ function \u66F8\u8A18\u7D20\u306B\u5206\u3051\u308B(text) {
14103
14105
  if (typeof \u533A\u5207\u308A !== "function") return [...text];
14104
14106
  return [...new \u533A\u5207\u308A(void 0, { granularity: "grapheme" }).segment(text)].map((g) => g.segment);
14105
14107
  }
14106
- function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8\u30552) {
14108
+ function \u7BB1\u306B\u7A4D\u3080(\u884C, \u7BB1\u306E\u5E45, \u7BB1\u306E\u9AD8\u30553) {
14107
14109
  const \u5019\u88DC = \u884C.filter((r, i) => i === 0 || r.text.trim() !== "");
14108
14110
  if (\u5019\u88DC.length === 0) return [];
14109
- const \u4F7F\u3048\u308B\u9AD8\u3055 = \u7BB1\u306E\u9AD8\u30552 - \u4E0A\u4E0B\u306E\u4F59\u767D * 2;
14111
+ const \u4F7F\u3048\u308B\u9AD8\u3055 = \u7BB1\u306E\u9AD8\u30553 - \u4E0A\u4E0B\u306E\u4F59\u767D * 2;
14110
14112
  const \u9AD8\u3055 = (rs) => rs.reduce((a, r) => a + r.fontSize * \u884C\u9001\u308A\u306E\u6BD4, 0);
14111
14113
  const \u6B8B\u3059 = [...\u5019\u88DC];
14112
14114
  while (\u6B8B\u3059.length > 1 && \u9AD8\u3055(\u6B8B\u3059) > \u4F7F\u3048\u308B\u9AD8\u3055) \u6B8B\u3059.pop();
@@ -14833,7 +14835,7 @@ function \u30D9\u30B8\u30A8\u306E\u7D2F\u7A4D\u5272\u5408(\u70B9, \u5236\u5FA1\u
14833
14835
  function \u7BB1\u306E\u6587\u5B57({
14834
14836
  \u884C,
14835
14837
  x,
14836
- \u7BB1\u306E\u9AD8\u3055: \u7BB1\u306E\u9AD8\u30552,
14838
+ \u7BB1\u306E\u9AD8\u3055: \u7BB1\u306E\u9AD8\u30553,
14837
14839
  fill,
14838
14840
  \u540D\u524D\u306E\u592A\u3055
14839
14841
  }) {
@@ -14842,7 +14844,7 @@ function \u7BB1\u306E\u6587\u5B57({
14842
14844
  {
14843
14845
  "data-cdl-role": r.\u5F79\u5272 === "subtitle" ? "tree-node-subtitle" : void 0,
14844
14846
  x,
14845
- y: \u7BB1\u306E\u9AD8\u30552 / 2 + r.dy,
14847
+ y: \u7BB1\u306E\u9AD8\u30553 / 2 + r.dy,
14846
14848
  fontSize: r.fontSize,
14847
14849
  fontWeight: r.\u5F79\u5272 === "title" ? \u540D\u524D\u306E\u592A\u3055 : 500,
14848
14850
  textAnchor: "middle",
@@ -22929,6 +22931,73 @@ function \u7B49\u5E45\u306E\u5B57(text, fontSize) {
22929
22931
  });
22930
22932
  return out;
22931
22933
  }
22934
+
22935
+ // src/layout/head-label.ts
22936
+ var \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2 = 22;
22937
+ var \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 = 8;
22938
+ var \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 = EDGE_LABEL_TEXT.sub.fontSize;
22939
+ var \u7BB1\u306E\u9AD8\u30552 = Math.round(\u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * 1.2);
22940
+ var BASELINE_RATIO = 0.8;
22941
+ function \u6700\u5F8C\u306E\u5411\u304D(d) {
22942
+ const segs = extractPathSegments(d);
22943
+ const last = segs[segs.length - 1];
22944
+ if (!last) return null;
22945
+ const end = { x: last.x2, y: last.y2 };
22946
+ for (let i = segs.length - 1; i >= 0; i--) {
22947
+ const s = segs[i];
22948
+ const \u5236\u5FA1\u70B9 = s.cmd === "Q" ? s.ctrl?.[0] : s.cmd === "C" ? s.ctrl?.[1] : void 0;
22949
+ for (const p of [\u5236\u5FA1\u70B9, { x: s.x1, y: s.y1 }]) {
22950
+ if (!p) continue;
22951
+ const dx = end.x - p.x;
22952
+ const dy = end.y - p.y;
22953
+ const len = Math.hypot(dx, dy);
22954
+ if (len > 1e-6) return { end, ux: dx / len, uy: dy / len };
22955
+ }
22956
+ }
22957
+ return null;
22958
+ }
22959
+ function \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge) {
22960
+ const text = edge.headLabel?.trim();
22961
+ if (!text) return null;
22962
+ const \u5411\u304D = \u6700\u5F8C\u306E\u5411\u304D(edge.d);
22963
+ if (!\u5411\u304D) return null;
22964
+ const { end, ux, uy } = \u5411\u304D;
22965
+ const bx = end.x - ux * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
22966
+ const by = end.y - uy * \u7AEF\u306E\u5B57\u3092\u623B\u3059\u8DDD\u96E2;
22967
+ const w = measureTextWidth(text, {
22968
+ fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
22969
+ fontWeight: EDGE_LABEL_TEXT.sub.fontWeight,
22970
+ fontFamily: "mono"
22971
+ });
22972
+ const h = \u7BB1\u306E\u9AD8\u30552;
22973
+ const \u672D = hasRenderedLabel(edge) && edge.labelX !== void 0 && edge.labelY !== void 0 ? { x: edge.labelX, y: edge.labelY } : null;
22974
+ let anchor;
22975
+ let box;
22976
+ if (Math.abs(ux) >= Math.abs(uy)) {
22977
+ const \u53F3\u3078\u9032\u3080 = ux > 0;
22978
+ const \u4E0A\u306B\u7F6E\u304F = \u672D !== null && \u672D.y > by;
22979
+ anchor = \u53F3\u3078\u9032\u3080 ? "end" : "start";
22980
+ box = {
22981
+ x: \u53F3\u3078\u9032\u3080 ? bx - w : bx,
22982
+ y: \u4E0A\u306B\u7F6E\u304F ? by - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - h : by + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593,
22983
+ w,
22984
+ h
22985
+ };
22986
+ } else {
22987
+ const \u4E0B\u3078\u9032\u3080 = uy > 0;
22988
+ const \u53F3\u306B\u7F6E\u304F = \u672D !== null && \u672D.x < bx;
22989
+ anchor = \u53F3\u306B\u7F6E\u304F ? "start" : "end";
22990
+ box = {
22991
+ x: \u53F3\u306B\u7F6E\u304F ? bx + \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 : bx - \u7AEF\u306E\u5B57\u3068\u7DDA\u306E\u9699\u9593 - w,
22992
+ y: \u4E0B\u3078\u9032\u3080 ? by - h : by,
22993
+ w,
22994
+ h
22995
+ };
22996
+ }
22997
+ const x = anchor === "start" ? box.x : box.x + box.w;
22998
+ const y = box.y + (h - \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055) / 2 + \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055 * BASELINE_RATIO;
22999
+ return { x, y, anchor, box };
23000
+ }
22932
23001
  function defaultEdgeWidth(active) {
22933
23002
  return active ? 2.5 : 1.25;
22934
23003
  }
@@ -23191,6 +23260,33 @@ function CdlEdgeLabelView({
23191
23260
  }
23192
23261
  );
23193
23262
  }
23263
+ function CdlEdgeHeadLabelView({
23264
+ edge,
23265
+ active
23266
+ }) {
23267
+ const \u7F6E\u304D\u5834\u6240 = \u7AEF\u306E\u5B57\u3092\u7F6E\u304F(edge);
23268
+ if (!\u7F6E\u304D\u5834\u6240) return null;
23269
+ const color = edgeColor(edge);
23270
+ return /* @__PURE__ */ jsx(
23271
+ "text",
23272
+ {
23273
+ "data-cdl-role": "edge-end-label",
23274
+ "data-cdl-edge-end-label-for": edge.id,
23275
+ x: \u7F6E\u304D\u5834\u6240.x,
23276
+ y: \u7F6E\u304D\u5834\u6240.y,
23277
+ fontSize: \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055,
23278
+ fontWeight: EDGE_LABEL_TEXT.sub.fontWeight,
23279
+ textAnchor: \u7F6E\u304D\u5834\u6240.anchor,
23280
+ fill: active ? color : "var(--cdl-text-dim, #5a6270)",
23281
+ stroke: "var(--cdl-label-bg, #ffffff)",
23282
+ strokeWidth: 4,
23283
+ strokeLinejoin: "round",
23284
+ paintOrder: "stroke",
23285
+ style: { fontFamily: fontFamilyAttr("sub") },
23286
+ children: \u7B49\u5E45\u306E\u5B57(edge.headLabel, \u7AEF\u306E\u5B57\u306E\u5927\u304D\u3055)
23287
+ }
23288
+ );
23289
+ }
23194
23290
 
23195
23291
  // src/kinds/node-tone.ts
23196
23292
  function nodeAccent(node, fallback) {
@@ -31475,6 +31571,14 @@ function CdlStage({
31475
31571
  },
31476
31572
  `label-${edge.id}`
31477
31573
  )),
31574
+ laid.edges.filter((edge) => edge.headLabel && \u77E2\u5370\u306E\u51FA\u756A.\u51FA\u308B\u304B(edge.id)).map((edge) => /* @__PURE__ */ jsx(
31575
+ CdlEdgeHeadLabelView,
31576
+ {
31577
+ edge,
31578
+ active: activeSet.has(edge.id)
31579
+ },
31580
+ `head-label-${edge.id}`
31581
+ )),
31478
31582
  debug && /* @__PURE__ */ jsxs("g", { pointerEvents: "none", children: [
31479
31583
  laid.bboxes.map((bbox, idx) => {
31480
31584
  const color = bbox.kind === "node" ? "#3b82f6" : bbox.kind === "lane-label" ? "#a855f7" : bbox.kind === "edge-label" ? "#10b981" : "#f59e0b";
@@ -32519,7 +32623,9 @@ function classDiagram(preset) {
32519
32623
  b.edge(r.from, r.to, {
32520
32624
  id: edgeId,
32521
32625
  label: r.label ?? r.type,
32522
- ...r.cardinality ? { sub: r.cardinality } : {},
32626
+ // 多重度は行き先の端に添える (#821)。 札の下の行に入れると語と続けて読まれ
32627
+ // (英字の頃は「HAS 1..*」 が「HAS1」)、 どちらの端の数かも読めない
32628
+ ...r.cardinality ? { headLabel: r.cardinality } : {},
32523
32629
  tone: r.tone ?? \u56F3\u306E\u65E2\u5B9A ?? CLASS_RELATION_TONE[r.type],
32524
32630
  // 関係の種類から線と端の形を決める (cdl#574 / #578)。 書いた値が勝つ
32525
32631
  style: r.style ?? \u898B\u305F\u76EE.style,