@robr0/design-system 0.7.0 → 0.9.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/README.md +4 -4
- package/components/Accordion/Accordion.js +1 -0
- package/components/AgentPlan/AgentPlan.css +231 -0
- package/components/AgentPlan/AgentPlan.d.ts +41 -0
- package/components/AgentPlan/AgentPlan.js +100 -0
- package/components/AgentStatus/AgentStatus.js +1 -0
- package/components/AiButton/AiButton.js +1 -0
- package/components/AlertDialog/AlertDialog.js +1 -0
- package/components/AnchorNav/AnchorNav.css +63 -0
- package/components/AnchorNav/AnchorNav.d.ts +33 -0
- package/components/AnchorNav/AnchorNav.js +82 -0
- package/components/AppLayout/AppLayout.js +1 -0
- package/components/AppSidebar/AppSidebar.js +1 -0
- package/components/Avatar/Avatar.js +1 -0
- package/components/Button/Button.js +1 -0
- package/components/Card/Card.js +1 -0
- package/components/Carousel/Carousel.js +1 -0
- package/components/ChatThread/ChatThread.js +1 -0
- package/components/Checkbox/Checkbox.js +1 -0
- package/components/CodeBlock/CodeBlock.js +1 -0
- package/components/CodeDiff/CodeDiff.css +175 -0
- package/components/CodeDiff/CodeDiff.d.ts +58 -0
- package/components/CodeDiff/CodeDiff.js +114 -0
- package/components/ColorPicker/ColorPicker.js +1 -0
- package/components/Combobox/Combobox.js +1 -0
- package/components/CommandPalette/CommandPalette.js +1 -0
- package/components/Composer/Composer.js +1 -0
- package/components/ContactCard/ContactCard.js +1 -0
- package/components/ContextMenu/ContextMenu.js +1 -0
- package/components/DataTable/DataTable.css +105 -0
- package/components/DataTable/DataTable.d.ts +81 -0
- package/components/DataTable/DataTable.js +236 -0
- package/components/DateInput/DateInput.js +1 -0
- package/components/DatePicker/DatePicker.js +1 -0
- package/components/Dialog/Dialog.js +1 -0
- package/components/Drawer/Drawer.js +1 -0
- package/components/Dropdown/Dropdown.js +1 -0
- package/components/DropdownMenu/DropdownMenu.css +1 -1
- package/components/DropdownMenu/DropdownMenu.js +1 -0
- package/components/EventCalendar/EventCalendar.css +328 -0
- package/components/EventCalendar/EventCalendar.d.ts +51 -0
- package/components/EventCalendar/EventCalendar.js +214 -0
- package/components/Field/Field.js +1 -0
- package/components/Field/FieldContext.js +1 -0
- package/components/FileInput/FileInput.js +1 -0
- package/components/Input/Input.js +1 -0
- package/components/InterruptCard/InterruptCard.css +11 -21
- package/components/InterruptCard/InterruptCard.d.ts +5 -6
- package/components/MessageCard/MessageCard.css +1 -2
- package/components/ModelPicker/ModelPicker.css +240 -0
- package/components/ModelPicker/ModelPicker.d.ts +60 -0
- package/components/ModelPicker/ModelPicker.js +218 -0
- package/components/NavList/NavList.js +1 -0
- package/components/NotificationCenter/NotificationCenter.css +262 -0
- package/components/NotificationCenter/NotificationCenter.d.ts +72 -0
- package/components/NotificationCenter/NotificationCenter.js +129 -0
- package/components/NumberInput/NumberInput.css +154 -0
- package/components/NumberInput/NumberInput.d.ts +44 -0
- package/components/NumberInput/NumberInput.js +147 -0
- package/components/Pagination/Pagination.js +1 -0
- package/components/PinInput/PinInput.css +92 -0
- package/components/PinInput/PinInput.d.ts +46 -0
- package/components/PinInput/PinInput.js +161 -0
- package/components/Popover/Popover.css +5 -6
- package/components/Popover/Popover.js +1 -0
- package/components/RadioButton/RadioButton.js +1 -0
- package/components/Reasoning/Reasoning.js +1 -0
- package/components/SegmentedControl/SegmentedControl.js +1 -0
- package/components/SelectionCard/SelectionCard.js +1 -0
- package/components/ShaderField/ShaderField.js +1 -0
- package/components/ShaderField/field.glsl.d.ts +11 -5
- package/components/ShaderField/field.glsl.js +4 -3
- package/components/ShaderField/useShaderField.d.ts +19 -2
- package/components/ShaderField/useShaderField.js +18 -3
- package/components/Slider/Slider.js +1 -0
- package/components/Sparkline/Sparkline.css +52 -0
- package/components/Sparkline/Sparkline.d.ts +49 -0
- package/components/Sparkline/Sparkline.js +86 -0
- package/components/Stepper/Stepper.css +207 -0
- package/components/Stepper/Stepper.d.ts +41 -0
- package/components/Stepper/Stepper.js +61 -0
- package/components/Tabs/Tabs.js +1 -0
- package/components/TagInput/TagInput.css +160 -0
- package/components/TagInput/TagInput.d.ts +43 -0
- package/components/TagInput/TagInput.js +137 -0
- package/components/Textarea/Textarea.js +1 -0
- package/components/TimePicker/TimePicker.css +230 -0
- package/components/TimePicker/TimePicker.d.ts +46 -0
- package/components/TimePicker/TimePicker.js +246 -0
- package/components/Timeline/Timeline.css +17 -0
- package/components/Timeline/Timeline.d.ts +2 -0
- package/components/Timeline/Timeline.js +1 -0
- package/components/Toast/Toast.js +1 -0
- package/components/ToggleGroup/ToggleGroup.js +1 -0
- package/components/ToggleSwitch/ToggleSwitch.js +1 -0
- package/components/ToolCall/ToolCall.css +7 -11
- package/components/ToolCall/ToolCall.js +1 -0
- package/components/Tooltip/Tooltip.js +1 -0
- package/components/TreeView/TreeView.css +119 -0
- package/components/TreeView/TreeView.d.ts +45 -0
- package/components/TreeView/TreeView.js +232 -0
- package/components/registry.d.ts +22 -6
- package/components/registry.js +3 -1
- package/components/registry.json +246 -20
- package/components/registry.json.d.ts +246 -20
- package/components/registry.json.js +2 -2
- package/index.d.ts +16 -2
- package/index.js +32 -1
- package/package.json +1 -1
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React, { useState, useMemo, useRef, useCallback } from "react";
|
|
4
|
+
import "./TreeView.css";
|
|
5
|
+
import "../../fonts/material-symbols.css";
|
|
6
|
+
const isBranchNode = (node) => Array.isArray(node.children) && node.children.length > 0;
|
|
7
|
+
const TreeView = React.forwardRef(
|
|
8
|
+
({
|
|
9
|
+
nodes,
|
|
10
|
+
defaultExpandedIds = [],
|
|
11
|
+
expandedIds,
|
|
12
|
+
onExpandedChange,
|
|
13
|
+
selectedId,
|
|
14
|
+
defaultSelectedId,
|
|
15
|
+
onSelect,
|
|
16
|
+
className = "",
|
|
17
|
+
...rest
|
|
18
|
+
}, ref) => {
|
|
19
|
+
const baseClass = "ds-treeview";
|
|
20
|
+
const baseId = React.useId();
|
|
21
|
+
const [internalExpanded, setInternalExpanded] = useState(
|
|
22
|
+
() => new Set(defaultExpandedIds)
|
|
23
|
+
);
|
|
24
|
+
const [internalSelected, setInternalSelected] = useState(
|
|
25
|
+
defaultSelectedId
|
|
26
|
+
);
|
|
27
|
+
const [focusedId, setFocusedId] = useState(void 0);
|
|
28
|
+
const expandedSet = useMemo(
|
|
29
|
+
() => expandedIds !== void 0 ? new Set(expandedIds) : internalExpanded,
|
|
30
|
+
[expandedIds, internalExpanded]
|
|
31
|
+
);
|
|
32
|
+
const selected = selectedId !== void 0 ? selectedId : internalSelected;
|
|
33
|
+
const itemRefs = useRef(/* @__PURE__ */ new Map());
|
|
34
|
+
const indexById = useMemo(() => {
|
|
35
|
+
const map = /* @__PURE__ */ new Map();
|
|
36
|
+
let i = 0;
|
|
37
|
+
const walk = (list) => {
|
|
38
|
+
for (const node of list) {
|
|
39
|
+
map.set(node.id, i);
|
|
40
|
+
i += 1;
|
|
41
|
+
if (node.children) walk(node.children);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
walk(nodes);
|
|
45
|
+
return map;
|
|
46
|
+
}, [nodes]);
|
|
47
|
+
const parentById = useMemo(() => {
|
|
48
|
+
const map = /* @__PURE__ */ new Map();
|
|
49
|
+
const walk = (list, parent) => {
|
|
50
|
+
for (const node of list) {
|
|
51
|
+
map.set(node.id, parent);
|
|
52
|
+
if (node.children) walk(node.children, node.id);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
walk(nodes);
|
|
56
|
+
return map;
|
|
57
|
+
}, [nodes]);
|
|
58
|
+
const visibleNodes = useMemo(() => {
|
|
59
|
+
const out = [];
|
|
60
|
+
const walk = (list) => {
|
|
61
|
+
for (const node of list) {
|
|
62
|
+
out.push(node);
|
|
63
|
+
if (isBranchNode(node) && expandedSet.has(node.id)) walk(node.children);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
walk(nodes);
|
|
67
|
+
return out;
|
|
68
|
+
}, [nodes, expandedSet]);
|
|
69
|
+
const visibleIds = useMemo(
|
|
70
|
+
() => new Set(visibleNodes.map((node) => node.id)),
|
|
71
|
+
[visibleNodes]
|
|
72
|
+
);
|
|
73
|
+
const tabbableId = focusedId !== void 0 && visibleIds.has(focusedId) ? focusedId : selected !== void 0 && visibleIds.has(selected) ? selected : visibleNodes[0]?.id;
|
|
74
|
+
const commitExpanded = useCallback(
|
|
75
|
+
(next) => {
|
|
76
|
+
if (expandedIds === void 0) setInternalExpanded(next);
|
|
77
|
+
onExpandedChange?.(Array.from(next));
|
|
78
|
+
},
|
|
79
|
+
[expandedIds, onExpandedChange]
|
|
80
|
+
);
|
|
81
|
+
const toggleBranch = useCallback(
|
|
82
|
+
(id) => {
|
|
83
|
+
const next = new Set(expandedSet);
|
|
84
|
+
if (next.has(id)) {
|
|
85
|
+
next.delete(id);
|
|
86
|
+
} else {
|
|
87
|
+
next.add(id);
|
|
88
|
+
}
|
|
89
|
+
commitExpanded(next);
|
|
90
|
+
},
|
|
91
|
+
[expandedSet, commitExpanded]
|
|
92
|
+
);
|
|
93
|
+
const selectNode = useCallback(
|
|
94
|
+
(id) => {
|
|
95
|
+
if (selectedId === void 0) setInternalSelected(id);
|
|
96
|
+
onSelect?.(id);
|
|
97
|
+
},
|
|
98
|
+
[selectedId, onSelect]
|
|
99
|
+
);
|
|
100
|
+
const focusNode = useCallback((id) => {
|
|
101
|
+
if (id === void 0) return;
|
|
102
|
+
setFocusedId(id);
|
|
103
|
+
itemRefs.current.get(id)?.focus();
|
|
104
|
+
}, []);
|
|
105
|
+
const handleKeyDown = (event, node) => {
|
|
106
|
+
const branch = isBranchNode(node);
|
|
107
|
+
const expanded = expandedSet.has(node.id);
|
|
108
|
+
const index = visibleNodes.findIndex((n) => n.id === node.id);
|
|
109
|
+
let handled = true;
|
|
110
|
+
switch (event.key) {
|
|
111
|
+
case "ArrowDown":
|
|
112
|
+
focusNode(visibleNodes[index + 1]?.id);
|
|
113
|
+
break;
|
|
114
|
+
case "ArrowUp":
|
|
115
|
+
focusNode(visibleNodes[index - 1]?.id);
|
|
116
|
+
break;
|
|
117
|
+
case "ArrowRight":
|
|
118
|
+
if (branch && !expanded) {
|
|
119
|
+
toggleBranch(node.id);
|
|
120
|
+
} else if (branch && expanded) {
|
|
121
|
+
focusNode(node.children[0]?.id);
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
124
|
+
case "ArrowLeft":
|
|
125
|
+
if (branch && expanded) {
|
|
126
|
+
toggleBranch(node.id);
|
|
127
|
+
} else {
|
|
128
|
+
focusNode(parentById.get(node.id));
|
|
129
|
+
}
|
|
130
|
+
break;
|
|
131
|
+
case "Home":
|
|
132
|
+
focusNode(visibleNodes[0]?.id);
|
|
133
|
+
break;
|
|
134
|
+
case "End":
|
|
135
|
+
focusNode(visibleNodes[visibleNodes.length - 1]?.id);
|
|
136
|
+
break;
|
|
137
|
+
case "Enter":
|
|
138
|
+
case " ":
|
|
139
|
+
selectNode(node.id);
|
|
140
|
+
break;
|
|
141
|
+
default:
|
|
142
|
+
handled = false;
|
|
143
|
+
}
|
|
144
|
+
if (handled) {
|
|
145
|
+
event.preventDefault();
|
|
146
|
+
event.stopPropagation();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
const renderNode = (node, depth) => {
|
|
150
|
+
const branch = isBranchNode(node);
|
|
151
|
+
const expanded = branch && expandedSet.has(node.id);
|
|
152
|
+
const isSelected = selected === node.id;
|
|
153
|
+
const labelId = `${baseId}-label-${indexById.get(node.id)}`;
|
|
154
|
+
const icon = node.icon ?? (branch ? "folder" : "draft");
|
|
155
|
+
const rowClasses = [
|
|
156
|
+
`${baseClass}__row`,
|
|
157
|
+
isSelected && `${baseClass}__row--selected`
|
|
158
|
+
].filter(Boolean).join(" ");
|
|
159
|
+
return /* @__PURE__ */ jsxs(
|
|
160
|
+
"li",
|
|
161
|
+
{
|
|
162
|
+
role: "treeitem",
|
|
163
|
+
"aria-expanded": branch ? expanded : void 0,
|
|
164
|
+
"aria-selected": isSelected,
|
|
165
|
+
"aria-labelledby": labelId,
|
|
166
|
+
tabIndex: node.id === tabbableId ? 0 : -1,
|
|
167
|
+
className: `${baseClass}__item`,
|
|
168
|
+
ref: (el) => {
|
|
169
|
+
if (el) {
|
|
170
|
+
itemRefs.current.set(node.id, el);
|
|
171
|
+
} else {
|
|
172
|
+
itemRefs.current.delete(node.id);
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
onKeyDown: (event) => handleKeyDown(event, node),
|
|
176
|
+
onFocus: (event) => {
|
|
177
|
+
event.stopPropagation();
|
|
178
|
+
setFocusedId(node.id);
|
|
179
|
+
},
|
|
180
|
+
onClick: (event) => {
|
|
181
|
+
event.stopPropagation();
|
|
182
|
+
if (branch) toggleBranch(node.id);
|
|
183
|
+
selectNode(node.id);
|
|
184
|
+
focusNode(node.id);
|
|
185
|
+
},
|
|
186
|
+
children: [
|
|
187
|
+
/* @__PURE__ */ jsxs(
|
|
188
|
+
"div",
|
|
189
|
+
{
|
|
190
|
+
className: rowClasses,
|
|
191
|
+
style: { "--ds-treeview-depth": depth },
|
|
192
|
+
children: [
|
|
193
|
+
branch ? /* @__PURE__ */ jsx(
|
|
194
|
+
"span",
|
|
195
|
+
{
|
|
196
|
+
className: `${baseClass}__chevron material-symbols-rounded`,
|
|
197
|
+
"aria-hidden": "true",
|
|
198
|
+
children: "chevron_right"
|
|
199
|
+
}
|
|
200
|
+
) : /* @__PURE__ */ jsx(
|
|
201
|
+
"span",
|
|
202
|
+
{
|
|
203
|
+
className: `${baseClass}__chevron ${baseClass}__chevron--spacer`,
|
|
204
|
+
"aria-hidden": "true"
|
|
205
|
+
}
|
|
206
|
+
),
|
|
207
|
+
/* @__PURE__ */ jsx(
|
|
208
|
+
"span",
|
|
209
|
+
{
|
|
210
|
+
className: `${baseClass}__icon material-symbols-rounded`,
|
|
211
|
+
"aria-hidden": "true",
|
|
212
|
+
children: icon
|
|
213
|
+
}
|
|
214
|
+
),
|
|
215
|
+
/* @__PURE__ */ jsx("span", { id: labelId, className: `${baseClass}__label`, children: node.label })
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
),
|
|
219
|
+
expanded && /* @__PURE__ */ jsx("ul", { role: "group", className: `${baseClass}__group`, children: node.children.map((child) => renderNode(child, depth + 1)) })
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
node.id
|
|
223
|
+
);
|
|
224
|
+
};
|
|
225
|
+
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
226
|
+
return /* @__PURE__ */ jsx("ul", { ...rest, ref, role: "tree", className: classes, children: nodes.map((node) => renderNode(node, 0)) });
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
TreeView.displayName = "TreeView";
|
|
230
|
+
export {
|
|
231
|
+
TreeView
|
|
232
|
+
};
|
package/components/registry.d.ts
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
*
|
|
5
5
|
* The data lives in registry.json. Each entry in `components` carries:
|
|
6
6
|
*
|
|
7
|
-
* name the
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* name the exported component name; also the folder under
|
|
8
|
+
* src/components unless `folder` says otherwise
|
|
9
|
+
* label the display name — "Nav list" for the NavList folder
|
|
10
|
+
* slug the website route segment — stored, not derived, so a
|
|
11
|
+
* name-to-slug exception stays plain data rather than a
|
|
11
12
|
* special case duplicated across validators
|
|
12
13
|
* description one line, used for the page title, the sidebar search index,
|
|
13
14
|
* and anywhere the component is summarised
|
|
@@ -16,6 +17,9 @@
|
|
|
16
17
|
* uses hooks or defines handlers. Presentational components are
|
|
17
18
|
* deliberately false so consumers can render them from a React
|
|
18
19
|
* Server Component.
|
|
20
|
+
* folder set only when the implementation lives in a shared folder
|
|
21
|
+
* rather than one named after the component — the nine chart
|
|
22
|
+
* components all live in Chart/. Omitted everywhere else.
|
|
19
23
|
*
|
|
20
24
|
* `docOnlyHelpers` names the internal documentation helpers that are
|
|
21
25
|
* deliberately excluded from the public count.
|
|
@@ -31,7 +35,7 @@
|
|
|
31
35
|
export interface ComponentMeta {
|
|
32
36
|
/** Folder under src/components, and the exported component name */
|
|
33
37
|
name: string;
|
|
34
|
-
/** Display name — may differ from `name` (
|
|
38
|
+
/** Display name — may differ from `name` (NavList → "Nav list") */
|
|
35
39
|
label: string;
|
|
36
40
|
/** Website route segment under /components */
|
|
37
41
|
slug: string;
|
|
@@ -41,10 +45,22 @@ export interface ComponentMeta {
|
|
|
41
45
|
category: string;
|
|
42
46
|
/** Whether the component declares 'use client' */
|
|
43
47
|
client: boolean;
|
|
48
|
+
/** Folder under src/components when it differs from `name` (shared folders like Chart) */
|
|
49
|
+
folder?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface ComponentCategoryMeta {
|
|
52
|
+
/** Category id — the value each component's `category` field carries, and the website route segment under /components */
|
|
53
|
+
id: string;
|
|
54
|
+
/** Display name for the category, used for section headings and landing pages */
|
|
55
|
+
label: string;
|
|
56
|
+
/** One-line summary of what the category holds */
|
|
57
|
+
description: string;
|
|
44
58
|
}
|
|
45
59
|
/** Full metadata for every public component, alphabetical by name. */
|
|
46
60
|
export declare const componentMetadata: readonly ComponentMeta[];
|
|
47
|
-
/**
|
|
61
|
+
/** Full metadata for every component category, alphabetical by id. */
|
|
62
|
+
export declare const componentCategoryMetadata: readonly ComponentCategoryMeta[];
|
|
63
|
+
/** The category ids a component may belong to. */
|
|
48
64
|
export declare const componentCategories: readonly string[];
|
|
49
65
|
/**
|
|
50
66
|
* The official public component list, names only.
|
package/components/registry.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import registry from "./registry.json.js";
|
|
2
2
|
const componentMetadata = registry.components;
|
|
3
|
-
const
|
|
3
|
+
const componentCategoryMetadata = registry.categories;
|
|
4
|
+
const componentCategories = registry.categories.map((c) => c.id);
|
|
4
5
|
const componentRegistry = registry.components.map((c) => c.name);
|
|
5
6
|
const COMPONENT_COUNT = registry.components.length;
|
|
6
7
|
export {
|
|
7
8
|
COMPONENT_COUNT,
|
|
8
9
|
componentCategories,
|
|
10
|
+
componentCategoryMetadata,
|
|
9
11
|
componentMetadata,
|
|
10
12
|
componentRegistry
|
|
11
13
|
};
|