@cardenelabs/cdl 0.46.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
@@ -9427,6 +9428,7 @@ function layout(diag) {
9427
9428
  ...diag.derived ? { derived: diag.derived } : {},
9428
9429
  // 矢印をいつ出すか (#582)。 描き手が読む欄なので、そのまま持ち越す
9429
9430
  ...diag.edgeReveal ? { edgeReveal: diag.edgeReveal } : {},
9431
+ ...diag.relationFocus ? { relationFocus: diag.relationFocus } : {},
9430
9432
  // どの配色で描くか (#1553)。 空文字は書かなかった扱いにする = 空の目印を出すと、
9431
9433
  // 消費側の `[data-cdl-palette]` が配色を書いていない図にも当たる。
9432
9434
  //
@@ -10300,7 +10302,8 @@ function CdlEdgeView({
10300
10302
  active,
10301
10303
  drawing,
10302
10304
  progress,
10303
- stateValues
10305
+ stateValues,
10306
+ flowing = false
10304
10307
  }) {
10305
10308
  const color = edgeColor(edge);
10306
10309
  const marker = edgeHeadMarkerName(edge.tone, edge.head, !active, edge.headFill);
@@ -10318,6 +10321,7 @@ function CdlEdgeView({
10318
10321
  "data-cdl-from": edge.from,
10319
10322
  "data-cdl-to": edge.to,
10320
10323
  "data-cdl-active": active ? "true" : "false",
10324
+ "data-cdl-flowing": flowing ? "true" : "false",
10321
10325
  "data-cdl-drawing": drawing ? "true" : "false",
10322
10326
  "data-cdl-path-d": edge.d,
10323
10327
  "data-cdl-label-x": edge.labelX,
@@ -10370,7 +10374,11 @@ function CdlEdgeView({
10370
10374
  strokeWidth: 14,
10371
10375
  strokeLinecap: "round"
10372
10376
  }
10373
- )
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
+ ] })
10374
10382
  ]
10375
10383
  }
10376
10384
  );
@@ -18143,7 +18151,8 @@ function CdlNodeView({
18143
18151
  progress,
18144
18152
  stateValues,
18145
18153
  currentPhaseId,
18146
- chartLineScale
18154
+ chartLineScale,
18155
+ \u95A2\u4FC2\u306E\u53D7\u3051\u53E3
18147
18156
  }) {
18148
18157
  const value = node.value ? interpolate(node.value, stateValues) : void 0;
18149
18158
  const rows = (node.rows ?? []).map((r) => interpolate(r, stateValues));
@@ -18465,6 +18474,23 @@ function CdlNodeView({
18465
18474
  "data-cdl-eyebrow": resolvedNode.eyebrow ?? "",
18466
18475
  "data-cdl-offset-x": offsetX || void 0,
18467
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
+ },
18468
18494
  transform: hasOffset ? `translate(${offsetX}, ${offsetY})` : void 0,
18469
18495
  opacity: boundOpacity,
18470
18496
  "data-cdl-tone": node.tone,
@@ -18488,6 +18514,18 @@ function CdlNodeView({
18488
18514
  }
18489
18515
  );
18490
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
+ }
18491
18529
  function CdlStage({
18492
18530
  laid,
18493
18531
  currentPhase,
@@ -18498,7 +18536,35 @@ function CdlStage({
18498
18536
  compact = false,
18499
18537
  svgRef
18500
18538
  }) {
18501
- 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;
18502
18568
  const \u77E2\u5370\u306E\u51FA\u756A = react.useMemo(() => {
18503
18569
  const \u521D\u51FA = /* @__PURE__ */ new Map();
18504
18570
  laid.phases.forEach((p, i) => {
@@ -18729,6 +18795,7 @@ function CdlStage({
18729
18795
  {
18730
18796
  edge,
18731
18797
  active: activeSet.has(edge.id),
18798
+ flowing: \u7126\u70B9\u306E\u96C6\u5408?.has(edge.id) === true && !\u52D5\u304D\u3092\u63A7\u3048\u308B,
18732
18799
  drawing: \u77E2\u5370\u306E\u51FA\u756A.\u4F38\u3070\u3059\u304B(edge.id),
18733
18800
  progress: \u77E2\u5370\u306E\u51FA\u756A.\u4F38\u3070\u3059\u304B(edge.id) ? \u63CF\u304F\u9032\u307F : progress,
18734
18801
  stateValues
@@ -18742,6 +18809,7 @@ function CdlStage({
18742
18809
  {
18743
18810
  node,
18744
18811
  active: activeSet.has(node.id),
18812
+ \u95A2\u4FC2\u306E\u53D7\u3051\u53E3: \u7BB1\u306E\u53D7\u3051\u53E3,
18745
18813
  drawing: \u63CF\u304F,
18746
18814
  progress: \u63CF\u304F ? \u63CF\u304F\u9032\u307F : progress,
18747
18815
  stateValues,