@conductor-by-89soone/react 0.3.1 → 0.4.1
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/README.md +231 -0
- package/dist/action.js +62 -3
- package/dist/cx.js +10 -1
- package/dist/data.js +65 -2
- package/dist/feedback.js +65 -2
- package/dist/form.js +115 -2
- package/dist/index.d.ts +7 -1
- package/dist/index.js +70 -15
- package/dist/interaction.d.ts +37 -0
- package/dist/interaction.js +47 -0
- package/dist/overlay.js +227 -2
- package/dist/relation.d.ts +56 -0
- package/dist/relation.js +215 -0
- package/dist/shell.d.ts +7 -1
- package/dist/shell.js +158 -2
- package/dist/status.js +35 -2
- package/dist/stylesheet-warning.d.ts +8 -0
- package/dist/{chunk-WEIMKRZV.js → stylesheet-warning.js} +5 -13
- package/dist/surface.js +45 -2
- package/dist/types.js +0 -1
- package/dist/workbench.d.ts +125 -0
- package/dist/workbench.js +200 -0
- package/package.json +13 -5
- package/dist/chunk-3YDK2JBK.js +0 -103
- package/dist/chunk-535YGQAR.js +0 -32
- package/dist/chunk-G7TRTZRR.js +0 -60
- package/dist/chunk-MR7FIZKV.js +0 -221
- package/dist/chunk-NF3ZHADJ.js +0 -60
- package/dist/chunk-R5BLKHR2.js +0 -81
- package/dist/chunk-RBD5Z2LR.js +0 -58
- package/dist/chunk-TUHWL5JC.js +0 -42
package/dist/relation.js
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { forwardRef, useId, useMemo, useState } from "react";
|
|
5
|
+
import { Button } from "./action.js";
|
|
6
|
+
import { Table } from "./data.js";
|
|
7
|
+
import { cx } from "./cx.js";
|
|
8
|
+
function layoutRelationNodes(nodes) {
|
|
9
|
+
const ordered = [...nodes].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
|
|
10
|
+
const columns = Math.max(1, Math.ceil(Math.sqrt(ordered.length)));
|
|
11
|
+
return ordered.map((node, index) => ({ ...node, x: 130 + index % columns * 280, y: 90 + Math.floor(index / columns) * 150 }));
|
|
12
|
+
}
|
|
13
|
+
function edgeState(edge) {
|
|
14
|
+
return [edge.retracted && "\uD574\uC81C\uB428", edge.unresolved && "\uBBF8\uD574\uACB0", edge.ambiguous && "\uBAA8\uD638\uD568"].filter(Boolean).join(" \xB7 ") || "\uD655\uC778\uB428";
|
|
15
|
+
}
|
|
16
|
+
const RelationGraph = forwardRef(function RelationGraph2({
|
|
17
|
+
nodes,
|
|
18
|
+
edges,
|
|
19
|
+
label,
|
|
20
|
+
selection: controlledSelection,
|
|
21
|
+
onSelectionChange,
|
|
22
|
+
viewport: controlledViewport,
|
|
23
|
+
onViewportChange,
|
|
24
|
+
state = "ready",
|
|
25
|
+
stateMessage,
|
|
26
|
+
onRetry,
|
|
27
|
+
className,
|
|
28
|
+
...props
|
|
29
|
+
}, ref) {
|
|
30
|
+
const uid = useId().replace(/:/g, "");
|
|
31
|
+
const [localSelection, setSelection] = useState(null);
|
|
32
|
+
const [localViewport, setViewport] = useState({ x: 0, y: 0, zoom: 1 });
|
|
33
|
+
const [query, setQuery] = useState("");
|
|
34
|
+
const [type, setType] = useState("");
|
|
35
|
+
const selection = controlledSelection === void 0 ? localSelection : controlledSelection;
|
|
36
|
+
const viewport = controlledViewport ?? localViewport;
|
|
37
|
+
const positioned = useMemo(() => layoutRelationNodes(nodes), [nodes]);
|
|
38
|
+
const byId = useMemo(() => new Map(positioned.map((node) => [node.id, node])), [positioned]);
|
|
39
|
+
const types = useMemo(() => [...new Set(edges.map((edge) => edge.type))].sort(), [edges]);
|
|
40
|
+
const visibleEdges = useMemo(() => [...edges].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0).filter((edge) => !type || edge.type === type), [edges, type]);
|
|
41
|
+
const found = positioned.filter((node) => `${node.label} ${node.id}`.toLocaleLowerCase().includes(query.toLocaleLowerCase()));
|
|
42
|
+
const neighbors = useMemo(() => {
|
|
43
|
+
const result = /* @__PURE__ */ new Set();
|
|
44
|
+
if (selection?.kind === "node") {
|
|
45
|
+
result.add(selection.id);
|
|
46
|
+
for (const edge of visibleEdges) if (edge.source === selection.id || edge.target === selection.id) {
|
|
47
|
+
result.add(edge.source);
|
|
48
|
+
result.add(edge.target);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}, [selection, visibleEdges]);
|
|
53
|
+
const width = Math.max(560, ...positioned.map((node) => node.x + 150));
|
|
54
|
+
const height = Math.max(300, ...positioned.map((node) => node.y + 90));
|
|
55
|
+
const zoom = Math.min(8, Math.max(0.5, Number.isFinite(viewport.zoom) ? viewport.zoom : 1));
|
|
56
|
+
const changeSelection = (next) => {
|
|
57
|
+
if (controlledSelection === void 0) setSelection(next);
|
|
58
|
+
onSelectionChange?.(next);
|
|
59
|
+
};
|
|
60
|
+
const changeViewport = (next) => {
|
|
61
|
+
if (!controlledViewport) setViewport(next);
|
|
62
|
+
onViewportChange?.(next);
|
|
63
|
+
};
|
|
64
|
+
const pan = (x, y) => changeViewport({ x: viewport.x + x * width / zoom / 4, y: viewport.y + y * height / zoom / 4, zoom });
|
|
65
|
+
const selectedNode = selection?.kind === "node" ? byId.get(selection.id) : void 0;
|
|
66
|
+
const selectedEdge = selection?.kind === "edge" ? edges.find((edge) => edge.id === selection.id) : void 0;
|
|
67
|
+
const endpointLabel = (id) => byId.get(id)?.label ?? "\uB300\uC0C1 \uC815\uBCF4 \uC5C6\uC74C";
|
|
68
|
+
const selectedHidden = selectedEdge && !visibleEdges.some((edge) => edge.id === selectedEdge.id);
|
|
69
|
+
const blocked = state === "loading" || state === "error" || state === "empty";
|
|
70
|
+
return /* @__PURE__ */ jsxs("div", { ...props, ref, className: cx("cdt-relation", className), "aria-label": props["aria-label"] ?? label, "aria-busy": props["aria-busy"] ?? (state === "loading" || void 0), children: [
|
|
71
|
+
/* @__PURE__ */ jsxs("div", { className: "cdt-relation__toolbar", children: [
|
|
72
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: `${uid}-find`, children: [
|
|
73
|
+
"\uB178\uB4DC \uCC3E\uAE30",
|
|
74
|
+
/* @__PURE__ */ jsx("input", { id: `${uid}-find`, className: "cdt-input", value: query, onChange: (event) => setQuery(event.target.value), placeholder: "\uC774\uB984 \uB610\uB294 \uC548\uC815 ID" })
|
|
75
|
+
] }),
|
|
76
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: `${uid}-type`, children: [
|
|
77
|
+
"\uAD00\uACC4 \uC720\uD615",
|
|
78
|
+
/* @__PURE__ */ jsxs("select", { id: `${uid}-type`, className: "cdt-input", value: type, onChange: (event) => setType(event.target.value), children: [
|
|
79
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "\uBAA8\uB4E0 \uC720\uD615" }),
|
|
80
|
+
types.map((value) => /* @__PURE__ */ jsx("option", { value, children: value }, value))
|
|
81
|
+
] })
|
|
82
|
+
] }),
|
|
83
|
+
/* @__PURE__ */ jsx("a", { href: `#${uid}-list`, onClick: (event) => {
|
|
84
|
+
event.preventDefault();
|
|
85
|
+
const list = event.currentTarget.ownerDocument.getElementById(`${uid}-list`);
|
|
86
|
+
list?.focus({ preventScroll: true });
|
|
87
|
+
list?.scrollIntoView({ block: "start" });
|
|
88
|
+
}, children: "\uB3D9\uC77C \uC815\uBCF4 \uBAA9\uB85D\uC73C\uB85C \uC774\uB3D9" })
|
|
89
|
+
] }),
|
|
90
|
+
/* @__PURE__ */ jsx("p", { className: "cdt-relation__legend", children: "\uD654\uC0B4\uD45C: \uCD9C\uBC1C \u2192 \uAD00\uACC4 \u2192 \uB3C4\uCC29. \uC2E4\uC120: \uD655\uC778\uB428 \xB7 \uC810\uC120: \uBBF8\uD574\uACB0/\uBAA8\uD638\uD568 \xB7 \uD30C\uC120: \uD574\uC81C\uB428. \uC704\uCE58\uB294 ID \uC21C\uC11C\uC774\uBA70 \uC2DC\uAC04\xB7\uBCD1\uD569\xB7\uC758\uC874 \uC21C\uC11C\uB97C \uB73B\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4." }),
|
|
91
|
+
/* @__PURE__ */ jsx("p", { role: state === "error" ? "alert" : "status", children: stateMessage ?? { ready: `${nodes.length}\uAC1C \uB178\uB4DC \xB7 ${visibleEdges.length}\uAC1C \uAD00\uACC4`, loading: "\uAD00\uACC4 \uBD88\uB7EC\uC624\uB294 \uC911", empty: "\uD655\uC778\uB41C \uAD00\uACC4 \uC5C6\uC74C", error: "\uAD00\uACC4\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4", partial: "\uBD80\uBD84 \uACB0\uACFC: \uD45C\uC2DC\uB418\uC9C0 \uC54A\uC740 \uAD00\uACC4\uAC00 \uC788\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4" }[state] }),
|
|
92
|
+
state === "error" && onRetry && /* @__PURE__ */ jsx(Button, { type: "button", onClick: onRetry, children: "\uAD00\uACC4 \uB2E4\uC2DC \uC2DC\uB3C4" }),
|
|
93
|
+
!blocked && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
94
|
+
/* @__PURE__ */ jsxs("div", { className: "cdt-relation__toolbar", "aria-label": "\uADF8\uB798\uD504 \uBCF4\uAE30 \uC870\uC808", children: [
|
|
95
|
+
/* @__PURE__ */ jsx(Button, { type: "button", disabled: zoom >= 8, onClick: () => changeViewport({ ...viewport, zoom: Math.min(8, zoom * 1.5) }), children: "\uD655\uB300" }),
|
|
96
|
+
/* @__PURE__ */ jsx(Button, { type: "button", disabled: zoom <= 0.5, onClick: () => changeViewport({ ...viewport, zoom: Math.max(0.5, zoom / 1.5) }), children: "\uCD95\uC18C" }),
|
|
97
|
+
/* @__PURE__ */ jsx(Button, { type: "button", onClick: () => changeViewport({ x: 0, y: 0, zoom: 1 }), children: "\uC804\uCCB4 \uBCF4\uAE30" }),
|
|
98
|
+
/* @__PURE__ */ jsx(Button, { type: "button", "aria-label": "\uADF8\uB798\uD504 \uC67C\uCABD\uC73C\uB85C \uC774\uB3D9", onClick: () => pan(-1, 0), children: "\u2190" }),
|
|
99
|
+
/* @__PURE__ */ jsx(Button, { type: "button", "aria-label": "\uADF8\uB798\uD504 \uC624\uB978\uCABD\uC73C\uB85C \uC774\uB3D9", onClick: () => pan(1, 0), children: "\u2192" }),
|
|
100
|
+
/* @__PURE__ */ jsx(Button, { type: "button", "aria-label": "\uADF8\uB798\uD504 \uC704\uB85C \uC774\uB3D9", onClick: () => pan(0, -1), children: "\u2191" }),
|
|
101
|
+
/* @__PURE__ */ jsx(Button, { type: "button", "aria-label": "\uADF8\uB798\uD504 \uC544\uB798\uB85C \uC774\uB3D9", onClick: () => pan(0, 1), children: "\u2193" }),
|
|
102
|
+
/* @__PURE__ */ jsxs("output", { "aria-label": "\uD655\uB300 \uBC30\uC728", children: [
|
|
103
|
+
Math.round(zoom * 100),
|
|
104
|
+
"%"
|
|
105
|
+
] })
|
|
106
|
+
] }),
|
|
107
|
+
/* @__PURE__ */ jsxs("svg", { className: "cdt-relation__canvas", "aria-hidden": "true", focusable: "false", viewBox: `${viewport.x} ${viewport.y} ${width / zoom} ${height / zoom}`, children: [
|
|
108
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("marker", { id: `${uid}-arrow`, viewBox: "0 0 10 10", refX: "9", refY: "5", markerWidth: "7", markerHeight: "7", orient: "auto-start-reverse", children: /* @__PURE__ */ jsx("path", { d: "M 0 0 L 10 5 L 0 10 z", className: "cdt-relation__arrow" }) }) }),
|
|
109
|
+
visibleEdges.map((edge, index) => {
|
|
110
|
+
const source = byId.get(edge.source);
|
|
111
|
+
const target = byId.get(edge.target);
|
|
112
|
+
if (!source || !target) return null;
|
|
113
|
+
const dx = target.x - source.x;
|
|
114
|
+
const dy = target.y - source.y;
|
|
115
|
+
const distance = Math.hypot(dx, dy) || 1;
|
|
116
|
+
const offset = dy === 0 ? -Math.sign(dx) * (100 + index % 3 * 20) : 28 + index % 3 * 12;
|
|
117
|
+
const inset = Math.min(Math.abs(dx) > 0 ? 118 / Math.abs(dx) : Infinity, Math.abs(dy) > 0 ? 34 / Math.abs(dy) : Infinity);
|
|
118
|
+
const path = source.id === target.id ? `M ${source.x} ${source.y - 26} C ${source.x - 90} ${source.y - 105}, ${source.x + 90} ${source.y - 105}, ${source.x + 30} ${source.y - 26}` : `M ${source.x} ${source.y} Q ${(source.x + target.x) / 2 - dy / distance * offset} ${(source.y + target.y) / 2 + dx / distance * offset} ${target.x - dx * inset} ${target.y - dy * inset}`;
|
|
119
|
+
return /* @__PURE__ */ jsxs("g", { "data-edge-id": edge.id, "data-selected": selectedEdge?.id === edge.id || void 0, "data-dimmed": neighbors.size > 0 && !(neighbors.has(edge.source) && neighbors.has(edge.target)) || void 0, className: "cdt-relation__edge", onClick: () => changeSelection({ kind: "edge", id: edge.id }), children: [
|
|
120
|
+
/* @__PURE__ */ jsx("path", { d: path, className: "cdt-relation__edge-hit" }),
|
|
121
|
+
/* @__PURE__ */ jsx("path", { d: path, markerEnd: `url(#${uid}-arrow)`, "data-state": edge.retracted ? "retracted" : edge.unresolved || edge.ambiguous ? "uncertain" : "confirmed" }),
|
|
122
|
+
(nodes.length <= 50 || selectedEdge?.id === edge.id) && /* @__PURE__ */ jsx("text", { x: (source.x + target.x) / 2 - dy / distance * offset / 2, y: (source.y + target.y) / 2 + dx / distance * offset / 2 - 8, textAnchor: "middle", className: "cdt-relation__edge-label", children: edge.label }),
|
|
123
|
+
/* @__PURE__ */ jsx("title", { children: `${endpointLabel(edge.source)} \u2192 ${edge.label} \u2192 ${endpointLabel(edge.target)} \xB7 ${edgeState(edge)}` })
|
|
124
|
+
] }, edge.id);
|
|
125
|
+
}),
|
|
126
|
+
positioned.map((node) => /* @__PURE__ */ jsxs("g", { "data-node-id": node.id, className: "cdt-relation__node", "data-selected": selectedNode?.id === node.id || void 0, "data-dimmed": neighbors.size > 0 && !neighbors.has(node.id) || void 0, onClick: () => changeSelection({ kind: "node", id: node.id }), children: [
|
|
127
|
+
/* @__PURE__ */ jsx("rect", { x: node.x - 110, y: node.y - 26, width: 220, height: 52, rx: 8 }),
|
|
128
|
+
/* @__PURE__ */ jsx("text", { x: node.x, y: node.y + 5, textAnchor: "middle", children: node.label.length > 24 ? `${node.label.slice(0, 23)}\u2026` : node.label }),
|
|
129
|
+
/* @__PURE__ */ jsx("title", { children: node.label })
|
|
130
|
+
] }, node.id))
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ jsxs("section", { "aria-label": "\uC120\uD0DD\uD55C \uAD00\uACC4 \uC0C1\uC138", className: "cdt-relation__detail", "aria-live": "polite", children: [
|
|
133
|
+
selectedNode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
134
|
+
/* @__PURE__ */ jsx("strong", { children: selectedNode.label }),
|
|
135
|
+
/* @__PURE__ */ jsx("p", { children: selectedNode.description ?? "\uCD94\uAC00 \uC124\uBA85 \uC5C6\uC74C" }),
|
|
136
|
+
/* @__PURE__ */ jsx("p", { children: selectedNode.unavailable ? "\uB300\uC0C1 \uB0B4\uC6A9\uC744 \uD45C\uC2DC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4." : "\uC5F0\uACB0\uB41C \uC774\uC6C3\uC774 \uAC15\uC870\uB418\uC5C8\uC2B5\uB2C8\uB2E4." })
|
|
137
|
+
] }) : selectedEdge ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
138
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
139
|
+
endpointLabel(selectedEdge.source),
|
|
140
|
+
" \u2192 ",
|
|
141
|
+
selectedEdge.label,
|
|
142
|
+
" \u2192 ",
|
|
143
|
+
endpointLabel(selectedEdge.target)
|
|
144
|
+
] }),
|
|
145
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
146
|
+
"\uC720\uD615: ",
|
|
147
|
+
selectedEdge.type,
|
|
148
|
+
" \xB7 \uC0C1\uD0DC: ",
|
|
149
|
+
edgeState(selectedEdge),
|
|
150
|
+
" \xB7 \uC2E0\uB8B0\uB3C4: ",
|
|
151
|
+
selectedEdge.confidence ?? "\uC54C \uC218 \uC5C6\uC74C"
|
|
152
|
+
] }),
|
|
153
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
154
|
+
"\uADFC\uAC70: ",
|
|
155
|
+
selectedEdge.evidence || "\uC81C\uACF5\uB418\uC9C0 \uC54A\uC74C"
|
|
156
|
+
] }),
|
|
157
|
+
selectedHidden && /* @__PURE__ */ jsx("p", { children: "\uC120\uD0DD\uD55C \uAD00\uACC4\uB294 \uD604\uC7AC \uC720\uD615 \uD544\uD130\uC5D0\uC11C \uC228\uACA8\uC838 \uC788\uC2B5\uB2C8\uB2E4." })
|
|
158
|
+
] }) : /* @__PURE__ */ jsx("p", { children: selection ? "\uC120\uD0DD\uD55C \uD56D\uBAA9\uC774 \uD604\uC7AC \uB370\uC774\uD130\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4." : "\uB178\uB4DC \uB610\uB294 \uAD00\uACC4\uB97C \uC120\uD0DD\uD558\uBA74 \uBC29\uD5A5, \uC0C1\uD0DC, \uADFC\uAC70\uB97C \uD655\uC778\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4." }),
|
|
159
|
+
selection && /* @__PURE__ */ jsx(Button, { type: "button", onClick: () => changeSelection(null), children: "\uC120\uD0DD \uD574\uC81C" })
|
|
160
|
+
] }),
|
|
161
|
+
/* @__PURE__ */ jsxs("section", { id: `${uid}-list`, tabIndex: -1, "aria-label": "\uAD00\uACC4 \uB300\uCCB4 \uBAA9\uB85D", children: [
|
|
162
|
+
/* @__PURE__ */ jsxs("details", { open: query.length > 0 || nodes.length <= 12, children: [
|
|
163
|
+
/* @__PURE__ */ jsxs("summary", { children: [
|
|
164
|
+
"\uB178\uB4DC \uBAA9\uB85D \xB7 ",
|
|
165
|
+
found.length,
|
|
166
|
+
"\uAC1C (\uACE0\uB9BD\uB41C \uB178\uB4DC \uD3EC\uD568)"
|
|
167
|
+
] }),
|
|
168
|
+
/* @__PURE__ */ jsx("ul", { className: "cdt-relation__nodes", children: found.map((node) => /* @__PURE__ */ jsxs("li", { children: [
|
|
169
|
+
/* @__PURE__ */ jsx(Button, { type: "button", "aria-pressed": selectedNode?.id === node.id, onClick: () => {
|
|
170
|
+
changeSelection({ kind: "node", id: node.id });
|
|
171
|
+
if (query) changeViewport({ x: node.x - width / zoom / 2, y: node.y - height / zoom / 2, zoom });
|
|
172
|
+
}, children: node.label }),
|
|
173
|
+
node.unavailable && /* @__PURE__ */ jsx("span", { children: " \xB7 \uB0B4\uC6A9 \uD45C\uC2DC \uBD88\uAC00" })
|
|
174
|
+
] }, node.id)) }),
|
|
175
|
+
found.length === 0 && /* @__PURE__ */ jsx("p", { children: "\uC77C\uCE58\uD558\uB294 \uB178\uB4DC \uC5C6\uC74C" })
|
|
176
|
+
] }),
|
|
177
|
+
/* @__PURE__ */ jsxs(Table, { caption: `${label} \u2014 \uBC29\uD5A5\uACFC \uADFC\uAC70 \uBAA9\uB85D`, children: [
|
|
178
|
+
/* @__PURE__ */ jsx(Table.Head, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [
|
|
179
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "\uCD9C\uBC1C \u2192 \uAD00\uACC4 \u2192 \uB3C4\uCC29" }),
|
|
180
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "\uC720\uD615 \xB7 \uC0C1\uD0DC" }),
|
|
181
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "\uC2E0\uB8B0\uB3C4 \xB7 \uADFC\uAC70" }),
|
|
182
|
+
/* @__PURE__ */ jsx(Table.HeaderCell, { children: "\uC120\uD0DD" })
|
|
183
|
+
] }) }),
|
|
184
|
+
/* @__PURE__ */ jsx(Table.Body, { children: visibleEdges.map((edge) => /* @__PURE__ */ jsxs(Table.Row, { "data-selected": selectedEdge?.id === edge.id || void 0, children: [
|
|
185
|
+
/* @__PURE__ */ jsxs(Table.Cell, { children: [
|
|
186
|
+
endpointLabel(edge.source),
|
|
187
|
+
" \u2192 ",
|
|
188
|
+
edge.label,
|
|
189
|
+
" \u2192 ",
|
|
190
|
+
endpointLabel(edge.target)
|
|
191
|
+
] }),
|
|
192
|
+
/* @__PURE__ */ jsxs(Table.Cell, { children: [
|
|
193
|
+
edge.type,
|
|
194
|
+
" \xB7 ",
|
|
195
|
+
edgeState(edge),
|
|
196
|
+
(!byId.has(edge.source) || !byId.has(edge.target)) && " \xB7 \uB05D\uC810 \uC815\uBCF4 \uC5C6\uC74C"
|
|
197
|
+
] }),
|
|
198
|
+
/* @__PURE__ */ jsxs(Table.Cell, { children: [
|
|
199
|
+
edge.confidence ?? "\uC54C \uC218 \uC5C6\uC74C",
|
|
200
|
+
" \xB7 ",
|
|
201
|
+
edge.evidence || "\uADFC\uAC70 \uC81C\uACF5\uB418\uC9C0 \uC54A\uC74C"
|
|
202
|
+
] }),
|
|
203
|
+
/* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx(Button, { type: "button", "aria-pressed": selectedEdge?.id === edge.id, "aria-label": `\uAD00\uACC4 \uC120\uD0DD: ${edge.id}`, onClick: () => changeSelection({ kind: "edge", id: edge.id }), children: "\uADFC\uAC70 \uBCF4\uAE30" }) })
|
|
204
|
+
] }, edge.id)) })
|
|
205
|
+
] }),
|
|
206
|
+
visibleEdges.length === 0 && /* @__PURE__ */ jsx("p", { children: "\uD604\uC7AC \uD544\uD130\uC5D0\uC11C \uD45C\uC2DC\uD560 \uAD00\uACC4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." })
|
|
207
|
+
] })
|
|
208
|
+
] })
|
|
209
|
+
] });
|
|
210
|
+
});
|
|
211
|
+
RelationGraph.displayName = "RelationGraph";
|
|
212
|
+
export {
|
|
213
|
+
RelationGraph,
|
|
214
|
+
layoutRelationNodes
|
|
215
|
+
};
|
package/dist/shell.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
import * as RadixDialog from '@radix-ui/react-dialog';
|
|
3
4
|
|
|
4
5
|
interface AppShellProps extends Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
5
6
|
readonly nav: ReactNode;
|
|
@@ -10,9 +11,14 @@ interface AppShellProps extends Omit<HTMLAttributes<HTMLDivElement>, "children">
|
|
|
10
11
|
/** Accessible name of the mobile navigation scrim, which closes the drawer. */
|
|
11
12
|
readonly navCloseLabel?: string;
|
|
12
13
|
readonly mainId?: string;
|
|
14
|
+
/** Changing this consumer-owned route identity closes navigation and focuses main. */
|
|
15
|
+
readonly routeKey?: string;
|
|
16
|
+
readonly navLabel?: string;
|
|
13
17
|
readonly children: ReactNode;
|
|
14
18
|
}
|
|
15
19
|
declare const AppShell: react.ForwardRefExoticComponent<AppShellProps & react.RefAttributes<HTMLDivElement>>;
|
|
20
|
+
/** Place inside AppShell, normally in TopBar.menuButton. Use asChild for IconButton. */
|
|
21
|
+
declare const AppShellNavTrigger: react.ForwardRefExoticComponent<Omit<RadixDialog.DialogTriggerProps & react.RefAttributes<HTMLButtonElement>, "ref"> & react.RefAttributes<HTMLButtonElement>>;
|
|
16
22
|
interface NavItem {
|
|
17
23
|
readonly id: string;
|
|
18
24
|
readonly label: string;
|
|
@@ -40,4 +46,4 @@ interface TopBarProps extends Omit<HTMLAttributes<HTMLElement>, "children" | "ti
|
|
|
40
46
|
}
|
|
41
47
|
declare const TopBar: react.ForwardRefExoticComponent<TopBarProps & react.RefAttributes<HTMLElement>>;
|
|
42
48
|
|
|
43
|
-
export { AppShell, type AppShellProps, type NavItem, type NavLinkRenderProps, NavList, type NavListProps, TopBar, type TopBarProps };
|
|
49
|
+
export { AppShell, AppShellNavTrigger, type AppShellProps, type NavItem, type NavLinkRenderProps, NavList, type NavListProps, TopBar, type TopBarProps };
|
package/dist/shell.js
CHANGED
|
@@ -1,2 +1,158 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import * as RadixDialog from "@radix-ui/react-dialog";
|
|
5
|
+
import {
|
|
6
|
+
Fragment as Fragment2,
|
|
7
|
+
forwardRef,
|
|
8
|
+
useRef,
|
|
9
|
+
useId,
|
|
10
|
+
useEffect,
|
|
11
|
+
useState
|
|
12
|
+
} from "react";
|
|
13
|
+
import { breakpoints } from "@conductor-by-89soone/tokens";
|
|
14
|
+
import { cx } from "./cx.js";
|
|
15
|
+
const AppShell = forwardRef(function AppShell2({
|
|
16
|
+
children,
|
|
17
|
+
className,
|
|
18
|
+
mainId: suppliedMainId,
|
|
19
|
+
routeKey,
|
|
20
|
+
navLabel = "Navigation",
|
|
21
|
+
nav,
|
|
22
|
+
navCloseLabel = "Close navigation",
|
|
23
|
+
navOpen,
|
|
24
|
+
onNavOpenChange,
|
|
25
|
+
skipLinkLabel,
|
|
26
|
+
topBar,
|
|
27
|
+
...props
|
|
28
|
+
}, ref) {
|
|
29
|
+
const mainRef = useRef(null);
|
|
30
|
+
const generatedId = useId();
|
|
31
|
+
const mainId = suppliedMainId ?? `cdt-main-${generatedId}`;
|
|
32
|
+
const [internalOpen, setInternalOpen] = useState(false);
|
|
33
|
+
const open = navOpen ?? internalOpen;
|
|
34
|
+
const returnFocus = useRef(null);
|
|
35
|
+
const outsideInteraction = useRef(false);
|
|
36
|
+
const routeChanged = useRef(false);
|
|
37
|
+
const previousRoute = useRef(routeKey);
|
|
38
|
+
const changeOpen = (next) => {
|
|
39
|
+
setInternalOpen(next);
|
|
40
|
+
onNavOpenChange?.(next);
|
|
41
|
+
};
|
|
42
|
+
const changeOpenRef = useRef(changeOpen);
|
|
43
|
+
changeOpenRef.current = changeOpen;
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (previousRoute.current === routeKey) return;
|
|
46
|
+
previousRoute.current = routeKey;
|
|
47
|
+
routeChanged.current = true;
|
|
48
|
+
changeOpenRef.current(false);
|
|
49
|
+
mainRef.current?.focus({ preventScroll: true });
|
|
50
|
+
}, [routeKey]);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (typeof window.matchMedia !== "function") return;
|
|
53
|
+
const media = window.matchMedia(`(max-width: ${breakpoints.md}px)`);
|
|
54
|
+
const onChange = () => {
|
|
55
|
+
if (!media.matches) {
|
|
56
|
+
routeChanged.current = true;
|
|
57
|
+
changeOpenRef.current(false);
|
|
58
|
+
mainRef.current?.focus({ preventScroll: true });
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
media.addEventListener("change", onChange);
|
|
62
|
+
return () => media.removeEventListener("change", onChange);
|
|
63
|
+
}, []);
|
|
64
|
+
return /* @__PURE__ */ jsxs(RadixDialog.Root, { modal: false, open, onOpenChange: changeOpen, children: [
|
|
65
|
+
/* @__PURE__ */ jsxs("div", { ...props, ref, className: cx("cdt-app-shell", className), children: [
|
|
66
|
+
/* @__PURE__ */ jsx(
|
|
67
|
+
"a",
|
|
68
|
+
{
|
|
69
|
+
className: "cdt-skip-link",
|
|
70
|
+
href: `#${mainId}`,
|
|
71
|
+
onClick: (event) => {
|
|
72
|
+
event.preventDefault();
|
|
73
|
+
mainRef.current?.focus();
|
|
74
|
+
},
|
|
75
|
+
children: skipLinkLabel
|
|
76
|
+
}
|
|
77
|
+
),
|
|
78
|
+
/* @__PURE__ */ jsx("aside", { className: "cdt-app-shell__nav", "aria-hidden": open || void 0, children: open ? null : nav }),
|
|
79
|
+
/* @__PURE__ */ jsxs("div", { className: "cdt-app-shell__content", children: [
|
|
80
|
+
topBar,
|
|
81
|
+
/* @__PURE__ */ jsx("main", { ref: mainRef, id: mainId, className: "cdt-app-shell__main", tabIndex: -1, children })
|
|
82
|
+
] })
|
|
83
|
+
] }),
|
|
84
|
+
/* @__PURE__ */ jsxs(RadixDialog.Portal, { children: [
|
|
85
|
+
/* @__PURE__ */ jsx(RadixDialog.Close, { asChild: true, children: /* @__PURE__ */ jsx("button", { type: "button", className: "cdt-app-shell__overlay", "aria-label": navCloseLabel }) }),
|
|
86
|
+
/* @__PURE__ */ jsxs(
|
|
87
|
+
RadixDialog.Content,
|
|
88
|
+
{
|
|
89
|
+
className: "cdt-app-shell__nav",
|
|
90
|
+
"data-mobile": "",
|
|
91
|
+
"aria-describedby": void 0,
|
|
92
|
+
onOpenAutoFocus: () => {
|
|
93
|
+
returnFocus.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
94
|
+
outsideInteraction.current = false;
|
|
95
|
+
routeChanged.current = false;
|
|
96
|
+
},
|
|
97
|
+
onInteractOutside: (event) => {
|
|
98
|
+
const target = event.detail.originalEvent.target;
|
|
99
|
+
outsideInteraction.current = !(target instanceof Element && target.closest(".cdt-app-shell__overlay"));
|
|
100
|
+
},
|
|
101
|
+
onCloseAutoFocus: (event) => {
|
|
102
|
+
event.preventDefault();
|
|
103
|
+
if (routeChanged.current) mainRef.current?.focus({ preventScroll: true });
|
|
104
|
+
else if (!outsideInteraction.current && returnFocus.current?.isConnected) returnFocus.current.focus({ preventScroll: true });
|
|
105
|
+
},
|
|
106
|
+
children: [
|
|
107
|
+
/* @__PURE__ */ jsx(RadixDialog.Title, { className: "cdt-sr-only", children: navLabel }),
|
|
108
|
+
nav
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
] })
|
|
113
|
+
] });
|
|
114
|
+
});
|
|
115
|
+
AppShell.displayName = "AppShell";
|
|
116
|
+
const AppShellNavTrigger = forwardRef(
|
|
117
|
+
function AppShellNavTrigger2({ className, asChild = false, ...props }, ref) {
|
|
118
|
+
return /* @__PURE__ */ jsx(RadixDialog.Trigger, { ...props, asChild, ref, className: cx(!asChild && "cdt-btn cdt-btn--ghost", className) });
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
AppShellNavTrigger.displayName = "AppShellNavTrigger";
|
|
122
|
+
const NavList = forwardRef(function NavList2({ className, items, renderLink, ...props }, ref) {
|
|
123
|
+
let previousSection;
|
|
124
|
+
return /* @__PURE__ */ jsx("nav", { ...props, ref, className: cx("cdt-nav-list", className), children: /* @__PURE__ */ jsx("ul", { className: "cdt-nav-list__items", children: items.map((item) => {
|
|
125
|
+
const showSection = item.section !== void 0 && item.section !== previousSection;
|
|
126
|
+
previousSection = item.section;
|
|
127
|
+
const linkProps = {
|
|
128
|
+
className: cx("cdt-nav-list__item", item.active && "cdt-nav-list__item--active"),
|
|
129
|
+
"aria-current": item.active ? "page" : void 0,
|
|
130
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
131
|
+
item.icon === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "cdt-nav-list__icon", "aria-hidden": "true", children: item.icon }),
|
|
132
|
+
/* @__PURE__ */ jsx("span", { children: item.label })
|
|
133
|
+
] })
|
|
134
|
+
};
|
|
135
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
136
|
+
showSection ? /* @__PURE__ */ jsx("li", { className: "cdt-nav-list__section-label", children: item.section }) : null,
|
|
137
|
+
/* @__PURE__ */ jsx("li", { children: renderLink(item, linkProps) })
|
|
138
|
+
] }, item.id);
|
|
139
|
+
}) }) });
|
|
140
|
+
});
|
|
141
|
+
NavList.displayName = "NavList";
|
|
142
|
+
const TopBar = forwardRef(function TopBar2({ actions, className, eyebrow, menuButton, title, ...props }, ref) {
|
|
143
|
+
return /* @__PURE__ */ jsxs("header", { ...props, ref, className: cx("cdt-topbar", className), title: typeof title === "string" ? title : void 0, children: [
|
|
144
|
+
menuButton === void 0 ? null : /* @__PURE__ */ jsx("div", { className: "cdt-topbar__menu-button", children: menuButton }),
|
|
145
|
+
eyebrow === void 0 && title === void 0 ? null : /* @__PURE__ */ jsxs("div", { className: "cdt-topbar__context", children: [
|
|
146
|
+
eyebrow === void 0 ? null : /* @__PURE__ */ jsx("div", { className: "cdt-topbar__eyebrow", children: eyebrow }),
|
|
147
|
+
title === void 0 ? null : /* @__PURE__ */ jsx("div", { className: "cdt-topbar__title", children: title })
|
|
148
|
+
] }),
|
|
149
|
+
actions === void 0 ? null : /* @__PURE__ */ jsx("div", { className: "cdt-topbar__actions", children: actions })
|
|
150
|
+
] });
|
|
151
|
+
});
|
|
152
|
+
TopBar.displayName = "TopBar";
|
|
153
|
+
export {
|
|
154
|
+
AppShell,
|
|
155
|
+
AppShellNavTrigger,
|
|
156
|
+
NavList,
|
|
157
|
+
TopBar
|
|
158
|
+
};
|
package/dist/status.js
CHANGED
|
@@ -1,2 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { SEVERITY_ICONS, STATUS_ICONS } from "@conductor-by-89soone/tokens";
|
|
4
|
+
import { forwardRef } from "react";
|
|
5
|
+
import { cx } from "./cx.js";
|
|
6
|
+
const Badge = forwardRef(function Badge2({ children, className, icon, tone = "neutral", ...props }, ref) {
|
|
7
|
+
return /* @__PURE__ */ jsxs("span", { ...props, ref, className: cx("cdt-badge", `cdt-badge--${tone}`, className), children: [
|
|
8
|
+
icon === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "cdt-badge__icon", "aria-hidden": "true", children: icon }),
|
|
9
|
+
children
|
|
10
|
+
] });
|
|
11
|
+
});
|
|
12
|
+
Badge.displayName = "Badge";
|
|
13
|
+
const markerStatuses = ["queued", "neutralEnd"];
|
|
14
|
+
const StatusBadge = forwardRef(function StatusBadge2({ className, icon, label, status, ...props }, ref) {
|
|
15
|
+
const isMarker = markerStatuses.includes(status);
|
|
16
|
+
const statusClass = status === "neutralEnd" ? "neutral-end" : status;
|
|
17
|
+
return /* @__PURE__ */ jsxs("span", { ...props, ref, className: cx("cdt-badge", "cdt-status-badge", `cdt-status-badge--${statusClass}`, className), children: [
|
|
18
|
+
isMarker ? /* @__PURE__ */ jsx("span", { className: cx("cdt-status-badge__marker", status === "neutralEnd" && "cdt-status-badge__marker--neutral-end"), "aria-hidden": "true" }) : null,
|
|
19
|
+
/* @__PURE__ */ jsx("span", { className: "cdt-badge__icon", "aria-hidden": "true", "data-cdt-icon": STATUS_ICONS[status], children: icon }),
|
|
20
|
+
label
|
|
21
|
+
] });
|
|
22
|
+
});
|
|
23
|
+
StatusBadge.displayName = "StatusBadge";
|
|
24
|
+
const SeverityTag = forwardRef(function SeverityTag2({ className, icon, label, severity, ...props }, ref) {
|
|
25
|
+
return /* @__PURE__ */ jsxs("span", { ...props, ref, className: cx("cdt-badge", "cdt-severity-tag", `cdt-severity-tag--${severity}`, className), children: [
|
|
26
|
+
/* @__PURE__ */ jsx("span", { className: "cdt-badge__icon", "aria-hidden": "true", "data-cdt-icon": SEVERITY_ICONS[severity], children: icon }),
|
|
27
|
+
label
|
|
28
|
+
] });
|
|
29
|
+
});
|
|
30
|
+
SeverityTag.displayName = "SeverityTag";
|
|
31
|
+
export {
|
|
32
|
+
Badge,
|
|
33
|
+
SeverityTag,
|
|
34
|
+
StatusBadge
|
|
35
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Warn once when a consumer renders a Conductor class without loading the CSS
|
|
3
|
+
* package. The deferred check gives bundlers time to apply extracted styles and
|
|
4
|
+
* never runs during SSR.
|
|
5
|
+
*/
|
|
6
|
+
declare function scheduleStylesheetWarning(): void;
|
|
7
|
+
|
|
8
|
+
export { scheduleStylesheetWarning };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var warningScheduled = false;
|
|
1
|
+
const STYLE_MARKER = "--cdt-font-sans";
|
|
2
|
+
let warningScheduled = false;
|
|
4
3
|
function scheduleStylesheetWarning() {
|
|
5
4
|
if (process.env.NODE_ENV !== "development" || typeof window === "undefined" || warningScheduled) return;
|
|
6
5
|
warningScheduled = true;
|
|
@@ -11,13 +10,6 @@ function scheduleStylesheetWarning() {
|
|
|
11
10
|
}
|
|
12
11
|
}, 0);
|
|
13
12
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (classNames.some((className) => typeof className === "string" && /(?:^|\s)cdt-/.test(className))) {
|
|
18
|
-
scheduleStylesheetWarning();
|
|
19
|
-
}
|
|
20
|
-
return classNames.filter((className) => typeof className === "string" && className !== "").join(" ");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export { cx };
|
|
13
|
+
export {
|
|
14
|
+
scheduleStylesheetWarning
|
|
15
|
+
};
|
package/dist/surface.js
CHANGED
|
@@ -1,2 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef, useEffect, useRef } from "react";
|
|
4
|
+
import { cx } from "./cx.js";
|
|
5
|
+
const nestedInteractive = "a,button,input,select,textarea,[role=button]";
|
|
6
|
+
const Card = forwardRef(function Card2({ as, children, className, href, onClick, size = "md", ...props }, forwardedRef) {
|
|
7
|
+
const rootRef = useRef(null);
|
|
8
|
+
const interactive = as === "a" || as === "button" || href !== void 0 || onClick !== void 0;
|
|
9
|
+
const element = as ?? (href === void 0 ? onClick === void 0 ? "div" : "button" : "a");
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (process.env.NODE_ENV !== "production" && interactive && rootRef.current?.querySelector(nestedInteractive) !== null) {
|
|
12
|
+
console.warn("[conductor] Interactive Card must not contain nested interactive elements.");
|
|
13
|
+
}
|
|
14
|
+
}, [interactive]);
|
|
15
|
+
const setRef = (node) => {
|
|
16
|
+
rootRef.current = node;
|
|
17
|
+
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
18
|
+
else if (forwardedRef !== null) forwardedRef.current = node;
|
|
19
|
+
};
|
|
20
|
+
const classes = cx("cdt-card", interactive && "cdt-card--interactive", size === "sm" && "cdt-card--sm", className);
|
|
21
|
+
if (element === "a") {
|
|
22
|
+
return /* @__PURE__ */ jsx("a", { ...props, ref: setRef, href, className: classes, children });
|
|
23
|
+
}
|
|
24
|
+
if (element === "button") {
|
|
25
|
+
return /* @__PURE__ */ jsx("button", { ...props, ref: setRef, type: "button", onClick, className: classes, children });
|
|
26
|
+
}
|
|
27
|
+
return /* @__PURE__ */ jsx("div", { ...props, ref: setRef, className: classes, children });
|
|
28
|
+
});
|
|
29
|
+
Card.displayName = "Card";
|
|
30
|
+
const CardGrid = forwardRef(function CardGrid2({ className, ...props }, ref) {
|
|
31
|
+
return /* @__PURE__ */ jsx("div", { ...props, ref, className: cx("cdt-card-grid", className) });
|
|
32
|
+
});
|
|
33
|
+
CardGrid.displayName = "CardGrid";
|
|
34
|
+
const Panel = forwardRef(function Panel2({ as = "div", className, size = "md", ...props }, ref) {
|
|
35
|
+
const classes = cx("cdt-panel", size === "sm" && "cdt-panel--sm", className);
|
|
36
|
+
if (as === "section") return /* @__PURE__ */ jsx("section", { ...props, ref, className: classes });
|
|
37
|
+
if (as === "aside") return /* @__PURE__ */ jsx("aside", { ...props, ref, className: classes });
|
|
38
|
+
return /* @__PURE__ */ jsx("div", { ...props, ref, className: classes });
|
|
39
|
+
});
|
|
40
|
+
Panel.displayName = "Panel";
|
|
41
|
+
export {
|
|
42
|
+
Card,
|
|
43
|
+
CardGrid,
|
|
44
|
+
Panel
|
|
45
|
+
};
|
package/dist/types.js
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|