@hex-core/components 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_tsup-dts-rollup.d.ts +3556 -0
- package/dist/accordion.d.ts +4 -13
- package/dist/alert-dialog.d.ts +11 -34
- package/dist/alert.d.ts +4 -17
- package/dist/aspect-ratio.d.ts +1 -7
- package/dist/attachment.d.ts +4 -0
- package/dist/attachment.js +157 -0
- package/dist/attachment.js.map +1 -0
- package/dist/avatar.d.ts +3 -11
- package/dist/badge.d.ts +3 -22
- package/dist/breadcrumb.d.ts +7 -27
- package/dist/button.d.ts +3 -13
- package/dist/calendar.d.ts +1 -17
- package/dist/card.d.ts +6 -16
- package/dist/checkbox.d.ts +2 -11
- package/dist/citation.d.ts +2 -0
- package/dist/citation.js +70 -0
- package/dist/citation.js.map +1 -0
- package/dist/cluster.d.ts +3 -34
- package/dist/code-block-copy.d.ts +2 -0
- package/dist/code-block-copy.js +108 -0
- package/dist/code-block-copy.js.map +1 -0
- package/dist/code-block.d.ts +3 -0
- package/dist/code-block.js +90 -0
- package/dist/code-block.js.map +1 -0
- package/dist/collapsible.d.ts +3 -11
- package/dist/color-picker.d.ts +2 -44
- package/dist/combobox.d.ts +3 -45
- package/dist/command.d.ts +9 -111
- package/dist/composer.d.ts +2 -0
- package/dist/composer.js +75 -0
- package/dist/composer.js.map +1 -0
- package/dist/container.d.ts +3 -41
- package/dist/context-menu.d.ts +12 -37
- package/dist/data-table.d.ts +2 -33
- package/dist/date-picker.d.ts +2 -43
- package/dist/dialog.d.ts +11 -46
- package/dist/drawer.d.ts +10 -41
- package/dist/dropdown-menu.d.ts +13 -39
- package/dist/dropzone.d.ts +3 -54
- package/dist/dropzone.js +46 -44
- package/dist/dropzone.js.map +1 -1
- package/dist/empty.d.ts +3 -0
- package/dist/empty.js +94 -0
- package/dist/empty.js.map +1 -0
- package/dist/error-state.d.ts +3 -0
- package/dist/error-state.js +67 -0
- package/dist/error-state.js.map +1 -0
- package/dist/file-tree.d.ts +3 -53
- package/dist/form.d.ts +8 -45
- package/dist/grid.d.ts +3 -50
- package/dist/hover-card.d.ts +3 -11
- package/dist/index.d.ts +325 -179
- package/dist/index.js +1592 -122
- package/dist/index.js.map +1 -1
- package/dist/input-otp.d.ts +5 -19
- package/dist/input.d.ts +2 -6
- package/dist/label.d.ts +2 -11
- package/dist/loading-indicator.d.ts +3 -0
- package/dist/loading-indicator.js +64 -0
- package/dist/loading-indicator.js.map +1 -0
- package/dist/loading.d.ts +3 -0
- package/dist/loading.js +80 -0
- package/dist/loading.js.map +1 -0
- package/dist/markdown.d.ts +2 -0
- package/dist/markdown.js +28 -0
- package/dist/markdown.js.map +1 -0
- package/dist/menubar.d.ts +11 -35
- package/dist/message-actions.d.ts +2 -0
- package/dist/message-actions.js +28 -0
- package/dist/message-actions.js.map +1 -0
- package/dist/message-list.d.ts +2 -0
- package/dist/message-list.js +49 -0
- package/dist/message-list.js.map +1 -0
- package/dist/message.d.ts +3 -0
- package/dist/message.js +35 -0
- package/dist/message.js.map +1 -0
- package/dist/multi-combobox.d.ts +3 -51
- package/dist/navigation-menu.d.ts +9 -23
- package/dist/pagination.d.ts +7 -40
- package/dist/popover.d.ts +4 -13
- package/dist/progress.d.ts +1 -10
- package/dist/radio-group.d.ts +2 -9
- package/dist/reasoning.d.ts +2 -0
- package/dist/reasoning.js +90 -0
- package/dist/reasoning.js.map +1 -0
- package/dist/resizable.d.ts +3 -28
- package/dist/schemas.d.ts +79 -121
- package/dist/schemas.js +1649 -1
- package/dist/schemas.js.map +1 -1
- package/dist/scroll-area.d.ts +3 -18
- package/dist/select.d.ts +8 -21
- package/dist/separator.d.ts +2 -11
- package/dist/sheet.d.ts +10 -39
- package/dist/sidebar.d.ts +8 -75
- package/dist/skeleton.d.ts +1 -11
- package/dist/slider.d.ts +2 -20
- package/dist/sonner.d.ts +2 -14
- package/dist/spacer.d.ts +3 -38
- package/dist/stack.d.ts +3 -34
- package/dist/stepper.d.ts +4 -48
- package/dist/suggestion.d.ts +2 -0
- package/dist/suggestion.js +55 -0
- package/dist/suggestion.js.map +1 -0
- package/dist/switch.d.ts +2 -11
- package/dist/table.d.ts +8 -24
- package/dist/tabs.d.ts +4 -13
- package/dist/tag.d.ts +3 -0
- package/dist/tag.js +107 -0
- package/dist/tag.js.map +1 -0
- package/dist/textarea.d.ts +2 -10
- package/dist/time-picker.d.ts +2 -34
- package/dist/timeline.d.ts +4 -42
- package/dist/toggle-group.d.ts +2 -17
- package/dist/toggle.d.ts +2 -19
- package/dist/tool-call.d.ts +2 -0
- package/dist/tool-call.js +133 -0
- package/dist/tool-call.js.map +1 -0
- package/dist/toolbar.d.ts +8 -0
- package/dist/toolbar.js +120 -0
- package/dist/toolbar.js.map +1 -0
- package/dist/tooltip.d.ts +4 -13
- package/dist/tree.d.ts +3 -0
- package/dist/tree.js +275 -0
- package/dist/tree.js.map +1 -0
- package/package.json +5 -1
- package/dist/button-variants-Bx6gCUFp.d.ts +0 -19
package/dist/tree.js
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import { twMerge } from 'tailwind-merge';
|
|
5
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
function flattenVisible(nodes, expanded) {
|
|
11
|
+
const out = [];
|
|
12
|
+
function walk(items, depth, parentId) {
|
|
13
|
+
for (const node of items) {
|
|
14
|
+
out.push({ node, depth, parentId });
|
|
15
|
+
if (node.children && expanded.has(node.id)) {
|
|
16
|
+
walk(node.children, depth + 1, node.id);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
walk(nodes, 0, null);
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
function Tree({
|
|
24
|
+
data,
|
|
25
|
+
defaultExpanded,
|
|
26
|
+
expanded: expandedProp,
|
|
27
|
+
onExpandedChange,
|
|
28
|
+
selected: selectedProp,
|
|
29
|
+
onSelect,
|
|
30
|
+
"aria-label": ariaLabel,
|
|
31
|
+
className,
|
|
32
|
+
ref
|
|
33
|
+
}) {
|
|
34
|
+
const [internalExpanded, setInternalExpanded] = React.useState(
|
|
35
|
+
() => new Set(defaultExpanded ?? [])
|
|
36
|
+
);
|
|
37
|
+
const expanded = React.useMemo(
|
|
38
|
+
() => expandedProp ? new Set(expandedProp) : internalExpanded,
|
|
39
|
+
[expandedProp, internalExpanded]
|
|
40
|
+
);
|
|
41
|
+
const [internalSelected, setInternalSelected] = React.useState(null);
|
|
42
|
+
const selected = selectedProp ?? internalSelected;
|
|
43
|
+
const visible = React.useMemo(() => flattenVisible(data, expanded), [data, expanded]);
|
|
44
|
+
const [focusedId, setFocusedId] = React.useState(
|
|
45
|
+
() => visible[0]?.node.id ?? null
|
|
46
|
+
);
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
if (focusedId && !visible.some((row) => row.node.id === focusedId)) {
|
|
49
|
+
setFocusedId(visible[0]?.node.id ?? null);
|
|
50
|
+
}
|
|
51
|
+
}, [visible, focusedId]);
|
|
52
|
+
const setExpandedSet = React.useCallback(
|
|
53
|
+
(next) => {
|
|
54
|
+
if (expandedProp) {
|
|
55
|
+
onExpandedChange?.([...next]);
|
|
56
|
+
} else {
|
|
57
|
+
setInternalExpanded(next);
|
|
58
|
+
onExpandedChange?.([...next]);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
[expandedProp, onExpandedChange]
|
|
62
|
+
);
|
|
63
|
+
const toggleExpand = React.useCallback(
|
|
64
|
+
(id) => {
|
|
65
|
+
const next = new Set(expanded);
|
|
66
|
+
if (next.has(id)) next.delete(id);
|
|
67
|
+
else next.add(id);
|
|
68
|
+
setExpandedSet(next);
|
|
69
|
+
},
|
|
70
|
+
[expanded, setExpandedSet]
|
|
71
|
+
);
|
|
72
|
+
const activate = React.useCallback(
|
|
73
|
+
(id) => {
|
|
74
|
+
if (selectedProp === void 0) setInternalSelected(id);
|
|
75
|
+
onSelect?.(id);
|
|
76
|
+
},
|
|
77
|
+
[selectedProp, onSelect]
|
|
78
|
+
);
|
|
79
|
+
const handleKeyDown = React.useCallback(
|
|
80
|
+
(e) => {
|
|
81
|
+
if (!focusedId) return;
|
|
82
|
+
const idx = visible.findIndex((row2) => row2.node.id === focusedId);
|
|
83
|
+
if (idx < 0) return;
|
|
84
|
+
const row = visible[idx];
|
|
85
|
+
if (!row) return;
|
|
86
|
+
const node = row.node;
|
|
87
|
+
const isParent = !!node.children;
|
|
88
|
+
const isExpanded = expanded.has(node.id);
|
|
89
|
+
switch (e.key) {
|
|
90
|
+
case "ArrowDown": {
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
const next = visible[idx + 1];
|
|
93
|
+
if (next) setFocusedId(next.node.id);
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
case "ArrowUp": {
|
|
97
|
+
e.preventDefault();
|
|
98
|
+
const prev = visible[idx - 1];
|
|
99
|
+
if (prev) setFocusedId(prev.node.id);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case "ArrowRight": {
|
|
103
|
+
e.preventDefault();
|
|
104
|
+
if (isParent && !isExpanded) toggleExpand(node.id);
|
|
105
|
+
else if (isParent && isExpanded) {
|
|
106
|
+
const next = visible[idx + 1];
|
|
107
|
+
if (next) setFocusedId(next.node.id);
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
case "ArrowLeft": {
|
|
112
|
+
e.preventDefault();
|
|
113
|
+
if (isParent && isExpanded) toggleExpand(node.id);
|
|
114
|
+
else if (row.parentId) {
|
|
115
|
+
setFocusedId(row.parentId);
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case "Home": {
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
if (visible[0]) setFocusedId(visible[0].node.id);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
case "End": {
|
|
125
|
+
e.preventDefault();
|
|
126
|
+
const last = visible[visible.length - 1];
|
|
127
|
+
if (last) setFocusedId(last.node.id);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case "Enter":
|
|
131
|
+
case " ": {
|
|
132
|
+
e.preventDefault();
|
|
133
|
+
if (node.disabled) return;
|
|
134
|
+
if (isParent) toggleExpand(node.id);
|
|
135
|
+
activate(node.id);
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
default:
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
[focusedId, visible, expanded, toggleExpand, activate]
|
|
143
|
+
);
|
|
144
|
+
const isSelectable = onSelect !== void 0 || selectedProp !== void 0;
|
|
145
|
+
return /* @__PURE__ */ jsx(
|
|
146
|
+
"ul",
|
|
147
|
+
{
|
|
148
|
+
ref,
|
|
149
|
+
role: "tree",
|
|
150
|
+
"aria-label": ariaLabel,
|
|
151
|
+
className: cn("flex flex-col text-sm text-foreground", className),
|
|
152
|
+
onKeyDown: handleKeyDown,
|
|
153
|
+
children: data.map((node) => /* @__PURE__ */ jsx(
|
|
154
|
+
TreeItem,
|
|
155
|
+
{
|
|
156
|
+
node,
|
|
157
|
+
depth: 0,
|
|
158
|
+
expanded,
|
|
159
|
+
selected,
|
|
160
|
+
isSelectable,
|
|
161
|
+
focusedId,
|
|
162
|
+
onFocus: setFocusedId,
|
|
163
|
+
onToggleExpand: toggleExpand,
|
|
164
|
+
onActivate: activate
|
|
165
|
+
},
|
|
166
|
+
node.id
|
|
167
|
+
))
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
function TreeItem({
|
|
172
|
+
node,
|
|
173
|
+
depth,
|
|
174
|
+
expanded,
|
|
175
|
+
selected,
|
|
176
|
+
isSelectable,
|
|
177
|
+
focusedId,
|
|
178
|
+
onFocus,
|
|
179
|
+
onToggleExpand,
|
|
180
|
+
onActivate
|
|
181
|
+
}) {
|
|
182
|
+
const children = node.children;
|
|
183
|
+
const isParent = children !== void 0;
|
|
184
|
+
const isExpanded = expanded.has(node.id);
|
|
185
|
+
const isSelected = selected === node.id;
|
|
186
|
+
const isFocused = focusedId === node.id;
|
|
187
|
+
const handleClick = () => {
|
|
188
|
+
if (node.disabled) return;
|
|
189
|
+
onFocus(node.id);
|
|
190
|
+
if (isParent) onToggleExpand(node.id);
|
|
191
|
+
onActivate(node.id);
|
|
192
|
+
};
|
|
193
|
+
const labelId = React.useId();
|
|
194
|
+
return /* @__PURE__ */ jsxs(
|
|
195
|
+
"li",
|
|
196
|
+
{
|
|
197
|
+
role: "treeitem",
|
|
198
|
+
"aria-labelledby": labelId,
|
|
199
|
+
"aria-level": depth + 1,
|
|
200
|
+
"aria-expanded": isParent ? isExpanded : void 0,
|
|
201
|
+
"aria-selected": isSelectable ? isSelected : void 0,
|
|
202
|
+
"aria-disabled": node.disabled || void 0,
|
|
203
|
+
tabIndex: isFocused ? 0 : -1,
|
|
204
|
+
onClick: (e) => {
|
|
205
|
+
e.stopPropagation();
|
|
206
|
+
handleClick();
|
|
207
|
+
},
|
|
208
|
+
onFocus: (e) => {
|
|
209
|
+
e.stopPropagation();
|
|
210
|
+
if (!node.disabled) onFocus(node.id);
|
|
211
|
+
},
|
|
212
|
+
className: cn(
|
|
213
|
+
"outline-none rounded-sm",
|
|
214
|
+
// H1: focus-visible-driven ring (NOT state-driven) — the ring
|
|
215
|
+
// only shows on keyboard focus, not on mouse clicks.
|
|
216
|
+
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"
|
|
217
|
+
),
|
|
218
|
+
children: [
|
|
219
|
+
/* @__PURE__ */ jsxs(
|
|
220
|
+
"div",
|
|
221
|
+
{
|
|
222
|
+
className: cn(
|
|
223
|
+
"flex cursor-pointer select-none items-center gap-[var(--gap-xs,0.25rem)] rounded-sm px-[var(--space-2,0.5rem)] py-[var(--space-1,0.25rem)]",
|
|
224
|
+
"transition-colors duration-[var(--duration-normal,200ms)] ease-out",
|
|
225
|
+
"hover:bg-accent hover:text-accent-foreground",
|
|
226
|
+
isSelected && "bg-accent text-accent-foreground font-medium",
|
|
227
|
+
node.disabled && "cursor-not-allowed opacity-50"
|
|
228
|
+
),
|
|
229
|
+
style: { paddingLeft: `calc(${depth} * var(--space-4, 1rem) + var(--space-2, 0.5rem))` },
|
|
230
|
+
children: [
|
|
231
|
+
isParent ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-flex h-4 w-4 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
232
|
+
"svg",
|
|
233
|
+
{
|
|
234
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
235
|
+
viewBox: "0 0 24 24",
|
|
236
|
+
fill: "none",
|
|
237
|
+
stroke: "currentColor",
|
|
238
|
+
strokeWidth: "2",
|
|
239
|
+
strokeLinecap: "round",
|
|
240
|
+
strokeLinejoin: "round",
|
|
241
|
+
className: cn(
|
|
242
|
+
"h-3 w-3 transition-transform duration-[var(--duration-normal,200ms)] ease-out",
|
|
243
|
+
isExpanded ? "rotate-90" : "rotate-0"
|
|
244
|
+
),
|
|
245
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" })
|
|
246
|
+
}
|
|
247
|
+
) }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-block h-4 w-4 shrink-0" }),
|
|
248
|
+
node.icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "inline-flex h-4 w-4 shrink-0 items-center justify-center [&_svg]:size-4", children: node.icon }) : null,
|
|
249
|
+
/* @__PURE__ */ jsx("span", { id: labelId, className: "truncate", children: node.label })
|
|
250
|
+
]
|
|
251
|
+
}
|
|
252
|
+
),
|
|
253
|
+
isParent && isExpanded && children ? /* @__PURE__ */ jsx("ul", { role: "group", "aria-labelledby": labelId, className: "flex flex-col", children: children.map((child) => /* @__PURE__ */ jsx(
|
|
254
|
+
TreeItem,
|
|
255
|
+
{
|
|
256
|
+
node: child,
|
|
257
|
+
depth: depth + 1,
|
|
258
|
+
expanded,
|
|
259
|
+
selected,
|
|
260
|
+
isSelectable,
|
|
261
|
+
focusedId,
|
|
262
|
+
onFocus,
|
|
263
|
+
onToggleExpand,
|
|
264
|
+
onActivate
|
|
265
|
+
},
|
|
266
|
+
child.id
|
|
267
|
+
)) }) : null
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export { Tree };
|
|
274
|
+
//# sourceMappingURL=tree.js.map
|
|
275
|
+
//# sourceMappingURL=tree.js.map
|
package/dist/tree.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/tree/tree.tsx"],"names":["row"],"mappings":"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","file":"tree.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * One node in a Tree. Generic — the shape is content-agnostic so consumers\n * can render org charts, taxonomy pickers, navigation trees, etc.\n *\n * For filesystem-shaped data (with file-extension icon logic baked in),\n * prefer {@link FileTree} instead.\n */\nexport interface TreeNode {\n\t/** Stable unique id used as React key + ARIA target. */\n\tid: string;\n\t/** Display name. */\n\tlabel: React.ReactNode;\n\t/** Nested children. Presence (even empty array) marks the node as a parent. */\n\tchildren?: TreeNode[];\n\t/** Optional icon (default: a chevron + dot). */\n\ticon?: React.ReactNode;\n\t/** Disable selection + expand toggle. */\n\tdisabled?: boolean;\n}\n\nexport interface TreeProps {\n\t/** Forwarded ref onto the root `<ul role=\"tree\">`. */\n\tref?: React.Ref<HTMLUListElement>;\n\t/** Root nodes. */\n\tdata: TreeNode[];\n\t/** Uncontrolled initial expanded ids. */\n\tdefaultExpanded?: string[];\n\t/** Controlled expanded ids. */\n\texpanded?: string[];\n\t/** Fired when expanded set changes (array of ids). */\n\tonExpandedChange?: (ids: string[]) => void;\n\t/** Controlled selected node id. */\n\tselected?: string;\n\t/** Fired when the user activates a node (click, Enter, or Space). */\n\tonSelect?: (id: string) => void;\n\t/** Required accessible name. */\n\t\"aria-label\": string;\n\t/** Optional additional class names. */\n\tclassName?: string;\n}\n\n/** Recursively flatten a tree into the visible-row order (respecting collapsed parents). */\nfunction flattenVisible(nodes: TreeNode[], expanded: Set<string>): Array<{ node: TreeNode; depth: number; parentId: string | null }> {\n\tconst out: Array<{ node: TreeNode; depth: number; parentId: string | null }> = [];\n\tfunction walk(items: TreeNode[], depth: number, parentId: string | null) {\n\t\tfor (const node of items) {\n\t\t\tout.push({ node, depth, parentId });\n\t\t\tif (node.children && expanded.has(node.id)) {\n\t\t\t\twalk(node.children, depth + 1, node.id);\n\t\t\t}\n\t\t}\n\t}\n\twalk(nodes, 0, null);\n\treturn out;\n}\n\n/**\n * Generic hierarchical list with roving-tabindex keyboard navigation —\n * arrow keys move focus, → expands, ← collapses, Home / End jump to\n * first / last visible row, Enter / Space activates the focused node.\n *\n * Distinct from {@link FileTree} (which adds folder/file icon-by-extension\n * logic baked in) and {@link Accordion} (two-level groupings without\n * item-selection semantics).\n *\n * @example\n * ```tsx\n * <Tree\n * aria-label=\"Org chart\"\n * data={[\n * { id: \"ceo\", label: \"CEO\", children: [\n * { id: \"cto\", label: \"CTO\", children: [\n * { id: \"eng-lead\", label: \"Eng Lead\" },\n * ]},\n * { id: \"cmo\", label: \"CMO\" },\n * ]},\n * ]}\n * defaultExpanded={[\"ceo\"]}\n * onSelect={(id) => console.log(id)}\n * />\n * ```\n */\nfunction Tree({\n\tdata,\n\tdefaultExpanded,\n\texpanded: expandedProp,\n\tonExpandedChange,\n\tselected: selectedProp,\n\tonSelect,\n\t\"aria-label\": ariaLabel,\n\tclassName,\n\tref,\n}: TreeProps) {\n\tconst [internalExpanded, setInternalExpanded] = React.useState<Set<string>>(\n\t\t() => new Set(defaultExpanded ?? []),\n\t);\n\tconst expanded = React.useMemo(\n\t\t() => (expandedProp ? new Set(expandedProp) : internalExpanded),\n\t\t[expandedProp, internalExpanded],\n\t);\n\n\t\tconst [internalSelected, setInternalSelected] = React.useState<string | null>(null);\n\t\tconst selected = selectedProp ?? internalSelected;\n\n\t\tconst visible = React.useMemo(() => flattenVisible(data, expanded), [data, expanded]);\n\n\t\tconst [focusedId, setFocusedId] = React.useState<string | null>(\n\t\t\t() => visible[0]?.node.id ?? null,\n\t\t);\n\n\t\t// If the focused node disappeared (parent collapsed), retarget to the parent.\n\t\tReact.useEffect(() => {\n\t\t\tif (focusedId && !visible.some((row) => row.node.id === focusedId)) {\n\t\t\t\tsetFocusedId(visible[0]?.node.id ?? null);\n\t\t\t}\n\t\t}, [visible, focusedId]);\n\n\t\tconst setExpandedSet = React.useCallback(\n\t\t\t(next: Set<string>) => {\n\t\t\t\tif (expandedProp) {\n\t\t\t\t\tonExpandedChange?.([...next]);\n\t\t\t\t} else {\n\t\t\t\t\tsetInternalExpanded(next);\n\t\t\t\t\tonExpandedChange?.([...next]);\n\t\t\t\t}\n\t\t\t},\n\t\t\t[expandedProp, onExpandedChange],\n\t\t);\n\n\t\tconst toggleExpand = React.useCallback(\n\t\t\t(id: string) => {\n\t\t\t\tconst next = new Set(expanded);\n\t\t\t\tif (next.has(id)) next.delete(id);\n\t\t\t\telse next.add(id);\n\t\t\t\tsetExpandedSet(next);\n\t\t\t},\n\t\t\t[expanded, setExpandedSet],\n\t\t);\n\n\t\tconst activate = React.useCallback(\n\t\t\t(id: string) => {\n\t\t\t\tif (selectedProp === undefined) setInternalSelected(id);\n\t\t\t\tonSelect?.(id);\n\t\t\t},\n\t\t\t[selectedProp, onSelect],\n\t\t);\n\n\t\tconst handleKeyDown = React.useCallback(\n\t\t\t(e: React.KeyboardEvent<HTMLUListElement>) => {\n\t\t\t\tif (!focusedId) return;\n\t\t\t\tconst idx = visible.findIndex((row) => row.node.id === focusedId);\n\t\t\t\tif (idx < 0) return;\n\t\t\t\tconst row = visible[idx];\n\t\t\t\tif (!row) return;\n\t\t\t\tconst node = row.node;\n\t\t\t\tconst isParent = !!node.children;\n\t\t\t\tconst isExpanded = expanded.has(node.id);\n\n\t\t\t\tswitch (e.key) {\n\t\t\t\t\tcase \"ArrowDown\": {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tconst next = visible[idx + 1];\n\t\t\t\t\t\tif (next) setFocusedId(next.node.id);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"ArrowUp\": {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tconst prev = visible[idx - 1];\n\t\t\t\t\t\tif (prev) setFocusedId(prev.node.id);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"ArrowRight\": {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tif (isParent && !isExpanded) toggleExpand(node.id);\n\t\t\t\t\t\telse if (isParent && isExpanded) {\n\t\t\t\t\t\t\tconst next = visible[idx + 1];\n\t\t\t\t\t\t\tif (next) setFocusedId(next.node.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"ArrowLeft\": {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tif (isParent && isExpanded) toggleExpand(node.id);\n\t\t\t\t\t\telse if (row.parentId) {\n\t\t\t\t\t\t\tsetFocusedId(row.parentId);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"Home\": {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tif (visible[0]) setFocusedId(visible[0].node.id);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"End\": {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tconst last = visible[visible.length - 1];\n\t\t\t\t\t\tif (last) setFocusedId(last.node.id);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"Enter\":\n\t\t\t\t\tcase \" \": {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tif (node.disabled) return;\n\t\t\t\t\t\tif (isParent) toggleExpand(node.id);\n\t\t\t\t\t\tactivate(node.id);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t},\n\t\t\t[focusedId, visible, expanded, toggleExpand, activate],\n\t\t);\n\n\t// H3: emit boolean aria-selected when selection is wired (so AT can\n\t// announce \"1 of N, not selected\" on non-selected items); leave it\n\t// undefined entirely when nothing on the tree is selectable.\n\tconst isSelectable = onSelect !== undefined || selectedProp !== undefined;\n\n\treturn (\n\t\t<ul\n\t\t\tref={ref}\n\t\t\trole=\"tree\"\n\t\t\taria-label={ariaLabel}\n\t\t\tclassName={cn(\"flex flex-col text-sm text-foreground\", className)}\n\t\t\tonKeyDown={handleKeyDown}\n\t\t>\n\t\t\t{data.map((node) => (\n\t\t\t\t<TreeItem\n\t\t\t\t\tkey={node.id}\n\t\t\t\t\tnode={node}\n\t\t\t\t\tdepth={0}\n\t\t\t\t\texpanded={expanded}\n\t\t\t\t\tselected={selected}\n\t\t\t\t\tisSelectable={isSelectable}\n\t\t\t\t\tfocusedId={focusedId}\n\t\t\t\t\tonFocus={setFocusedId}\n\t\t\t\t\tonToggleExpand={toggleExpand}\n\t\t\t\t\tonActivate={activate}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</ul>\n\t);\n}\n\ninterface TreeItemProps {\n\tnode: TreeNode;\n\tdepth: number;\n\texpanded: Set<string>;\n\tselected: string | null;\n\tisSelectable: boolean;\n\tfocusedId: string | null;\n\tonFocus: (id: string) => void;\n\tonToggleExpand: (id: string) => void;\n\tonActivate: (id: string) => void;\n}\n\n/** One row inside a Tree. Recurses through children when expanded. */\nfunction TreeItem({\n\tnode,\n\tdepth,\n\texpanded,\n\tselected,\n\tisSelectable,\n\tfocusedId,\n\tonFocus,\n\tonToggleExpand,\n\tonActivate,\n}: TreeItemProps) {\n\tconst children = node.children;\n\tconst isParent = children !== undefined;\n\tconst isExpanded = expanded.has(node.id);\n\tconst isSelected = selected === node.id;\n\tconst isFocused = focusedId === node.id;\n\n\tconst handleClick = () => {\n\t\tif (node.disabled) return;\n\t\tonFocus(node.id);\n\t\tif (isParent) onToggleExpand(node.id);\n\t\tonActivate(node.id);\n\t};\n\n\tconst labelId = React.useId();\n\treturn (\n\t\t<li\n\t\t\trole=\"treeitem\"\n\t\t\taria-labelledby={labelId}\n\t\t\taria-level={depth + 1}\n\t\t\taria-expanded={isParent ? isExpanded : undefined}\n\t\t\t// H3: when the tree is selectable (caller wired onSelect or\n\t\t\t// selected), emit boolean aria-selected on every item — AT\n\t\t\t// announces \"1 of N, not selected\" instead of dropping the\n\t\t\t// attribute entirely. When nothing is selectable, leave it off.\n\t\t\taria-selected={isSelectable ? isSelected : undefined}\n\t\t\taria-disabled={node.disabled || undefined}\n\t\t\ttabIndex={isFocused ? 0 : -1}\n\t\t\tonClick={(e) => {\n\t\t\t\t// Stop bubbling so a parent treeitem doesn't refire on a\n\t\t\t\t// nested-child click — each li carries its own click handler.\n\t\t\t\te.stopPropagation();\n\t\t\t\thandleClick();\n\t\t\t}}\n\t\t\tonFocus={(e) => {\n\t\t\t\t// stopPropagation prevents the parent treeitem's onFocus from\n\t\t\t\t// also firing when a deeper child gains focus, racing the\n\t\t\t\t// focusedId state. Side effect: focus-trap libraries listening\n\t\t\t\t// at a wrapping container don't see nested-tree focus events.\n\t\t\t\t// In practice tree-inside-Drawer / Dialog still works because\n\t\t\t\t// those focus traps activate on outer focusin, not inner.\n\t\t\t\te.stopPropagation();\n\t\t\t\tif (!node.disabled) onFocus(node.id);\n\t\t\t}}\n\t\t\tclassName={cn(\n\t\t\t\t\"outline-none rounded-sm\",\n\t\t\t\t// H1: focus-visible-driven ring (NOT state-driven) — the ring\n\t\t\t\t// only shows on keyboard focus, not on mouse clicks.\n\t\t\t\t\"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n\t\t\t)}\n\t\t>\n\t\t\t{/*\n\t\t\t Row element — visible surface. Style only; the li carries the\n\t\t\t interactivity + focus + ARIA. aria-hidden on chevron + icon\n\t\t\t spans keeps the accessible name pinned to the labelled\n\t\t\t <span id={labelId}>.\n\t\t\t*/}\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex cursor-pointer select-none items-center gap-[var(--gap-xs,0.25rem)] rounded-sm px-[var(--space-2,0.5rem)] py-[var(--space-1,0.25rem)]\",\n\t\t\t\t\t\"transition-colors duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\"hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\t\tisSelected && \"bg-accent text-accent-foreground font-medium\",\n\t\t\t\t\tnode.disabled && \"cursor-not-allowed opacity-50\",\n\t\t\t\t)}\n\t\t\t\tstyle={{ paddingLeft: `calc(${depth} * var(--space-4, 1rem) + var(--space-2, 0.5rem))` }}\n\t\t\t>\n\t\t\t\t{isParent ? (\n\t\t\t\t\t<span aria-hidden=\"true\" className=\"inline-flex h-4 w-4 shrink-0 items-center justify-center\">\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"h-3 w-3 transition-transform duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\t\t\tisExpanded ? \"rotate-90\" : \"rotate-0\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<polyline points=\"9 18 15 12 9 6\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</span>\n\t\t\t\t) : (\n\t\t\t\t\t<span aria-hidden=\"true\" className=\"inline-block h-4 w-4 shrink-0\" />\n\t\t\t\t)}\n\t\t\t\t{node.icon ? (\n\t\t\t\t\t<span aria-hidden=\"true\" className=\"inline-flex h-4 w-4 shrink-0 items-center justify-center [&_svg]:size-4\">\n\t\t\t\t\t\t{node.icon}\n\t\t\t\t\t</span>\n\t\t\t\t) : null}\n\t\t\t\t<span id={labelId} className=\"truncate\">\n\t\t\t\t\t{node.label}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t{isParent && isExpanded && children ? (\n\t\t\t\t<ul role=\"group\" aria-labelledby={labelId} className=\"flex flex-col\">\n\t\t\t\t\t{children.map((child) => (\n\t\t\t\t\t\t<TreeItem\n\t\t\t\t\t\t\tkey={child.id}\n\t\t\t\t\t\t\tnode={child}\n\t\t\t\t\t\t\tdepth={depth + 1}\n\t\t\t\t\t\t\texpanded={expanded}\n\t\t\t\t\t\t\tselected={selected}\n\t\t\t\t\t\t\tisSelectable={isSelectable}\n\t\t\t\t\t\t\tfocusedId={focusedId}\n\t\t\t\t\t\t\tonFocus={onFocus}\n\t\t\t\t\t\t\tonToggleExpand={onToggleExpand}\n\t\t\t\t\t\t\tonActivate={onActivate}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t) : null}\n\t\t</li>\n\t);\n}\n\nexport { Tree };\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hex-core/components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "AI-native React components for Hex UI — Radix UI + Tailwind CSS with machine-readable schemas. RSC-aware per-component bundles + tree-shakable.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -77,12 +77,16 @@
|
|
|
77
77
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
78
78
|
"@radix-ui/react-toggle": "^1.1.10",
|
|
79
79
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
80
|
+
"@radix-ui/react-toolbar": "^1.1.11",
|
|
80
81
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
81
82
|
"class-variance-authority": "^0.7.0",
|
|
82
83
|
"clsx": "^2.1.0",
|
|
84
|
+
"shiki": "^4.0.2",
|
|
85
|
+
"streamdown": "^2.5.0",
|
|
83
86
|
"tailwind-merge": "^3.5.0"
|
|
84
87
|
},
|
|
85
88
|
"devDependencies": {
|
|
89
|
+
"@microsoft/api-extractor": "^7.58.7",
|
|
86
90
|
"@tanstack/react-table": "^8.21.3",
|
|
87
91
|
"@types/react": "^19.0.0",
|
|
88
92
|
"@types/react-dom": "^19.0.0",
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
2
|
-
import { VariantProps } from 'class-variance-authority';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* CVA variants for the Button component.
|
|
6
|
-
*
|
|
7
|
-
* Lives in its own module so RSC-safe consumers (`Pagination`, future
|
|
8
|
-
* link-styled buttons in static layouts) can import variants without
|
|
9
|
-
* pulling in the full `Button` runtime — `Button` itself is client-only
|
|
10
|
-
* because of `Slot` + `forwardRef` + the loading spinner. Splitting the
|
|
11
|
-
* variants out keeps `dist/pagination.js` free of `@radix-ui/react-slot`.
|
|
12
|
-
*/
|
|
13
|
-
declare const buttonVariants: (props?: ({
|
|
14
|
-
variant?: "default" | "secondary" | "destructive" | "outline" | "link" | "ghost" | null | undefined;
|
|
15
|
-
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
|
|
16
|
-
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
17
|
-
type ButtonVariantsProps = VariantProps<typeof buttonVariants>;
|
|
18
|
-
|
|
19
|
-
export { type ButtonVariantsProps as B, buttonVariants as b };
|