@app-studio/web 0.9.17 → 0.9.19
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/components/AuthGuard/index.d.ts +1 -1
- package/dist/utils/request.d.ts +2 -2
- package/dist/web.cjs.development.js +41 -46
- package/dist/web.cjs.development.js.map +1 -1
- package/dist/web.cjs.production.min.js +1 -1
- package/dist/web.cjs.production.min.js.map +1 -1
- package/dist/web.esm.js +43 -48
- package/dist/web.esm.js.map +1 -1
- package/dist/web.umd.development.js +45 -45
- package/dist/web.umd.development.js.map +1 -1
- package/dist/web.umd.production.min.js +1 -1
- package/dist/web.umd.production.min.js.map +1 -1
- package/docs/README.md +52 -0
- package/docs/adk-components.md +316 -0
- package/docs/adk-quick-start.md +294 -0
- package/docs/api-integration.md +801 -0
- package/docs/api-reference/README.md +103 -0
- package/docs/api-reference/data-display/flow.md +220 -0
- package/docs/api-reference/data-display/tree.md +210 -0
- package/docs/api-reference/form/chat-input.md +210 -0
- package/docs/api-reference/utility/button.md +145 -0
- package/docs/api-reference/utility/title.md +301 -0
- package/docs/app-studio.md +302 -0
- package/docs/component-development/guide.md +546 -0
- package/docs/contributing/documentation.md +153 -0
- package/docs/conventions.md +536 -0
- package/docs/design-system/theming.md +299 -0
- package/docs/documentation-system.md +143 -0
- package/docs/getting-started/component-usage.md +211 -0
- package/docs/getting-started/introduction.md +114 -0
- package/docs/guide.md +550 -0
- package/docs/integration-guide.md +449 -0
- package/docs/tutorials/README.md +51 -0
- package/docs/tutorials/basic/creating-a-simple-form.md +566 -0
- package/package.json +3 -2
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
This section provides detailed API documentation for all components in the App Studio Web Component Library.
|
|
4
|
+
|
|
5
|
+
## Component Categories
|
|
6
|
+
|
|
7
|
+
- [Layout Components](#layout-components)
|
|
8
|
+
- [Form Components](#form-components)
|
|
9
|
+
- [Navigation Components](#navigation-components)
|
|
10
|
+
- [Feedback Components](#feedback-components)
|
|
11
|
+
- [Data Display Components](#data-display-components)
|
|
12
|
+
- [Utility Components](#utility-components)
|
|
13
|
+
- [Interactive Components](#interactive-components)
|
|
14
|
+
|
|
15
|
+
## Layout Components
|
|
16
|
+
|
|
17
|
+
- [View](./layout/view.md) - Base container component
|
|
18
|
+
- [Horizontal](./layout/horizontal.md) - Horizontal flex container
|
|
19
|
+
- [Vertical](./layout/vertical.md) - Vertical flex container
|
|
20
|
+
- [Center](./layout/center.md) - Centered flex container
|
|
21
|
+
- [AspectRatio](./layout/aspect-ratio.md) - Container with fixed aspect ratio
|
|
22
|
+
- [Separator](./layout/separator.md) - Visual or semantic separator
|
|
23
|
+
- [Resizable](./layout/resizable.md) - Resizable container
|
|
24
|
+
|
|
25
|
+
## Form Components
|
|
26
|
+
|
|
27
|
+
- [Checkbox](./form/checkbox.md) - Checkbox input
|
|
28
|
+
- [ChatInput](./form/chat-input.md) - Chat input with file uploads and prompt examples
|
|
29
|
+
- [Radio](./form/radio.md) - Radio input
|
|
30
|
+
- [Select](./form/select.md) - Select dropdown
|
|
31
|
+
- [Switch](./form/switch.md) - Toggle switch
|
|
32
|
+
- [TextArea](./form/text-area.md) - Multi-line text input
|
|
33
|
+
- [TextField](./form/text-field.md) - Single-line text input
|
|
34
|
+
- [OTPInput](./form/otp-input.md) - One-time password input
|
|
35
|
+
|
|
36
|
+
## Navigation Components
|
|
37
|
+
|
|
38
|
+
- [Accordion](./navigation/accordion.md) - Expandable content sections
|
|
39
|
+
- [Menubar](./navigation/menubar.md) - Horizontal menu
|
|
40
|
+
- [NavigationMenu](./navigation/navigation-menu.md) - Navigation menu
|
|
41
|
+
- [Pagination](./navigation/pagination.md) - Page navigation
|
|
42
|
+
- [Sidebar](./navigation/sidebar.md) - Side navigation
|
|
43
|
+
- [Tabs](./navigation/tabs.md) - Tabbed interface
|
|
44
|
+
|
|
45
|
+
## Feedback Components
|
|
46
|
+
|
|
47
|
+
- [Alert](./feedback/alert.md) - Informational message
|
|
48
|
+
- [Modal](./feedback/modal.md) - Dialog box
|
|
49
|
+
- [Toast](./feedback/toast.md) - Temporary notification
|
|
50
|
+
- [Tooltip](./feedback/tooltip.md) - Contextual information
|
|
51
|
+
|
|
52
|
+
## Data Display Components
|
|
53
|
+
|
|
54
|
+
- [Avatar](./data-display/avatar.md) - User or entity representation
|
|
55
|
+
- [Badge](./data-display/badge.md) - Small count or status indicator
|
|
56
|
+
- [Card](./data-display/card.md) - Content container
|
|
57
|
+
- [Table](./data-display/table.md) - Tabular data
|
|
58
|
+
- [Chart](./data-display/chart.md) - Data visualization
|
|
59
|
+
- [Flow](./data-display/flow.md) - Interactive workflow diagrams and flowcharts
|
|
60
|
+
- [Tree](./data-display/tree.md) - Hierarchical tree structure
|
|
61
|
+
|
|
62
|
+
## Utility Components
|
|
63
|
+
|
|
64
|
+
- [Button](./utility/button.md) - Interactive button
|
|
65
|
+
- [Gradient](./utility/gradient.md) - Gradient background
|
|
66
|
+
- [Loader](./utility/loader.md) - Loading indicator
|
|
67
|
+
- [Text](./utility/text.md) - Text display
|
|
68
|
+
|
|
69
|
+
## Interactive Components
|
|
70
|
+
|
|
71
|
+
- [Carousel](./interactive/carousel.md) - Slideshow
|
|
72
|
+
- [ContextMenu](./interactive/context-menu.md) - Right-click menu
|
|
73
|
+
- [DropdownMenu](./interactive/dropdown-menu.md) - Dropdown menu
|
|
74
|
+
- [HoverCard](./interactive/hover-card.md) - Card that appears on hover
|
|
75
|
+
- [Slider](./interactive/slider.md) - Range input
|
|
76
|
+
- [Toggle](./interactive/toggle.md) - Toggle button
|
|
77
|
+
- [ToggleGroup](./interactive/toggle-group.md) - Group of toggle buttons
|
|
78
|
+
|
|
79
|
+
## Component API Structure
|
|
80
|
+
|
|
81
|
+
Each component's API documentation follows a consistent structure:
|
|
82
|
+
|
|
83
|
+
1. **Import** - How to import the component
|
|
84
|
+
2. **Props** - Detailed list of props with types and descriptions
|
|
85
|
+
3. **Examples** - Basic usage examples
|
|
86
|
+
4. **Variants** - Available variants and their usage
|
|
87
|
+
5. **Compound Components** - Sub-components (if applicable)
|
|
88
|
+
6. **Accessibility** - Accessibility features and considerations
|
|
89
|
+
7. **Best Practices** - Recommended usage patterns
|
|
90
|
+
|
|
91
|
+
## Generating API Documentation
|
|
92
|
+
|
|
93
|
+
Component API documentation is automatically generated using the `bot-doc` tool. To regenerate documentation for a component:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npm run bot-doc -- ComponentName src/components/ComponentName
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
To regenerate documentation for all components:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm run create-docs
|
|
103
|
+
```
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Flow
|
|
2
|
+
|
|
3
|
+
The Flow component is used to create interactive workflow diagrams and flowcharts with support for node connections, drag-and-drop functionality, and viewport controls.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```jsx
|
|
8
|
+
import { Flow } from '@app-studio/web';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| ---- | ---- | ------- | ----------- |
|
|
15
|
+
| nodes | FlowNode[] | [] | Array of nodes in the flow |
|
|
16
|
+
| edges | NodeConnection[] | [] | Array of edges/connections between nodes |
|
|
17
|
+
| size | 'sm' \| 'md' \| 'lg' | 'md' | Size of the flow nodes |
|
|
18
|
+
| variant | 'default' \| 'outline' \| 'filled' | 'default' | Visual variant of the flow nodes |
|
|
19
|
+
| direction | 'horizontal' \| 'vertical' | 'vertical' | Direction of the flow layout |
|
|
20
|
+
| showControls | boolean | true | Whether to show viewport controls (zoom in/out, reset) |
|
|
21
|
+
| allowAddingNodes | boolean | true | Whether to allow adding new nodes |
|
|
22
|
+
| allowDraggingNodes | boolean | true | Whether to allow dragging nodes |
|
|
23
|
+
| selectedNodeId | string | undefined | ID of the currently selected node |
|
|
24
|
+
| onNodeSelect | (nodeId: string \| null) => void | undefined | Callback when a node is selected |
|
|
25
|
+
| onNodesChange | (nodes: FlowNode[]) => void | undefined | Callback when nodes change |
|
|
26
|
+
| onEdgesChange | (edges: NodeConnection[]) => void | undefined | Callback when edges change |
|
|
27
|
+
| onNodeAdd | (node: FlowNode) => void | undefined | Callback when a node is added |
|
|
28
|
+
| onNodeDragStart | (nodeId: string) => void | undefined | Callback when node dragging starts |
|
|
29
|
+
| onNodeDrag | (nodeId: string, position: NodePosition) => void | undefined | Callback during node dragging |
|
|
30
|
+
| onNodeDragEnd | (nodeId: string, position: NodePosition) => void | undefined | Callback when node dragging ends |
|
|
31
|
+
| viewport | FlowViewport | { zoom: 1, x: 0, y: 0 } | Current viewport state (zoom level and position) |
|
|
32
|
+
| onViewportChange | (viewport: FlowViewport) => void | undefined | Callback when viewport changes |
|
|
33
|
+
| views | object | {} | Custom styling for different parts of the component |
|
|
34
|
+
|
|
35
|
+
## Node Structure
|
|
36
|
+
|
|
37
|
+
The `FlowNode` interface defines the structure of nodes in the Flow component:
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
interface FlowNode {
|
|
41
|
+
id: string;
|
|
42
|
+
type?: 'default' | 'start' | 'end' | 'decision' | 'process' | string;
|
|
43
|
+
position: { x: number; y: number };
|
|
44
|
+
data?: {
|
|
45
|
+
label?: string;
|
|
46
|
+
subtitle?: string;
|
|
47
|
+
icon?: React.ReactNode;
|
|
48
|
+
number?: number;
|
|
49
|
+
[key: string]: any;
|
|
50
|
+
};
|
|
51
|
+
selected?: boolean;
|
|
52
|
+
isDragging?: boolean;
|
|
53
|
+
draggable?: boolean;
|
|
54
|
+
style?: ViewProps;
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Edge Structure
|
|
59
|
+
|
|
60
|
+
The `NodeConnection` interface defines the structure of edges in the Flow component:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
interface NodeConnection {
|
|
64
|
+
id: string;
|
|
65
|
+
source: string;
|
|
66
|
+
target: string;
|
|
67
|
+
label?: string;
|
|
68
|
+
style?: ViewProps;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Examples
|
|
73
|
+
|
|
74
|
+
### Basic Usage
|
|
75
|
+
|
|
76
|
+
```jsx
|
|
77
|
+
import React, { useState } from 'react';
|
|
78
|
+
import { Flow } from '@app-studio/web';
|
|
79
|
+
import { View } from 'app-studio';
|
|
80
|
+
|
|
81
|
+
export const BasicFlow = () => {
|
|
82
|
+
// Initial nodes and edges
|
|
83
|
+
const [nodes, setNodes] = useState([
|
|
84
|
+
{
|
|
85
|
+
id: 'node-1',
|
|
86
|
+
position: { x: 50, y: 50 },
|
|
87
|
+
data: {
|
|
88
|
+
label: 'Start Node',
|
|
89
|
+
subtitle: 'Begin here'
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'node-2',
|
|
94
|
+
position: { x: 50, y: 200 },
|
|
95
|
+
data: {
|
|
96
|
+
label: 'Process Node',
|
|
97
|
+
subtitle: 'Do something'
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
const [edges, setEdges] = useState([
|
|
103
|
+
{ id: 'edge-1-2', source: 'node-1', target: 'node-2' },
|
|
104
|
+
]);
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<View height="400px" border="1px solid" borderColor="color.gray.200" borderRadius={8}>
|
|
108
|
+
<Flow
|
|
109
|
+
nodes={nodes}
|
|
110
|
+
edges={edges}
|
|
111
|
+
onNodesChange={setNodes}
|
|
112
|
+
onEdgesChange={setEdges}
|
|
113
|
+
/>
|
|
114
|
+
</View>
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### With Node Addition
|
|
120
|
+
|
|
121
|
+
```jsx
|
|
122
|
+
import React, { useState } from 'react';
|
|
123
|
+
import { Flow } from '@app-studio/web';
|
|
124
|
+
import { View } from 'app-studio';
|
|
125
|
+
|
|
126
|
+
export const FlowWithNodeAddition = () => {
|
|
127
|
+
const [nodes, setNodes] = useState([
|
|
128
|
+
{
|
|
129
|
+
id: 'node-1',
|
|
130
|
+
position: { x: 50, y: 50 },
|
|
131
|
+
data: { label: 'Start', subtitle: 'Begin workflow' },
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
id: 'node-2',
|
|
135
|
+
position: { x: 50, y: 200 },
|
|
136
|
+
data: { label: 'Process', subtitle: 'Do something' },
|
|
137
|
+
},
|
|
138
|
+
]);
|
|
139
|
+
|
|
140
|
+
const [edges, setEdges] = useState([
|
|
141
|
+
{ id: 'edge-1-2', source: 'node-1', target: 'node-2' },
|
|
142
|
+
]);
|
|
143
|
+
|
|
144
|
+
const [selectedNodeId, setSelectedNodeId] = useState(null);
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
<View height="400px" border="1px solid" borderColor="color.gray.200" borderRadius={8}>
|
|
148
|
+
<Flow
|
|
149
|
+
nodes={nodes}
|
|
150
|
+
edges={edges}
|
|
151
|
+
onNodesChange={setNodes}
|
|
152
|
+
onEdgesChange={setEdges}
|
|
153
|
+
selectedNodeId={selectedNodeId}
|
|
154
|
+
onNodeSelect={setSelectedNodeId}
|
|
155
|
+
allowAddingNodes={true}
|
|
156
|
+
onNodeAdd={(newNode) => {
|
|
157
|
+
setNodes((prevNodes) => [...prevNodes, newNode]);
|
|
158
|
+
}}
|
|
159
|
+
/>
|
|
160
|
+
</View>
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Compound Components
|
|
166
|
+
|
|
167
|
+
The Flow component uses a compound component pattern with the following sub-components:
|
|
168
|
+
|
|
169
|
+
```jsx
|
|
170
|
+
// These are primarily for potential direct use or a more componentized future version
|
|
171
|
+
Flow.Node // Renders a single node
|
|
172
|
+
Flow.Edge // Renders a connection between nodes
|
|
173
|
+
Flow.Controls // Renders viewport controls
|
|
174
|
+
Flow.AddNodeButton // Renders a button to add a new node
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Customization
|
|
178
|
+
|
|
179
|
+
The Flow component can be customized using the `views` prop:
|
|
180
|
+
|
|
181
|
+
```jsx
|
|
182
|
+
<Flow
|
|
183
|
+
// ...other props
|
|
184
|
+
views={{
|
|
185
|
+
container: { /* styles for the main flow container */ },
|
|
186
|
+
node: {
|
|
187
|
+
container: { /* styles for the node's root View */ },
|
|
188
|
+
content: { /* styles for the content wrapper inside the node */ },
|
|
189
|
+
icon: { /* styles for the node's icon View */ },
|
|
190
|
+
},
|
|
191
|
+
edge: {
|
|
192
|
+
path: { /* styles for the SVG path */ },
|
|
193
|
+
label: { /* styles for the edge label */ },
|
|
194
|
+
},
|
|
195
|
+
controls: {
|
|
196
|
+
container: { /* styles for the controls container */ },
|
|
197
|
+
button: { /* styles for individual control buttons */ },
|
|
198
|
+
},
|
|
199
|
+
addNodeButton: { /* styles for the add node button */ },
|
|
200
|
+
}}
|
|
201
|
+
/>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Accessibility
|
|
205
|
+
|
|
206
|
+
The Flow component implements the following accessibility features:
|
|
207
|
+
|
|
208
|
+
- Keyboard navigation for selecting nodes
|
|
209
|
+
- ARIA attributes for interactive elements
|
|
210
|
+
- Focus management for controls and nodes
|
|
211
|
+
- Proper contrast for node and edge colors
|
|
212
|
+
|
|
213
|
+
## Best Practices
|
|
214
|
+
|
|
215
|
+
- Provide clear labels and subtitles for nodes to improve understanding
|
|
216
|
+
- Use consistent node types and styling for similar functionality
|
|
217
|
+
- Implement proper error handling for node and edge operations
|
|
218
|
+
- Consider viewport size when determining initial node positions
|
|
219
|
+
- Use the `onNodeAdd` callback to validate new node positions
|
|
220
|
+
- Implement undo/redo functionality for node operations when needed
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Tree
|
|
2
|
+
|
|
3
|
+
The Tree component is used for displaying hierarchical data with expandable/collapsible nodes. It supports both a compound component pattern and a data-driven approach.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```jsx
|
|
8
|
+
import { Tree } from '@app-studio/web';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Default | Description |
|
|
14
|
+
| ---- | ---- | ------- | ----------- |
|
|
15
|
+
| children | React.ReactNode | undefined | Child elements for compound component pattern (e.g., `<Tree.Item />`) |
|
|
16
|
+
| items | TreeNode[] | undefined | Data-driven approach: array of tree nodes |
|
|
17
|
+
| size | 'sm' \| 'md' \| 'lg' | 'md' | Size of the tree items |
|
|
18
|
+
| variant | 'default' \| 'outline' \| 'filled' | 'default' | Visual variant of the tree items |
|
|
19
|
+
| defaultExpandedItems | string[] | [] | IDs of initially expanded items (uncontrolled mode) |
|
|
20
|
+
| expandedItems | string[] | undefined | IDs of expanded items (controlled mode) |
|
|
21
|
+
| onExpandedItemsChange | (expandedItems: string[]) => void | undefined | Callback when expanded items change |
|
|
22
|
+
| onItemSelect | (itemId: string, item?: TreeNode) => void | undefined | Callback when an item is selected |
|
|
23
|
+
| selectedItem | string | undefined | ID of the currently selected item (controlled mode) |
|
|
24
|
+
| defaultSelectedItem | string | undefined | ID of the initially selected item (uncontrolled mode) |
|
|
25
|
+
| multiSelect | boolean | false | Whether to allow multiple selection |
|
|
26
|
+
| allowDragAndDrop | boolean | false | Whether to enable drag and drop functionality |
|
|
27
|
+
| dragHandleIcon | React.ReactNode | undefined | Custom icon to use for the drag handle |
|
|
28
|
+
| onItemsReorder | (items: TreeNode[]) => void | undefined | Callback when items are reordered via drag and drop |
|
|
29
|
+
| onDragStart | (itemId: string, event: React.DragEvent) => void | undefined | Callback when drag starts on an item |
|
|
30
|
+
| onDragEnd | (itemId: string) => void | undefined | Callback when drag ends |
|
|
31
|
+
| views | object | {} | Custom styling for different parts of the component |
|
|
32
|
+
|
|
33
|
+
## TreeNode Structure
|
|
34
|
+
|
|
35
|
+
The `TreeNode` interface defines the structure of nodes in the data-driven approach:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
interface TreeNode {
|
|
39
|
+
id: string;
|
|
40
|
+
label: string;
|
|
41
|
+
icon?: React.ReactNode;
|
|
42
|
+
children?: TreeNode[];
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
data?: any;
|
|
45
|
+
style?: ViewProps;
|
|
46
|
+
isDragging?: boolean;
|
|
47
|
+
draggable?: boolean;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
|
|
53
|
+
### Compound Component Pattern
|
|
54
|
+
|
|
55
|
+
```jsx
|
|
56
|
+
import React from 'react';
|
|
57
|
+
import { Tree } from '@app-studio/web';
|
|
58
|
+
import { FolderIcon, FileIcon } from '@app-studio/web';
|
|
59
|
+
|
|
60
|
+
export const CompoundTree = () => {
|
|
61
|
+
return (
|
|
62
|
+
<Tree defaultExpandedItems={['parent-1']}>
|
|
63
|
+
<Tree.Item value="parent-1" icon={<FolderIcon />}>
|
|
64
|
+
<Tree.ItemLabel>Parent Item 1</Tree.ItemLabel>
|
|
65
|
+
<Tree.ItemContent>
|
|
66
|
+
<Tree.Item value="child-1-1" icon={<FileIcon />}>
|
|
67
|
+
<Tree.ItemLabel>Child Item 1.1</Tree.ItemLabel>
|
|
68
|
+
</Tree.Item>
|
|
69
|
+
<Tree.Item value="child-1-2" icon={<FileIcon />}>
|
|
70
|
+
<Tree.ItemLabel>Child Item 1.2</Tree.ItemLabel>
|
|
71
|
+
</Tree.Item>
|
|
72
|
+
</Tree.ItemContent>
|
|
73
|
+
</Tree.Item>
|
|
74
|
+
<Tree.Item value="parent-2" icon={<FolderIcon />}>
|
|
75
|
+
<Tree.ItemLabel>Parent Item 2</Tree.ItemLabel>
|
|
76
|
+
<Tree.ItemContent>
|
|
77
|
+
<Tree.Item value="child-2-1" icon={<FileIcon />}>
|
|
78
|
+
<Tree.ItemLabel>Child Item 2.1</Tree.ItemLabel>
|
|
79
|
+
</Tree.Item>
|
|
80
|
+
</Tree.ItemContent>
|
|
81
|
+
</Tree.Item>
|
|
82
|
+
</Tree>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Data-Driven Approach
|
|
88
|
+
|
|
89
|
+
```jsx
|
|
90
|
+
import React from 'react';
|
|
91
|
+
import { Tree } from '@app-studio/web';
|
|
92
|
+
import { FolderIcon, FileIcon } from '@app-studio/web';
|
|
93
|
+
|
|
94
|
+
export const DataDrivenTree = () => {
|
|
95
|
+
const treeNodes = [
|
|
96
|
+
{
|
|
97
|
+
id: 'parent-1',
|
|
98
|
+
label: 'Parent Item 1',
|
|
99
|
+
icon: <FolderIcon />,
|
|
100
|
+
children: [
|
|
101
|
+
{ id: 'child-1-1', label: 'Child Item 1.1', icon: <FileIcon /> },
|
|
102
|
+
{ id: 'child-1-2', label: 'Child Item 1.2', icon: <FileIcon /> }
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: 'parent-2',
|
|
107
|
+
label: 'Parent Item 2',
|
|
108
|
+
icon: <FolderIcon />,
|
|
109
|
+
children: [
|
|
110
|
+
{ id: 'child-2-1', label: 'Child Item 2.1', icon: <FileIcon /> }
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<Tree
|
|
117
|
+
items={treeNodes}
|
|
118
|
+
defaultExpandedItems={['parent-1']}
|
|
119
|
+
onItemSelect={(itemId, item) => console.log(`Selected: ${itemId}`, item)}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
};
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### With Drag and Drop
|
|
126
|
+
|
|
127
|
+
```jsx
|
|
128
|
+
import React, { useState } from 'react';
|
|
129
|
+
import { Tree } from '@app-studio/web';
|
|
130
|
+
import { FolderIcon, FileIcon } from '@app-studio/web';
|
|
131
|
+
|
|
132
|
+
export const DraggableTree = () => {
|
|
133
|
+
const [menuItems, setMenuItems] = useState([
|
|
134
|
+
{
|
|
135
|
+
id: 'menu-1',
|
|
136
|
+
label: 'Menu Item 1',
|
|
137
|
+
icon: <FolderIcon />,
|
|
138
|
+
children: [
|
|
139
|
+
{ id: 'submenu-1-1', label: 'Submenu Item 1.1', icon: <FileIcon /> }
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: 'menu-2',
|
|
144
|
+
label: 'Menu Item 2',
|
|
145
|
+
icon: <FolderIcon />,
|
|
146
|
+
children: [
|
|
147
|
+
{ id: 'submenu-2-1', label: 'Submenu Item 2.1', icon: <FileIcon /> }
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
]);
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<Tree
|
|
154
|
+
items={menuItems}
|
|
155
|
+
allowDragAndDrop={true}
|
|
156
|
+
onItemsReorder={setMenuItems}
|
|
157
|
+
onDragStart={(itemId) => console.log(`Started dragging: ${itemId}`)}
|
|
158
|
+
onDragEnd={(itemId) => console.log(`Finished dragging: ${itemId}`)}
|
|
159
|
+
/>
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Compound Components
|
|
165
|
+
|
|
166
|
+
The Tree component uses a compound component pattern with the following sub-components:
|
|
167
|
+
|
|
168
|
+
```jsx
|
|
169
|
+
Tree.Item // Represents a tree node
|
|
170
|
+
Tree.ItemLabel // The clickable label part of a tree node
|
|
171
|
+
Tree.ItemContent // Container for child nodes
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Customization
|
|
175
|
+
|
|
176
|
+
The Tree component can be customized using the `views` prop:
|
|
177
|
+
|
|
178
|
+
```jsx
|
|
179
|
+
<Tree
|
|
180
|
+
// ...other props
|
|
181
|
+
views={{
|
|
182
|
+
container: { /* styles for the root container */ },
|
|
183
|
+
item: { /* styles for each tree item */ },
|
|
184
|
+
itemLabel: { /* styles for the clickable label part */ },
|
|
185
|
+
itemContent: { /* styles for the children wrapper */ },
|
|
186
|
+
icon: { /* styles for the item's main icon */ },
|
|
187
|
+
expandIcon: { /* styles for the expand/collapse chevron icon */ },
|
|
188
|
+
draggedItem: { /* styles for the item being dragged */ },
|
|
189
|
+
dragHandle: { /* styles for the drag handle icon */ },
|
|
190
|
+
}}
|
|
191
|
+
/>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Accessibility
|
|
195
|
+
|
|
196
|
+
The Tree component implements the following accessibility features:
|
|
197
|
+
|
|
198
|
+
- Keyboard navigation for expanding/collapsing nodes
|
|
199
|
+
- ARIA attributes for tree structure
|
|
200
|
+
- Focus management for interactive elements
|
|
201
|
+
- Proper contrast for selected and hovered states
|
|
202
|
+
|
|
203
|
+
## Best Practices
|
|
204
|
+
|
|
205
|
+
- Use consistent icons for similar node types
|
|
206
|
+
- Provide clear labels for all nodes
|
|
207
|
+
- Implement proper error handling for drag and drop operations
|
|
208
|
+
- Consider the depth of your tree structure (avoid deeply nested trees)
|
|
209
|
+
- Use the `onItemSelect` callback to handle item selection
|
|
210
|
+
- Implement undo/redo functionality for drag and drop operations when needed
|