@cardenelabs/cdl 0.21.1 → 0.22.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,39 @@ CDL (Chainome Diagram Language) の主要変更履歴。
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.22.0] - 2026-08-30
9
+
10
+ ### Changed
11
+
12
+ - **箱が中身より高い時、字を中央へ寄せるようにした** (#597)
13
+
14
+ 段の高さは行内の最大値で決まるので、行に高い箱が 1 つあると同じ行の箱もそこまで伸びる。
15
+ 字は上から置かれるため、伸びたぶんがそのまま下に空いていた。
16
+
17
+ 実測 = dragon の見本で `BEGIN tx` の箱が 240 に伸びているのに中身は 67。 字が上端に
18
+ 貼り付き、同じ縦列の下 2 つ (67 のまま) と不揃いに見えていた。
19
+
20
+ 余りを上下で分ける。 3 段 (小見出し / 名前 / 説明) は同じ量だけ動かすので、段どうしの
21
+ 間隔は変わらない。
22
+
23
+ 行を持つ箱と値を持つ箱は動かさない (行は上端から数え、値は下端から置くので重なる)。
24
+ 小型の箱と、字を中央へ寄せる 2 種別も元から中央にあるので対象外。
25
+
26
+ ## [0.21.2] - 2026-08-30
27
+
28
+ ### Fixed
29
+
30
+ - **雲の字を絵の芯に合わせた** (#588)
31
+
32
+ 雲は 5 つの円で描き、箱の上へ 0.11 はみ出し下は 0.15 手前で終わる = **絵の芯が箱の芯より
33
+ 上にある**。 字を箱の芯に合わせていたので、絵に対して下へ寄って見えていた
34
+ (実測で上 71.5 / 下 27.9、差 43.6)。 直して 49 / 51.5 になる。
35
+
36
+ 円の中心と半径を `layout/spec.ts` の表に移し、描き手と字を置く側が同じ表から引く。
37
+ 絵の芯もその表から出すので、円を動かせば字も追随する。
38
+
39
+ ひし形 (`decision`) は箱と絵の芯が同じなので動かない。
40
+
8
41
  ## [0.21.1] - 2026-08-29
9
42
 
10
43
  ### Fixed
@@ -1080,7 +1113,9 @@ Initial OSS release.
1080
1113
  使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
1081
1114
  行き止まりになる。
1082
1115
 
1083
- [Unreleased]: https://github.com/cardene777/cdl/compare/v0.21.1...HEAD
1116
+ [Unreleased]: https://github.com/cardene777/cdl/compare/v0.22.0...HEAD
1117
+ [0.22.0]: https://github.com/cardene777/cdl/compare/v0.21.2...v0.22.0
1118
+ [0.21.2]: https://github.com/cardene777/cdl/compare/v0.21.1...v0.21.2
1084
1119
  [0.21.1]: https://github.com/cardene777/cdl/compare/v0.21.0...v0.21.1
1085
1120
  [0.21.0]: https://github.com/cardene777/cdl/compare/v0.20.1...v0.21.0
1086
1121
  [0.20.1]: https://github.com/cardene777/cdl/compare/v0.20.0...v0.20.1
package/dist/index.cjs CHANGED
@@ -12026,6 +12026,25 @@ function \u4E2D\u8EAB\u304B\u3089\u51FA\u3059\u9AD8\u3055(kind, \u6E80\u8F09h, \
12026
12026
  return Math.max(MIN_BOX_H, \u6E80\u8F09h - \u5F15\u304F);
12027
12027
  }
12028
12028
  var MIN_BOX_H = 44;
12029
+ var CLOUD_CIRCLES = [
12030
+ { cx: -0.8, cy: -0.05 + 0.08, r: 0.32 },
12031
+ { cx: -0.4, cy: -0.05 - 0.05, r: 0.4 },
12032
+ { cx: 0, cy: -0.05 - 0.1, r: 0.46 },
12033
+ { cx: 0.4, cy: -0.05 - 0.05, r: 0.4 },
12034
+ { cx: 0.8, cy: -0.05 + 0.08, r: 0.32 }
12035
+ ];
12036
+ var CLOUD_ART_CENTER_RISE = (() => {
12037
+ const \u4E0A = Math.min(...CLOUD_CIRCLES.map((c) => c.cy - c.r));
12038
+ const \u4E0B = Math.max(...CLOUD_CIRCLES.map((c) => c.cy + c.r));
12039
+ return -(\u4E0A + \u4E0B) / 2;
12040
+ })();
12041
+ function \u4F59\u308A\u3092\u5206\u3051\u308B(kind, \u6E80\u8F09h, \u5B9F\u969B\u306Eh, \u4E2D\u8EAB) {
12042
+ if (!\u6BB5\u3092\u7A4D\u3080\u7BB1\u304B(kind, \u4E2D\u8EAB.hasRows)) return 0;
12043
+ if (\u4E2D\u8EAB.hasValue) return 0;
12044
+ const \u8981\u308B\u9AD8\u3055 = \u4E2D\u8EAB\u304B\u3089\u51FA\u3059\u9AD8\u3055(kind, \u6E80\u8F09h, \u4E2D\u8EAB);
12045
+ const \u4F59\u308A = \u5B9F\u969B\u306Eh - \u8981\u308B\u9AD8\u3055;
12046
+ return \u4F59\u308A > 0 ? Math.round(\u4F59\u308A / 2) : 0;
12047
+ }
12029
12048
 
12030
12049
  // src/layout/footer-shape.ts
12031
12050
  var SHAPE_DRAW_UP_EXTENT = {
@@ -21705,7 +21724,14 @@ function ActorNode({ node, active, value }) {
21705
21724
  const x = node.cx - node.w / 2;
21706
21725
  const y = node.cy - node.h / 2;
21707
21726
  const \u7E70\u308A\u4E0A\u3052 = node.eyebrow ? 0 : \u76EE\u5370\u306A\u3057\u306E\u7E70\u308A\u4E0A\u3052("actor");
21708
- const \u540D\u524D = titlePlacement(node, { x: 26, y: 86 - \u7E70\u308A\u4E0A\u3052, size: 32 }, { hasEyebrow: Boolean(node.eyebrow) });
21727
+ const \u4F59\u308A = \u4F59\u308A\u3092\u5206\u3051\u308B("actor", NODE_SIZE.actor.h, node.h, {
21728
+ hasEyebrow: Boolean(node.eyebrow),
21729
+ hasSubtitle: Boolean(node.subtitle),
21730
+ hasValue: Boolean(value),
21731
+ hasRows: false
21732
+ });
21733
+ const \u305A\u3089\u3057 = \u7E70\u308A\u4E0A\u3052 - \u4F59\u308A;
21734
+ const \u540D\u524D = titlePlacement(node, { x: 26, y: 86 - \u305A\u3089\u3057, size: 32 }, { hasEyebrow: Boolean(node.eyebrow) });
21709
21735
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x} ${y})`, children: [
21710
21736
  /* @__PURE__ */ jsxRuntime.jsx(
21711
21737
  "rect",
@@ -21721,7 +21747,7 @@ function ActorNode({ node, active, value }) {
21721
21747
  strokeWidth: active ? 3 : 1.25
21722
21748
  }
21723
21749
  ),
21724
- node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 38, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
21750
+ node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 38 - \u4F59\u308A, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
21725
21751
  /* @__PURE__ */ jsxRuntime.jsx(
21726
21752
  "text",
21727
21753
  {
@@ -21740,13 +21766,13 @@ function ActorNode({ node, active, value }) {
21740
21766
  {
21741
21767
  "data-cdl-role": "node-row-divider",
21742
21768
  x1: 26,
21743
- y1: 110 - \u7E70\u308A\u4E0A\u3052,
21769
+ y1: 110 - \u305A\u3089\u3057,
21744
21770
  x2: node.w - 26,
21745
- y2: 110 - \u7E70\u308A\u4E0A\u3052,
21771
+ y2: 110 - \u305A\u3089\u3057,
21746
21772
  stroke: "var(--cdl-row-divider, #7e848e)"
21747
21773
  }
21748
21774
  ),
21749
- node.subtitle && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 140 - \u7E70\u308A\u4E0A\u3052, fontSize: 20, fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle }),
21775
+ node.subtitle && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 140 - \u305A\u3089\u3057, fontSize: 20, fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle }),
21750
21776
  value && /* @__PURE__ */ jsxRuntime.jsx(
21751
21777
  "text",
21752
21778
  {
@@ -21772,7 +21798,14 @@ function CardNode({ node, active }) {
21772
21798
  const compact = isCompactBox(node.h);
21773
21799
  const \u5C0F\u578B\u306B\u547C\u3073\u540D = compact && Boolean(node.subtitle);
21774
21800
  const \u7E70\u308A\u4E0A\u3052 = node.eyebrow ? 0 : \u76EE\u5370\u306A\u3057\u306E\u7E70\u308A\u4E0A\u3052("card");
21775
- const titleY = compact ? \u5C0F\u578B\u306B\u547C\u3073\u540D ? node.h / 2 - 2 : node.h / 2 + 8 : 86 - \u7E70\u308A\u4E0A\u3052;
21801
+ const \u4F59\u308A = compact ? 0 : \u4F59\u308A\u3092\u5206\u3051\u308B("card", NODE_SIZE.card.h, node.h, {
21802
+ hasEyebrow: Boolean(node.eyebrow),
21803
+ hasSubtitle: Boolean(node.subtitle),
21804
+ hasValue: false,
21805
+ hasRows: false
21806
+ });
21807
+ const \u305A\u3089\u3057 = \u7E70\u308A\u4E0A\u3052 - \u4F59\u308A;
21808
+ const titleY = compact ? \u5C0F\u578B\u306B\u547C\u3073\u540D ? node.h / 2 - 2 : node.h / 2 + 8 : 86 - \u305A\u3089\u3057;
21776
21809
  const titleX = compact ? node.w / 2 : 26;
21777
21810
  const paddingX = compact ? 16 : 52;
21778
21811
  const availableW = node.w - paddingX;
@@ -21795,7 +21828,7 @@ function CardNode({ node, active }) {
21795
21828
  strokeWidth: active ? 3 : 1.25
21796
21829
  }
21797
21830
  ),
21798
- !compact && node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 38, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
21831
+ !compact && node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 38 - \u4F59\u308A, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
21799
21832
  /* @__PURE__ */ jsxRuntime.jsx(
21800
21833
  "text",
21801
21834
  {
@@ -21809,7 +21842,7 @@ function CardNode({ node, active }) {
21809
21842
  children: node.title
21810
21843
  }
21811
21844
  ),
21812
- !compact && node.subtitle && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 124 - \u7E70\u308A\u4E0A\u3052, fontSize: subtitleSize, fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle }),
21845
+ !compact && node.subtitle && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 124 - \u305A\u3089\u3057, fontSize: subtitleSize, fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle }),
21813
21846
  \u5C0F\u578B\u306B\u547C\u3073\u540D && /* @__PURE__ */ jsxRuntime.jsx(
21814
21847
  "text",
21815
21848
  {
@@ -22074,7 +22107,14 @@ function EventNode({
22074
22107
  const x = node.cx - node.w / 2;
22075
22108
  const y = node.cy - node.h / 2;
22076
22109
  const \u7E70\u308A\u4E0A\u3052 = node.eyebrow ? 0 : \u76EE\u5370\u306A\u3057\u306E\u7E70\u308A\u4E0A\u3052("event");
22077
- const \u540D\u524D = titlePlacement(node, { x: 26, y: 88 - \u7E70\u308A\u4E0A\u3052, size: 26 }, { hasEyebrow: Boolean(node.eyebrow) });
22110
+ const \u4F59\u308A = \u4F59\u308A\u3092\u5206\u3051\u308B("event", NODE_SIZE.event.h, node.h, {
22111
+ hasEyebrow: Boolean(node.eyebrow),
22112
+ hasSubtitle: Boolean(node.subtitle),
22113
+ hasValue: false,
22114
+ hasRows: false
22115
+ });
22116
+ const \u305A\u3089\u3057 = \u7E70\u308A\u4E0A\u3052 - \u4F59\u308A;
22117
+ const \u540D\u524D = titlePlacement(node, { x: 26, y: 88 - \u305A\u3089\u3057, size: 26 }, { hasEyebrow: Boolean(node.eyebrow) });
22078
22118
  const scale = active ? 0.78 + 0.22 * progress : 0.92;
22079
22119
  const opacity = active ? 0.5 + 0.5 * progress : 0.65;
22080
22120
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -22097,7 +22137,7 @@ function EventNode({
22097
22137
  strokeWidth: active ? 3 : 1.25
22098
22138
  }
22099
22139
  ),
22100
- node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 38, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
22140
+ node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 38 - \u4F59\u308A, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
22101
22141
  /* @__PURE__ */ jsxRuntime.jsx(
22102
22142
  "text",
22103
22143
  {
@@ -22116,7 +22156,7 @@ function EventNode({
22116
22156
  "text",
22117
22157
  {
22118
22158
  x: 26,
22119
- y: 128 - \u7E70\u308A\u4E0A\u3052,
22159
+ y: 128 - \u305A\u3089\u3057,
22120
22160
  fontSize: 21,
22121
22161
  fill: "var(--cdl-text-dim, #5a6270)",
22122
22162
  style: { fontFamily: "'JetBrains Mono', monospace" },
@@ -22133,7 +22173,14 @@ function FunctionNode({ node, active }) {
22133
22173
  const x = node.cx - node.w / 2;
22134
22174
  const y = node.cy - node.h / 2;
22135
22175
  const \u7E70\u308A\u4E0A\u3052 = node.eyebrow ? 0 : \u76EE\u5370\u306A\u3057\u306E\u7E70\u308A\u4E0A\u3052("function");
22136
- const \u540D\u524D = titlePlacement(node, { x: 26, y: 86 - \u7E70\u308A\u4E0A\u3052, size: 24 }, { hasEyebrow: Boolean(node.eyebrow) });
22176
+ const \u4F59\u308A = \u4F59\u308A\u3092\u5206\u3051\u308B("function", NODE_SIZE.function.h, node.h, {
22177
+ hasEyebrow: Boolean(node.eyebrow),
22178
+ hasSubtitle: Boolean(node.subtitle),
22179
+ hasValue: false,
22180
+ hasRows: false
22181
+ });
22182
+ const \u305A\u3089\u3057 = \u7E70\u308A\u4E0A\u3052 - \u4F59\u308A;
22183
+ const \u540D\u524D = titlePlacement(node, { x: 26, y: 86 - \u305A\u3089\u3057, size: 24 }, { hasEyebrow: Boolean(node.eyebrow) });
22137
22184
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x} ${y})`, children: [
22138
22185
  /* @__PURE__ */ jsxRuntime.jsx(
22139
22186
  "rect",
@@ -22150,7 +22197,7 @@ function FunctionNode({ node, active }) {
22150
22197
  strokeOpacity: active ? 1 : 0.5
22151
22198
  }
22152
22199
  ),
22153
- node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 38, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
22200
+ node.eyebrow && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 38 - \u4F59\u308A, fontSize: 18, fontWeight: 700, letterSpacing: 2, fill: accent, children: node.eyebrow }),
22154
22201
  /* @__PURE__ */ jsxRuntime.jsx(
22155
22202
  "text",
22156
22203
  {
@@ -22165,7 +22212,7 @@ function FunctionNode({ node, active }) {
22165
22212
  children: node.title
22166
22213
  }
22167
22214
  ),
22168
- node.subtitle && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 126 - \u7E70\u308A\u4E0A\u3052, fontSize: 20, fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle })
22215
+ node.subtitle && /* @__PURE__ */ jsxRuntime.jsx("text", { x: 26, y: 126 - \u305A\u3089\u3057, fontSize: 20, fill: "var(--cdl-text-dim, #5a6270)", children: node.subtitle })
22169
22216
  ] });
22170
22217
  }
22171
22218
  var ROW_GLYPH_HALF = 7;
@@ -22504,21 +22551,12 @@ function GenericNode({
22504
22551
  if (shape === "cloud") {
22505
22552
  const cx = w / 2;
22506
22553
  const cy = h / 2;
22507
- const cloudCenterY = cy - h * 0.05;
22508
- const usableW = w * 0.85;
22509
- const halfW = usableW / 2;
22510
- const circles = [
22511
- { cx: cx - halfW * 0.8, cy: cloudCenterY + h * 0.08, r: h * 0.32 },
22512
- // 左端
22513
- { cx: cx - halfW * 0.4, cy: cloudCenterY - h * 0.05, r: h * 0.4 },
22514
- // 左
22515
- { cx, cy: cloudCenterY - h * 0.1, r: h * 0.46 },
22516
- // 中央 (最大)
22517
- { cx: cx + halfW * 0.4, cy: cloudCenterY - h * 0.05, r: h * 0.4 },
22518
- // 右
22519
- { cx: cx + halfW * 0.8, cy: cloudCenterY + h * 0.08, r: h * 0.32 }
22520
- // 右端
22521
- ];
22554
+ const halfW = w * 0.85 / 2;
22555
+ const circles = CLOUD_CIRCLES.map((c) => ({
22556
+ cx: cx + halfW * c.cx,
22557
+ cy: cy + h * c.cy,
22558
+ r: h * c.r
22559
+ }));
22522
22560
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
22523
22561
  circles.map((c, i) => /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: c.cx, cy: c.cy, r: c.r, fill: "var(--cdl-node-fill, #ffffff)" }, `fill-${i}`)),
22524
22562
  circles.map((c, i) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -22557,11 +22595,19 @@ function GenericNode({
22557
22595
  const textX = centered ? w / 2 : 20;
22558
22596
  const cylinderShift = genericTextShift(node.kind);
22559
22597
  const \u7E70\u308A\u4E0A\u3052 = node.eyebrow || centered ? 0 : \u76EE\u5370\u306A\u3057\u306E\u7E70\u308A\u4E0A\u3052(node.kind, hasRows);
22560
- const eyebrowY = centered ? h / 2 - 26 : 32 + cylinderShift;
22561
- const titleY = genericTitleBaselineY(node.kind, h, hasRows) - \u7E70\u308A\u4E0A\u3052;
22562
- const subtitleY = centered ? h / 2 + 28 : 96 + cylinderShift - \u7E70\u308A\u4E0A\u3052;
22598
+ const \u4F59\u308A = centered ? 0 : \u4F59\u308A\u3092\u5206\u3051\u308B(node.kind, NODE_SIZE[node.kind]?.h ?? h, h, {
22599
+ hasEyebrow: Boolean(node.eyebrow),
22600
+ hasSubtitle: Boolean(node.subtitle),
22601
+ hasValue: Boolean(resolvedValue),
22602
+ hasRows
22603
+ });
22604
+ const \u305A\u3089\u3057 = \u7E70\u308A\u4E0A\u3052 - \u4F59\u308A;
22605
+ const \u7D75\u306E\u82AF = centered && STYLES[node.kind]?.shape === "cloud" ? h * CLOUD_ART_CENTER_RISE : 0;
22606
+ const eyebrowY = centered ? h / 2 - 26 - \u7D75\u306E\u82AF : 32 + cylinderShift + \u4F59\u308A;
22607
+ const titleY = genericTitleBaselineY(node.kind, h, hasRows) - \u305A\u3089\u3057 - \u7D75\u306E\u82AF;
22608
+ const subtitleY = centered ? h / 2 + 28 - \u7D75\u306E\u82AF : 96 + cylinderShift - \u305A\u3089\u3057;
22563
22609
  const iconX = centered ? w / 2 + 40 : w - 48;
22564
- const iconY = centered ? h / 2 - 44 : 18 + cylinderShift;
22610
+ const iconY = centered ? h / 2 - 44 - \u7D75\u306E\u82AF : 18 + cylinderShift;
22565
22611
  const dominantBaseline = centered ? "middle" : void 0;
22566
22612
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x} ${y})`, "data-cdl-role": "node-body", children: [
22567
22613
  shapeEl,