@cardenelabs/cdl 0.60.0 → 0.62.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.
@@ -26,6 +26,7 @@ import { resolveChartData } from "./payload-binding";
26
26
  import { relatedFocusSet } from "./relation-focus";
27
27
  import { TONE, TONE_HEX } from "./tone";
28
28
  import { computeStateValues } from "./utils";
29
+ import type { 値の名前の表 } from "../input-option";
29
30
 
30
31
  export function CdlStage({
31
32
  laid,
@@ -36,8 +37,11 @@ export function CdlStage({
36
37
  debug,
37
38
  compact = false,
38
39
  svgRef,
40
+ 値の名前,
39
41
  }: {
40
42
  laid: LaidDiagram;
43
+ /** 入力欄の値ごとの名前 (#855)。 箱の字の差し込みへ渡す。 渡さない呼び方は値を綴りのまま差し込む */
44
+ 値の名前?: 値の名前の表;
41
45
  currentPhase: CdlPhase | undefined;
42
46
  progress: number;
43
47
  /**
@@ -432,6 +436,7 @@ export function CdlStage({
432
436
  drawing={描く}
433
437
  progress={描く ? 描く進み : progress}
434
438
  stateValues={stateValues}
439
+ 値の名前={値の名前}
435
440
  currentPhaseId={currentPhase?.id}
436
441
  chartLineScale={chartLineScales.get(node.id)}
437
442
  />
@@ -2,6 +2,7 @@ import { lerp } from "../anim";
2
2
  import type { LaidDiagram } from "../types";
3
3
  import { withDerivedValues } from "./derived-values";
4
4
  import { TEMPLATE_LEFTOVER_SRC, TEMPLATE_REF_SRC } from "../template-name";
5
+ import { 値を名前で読む, type 値の名前の表 } from "../input-option";
5
6
 
6
7
  const TEMPLATE_REF_RE = new RegExp(TEMPLATE_REF_SRC, "g");
7
8
  // 残っている参照の判定用。 `g` を付けないので `lastIndex` を持たず、 使い回しても結果が
@@ -113,14 +114,25 @@ export function mergeStateValues(
113
114
  *
114
115
  * 名前に使える文字は `template-name.ts` が決める (engine 全体で 1 つ)。 ここだけで
115
116
  * 定義すると、 式を書ける側との間で「読めるが書けない」 「書けるが読めない」 名前ができる。
117
+ *
118
+ * `名前の表` を渡すと、 付け足しの無い `{id}` の値を入力欄の値ごとの名前で差し込む (#855)。
119
+ * 渡すのは画面に字を描く所 (箱の題・副題・見出し・値・行) だけ。 表示の出し分けと数の差し込みは
120
+ * 値を綴りのまま読む必要があるので渡さない。
116
121
  */
117
- export function interpolate(template: string, values: Record<string, string>): string {
122
+ export function interpolate(
123
+ template: string,
124
+ values: Record<string, string>,
125
+ 名前の表?: 値の名前の表,
126
+ ): string {
118
127
  return template.replace(TEMPLATE_REF_RE, (_, id: string, accessor?: string) => {
119
128
  // 自分が持つ名前だけを見る。 継承を辿ると `{constructor}` が「値がある」 と読まれ、
120
129
  // prototype の中身が図に出る (実測)
121
130
  const raw = Object.hasOwn(values, id) ? values[id] : undefined;
122
131
  if (raw === undefined) return `{${id}${accessor ?? ""}}`;
123
- if (!accessor) return raw;
132
+ if (!accessor) {
133
+ const 入力欄 = 名前の表?.get(id);
134
+ return 入力欄 ? 値を名前で読む(入力欄, raw) : raw;
135
+ }
124
136
  const arr = parseArraySignal(raw);
125
137
  if (!arr) return `{${id}${accessor}}`;
126
138
  if (accessor === ".length") return String(arr.length);
package/src/render.tsx CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  type InteractiveHandlerMap,
11
11
  } from "./render/interactive-panel";
12
12
  import { computeStateValues, mergeStateValues } from "./render/utils";
13
+ import { 値の名前の表を作る } from "./input-option";
13
14
  import { visualValidateLaid } from "./visual-validate";
14
15
  import type { CdlDiagram, LaidDiagram } from "./types";
15
16
 
@@ -165,6 +166,10 @@ export function CdlDiagramView({ diagram, laid: laidProp, hideHeader = false, hi
165
166
  return mergeStateValues(baseStateValues, interactive.stateOverrides);
166
167
  }, [isInteractive, baseStateValues, interactive.stateOverrides]);
167
168
 
169
+ // 入力欄の値ごとの名前 (#855)。 状態の値には混ぜず、箱の字の差し込みにだけ渡す
170
+ // (出し分けと綴りで読む読み出しは値を綴りのまま読む)
171
+ const 値の名前 = useMemo(() => 値の名前の表を作る(diagram.inputs), [diagram.inputs]);
172
+
168
173
  return (
169
174
  <div
170
175
  ref={isInteractive ? interactive.containerRef : undefined}
@@ -193,7 +198,7 @@ export function CdlDiagramView({ diagram, laid: laidProp, hideHeader = false, hi
193
198
  {/* interactive panel = input widget / formula readout / scroll readout (SVG の上に配置)、
194
199
  diagram に interactive primitive がなければ null (SSR / render 影響なし) */}
195
200
  {isInteractive && interactive.panel}
196
- <CdlStage laid={laid} currentPhase={currentPhase} progress={progress} drawProgress={drawProgress} stateValues={stateValues} debug={debug} compact={hideHeader} svgRef={isInteractive ? interactive.svgRef : undefined} />
201
+ <CdlStage laid={laid} currentPhase={currentPhase} progress={progress} drawProgress={drawProgress} stateValues={stateValues} 値の名前={値の名前} debug={debug} compact={hideHeader} svgRef={isInteractive ? interactive.svgRef : undefined} />
197
202
  {/* hideHeader + multi-phase 時、 phase indicator が消えると動きが読めないため
198
203
  mini indicator (dot 列 + 現在 phase title + badge) を bottom に追加 */}
199
204
  {hideHeader && !hideMiniPhaseIndicator && currentPhase && laid.phases.length > 1 && (
package/src/types.ts CHANGED
@@ -820,6 +820,15 @@ export type CdlState = {
820
820
  initial: number | string;
821
821
  };
822
822
 
823
+ /**
824
+ * 選択肢を持つ入力欄 (`dropdown` / `radio` / `tabs` / `multi-select`) の 1 つの選択肢 (#855)。
825
+ *
826
+ * 文字列は値と見せる字を兼ねる。 組は `value` を入力欄の値にし、`label` を操作部の選択肢と
827
+ * 箱の字の差し込み (`{id}`) に描く。 値は綴りのまま残るので、綴りで読む読み出し (信号の灯り等) と
828
+ * 表示の出し分け (`visibleIf`) は名前に影響されない。
829
+ */
830
+ export type CdlInputOption = string | { value: string; label: string };
831
+
823
832
  /**
824
833
  * interactive input widget spec (v0.5+、 CAR #243)。
825
834
  *
@@ -855,8 +864,8 @@ export type CdlInput =
855
864
  | {
856
865
  id: string;
857
866
  kind: "dropdown";
858
- /** 選択肢一覧 (非空必須、 defaultValue はこの中の 1 つ) */
859
- options: readonly string[];
867
+ /** 選択肢一覧 (非空必須、 defaultValue はこの中の 1 つの値) */
868
+ options: readonly CdlInputOption[];
860
869
  defaultValue: string;
861
870
  label?: string;
862
871
  }
@@ -865,6 +874,10 @@ export type CdlInput =
865
874
  kind: "toggle";
866
875
  defaultValue: boolean;
867
876
  label?: string;
877
+ /** 入の時に箱の字の差し込み (`{id}`) へ描く名前。 省略時は `true` (#855) */
878
+ onLabel?: string;
879
+ /** 切の時に箱の字の差し込み (`{id}`) へ描く名前。 省略時は `false` (#855) */
880
+ offLabel?: string;
868
881
  }
869
882
  /**
870
883
  * XY pad = 2 軸 slider、 `.input.xypad(id)` は 実は 2 個の signal (id_x / id_y) を生成する
@@ -896,7 +909,7 @@ export type CdlInput =
896
909
  | {
897
910
  id: string;
898
911
  kind: "radio";
899
- options: readonly string[];
912
+ options: readonly CdlInputOption[];
900
913
  defaultValue: string;
901
914
  label?: string;
902
915
  }
@@ -922,7 +935,7 @@ export type CdlInput =
922
935
  | {
923
936
  id: string;
924
937
  kind: "multi-select";
925
- options: readonly string[];
938
+ options: readonly CdlInputOption[];
926
939
  defaultValues: readonly string[];
927
940
  label?: string;
928
941
  }
@@ -930,7 +943,7 @@ export type CdlInput =
930
943
  | {
931
944
  id: string;
932
945
  kind: "tabs";
933
- options: readonly string[];
946
+ options: readonly CdlInputOption[];
934
947
  defaultValue: string;
935
948
  label?: string;
936
949
  }