@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,209 +0,0 @@
|
|
|
1
|
-
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
2
|
-
import {
|
|
3
|
-
type ComponentProps,
|
|
4
|
-
type ComponentRef,
|
|
5
|
-
forwardRef,
|
|
6
|
-
type ReactNode,
|
|
7
|
-
} from "react";
|
|
8
|
-
|
|
9
|
-
import { cn } from "../utilities/cn";
|
|
10
|
-
import { inputVariants } from "./package-input";
|
|
11
|
-
import { SelectCheckIcon, SelectChevronDownIcon } from "./select-icons";
|
|
12
|
-
|
|
13
|
-
export const Select = SelectPrimitive.Root;
|
|
14
|
-
export const SelectGroup = SelectPrimitive.Group;
|
|
15
|
-
export const SelectValue = SelectPrimitive.Value;
|
|
16
|
-
|
|
17
|
-
export type SelectTriggerProps = ComponentProps<typeof SelectPrimitive.Trigger>;
|
|
18
|
-
|
|
19
|
-
export const SelectTrigger = forwardRef<
|
|
20
|
-
ComponentRef<typeof SelectPrimitive.Trigger>,
|
|
21
|
-
SelectTriggerProps
|
|
22
|
-
>(function SelectTrigger({ className, children, ...props }, ref) {
|
|
23
|
-
return (
|
|
24
|
-
<SelectPrimitive.Trigger
|
|
25
|
-
className={cn(
|
|
26
|
-
inputVariants({
|
|
27
|
-
className:
|
|
28
|
-
"flex items-center justify-between gap-2 text-left data-[placeholder]:text-on-surface-disabled [&>span]:line-clamp-1",
|
|
29
|
-
}),
|
|
30
|
-
className,
|
|
31
|
-
)}
|
|
32
|
-
ref={ref}
|
|
33
|
-
{...props}
|
|
34
|
-
>
|
|
35
|
-
{children}
|
|
36
|
-
<SelectPrimitive.Icon asChild>
|
|
37
|
-
<SelectChevronDownIcon className="h-4 w-4 shrink-0 text-af-text-subtle" />
|
|
38
|
-
</SelectPrimitive.Icon>
|
|
39
|
-
</SelectPrimitive.Trigger>
|
|
40
|
-
);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
export type SelectContentProps = ComponentProps<typeof SelectPrimitive.Content>;
|
|
44
|
-
|
|
45
|
-
// tailwind-exception: intrinsic-sizing
|
|
46
|
-
const SELECT_CONTENT_POPPER_CLASS = "min-w-[var(--radix-select-trigger-width)]";
|
|
47
|
-
// tailwind-exception: intrinsic-sizing
|
|
48
|
-
const SELECT_VIEWPORT_POPPER_CLASS =
|
|
49
|
-
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]";
|
|
50
|
-
|
|
51
|
-
export function SelectContent({
|
|
52
|
-
children,
|
|
53
|
-
className,
|
|
54
|
-
onCloseAutoFocus,
|
|
55
|
-
position = "popper",
|
|
56
|
-
...props
|
|
57
|
-
}: SelectContentProps) {
|
|
58
|
-
return (
|
|
59
|
-
<SelectPrimitive.Portal>
|
|
60
|
-
<SelectPrimitive.Content
|
|
61
|
-
className={cn(
|
|
62
|
-
"relative z-50 max-h-72 overflow-hidden rounded-xl border border-outline bg-surface-container-high text-on-surface shadow-af-panel data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
63
|
-
position === "popper" && SELECT_CONTENT_POPPER_CLASS,
|
|
64
|
-
position === "popper" &&
|
|
65
|
-
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
66
|
-
className,
|
|
67
|
-
)}
|
|
68
|
-
onCloseAutoFocus={onCloseAutoFocus}
|
|
69
|
-
position={position}
|
|
70
|
-
{...props}
|
|
71
|
-
>
|
|
72
|
-
<SelectPrimitive.Viewport
|
|
73
|
-
className={cn(
|
|
74
|
-
"p-1",
|
|
75
|
-
position === "popper" && SELECT_VIEWPORT_POPPER_CLASS,
|
|
76
|
-
)}
|
|
77
|
-
>
|
|
78
|
-
{children}
|
|
79
|
-
</SelectPrimitive.Viewport>
|
|
80
|
-
</SelectPrimitive.Content>
|
|
81
|
-
</SelectPrimitive.Portal>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export type SelectLabelProps = ComponentProps<typeof SelectPrimitive.Label>;
|
|
86
|
-
|
|
87
|
-
export function SelectLabel({ className, ...props }: SelectLabelProps) {
|
|
88
|
-
return (
|
|
89
|
-
<SelectPrimitive.Label
|
|
90
|
-
className={cn(
|
|
91
|
-
"px-2 py-1.5 text-xs font-semibold uppercase tracking-[0.08em] text-on-surface-subtle",
|
|
92
|
-
className,
|
|
93
|
-
)}
|
|
94
|
-
{...props}
|
|
95
|
-
/>
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export const SELECT_EMPTY_STATE_VALUE = "__select-empty-state__";
|
|
100
|
-
|
|
101
|
-
export type SelectItemProps = ComponentProps<typeof SelectPrimitive.Item>;
|
|
102
|
-
|
|
103
|
-
export const SelectItem = forwardRef<
|
|
104
|
-
ComponentRef<typeof SelectPrimitive.Item>,
|
|
105
|
-
SelectItemProps
|
|
106
|
-
>(function SelectItem({ children, className, ...props }, ref) {
|
|
107
|
-
return (
|
|
108
|
-
<SelectPrimitive.Item
|
|
109
|
-
className={cn(
|
|
110
|
-
"relative flex w-full min-w-0 cursor-default select-none items-center rounded-lg py-2 pl-8 pr-2 text-sm outline-none focus:bg-surface-container-highest data-[disabled]:pointer-events-none data-[disabled]:text-on-surface-disabled data-[highlighted]:bg-surface-container-highest",
|
|
111
|
-
className,
|
|
112
|
-
)}
|
|
113
|
-
ref={ref}
|
|
114
|
-
{...props}
|
|
115
|
-
>
|
|
116
|
-
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
117
|
-
<SelectPrimitive.ItemIndicator>
|
|
118
|
-
<SelectCheckIcon className="h-4 w-4" />
|
|
119
|
-
</SelectPrimitive.ItemIndicator>
|
|
120
|
-
</span>
|
|
121
|
-
<SelectPrimitive.ItemText className="line-clamp-2 break-words">
|
|
122
|
-
{children}
|
|
123
|
-
</SelectPrimitive.ItemText>
|
|
124
|
-
</SelectPrimitive.Item>
|
|
125
|
-
);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
export type SelectEmptyProps = {
|
|
129
|
-
children: ReactNode;
|
|
130
|
-
className?: string;
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
export function SelectEmpty({ children, className }: SelectEmptyProps) {
|
|
134
|
-
return (
|
|
135
|
-
<SelectPrimitive.Item
|
|
136
|
-
className={cn(
|
|
137
|
-
"relative flex w-full min-w-0 cursor-default select-none items-center rounded-lg px-2 py-2 text-sm text-on-surface-disabled data-[disabled]:pointer-events-none data-[disabled]:text-on-surface-disabled",
|
|
138
|
-
className,
|
|
139
|
-
)}
|
|
140
|
-
disabled
|
|
141
|
-
value={SELECT_EMPTY_STATE_VALUE}
|
|
142
|
-
>
|
|
143
|
-
<SelectPrimitive.ItemText className="line-clamp-2 break-words">
|
|
144
|
-
{children}
|
|
145
|
-
</SelectPrimitive.ItemText>
|
|
146
|
-
</SelectPrimitive.Item>
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export type SelectSeparatorProps = ComponentProps<
|
|
151
|
-
typeof SelectPrimitive.Separator
|
|
152
|
-
>;
|
|
153
|
-
|
|
154
|
-
export function SelectSeparator({ className, ...props }: SelectSeparatorProps) {
|
|
155
|
-
return (
|
|
156
|
-
<SelectPrimitive.Separator
|
|
157
|
-
className={cn("-mx-1 my-1 h-px bg-outline", className)}
|
|
158
|
-
{...props}
|
|
159
|
-
/>
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export interface SelectFieldProps {
|
|
164
|
-
children: ReactNode;
|
|
165
|
-
className?: string;
|
|
166
|
-
description?: ReactNode;
|
|
167
|
-
descriptionId?: string;
|
|
168
|
-
error?: ReactNode;
|
|
169
|
-
errorId?: string;
|
|
170
|
-
inputId: string;
|
|
171
|
-
label: ReactNode;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export function SelectField({
|
|
175
|
-
children,
|
|
176
|
-
className,
|
|
177
|
-
description,
|
|
178
|
-
descriptionId,
|
|
179
|
-
error,
|
|
180
|
-
errorId,
|
|
181
|
-
inputId,
|
|
182
|
-
label,
|
|
183
|
-
}: SelectFieldProps) {
|
|
184
|
-
return (
|
|
185
|
-
<div className={cn("grid gap-2", className)}>
|
|
186
|
-
<label
|
|
187
|
-
className="text-xs font-bold uppercase tracking-[0.08em] text-af-text-subtle"
|
|
188
|
-
htmlFor={inputId}
|
|
189
|
-
>
|
|
190
|
-
{label}
|
|
191
|
-
</label>
|
|
192
|
-
{children}
|
|
193
|
-
{description ? (
|
|
194
|
-
<p className="m-0 text-sm text-af-text-muted" id={descriptionId}>
|
|
195
|
-
{description}
|
|
196
|
-
</p>
|
|
197
|
-
) : null}
|
|
198
|
-
{error ? (
|
|
199
|
-
<p
|
|
200
|
-
className="m-0 text-sm font-medium text-on-error-container"
|
|
201
|
-
id={errorId}
|
|
202
|
-
role="alert"
|
|
203
|
-
>
|
|
204
|
-
{error}
|
|
205
|
-
</p>
|
|
206
|
-
) : null}
|
|
207
|
-
</div>
|
|
208
|
-
);
|
|
209
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { forwardRef, type TextareaHTMLAttributes } from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../utilities/cn";
|
|
4
|
-
import { inputVariants } from "./package-input";
|
|
5
|
-
|
|
6
|
-
const TEXTAREA_PLAIN_CLASS =
|
|
7
|
-
"m-0 w-full resize-none border-0 bg-transparent p-0 text-sm leading-6 text-on-surface outline-none";
|
|
8
|
-
|
|
9
|
-
const TEXTAREA_FIELD_CLASS =
|
|
10
|
-
"min-h-28 max-h-52 resize-none overflow-y-auto py-3";
|
|
11
|
-
|
|
12
|
-
export type PackageTextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & {
|
|
13
|
-
variant?: "field" | "plain";
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export function textareaVariants({ className }: { className?: string } = {}) {
|
|
17
|
-
return inputVariants({ className: cn(TEXTAREA_FIELD_CLASS, className) });
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const PackageTextarea = forwardRef<
|
|
21
|
-
HTMLTextAreaElement,
|
|
22
|
-
PackageTextareaProps
|
|
23
|
-
>(function PackageTextarea({ className, variant = "field", ...props }, ref) {
|
|
24
|
-
return (
|
|
25
|
-
<textarea
|
|
26
|
-
className={
|
|
27
|
-
variant === "plain"
|
|
28
|
-
? cn(TEXTAREA_PLAIN_CLASS, className)
|
|
29
|
-
: textareaVariants({ className })
|
|
30
|
-
}
|
|
31
|
-
ref={ref}
|
|
32
|
-
{...props}
|
|
33
|
-
/>
|
|
34
|
-
);
|
|
35
|
-
});
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { SVGProps } from "react";
|
|
2
|
-
|
|
3
|
-
export function SelectChevronDownIcon(props: SVGProps<SVGSVGElement>) {
|
|
4
|
-
return (
|
|
5
|
-
<svg
|
|
6
|
-
aria-hidden="true"
|
|
7
|
-
fill="none"
|
|
8
|
-
stroke="currentColor"
|
|
9
|
-
strokeLinecap="round"
|
|
10
|
-
strokeLinejoin="round"
|
|
11
|
-
strokeWidth={1.8}
|
|
12
|
-
viewBox="0 0 24 24"
|
|
13
|
-
{...props}
|
|
14
|
-
>
|
|
15
|
-
<path d="m6 9 6 6 6-6" />
|
|
16
|
-
</svg>
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function SelectCheckIcon(props: SVGProps<SVGSVGElement>) {
|
|
21
|
-
return (
|
|
22
|
-
<svg
|
|
23
|
-
aria-hidden="true"
|
|
24
|
-
fill="none"
|
|
25
|
-
stroke="currentColor"
|
|
26
|
-
strokeLinecap="round"
|
|
27
|
-
strokeLinejoin="round"
|
|
28
|
-
strokeWidth={2}
|
|
29
|
-
viewBox="0 0 24 24"
|
|
30
|
-
{...props}
|
|
31
|
-
>
|
|
32
|
-
<path d="M20 6 9 17l-5-5" />
|
|
33
|
-
</svg>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import { getBezierPath, Position } from "@xyflow/react";
|
|
2
|
-
|
|
3
|
-
export type GraphEdgeWaypoint = {
|
|
4
|
-
x: number;
|
|
5
|
-
y: number;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const CATMULL_ROM_ALPHA = 0.5;
|
|
9
|
-
const MIN_PARAMETER_DISTANCE = 0.0001;
|
|
10
|
-
const VIRTUAL_ENDPOINT_DISTANCE = 96;
|
|
11
|
-
|
|
12
|
-
function positionVector(position: Position): GraphEdgeWaypoint {
|
|
13
|
-
switch (position) {
|
|
14
|
-
case Position.Left:
|
|
15
|
-
return { x: -1, y: 0 };
|
|
16
|
-
case Position.Right:
|
|
17
|
-
return { x: 1, y: 0 };
|
|
18
|
-
case Position.Top:
|
|
19
|
-
return { x: 0, y: -1 };
|
|
20
|
-
case Position.Bottom:
|
|
21
|
-
return { x: 0, y: 1 };
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function pointDistance(
|
|
26
|
-
first: GraphEdgeWaypoint,
|
|
27
|
-
second: GraphEdgeWaypoint,
|
|
28
|
-
): number {
|
|
29
|
-
return Math.hypot(second.x - first.x, second.y - first.y);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function catmullRomParameterDistance(
|
|
33
|
-
first: GraphEdgeWaypoint,
|
|
34
|
-
second: GraphEdgeWaypoint,
|
|
35
|
-
): number {
|
|
36
|
-
return Math.max(
|
|
37
|
-
MIN_PARAMETER_DISTANCE,
|
|
38
|
-
pointDistance(first, second) ** CATMULL_ROM_ALPHA,
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function formatPathNumber(value: number): string {
|
|
43
|
-
if (Object.is(value, -0)) {
|
|
44
|
-
return "0";
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return Number.isInteger(value) ? `${value}` : value.toFixed(3);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function compactConsecutiveRoutePoints(
|
|
51
|
-
routePoints: readonly GraphEdgeWaypoint[],
|
|
52
|
-
): GraphEdgeWaypoint[] {
|
|
53
|
-
const compacted: GraphEdgeWaypoint[] = [];
|
|
54
|
-
|
|
55
|
-
for (const point of routePoints) {
|
|
56
|
-
const previous = compacted.at(-1);
|
|
57
|
-
if (previous && previous.x === point.x && previous.y === point.y) {
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
compacted.push(point);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return compacted;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function virtualEndpoint(input: {
|
|
68
|
-
direction: GraphEdgeWaypoint;
|
|
69
|
-
from: GraphEdgeWaypoint;
|
|
70
|
-
mode: "after" | "before";
|
|
71
|
-
neighbor: GraphEdgeWaypoint;
|
|
72
|
-
}): GraphEdgeWaypoint {
|
|
73
|
-
const distance = Math.max(
|
|
74
|
-
VIRTUAL_ENDPOINT_DISTANCE,
|
|
75
|
-
pointDistance(input.from, input.neighbor),
|
|
76
|
-
);
|
|
77
|
-
const scalar = input.mode === "before" ? -distance : distance;
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
x: input.from.x + input.direction.x * scalar,
|
|
81
|
-
y: input.from.y + input.direction.y * scalar,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function catmullRomTangent(input: {
|
|
86
|
-
current: GraphEdgeWaypoint;
|
|
87
|
-
next: GraphEdgeWaypoint;
|
|
88
|
-
previous: GraphEdgeWaypoint;
|
|
89
|
-
tCurrent: number;
|
|
90
|
-
tNext: number;
|
|
91
|
-
tPrevious: number;
|
|
92
|
-
}): GraphEdgeWaypoint {
|
|
93
|
-
const previousSpan = input.tCurrent - input.tPrevious;
|
|
94
|
-
const nextSpan = input.tNext - input.tCurrent;
|
|
95
|
-
const totalSpan = input.tNext - input.tPrevious;
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
x:
|
|
99
|
-
nextSpan *
|
|
100
|
-
((input.current.x - input.previous.x) / previousSpan -
|
|
101
|
-
(input.next.x - input.previous.x) / totalSpan +
|
|
102
|
-
(input.next.x - input.current.x) / nextSpan),
|
|
103
|
-
y:
|
|
104
|
-
nextSpan *
|
|
105
|
-
((input.current.y - input.previous.y) / previousSpan -
|
|
106
|
-
(input.next.y - input.previous.y) / totalSpan +
|
|
107
|
-
(input.next.y - input.current.y) / nextSpan),
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function buildWaypointCatmullRomPath(input: {
|
|
112
|
-
routePoints: readonly GraphEdgeWaypoint[];
|
|
113
|
-
sourcePosition: Position;
|
|
114
|
-
targetPosition: Position;
|
|
115
|
-
}): string {
|
|
116
|
-
const routePoints = compactConsecutiveRoutePoints(input.routePoints);
|
|
117
|
-
if (routePoints.length <= 1) {
|
|
118
|
-
const [point] = routePoints;
|
|
119
|
-
return point
|
|
120
|
-
? `M ${formatPathNumber(point.x)} ${formatPathNumber(point.y)}`
|
|
121
|
-
: "";
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const lastPointIndex = routePoints.length - 1;
|
|
125
|
-
const [source] = routePoints;
|
|
126
|
-
const points = [
|
|
127
|
-
virtualEndpoint({
|
|
128
|
-
direction: positionVector(input.sourcePosition),
|
|
129
|
-
from: source,
|
|
130
|
-
mode: "before",
|
|
131
|
-
neighbor: routePoints[1],
|
|
132
|
-
}),
|
|
133
|
-
...routePoints,
|
|
134
|
-
virtualEndpoint({
|
|
135
|
-
direction: {
|
|
136
|
-
x: -positionVector(input.targetPosition).x,
|
|
137
|
-
y: -positionVector(input.targetPosition).y,
|
|
138
|
-
},
|
|
139
|
-
from: routePoints[lastPointIndex],
|
|
140
|
-
mode: "after",
|
|
141
|
-
neighbor: routePoints[lastPointIndex - 1],
|
|
142
|
-
}),
|
|
143
|
-
];
|
|
144
|
-
const segments = [
|
|
145
|
-
`M ${formatPathNumber(source.x)} ${formatPathNumber(source.y)}`,
|
|
146
|
-
];
|
|
147
|
-
|
|
148
|
-
for (let index = 1; index <= lastPointIndex; index += 1) {
|
|
149
|
-
const previous = points[index - 1];
|
|
150
|
-
const start = points[index];
|
|
151
|
-
const end = points[index + 1];
|
|
152
|
-
const next = points[index + 2];
|
|
153
|
-
const tPrevious = 0;
|
|
154
|
-
const tStart = tPrevious + catmullRomParameterDistance(previous, start);
|
|
155
|
-
const tEnd = tStart + catmullRomParameterDistance(start, end);
|
|
156
|
-
const tNext = tEnd + catmullRomParameterDistance(end, next);
|
|
157
|
-
const startTangent = catmullRomTangent({
|
|
158
|
-
current: start,
|
|
159
|
-
next: end,
|
|
160
|
-
previous,
|
|
161
|
-
tCurrent: tStart,
|
|
162
|
-
tNext: tEnd,
|
|
163
|
-
tPrevious,
|
|
164
|
-
});
|
|
165
|
-
const endTangent = catmullRomTangent({
|
|
166
|
-
current: end,
|
|
167
|
-
next,
|
|
168
|
-
previous: start,
|
|
169
|
-
tCurrent: tEnd,
|
|
170
|
-
tNext,
|
|
171
|
-
tPrevious: tStart,
|
|
172
|
-
});
|
|
173
|
-
const firstControl = {
|
|
174
|
-
x: start.x + startTangent.x / 3,
|
|
175
|
-
y: start.y + startTangent.y / 3,
|
|
176
|
-
};
|
|
177
|
-
const secondControl = {
|
|
178
|
-
x: end.x - endTangent.x / 3,
|
|
179
|
-
y: end.y - endTangent.y / 3,
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
segments.push(
|
|
183
|
-
[
|
|
184
|
-
"C",
|
|
185
|
-
formatPathNumber(firstControl.x),
|
|
186
|
-
formatPathNumber(firstControl.y),
|
|
187
|
-
`${formatPathNumber(secondControl.x)},`,
|
|
188
|
-
formatPathNumber(secondControl.y),
|
|
189
|
-
`${formatPathNumber(end.x)},`,
|
|
190
|
-
formatPathNumber(end.y),
|
|
191
|
-
].join(" "),
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return segments.join(" ");
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export function buildGraphEdgePathThroughWaypoints(input: {
|
|
199
|
-
sourceX: number;
|
|
200
|
-
sourceY: number;
|
|
201
|
-
sourcePosition: Position;
|
|
202
|
-
targetX: number;
|
|
203
|
-
targetY: number;
|
|
204
|
-
targetPosition: Position;
|
|
205
|
-
waypoints?: readonly GraphEdgeWaypoint[];
|
|
206
|
-
}): {
|
|
207
|
-
labelX: number;
|
|
208
|
-
labelY: number;
|
|
209
|
-
path: string;
|
|
210
|
-
} {
|
|
211
|
-
const routePoints = [
|
|
212
|
-
{ x: input.sourceX, y: input.sourceY },
|
|
213
|
-
...(input.waypoints ?? []),
|
|
214
|
-
{ x: input.targetX, y: input.targetY },
|
|
215
|
-
];
|
|
216
|
-
|
|
217
|
-
if (routePoints.length <= 2) {
|
|
218
|
-
const [path, labelX, labelY] = getBezierPath({
|
|
219
|
-
sourcePosition: input.sourcePosition,
|
|
220
|
-
sourceX: input.sourceX,
|
|
221
|
-
sourceY: input.sourceY,
|
|
222
|
-
targetPosition: input.targetPosition,
|
|
223
|
-
targetX: input.targetX,
|
|
224
|
-
targetY: input.targetY,
|
|
225
|
-
});
|
|
226
|
-
return { labelX, labelY, path };
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const path = buildWaypointCatmullRomPath({
|
|
230
|
-
routePoints,
|
|
231
|
-
sourcePosition: input.sourcePosition,
|
|
232
|
-
targetPosition: input.targetPosition,
|
|
233
|
-
});
|
|
234
|
-
const midpointIndex = Math.floor((routePoints.length - 1) / 2);
|
|
235
|
-
const labelPoint = routePoints[midpointIndex];
|
|
236
|
-
return {
|
|
237
|
-
labelX: labelPoint.x,
|
|
238
|
-
labelY: labelPoint.y,
|
|
239
|
-
path,
|
|
240
|
-
};
|
|
241
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { BaseEdge, type EdgeProps, getBezierPath } from "@xyflow/react";
|
|
2
|
-
import { useEffect, useRef, useState } from "react";
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
buildGraphEdgePathThroughWaypoints,
|
|
6
|
-
type GraphEdgeWaypoint,
|
|
7
|
-
} from "./graph-edge-path";
|
|
8
|
-
|
|
9
|
-
export type GraphEdgeData = {
|
|
10
|
-
alwaysShowLabel?: boolean;
|
|
11
|
-
label?: string;
|
|
12
|
-
waypoints?: GraphEdgeWaypoint[];
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const GRAPH_EDGE_TYPES = {
|
|
16
|
-
graphEdge: GraphEdge,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type GraphEdgeProps = EdgeProps & {
|
|
20
|
-
edgeClassName?: string;
|
|
21
|
-
labelClassName?: string;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export function GraphEdge({
|
|
25
|
-
data,
|
|
26
|
-
edgeClassName = "graph-edge",
|
|
27
|
-
id,
|
|
28
|
-
interactionWidth,
|
|
29
|
-
labelClassName = "graph-edge-label pointer-events-none fill-on-surface-subtle text-[11px] font-semibold",
|
|
30
|
-
markerEnd,
|
|
31
|
-
selected,
|
|
32
|
-
sourcePosition,
|
|
33
|
-
sourceX,
|
|
34
|
-
sourceY,
|
|
35
|
-
style,
|
|
36
|
-
targetPosition,
|
|
37
|
-
targetX,
|
|
38
|
-
targetY,
|
|
39
|
-
}: GraphEdgeProps) {
|
|
40
|
-
const edgeRef = useRef<SVGGElement | null>(null);
|
|
41
|
-
const [inspected, setInspected] = useState(false);
|
|
42
|
-
const edgeData = (data ?? {}) as GraphEdgeData;
|
|
43
|
-
const routedPath = buildGraphEdgePathThroughWaypoints({
|
|
44
|
-
sourcePosition,
|
|
45
|
-
sourceX,
|
|
46
|
-
sourceY,
|
|
47
|
-
targetPosition,
|
|
48
|
-
targetX,
|
|
49
|
-
targetY,
|
|
50
|
-
waypoints: edgeData.waypoints,
|
|
51
|
-
});
|
|
52
|
-
const [fallbackPath, fallbackLabelX, fallbackLabelY] = getBezierPath({
|
|
53
|
-
sourcePosition,
|
|
54
|
-
sourceX,
|
|
55
|
-
sourceY,
|
|
56
|
-
targetPosition,
|
|
57
|
-
targetX,
|
|
58
|
-
targetY,
|
|
59
|
-
});
|
|
60
|
-
const edgePath =
|
|
61
|
-
edgeData.waypoints && edgeData.waypoints.length > 0
|
|
62
|
-
? routedPath.path
|
|
63
|
-
: fallbackPath;
|
|
64
|
-
const labelX =
|
|
65
|
-
edgeData.waypoints && edgeData.waypoints.length > 0
|
|
66
|
-
? routedPath.labelX
|
|
67
|
-
: fallbackLabelX;
|
|
68
|
-
const labelY =
|
|
69
|
-
edgeData.waypoints && edgeData.waypoints.length > 0
|
|
70
|
-
? routedPath.labelY
|
|
71
|
-
: fallbackLabelY;
|
|
72
|
-
|
|
73
|
-
useEffect(() => {
|
|
74
|
-
const edgeElement = edgeRef.current?.parentElement;
|
|
75
|
-
if (!edgeElement) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const show = () => setInspected(true);
|
|
80
|
-
const hide = () => setInspected(false);
|
|
81
|
-
|
|
82
|
-
edgeElement.addEventListener("mouseenter", show);
|
|
83
|
-
edgeElement.addEventListener("mouseleave", hide);
|
|
84
|
-
edgeElement.addEventListener("focusin", show);
|
|
85
|
-
edgeElement.addEventListener("focusout", hide);
|
|
86
|
-
|
|
87
|
-
return () => {
|
|
88
|
-
edgeElement.removeEventListener("mouseenter", show);
|
|
89
|
-
edgeElement.removeEventListener("mouseleave", hide);
|
|
90
|
-
edgeElement.removeEventListener("focusin", show);
|
|
91
|
-
edgeElement.removeEventListener("focusout", hide);
|
|
92
|
-
};
|
|
93
|
-
}, []);
|
|
94
|
-
|
|
95
|
-
const revealLabel = Boolean(
|
|
96
|
-
edgeData.label && (edgeData.alwaysShowLabel || inspected || selected),
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<g
|
|
101
|
-
className={edgeClassName}
|
|
102
|
-
data-edge-id={id}
|
|
103
|
-
data-label-visible={revealLabel ? "true" : "false"}
|
|
104
|
-
ref={edgeRef}
|
|
105
|
-
>
|
|
106
|
-
<BaseEdge
|
|
107
|
-
interactionWidth={interactionWidth}
|
|
108
|
-
markerEnd={markerEnd}
|
|
109
|
-
path={edgePath}
|
|
110
|
-
style={style}
|
|
111
|
-
/>
|
|
112
|
-
{edgeData.label ? (
|
|
113
|
-
<text
|
|
114
|
-
className={labelClassName}
|
|
115
|
-
style={{
|
|
116
|
-
paintOrder: "stroke",
|
|
117
|
-
stroke: "var(--color-surface)",
|
|
118
|
-
strokeLinejoin: "round",
|
|
119
|
-
strokeWidth: 8,
|
|
120
|
-
}}
|
|
121
|
-
textAnchor="middle"
|
|
122
|
-
x={labelX}
|
|
123
|
-
y={labelY}
|
|
124
|
-
>
|
|
125
|
-
{edgeData.label}
|
|
126
|
-
</text>
|
|
127
|
-
) : null}
|
|
128
|
-
</g>
|
|
129
|
-
);
|
|
130
|
-
}
|