@app-studio/web 0.9.31 → 0.9.33
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/docs/components/Accordion.mdx +158 -0
- package/docs/components/Alert.mdx +123 -0
- package/docs/components/AspectRatio.mdx +55 -0
- package/docs/components/Avatar.mdx +85 -0
- package/docs/components/Background.mdx +522 -0
- package/docs/components/Badge.mdx +220 -0
- package/docs/components/Button.mdx +272 -0
- package/docs/components/Calendar.mdx +274 -0
- package/docs/components/Card.mdx +341 -0
- package/docs/components/Carousel.mdx +411 -0
- package/docs/components/Center.mdx +474 -0
- package/docs/components/Chart.mdx +232 -0
- package/docs/components/ChatInput.mdx +373 -0
- package/docs/components/Checkbox.mdx +66 -0
- package/docs/components/ColorInput.mdx +209 -0
- package/docs/components/ComboBox.mdx +364 -0
- package/docs/components/Command.mdx +252 -0
- package/docs/components/ContextMenu.mdx +219 -0
- package/docs/components/CountryPicker.mdx +123 -0
- package/docs/components/DatePicker.mdx +77 -0
- package/docs/components/DragAndDrop.mdx +539 -0
- package/docs/components/DropdownMenu.mdx +205 -0
- package/docs/components/File.mdx +8 -0
- package/docs/components/Flow.mdx +257 -0
- package/docs/components/Form.mdx +681 -0
- package/docs/components/Formik.mdx +621 -0
- package/docs/components/Gradient.mdx +271 -0
- package/docs/components/Horizontal.mdx +40 -0
- package/docs/components/HoverCard.mdx +140 -0
- package/docs/components/Icon.mdx +438 -0
- package/docs/components/Label.mdx +438 -0
- package/docs/components/Link.mdx +83 -0
- package/docs/components/Loader.mdx +527 -0
- package/docs/components/Menubar.mdx +124 -0
- package/docs/components/Message.mdx +571 -0
- package/docs/components/Modal.mdx +533 -0
- package/docs/components/NavigationMenu.mdx +165 -0
- package/docs/components/Pagination.mdx +150 -0
- package/docs/components/Password.mdx +121 -0
- package/docs/components/Resizable.mdx +148 -0
- package/docs/components/Select.mdx +126 -0
- package/docs/components/Separator.mdx +121 -0
- package/docs/components/Sidebar.mdx +147 -0
- package/docs/components/Slider.mdx +232 -0
- package/docs/components/Switch.mdx +62 -0
- package/docs/components/Table.mdx +409 -0
- package/docs/components/Tabs.mdx +215 -0
- package/docs/components/TagInput.mdx +528 -0
- package/docs/components/Text.mdx +163 -0
- package/docs/components/TextArea.mdx +136 -0
- package/docs/components/TextField.mdx +225 -0
- package/docs/components/Title.mdx +535 -0
- package/docs/components/Toast.mdx +165 -0
- package/docs/components/Toggle.mdx +141 -0
- package/docs/components/ToggleGroup.mdx +165 -0
- package/docs/components/Tooltip.mdx +191 -0
- package/docs/components/Tree.mdx +340 -0
- package/docs/components/Uploader.mdx +426 -0
- package/docs/components/Vertical.mdx +566 -0
- package/docs/components.md +285 -0
- package/package.json +1 -1
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# Tree
|
|
2
|
+
|
|
3
|
+
A component for displaying hierarchical data with expandable/collapsible nodes. Supports both a compound component pattern and a data-driven approach.
|
|
4
|
+
|
|
5
|
+
### **Import**
|
|
6
|
+
```tsx
|
|
7
|
+
import { Tree } from '@app-studio/web';
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
### **Default**
|
|
11
|
+
```tsx
|
|
12
|
+
import React from 'react';
|
|
13
|
+
import { Tree } from '@app-studio/web';
|
|
14
|
+
import { Text, Vertical } from 'app-studio';
|
|
15
|
+
import { FolderIcon, FileIcon, DocumentIcon } from '@app-studio/web';
|
|
16
|
+
|
|
17
|
+
export const DefaultTree = () => {
|
|
18
|
+
return (
|
|
19
|
+
<Vertical gap={20} width="100%" maxWidth={400}>
|
|
20
|
+
<Text marginBottom={10} fontWeight="bold">
|
|
21
|
+
Default Tree (Compound)
|
|
22
|
+
</Text>
|
|
23
|
+
<Tree
|
|
24
|
+
defaultExpandedItems={['files', 'documents']}
|
|
25
|
+
onItemSelect={(itemId, itemData) =>
|
|
26
|
+
console.log(`Compound item selected: ${itemId}`, itemData)
|
|
27
|
+
}
|
|
28
|
+
>
|
|
29
|
+
<Tree.Item value="files" icon={<FolderIcon size={16} />}>
|
|
30
|
+
<Tree.ItemLabel>Files</Tree.ItemLabel>
|
|
31
|
+
<Tree.ItemContent>
|
|
32
|
+
<Tree.Item value="documents" icon={<FolderIcon size={16} />}>
|
|
33
|
+
<Tree.ItemLabel>Documents</Tree.ItemLabel>
|
|
34
|
+
<Tree.ItemContent>
|
|
35
|
+
<Tree.Item value="doc1" icon={<DocumentIcon size={16} />}>
|
|
36
|
+
<Tree.ItemLabel>Document 1.docx</Tree.ItemLabel>
|
|
37
|
+
</Tree.Item>
|
|
38
|
+
<Tree.Item value="doc2" icon={<DocumentIcon size={16} />}>
|
|
39
|
+
<Tree.ItemLabel>Document 2.pdf</Tree.ItemLabel>
|
|
40
|
+
</Tree.Item>
|
|
41
|
+
</Tree.ItemContent>
|
|
42
|
+
</Tree.Item>
|
|
43
|
+
<Tree.Item value="images" icon={<FolderIcon size={16} />}>
|
|
44
|
+
<Tree.ItemLabel>Images</Tree.ItemLabel>
|
|
45
|
+
<Tree.ItemContent>
|
|
46
|
+
<Tree.Item value="img1" icon={<FileIcon size={16} />}>
|
|
47
|
+
<Tree.ItemLabel>image1.jpg</Tree.ItemLabel>
|
|
48
|
+
</Tree.Item>
|
|
49
|
+
<Tree.Item value="img2" icon={<FileIcon size={16} />}>
|
|
50
|
+
<Tree.ItemLabel>image2.png</Tree.ItemLabel>
|
|
51
|
+
</Tree.Item>
|
|
52
|
+
</Tree.ItemContent>
|
|
53
|
+
</Tree.Item>
|
|
54
|
+
</Tree.ItemContent>
|
|
55
|
+
</Tree.Item>
|
|
56
|
+
</Tree>
|
|
57
|
+
</Vertical>
|
|
58
|
+
);
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### **Data-Driven**
|
|
63
|
+
```tsx
|
|
64
|
+
import React from 'react';
|
|
65
|
+
import { Tree } from '@app-studio/web';
|
|
66
|
+
import { Text, Vertical } from 'app-studio';
|
|
67
|
+
import { FolderIcon, FileIcon, DocumentIcon } from '@app-studio/web';
|
|
68
|
+
import { TreeNode } from '@app-studio/web';
|
|
69
|
+
|
|
70
|
+
export const DataDrivenTree = () => {
|
|
71
|
+
const treeData: TreeNode[] = [
|
|
72
|
+
{
|
|
73
|
+
id: 'files',
|
|
74
|
+
label: 'Files',
|
|
75
|
+
icon: <FolderIcon size={16} />,
|
|
76
|
+
children: [
|
|
77
|
+
{
|
|
78
|
+
id: 'documents',
|
|
79
|
+
label: 'Documents',
|
|
80
|
+
icon: <FolderIcon size={16} />,
|
|
81
|
+
children: [
|
|
82
|
+
{
|
|
83
|
+
id: 'doc1',
|
|
84
|
+
label: 'Document 1.docx',
|
|
85
|
+
icon: <DocumentIcon size={16} />,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'doc2',
|
|
89
|
+
label: 'Document 2.pdf',
|
|
90
|
+
icon: <DocumentIcon size={16} />,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 'images',
|
|
96
|
+
label: 'Images',
|
|
97
|
+
icon: <FolderIcon size={16} />,
|
|
98
|
+
children: [
|
|
99
|
+
{
|
|
100
|
+
id: 'img1',
|
|
101
|
+
label: 'image1.jpg',
|
|
102
|
+
icon: <FileIcon size={16} />,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'img2',
|
|
106
|
+
label: 'image2.png',
|
|
107
|
+
icon: <FileIcon size={16} />,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: 'videos',
|
|
113
|
+
label: 'Videos (Empty)',
|
|
114
|
+
icon: <FolderIcon size={16} />,
|
|
115
|
+
children: [], // Example of an empty expandable folder
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: 'report',
|
|
119
|
+
label: 'Annual Report.docx',
|
|
120
|
+
icon: <DocumentIcon size={16} />,
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<Vertical gap={20} width="100%" maxWidth={400}>
|
|
128
|
+
<Text marginBottom={10} fontWeight="bold">
|
|
129
|
+
Data-Driven Tree
|
|
130
|
+
</Text>
|
|
131
|
+
<Tree
|
|
132
|
+
items={treeData}
|
|
133
|
+
defaultExpandedItems={['files', 'documents']}
|
|
134
|
+
onItemSelect={(itemId, itemData) =>
|
|
135
|
+
console.log(`Selected item: ${itemId}`, itemData)
|
|
136
|
+
}
|
|
137
|
+
/>
|
|
138
|
+
</Vertical>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### **With Drag and Drop**
|
|
144
|
+
```tsx
|
|
145
|
+
import React, { useState } from 'react';
|
|
146
|
+
import { Tree } from '@app-studio/web';
|
|
147
|
+
import { Text, View, Vertical } from 'app-studio';
|
|
148
|
+
import { FolderIcon, FileIcon, DragHandleIcon } from '@app-studio/web';
|
|
149
|
+
import { TreeNode } from '@app-studio/web';
|
|
150
|
+
|
|
151
|
+
const CustomDragHandleIcon = () => (
|
|
152
|
+
<DragHandleIcon size={16} color="color.gray.400" />
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
export const DraggableTree = () => {
|
|
156
|
+
const [expandedItems, setExpandedItems] = useState(['menu-1', 'menu-2']);
|
|
157
|
+
|
|
158
|
+
const [items, setItems] = useState<TreeNode[]>([
|
|
159
|
+
{
|
|
160
|
+
id: 'menu-1',
|
|
161
|
+
label: 'Menu Item 1',
|
|
162
|
+
icon: <FolderIcon size={16} />,
|
|
163
|
+
children: [
|
|
164
|
+
{
|
|
165
|
+
id: 'submenu-1-1',
|
|
166
|
+
label: 'Submenu Item 1.1',
|
|
167
|
+
icon: <FileIcon size={16} />
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: 'menu-2',
|
|
173
|
+
label: 'Menu Item 2',
|
|
174
|
+
icon: <FolderIcon size={16} />,
|
|
175
|
+
children: [
|
|
176
|
+
{
|
|
177
|
+
id: 'submenu-2-1',
|
|
178
|
+
label: 'Submenu Item 2.1',
|
|
179
|
+
icon: <FileIcon size={16} />
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
]);
|
|
184
|
+
|
|
185
|
+
const handleItemsReorder = (newItems: TreeNode[]) => {
|
|
186
|
+
setItems(newItems);
|
|
187
|
+
console.log('Items reordered:', newItems);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const handleDragStart = (itemId: string) => {
|
|
191
|
+
console.log(`Started dragging: ${itemId}`);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const handleDragEnd = (itemId: string) => {
|
|
195
|
+
console.log(`Finished dragging: ${itemId}`);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
<View width="300px">
|
|
200
|
+
<Tree
|
|
201
|
+
items={items}
|
|
202
|
+
expandedItems={expandedItems}
|
|
203
|
+
onExpandedItemsChange={setExpandedItems}
|
|
204
|
+
allowDragAndDrop={true}
|
|
205
|
+
dragHandleIcon={<CustomDragHandleIcon />}
|
|
206
|
+
onItemsReorder={handleItemsReorder}
|
|
207
|
+
onDragStart={handleDragStart}
|
|
208
|
+
onDragEnd={handleDragEnd}
|
|
209
|
+
/>
|
|
210
|
+
</View>
|
|
211
|
+
);
|
|
212
|
+
};
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### **Variants and Sizes**
|
|
216
|
+
```tsx
|
|
217
|
+
import React from 'react';
|
|
218
|
+
import { Tree } from '@app-studio/web';
|
|
219
|
+
import { Text, Horizontal, Vertical } from 'app-studio';
|
|
220
|
+
import { FolderIcon, FileIcon } from '@app-studio/web';
|
|
221
|
+
import { TreeNode } from '@app-studio/web';
|
|
222
|
+
|
|
223
|
+
export const TreeVariants = () => {
|
|
224
|
+
const treeData: TreeNode[] = [
|
|
225
|
+
{
|
|
226
|
+
id: 'root-fx',
|
|
227
|
+
label: 'Project',
|
|
228
|
+
icon: <FolderIcon size={16} />,
|
|
229
|
+
children: [
|
|
230
|
+
{
|
|
231
|
+
id: 'src-fx',
|
|
232
|
+
label: 'src',
|
|
233
|
+
icon: <FolderIcon size={16} />,
|
|
234
|
+
children: [
|
|
235
|
+
{
|
|
236
|
+
id: 'components-fx',
|
|
237
|
+
label: 'components',
|
|
238
|
+
icon: <FileIcon size={16} />,
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: 'utils-fx',
|
|
242
|
+
label: 'utils',
|
|
243
|
+
icon: <FileIcon size={16} />,
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
id: 'public-fx',
|
|
249
|
+
label: 'public',
|
|
250
|
+
icon: <FolderIcon size={16} />,
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
|
|
256
|
+
return (
|
|
257
|
+
<Vertical gap={20}>
|
|
258
|
+
<Horizontal gap={30} alignItems="flex-start" flexWrap="wrap">
|
|
259
|
+
<Vertical gap={10}>
|
|
260
|
+
<Text fontWeight="medium">Default Variant</Text>
|
|
261
|
+
<Tree
|
|
262
|
+
items={treeData}
|
|
263
|
+
defaultExpandedItems={['root-fx', 'src-fx']}
|
|
264
|
+
variant="default"
|
|
265
|
+
/>
|
|
266
|
+
</Vertical>
|
|
267
|
+
|
|
268
|
+
<Vertical gap={10}>
|
|
269
|
+
<Text fontWeight="medium">Outline Variant</Text>
|
|
270
|
+
<Tree
|
|
271
|
+
items={treeData}
|
|
272
|
+
defaultExpandedItems={['root-fx', 'src-fx']}
|
|
273
|
+
variant="outline"
|
|
274
|
+
/>
|
|
275
|
+
</Vertical>
|
|
276
|
+
|
|
277
|
+
<Vertical gap={10}>
|
|
278
|
+
<Text fontWeight="medium">Filled Variant</Text>
|
|
279
|
+
<Tree
|
|
280
|
+
items={treeData}
|
|
281
|
+
defaultExpandedItems={['root-fx', 'src-fx']}
|
|
282
|
+
variant="filled"
|
|
283
|
+
/>
|
|
284
|
+
</Vertical>
|
|
285
|
+
</Horizontal>
|
|
286
|
+
|
|
287
|
+
<Horizontal gap={30} alignItems="flex-start" flexWrap="wrap">
|
|
288
|
+
<Vertical gap={10}>
|
|
289
|
+
<Text fontWeight="medium">Small Size</Text>
|
|
290
|
+
<Tree
|
|
291
|
+
items={treeData}
|
|
292
|
+
defaultExpandedItems={['root-fx', 'src-fx']}
|
|
293
|
+
size="sm"
|
|
294
|
+
/>
|
|
295
|
+
</Vertical>
|
|
296
|
+
|
|
297
|
+
<Vertical gap={10}>
|
|
298
|
+
<Text fontWeight="medium">Medium Size (Default)</Text>
|
|
299
|
+
<Tree
|
|
300
|
+
items={treeData}
|
|
301
|
+
defaultExpandedItems={['root-fx', 'src-fx']}
|
|
302
|
+
size="md"
|
|
303
|
+
/>
|
|
304
|
+
</Vertical>
|
|
305
|
+
|
|
306
|
+
<Vertical gap={10}>
|
|
307
|
+
<Text fontWeight="medium">Large Size</Text>
|
|
308
|
+
<Tree
|
|
309
|
+
items={treeData}
|
|
310
|
+
defaultExpandedItems={['root-fx', 'src-fx']}
|
|
311
|
+
size="lg"
|
|
312
|
+
/>
|
|
313
|
+
</Vertical>
|
|
314
|
+
</Horizontal>
|
|
315
|
+
</Vertical>
|
|
316
|
+
);
|
|
317
|
+
};
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### **Props**
|
|
321
|
+
|
|
322
|
+
| Prop | Type | Default | Description |
|
|
323
|
+
| ---- | ---- | ------- | ----------- |
|
|
324
|
+
| children | React.ReactNode | undefined | Child elements for compound component pattern |
|
|
325
|
+
| items | TreeNode[] | undefined | Data-driven approach: array of tree nodes |
|
|
326
|
+
| size | 'sm' \| 'md' \| 'lg' | 'md' | Size of the tree items |
|
|
327
|
+
| variant | 'default' \| 'outline' \| 'filled' | 'default' | Visual variant of the tree items |
|
|
328
|
+
| defaultExpandedItems | string[] | [] | IDs of initially expanded items (uncontrolled mode) |
|
|
329
|
+
| expandedItems | string[] | undefined | IDs of expanded items (controlled mode) |
|
|
330
|
+
| onExpandedItemsChange | (expandedItems: string[]) => void | undefined | Callback when expanded items change |
|
|
331
|
+
| onItemSelect | (itemId: string, item?: TreeNode) => void | undefined | Callback when an item is selected |
|
|
332
|
+
| selectedItem | string | undefined | ID of the currently selected item (controlled mode) |
|
|
333
|
+
| defaultSelectedItem | string | undefined | ID of the initially selected item (uncontrolled mode) |
|
|
334
|
+
| multiSelect | boolean | false | Whether to allow multiple selection |
|
|
335
|
+
| allowDragAndDrop | boolean | false | Whether to enable drag and drop functionality |
|
|
336
|
+
| dragHandleIcon | React.ReactNode | undefined | Custom icon to use for the drag handle |
|
|
337
|
+
| onItemsReorder | (items: TreeNode[]) => void | undefined | Callback when items are reordered via drag and drop |
|
|
338
|
+
| onDragStart | (itemId: string, event: React.DragEvent) => void | undefined | Callback when drag starts on an item |
|
|
339
|
+
| onDragEnd | (itemId: string) => void | undefined | Callback when drag ends |
|
|
340
|
+
| views | object | {} | Custom styling for different parts of the component |
|