@cardenelabs/cdl 0.23.0 → 0.25.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.
@@ -3,6 +3,28 @@ import { EDGE_HEAD_DEFAULT, EDGE_HEAD_FILL_DEFAULT, type LaidEdge } from "../typ
3
3
  import { edgeHeadMarkerId } from "./edge-head";
4
4
  import { computeLabelBBoxWorld, hasRenderedLabel, LABEL_PILL_PAD_X } from "../layout/spec";
5
5
  import { hasTone, toneColor } from "./tone";
6
+ import type { EdgeRole, Tone } from "../types";
7
+
8
+ /**
9
+ * 辺の色 (#618)。 役目を書いた辺だけ「いま」 の色で引く。
10
+ *
11
+ * 図の中に道が 2 種 (主となる 1 本と、 そこから枝分かれする預け先) ある時、 どちらも
12
+ * 同じ色だとどこから読むかが決まらない。 主となる道にだけ別の色を当てて順番を作る。
13
+ */
14
+ /**
15
+ * 辺の太さの既定 (#618)。
16
+ *
17
+ * 元は光って 5 / 光らず 2.5 で、 消費側 (dragon) が `!important` で 2.25 に上書きしていた。
18
+ * 実際に画面へ出る 2.25 は箱の枠 (1.75) より太く、 線が箱より前に出ていた。
19
+ * 箱の枠と釣り合う細さへ下げる。
20
+ */
21
+ export function defaultEdgeWidth(active: boolean): number {
22
+ return active ? 2.5 : 1.25;
23
+ }
24
+
25
+ export function edgeColor(edge: { tone: Tone; role?: EdgeRole }): string {
26
+ return edge.role === "main" ? "var(--cdl-now, #c0421f)" : toneColor(edge.tone);
27
+ }
6
28
  import { EDGE_LABEL_TEXT, fontFamilyAttr, type EdgeLabelLine } from "../label-text";
7
29
  import { interpolate, pathSubpath, resolveNumericAttr, shrinkPathEnd } from "./utils";
8
30
 
@@ -39,7 +61,7 @@ export function CdlEdgeView({
39
61
  progress: number;
40
62
  stateValues?: Record<string, string>;
41
63
  }): JSX.Element {
42
- const color = toneColor(edge.tone);
64
+ const color = edgeColor(edge);
43
65
  // 光っていない edge も tone の色で描く。 以前は一律の灰色に落としていたため、 何も光っていない
44
66
  // 静的な図では全 edge が同じ色になり、 因果の向き (警戒 = 赤 / 良好 = 緑) が線から読めなかった。
45
67
  // 光っている / いないの区別は、 実線は太さ (5 対 2.5) と線種 (実線対破線)、 点線は太さ (5 対 4)
@@ -171,7 +193,7 @@ function SolidEdgePath({
171
193
  // 伸ばすのは初めて出る段だけ (#584)。 光っているかで引くと、光り続ける図で毎段引き直される
172
194
  const visibleD = drawing ? pathSubpath(edge.d, progress) : edge.d;
173
195
  // signal binding: widthBind / strokeBind / dashOffsetBind (CAR edge-signal-binding)
174
- const defaultWidth = active ? 5 : 2.5;
196
+ const defaultWidth = defaultEdgeWidth(active);
175
197
  const boundWidth = edge.widthBind && stateValues
176
198
  ? resolveNumericAttr(edge.widthBind, stateValues, defaultWidth)
177
199
  : defaultWidth;
@@ -269,7 +291,7 @@ export function CdlEdgeGlowView({
269
291
  active: boolean;
270
292
  }): JSX.Element | null {
271
293
  if (!active) return null;
272
- const color = toneColor(edge.tone);
294
+ const color = edgeColor(edge);
273
295
  return <EdgeGlowCircles color={color} edgeId={edge.id} />;
274
296
  }
275
297
 
@@ -286,7 +308,7 @@ export function CdlEdgeLabelView({
286
308
  // 空 label でも rect + text で 12.5x12.5 の小 marker が残り、 dragon sweep で
287
309
  // node bbox と数十 px² の実測 overlap を生む (mind-demo 61px² 事象)。
288
310
  if (!hasRenderedLabel(edge)) return null;
289
- const color = toneColor(edge.tone);
311
+ const color = edgeColor(edge);
290
312
  // SSOT = spec.ts の computeLabelBBoxWorld (CAR-431 で render / layout / predict-bbox 3 箇所の
291
313
  // bbox 計算 drift を解消)。 pill h / w / padding / boxLeftX / boxTopY は本 helper 経由で取得、
292
314
  // <g transform="translate(labelX, labelY)"> 内 rect は相対座標なので world x/y を helper から
@@ -312,19 +334,22 @@ export function CdlEdgeLabelView({
312
334
  data-cdl-edge-label-text={edge.label}
313
335
  data-cdl-edge-sub-text={edge.sub ?? ""}
314
336
  >
315
- <rect
316
- data-cdl-role="edge-label-bg"
317
- x={boxLeftX}
318
- y={boxTopY}
319
- width={boxW}
320
- height={boxH}
321
- rx={10}
322
- fill="var(--cdl-label-bg, #ffffff)"
323
- stroke={active ? color : "var(--cdl-divider, #d4d4d8)"}
324
- strokeOpacity={active ? 0.9 : 0.55}
325
- strokeWidth={1.5}
326
- opacity={active ? 1 : 0.92}
327
- />
337
+ {/* 下地は既定で敷く。 丸い下地は箱と同じ形なので、 罫の細い図では外せるようにした (#618) */}
338
+ {edge.labelPlate !== false && (
339
+ <rect
340
+ data-cdl-role="edge-label-bg"
341
+ x={boxLeftX}
342
+ y={boxTopY}
343
+ width={boxW}
344
+ height={boxH}
345
+ rx={10}
346
+ fill="var(--cdl-label-bg, #ffffff)"
347
+ stroke={active ? color : "var(--cdl-divider, #d4d4d8)"}
348
+ strokeOpacity={active ? 0.9 : 0.55}
349
+ strokeWidth={1.5}
350
+ opacity={active ? 1 : 0.92}
351
+ />
352
+ )}
328
353
  <text
329
354
  data-cdl-role="edge-label"
330
355
  x={textX}
@@ -144,6 +144,13 @@ export function CdlStage({
144
144
  // 倍率は SVG 要素そのものに載せる。 中身を包む `<g>` を作らないので、
145
145
  // 倍率 1 / 未指定の DOM は従来と 1 byte も変わらない。
146
146
  data-cdl-scale={diagramScale === 1 ? undefined : diagramScale}
147
+ // どの配色で描くか (#1553)。 cdl は色の値を持たず、名前だけを出す。
148
+ // 消費側 (dragon の theme 等) が名前を見て変数の値を決める。
149
+ //
150
+ // **ここでは空文字を弾かない**。 公開経路は `CdlDiagramView` だけで、必ず組み立てを
151
+ // 通るため、空文字は `layout` が既に落としている。 ここにも守りを置くと、
152
+ // どの入力でも通らない分岐が残る
153
+ data-cdl-palette={laid.palette}
147
154
  >
148
155
  <defs>
149
156
  {/* CAR-643 = cdl は geometry only。 shadow / border effect の filter は cdl SVG 内に
@@ -61,6 +61,8 @@ type 読まない欄 =
61
61
  | "journeyData"
62
62
  // 行頭の印 (#578)。 字ではなく形なので、状態から値を差し込む対象にならない
63
63
  | "rowMarks"
64
+ // 1 行おきの縞 (#1553)。 敷くか敷かないかの真偽値で、字を差し込む先が無い
65
+ | "rowStripe"
64
66
  // 時系列のやり取りの中身 (#578)。 種別が内側で解決するので、ここでは差し込まない
65
67
  | "sequenceData";
66
68
 
package/src/types.ts CHANGED
@@ -134,6 +134,9 @@ export type Side = "top" | "right" | "bottom" | "left";
134
134
  */
135
135
  export type EdgeStyle = "solid" | "dotted-flow" | "dashed";
136
136
 
137
+ /** 辺の役目 (#618)。 `main` = 図の主となる道 */
138
+ export type EdgeRole = "main";
139
+
137
140
  /**
138
141
  * 線の種類の全種 (#578)。 **型だけでなく実体を持つ**。
139
142
  *
@@ -348,6 +351,16 @@ export type CdlNode = {
348
351
  * 空文字の行と `null` の印を組にすると **群の間** になる (持ち物と振る舞いの間など)。
349
352
  */
350
353
  rowMarks?: readonly (RowMark | null)[];
354
+ /**
355
+ * 行に 1 行おきの縞を敷くか (#1553)。
356
+ *
357
+ * 表の箱は小さい字が密に並ぶので、行を横に追う時の目印が無い。
358
+ * 色を増やさずに、面を 1 行おきに変えて追えるようにする。
359
+ *
360
+ * **既定では敷かない**。 `er` が設計の形で立てた実体だけが持つ。
361
+ * クラス図も同じ `storage` を使うが、持ち物と振る舞いは行頭の印で既に分かれている。
362
+ */
363
+ rowStripe?: boolean;
351
364
  /**
352
365
  * 時系列のやり取りの中身 (#578)。 `sequence-board` 種別が読む。
353
366
  *
@@ -637,6 +650,21 @@ export type CdlEdge = {
637
650
  side?: Side;
638
651
  /** visual style、 default "solid" */
639
652
  style?: EdgeStyle;
653
+ /**
654
+ * 辺の役目 (#618)。 書かなければ従来どおり tone の色で引く。
655
+ *
656
+ * `main` を書いた辺だけ「いま」 の色 (`--cdl-now`) で引く。 図の中で 1 本の道を
657
+ * 目立たせ、 どこから読むかを決めるための口。 すべての辺に書くと差が消えるので、
658
+ * 主となる 1 本 (または 1 続き) にだけ書く。
659
+ */
660
+ role?: EdgeRole;
661
+ /**
662
+ * 名前の下地を敷くか (#618)。 書かなければ敷く (従来どおり)。
663
+ *
664
+ * 丸い下地は箱と同じ形なので、 名前が小さな箱に見える。 罫の細い図では外したほうが
665
+ * 線と名前の区別が付く。
666
+ */
667
+ labelPlate?: boolean;
640
668
  /** 端の形、 default "triangle" (#560)。 線の種類とは別の軸 */
641
669
  head?: EdgeHead;
642
670
  /**
@@ -2489,6 +2517,17 @@ export type CdlDiagram = {
2489
2517
  * 既定は `"extract"` = 付け忘れても検知が緩まない向き。
2490
2518
  */
2491
2519
  structuredData?: "extract" | "exclude";
2520
+ /**
2521
+ * この図をどの配色で描くか (#1553)。 書かない図は消費側の既定で描かれる。
2522
+ *
2523
+ * **cdl は色の値を持たない**。 名前を `data-cdl-palette` として markup に出すだけで、
2524
+ * 実際の値は消費側 (dragon の theme 等) が名前を見て決める。 値を engine に持たせると、
2525
+ * 消費側が配色を変えるたびに engine の release が要る。
2526
+ *
2527
+ * 空文字は書かなかった扱いにする = 空を出すと消費側の `[data-cdl-palette]` が
2528
+ * 既定の図にも当たる。
2529
+ */
2530
+ palette?: string;
2492
2531
  /**
2493
2532
  * 矢印をいつ出すか (既定 = `"phase"`、 #582)。
2494
2533
  *
@@ -2693,6 +2732,8 @@ export type BBox = {
2693
2732
  export type LaidDiagram = {
2694
2733
  id: string;
2695
2734
  topic: string;
2735
+ /** どの配色で描くか (#1553)。 `CdlDiagram.palette` をそのまま持ち越す */
2736
+ palette?: string;
2696
2737
  viewBox: { x: number; y: number; w: number; h: number };
2697
2738
  /**
2698
2739
  * 図全体の倍率 (`CdlViewport.scale` を正規化した値)。