@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/CHANGELOG.md +33 -1
- package/dist/index.cjs +76 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -3
- package/dist/index.d.ts +29 -3
- package/dist/index.js +74 -5
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +72 -4
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +72 -4
- package/dist/react.js.map +1 -1
- package/dist/{render-UGswDfAh.d.cts → render-C53-PeJZ.d.cts} +25 -1
- package/dist/{render-UGswDfAh.d.ts → render-C53-PeJZ.d.ts} +25 -1
- package/package.json +1 -1
- package/src/index.ts +6 -0
- package/src/layout.ts +1 -0
- package/src/render/edges.tsx +19 -0
- package/src/render/nodes.tsx +40 -1
- package/src/render/relation-focus.ts +40 -0
- package/src/render/stage.tsx +55 -2
- package/src/types.ts +27 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,37 @@ CDL (Chainome Diagram Language) の主要変更履歴。
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.47.0] - 2026-09-11
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **箱に触れると関係する線だけが光るようにした** (#806)
|
|
13
|
+
|
|
14
|
+
クラス図と ER 図は **順番を持たない**。 段を進めて線を 1 本ずつ引く見せ方は作り手が決めた
|
|
15
|
+
読ませ方でしかなく、読み手の問い (この箱はどこと繋がっているか) には答えていなかった。
|
|
16
|
+
|
|
17
|
+
`CdlDiagram.relationFocus` に `"hover"` を書くと、箱に触れた時に その箱 ・ 繋がる線 ・
|
|
18
|
+
相手の箱だけが光り、他が沈む。 押すと留まり、もう一度押すか `Esc` で外れる
|
|
19
|
+
(線を目で追う間に指が外れると読めないため)。
|
|
20
|
+
|
|
21
|
+
| 書いた値 | 触れた時 |
|
|
22
|
+
|---|---|
|
|
23
|
+
| 書かない / `"off"` | 何もしない (既定) |
|
|
24
|
+
| `"hover"` | 関係する箱と線だけが光り、繋がる線に粒が流れる |
|
|
25
|
+
|
|
26
|
+
光る集合は「触れた箱」「繋がる線」「線の相手の箱」 の 3 つで、**線の向きは問わない** =
|
|
27
|
+
クラス図の「継ぐ」 は子から親へ、 ER の「持つ」 は親から子へ向くが、読み手にとっては
|
|
28
|
+
どちらも「この箱の関係」 だから。 集合は `activate` と同じ所に入れるので、光る / 沈むの
|
|
29
|
+
見え方は既にある仕組みをそのまま使う。
|
|
30
|
+
|
|
31
|
+
**触れていない間は段が勝つ** = この指定を足しても、段を持つ図の見え方は変わらない。
|
|
32
|
+
指定を書かない図では箱に属性も受け口も付かないので、`tab` の順番も DOM も動かない。
|
|
33
|
+
|
|
34
|
+
`prefers-reduced-motion` が立っている時は粒を流さない。 光る側は控えない =
|
|
35
|
+
動きではなく見分けなので、控える指定とは別の軸。
|
|
36
|
+
|
|
37
|
+
箱は `role="button"` と `tabIndex` を持ち、`Enter` と `Space` でも留められる。
|
|
38
|
+
|
|
8
39
|
## [0.46.0] - 2026-09-11
|
|
9
40
|
|
|
10
41
|
### Fixed
|
|
@@ -2320,7 +2351,8 @@ Initial OSS release.
|
|
|
2320
2351
|
使わない = annotated tag を push しても GitHub Release は作られず、 Release を作っていない版で
|
|
2321
2352
|
行き止まりになる。
|
|
2322
2353
|
|
|
2323
|
-
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.
|
|
2354
|
+
[Unreleased]: https://github.com/cardene777/cdl/compare/v0.47.0...HEAD
|
|
2355
|
+
[0.47.0]: https://github.com/cardene777/cdl/compare/v0.46.0...v0.47.0
|
|
2324
2356
|
[0.46.0]: https://github.com/cardene777/cdl/compare/v0.45.0...v0.46.0
|
|
2325
2357
|
[0.45.0]: https://github.com/cardene777/cdl/compare/v0.44.0...v0.45.0
|
|
2326
2358
|
[0.44.0]: https://github.com/cardene777/cdl/compare/v0.43.0...v0.44.0
|
package/dist/index.cjs
CHANGED
|
@@ -13751,6 +13751,8 @@ var EDGE_HEADS = [
|
|
|
13751
13751
|
var EDGE_HEAD_FILL_DEFAULT = "solid";
|
|
13752
13752
|
var EDGE_HEAD_FILLS = ["solid", "hollow"];
|
|
13753
13753
|
var EDGE_REVEALS = ["phase", "all"];
|
|
13754
|
+
var RELATION_FOCUSES = ["off", "hover"];
|
|
13755
|
+
var RELATION_FOCUS_DEFAULT = "off";
|
|
13754
13756
|
var EDGE_REVEAL_DEFAULT = "phase";
|
|
13755
13757
|
|
|
13756
13758
|
// src/kinds/text-width.ts
|
|
@@ -20722,6 +20724,7 @@ function layout(diag) {
|
|
|
20722
20724
|
...diag.derived ? { derived: diag.derived } : {},
|
|
20723
20725
|
// 矢印をいつ出すか (#582)。 描き手が読む欄なので、そのまま持ち越す
|
|
20724
20726
|
...diag.edgeReveal ? { edgeReveal: diag.edgeReveal } : {},
|
|
20727
|
+
...diag.relationFocus ? { relationFocus: diag.relationFocus } : {},
|
|
20725
20728
|
// どの配色で描くか (#1553)。 空文字は書かなかった扱いにする = 空の目印を出すと、
|
|
20726
20729
|
// 消費側の `[data-cdl-palette]` が配色を書いていない図にも当たる。
|
|
20727
20730
|
//
|
|
@@ -22809,7 +22812,8 @@ function CdlEdgeView({
|
|
|
22809
22812
|
active,
|
|
22810
22813
|
drawing,
|
|
22811
22814
|
progress,
|
|
22812
|
-
stateValues
|
|
22815
|
+
stateValues,
|
|
22816
|
+
flowing = false
|
|
22813
22817
|
}) {
|
|
22814
22818
|
const color = edgeColor(edge);
|
|
22815
22819
|
const marker = edgeHeadMarkerName(edge.tone, edge.head, !active, edge.headFill);
|
|
@@ -22827,6 +22831,7 @@ function CdlEdgeView({
|
|
|
22827
22831
|
"data-cdl-from": edge.from,
|
|
22828
22832
|
"data-cdl-to": edge.to,
|
|
22829
22833
|
"data-cdl-active": active ? "true" : "false",
|
|
22834
|
+
"data-cdl-flowing": flowing ? "true" : "false",
|
|
22830
22835
|
"data-cdl-drawing": drawing ? "true" : "false",
|
|
22831
22836
|
"data-cdl-path-d": edge.d,
|
|
22832
22837
|
"data-cdl-label-x": edge.labelX,
|
|
@@ -22879,7 +22884,11 @@ function CdlEdgeView({
|
|
|
22879
22884
|
strokeWidth: 14,
|
|
22880
22885
|
strokeLinecap: "round"
|
|
22881
22886
|
}
|
|
22882
|
-
)
|
|
22887
|
+
),
|
|
22888
|
+
flowing && !isDotted && /* @__PURE__ */ jsxRuntime.jsxs("g", { "data-cdl-role": "edge-flow", children: [
|
|
22889
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { id: glowPathId, d: edge.d, fill: "none", stroke: "none" }),
|
|
22890
|
+
/* @__PURE__ */ jsxRuntime.jsx(EdgeGlowCircles, { color, edgeId: edge.id })
|
|
22891
|
+
] })
|
|
22883
22892
|
]
|
|
22884
22893
|
}
|
|
22885
22894
|
);
|
|
@@ -30655,7 +30664,8 @@ function CdlNodeView({
|
|
|
30655
30664
|
progress,
|
|
30656
30665
|
stateValues,
|
|
30657
30666
|
currentPhaseId,
|
|
30658
|
-
chartLineScale
|
|
30667
|
+
chartLineScale,
|
|
30668
|
+
\u95A2\u4FC2\u306E\u53D7\u3051\u53E3
|
|
30659
30669
|
}) {
|
|
30660
30670
|
const value = node.value ? interpolate(node.value, stateValues) : void 0;
|
|
30661
30671
|
const rows = (node.rows ?? []).map((r) => interpolate(r, stateValues));
|
|
@@ -30977,6 +30987,23 @@ function CdlNodeView({
|
|
|
30977
30987
|
"data-cdl-eyebrow": resolvedNode.eyebrow ?? "",
|
|
30978
30988
|
"data-cdl-offset-x": offsetX || void 0,
|
|
30979
30989
|
"data-cdl-offset-y": offsetY || void 0,
|
|
30990
|
+
...\u95A2\u4FC2\u306E\u53D7\u3051\u53E3 === void 0 ? {} : {
|
|
30991
|
+
// 読み上げに「押せる」 ことを伝え、 tab でも辿れるようにする。
|
|
30992
|
+
role: "button",
|
|
30993
|
+
tabIndex: 0,
|
|
30994
|
+
"aria-pressed": \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u7126\u70B9 === node.id,
|
|
30995
|
+
style: { cursor: "pointer" },
|
|
30996
|
+
onPointerEnter: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u89E6\u308C\u305F(node.id),
|
|
30997
|
+
onPointerLeave: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u96E2\u308C\u305F(),
|
|
30998
|
+
onFocus: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u89E6\u308C\u305F(node.id),
|
|
30999
|
+
onBlur: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u96E2\u308C\u305F(),
|
|
31000
|
+
onClick: () => \u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u62BC\u3057\u305F(node.id),
|
|
31001
|
+
onKeyDown: (e) => {
|
|
31002
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
31003
|
+
e.preventDefault();
|
|
31004
|
+
\u95A2\u4FC2\u306E\u53D7\u3051\u53E3.\u62BC\u3057\u305F(node.id);
|
|
31005
|
+
}
|
|
31006
|
+
},
|
|
30980
31007
|
transform: hasOffset ? `translate(${offsetX}, ${offsetY})` : void 0,
|
|
30981
31008
|
opacity: boundOpacity,
|
|
30982
31009
|
"data-cdl-tone": node.tone,
|
|
@@ -31000,6 +31027,18 @@ function CdlNodeView({
|
|
|
31000
31027
|
}
|
|
31001
31028
|
);
|
|
31002
31029
|
}
|
|
31030
|
+
|
|
31031
|
+
// src/render/relation-focus.ts
|
|
31032
|
+
function relatedFocusSet(edges, nodeId) {
|
|
31033
|
+
const \u96C6\u5408 = /* @__PURE__ */ new Set([nodeId]);
|
|
31034
|
+
for (const e of edges) {
|
|
31035
|
+
if (e.from !== nodeId && e.to !== nodeId) continue;
|
|
31036
|
+
\u96C6\u5408.add(e.id);
|
|
31037
|
+
\u96C6\u5408.add(e.from);
|
|
31038
|
+
\u96C6\u5408.add(e.to);
|
|
31039
|
+
}
|
|
31040
|
+
return \u96C6\u5408;
|
|
31041
|
+
}
|
|
31003
31042
|
function CdlStage({
|
|
31004
31043
|
laid,
|
|
31005
31044
|
currentPhase,
|
|
@@ -31010,7 +31049,35 @@ function CdlStage({
|
|
|
31010
31049
|
compact = false,
|
|
31011
31050
|
svgRef
|
|
31012
31051
|
}) {
|
|
31013
|
-
const
|
|
31052
|
+
const [\u7126\u70B9, set\u7126\u70B9] = react.useState(null);
|
|
31053
|
+
const \u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B = (laid.relationFocus ?? RELATION_FOCUS_DEFAULT) === "hover";
|
|
31054
|
+
const \u52D5\u304D\u3092\u63A7\u3048\u308B = useReducedMotion();
|
|
31055
|
+
react.useEffect(() => {
|
|
31056
|
+
if (!\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B) set\u7126\u70B9(null);
|
|
31057
|
+
}, [\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B]);
|
|
31058
|
+
react.useEffect(() => {
|
|
31059
|
+
if (!\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B || \u7126\u70B9?.\u7559\u3081\u305F !== true) return;
|
|
31060
|
+
const \u62BC\u3057\u305F2 = (e) => {
|
|
31061
|
+
if (e.key === "Escape") set\u7126\u70B9(null);
|
|
31062
|
+
};
|
|
31063
|
+
window.addEventListener("keydown", \u62BC\u3057\u305F2);
|
|
31064
|
+
return () => window.removeEventListener("keydown", \u62BC\u3057\u305F2);
|
|
31065
|
+
}, [\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B, \u7126\u70B9?.\u7559\u3081\u305F]);
|
|
31066
|
+
const \u89E6\u308C\u305F = react.useCallback((id) => {
|
|
31067
|
+
set\u7126\u70B9((\u524D) => \u524D?.\u7559\u3081\u305F === true ? \u524D : { id, \u7559\u3081\u305F: false });
|
|
31068
|
+
}, []);
|
|
31069
|
+
const \u96E2\u308C\u305F = react.useCallback(() => {
|
|
31070
|
+
set\u7126\u70B9((\u524D) => \u524D?.\u7559\u3081\u305F === true ? \u524D : null);
|
|
31071
|
+
}, []);
|
|
31072
|
+
const \u62BC\u3057\u305F = react.useCallback((id) => {
|
|
31073
|
+
set\u7126\u70B9((\u524D) => \u524D?.id === id && \u524D.\u7559\u3081\u305F ? null : { id, \u7559\u3081\u305F: true });
|
|
31074
|
+
}, []);
|
|
31075
|
+
const \u7126\u70B9\u306E\u96C6\u5408 = react.useMemo(
|
|
31076
|
+
() => \u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B && \u7126\u70B9 !== null ? relatedFocusSet(laid.edges, \u7126\u70B9.id) : null,
|
|
31077
|
+
[\u95A2\u4FC2\u3092\u5149\u3089\u305B\u308B, \u7126\u70B9, laid.edges]
|
|
31078
|
+
);
|
|
31079
|
+
const activeSet = \u7126\u70B9\u306E\u96C6\u5408 ?? new Set(currentPhase?.activate ?? []);
|
|
31080
|
+
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;
|
|
31014
31081
|
const \u77E2\u5370\u306E\u51FA\u756A = react.useMemo(() => {
|
|
31015
31082
|
const \u521D\u51FA = /* @__PURE__ */ new Map();
|
|
31016
31083
|
laid.phases.forEach((p, i) => {
|
|
@@ -31241,6 +31308,7 @@ function CdlStage({
|
|
|
31241
31308
|
{
|
|
31242
31309
|
edge,
|
|
31243
31310
|
active: activeSet.has(edge.id),
|
|
31311
|
+
flowing: \u7126\u70B9\u306E\u96C6\u5408?.has(edge.id) === true && !\u52D5\u304D\u3092\u63A7\u3048\u308B,
|
|
31244
31312
|
drawing: \u77E2\u5370\u306E\u51FA\u756A.\u4F38\u3070\u3059\u304B(edge.id),
|
|
31245
31313
|
progress: \u77E2\u5370\u306E\u51FA\u756A.\u4F38\u3070\u3059\u304B(edge.id) ? \u63CF\u304F\u9032\u307F : progress,
|
|
31246
31314
|
stateValues
|
|
@@ -31254,6 +31322,7 @@ function CdlStage({
|
|
|
31254
31322
|
{
|
|
31255
31323
|
node,
|
|
31256
31324
|
active: activeSet.has(node.id),
|
|
31325
|
+
\u95A2\u4FC2\u306E\u53D7\u3051\u53E3: \u7BB1\u306E\u53D7\u3051\u53E3,
|
|
31257
31326
|
drawing: \u63CF\u304F,
|
|
31258
31327
|
progress: \u63CF\u304F ? \u63CF\u304F\u9032\u307F : progress,
|
|
31259
31328
|
stateValues,
|
|
@@ -32881,6 +32950,8 @@ exports.NEAR_COLLISION_DEFAULT_MIN = NEAR_COLLISION_DEFAULT_MIN;
|
|
|
32881
32950
|
exports.NEAR_COLLISION_POLICY = NEAR_COLLISION_POLICY;
|
|
32882
32951
|
exports.NODE_FRAME_SELECTOR = NODE_FRAME_SELECTOR;
|
|
32883
32952
|
exports.NODE_KINDS = NODE_KINDS;
|
|
32953
|
+
exports.RELATION_FOCUSES = RELATION_FOCUSES;
|
|
32954
|
+
exports.RELATION_FOCUS_DEFAULT = RELATION_FOCUS_DEFAULT;
|
|
32884
32955
|
exports.ROW_GAP_VARIANCE_TOL = ROW_GAP_VARIANCE_TOL;
|
|
32885
32956
|
exports.SEQUENCE_MESSAGE_LOOK = SEQUENCE_MESSAGE_LOOK;
|
|
32886
32957
|
exports.SPEC_CLEARANCE_POLICY = SPEC_CLEARANCE_POLICY;
|
|
@@ -32946,6 +33017,7 @@ exports.pxToWorld = pxToWorld;
|
|
|
32946
33017
|
exports.quadrant = quadrant;
|
|
32947
33018
|
exports.rectRectClearance = rectRectClearance;
|
|
32948
33019
|
exports.rectRectOverlapArea = rectRectOverlapArea;
|
|
33020
|
+
exports.relatedFocusSet = relatedFocusSet;
|
|
32949
33021
|
exports.rendersRows = rendersRows;
|
|
32950
33022
|
exports.requiredContrastRatio = requiredContrastRatio;
|
|
32951
33023
|
exports.requiredNearClearance = requiredNearClearance;
|