@app-studio/web 0.9.41 → 0.9.44
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/bot/Bot.d.ts +15 -0
- package/dist/bot/Cache.d.ts +13 -0
- package/dist/bot/Config.d.ts +13 -0
- package/dist/bot/ContentFetcher.d.ts +9 -0
- package/dist/bot/DocuCode.d.ts +19 -0
- package/dist/bot/FileHandler.d.ts +39 -0
- package/dist/bot/ai/AnthropicConnector.d.ts +6 -0
- package/dist/bot/ai/GeminiConnector.d.ts +7 -0
- package/dist/bot/ai/GroqConnector.d.ts +7 -0
- package/dist/bot/ai/HuggingFaceConnector.d.ts +6 -0
- package/dist/bot/ai/OpenAIConnector.d.ts +11 -0
- package/dist/bot/ai/ReplicateConnector.d.ts +7 -0
- package/dist/bot/ai/SambaNovaConnector.d.ts +6 -0
- package/dist/bot/ai/ai.config.d.ts +12 -0
- package/dist/bot/ai/ai.service.d.ts +36 -0
- package/dist/bot/data.d.ts +19 -0
- package/dist/bot/extractors.d.ts +8 -0
- package/dist/bot/index.d.ts +1 -0
- package/dist/bot/prompt/1-project.d.ts +1 -0
- package/dist/bot/prompt/2-response.d.ts +1 -0
- package/dist/bot/prompt/3-comment.d.ts +1 -0
- package/dist/components/Title/Title/SlideEffect.d.ts +14 -0
- package/dist/components/Title/Title/Title.props.d.ts +20 -0
- package/dist/components/Title/Title/Title.state.d.ts +4 -0
- package/dist/web.cjs.development.js +265 -78
- 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 +265 -78
- package/dist/web.esm.js.map +1 -1
- package/dist/web.umd.development.js +265 -78
- 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/components/Accordion.mdx +74 -121
- package/docs/components/Alert.mdx +19 -70
- package/docs/components/AspectRatio.mdx +13 -11
- package/docs/components/AudioInput.mdx +43 -0
- package/docs/components/Avatar.mdx +18 -43
- package/docs/components/Background.mdx +100 -492
- package/docs/components/Badge.mdx +45 -130
- package/docs/components/Button.mdx +76 -128
- package/docs/components/Calendar.mdx +7 -7
- package/docs/components/Card.mdx +247 -290
- package/docs/components/Carousel.mdx +94 -321
- package/docs/components/Chart.mdx +171 -26
- package/docs/components/ChatInput.mdx +327 -275
- package/docs/components/Checkbox.mdx +3 -5
- package/docs/components/ColorInput.mdx +6 -6
- package/docs/components/ColorPicker.mdx +452 -0
- package/docs/components/ComboBox.mdx +13 -13
- package/docs/components/Command.mdx +140 -188
- package/docs/components/ContextMenu.mdx +47 -171
- package/docs/components/CookieConsent.mdx +53 -0
- package/docs/components/CountryPicker.mdx +8 -8
- package/docs/components/DatePicker.mdx +3 -3
- package/docs/components/DragAndDrop.mdx +279 -463
- package/docs/components/Drawer.mdx +392 -231
- package/docs/components/DropdownMenu.mdx +37 -155
- package/docs/components/EmojiPicker.mdx +84 -0
- package/docs/components/File.mdx +130 -4
- package/docs/components/Formik.mdx +39 -39
- package/docs/components/Gradient.mdx +359 -182
- package/docs/components/Horizontal.mdx +1 -2
- package/docs/components/HoverCard.mdx +57 -125
- package/docs/components/KanbanBoard.mdx +9 -9
- package/docs/components/Link.mdx +22 -30
- package/docs/components/Loader.mdx +230 -413
- package/docs/components/Menubar.mdx +73 -69
- package/docs/components/Message.mdx +210 -525
- package/docs/components/Modal.mdx +351 -475
- package/docs/components/NavigationMenu.mdx +8 -8
- package/docs/components/OTPInput.mdx +194 -0
- package/docs/components/Pagination.mdx +451 -107
- package/docs/components/Password.mdx +8 -8
- package/docs/components/ProgressBar.mdx +460 -0
- package/docs/components/Resizable.mdx +103 -102
- package/docs/components/Select.mdx +5 -5
- package/docs/components/Separator.mdx +11 -98
- package/docs/components/ShareButton.mdx +29 -0
- package/docs/components/Sidebar.mdx +70 -131
- package/docs/components/Slider.mdx +99 -185
- package/docs/components/StatusIndicator.mdx +373 -0
- package/docs/components/Switch.mdx +3 -3
- package/docs/components/Table.mdx +25 -105
- package/docs/components/Tabs.mdx +40 -143
- package/docs/components/TagInput.mdx +17 -17
- package/docs/components/Text.mdx +3 -3
- package/docs/components/TextArea.mdx +6 -6
- package/docs/components/TextField.mdx +12 -12
- package/docs/components/Title.mdx +267 -525
- package/docs/components/Toast.mdx +65 -142
- package/docs/components/Toggle.mdx +37 -49
- package/docs/components/ToggleGroup.mdx +36 -57
- package/docs/components/Tooltip.mdx +501 -138
- package/docs/components/Uploader.mdx +205 -351
- package/package.json +1 -1
- package/dist/components/AuthGuard/AuthGuard.d.ts +0 -35
- package/dist/components/AuthGuard/index.d.ts +0 -1
- package/docs/adk-components.md +0 -319
- package/docs/adk-quick-start.md +0 -268
|
@@ -1,539 +1,355 @@
|
|
|
1
1
|
# DragAndDrop
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A drag-and-drop component for reordering items with touch and mouse support.
|
|
4
4
|
|
|
5
5
|
### **Import**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
```tsx
|
|
7
|
+
import { DragAndDrop } from '@app-studio/web';
|
|
8
|
+
```
|
|
9
9
|
|
|
10
|
-
### **
|
|
10
|
+
### **Default**
|
|
11
11
|
```tsx
|
|
12
12
|
import React, { useState } from 'react';
|
|
13
13
|
import { DragAndDrop } from '@app-studio/web';
|
|
14
|
-
import {
|
|
14
|
+
import { Text } from 'app-studio';
|
|
15
15
|
|
|
16
|
-
export const
|
|
16
|
+
export const DefaultDragAndDrop = () => {
|
|
17
17
|
const [items, setItems] = useState([
|
|
18
|
-
'Item 1',
|
|
19
|
-
'Item 2',
|
|
20
|
-
'Item 3',
|
|
21
|
-
'Item 4'
|
|
18
|
+
{ id: 1, name: 'Item 1' },
|
|
19
|
+
{ id: 2, name: 'Item 2' },
|
|
20
|
+
{ id: 3, name: 'Item 3' },
|
|
22
21
|
]);
|
|
23
|
-
|
|
24
|
-
const handleItemsChange = (newItems: string[]) => {
|
|
25
|
-
console.log('Items reordered:', newItems);
|
|
26
|
-
setItems(newItems);
|
|
27
|
-
};
|
|
28
|
-
|
|
22
|
+
|
|
29
23
|
return (
|
|
30
|
-
<DragAndDrop
|
|
24
|
+
<DragAndDrop
|
|
31
25
|
items={items}
|
|
32
|
-
onChange={
|
|
33
|
-
|
|
34
|
-
padding: 16,
|
|
35
|
-
backgroundColor: 'color.gray.50',
|
|
36
|
-
borderRadius: 8,
|
|
37
|
-
}}
|
|
38
|
-
itemProps={{
|
|
39
|
-
marginBottom: 8,
|
|
40
|
-
padding: 12,
|
|
41
|
-
backgroundColor: 'color.white',
|
|
42
|
-
borderRadius: 4,
|
|
43
|
-
border: '1px solid',
|
|
44
|
-
borderColor: 'color.gray.200',
|
|
45
|
-
}}
|
|
26
|
+
onChange={setItems}
|
|
27
|
+
renderItem={(item) => <Text>{item.name}</Text>}
|
|
46
28
|
/>
|
|
47
29
|
);
|
|
48
30
|
};
|
|
49
31
|
```
|
|
50
32
|
|
|
51
|
-
### **
|
|
33
|
+
### **items**
|
|
34
|
+
Array of items to be reordered.
|
|
35
|
+
|
|
36
|
+
- **Type:** `any[]`
|
|
37
|
+
- **Required:** `true`
|
|
38
|
+
|
|
52
39
|
```tsx
|
|
53
40
|
import React, { useState } from 'react';
|
|
54
41
|
import { DragAndDrop } from '@app-studio/web';
|
|
55
|
-
import {
|
|
56
|
-
import { DragHandleIcon, EditIcon, DeleteIcon } from '@app-studio/web';
|
|
57
|
-
|
|
58
|
-
interface Task {
|
|
59
|
-
id: string;
|
|
60
|
-
title: string;
|
|
61
|
-
description: string;
|
|
62
|
-
priority: 'low' | 'medium' | 'high';
|
|
63
|
-
completed: boolean;
|
|
64
|
-
}
|
|
42
|
+
import { Text } from 'app-studio';
|
|
65
43
|
|
|
66
|
-
export const
|
|
67
|
-
const [tasks, setTasks] = useState
|
|
68
|
-
{
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
description: 'Create wireframes and mockups',
|
|
72
|
-
priority: 'high',
|
|
73
|
-
completed: false,
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
id: '2',
|
|
77
|
-
title: 'Implement Authentication',
|
|
78
|
-
description: 'Set up user login and registration',
|
|
79
|
-
priority: 'medium',
|
|
80
|
-
completed: false,
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
id: '3',
|
|
84
|
-
title: 'Write Documentation',
|
|
85
|
-
description: 'Document API endpoints',
|
|
86
|
-
priority: 'low',
|
|
87
|
-
completed: true,
|
|
88
|
-
},
|
|
44
|
+
export const ItemsDragAndDrop = () => {
|
|
45
|
+
const [tasks, setTasks] = useState([
|
|
46
|
+
{ id: 1, title: 'Design mockups', priority: 'high' },
|
|
47
|
+
{ id: 2, title: 'Write documentation', priority: 'medium' },
|
|
48
|
+
{ id: 3, title: 'Code review', priority: 'low' },
|
|
89
49
|
]);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<DragAndDrop
|
|
53
|
+
items={tasks}
|
|
54
|
+
onChange={setTasks}
|
|
55
|
+
renderItem={(task) => (
|
|
56
|
+
<Text>{task.title} - {task.priority}</Text>
|
|
57
|
+
)}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
```
|
|
90
62
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
};
|
|
63
|
+
### **onChange**
|
|
64
|
+
Callback function when items are reordered.
|
|
94
65
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return (
|
|
103
|
-
<View
|
|
104
|
-
padding={16}
|
|
105
|
-
backgroundColor={task.completed ? 'color.gray.50' : 'color.white'}
|
|
106
|
-
border="1px solid"
|
|
107
|
-
borderColor="color.gray.200"
|
|
108
|
-
borderRadius={8}
|
|
109
|
-
marginBottom={8}
|
|
110
|
-
>
|
|
111
|
-
<Horizontal justifyContent="space-between" alignItems="flex-start">
|
|
112
|
-
<View flex={1}>
|
|
113
|
-
<Horizontal alignItems="center" marginBottom={8}>
|
|
114
|
-
<View
|
|
115
|
-
width={8}
|
|
116
|
-
height={8}
|
|
117
|
-
borderRadius="50%"
|
|
118
|
-
backgroundColor={priorityColors[task.priority]}
|
|
119
|
-
marginRight={8}
|
|
120
|
-
/>
|
|
121
|
-
<Text
|
|
122
|
-
fontWeight="semibold"
|
|
123
|
-
textDecoration={task.completed ? 'line-through' : 'none'}
|
|
124
|
-
color={task.completed ? 'color.gray.500' : 'color.gray.900'}
|
|
125
|
-
>
|
|
126
|
-
{task.title}
|
|
127
|
-
</Text>
|
|
128
|
-
</Horizontal>
|
|
129
|
-
<Text
|
|
130
|
-
fontSize={14}
|
|
131
|
-
color="color.gray.600"
|
|
132
|
-
textDecoration={task.completed ? 'line-through' : 'none'}
|
|
133
|
-
>
|
|
134
|
-
{task.description}
|
|
135
|
-
</Text>
|
|
136
|
-
</View>
|
|
137
|
-
|
|
138
|
-
<Horizontal gap={8} alignItems="center">
|
|
139
|
-
<EditIcon widthHeight={16} color="color.gray.400" />
|
|
140
|
-
<DeleteIcon widthHeight={16} color="color.gray.400" />
|
|
141
|
-
<DragHandleIcon widthHeight={16} color="color.gray.400" />
|
|
142
|
-
</Horizontal>
|
|
143
|
-
</Horizontal>
|
|
144
|
-
</View>
|
|
145
|
-
);
|
|
146
|
-
};
|
|
66
|
+
- **Type:** `(items: any[]) => void`
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import React, { useState } from 'react';
|
|
70
|
+
import { DragAndDrop } from '@app-studio/web';
|
|
71
|
+
import { Text, Vertical } from 'app-studio';
|
|
147
72
|
|
|
73
|
+
export const OnChangeDragAndDrop = () => {
|
|
74
|
+
const [items, setItems] = useState(['First', 'Second', 'Third']);
|
|
75
|
+
|
|
148
76
|
return (
|
|
149
|
-
<
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
onChange={handleTasksChange}
|
|
156
|
-
renderItem={renderTask}
|
|
157
|
-
containerProps={{
|
|
158
|
-
padding: 16,
|
|
159
|
-
backgroundColor: 'color.gray.50',
|
|
160
|
-
borderRadius: 12,
|
|
161
|
-
minHeight: 200,
|
|
77
|
+
<Vertical gap={10}>
|
|
78
|
+
<DragAndDrop
|
|
79
|
+
items={items}
|
|
80
|
+
onChange={(newItems) => {
|
|
81
|
+
console.log('Order changed:', newItems);
|
|
82
|
+
setItems(newItems);
|
|
162
83
|
}}
|
|
84
|
+
renderItem={(item) => <Text>{item}</Text>}
|
|
163
85
|
/>
|
|
164
|
-
|
|
86
|
+
<Text>Current order: {items.join(', ')}</Text>
|
|
87
|
+
</Vertical>
|
|
165
88
|
);
|
|
166
89
|
};
|
|
167
90
|
```
|
|
168
91
|
|
|
169
|
-
### **
|
|
92
|
+
### **renderItem**
|
|
93
|
+
Custom render function for each item.
|
|
94
|
+
|
|
95
|
+
- **Type:** `(item: any, index: number) => React.ReactNode`
|
|
96
|
+
|
|
170
97
|
```tsx
|
|
171
98
|
import React, { useState } from 'react';
|
|
172
99
|
import { DragAndDrop } from '@app-studio/web';
|
|
173
|
-
import { View, Text, Horizontal
|
|
100
|
+
import { View, Text, Horizontal } from 'app-studio';
|
|
174
101
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
interface KanbanColumn {
|
|
183
|
-
id: string;
|
|
184
|
-
title: string;
|
|
185
|
-
items: KanbanItem[];
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export const KanbanBoard = () => {
|
|
189
|
-
const [columns, setColumns] = useState<KanbanColumn[]>([
|
|
190
|
-
{
|
|
191
|
-
id: 'todo',
|
|
192
|
-
title: 'To Do',
|
|
193
|
-
items: [
|
|
194
|
-
{ id: '1', title: 'Design System', assignee: 'John', tags: ['Design'] },
|
|
195
|
-
{ id: '2', title: 'API Integration', assignee: 'Jane', tags: ['Backend'] },
|
|
196
|
-
],
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
id: 'inprogress',
|
|
200
|
-
title: 'In Progress',
|
|
201
|
-
items: [
|
|
202
|
-
{ id: '3', title: 'User Dashboard', assignee: 'Bob', tags: ['Frontend'] },
|
|
203
|
-
],
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
id: 'done',
|
|
207
|
-
title: 'Done',
|
|
208
|
-
items: [
|
|
209
|
-
{ id: '4', title: 'Project Setup', assignee: 'Alice', tags: ['DevOps'] },
|
|
210
|
-
],
|
|
211
|
-
},
|
|
102
|
+
export const CustomRenderDragAndDrop = () => {
|
|
103
|
+
const [items, setItems] = useState([
|
|
104
|
+
{ id: 1, name: 'Task 1', completed: false },
|
|
105
|
+
{ id: 2, name: 'Task 2', completed: true },
|
|
106
|
+
{ id: 3, name: 'Task 3', completed: false },
|
|
212
107
|
]);
|
|
213
|
-
|
|
214
|
-
const handleColumnItemsChange = (columnId: string, newItems: KanbanItem[]) => {
|
|
215
|
-
setColumns(prev =>
|
|
216
|
-
prev.map(col =>
|
|
217
|
-
col.id === columnId
|
|
218
|
-
? { ...col, items: newItems }
|
|
219
|
-
: col
|
|
220
|
-
)
|
|
221
|
-
);
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
const renderKanbanItem = (item: KanbanItem) => (
|
|
225
|
-
<View
|
|
226
|
-
padding={12}
|
|
227
|
-
backgroundColor="color.white"
|
|
228
|
-
border="1px solid"
|
|
229
|
-
borderColor="color.gray.200"
|
|
230
|
-
borderRadius={6}
|
|
231
|
-
marginBottom={8}
|
|
232
|
-
boxShadow="0 1px 3px rgba(0,0,0,0.1)"
|
|
233
|
-
>
|
|
234
|
-
<Text fontWeight="medium" marginBottom={8}>
|
|
235
|
-
{item.title}
|
|
236
|
-
</Text>
|
|
237
|
-
<Horizontal justifyContent="space-between" alignItems="center">
|
|
238
|
-
<Text fontSize={12} color="color.gray.600">
|
|
239
|
-
{item.assignee}
|
|
240
|
-
</Text>
|
|
241
|
-
<Horizontal gap={4}>
|
|
242
|
-
{item.tags.map(tag => (
|
|
243
|
-
<View
|
|
244
|
-
key={tag}
|
|
245
|
-
padding="2px 6px"
|
|
246
|
-
backgroundColor="color.blue.100"
|
|
247
|
-
borderRadius={4}
|
|
248
|
-
>
|
|
249
|
-
<Text fontSize={10} color="color.blue.700">
|
|
250
|
-
{tag}
|
|
251
|
-
</Text>
|
|
252
|
-
</View>
|
|
253
|
-
))}
|
|
254
|
-
</Horizontal>
|
|
255
|
-
</Horizontal>
|
|
256
|
-
</View>
|
|
257
|
-
);
|
|
258
|
-
|
|
108
|
+
|
|
259
109
|
return (
|
|
260
|
-
<
|
|
261
|
-
{
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
110
|
+
<DragAndDrop
|
|
111
|
+
items={items}
|
|
112
|
+
onChange={setItems}
|
|
113
|
+
renderItem={(item, index) => (
|
|
114
|
+
<Horizontal
|
|
115
|
+
gap={10}
|
|
116
|
+
alignItems="center"
|
|
117
|
+
padding={12}
|
|
118
|
+
backgroundColor={item.completed ? '#d1fae5' : '#fee2e2'}
|
|
266
119
|
borderRadius={8}
|
|
267
|
-
padding={16}
|
|
268
120
|
>
|
|
269
|
-
<Text fontWeight="bold"
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
renderItem={renderKanbanItem}
|
|
276
|
-
containerProps={{
|
|
277
|
-
minHeight: 300,
|
|
278
|
-
}}
|
|
279
|
-
/>
|
|
280
|
-
</View>
|
|
281
|
-
))}
|
|
282
|
-
</Horizontal>
|
|
121
|
+
<Text fontWeight="bold">#{index + 1}</Text>
|
|
122
|
+
<Text>{item.name}</Text>
|
|
123
|
+
{item.completed && <Text>✓</Text>}
|
|
124
|
+
</Horizontal>
|
|
125
|
+
)}
|
|
126
|
+
/>
|
|
283
127
|
);
|
|
284
128
|
};
|
|
285
129
|
```
|
|
286
130
|
|
|
287
|
-
### **
|
|
288
|
-
|
|
289
|
-
| Prop | Type | Default | Description |
|
|
290
|
-
| ---- | ---- | ------- | ----------- |
|
|
291
|
-
| items | any[] | required | Array of items to be rendered and reordered |
|
|
292
|
-
| onChange | `(items: any[]) => void` | undefined | Callback function called when items are reordered |
|
|
293
|
-
| renderItem | `(item: any, index: number) => React.ReactNode` | undefined | Custom render function for each item |
|
|
294
|
-
| containerProps | ViewProps | undefined | Props to apply to the container element |
|
|
295
|
-
| itemProps | ViewProps | undefined | Props to apply to each item wrapper |
|
|
131
|
+
### **containerProps**
|
|
132
|
+
Props for the container element.
|
|
296
133
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
**Touch Support:**
|
|
300
|
-
The component automatically supports touch devices for mobile drag and drop:
|
|
134
|
+
- **Type:** `ViewProps`
|
|
301
135
|
|
|
302
136
|
```tsx
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
onChange={handleChange}
|
|
307
|
-
// Works on both desktop and mobile
|
|
308
|
-
/>
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
**Visual Feedback:**
|
|
312
|
-
Items provide visual feedback during drag operations:
|
|
137
|
+
import React, { useState } from 'react';
|
|
138
|
+
import { DragAndDrop } from '@app-studio/web';
|
|
139
|
+
import { Text } from 'app-studio';
|
|
313
140
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
/>
|
|
141
|
+
export const ContainerPropsDragAndDrop = () => {
|
|
142
|
+
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<DragAndDrop
|
|
146
|
+
items={items}
|
|
147
|
+
onChange={setItems}
|
|
148
|
+
renderItem={(item) => <Text>{item}</Text>}
|
|
149
|
+
containerProps={{
|
|
150
|
+
backgroundColor: '#f3f4f6',
|
|
151
|
+
padding: 20,
|
|
152
|
+
borderRadius: 12,
|
|
153
|
+
gap: 10,
|
|
154
|
+
}}
|
|
155
|
+
/>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
332
158
|
```
|
|
333
159
|
|
|
334
|
-
### **
|
|
160
|
+
### **itemProps**
|
|
161
|
+
Props for each item element.
|
|
335
162
|
|
|
336
|
-
**
|
|
337
|
-
```tsx
|
|
338
|
-
import { Tree } from '@app-studio/web';
|
|
339
|
-
|
|
340
|
-
// Tree component has built-in drag and drop
|
|
341
|
-
<Tree
|
|
342
|
-
items={treeItems}
|
|
343
|
-
allowDragAndDrop={true}
|
|
344
|
-
onItemsReorder={handleTreeReorder}
|
|
345
|
-
dragHandleIcon={<DragHandleIcon />}
|
|
346
|
-
/>
|
|
347
|
-
```
|
|
163
|
+
- **Type:** `ViewProps`
|
|
348
164
|
|
|
349
|
-
**With Flow Component:**
|
|
350
165
|
```tsx
|
|
351
|
-
import {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
<Flow
|
|
355
|
-
nodes={flowNodes}
|
|
356
|
-
allowDraggingNodes={true}
|
|
357
|
-
onNodeDragEnd={handleNodeDragEnd}
|
|
358
|
-
/>
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### **Styling and Customization**
|
|
166
|
+
import React, { useState } from 'react';
|
|
167
|
+
import { DragAndDrop } from '@app-studio/web';
|
|
168
|
+
import { Text } from 'app-studio';
|
|
362
169
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
170
|
+
export const ItemPropsDragAndDrop = () => {
|
|
171
|
+
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<DragAndDrop
|
|
175
|
+
items={items}
|
|
176
|
+
onChange={setItems}
|
|
177
|
+
renderItem={(item) => <Text>{item}</Text>}
|
|
178
|
+
itemProps={{
|
|
179
|
+
padding: 15,
|
|
180
|
+
backgroundColor: '#ffffff',
|
|
181
|
+
borderRadius: 8,
|
|
182
|
+
cursor: 'grab',
|
|
183
|
+
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
184
|
+
}}
|
|
373
185
|
/>
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
);
|
|
377
|
-
|
|
378
|
-
<DragAndDrop
|
|
379
|
-
items={items}
|
|
380
|
-
onChange={handleChange}
|
|
381
|
-
renderItem={renderItemWithHandle}
|
|
382
|
-
/>
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
**Conditional Dragging:**
|
|
386
|
-
```tsx
|
|
387
|
-
const renderConditionalItem = (item, index) => (
|
|
388
|
-
<View
|
|
389
|
-
padding={12}
|
|
390
|
-
backgroundColor={item.locked ? 'color.gray.100' : 'color.white'}
|
|
391
|
-
cursor={item.locked ? 'not-allowed' : 'grab'}
|
|
392
|
-
opacity={item.locked ? 0.6 : 1}
|
|
393
|
-
>
|
|
394
|
-
<Text>{item.name}</Text>
|
|
395
|
-
{item.locked && <Text fontSize={12} color="color.gray.500">Locked</Text>}
|
|
396
|
-
</View>
|
|
397
|
-
);
|
|
186
|
+
);
|
|
187
|
+
};
|
|
398
188
|
```
|
|
399
189
|
|
|
400
|
-
### **
|
|
190
|
+
### **views**
|
|
191
|
+
Custom styles for container and items.
|
|
401
192
|
|
|
402
|
-
**
|
|
403
|
-
For large lists, consider implementing virtualization:
|
|
193
|
+
- **Type:** `{ container?: ViewProps; item?: ViewProps }`
|
|
404
194
|
|
|
405
195
|
```tsx
|
|
406
|
-
import {
|
|
196
|
+
import React, { useState } from 'react';
|
|
197
|
+
import { DragAndDrop } from '@app-studio/web';
|
|
198
|
+
import { Text } from 'app-studio';
|
|
407
199
|
|
|
408
|
-
|
|
409
|
-
const
|
|
200
|
+
export const StyledDragAndDrop = () => {
|
|
201
|
+
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
|
|
202
|
+
|
|
410
203
|
return (
|
|
411
|
-
<
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
204
|
+
<DragAndDrop
|
|
205
|
+
items={items}
|
|
206
|
+
onChange={setItems}
|
|
207
|
+
renderItem={(item) => <Text>{item}</Text>}
|
|
208
|
+
views={{
|
|
209
|
+
container: {
|
|
210
|
+
backgroundColor: '#1f2937',
|
|
211
|
+
padding: 20,
|
|
212
|
+
borderRadius: 16,
|
|
213
|
+
},
|
|
214
|
+
item: {
|
|
215
|
+
backgroundColor: '#374151',
|
|
216
|
+
color: '#ffffff',
|
|
217
|
+
padding: 16,
|
|
218
|
+
borderRadius: 8,
|
|
219
|
+
marginBottom: 8,
|
|
220
|
+
}
|
|
221
|
+
}}
|
|
222
|
+
/>
|
|
425
223
|
);
|
|
426
224
|
};
|
|
427
225
|
```
|
|
428
226
|
|
|
429
|
-
**
|
|
430
|
-
|
|
431
|
-
// Clean up event listeners and references
|
|
432
|
-
useEffect(() => {
|
|
433
|
-
return () => {
|
|
434
|
-
// Component handles cleanup automatically
|
|
435
|
-
};
|
|
436
|
-
}, []);
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
### **Accessibility**
|
|
440
|
-
|
|
441
|
-
The DragAndDrop component includes accessibility features:
|
|
442
|
-
|
|
443
|
-
- **Keyboard Navigation**: Support for keyboard-based reordering
|
|
444
|
-
- **Screen Reader Support**: ARIA attributes for assistive technologies
|
|
445
|
-
- **Focus Management**: Proper focus handling during drag operations
|
|
227
|
+
### **Complex Example**
|
|
228
|
+
A task list with drag-and-drop reordering.
|
|
446
229
|
|
|
447
230
|
```tsx
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
containerProps={{
|
|
452
|
-
role: 'list',
|
|
453
|
-
'aria-label': 'Reorderable task list',
|
|
454
|
-
}}
|
|
455
|
-
itemProps={{
|
|
456
|
-
role: 'listitem',
|
|
457
|
-
tabIndex: 0,
|
|
458
|
-
'aria-grabbed': false, // Dynamically updated during drag
|
|
459
|
-
}}
|
|
460
|
-
/>
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
### **Best Practices**
|
|
464
|
-
|
|
465
|
-
**State Management:**
|
|
466
|
-
- Keep the items state in a parent component
|
|
467
|
-
- Use unique IDs for items when possible
|
|
468
|
-
- Handle state updates immutably
|
|
469
|
-
|
|
470
|
-
**User Experience:**
|
|
471
|
-
- Provide visual feedback during drag operations
|
|
472
|
-
- Use appropriate cursor styles
|
|
473
|
-
- Consider adding drag handles for complex items
|
|
474
|
-
- Test on both desktop and mobile devices
|
|
231
|
+
import React, { useState } from 'react';
|
|
232
|
+
import { DragAndDrop } from '@app-studio/web';
|
|
233
|
+
import { View, Text, Horizontal, Vertical } from 'app-studio';
|
|
475
234
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
235
|
+
interface Task {
|
|
236
|
+
id: number;
|
|
237
|
+
title: string;
|
|
238
|
+
description: string;
|
|
239
|
+
priority: 'low' | 'medium' | 'high';
|
|
240
|
+
completed: boolean;
|
|
241
|
+
}
|
|
480
242
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
243
|
+
export const TaskListDragAndDrop = () => {
|
|
244
|
+
const [tasks, setTasks] = useState<Task[]>([
|
|
245
|
+
{
|
|
246
|
+
id: 1,
|
|
247
|
+
title: 'Design Homepage',
|
|
248
|
+
description: 'Create mockups for the new homepage',
|
|
249
|
+
priority: 'high',
|
|
250
|
+
completed: false
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: 2,
|
|
254
|
+
title: 'Write Tests',
|
|
255
|
+
description: 'Add unit tests for user module',
|
|
256
|
+
priority: 'medium',
|
|
257
|
+
completed: false
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
id: 3,
|
|
261
|
+
title: 'Update Documentation',
|
|
262
|
+
description: 'Document new API endpoints',
|
|
263
|
+
priority: 'low',
|
|
264
|
+
completed: true
|
|
265
|
+
},
|
|
266
|
+
]);
|
|
267
|
+
|
|
268
|
+
const priorityColors = {
|
|
269
|
+
high: '#ef4444',
|
|
270
|
+
medium: '#f59e0b',
|
|
271
|
+
low: '#10b981',
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
return (
|
|
275
|
+
<DragAndDrop
|
|
276
|
+
items={tasks}
|
|
277
|
+
onChange={setTasks}
|
|
278
|
+
renderItem={(task, index) => (
|
|
279
|
+
<View
|
|
280
|
+
padding={16}
|
|
281
|
+
backgroundColor="#ffffff"
|
|
282
|
+
borderRadius={12}
|
|
283
|
+
borderLeftWidth={4}
|
|
284
|
+
borderLeftColor={priorityColors[task.priority]}
|
|
285
|
+
boxShadow="0 2px 8px rgba(0,0,0,0.1)"
|
|
286
|
+
>
|
|
287
|
+
<Horizontal justifyContent="space-between" alignItems="center">
|
|
288
|
+
<Vertical gap={4}>
|
|
289
|
+
<Horizontal gap={8} alignItems="center">
|
|
290
|
+
<Text fontSize={16} fontWeight="bold">
|
|
291
|
+
{task.title}
|
|
292
|
+
</Text>
|
|
293
|
+
<Text
|
|
294
|
+
fontSize={12}
|
|
295
|
+
color={priorityColors[task.priority]}
|
|
296
|
+
textTransform="uppercase"
|
|
297
|
+
>
|
|
298
|
+
{task.priority}
|
|
299
|
+
</Text>
|
|
300
|
+
</Horizontal>
|
|
301
|
+
<Text fontSize={14} color="#6b7280">
|
|
302
|
+
{task.description}
|
|
303
|
+
</Text>
|
|
304
|
+
</Vertical>
|
|
305
|
+
{task.completed && (
|
|
306
|
+
<Text fontSize={20}>✓</Text>
|
|
307
|
+
)}
|
|
308
|
+
</Horizontal>
|
|
309
|
+
</View>
|
|
310
|
+
)}
|
|
311
|
+
views={{
|
|
312
|
+
container: {
|
|
313
|
+
gap: 12,
|
|
314
|
+
},
|
|
315
|
+
item: {
|
|
316
|
+
cursor: 'grab',
|
|
317
|
+
transition: 'all 0.2s ease',
|
|
318
|
+
hover: {
|
|
319
|
+
transform: 'translateX(4px)',
|
|
320
|
+
boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}}
|
|
324
|
+
/>
|
|
325
|
+
);
|
|
326
|
+
};
|
|
327
|
+
```
|
|
486
328
|
|
|
487
|
-
### **
|
|
329
|
+
### **Touch Support**
|
|
330
|
+
The component supports both mouse and touch events for mobile devices.
|
|
488
331
|
|
|
489
|
-
**Sortable Table Rows:**
|
|
490
332
|
```tsx
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
<tr>
|
|
495
|
-
<th>Name</th>
|
|
496
|
-
<th>Status</th>
|
|
497
|
-
<th>Actions</th>
|
|
498
|
-
</tr>
|
|
499
|
-
</thead>
|
|
500
|
-
<tbody>
|
|
501
|
-
<DragAndDrop
|
|
502
|
-
items={data}
|
|
503
|
-
onChange={setData}
|
|
504
|
-
renderItem={(item) => (
|
|
505
|
-
<tr>
|
|
506
|
-
<td>{item.name}</td>
|
|
507
|
-
<td>{item.status}</td>
|
|
508
|
-
<td>
|
|
509
|
-
<DragHandleIcon widthHeight={16} />
|
|
510
|
-
</td>
|
|
511
|
-
</tr>
|
|
512
|
-
)}
|
|
513
|
-
/>
|
|
514
|
-
</tbody>
|
|
515
|
-
</table>
|
|
516
|
-
);
|
|
517
|
-
```
|
|
333
|
+
import React, { useState } from 'react';
|
|
334
|
+
import { DragAndDrop } from '@app-studio/web';
|
|
335
|
+
import { Text } from 'app-studio';
|
|
518
336
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
)}
|
|
537
|
-
/>
|
|
538
|
-
);
|
|
337
|
+
export const TouchDragAndDrop = () => {
|
|
338
|
+
const [items, setItems] = useState([
|
|
339
|
+
'Swipe to reorder',
|
|
340
|
+
'Works on mobile',
|
|
341
|
+
'Touch friendly',
|
|
342
|
+
]);
|
|
343
|
+
|
|
344
|
+
return (
|
|
345
|
+
<DragAndDrop
|
|
346
|
+
items={items}
|
|
347
|
+
onChange={setItems}
|
|
348
|
+
renderItem={(item) => (
|
|
349
|
+
<Text padding={16}>{item}</Text>
|
|
350
|
+
)}
|
|
351
|
+
/>
|
|
352
|
+
);
|
|
353
|
+
};
|
|
539
354
|
```
|
|
355
|
+
|