@cardenelabs/cdl 0.7.0 → 0.10.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +446 -0
  2. package/SPEC.md +42 -18
  3. package/dist/index.cjs +793 -347
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +73 -14
  6. package/dist/index.d.ts +73 -14
  7. package/dist/index.js +793 -347
  8. package/dist/index.js.map +1 -1
  9. package/dist/react.cjs +658 -236
  10. package/dist/react.cjs.map +1 -1
  11. package/dist/react.d.cts +1 -1
  12. package/dist/react.d.ts +1 -1
  13. package/dist/react.js +658 -236
  14. package/dist/react.js.map +1 -1
  15. package/dist/{render-DquCvgOB.d.cts → render-CH1Qn3Jv.d.cts} +47 -2
  16. package/dist/{render-DquCvgOB.d.ts → render-CH1Qn3Jv.d.ts} +47 -2
  17. package/package.json +6 -3
  18. package/src/builder.ts +13 -1
  19. package/src/kinds/box-lines.ts +120 -0
  20. package/src/kinds/chart-line.tsx +94 -25
  21. package/src/kinds/gantt.tsx +152 -24
  22. package/src/kinds/mind-map.tsx +50 -12
  23. package/src/kinds/quadrant.tsx +28 -2
  24. package/src/kinds/shape-blockchain.tsx +65 -12
  25. package/src/kinds/shape-region.tsx +152 -34
  26. package/src/kinds/tree.tsx +92 -20
  27. package/src/layout/collisions.ts +10 -2
  28. package/src/layout/footer-shape.ts +86 -24
  29. package/src/layout/lifeline.ts +80 -0
  30. package/src/layout/spec.ts +21 -2
  31. package/src/layout/text-width.ts +92 -4
  32. package/src/layout/viewbox.ts +0 -8
  33. package/src/layout.ts +8 -1
  34. package/src/presets.ts +120 -22
  35. package/src/render/header.tsx +3 -1
  36. package/src/render/nodes.tsx +15 -1
  37. package/src/render/payload-binding.ts +31 -8
  38. package/src/render/stage.tsx +21 -34
  39. package/src/render/template-fields.ts +212 -0
  40. package/src/render/utils.ts +32 -2
  41. package/src/render.tsx +2 -9
  42. package/src/types.ts +47 -2
  43. package/src/validate.ts +45 -13
  44. package/src/visual-validate.ts +34 -1
  45. package/src/layout/label-shift.ts +0 -28
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 CdlState, f as CdlEventTarget, g as Computed, h as CdlDerivedValue, i as CdlScrollTrigger, L as LaidDiagram, j as CdlDiagramViewProps, k as LaidEdge, l as LaidNode, m as CdlEdge, B as BBox, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-DquCvgOB.cjs';
2
- export { n as CdlDiagramView, o as CdlEventBinding, p as CdlEventKind, q as CdlFormula, r as CdlPhase, I as InteractiveHandlerMap, s as InteractiveSignalsAccessor, t as LaidLane, u as NODE_KINDS, v as ScrollProgressHandle, w as TONES, x as computeEventBindingKey, y as computeFormulaKey, z as computeInputSignalKey, A as computeScrollTriggerKey, D as computed, F as createInteractiveSignalsAccessor, G as createScrollProgressHandle, H as createScrollProgressSignals, K as hasInteractivePrimitives, M as signal } from './render-DquCvgOB.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 CdlState, f as CdlEventTarget, g as Computed, h as CdlDerivedValue, i as CdlScrollTrigger, L as LaidDiagram, j as CdlDiagramViewProps, k as LaidEdge, l as LaidNode, m as CdlEdge, B as BBox, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-CH1Qn3Jv.cjs';
2
+ export { n as CdlDiagramView, o as CdlEventBinding, p as CdlEventKind, q as CdlFormula, r as CdlPhase, I as InteractiveHandlerMap, s as InteractiveSignalsAccessor, t as LaidLane, u as NODE_KINDS, v as ScrollProgressHandle, w as TONES, x as computeEventBindingKey, y as computeFormulaKey, z as computeInputSignalKey, A as computeScrollTriggerKey, D as computed, F as createInteractiveSignalsAccessor, G as createScrollProgressHandle, H as createScrollProgressSignals, K as hasInteractivePrimitives, M as signal } from './render-CH1Qn3Jv.cjs';
3
3
  import { JSX } from 'react';
4
4
 
5
5
  declare function effect(fn: () => void | (() => void)): () => void;
@@ -997,6 +997,11 @@ type InputChain = {
997
997
  };
998
998
  type PhaseBuilder = {
999
999
  activate: (...ids: string[]) => PhaseBuilder;
1000
+ /**
1001
+ * この phase で左の起点から描き始める node を指定する (cdl#512)。
1002
+ * 対象は phase の進み (0→1) に合わせて描かれる。 現在の対象種別は `chart-line`。
1003
+ */
1004
+ draw: (...ids: string[]) => PhaseBuilder;
1000
1005
  /** 数値 state の線形補間 (write phase で 100→90 等) */
1001
1006
  tween: (stateId: string, from: number, to: number) => PhaseBuilder;
1002
1007
  /** 任意型 state を即時切替 (この phase 到達で value 上書き、 lerp なし) */
@@ -1535,7 +1540,7 @@ interface Violation {
1535
1540
  detail: string;
1536
1541
  severity: "error" | "warn";
1537
1542
  }
1538
- type VisualAxis = "node-visibility" | "edge-label-overlap" | "edge-label-proximity" | "text-readability" | "row-format" | "alignment" | "clearance" | "arrow-endpoint-anchoring" | "label-char-range" | "node-overlap" | "edge-crossing" | "edge-node-cross" | "edge-segment-orthogonality" | "label-inside-viewbox" | "lane-cx-consistency" | "row-vertical-spacing" | "group-boundary-clearance" | "node-vertical-clearance" | "lane-lane-gap" | "arrow-marker-clearance" | "grid-alignment" | "phase-layout-stability" | "responsive-viewport" | "accessibility-basics" | "animation-frame-integrity" | "i18n-cjk-detection" | "contrast-basics" | "print-media-compat" | "color-blind-safety" | "marker-gradient-def-integrity" | "subpixel-precision" | "dom-complexity-budget" | "reduced-motion-compat" | "touch-target-size" | "row-content-typing" | "terminal-safe-text" | "gpu-layer-efficiency" | "memory-budget" | "svg-injection-safety" | "seo-metadata-quality" | "bidi-hyphenation" | "structured-data-extraction" | "diagram-version-semver" | "migration-path-consistency" | "axis-coverage-meta" | "axis-documentation-completeness" | "fixture-drift-detection" | "locale-parity" | "validate-performance-budget" | "node-inside-viewbox" | "node-inside-lane" | "edge-inside-viewbox" | "lane-label-inside-viewbox" | "lane-label-overlap" | "row-alignment" | "column-alignment" | "edge-stubout-min" | "fan-origin-single-point" | "detour-slot-distinct" | "arrow-endpoint-center" | "lane-border-clearance" | "row-gap-uniform" | "column-gap-uniform" | "rows-not-rendered" | "malformed-input" | "validation-interrupted";
1543
+ type VisualAxis = "node-visibility" | "edge-label-overlap" | "edge-label-proximity" | "text-readability" | "row-format" | "alignment" | "clearance" | "arrow-endpoint-anchoring" | "label-char-range" | "node-overlap" | "edge-crossing" | "edge-node-cross" | "edge-segment-orthogonality" | "label-inside-viewbox" | "lane-cx-consistency" | "row-vertical-spacing" | "group-boundary-clearance" | "node-vertical-clearance" | "lane-lane-gap" | "arrow-marker-clearance" | "grid-alignment" | "phase-layout-stability" | "responsive-viewport" | "accessibility-basics" | "animation-frame-integrity" | "i18n-cjk-detection" | "contrast-basics" | "print-media-compat" | "color-blind-safety" | "marker-gradient-def-integrity" | "subpixel-precision" | "dom-complexity-budget" | "reduced-motion-compat" | "touch-target-size" | "row-content-typing" | "terminal-safe-text" | "gpu-layer-efficiency" | "memory-budget" | "svg-injection-safety" | "seo-metadata-quality" | "bidi-hyphenation" | "structured-data-extraction" | "diagram-version-semver" | "migration-path-consistency" | "axis-coverage-meta" | "axis-documentation-completeness" | "fixture-drift-detection" | "locale-parity" | "validate-performance-budget" | "node-inside-viewbox" | "shape-label-dropped" | "node-inside-lane" | "edge-inside-viewbox" | "lane-label-inside-viewbox" | "lane-label-overlap" | "row-alignment" | "column-alignment" | "edge-stubout-min" | "fan-origin-single-point" | "detour-slot-distinct" | "arrow-endpoint-center" | "lane-border-clearance" | "row-gap-uniform" | "column-gap-uniform" | "rows-not-rendered" | "malformed-input" | "validation-interrupted";
1539
1544
  /**
1540
1545
  * 検査の用途。 用途によって見るべき軸が違う。
1541
1546
  *
@@ -2643,6 +2648,16 @@ declare function bboxDiffWorld(predicted: {
2643
2648
  max: number;
2644
2649
  };
2645
2650
 
2651
+ /**
2652
+ * 状態を読む書き方 (`{名前}`)。
2653
+ *
2654
+ * 中身の型 (`BoundNumber` / `BoundEnum`) は任意の文字列を受けるが、 **入口はこの形だけに
2655
+ * 限る** (#468 Round 1)。 広いままだと `value: "abc"` や `quadrant: "topLfet"` のような
2656
+ * 書き間違いが、 これまで組み立ての時点で止まっていたのに実行時まで進み、 解決側の既定値
2657
+ * (0 / 左下 / 普通) に落ちた図が出る。
2658
+ */
2659
+ type 名前の頭 = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "_";
2660
+ type BindingRef = `{${名前の頭}${string}}`;
2646
2661
  /**
2647
2662
  * 高位 API ... 著者が「lane / node / edge を 1 件ずつ宣言」 する低位 API を簡略化。
2648
2663
  *
@@ -2690,10 +2705,32 @@ type FlowPreset = {
2690
2705
  /** edge tone / style の default (各 step → next step の edge) */
2691
2706
  defaultTone?: Tone;
2692
2707
  defaultStyle?: EdgeStyle;
2708
+ /**
2709
+ * step 間の edge を自動生成するか (既定 true)。
2710
+ *
2711
+ * `false` にすると `step()` は node だけを置き、矢印は呼び手が `edge()` で宣言する。
2712
+ * **並び順と違う流れ** (`alpha` から `gamma` へ直接繋いで `beta` を経由しない等) を
2713
+ * 書きたい時に使う。 自動生成しか無かった間、その形は本 preset では作れなかった (#474)。
2714
+ *
2715
+ * 既定を `true` にしているので、既存の呼び出しは 1 行も変えずに同じ図になる。
2716
+ */
2717
+ autoChain?: boolean;
2693
2718
  };
2694
2719
  type FlowBuilder = {
2695
- /** step を順番に追加、 自動で前 step から edge 接続 */
2720
+ /** step を順番に追加、 自動で前 step から edge 接続 (`autoChain: false` なら node だけ) */
2696
2721
  step: (node: FlowStepInput, edgeLabel?: string) => FlowBuilder;
2722
+ /**
2723
+ * 矢印を宣言する (#474)。 tone / style は preset の既定を引き継ぐ。
2724
+ *
2725
+ * ここで作った矢印も `build()` の phase の `activate` に載る (自動生成分と同じ扱い)。
2726
+ * 載せないと animation で光らず、自動生成と見た目が揃わない。
2727
+ */
2728
+ edge: (from: string, to: string, opts?: {
2729
+ id?: string;
2730
+ label?: string;
2731
+ tone?: Tone;
2732
+ style?: EdgeStyle;
2733
+ }) => FlowBuilder;
2697
2734
  build: () => ReturnType<DiagramBuilder["build"]>;
2698
2735
  };
2699
2736
  /**
@@ -3023,8 +3060,8 @@ type TreeNode = {
3023
3060
  parent?: string;
3024
3061
  /** 表示 kind (default "card") */
3025
3062
  kind?: NodeKind;
3063
+ /** 箱の 2 行目に出す補足。 上の小ラベルは木では受けない (#471、 `TreeNodePayload` 参照) */
3026
3064
  subtitle?: string;
3027
- eyebrow?: string;
3028
3065
  };
3029
3066
  type TreePreset = {
3030
3067
  id: string;
@@ -3055,7 +3092,8 @@ declare function tree(preset: TreePreset): TreeBuilder;
3055
3092
  type JourneyStep = {
3056
3093
  id: string;
3057
3094
  title: string;
3058
- emotion: JourneyEmotion;
3095
+ /** 起伏の段階。 `{名前}` を書くと状態から読む (#468) */
3096
+ emotion: JourneyEmotion | BindingRef;
3059
3097
  /** どの touchpoint (例 "Website", "Email", "Support") */
3060
3098
  touchpoint?: string;
3061
3099
  /** opportunity (改善余地のメモ) */
@@ -3121,8 +3159,8 @@ declare function mindMap(preset: MindMapPreset): MindMapBuilder;
3121
3159
  type FunnelStage = {
3122
3160
  id: string;
3123
3161
  title: string;
3124
- /** この stage の人数 / 件数 */
3125
- count: number;
3162
+ /** この stage の人数 / 件数。 `{名前}` を書くと状態から読む (#468) */
3163
+ count: number | BindingRef;
3126
3164
  /** stage 詳細 */
3127
3165
  subtitle?: string;
3128
3166
  };
@@ -3153,8 +3191,8 @@ type QuadrantQuadrantLabel = QuadrantKey;
3153
3191
  type QuadrantItem = {
3154
3192
  id: string;
3155
3193
  title: string;
3156
- /** どの象限 (4 象限) */
3157
- quadrant: QuadrantQuadrantLabel;
3194
+ /** どの象限 (4 象限) `{名前}` を書くと状態から読む (#468) */
3195
+ quadrant: QuadrantQuadrantLabel | BindingRef;
3158
3196
  subtitle?: string;
3159
3197
  };
3160
3198
  type QuadrantPreset = {
@@ -3198,7 +3236,8 @@ type ChartType = "pie" | "bar" | "line";
3198
3236
  type ChartDatum = {
3199
3237
  id: string;
3200
3238
  label: string;
3201
- value: number;
3239
+ /** 棒 / 折れ線 / 扇の大きさ。 `{名前}` を書くと状態から読む (#468) */
3240
+ value: number | BindingRef;
3202
3241
  /** 個別 tone (default は preset の defaultTone) */
3203
3242
  tone?: Tone;
3204
3243
  };
@@ -3231,9 +3270,15 @@ declare function chart(preset: ChartPreset): ChartBuilder;
3231
3270
  type GanttTask = {
3232
3271
  id: string;
3233
3272
  title: string;
3234
- /** 開始 (例 "2026-Q1" / "Day 1") */
3273
+ /**
3274
+ * 開始の目盛りの名前 (例 "2026-Q1" / "Day 1")。
3275
+ *
3276
+ * `{名前}` を書くと **位置そのもの** を状態から読む (#468)。 目盛りの名前の対応付けは
3277
+ * 飛ばす = 名前の並びに `{名前}` が混ざると、 位置が状態で動くたびに目盛りの並びが
3278
+ * 変わってしまう。
3279
+ */
3235
3280
  start: string;
3236
- /** 終了 (例 "2026-Q2") */
3281
+ /** 終了の目盛りの名前。 `{名前}` の扱いは `start` と同じ (#468) */
3237
3282
  end: string;
3238
3283
  /** owner / assignee */
3239
3284
  owner?: string;
@@ -3245,6 +3290,17 @@ type GanttPreset = {
3245
3290
  topic: string;
3246
3291
  defaultTone?: Tone;
3247
3292
  laneWidth?: number;
3293
+ /**
3294
+ * 横軸を何目盛り分にするか (`#483`)。
3295
+ *
3296
+ * 書かないと今までどおり全 task の最大値から自動で決まるため、 `{名前}` で動く task が
3297
+ * 1 つあると **動かしていない task の帯まで伸び縮みする** (実測 = 端を 3 から 9 に動かすと
3298
+ * 静的な task の帯が 252 から 97.2 になった)。
3299
+ *
3300
+ * 書くと尺がその値で固定され、 他の task の帯の位置と幅が変わらない。 範囲から外れる task の
3301
+ * 帯は右端の目盛りに寄せて描く (`kinds/gantt.tsx` SSOT)。
3302
+ */
3303
+ axisMax?: number;
3248
3304
  };
3249
3305
  type GanttBuilder = {
3250
3306
  task: (t: GanttTask) => GanttBuilder;
@@ -3254,8 +3310,11 @@ type GanttBuilder = {
3254
3310
  * gantt preset ... Gantt chart / sprint planning / release timeline。
3255
3311
  * task ごとに 1 lane を作り、 start - end + owner を subtitle、 dependsOn で前 task → 次 task の edge を auto 生成。
3256
3312
  *
3313
+ * 横軸の範囲は既定では全 task の最大値から自動で決まる。 `axisMax` を書くと尺がその値で
3314
+ * 固定され、 `{名前}` で動く task があっても他の task の帯が動かない (`#483`)。
3315
+ *
3257
3316
  * @example
3258
- * gantt({ id: "release", topic: "Release timeline" })
3317
+ * gantt({ id: "release", topic: "Release timeline", axisMax: 4 })
3259
3318
  * .task({ id: "design", title: "Design", start: "Q1", end: "Q1" })
3260
3319
  * .task({ id: "build", title: "Build", start: "Q2", end: "Q2", dependsOn: "design" })
3261
3320
  * .task({ id: "test", title: "Test", start: "Q3", end: "Q3", dependsOn: "build" })
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 CdlState, f as CdlEventTarget, g as Computed, h as CdlDerivedValue, i as CdlScrollTrigger, L as LaidDiagram, j as CdlDiagramViewProps, k as LaidEdge, l as LaidNode, m as CdlEdge, B as BBox, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-DquCvgOB.js';
2
- export { n as CdlDiagramView, o as CdlEventBinding, p as CdlEventKind, q as CdlFormula, r as CdlPhase, I as InteractiveHandlerMap, s as InteractiveSignalsAccessor, t as LaidLane, u as NODE_KINDS, v as ScrollProgressHandle, w as TONES, x as computeEventBindingKey, y as computeFormulaKey, z as computeInputSignalKey, A as computeScrollTriggerKey, D as computed, F as createInteractiveSignalsAccessor, G as createScrollProgressHandle, H as createScrollProgressSignals, K as hasInteractivePrimitives, M as signal } from './render-DquCvgOB.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 CdlState, f as CdlEventTarget, g as Computed, h as CdlDerivedValue, i as CdlScrollTrigger, L as LaidDiagram, j as CdlDiagramViewProps, k as LaidEdge, l as LaidNode, m as CdlEdge, B as BBox, N as NodeKind, J as JourneyEmotion, Q as QuadrantKey } from './render-CH1Qn3Jv.js';
2
+ export { n as CdlDiagramView, o as CdlEventBinding, p as CdlEventKind, q as CdlFormula, r as CdlPhase, I as InteractiveHandlerMap, s as InteractiveSignalsAccessor, t as LaidLane, u as NODE_KINDS, v as ScrollProgressHandle, w as TONES, x as computeEventBindingKey, y as computeFormulaKey, z as computeInputSignalKey, A as computeScrollTriggerKey, D as computed, F as createInteractiveSignalsAccessor, G as createScrollProgressHandle, H as createScrollProgressSignals, K as hasInteractivePrimitives, M as signal } from './render-CH1Qn3Jv.js';
3
3
  import { JSX } from 'react';
4
4
 
5
5
  declare function effect(fn: () => void | (() => void)): () => void;
@@ -997,6 +997,11 @@ type InputChain = {
997
997
  };
998
998
  type PhaseBuilder = {
999
999
  activate: (...ids: string[]) => PhaseBuilder;
1000
+ /**
1001
+ * この phase で左の起点から描き始める node を指定する (cdl#512)。
1002
+ * 対象は phase の進み (0→1) に合わせて描かれる。 現在の対象種別は `chart-line`。
1003
+ */
1004
+ draw: (...ids: string[]) => PhaseBuilder;
1000
1005
  /** 数値 state の線形補間 (write phase で 100→90 等) */
1001
1006
  tween: (stateId: string, from: number, to: number) => PhaseBuilder;
1002
1007
  /** 任意型 state を即時切替 (この phase 到達で value 上書き、 lerp なし) */
@@ -1535,7 +1540,7 @@ interface Violation {
1535
1540
  detail: string;
1536
1541
  severity: "error" | "warn";
1537
1542
  }
1538
- type VisualAxis = "node-visibility" | "edge-label-overlap" | "edge-label-proximity" | "text-readability" | "row-format" | "alignment" | "clearance" | "arrow-endpoint-anchoring" | "label-char-range" | "node-overlap" | "edge-crossing" | "edge-node-cross" | "edge-segment-orthogonality" | "label-inside-viewbox" | "lane-cx-consistency" | "row-vertical-spacing" | "group-boundary-clearance" | "node-vertical-clearance" | "lane-lane-gap" | "arrow-marker-clearance" | "grid-alignment" | "phase-layout-stability" | "responsive-viewport" | "accessibility-basics" | "animation-frame-integrity" | "i18n-cjk-detection" | "contrast-basics" | "print-media-compat" | "color-blind-safety" | "marker-gradient-def-integrity" | "subpixel-precision" | "dom-complexity-budget" | "reduced-motion-compat" | "touch-target-size" | "row-content-typing" | "terminal-safe-text" | "gpu-layer-efficiency" | "memory-budget" | "svg-injection-safety" | "seo-metadata-quality" | "bidi-hyphenation" | "structured-data-extraction" | "diagram-version-semver" | "migration-path-consistency" | "axis-coverage-meta" | "axis-documentation-completeness" | "fixture-drift-detection" | "locale-parity" | "validate-performance-budget" | "node-inside-viewbox" | "node-inside-lane" | "edge-inside-viewbox" | "lane-label-inside-viewbox" | "lane-label-overlap" | "row-alignment" | "column-alignment" | "edge-stubout-min" | "fan-origin-single-point" | "detour-slot-distinct" | "arrow-endpoint-center" | "lane-border-clearance" | "row-gap-uniform" | "column-gap-uniform" | "rows-not-rendered" | "malformed-input" | "validation-interrupted";
1543
+ type VisualAxis = "node-visibility" | "edge-label-overlap" | "edge-label-proximity" | "text-readability" | "row-format" | "alignment" | "clearance" | "arrow-endpoint-anchoring" | "label-char-range" | "node-overlap" | "edge-crossing" | "edge-node-cross" | "edge-segment-orthogonality" | "label-inside-viewbox" | "lane-cx-consistency" | "row-vertical-spacing" | "group-boundary-clearance" | "node-vertical-clearance" | "lane-lane-gap" | "arrow-marker-clearance" | "grid-alignment" | "phase-layout-stability" | "responsive-viewport" | "accessibility-basics" | "animation-frame-integrity" | "i18n-cjk-detection" | "contrast-basics" | "print-media-compat" | "color-blind-safety" | "marker-gradient-def-integrity" | "subpixel-precision" | "dom-complexity-budget" | "reduced-motion-compat" | "touch-target-size" | "row-content-typing" | "terminal-safe-text" | "gpu-layer-efficiency" | "memory-budget" | "svg-injection-safety" | "seo-metadata-quality" | "bidi-hyphenation" | "structured-data-extraction" | "diagram-version-semver" | "migration-path-consistency" | "axis-coverage-meta" | "axis-documentation-completeness" | "fixture-drift-detection" | "locale-parity" | "validate-performance-budget" | "node-inside-viewbox" | "shape-label-dropped" | "node-inside-lane" | "edge-inside-viewbox" | "lane-label-inside-viewbox" | "lane-label-overlap" | "row-alignment" | "column-alignment" | "edge-stubout-min" | "fan-origin-single-point" | "detour-slot-distinct" | "arrow-endpoint-center" | "lane-border-clearance" | "row-gap-uniform" | "column-gap-uniform" | "rows-not-rendered" | "malformed-input" | "validation-interrupted";
1539
1544
  /**
1540
1545
  * 検査の用途。 用途によって見るべき軸が違う。
1541
1546
  *
@@ -2643,6 +2648,16 @@ declare function bboxDiffWorld(predicted: {
2643
2648
  max: number;
2644
2649
  };
2645
2650
 
2651
+ /**
2652
+ * 状態を読む書き方 (`{名前}`)。
2653
+ *
2654
+ * 中身の型 (`BoundNumber` / `BoundEnum`) は任意の文字列を受けるが、 **入口はこの形だけに
2655
+ * 限る** (#468 Round 1)。 広いままだと `value: "abc"` や `quadrant: "topLfet"` のような
2656
+ * 書き間違いが、 これまで組み立ての時点で止まっていたのに実行時まで進み、 解決側の既定値
2657
+ * (0 / 左下 / 普通) に落ちた図が出る。
2658
+ */
2659
+ type 名前の頭 = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "_";
2660
+ type BindingRef = `{${名前の頭}${string}}`;
2646
2661
  /**
2647
2662
  * 高位 API ... 著者が「lane / node / edge を 1 件ずつ宣言」 する低位 API を簡略化。
2648
2663
  *
@@ -2690,10 +2705,32 @@ type FlowPreset = {
2690
2705
  /** edge tone / style の default (各 step → next step の edge) */
2691
2706
  defaultTone?: Tone;
2692
2707
  defaultStyle?: EdgeStyle;
2708
+ /**
2709
+ * step 間の edge を自動生成するか (既定 true)。
2710
+ *
2711
+ * `false` にすると `step()` は node だけを置き、矢印は呼び手が `edge()` で宣言する。
2712
+ * **並び順と違う流れ** (`alpha` から `gamma` へ直接繋いで `beta` を経由しない等) を
2713
+ * 書きたい時に使う。 自動生成しか無かった間、その形は本 preset では作れなかった (#474)。
2714
+ *
2715
+ * 既定を `true` にしているので、既存の呼び出しは 1 行も変えずに同じ図になる。
2716
+ */
2717
+ autoChain?: boolean;
2693
2718
  };
2694
2719
  type FlowBuilder = {
2695
- /** step を順番に追加、 自動で前 step から edge 接続 */
2720
+ /** step を順番に追加、 自動で前 step から edge 接続 (`autoChain: false` なら node だけ) */
2696
2721
  step: (node: FlowStepInput, edgeLabel?: string) => FlowBuilder;
2722
+ /**
2723
+ * 矢印を宣言する (#474)。 tone / style は preset の既定を引き継ぐ。
2724
+ *
2725
+ * ここで作った矢印も `build()` の phase の `activate` に載る (自動生成分と同じ扱い)。
2726
+ * 載せないと animation で光らず、自動生成と見た目が揃わない。
2727
+ */
2728
+ edge: (from: string, to: string, opts?: {
2729
+ id?: string;
2730
+ label?: string;
2731
+ tone?: Tone;
2732
+ style?: EdgeStyle;
2733
+ }) => FlowBuilder;
2697
2734
  build: () => ReturnType<DiagramBuilder["build"]>;
2698
2735
  };
2699
2736
  /**
@@ -3023,8 +3060,8 @@ type TreeNode = {
3023
3060
  parent?: string;
3024
3061
  /** 表示 kind (default "card") */
3025
3062
  kind?: NodeKind;
3063
+ /** 箱の 2 行目に出す補足。 上の小ラベルは木では受けない (#471、 `TreeNodePayload` 参照) */
3026
3064
  subtitle?: string;
3027
- eyebrow?: string;
3028
3065
  };
3029
3066
  type TreePreset = {
3030
3067
  id: string;
@@ -3055,7 +3092,8 @@ declare function tree(preset: TreePreset): TreeBuilder;
3055
3092
  type JourneyStep = {
3056
3093
  id: string;
3057
3094
  title: string;
3058
- emotion: JourneyEmotion;
3095
+ /** 起伏の段階。 `{名前}` を書くと状態から読む (#468) */
3096
+ emotion: JourneyEmotion | BindingRef;
3059
3097
  /** どの touchpoint (例 "Website", "Email", "Support") */
3060
3098
  touchpoint?: string;
3061
3099
  /** opportunity (改善余地のメモ) */
@@ -3121,8 +3159,8 @@ declare function mindMap(preset: MindMapPreset): MindMapBuilder;
3121
3159
  type FunnelStage = {
3122
3160
  id: string;
3123
3161
  title: string;
3124
- /** この stage の人数 / 件数 */
3125
- count: number;
3162
+ /** この stage の人数 / 件数。 `{名前}` を書くと状態から読む (#468) */
3163
+ count: number | BindingRef;
3126
3164
  /** stage 詳細 */
3127
3165
  subtitle?: string;
3128
3166
  };
@@ -3153,8 +3191,8 @@ type QuadrantQuadrantLabel = QuadrantKey;
3153
3191
  type QuadrantItem = {
3154
3192
  id: string;
3155
3193
  title: string;
3156
- /** どの象限 (4 象限) */
3157
- quadrant: QuadrantQuadrantLabel;
3194
+ /** どの象限 (4 象限) `{名前}` を書くと状態から読む (#468) */
3195
+ quadrant: QuadrantQuadrantLabel | BindingRef;
3158
3196
  subtitle?: string;
3159
3197
  };
3160
3198
  type QuadrantPreset = {
@@ -3198,7 +3236,8 @@ type ChartType = "pie" | "bar" | "line";
3198
3236
  type ChartDatum = {
3199
3237
  id: string;
3200
3238
  label: string;
3201
- value: number;
3239
+ /** 棒 / 折れ線 / 扇の大きさ。 `{名前}` を書くと状態から読む (#468) */
3240
+ value: number | BindingRef;
3202
3241
  /** 個別 tone (default は preset の defaultTone) */
3203
3242
  tone?: Tone;
3204
3243
  };
@@ -3231,9 +3270,15 @@ declare function chart(preset: ChartPreset): ChartBuilder;
3231
3270
  type GanttTask = {
3232
3271
  id: string;
3233
3272
  title: string;
3234
- /** 開始 (例 "2026-Q1" / "Day 1") */
3273
+ /**
3274
+ * 開始の目盛りの名前 (例 "2026-Q1" / "Day 1")。
3275
+ *
3276
+ * `{名前}` を書くと **位置そのもの** を状態から読む (#468)。 目盛りの名前の対応付けは
3277
+ * 飛ばす = 名前の並びに `{名前}` が混ざると、 位置が状態で動くたびに目盛りの並びが
3278
+ * 変わってしまう。
3279
+ */
3235
3280
  start: string;
3236
- /** 終了 (例 "2026-Q2") */
3281
+ /** 終了の目盛りの名前。 `{名前}` の扱いは `start` と同じ (#468) */
3237
3282
  end: string;
3238
3283
  /** owner / assignee */
3239
3284
  owner?: string;
@@ -3245,6 +3290,17 @@ type GanttPreset = {
3245
3290
  topic: string;
3246
3291
  defaultTone?: Tone;
3247
3292
  laneWidth?: number;
3293
+ /**
3294
+ * 横軸を何目盛り分にするか (`#483`)。
3295
+ *
3296
+ * 書かないと今までどおり全 task の最大値から自動で決まるため、 `{名前}` で動く task が
3297
+ * 1 つあると **動かしていない task の帯まで伸び縮みする** (実測 = 端を 3 から 9 に動かすと
3298
+ * 静的な task の帯が 252 から 97.2 になった)。
3299
+ *
3300
+ * 書くと尺がその値で固定され、 他の task の帯の位置と幅が変わらない。 範囲から外れる task の
3301
+ * 帯は右端の目盛りに寄せて描く (`kinds/gantt.tsx` SSOT)。
3302
+ */
3303
+ axisMax?: number;
3248
3304
  };
3249
3305
  type GanttBuilder = {
3250
3306
  task: (t: GanttTask) => GanttBuilder;
@@ -3254,8 +3310,11 @@ type GanttBuilder = {
3254
3310
  * gantt preset ... Gantt chart / sprint planning / release timeline。
3255
3311
  * task ごとに 1 lane を作り、 start - end + owner を subtitle、 dependsOn で前 task → 次 task の edge を auto 生成。
3256
3312
  *
3313
+ * 横軸の範囲は既定では全 task の最大値から自動で決まる。 `axisMax` を書くと尺がその値で
3314
+ * 固定され、 `{名前}` で動く task があっても他の task の帯が動かない (`#483`)。
3315
+ *
3257
3316
  * @example
3258
- * gantt({ id: "release", topic: "Release timeline" })
3317
+ * gantt({ id: "release", topic: "Release timeline", axisMax: 4 })
3259
3318
  * .task({ id: "design", title: "Design", start: "Q1", end: "Q1" })
3260
3319
  * .task({ id: "build", title: "Build", start: "Q2", end: "Q2", dependsOn: "design" })
3261
3320
  * .task({ id: "test", title: "Test", start: "Q3", end: "Q3", dependsOn: "build" })