@cardenelabs/cdl 0.60.0 → 0.61.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/CHANGELOG.md CHANGED
@@ -5,6 +5,26 @@ CDL (Chainome Diagram Language) の主要変更履歴。
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.61.0] - 2026-09-13
9
+
10
+ ### Added
11
+
12
+ - **選択肢と切り替えの値に見せる名前を書いて、操作部と箱の字をその名前で描けるようにした** (#855)
13
+
14
+ 選択肢を持つ入力欄 (`dropdown` / `radio` / `tabs` / `multi-select`) は選択肢を文字列で受け、1 つの文字列が
15
+ 値と見せる字を兼ねていた。 値を日本語にすると綴りで読む読み出し (信号の灯り等) が読めなくなるので、日本語の
16
+ 図でも選択肢と箱の差し込み (`状態: {status}`) に `red` のような英字が残っていた。
17
+
18
+ 選択肢を `{ value, label }` の組でも書けるようにした (文字列と混ぜて書ける。 型は `CdlInputOption`)。
19
+ 操作部の選択肢は名前を描き、`value` 属性・選んだ時に入る値・`data-cdl-multi-value` は綴りのまま。
20
+ 切り替えは `.input.toggle(id, { onLabel, offLabel })` で入と切の名前を書ける。
21
+
22
+ 箱の題・副題・見出し・値・行の差し込み (`{id}`) は、値が名前を持てば名前を差し込む。 `multi-select` は
23
+ 選んだ値ごとに名前へ置き換える。 状態の値そのものは綴りのまま残すので、表示の出し分け (`visibleIf`)・
24
+ 数の差し込み・読み出しは名前に影響されない。 組み立ての既定値の検査は値で比べ、名前を渡すと拒む。
25
+
26
+ 名前を書かない図は、操作部も箱も変更前と同じ markup を描く。
27
+
8
28
  ## [0.60.0] - 2026-09-13
9
29
 
10
30
  ### Added
@@ -2625,7 +2645,8 @@ Initial OSS release.
2625
2645
  使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
2626
2646
  行き止まりになる。
2627
2647
 
2628
- [Unreleased]: https://github.com/cardene777/cdl/compare/v0.60.0...HEAD
2648
+ [Unreleased]: https://github.com/cardene777/cdl/compare/v0.61.0...HEAD
2649
+ [0.61.0]: https://github.com/cardene777/cdl/compare/v0.60.0...v0.61.0
2629
2650
  [0.60.0]: https://github.com/cardene777/cdl/compare/v0.59.1...v0.60.0
2630
2651
  [0.59.1]: https://github.com/cardene777/cdl/compare/v0.59.0...v0.59.1
2631
2652
  [0.59.0]: https://github.com/cardene777/cdl/compare/v0.58.0...v0.59.0
package/dist/index.cjs CHANGED
@@ -1591,6 +1591,34 @@ function warn(message) {
1591
1591
  }
1592
1592
  }
1593
1593
 
1594
+ // src/input-option.ts
1595
+ function \u9078\u629E\u80A2\u306E\u5024(option) {
1596
+ return typeof option === "string" ? option : option.value;
1597
+ }
1598
+ function \u9078\u629E\u80A2\u306E\u540D\u524D(option) {
1599
+ return typeof option === "string" || option.label === "" ? \u9078\u629E\u80A2\u306E\u5024(option) : option.label;
1600
+ }
1601
+ function \u5024\u306E\u540D\u524D\u306E\u8868\u3092\u4F5C\u308B(inputs) {
1602
+ const \u8868 = /* @__PURE__ */ new Map();
1603
+ for (const input of inputs ?? []) {
1604
+ const \u540D\u524D = /* @__PURE__ */ new Map();
1605
+ if (input.kind === "dropdown" || input.kind === "radio" || input.kind === "tabs" || input.kind === "multi-select") {
1606
+ for (const option of input.options) {
1607
+ if (typeof option !== "string" && option.label !== "") \u540D\u524D.set(option.value, option.label);
1608
+ }
1609
+ } else if (input.kind === "toggle") {
1610
+ if (input.onLabel) \u540D\u524D.set("true", input.onLabel);
1611
+ if (input.offLabel) \u540D\u524D.set("false", input.offLabel);
1612
+ }
1613
+ if (\u540D\u524D.size > 0) \u8868.set(input.id, { \u540D\u524D, \u8907\u6570: input.kind === "multi-select" });
1614
+ }
1615
+ return \u8868;
1616
+ }
1617
+ function \u5024\u3092\u540D\u524D\u3067\u8AAD\u3080(\u5165\u529B\u6B04, \u5024) {
1618
+ if (!\u5165\u529B\u6B04.\u8907\u6570) return \u5165\u529B\u6B04.\u540D\u524D.get(\u5024) ?? \u5024;
1619
+ return \u5024.split(",").map((v) => \u5165\u529B\u6B04.\u540D\u524D.get(v) ?? v).join(",");
1620
+ }
1621
+
1594
1622
  // src/kinds/text-width.ts
1595
1623
  var WIDE_RATIO = 1.04;
1596
1624
  var NARROW_RATIO = 0.37;
@@ -2099,7 +2127,7 @@ function InputWidget({
2099
2127
  },
2100
2128
  "data-cdl-input": input.id,
2101
2129
  className: "cdl-ip-dropdown-select",
2102
- children: input.options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt, children: opt }, opt))
2130
+ children: input.options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: \u9078\u629E\u80A2\u306E\u5024(opt), children: \u9078\u629E\u80A2\u306E\u540D\u524D(opt) }, \u9078\u629E\u80A2\u306E\u5024(opt)))
2103
2131
  }
2104
2132
  )
2105
2133
  ] });
@@ -2116,17 +2144,17 @@ function InputWidget({
2116
2144
  {
2117
2145
  type: "radio",
2118
2146
  name: input.id,
2119
- value: opt,
2120
- checked: value === opt,
2147
+ value: \u9078\u629E\u80A2\u306E\u5024(opt),
2148
+ checked: value === \u9078\u629E\u80A2\u306E\u5024(opt),
2121
2149
  onChange: () => {
2122
- signal2.value = opt;
2150
+ signal2.value = \u9078\u629E\u80A2\u306E\u5024(opt);
2123
2151
  },
2124
2152
  "data-cdl-input": input.id,
2125
2153
  className: "cdl-ip-radio-input"
2126
2154
  }
2127
2155
  ),
2128
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cdl-ip-radio-label", children: opt })
2129
- ] }, opt)) })
2156
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cdl-ip-radio-label", children: \u9078\u629E\u80A2\u306E\u540D\u524D(opt) })
2157
+ ] }, \u9078\u629E\u80A2\u306E\u5024(opt))) })
2130
2158
  ] });
2131
2159
  case "color":
2132
2160
  return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "cdl-ip-item cdl-ip-color", "data-cdl-input-kind": "color", children: [
@@ -2176,14 +2204,14 @@ function InputWidget({
2176
2204
  {
2177
2205
  type: "button",
2178
2206
  role: "tab",
2179
- className: `cdl-ip-tabs-btn ${value === opt ? "cdl-ip-tabs-active" : ""}`,
2207
+ className: `cdl-ip-tabs-btn ${value === \u9078\u629E\u80A2\u306E\u5024(opt) ? "cdl-ip-tabs-active" : ""}`,
2180
2208
  onClick: () => {
2181
- signal2.value = opt;
2209
+ signal2.value = \u9078\u629E\u80A2\u306E\u5024(opt);
2182
2210
  },
2183
2211
  "data-cdl-input": input.id,
2184
- children: opt
2212
+ children: \u9078\u629E\u80A2\u306E\u540D\u524D(opt)
2185
2213
  },
2186
- opt
2214
+ \u9078\u629E\u80A2\u306E\u5024(opt)
2187
2215
  )) })
2188
2216
  ] });
2189
2217
  case "datetime":
@@ -4238,13 +4266,13 @@ function MultiSelectWidget({
4238
4266
  "button",
4239
4267
  {
4240
4268
  type: "button",
4241
- className: `cdl-ip-multi-select-chip ${selected.has(opt) ? "cdl-ip-multi-select-active" : ""}`,
4242
- onClick: () => toggle(opt),
4269
+ className: `cdl-ip-multi-select-chip ${selected.has(\u9078\u629E\u80A2\u306E\u5024(opt)) ? "cdl-ip-multi-select-active" : ""}`,
4270
+ onClick: () => toggle(\u9078\u629E\u80A2\u306E\u5024(opt)),
4243
4271
  "data-cdl-input": input.id,
4244
- "data-cdl-multi-value": opt,
4245
- children: opt
4272
+ "data-cdl-multi-value": \u9078\u629E\u80A2\u306E\u5024(opt),
4273
+ children: \u9078\u629E\u80A2\u306E\u540D\u524D(opt)
4246
4274
  },
4247
- opt
4275
+ \u9078\u629E\u80A2\u306E\u5024(opt)
4248
4276
  )) })
4249
4277
  ] });
4250
4278
  }
@@ -10130,9 +10158,9 @@ function diagram(id, options) {
10130
10158
  if (opts.options.length === 0) {
10131
10159
  throw new Error(`input.dropdown '${inputId}' \u306E options \u304C\u7A7A\u3067\u3059 (\u6700\u4F4E 1 \u4EF6\u5FC5\u8981)`);
10132
10160
  }
10133
- if (!opts.options.includes(opts.defaultValue)) {
10161
+ if (!opts.options.some((o) => \u9078\u629E\u80A2\u306E\u5024(o) === opts.defaultValue)) {
10134
10162
  throw new Error(
10135
- `input.dropdown '${inputId}' \u306E defaultValue '${opts.defaultValue}' \u304C options \u306B\u542B\u307E\u308C\u307E\u305B\u3093 (options: ${opts.options.join(", ")})`
10163
+ `input.dropdown '${inputId}' \u306E defaultValue '${opts.defaultValue}' \u304C options \u306E\u5024\u306B\u542B\u307E\u308C\u307E\u305B\u3093 (options: ${opts.options.map(\u9078\u629E\u80A2\u306E\u5024).join(", ")})`
10136
10164
  );
10137
10165
  }
10138
10166
  inputs.push({
@@ -10150,6 +10178,9 @@ function diagram(id, options) {
10150
10178
  id: inputId,
10151
10179
  kind: "toggle",
10152
10180
  defaultValue: opts.defaultValue,
10181
+ // 名前を渡さない切り替えは変更前と同じ形に保つ (空の名前も渡さないのと同じ)
10182
+ ...opts.onLabel ? { onLabel: opts.onLabel } : {},
10183
+ ...opts.offLabel ? { offLabel: opts.offLabel } : {},
10153
10184
  label: opts.label
10154
10185
  });
10155
10186
  return api;
@@ -10217,9 +10248,9 @@ function diagram(id, options) {
10217
10248
  if (opts.options.length === 0) {
10218
10249
  throw new Error(`input.radio '${inputId}' \u306E options \u304C\u7A7A\u3067\u3059`);
10219
10250
  }
10220
- if (!opts.options.includes(opts.defaultValue)) {
10251
+ if (!opts.options.some((o) => \u9078\u629E\u80A2\u306E\u5024(o) === opts.defaultValue)) {
10221
10252
  throw new Error(
10222
- `input.radio '${inputId}' \u306E defaultValue '${opts.defaultValue}' \u304C options \u306B\u542B\u307E\u308C\u307E\u305B\u3093`
10253
+ `input.radio '${inputId}' \u306E defaultValue '${opts.defaultValue}' \u304C options \u306E\u5024\u306B\u542B\u307E\u308C\u307E\u305B\u3093`
10223
10254
  );
10224
10255
  }
10225
10256
  inputs.push({
@@ -10304,8 +10335,8 @@ function diagram(id, options) {
10304
10335
  if (opts.options.length === 0) {
10305
10336
  throw new Error(`input.tabs '${inputId}' \u306E options \u304C\u7A7A\u3067\u3059`);
10306
10337
  }
10307
- if (!opts.options.includes(opts.defaultValue)) {
10308
- throw new Error(`input.tabs '${inputId}' \u306E defaultValue \u304C options \u306B\u542B\u307E\u308C\u307E\u305B\u3093`);
10338
+ if (!opts.options.some((o) => \u9078\u629E\u80A2\u306E\u5024(o) === opts.defaultValue)) {
10339
+ throw new Error(`input.tabs '${inputId}' \u306E defaultValue \u304C options \u306E\u5024\u306B\u542B\u307E\u308C\u307E\u305B\u3093`);
10309
10340
  }
10310
10341
  inputs.push({
10311
10342
  id: inputId,
@@ -14936,11 +14967,14 @@ function mergeStateValues(base, overrides) {
14936
14967
  }
14937
14968
  return merged;
14938
14969
  }
14939
- function interpolate(template, values) {
14970
+ function interpolate(template, values, \u540D\u524D\u306E\u8868) {
14940
14971
  return template.replace(TEMPLATE_REF_RE, (_, id, accessor) => {
14941
14972
  const raw = Object.hasOwn(values, id) ? values[id] : void 0;
14942
14973
  if (raw === void 0) return `{${id}${accessor ?? ""}}`;
14943
- if (!accessor) return raw;
14974
+ if (!accessor) {
14975
+ const \u5165\u529B\u6B04 = \u540D\u524D\u306E\u8868?.get(id);
14976
+ return \u5165\u529B\u6B04 ? \u5024\u3092\u540D\u524D\u3067\u8AAD\u3080(\u5165\u529B\u6B04, raw) : raw;
14977
+ }
14944
14978
  const arr = parseArraySignal(raw);
14945
14979
  if (!arr) return `{${id}${accessor}}`;
14946
14980
  if (accessor === ".length") return String(arr.length);
@@ -24584,7 +24618,8 @@ function GenericNode({
24584
24618
  node,
24585
24619
  active,
24586
24620
  value,
24587
- stateValues
24621
+ stateValues,
24622
+ \u5024\u306E\u540D\u524D
24588
24623
  }) {
24589
24624
  const base = STYLES[node.kind] ?? FALLBACK;
24590
24625
  const toned = toneColor3(node.tone);
@@ -24670,7 +24705,7 @@ function GenericNode({
24670
24705
  style.look === "ledger" && /* @__PURE__ */ jsxRuntime.jsx("line", { x1: 1, y1: h - 7, x2: w - 1, y2: h - 7, stroke: paint.stroke, strokeWidth: 1 })
24671
24706
  ] });
24672
24707
  })();
24673
- const resolvedValue = value !== void 0 ? interpolate(value, stateValues) : void 0;
24708
+ const resolvedValue = value !== void 0 ? interpolate(value, stateValues, \u5024\u306E\u540D\u524D) : void 0;
24674
24709
  const hasRows = (node.rows?.length ?? 0) > 0;
24675
24710
  const centered = genericTextCentered(node.kind, hasRows);
24676
24711
  const textAnchor = centered ? "middle" : "start";
@@ -24720,7 +24755,7 @@ function GenericNode({
24720
24755
  }
24721
24756
  ),
24722
24757
  node.rows && node.rows.length > 0 && (() => {
24723
- const resolved = node.rows.map((row) => interpolate(row, stateValues));
24758
+ const resolved = node.rows.map((row) => interpolate(row, stateValues, \u5024\u306E\u540D\u524D));
24724
24759
  const splits = resolved.map(splitRow);
24725
24760
  const leftMaxWidth = splits.reduce(
24726
24761
  (m, s) => Math.max(m, rowColumnWidth(s.left, GENERIC_ROW_LEFT_SIZE_PX, false)),
@@ -31385,10 +31420,11 @@ function CdlNodeView({
31385
31420
  currentPhaseId,
31386
31421
  chartLineScale,
31387
31422
  \u95A2\u4FC2\u306E\u53D7\u3051\u53E3,
31388
- lang
31423
+ lang,
31424
+ \u5024\u306E\u540D\u524D
31389
31425
  }) {
31390
- const value = node.value ? interpolate(node.value, stateValues) : void 0;
31391
- const rows = (node.rows ?? []).map((r) => interpolate(r, stateValues));
31426
+ const value = node.value ? interpolate(node.value, stateValues, \u5024\u306E\u540D\u524D) : void 0;
31427
+ const rows = (node.rows ?? []).map((r) => interpolate(r, stateValues, \u5024\u306E\u540D\u524D));
31392
31428
  const boundW = node.wBind ? resolveNumericAttr(node.wBind, stateValues, node.w) : node.w;
31393
31429
  const boundH = node.hBind ? resolveNumericAttr(node.hBind, stateValues, node.h) : node.h;
31394
31430
  const boundOpacity = node.opacity !== void 0 ? Math.min(1, Math.max(0, resolveNumericAttr(node.opacity, stateValues, 1))) : void 0;
@@ -31402,9 +31438,9 @@ function CdlNodeView({
31402
31438
  }
31403
31439
  const resolvedNode = {
31404
31440
  ...node,
31405
- title: interpolate(node.title, stateValues),
31406
- subtitle: node.subtitle ? interpolate(node.subtitle, stateValues) : node.subtitle,
31407
- eyebrow: node.eyebrow ? interpolate(node.eyebrow, stateValues) : node.eyebrow,
31441
+ title: interpolate(node.title, stateValues, \u5024\u306E\u540D\u524D),
31442
+ subtitle: node.subtitle ? interpolate(node.subtitle, stateValues, \u5024\u306E\u540D\u524D) : node.subtitle,
31443
+ eyebrow: node.eyebrow ? interpolate(node.eyebrow, stateValues, \u5024\u306E\u540D\u524D) : node.eyebrow,
31408
31444
  w: boundW,
31409
31445
  h: boundH
31410
31446
  };
@@ -31685,7 +31721,7 @@ function CdlNodeView({
31685
31721
  case "mark-end":
31686
31722
  return /* @__PURE__ */ jsxRuntime.jsx(MarkEndNode, { node: resolvedNode, active });
31687
31723
  default:
31688
- return /* @__PURE__ */ jsxRuntime.jsx(GenericNode, { node: resolvedNode, active, value: node.value, stateValues });
31724
+ return /* @__PURE__ */ jsxRuntime.jsx(GenericNode, { node: resolvedNode, active, value: node.value, stateValues, \u5024\u306E\u540D\u524D });
31689
31725
  }
31690
31726
  })();
31691
31727
  const offsetX = node.renderOffsetX !== void 0 ? resolveNumericAttr(node.renderOffsetX, stateValues, 0) : 0;
@@ -31767,7 +31803,8 @@ function CdlStage({
31767
31803
  stateValues,
31768
31804
  debug,
31769
31805
  compact = false,
31770
- svgRef
31806
+ svgRef,
31807
+ \u5024\u306E\u540D\u524D
31771
31808
  }) {
31772
31809
  const [\u7126\u70B9, set\u7126\u70B9] = react.useState(null);
31773
31810
  const \u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B = (laid.relationFocus ?? RELATION_FOCUS_DEFAULT) === "hover";
@@ -32047,6 +32084,7 @@ function CdlStage({
32047
32084
  drawing: \u63CF\u304F,
32048
32085
  progress: \u63CF\u304F ? \u63CF\u304F\u9032\u307F : progress,
32049
32086
  stateValues,
32087
+ \u5024\u306E\u540D\u524D,
32050
32088
  currentPhaseId: currentPhase?.id,
32051
32089
  chartLineScale: chartLineScales.get(node.id)
32052
32090
  }
@@ -32288,6 +32326,7 @@ function CdlDiagramView({ diagram: diagram2, laid: laidProp, hideHeader = false,
32288
32326
  if (!isInteractive) return baseStateValues;
32289
32327
  return mergeStateValues(baseStateValues, interactive.stateOverrides);
32290
32328
  }, [isInteractive, baseStateValues, interactive.stateOverrides]);
32329
+ const \u5024\u306E\u540D\u524D = react.useMemo(() => \u5024\u306E\u540D\u524D\u306E\u8868\u3092\u4F5C\u308B(diagram2.inputs), [diagram2.inputs]);
32291
32330
  return /* @__PURE__ */ jsxRuntime.jsxs(
32292
32331
  "div",
32293
32332
  {
@@ -32316,7 +32355,7 @@ function CdlDiagramView({ diagram: diagram2, laid: laidProp, hideHeader = false,
32316
32355
  }
32317
32356
  ),
32318
32357
  isInteractive && interactive.panel,
32319
- /* @__PURE__ */ jsxRuntime.jsx(CdlStage, { laid, currentPhase, progress, drawProgress, stateValues, debug, compact: hideHeader, svgRef: isInteractive ? interactive.svgRef : void 0 }),
32358
+ /* @__PURE__ */ jsxRuntime.jsx(CdlStage, { laid, currentPhase, progress, drawProgress, stateValues, \u5024\u306E\u540D\u524D, debug, compact: hideHeader, svgRef: isInteractive ? interactive.svgRef : void 0 }),
32320
32359
  hideHeader && !hideMiniPhaseIndicator && currentPhase && laid.phases.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 border-t border-[var(--cdl-divider,#d4d4d8)]/40 bg-[var(--cdl-stage-bg,#f1f5f9)]/50 px-3 py-2 text-xs", children: [
32321
32360
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
32322
32361
  laid.phases.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(