@you-agent-factory/components 0.0.0 → 0.0.2
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/LICENSE.md +21 -0
- package/README.md +38 -7
- package/dist/category-paths.d.ts +3 -0
- package/dist/charts/chart-state-panel.d.ts +11 -0
- package/dist/charts/chart.d.ts +35 -0
- package/dist/charts/index.d.ts +5 -0
- package/dist/charts/index.js +287 -0
- package/dist/chunks/action-row.js +39 -0
- package/dist/chunks/alert-panel.js +182 -0
- package/dist/chunks/button.js +193 -0
- package/dist/chunks/cn.js +6 -0
- package/dist/chunks/factory-emulator-controls.js +123 -0
- package/dist/chunks/package-form-field.js +546 -0
- package/dist/chunks/scroll-area.js +261 -0
- package/dist/chunks/surface-panel.js +73 -0
- package/dist/chunks/table-layout.js +292 -0
- package/dist/chunks/typography-roles.js +26 -0
- package/dist/chunks/typography.js +129 -0
- package/dist/chunks/widget-frame.js +344 -0
- package/dist/data-display/code-panel.d.ts +12 -0
- package/dist/data-display/data-table.d.ts +27 -0
- package/dist/data-display/description-list.d.ts +4 -0
- package/{src/data-display/index.ts → dist/data-display/index.d.ts} +4 -26
- package/dist/data-display/index.js +20 -0
- package/dist/data-display/table-layout.d.ts +8 -0
- package/dist/data-display/table.d.ts +14 -0
- package/dist/factory-emulator/factory-emulator-controls.d.ts +23 -0
- package/dist/factory-emulator/index.d.ts +6 -0
- package/dist/factory-emulator/index.js +6 -0
- package/dist/feedback/alert-panel-semantics.d.ts +11 -0
- package/dist/feedback/alert-panel.d.ts +29 -0
- package/dist/feedback/index.d.ts +6 -0
- package/dist/feedback/index.js +10 -0
- package/dist/feedback/skeleton.d.ts +2 -0
- package/dist/forms/index.d.ts +19 -0
- package/dist/forms/index.js +37 -0
- package/dist/forms/package-checkbox.d.ts +3 -0
- package/dist/forms/package-enum-select.d.ts +42 -0
- package/dist/forms/package-file-input.d.ts +3 -0
- package/dist/forms/package-form-field.d.ts +49 -0
- package/dist/forms/package-input.d.ts +6 -0
- package/dist/forms/package-native-select.d.ts +3 -0
- package/dist/forms/package-select.d.ts +32 -0
- package/dist/forms/package-textarea.d.ts +10 -0
- package/dist/forms/select-icons.d.ts +3 -0
- package/dist/graphs/graph-edge-path.d.ts +18 -0
- package/dist/graphs/graph-edge.d.ts +15 -0
- package/dist/graphs/graph-node-button.d.ts +11 -0
- package/dist/graphs/graph-node-handle-badge.d.ts +5 -0
- package/dist/graphs/graph-node-handle.d.ts +18 -0
- package/dist/graphs/graph-node-shell.d.ts +13 -0
- package/dist/graphs/graph-node-state-indicator.d.ts +6 -0
- package/dist/graphs/graph-node-state.d.ts +23 -0
- package/dist/graphs/graph-viewport-surface.d.ts +5 -0
- package/dist/graphs/index.d.ts +13 -0
- package/dist/graphs/index.js +614 -0
- package/{src/icons/index.ts → dist/icons/index.d.ts} +1 -2
- package/dist/icons/index.js +4 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +145 -0
- package/dist/layout/action-row.d.ts +8 -0
- package/{src/layout/index.ts → dist/layout/index.d.ts} +1 -3
- package/dist/layout/index.js +9 -0
- package/dist/layout/surface-panel.d.ts +15 -0
- package/{src/navigation/index.ts → dist/navigation/index.d.ts} +1 -2
- package/dist/navigation/index.js +4 -0
- package/dist/overlays/collapsible.d.ts +5 -0
- package/dist/overlays/dialog.d.ts +16 -0
- package/dist/overlays/index.d.ts +10 -0
- package/dist/overlays/index.js +27 -0
- package/dist/overlays/overlay-layout.d.ts +6 -0
- package/dist/overlays/popover.d.ts +6 -0
- package/dist/overlays/scroll-area.d.ts +9 -0
- package/dist/primitives/button-link.d.ts +5 -0
- package/dist/primitives/button.d.ts +9 -0
- package/dist/primitives/icon-button-shell.d.ts +10 -0
- package/{src/primitives/index.ts → dist/primitives/index.d.ts} +2 -19
- package/dist/primitives/index.js +49 -0
- package/dist/primitives/package-text.d.ts +6 -0
- package/dist/primitives/typography-roles.d.ts +12 -0
- package/dist/primitives/typography.d.ts +36 -0
- package/dist/recipes/index.d.ts +14 -0
- package/dist/recipes/index.js +32 -0
- package/dist/recipes/widget-frame-content.d.ts +24 -0
- package/dist/recipes/widget-frame-disclosure.d.ts +33 -0
- package/dist/recipes/widget-frame-layout.d.ts +12 -0
- package/dist/recipes/widget-frame-skeleton.d.ts +2 -0
- package/dist/recipes/widget-frame-states.d.ts +15 -0
- package/dist/recipes/widget-frame-typography.d.ts +10 -0
- package/dist/recipes/widget-frame.d.ts +12 -0
- package/{src → dist}/styles.css +36 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +16 -0
- package/dist/testing/render.d.ts +5 -0
- package/{src/tokens/index.ts → dist/tokens/index.d.ts} +1 -2
- package/dist/tokens/index.js +4 -0
- package/dist/utilities/cn.d.ts +1 -0
- package/{src/utilities/index.ts → dist/utilities/index.d.ts} +1 -3
- package/dist/utilities/index.js +6 -0
- package/package.json +65 -64
- package/docs/README.md +0 -83
- package/docs/button.md +0 -119
- package/docs/charts.md +0 -325
- package/docs/data-display-code-panel.md +0 -120
- package/docs/feedback-alert-panel.md +0 -117
- package/docs/feedback-skeleton.md +0 -54
- package/docs/forms-form-field.md +0 -490
- package/docs/forms-input-primitives.md +0 -311
- package/docs/forms-select-primitives.md +0 -362
- package/docs/graphs.md +0 -250
- package/docs/layout-display-primitives.md +0 -211
- package/docs/overlays.md +0 -414
- package/docs/table-data-table.md +0 -331
- package/docs/typography-roles.md +0 -182
- package/docs/widget-frame-recipes.md +0 -273
- package/src/category-paths.ts +0 -20
- package/src/charts/chart-state-panel.tsx +0 -103
- package/src/charts/chart.tsx +0 -287
- package/src/charts/index.ts +0 -21
- package/src/data-display/code-panel.tsx +0 -67
- package/src/data-display/data-table.tsx +0 -180
- package/src/data-display/description-list.tsx +0 -24
- package/src/data-display/table-layout.ts +0 -12
- package/src/data-display/table.tsx +0 -131
- package/src/feedback/alert-panel-semantics.ts +0 -75
- package/src/feedback/alert-panel.tsx +0 -187
- package/src/feedback/index.ts +0 -21
- package/src/feedback/skeleton.tsx +0 -16
- package/src/forms/index.ts +0 -73
- package/src/forms/package-checkbox.tsx +0 -50
- package/src/forms/package-enum-select.tsx +0 -185
- package/src/forms/package-file-input.tsx +0 -25
- package/src/forms/package-form-field.tsx +0 -202
- package/src/forms/package-input.tsx +0 -25
- package/src/forms/package-native-select.tsx +0 -25
- package/src/forms/package-select.tsx +0 -209
- package/src/forms/package-textarea.tsx +0 -35
- package/src/forms/select-icons.tsx +0 -35
- package/src/graphs/graph-edge-path.ts +0 -241
- package/src/graphs/graph-edge.tsx +0 -130
- package/src/graphs/graph-interactive-example.tsx +0 -187
- package/src/graphs/graph-node-button.tsx +0 -51
- package/src/graphs/graph-node-handle-badge.tsx +0 -108
- package/src/graphs/graph-node-handle.ts +0 -28
- package/src/graphs/graph-node-shell.tsx +0 -111
- package/src/graphs/graph-node-state-indicator.tsx +0 -47
- package/src/graphs/graph-node-state.ts +0 -111
- package/src/graphs/graph-viewport-surface.tsx +0 -27
- package/src/graphs/index.ts +0 -41
- package/src/index.ts +0 -209
- package/src/layout/action-row.tsx +0 -53
- package/src/layout/surface-panel.tsx +0 -91
- package/src/overlays/collapsible.tsx +0 -22
- package/src/overlays/dialog.tsx +0 -148
- package/src/overlays/index.ts +0 -31
- package/src/overlays/overlay-layout.ts +0 -9
- package/src/overlays/popover.tsx +0 -29
- package/src/overlays/scroll-area.tsx +0 -78
- package/src/primitives/button-link.tsx +0 -22
- package/src/primitives/button.tsx +0 -258
- package/src/primitives/icon-button-shell.tsx +0 -49
- package/src/primitives/package-text.tsx +0 -29
- package/src/primitives/typography-roles.ts +0 -12
- package/src/primitives/typography.tsx +0 -165
- package/src/recipes/index.ts +0 -61
- package/src/recipes/widget-frame-content.tsx +0 -114
- package/src/recipes/widget-frame-disclosure.tsx +0 -161
- package/src/recipes/widget-frame-layout.ts +0 -40
- package/src/recipes/widget-frame-skeleton.tsx +0 -16
- package/src/recipes/widget-frame-states.tsx +0 -99
- package/src/recipes/widget-frame-typography.ts +0 -19
- package/src/recipes/widget-frame.tsx +0 -84
- package/src/testing/index.ts +0 -13
- package/src/testing/render.tsx +0 -16
- package/src/utilities/cn.ts +0 -5
- /package/{src → dist}/styles/color-palette-presets.css +0 -0
- /package/{src → dist}/styles/color-role-tokens.css +0 -0
- /package/{src → dist}/styles/layout-role-tokens.css +0 -0
- /package/{src → dist}/styles/text-color-role-tokens.css +0 -0
- /package/{src → dist}/styles/typography-role-tokens.css +0 -0
- /package/{src → dist}/styles/typography-role-utilities.css +0 -0
- /package/{src → dist}/styles/typography-roles.css +0 -0
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import "@xyflow/react/dist/style.css";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
Background,
|
|
5
|
-
Controls,
|
|
6
|
-
ReactFlow,
|
|
7
|
-
ReactFlowProvider,
|
|
8
|
-
type Edge,
|
|
9
|
-
type Node,
|
|
10
|
-
type NodeProps,
|
|
11
|
-
} from "@xyflow/react";
|
|
12
|
-
import { useCallback, useMemo, useState } from "react";
|
|
13
|
-
|
|
14
|
-
import { GRAPH_EDGE_TYPES } from "./graph-edge";
|
|
15
|
-
import {
|
|
16
|
-
desktopInteractiveGraphNodes,
|
|
17
|
-
type GraphInteractiveFixtureNode,
|
|
18
|
-
} from "./graph-story-fixtures";
|
|
19
|
-
import { GraphNodeButton } from "./graph-node-button";
|
|
20
|
-
import { GraphNodeShell } from "./graph-node-shell";
|
|
21
|
-
import type { GraphNodeState } from "./graph-node-state";
|
|
22
|
-
import { GraphViewportSurface } from "./graph-viewport-surface";
|
|
23
|
-
|
|
24
|
-
type GenericGraphFlowNodeData = GraphInteractiveFixtureNode & {
|
|
25
|
-
graphState: GraphNodeState;
|
|
26
|
-
onActivate?: () => void;
|
|
27
|
-
shellState: GraphNodeState;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
function GenericGraphFlowNode({ data }: NodeProps<Node<GenericGraphFlowNodeData>>) {
|
|
31
|
-
return (
|
|
32
|
-
<div className="w-44 max-w-full sm:w-52">
|
|
33
|
-
<GraphNodeShell
|
|
34
|
-
handles={data.handles}
|
|
35
|
-
nodeKind={data.nodeKind}
|
|
36
|
-
state={data.shellState}
|
|
37
|
-
stateLabel={data.stateLabel}
|
|
38
|
-
>
|
|
39
|
-
<GraphNodeButton
|
|
40
|
-
graphState={data.graphState}
|
|
41
|
-
onClick={data.onActivate}
|
|
42
|
-
stateLabel={data.stateLabel}
|
|
43
|
-
>
|
|
44
|
-
{data.label}
|
|
45
|
-
</GraphNodeButton>
|
|
46
|
-
</GraphNodeShell>
|
|
47
|
-
</div>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const GENERIC_GRAPH_NODE_TYPES = {
|
|
52
|
-
genericGraph: GenericGraphFlowNode,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
function buildFlowNodes(
|
|
56
|
-
fixtureNodes: GraphInteractiveFixtureNode[],
|
|
57
|
-
selectedNodeId: string | null,
|
|
58
|
-
onSelectNode: (nodeId: string) => void,
|
|
59
|
-
): Node<GenericGraphFlowNodeData>[] {
|
|
60
|
-
return fixtureNodes.map((fixtureNode) => {
|
|
61
|
-
const isSelectable = fixtureNode.selectable === true;
|
|
62
|
-
const isSelected = isSelectable && selectedNodeId === fixtureNode.id;
|
|
63
|
-
const resolvedState =
|
|
64
|
-
fixtureNode.fixedState ?? (isSelected ? "selected" : "default");
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
data: {
|
|
68
|
-
...fixtureNode,
|
|
69
|
-
graphState: resolvedState,
|
|
70
|
-
onActivate: isSelectable
|
|
71
|
-
? () => {
|
|
72
|
-
onSelectNode(fixtureNode.id);
|
|
73
|
-
}
|
|
74
|
-
: undefined,
|
|
75
|
-
shellState: resolvedState,
|
|
76
|
-
},
|
|
77
|
-
draggable: false,
|
|
78
|
-
id: fixtureNode.id,
|
|
79
|
-
position: fixtureNode.position,
|
|
80
|
-
selectable: false,
|
|
81
|
-
type: "genericGraph",
|
|
82
|
-
};
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function buildFlowEdges(
|
|
87
|
-
fixtureNodes: GraphInteractiveFixtureNode[],
|
|
88
|
-
selectedNodeId: string | null,
|
|
89
|
-
): Edge[] {
|
|
90
|
-
const readyNode = fixtureNodes.find((node) => node.id === "ready-node");
|
|
91
|
-
const targetNode = fixtureNodes.find((node) => node.id === "target-node");
|
|
92
|
-
|
|
93
|
-
if (!readyNode || !targetNode) {
|
|
94
|
-
return [];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return [
|
|
98
|
-
{
|
|
99
|
-
data: {
|
|
100
|
-
alwaysShowLabel: true,
|
|
101
|
-
label: "Example edge",
|
|
102
|
-
waypoints:
|
|
103
|
-
readyNode.position.y === targetNode.position.y
|
|
104
|
-
? undefined
|
|
105
|
-
: [
|
|
106
|
-
{
|
|
107
|
-
x: (readyNode.position.x + targetNode.position.x) / 2 + 72,
|
|
108
|
-
y: readyNode.position.y + 48,
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
x: (readyNode.position.x + targetNode.position.x) / 2 + 72,
|
|
112
|
-
y: targetNode.position.y + 48,
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
},
|
|
116
|
-
id: "ready-to-target",
|
|
117
|
-
selectable: false,
|
|
118
|
-
source: readyNode.id,
|
|
119
|
-
target: targetNode.id,
|
|
120
|
-
type: "graphEdge",
|
|
121
|
-
},
|
|
122
|
-
].map((edge) => ({
|
|
123
|
-
...edge,
|
|
124
|
-
selected: selectedNodeId === edge.source || selectedNodeId === edge.target,
|
|
125
|
-
}));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export type GraphInteractiveExampleProps = {
|
|
129
|
-
"aria-label"?: string;
|
|
130
|
-
className?: string;
|
|
131
|
-
fixtureNodes?: GraphInteractiveFixtureNode[];
|
|
132
|
-
initialSelectedNodeId?: string | null;
|
|
133
|
-
viewportWidthClass?: string;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
export function GraphInteractiveExample({
|
|
137
|
-
"aria-label": ariaLabel = "Interactive graph example",
|
|
138
|
-
className = "h-[28rem]",
|
|
139
|
-
fixtureNodes = desktopInteractiveGraphNodes,
|
|
140
|
-
initialSelectedNodeId = null,
|
|
141
|
-
viewportWidthClass = "w-[48rem] max-w-full",
|
|
142
|
-
}: GraphInteractiveExampleProps) {
|
|
143
|
-
const [selectedNodeId, setSelectedNodeId] = useState<string | null>(
|
|
144
|
-
initialSelectedNodeId,
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
const handleSelectNode = useCallback((nodeId: string) => {
|
|
148
|
-
setSelectedNodeId(nodeId);
|
|
149
|
-
}, []);
|
|
150
|
-
|
|
151
|
-
const nodes = useMemo(
|
|
152
|
-
() => buildFlowNodes(fixtureNodes, selectedNodeId, handleSelectNode),
|
|
153
|
-
[fixtureNodes, handleSelectNode, selectedNodeId],
|
|
154
|
-
);
|
|
155
|
-
const edges = useMemo(
|
|
156
|
-
() => buildFlowEdges(fixtureNodes, selectedNodeId),
|
|
157
|
-
[fixtureNodes, selectedNodeId],
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
return (
|
|
161
|
-
<ReactFlowProvider>
|
|
162
|
-
<div className={viewportWidthClass}>
|
|
163
|
-
<GraphViewportSurface aria-label={ariaLabel} className={className}>
|
|
164
|
-
<ReactFlow
|
|
165
|
-
defaultEdgeOptions={{ selectable: false }}
|
|
166
|
-
edgeTypes={GRAPH_EDGE_TYPES}
|
|
167
|
-
edges={edges}
|
|
168
|
-
fitView
|
|
169
|
-
fitViewOptions={{ padding: 0.2 }}
|
|
170
|
-
maxZoom={1.25}
|
|
171
|
-
minZoom={0.5}
|
|
172
|
-
nodeTypes={GENERIC_GRAPH_NODE_TYPES}
|
|
173
|
-
nodes={nodes}
|
|
174
|
-
nodesConnectable={false}
|
|
175
|
-
nodesDraggable={false}
|
|
176
|
-
panOnDrag={true}
|
|
177
|
-
proOptions={{ hideAttribution: true }}
|
|
178
|
-
zoomOnScroll={true}
|
|
179
|
-
>
|
|
180
|
-
<Background gap={16} size={1} />
|
|
181
|
-
<Controls showInteractive={false} />
|
|
182
|
-
</ReactFlow>
|
|
183
|
-
</GraphViewportSurface>
|
|
184
|
-
</div>
|
|
185
|
-
</ReactFlowProvider>
|
|
186
|
-
);
|
|
187
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { type ButtonHTMLAttributes, forwardRef } from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../utilities/cn";
|
|
4
|
-
import {
|
|
5
|
-
type GraphNodeState,
|
|
6
|
-
graphNodeButtonIsDisabled,
|
|
7
|
-
graphNodeButtonStateAttributes,
|
|
8
|
-
graphNodeButtonStateClassName,
|
|
9
|
-
} from "./graph-node-state";
|
|
10
|
-
|
|
11
|
-
export type GraphNodeButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
12
|
-
graphState?: GraphNodeState;
|
|
13
|
-
stateLabel?: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const GRAPH_NODE_BUTTON_BASE_CLASS =
|
|
17
|
-
"nodrag nopan cursor-pointer border-0 bg-transparent p-0 text-left text-inherit focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-af-focus-ring disabled:cursor-not-allowed disabled:opacity-100";
|
|
18
|
-
|
|
19
|
-
export const GraphNodeButton = forwardRef<
|
|
20
|
-
HTMLButtonElement,
|
|
21
|
-
GraphNodeButtonProps
|
|
22
|
-
>(function GraphNodeButton(
|
|
23
|
-
{
|
|
24
|
-
className,
|
|
25
|
-
disabled,
|
|
26
|
-
graphState = "default",
|
|
27
|
-
onClick,
|
|
28
|
-
stateLabel,
|
|
29
|
-
type = "button",
|
|
30
|
-
...props
|
|
31
|
-
},
|
|
32
|
-
ref,
|
|
33
|
-
) {
|
|
34
|
-
const isDisabled = graphNodeButtonIsDisabled(graphState, disabled);
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<button
|
|
38
|
-
className={cn(
|
|
39
|
-
GRAPH_NODE_BUTTON_BASE_CLASS,
|
|
40
|
-
graphNodeButtonStateClassName(graphState),
|
|
41
|
-
className,
|
|
42
|
-
)}
|
|
43
|
-
disabled={isDisabled}
|
|
44
|
-
onClick={isDisabled ? undefined : onClick}
|
|
45
|
-
ref={ref}
|
|
46
|
-
type={type}
|
|
47
|
-
{...graphNodeButtonStateAttributes(graphState, stateLabel)}
|
|
48
|
-
{...props}
|
|
49
|
-
/>
|
|
50
|
-
);
|
|
51
|
-
});
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { Handle, Position } from "@xyflow/react";
|
|
2
|
-
import type { CSSProperties } from "react";
|
|
3
|
-
|
|
4
|
-
import { cn } from "../utilities/cn";
|
|
5
|
-
import type { GraphNodeHandle, GraphNodeHandleTone } from "./graph-node-handle";
|
|
6
|
-
|
|
7
|
-
export interface GraphNodeHandleBadgeProps {
|
|
8
|
-
handle: GraphNodeHandle;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function GraphNodeHandleBadge({ handle }: GraphNodeHandleBadgeProps) {
|
|
12
|
-
const position = handle.side === "left" ? Position.Left : Position.Right;
|
|
13
|
-
const overlayHandleStyle = anchoredHandleStyle(handle.side);
|
|
14
|
-
|
|
15
|
-
if (handle.hidden) {
|
|
16
|
-
return (
|
|
17
|
-
<Handle
|
|
18
|
-
className="pointer-events-none !top-1/2 opacity-0"
|
|
19
|
-
id={handle.id}
|
|
20
|
-
isConnectable={handle.connectable ?? false}
|
|
21
|
-
position={position}
|
|
22
|
-
style={overlayHandleStyle}
|
|
23
|
-
type={handle.type}
|
|
24
|
-
/>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const tone = handle.tone ?? "default";
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<div
|
|
32
|
-
className="pointer-events-none relative flex h-5 w-5 items-center justify-center"
|
|
33
|
-
data-node-handle-badge={handle.id}
|
|
34
|
-
data-node-handle-invalid={handle.validationError ? "true" : undefined}
|
|
35
|
-
data-node-handle-tone={tone}
|
|
36
|
-
>
|
|
37
|
-
<Handle
|
|
38
|
-
aria-invalid={handle.validationError ? true : undefined}
|
|
39
|
-
aria-label={handle.buttonAriaLabel ?? handle.label}
|
|
40
|
-
className={cn(
|
|
41
|
-
"pointer-events-auto absolute !top-1/2 !h-5 !w-5 !border-0 !bg-transparent",
|
|
42
|
-
"before:pointer-events-none before:absolute before:top-1/2 before:h-2.5 before:w-2.5 before:-translate-x-1/2 before:-translate-y-1/2 before:rounded-full before:border before:border-surface before:bg-[var(--node-handle-background)] before:shadow-sm before:transition before:content-['']",
|
|
43
|
-
handle.side === "left" ? "before:left-0" : "before:left-full",
|
|
44
|
-
handle.buttonPressed &&
|
|
45
|
-
"before:scale-125 before:shadow-[0_0_0_3px_var(--color-primary-container)]",
|
|
46
|
-
handle.variant === "valid-target" &&
|
|
47
|
-
"before:scale-125 before:shadow-[0_0_0_3px_var(--color-success-container)]",
|
|
48
|
-
handle.variant === "error" &&
|
|
49
|
-
"before:border-af-danger-border before:shadow-[0_0_0_3px_var(--color-error-container)] motion-safe:before:animate-pulse",
|
|
50
|
-
handle.validationError &&
|
|
51
|
-
"before:ring-2 before:ring-af-danger-border motion-safe:before:animate-pulse",
|
|
52
|
-
)}
|
|
53
|
-
id={handle.id}
|
|
54
|
-
isConnectable={handle.connectable ?? true}
|
|
55
|
-
onClick={handle.onButtonClick}
|
|
56
|
-
position={position}
|
|
57
|
-
style={
|
|
58
|
-
{
|
|
59
|
-
...overlayHandleStyle,
|
|
60
|
-
"--node-handle-background": handleDotColor(tone),
|
|
61
|
-
opacity: handle.buttonDisabled ? 0.45 : undefined,
|
|
62
|
-
} as CSSProperties
|
|
63
|
-
}
|
|
64
|
-
title={handle.buttonTitle ?? handle.validationMessage}
|
|
65
|
-
type={handle.type}
|
|
66
|
-
/>
|
|
67
|
-
</div>
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function handleDotColor(tone: GraphNodeHandleTone): string {
|
|
72
|
-
switch (tone) {
|
|
73
|
-
case "assignment":
|
|
74
|
-
return "var(--color-success)";
|
|
75
|
-
case "continue":
|
|
76
|
-
return "var(--color-secondary)";
|
|
77
|
-
case "failure":
|
|
78
|
-
return "var(--color-error)";
|
|
79
|
-
case "input":
|
|
80
|
-
return "var(--color-success)";
|
|
81
|
-
case "output":
|
|
82
|
-
return "var(--color-success)";
|
|
83
|
-
case "rejection":
|
|
84
|
-
return "var(--color-warning)";
|
|
85
|
-
case "resource":
|
|
86
|
-
return "var(--color-black)";
|
|
87
|
-
case "worker":
|
|
88
|
-
return "var(--color-purple-500)";
|
|
89
|
-
default:
|
|
90
|
-
return "var(--color-success)";
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function anchoredHandleStyle(
|
|
95
|
-
side: GraphNodeHandle["side"],
|
|
96
|
-
): CSSProperties {
|
|
97
|
-
return side === "left"
|
|
98
|
-
? {
|
|
99
|
-
left: "50%",
|
|
100
|
-
top: "50%",
|
|
101
|
-
transform: "translateY(-50%)",
|
|
102
|
-
}
|
|
103
|
-
: {
|
|
104
|
-
left: "50%",
|
|
105
|
-
top: "50%",
|
|
106
|
-
transform: "translate(-100%, -50%)",
|
|
107
|
-
};
|
|
108
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export type GraphNodeHandleTone =
|
|
2
|
-
| "assignment"
|
|
3
|
-
| "continue"
|
|
4
|
-
| "default"
|
|
5
|
-
| "failure"
|
|
6
|
-
| "input"
|
|
7
|
-
| "output"
|
|
8
|
-
| "rejection"
|
|
9
|
-
| "resource"
|
|
10
|
-
| "worker";
|
|
11
|
-
|
|
12
|
-
export interface GraphNodeHandle {
|
|
13
|
-
buttonAriaLabel?: string;
|
|
14
|
-
buttonDisabled?: boolean;
|
|
15
|
-
buttonPressed?: boolean;
|
|
16
|
-
buttonTitle?: string;
|
|
17
|
-
connectable?: boolean;
|
|
18
|
-
hidden?: boolean;
|
|
19
|
-
id: string;
|
|
20
|
-
label: string;
|
|
21
|
-
onButtonClick?: () => void;
|
|
22
|
-
side: "left" | "right";
|
|
23
|
-
tone?: GraphNodeHandleTone;
|
|
24
|
-
type: "source" | "target";
|
|
25
|
-
validationError?: boolean;
|
|
26
|
-
validationMessage?: string;
|
|
27
|
-
variant?: "default" | "error" | "muted" | "selected" | "valid-target";
|
|
28
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../utilities/cn";
|
|
4
|
-
import { GraphNodeHandleBadge } from "./graph-node-handle-badge";
|
|
5
|
-
import type { GraphNodeHandle } from "./graph-node-handle";
|
|
6
|
-
import { GraphNodeStateIndicator } from "./graph-node-state-indicator";
|
|
7
|
-
import {
|
|
8
|
-
GRAPH_NODE_CONTENT_MIN_HEIGHT_CLASS,
|
|
9
|
-
type GraphNodeState,
|
|
10
|
-
graphNodeShellStateAttributes,
|
|
11
|
-
graphNodeShellStateClassName,
|
|
12
|
-
} from "./graph-node-state";
|
|
13
|
-
|
|
14
|
-
export interface GraphNodeShellProps
|
|
15
|
-
extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
16
|
-
children: ReactNode;
|
|
17
|
-
className?: string;
|
|
18
|
-
handles: GraphNodeHandle[];
|
|
19
|
-
nodeKind?: string;
|
|
20
|
-
showStateIndicator?: boolean;
|
|
21
|
-
state?: GraphNodeState;
|
|
22
|
-
stateLabel?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function GraphNodeShell({
|
|
26
|
-
children,
|
|
27
|
-
className = "",
|
|
28
|
-
handles,
|
|
29
|
-
nodeKind,
|
|
30
|
-
showStateIndicator = true,
|
|
31
|
-
state = "default",
|
|
32
|
-
stateLabel,
|
|
33
|
-
...articleProps
|
|
34
|
-
}: GraphNodeShellProps) {
|
|
35
|
-
const leftHandles = handles.filter((handle) => handle.side === "left");
|
|
36
|
-
const rightHandles = handles.filter((handle) => handle.side === "right");
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<article
|
|
40
|
-
className={cn(
|
|
41
|
-
"relative flex h-full min-w-0 w-full overflow-visible rounded-lg border border-outline bg-surface text-on-surface",
|
|
42
|
-
graphNodeShellStateClassName(state),
|
|
43
|
-
className,
|
|
44
|
-
)}
|
|
45
|
-
data-graph-node-kind={nodeKind}
|
|
46
|
-
{...graphNodeShellStateAttributes(state, stateLabel)}
|
|
47
|
-
{...articleProps}
|
|
48
|
-
>
|
|
49
|
-
<NodeHandleRail handles={leftHandles} side="left" />
|
|
50
|
-
<NodeHandleRail handles={rightHandles} side="right" />
|
|
51
|
-
<div
|
|
52
|
-
className={cn(
|
|
53
|
-
"flex h-full min-w-0 w-full flex-col gap-1 py-3",
|
|
54
|
-
showStateIndicator && GRAPH_NODE_CONTENT_MIN_HEIGHT_CLASS,
|
|
55
|
-
leftHandles.length > 0 ? "pl-6 pr-3" : "px-3",
|
|
56
|
-
rightHandles.length > 0 && leftHandles.length > 0
|
|
57
|
-
? "pr-6"
|
|
58
|
-
: rightHandles.length > 0
|
|
59
|
-
? "pl-3 pr-6"
|
|
60
|
-
: null,
|
|
61
|
-
)}
|
|
62
|
-
>
|
|
63
|
-
{showStateIndicator ? (
|
|
64
|
-
<GraphNodeStateIndicator state={state} stateLabel={stateLabel} />
|
|
65
|
-
) : null}
|
|
66
|
-
{children}
|
|
67
|
-
</div>
|
|
68
|
-
</article>
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function NodeHandleRail({
|
|
73
|
-
handles,
|
|
74
|
-
side,
|
|
75
|
-
}: {
|
|
76
|
-
handles: GraphNodeHandle[];
|
|
77
|
-
side: "left" | "right";
|
|
78
|
-
}) {
|
|
79
|
-
if (handles.length === 0) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return (
|
|
84
|
-
<div
|
|
85
|
-
className={cn(
|
|
86
|
-
"pointer-events-none absolute inset-y-0 z-20 w-6",
|
|
87
|
-
side === "left" ? "left-0" : "right-0",
|
|
88
|
-
)}
|
|
89
|
-
data-node-handle-rail={side}
|
|
90
|
-
>
|
|
91
|
-
{handles.map((handle, index) => (
|
|
92
|
-
<div
|
|
93
|
-
className={cn(
|
|
94
|
-
"absolute top-0 flex -translate-y-1/2",
|
|
95
|
-
side === "left"
|
|
96
|
-
? "left-0 -translate-x-1/2"
|
|
97
|
-
: "right-0 translate-x-1/2",
|
|
98
|
-
)}
|
|
99
|
-
key={handle.id}
|
|
100
|
-
style={{ top: handlePosition(index, handles.length) }}
|
|
101
|
-
>
|
|
102
|
-
<GraphNodeHandleBadge handle={handle} />
|
|
103
|
-
</div>
|
|
104
|
-
))}
|
|
105
|
-
</div>
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function handlePosition(index: number, count: number): string {
|
|
110
|
-
return `${((index + 1) * 100) / (count + 1)}%`;
|
|
111
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { cn } from "../utilities/cn";
|
|
2
|
-
import {
|
|
3
|
-
defaultGraphNodeStateLabel,
|
|
4
|
-
GRAPH_NODE_STATE_INDICATOR_HEIGHT_CLASS,
|
|
5
|
-
type GraphNodeState,
|
|
6
|
-
} from "./graph-node-state";
|
|
7
|
-
|
|
8
|
-
export interface GraphNodeStateIndicatorProps {
|
|
9
|
-
state: GraphNodeState;
|
|
10
|
-
stateLabel?: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function GraphNodeStateIndicator({
|
|
14
|
-
state,
|
|
15
|
-
stateLabel,
|
|
16
|
-
}: GraphNodeStateIndicatorProps) {
|
|
17
|
-
const label = stateLabel ?? defaultGraphNodeStateLabel(state);
|
|
18
|
-
const showIndicator = state === "loading" || state === "error";
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<div
|
|
22
|
-
aria-hidden={showIndicator ? undefined : true}
|
|
23
|
-
className={cn(
|
|
24
|
-
GRAPH_NODE_STATE_INDICATOR_HEIGHT_CLASS,
|
|
25
|
-
"flex items-center gap-2 text-[0.65rem] font-semibold uppercase tracking-[0.08em]",
|
|
26
|
-
state === "error" ? "text-on-error-container" : "text-on-surface-variant",
|
|
27
|
-
!showIndicator && "invisible",
|
|
28
|
-
)}
|
|
29
|
-
data-graph-node-state-indicator={showIndicator ? state : undefined}
|
|
30
|
-
>
|
|
31
|
-
{state === "loading" ? (
|
|
32
|
-
<>
|
|
33
|
-
<span
|
|
34
|
-
aria-hidden="true"
|
|
35
|
-
className="inline-block h-4 w-4 shrink-0 animate-spin rounded-full border-2 border-outline border-t-primary"
|
|
36
|
-
data-graph-node-loading-spinner="true"
|
|
37
|
-
/>
|
|
38
|
-
<span>{label ?? "Loading"}</span>
|
|
39
|
-
</>
|
|
40
|
-
) : state === "error" ? (
|
|
41
|
-
<span role="alert">{label ?? "Error"}</span>
|
|
42
|
-
) : (
|
|
43
|
-
<span aria-hidden="true"> </span>
|
|
44
|
-
)}
|
|
45
|
-
</div>
|
|
46
|
-
);
|
|
47
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { cn } from "../utilities/cn";
|
|
2
|
-
|
|
3
|
-
export type GraphNodeState =
|
|
4
|
-
| "default"
|
|
5
|
-
| "selected"
|
|
6
|
-
| "disabled"
|
|
7
|
-
| "loading"
|
|
8
|
-
| "error";
|
|
9
|
-
|
|
10
|
-
export const GRAPH_NODE_CONTENT_MIN_HEIGHT_CLASS = "min-h-12";
|
|
11
|
-
|
|
12
|
-
export const GRAPH_NODE_STATE_INDICATOR_HEIGHT_CLASS = "min-h-5";
|
|
13
|
-
|
|
14
|
-
export function graphNodeShellStateClassName(state: GraphNodeState): string {
|
|
15
|
-
switch (state) {
|
|
16
|
-
case "selected":
|
|
17
|
-
return cn(
|
|
18
|
-
"border-2 border-primary bg-primary-container",
|
|
19
|
-
"shadow-[0_0_0_1px_rgb(from_var(--color-primary)_r_g_b_/_0.28),0_0_0_4px_rgb(from_var(--color-primary)_r_g_b_/_0.08)]",
|
|
20
|
-
);
|
|
21
|
-
case "error":
|
|
22
|
-
return cn(
|
|
23
|
-
"border-2 border-dashed border-error bg-error-container",
|
|
24
|
-
"shadow-[0_0_0_3px_var(--color-error-container)]",
|
|
25
|
-
);
|
|
26
|
-
case "disabled":
|
|
27
|
-
return "border-outline-variant bg-surface-container text-on-surface";
|
|
28
|
-
case "loading":
|
|
29
|
-
return "border-outline bg-surface";
|
|
30
|
-
default:
|
|
31
|
-
return "";
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function graphNodeButtonStateClassName(state: GraphNodeState): string {
|
|
36
|
-
switch (state) {
|
|
37
|
-
case "selected":
|
|
38
|
-
return "ring-2 ring-primary/30";
|
|
39
|
-
case "error":
|
|
40
|
-
return "ring-2 ring-error/40";
|
|
41
|
-
case "disabled":
|
|
42
|
-
case "loading":
|
|
43
|
-
return "cursor-not-allowed";
|
|
44
|
-
default:
|
|
45
|
-
return "";
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function graphNodeShellStateAttributes(
|
|
50
|
-
state: GraphNodeState,
|
|
51
|
-
stateLabel?: string,
|
|
52
|
-
): {
|
|
53
|
-
"aria-busy"?: boolean;
|
|
54
|
-
"aria-disabled"?: boolean;
|
|
55
|
-
"aria-invalid"?: boolean;
|
|
56
|
-
"aria-label"?: string;
|
|
57
|
-
"aria-selected"?: boolean;
|
|
58
|
-
"data-graph-node-state"?: GraphNodeState;
|
|
59
|
-
} {
|
|
60
|
-
return {
|
|
61
|
-
"aria-busy": state === "loading" ? true : undefined,
|
|
62
|
-
"aria-disabled": state === "disabled" ? true : undefined,
|
|
63
|
-
"aria-invalid": state === "error" ? true : undefined,
|
|
64
|
-
"aria-label": stateLabel,
|
|
65
|
-
"aria-selected": state === "selected" ? true : undefined,
|
|
66
|
-
"data-graph-node-state": state === "default" ? undefined : state,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function graphNodeButtonStateAttributes(
|
|
71
|
-
state: GraphNodeState,
|
|
72
|
-
stateLabel?: string,
|
|
73
|
-
): {
|
|
74
|
-
"aria-busy"?: boolean;
|
|
75
|
-
"aria-disabled"?: boolean;
|
|
76
|
-
"aria-invalid"?: boolean;
|
|
77
|
-
"aria-label"?: string;
|
|
78
|
-
"aria-pressed"?: boolean;
|
|
79
|
-
"data-graph-node-state"?: GraphNodeState;
|
|
80
|
-
} {
|
|
81
|
-
return {
|
|
82
|
-
"aria-busy": state === "loading" ? true : undefined,
|
|
83
|
-
"aria-disabled": state === "disabled" ? true : undefined,
|
|
84
|
-
"aria-invalid": state === "error" ? true : undefined,
|
|
85
|
-
"aria-label": stateLabel,
|
|
86
|
-
"aria-pressed": state === "selected" ? true : undefined,
|
|
87
|
-
"data-graph-node-state": state === "default" ? undefined : state,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function graphNodeButtonIsDisabled(
|
|
92
|
-
state: GraphNodeState,
|
|
93
|
-
disabled?: boolean,
|
|
94
|
-
): boolean {
|
|
95
|
-
return disabled === true || state === "disabled" || state === "loading";
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export function defaultGraphNodeStateLabel(state: GraphNodeState): string | undefined {
|
|
99
|
-
switch (state) {
|
|
100
|
-
case "selected":
|
|
101
|
-
return "Selected node";
|
|
102
|
-
case "disabled":
|
|
103
|
-
return "Disabled node";
|
|
104
|
-
case "loading":
|
|
105
|
-
return "Loading node";
|
|
106
|
-
case "error":
|
|
107
|
-
return "Error node";
|
|
108
|
-
default:
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { forwardRef, type HTMLAttributes, type ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../utilities/cn";
|
|
4
|
-
|
|
5
|
-
export interface GraphViewportSurfaceProps extends HTMLAttributes<HTMLElement> {
|
|
6
|
-
children: ReactNode;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const GraphViewportSurface = forwardRef<
|
|
10
|
-
HTMLElement,
|
|
11
|
-
GraphViewportSurfaceProps
|
|
12
|
-
>(function GraphViewportSurface({ children, className, role, ...props }, ref) {
|
|
13
|
-
return (
|
|
14
|
-
<section
|
|
15
|
-
className={cn(
|
|
16
|
-
"relative min-h-0 overflow-hidden rounded-3xl border shadow-none transition-colors",
|
|
17
|
-
className,
|
|
18
|
-
)}
|
|
19
|
-
data-graph-viewport-surface="true"
|
|
20
|
-
ref={ref}
|
|
21
|
-
role={role ?? "region"}
|
|
22
|
-
{...props}
|
|
23
|
-
>
|
|
24
|
-
{children}
|
|
25
|
-
</section>
|
|
26
|
-
);
|
|
27
|
-
});
|