@cardenelabs/cdl 0.45.0 → 0.47.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/dist/react.cjs CHANGED
@@ -2423,6 +2423,7 @@ var EDGE_HEADS = [
2423
2423
  ];
2424
2424
  var EDGE_HEAD_FILL_DEFAULT = "solid";
2425
2425
  var EDGE_HEAD_FILLS = ["solid", "hollow"];
2426
+ var RELATION_FOCUS_DEFAULT = "off";
2426
2427
  var EDGE_REVEAL_DEFAULT = "phase";
2427
2428
 
2428
2429
  // src/kinds/text-width.ts
@@ -6887,6 +6888,9 @@ var LANE_PAD_MIN = 25;
6887
6888
  // src/layout/edges.ts
6888
6889
  var VERTICAL_DETOUR_GAP = 50;
6889
6890
  var VERTICAL_DETOUR_CORNER = 14;
6891
+ function verticalCornerDir(from, to) {
6892
+ return to < from ? -1 : 1;
6893
+ }
6890
6894
  var VERTICAL_DETOUR_EXIT = 45;
6891
6895
  function nearestBoxDistance(anchorX, dir, verticalTop, verticalBottom, boxes) {
6892
6896
  let nearest = Infinity;
@@ -8068,12 +8072,14 @@ function routePath(from, to, fromSide, toSide, obstacles = [], detourSide, _from
8068
8072
  midY2 = retreatBelowMidBlockers(midY2);
8069
8073
  const corner = 14;
8070
8074
  const labelY = midY2 - labelInit;
8075
+ const \u7E26\u306E\u5411\u304DA = verticalCornerDir(A.y, midY2);
8076
+ const \u7E26\u306E\u5411\u304DB = verticalCornerDir(midY2, B.y);
8071
8077
  return {
8072
8078
  d: `M ${A.x} ${A.y}
8073
- L ${A.x} ${midY2 - corner}
8079
+ L ${A.x} ${midY2 - \u7E26\u306E\u5411\u304DA * corner}
8074
8080
  Q ${A.x} ${midY2}, ${A.x + xDir * corner} ${midY2}
8075
8081
  L ${B.x - xDir * corner} ${midY2}
8076
- Q ${B.x} ${midY2}, ${B.x} ${midY2 + corner}
8082
+ Q ${B.x} ${midY2}, ${B.x} ${midY2 + \u7E26\u306E\u5411\u304DB * corner}
8077
8083
  L ${B.x} ${B.y}`,
8078
8084
  labelX: (A.x + B.x) / 2,
8079
8085
  labelY,
@@ -9422,6 +9428,7 @@ function layout(diag) {
9422
9428
  ...diag.derived ? { derived: diag.derived } : {},
9423
9429
  // 矢印をいつ出すか (#582)。 描き手が読む欄なので、そのまま持ち越す
9424
9430
  ...diag.edgeReveal ? { edgeReveal: diag.edgeReveal } : {},
9431
+ ...diag.relationFocus ? { relationFocus: diag.relationFocus } : {},
9425
9432
  // どの配色で描くか (#1553)。 空文字は書かなかった扱いにする = 空の目印を出すと、
9426
9433
  // 消費側の `[data-cdl-palette]` が配色を書いていない図にも当たる。
9427
9434
  //
@@ -10295,7 +10302,8 @@ function CdlEdgeView({
10295
10302
  active,
10296
10303
  drawing,
10297
10304
  progress,
10298
- stateValues
10305
+ stateValues,
10306
+ flowing = false
10299
10307
  }) {
10300
10308
  const color = edgeColor(edge);
10301
10309
  const marker = edgeHeadMarkerName(edge.tone, edge.head, !active, edge.headFill);
@@ -10313,6 +10321,7 @@ function CdlEdgeView({
10313
10321
  "data-cdl-from": edge.from,
10314
10322
  "data-cdl-to": edge.to,
10315
10323
  "data-cdl-active": active ? "true" : "false",
10324
+ "data-cdl-flowing": flowing ? "true" : "false",
10316
10325
  "data-cdl-drawing": drawing ? "true" : "false",
10317
10326
  "data-cdl-path-d": edge.d,
10318
10327
  "data-cdl-label-x": edge.labelX,
@@ -10365,7 +10374,11 @@ function CdlEdgeView({
10365
10374
  strokeWidth: 14,
10366
10375
  strokeLinecap: "round"
10367
10376
  }
10368
- )
10377
+ ),
10378
+ flowing && !isDotted && /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-role": "edge-flow", children: [
10379
+ /* @__PURE__ */ jsxRuntime.jsx("path", { id: glowPathId, d: edge.d, fill: "none", stroke: "none" }),
10380
+ /* @__PURE__ */ jsxRuntime.jsx(EdgeGlowCircles, { color, edgeId: edge.id })
10381
+ ] })
10369
10382
  ]
10370
10383
  }
10371
10384
  );
@@ -18138,7 +18151,8 @@ function CdlNodeView({
18138
18151
  progress,
18139
18152
  stateValues,
18140
18153
  currentPhaseId,
18141
- chartLineScale
18154
+ chartLineScale,
18155
+ \u95A2\u4FC2\u306E\u53D7\u3051\u53E3
18142
18156
  }) {
18143
18157
  const value = node.value ? interpolate(node.value, stateValues) : void 0;
18144
18158
  const rows = (node.rows ?? []).map((r) => interpolate(r, stateValues));
@@ -18460,6 +18474,23 @@ function CdlNodeView({
18460
18474
  "data-cdl-eyebrow": resolvedNode.eyebrow ?? "",
18461
18475
  "data-cdl-offset-x": offsetX || void 0,
18462
18476
  "data-cdl-offset-y": offsetY || void 0,
18477
+ ...\u95A2\u4FC2\u306E\u53D7\u3051\u53E3 === void 0 ? {} : {
18478
+ // 読み上げに「押せる」 ことを伝え、 tab でも辿れるようにする。
18479
+ role: "button",
18480
+ tabIndex: 0,
18481
+ "aria-pressed": \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u7126\u70B9 === node.id,
18482
+ style: { cursor: "pointer" },
18483
+ onPointerEnter: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u89E6\u308C\u305F(node.id),
18484
+ onPointerLeave: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u96E2\u308C\u305F(),
18485
+ onFocus: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u89E6\u308C\u305F(node.id),
18486
+ onBlur: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u96E2\u308C\u305F(),
18487
+ onClick: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u62BC\u3057\u305F(node.id),
18488
+ onKeyDown: (e) => {
18489
+ if (e.key !== "Enter" && e.key !== " ") return;
18490
+ e.preventDefault();
18491
+ \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u62BC\u3057\u305F(node.id);
18492
+ }
18493
+ },
18463
18494
  transform: hasOffset ? `translate(${offsetX}, ${offsetY})` : void 0,
18464
18495
  opacity: boundOpacity,
18465
18496
  "data-cdl-tone": node.tone,
@@ -18483,6 +18514,18 @@ function CdlNodeView({
18483
18514
  }
18484
18515
  );
18485
18516
  }
18517
+
18518
+ // src/render/relation-focus.ts
18519
+ function relatedFocusSet(edges, nodeId) {
18520
+ const \u96C6\u5408 = /* @__PURE__ */ new Set([nodeId]);
18521
+ for (const e of edges) {
18522
+ if (e.from !== nodeId && e.to !== nodeId) continue;
18523
+ \u96C6\u5408.add(e.id);
18524
+ \u96C6\u5408.add(e.from);
18525
+ \u96C6\u5408.add(e.to);
18526
+ }
18527
+ return \u96C6\u5408;
18528
+ }
18486
18529
  function CdlStage({
18487
18530
  laid,
18488
18531
  currentPhase,
@@ -18493,7 +18536,35 @@ function CdlStage({
18493
18536
  compact = false,
18494
18537
  svgRef
18495
18538
  }) {
18496
- const activeSet = new Set(currentPhase?.activate ?? []);
18539
+ const [\u7126\u70B9, set\u7126\u70B9] = react.useState(null);
18540
+ const \u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B = (laid.relationFocus ?? RELATION_FOCUS_DEFAULT) === "hover";
18541
+ const \u52D5\u304D\u3092\u63A7\u3048\u308B = useReducedMotion();
18542
+ react.useEffect(() => {
18543
+ if (!\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B) set\u7126\u70B9(null);
18544
+ }, [\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B]);
18545
+ react.useEffect(() => {
18546
+ if (!\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B || \u7126\u70B9?.\u7559\u3081\u305F !== true) return;
18547
+ const \u62BC\u3057\u305F2 = (e) => {
18548
+ if (e.key === "Escape") set\u7126\u70B9(null);
18549
+ };
18550
+ window.addEventListener("keydown", \u62BC\u3057\u305F2);
18551
+ return () => window.removeEventListener("keydown", \u62BC\u3057\u305F2);
18552
+ }, [\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B, \u7126\u70B9?.\u7559\u3081\u305F]);
18553
+ const \u89E6\u308C\u305F = react.useCallback((id) => {
18554
+ set\u7126\u70B9((\u524D) => \u524D?.\u7559\u3081\u305F === true ? \u524D : { id, \u7559\u3081\u305F: false });
18555
+ }, []);
18556
+ const \u96E2\u308C\u305F = react.useCallback(() => {
18557
+ set\u7126\u70B9((\u524D) => \u524D?.\u7559\u3081\u305F === true ? \u524D : null);
18558
+ }, []);
18559
+ const \u62BC\u3057\u305F = react.useCallback((id) => {
18560
+ set\u7126\u70B9((\u524D) => \u524D?.id === id && \u524D.\u7559\u3081\u305F ? null : { id, \u7559\u3081\u305F: true });
18561
+ }, []);
18562
+ const \u7126\u70B9\u306E\u96C6\u5408 = react.useMemo(
18563
+ () => \u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B && \u7126\u70B9 !== null ? relatedFocusSet(laid.edges, \u7126\u70B9.id) : null,
18564
+ [\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B, \u7126\u70B9, laid.edges]
18565
+ );
18566
+ const activeSet = \u7126\u70B9\u306E\u96C6\u5408 ?? new Set(currentPhase?.activate ?? []);
18567
+ const \u7BB1\u306E\u53D7\u3051\u53E3 = \u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B ? { \u89E6\u308C\u305F, \u96E2\u308C\u305F, \u62BC\u3057\u305F, \u7126\u70B9: \u7126\u70B9?.id ?? null } : void 0;
18497
18568
  const \u77E2\u5370\u306E\u51FA\u756A = react.useMemo(() => {
18498
18569
  const \u521D\u51FA = /* @__PURE__ */ new Map();
18499
18570
  laid.phases.forEach((p, i) => {
@@ -18724,6 +18795,7 @@ function CdlStage({
18724
18795
  {
18725
18796
  edge,
18726
18797
  active: activeSet.has(edge.id),
18798
+ flowing: \u7126\u70B9\u306E\u96C6\u5408?.has(edge.id) === true && !\u52D5\u304D\u3092\u63A7\u3048\u308B,
18727
18799
  drawing: \u77E2\u5370\u306E\u51FA\u756A.\u4F38\u3070\u3059\u304B(edge.id),
18728
18800
  progress: \u77E2\u5370\u306E\u51FA\u756A.\u4F38\u3070\u3059\u304B(edge.id) ? \u63CF\u304F\u9032\u307F : progress,
18729
18801
  stateValues
@@ -18737,6 +18809,7 @@ function CdlStage({
18737
18809
  {
18738
18810
  node,
18739
18811
  active: activeSet.has(node.id),
18812
+ \u95A2\u4FC2\u306E\u53D7\u3051\u53E3: \u7BB1\u306E\u53D7\u3051\u53E3,
18740
18813
  drawing: \u63CF\u304F,
18741
18814
  progress: \u63CF\u304F ? \u63CF\u304F\u9032\u307F : progress,
18742
18815
  stateValues,