@app-studio/web 0.9.41 → 0.9.43
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/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,304 +1,465 @@
|
|
|
1
|
-
# Drawer
|
|
1
|
+
# Drawer
|
|
2
2
|
|
|
3
|
-
A
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Flexible Placement**: Slide from left, right, top, or bottom
|
|
8
|
-
- **Multiple Sizes**: Choose from xs, sm, md, lg, xl, or full width/height
|
|
9
|
-
- **Compound Component**: Use sub-components for granular control
|
|
10
|
-
- **Customizable Closing**: Prevent closing on overlay click when needed
|
|
11
|
-
- **Smooth Animations**: CSS-based transitions for performance
|
|
12
|
-
- **Accessible**: Built with modal best practices
|
|
13
|
-
|
|
14
|
-
## Installation
|
|
15
|
-
|
|
16
|
-
The Drawer component is part of the app-studio library and is already available in your project.
|
|
3
|
+
A slide-out panel component that appears from the edge of the screen, with support for different placements, sizes, and content sections.
|
|
17
4
|
|
|
5
|
+
### **Import**
|
|
18
6
|
```tsx
|
|
19
7
|
import { Drawer } from '@app-studio/web';
|
|
20
8
|
```
|
|
21
9
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
### Simple Drawer
|
|
25
|
-
|
|
10
|
+
### **Default**
|
|
26
11
|
```tsx
|
|
27
|
-
import { useState } from 'react';
|
|
12
|
+
import React, { useState } from 'react';
|
|
28
13
|
import { Drawer } from '@app-studio/web';
|
|
29
|
-
import { Button } from '
|
|
14
|
+
import { Button, Text } from 'app-studio';
|
|
30
15
|
|
|
31
|
-
export
|
|
16
|
+
export const DefaultDrawer = () => {
|
|
32
17
|
const [isOpen, setIsOpen] = useState(false);
|
|
33
|
-
|
|
18
|
+
|
|
34
19
|
return (
|
|
35
20
|
<>
|
|
36
21
|
<Button onClick={() => setIsOpen(true)}>Open Drawer</Button>
|
|
37
|
-
|
|
38
|
-
<Drawer
|
|
39
|
-
<Drawer.
|
|
40
|
-
Drawer
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
22
|
+
|
|
23
|
+
<Drawer>
|
|
24
|
+
<Drawer.Overlay isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
25
|
+
<Drawer.Container>
|
|
26
|
+
<Drawer.Header onClose={() => setIsOpen(false)}>
|
|
27
|
+
<Text>Drawer Title</Text>
|
|
28
|
+
</Drawer.Header>
|
|
29
|
+
<Drawer.Body>
|
|
30
|
+
<Text>Drawer content goes here</Text>
|
|
31
|
+
</Drawer.Body>
|
|
32
|
+
<Drawer.Footer>
|
|
33
|
+
<Button onClick={() => setIsOpen(false)}>Close</Button>
|
|
34
|
+
</Drawer.Footer>
|
|
35
|
+
</Drawer.Container>
|
|
36
|
+
</Drawer.Overlay>
|
|
48
37
|
</Drawer>
|
|
49
38
|
</>
|
|
50
39
|
);
|
|
51
|
-
}
|
|
40
|
+
};
|
|
52
41
|
```
|
|
53
42
|
|
|
54
|
-
###
|
|
55
|
-
|
|
56
|
-
```tsx
|
|
57
|
-
<Drawer isOpen={isOpen} onClose={onClose} placement="left">
|
|
58
|
-
{/* Content */}
|
|
59
|
-
</Drawer>
|
|
60
|
-
|
|
61
|
-
<Drawer isOpen={isOpen} onClose={onClose} placement="right">
|
|
62
|
-
{/* Content */}
|
|
63
|
-
</Drawer>
|
|
64
|
-
|
|
65
|
-
<Drawer isOpen={isOpen} onClose={onClose} placement="top">
|
|
66
|
-
{/* Content */}
|
|
67
|
-
</Drawer>
|
|
68
|
-
|
|
69
|
-
<Drawer isOpen={isOpen} onClose={onClose} placement="bottom">
|
|
70
|
-
{/* Content */}
|
|
71
|
-
</Drawer>
|
|
72
|
-
```
|
|
43
|
+
### **isOpen**
|
|
44
|
+
Controls the visibility of the drawer.
|
|
73
45
|
|
|
74
|
-
|
|
46
|
+
- **Type:** `boolean`
|
|
47
|
+
- **Required:** `true`
|
|
75
48
|
|
|
76
49
|
```tsx
|
|
77
|
-
|
|
78
|
-
|
|
50
|
+
import React, { useState } from 'react';
|
|
51
|
+
import { Drawer } from '@app-studio/web';
|
|
52
|
+
import { Button, Text } from 'app-studio';
|
|
79
53
|
|
|
80
|
-
|
|
81
|
-
|
|
54
|
+
export const ControlledDrawer = () => {
|
|
55
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<>
|
|
59
|
+
<Button onClick={() => setIsOpen(true)}>Open</Button>
|
|
60
|
+
<Drawer>
|
|
61
|
+
<Drawer.Overlay isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
62
|
+
<Drawer.Container>
|
|
63
|
+
<Drawer.Body>
|
|
64
|
+
<Text>Controlled Drawer</Text>
|
|
65
|
+
</Drawer.Body>
|
|
66
|
+
</Drawer.Container>
|
|
67
|
+
</Drawer.Overlay>
|
|
68
|
+
</Drawer>
|
|
69
|
+
</>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
```
|
|
82
73
|
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
### **onClose**
|
|
75
|
+
Callback function executed when the drawer closes.
|
|
85
76
|
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
- **Type:** `() => void`
|
|
78
|
+
- **Required:** `true`
|
|
88
79
|
|
|
89
|
-
|
|
90
|
-
|
|
80
|
+
```tsx
|
|
81
|
+
import React, { useState } from 'react';
|
|
82
|
+
import { Drawer } from '@app-studio/web';
|
|
83
|
+
import { Button, Text } from 'app-studio';
|
|
91
84
|
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
export const CloseCallbackDrawer = () => {
|
|
86
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<>
|
|
90
|
+
<Button onClick={() => setIsOpen(true)}>Open</Button>
|
|
91
|
+
<Drawer>
|
|
92
|
+
<Drawer.Overlay
|
|
93
|
+
isOpen={isOpen}
|
|
94
|
+
onClose={() => {
|
|
95
|
+
console.log('Drawer closing');
|
|
96
|
+
setIsOpen(false);
|
|
97
|
+
}}
|
|
98
|
+
>
|
|
99
|
+
<Drawer.Container>
|
|
100
|
+
<Drawer.Body>
|
|
101
|
+
<Text>Click outside to close</Text>
|
|
102
|
+
</Drawer.Body>
|
|
103
|
+
</Drawer.Container>
|
|
104
|
+
</Drawer.Overlay>
|
|
105
|
+
</Drawer>
|
|
106
|
+
</>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
94
109
|
```
|
|
95
110
|
|
|
96
|
-
|
|
111
|
+
### **placement**
|
|
112
|
+
The placement of the drawer.
|
|
97
113
|
|
|
98
|
-
|
|
114
|
+
- **Type:** `Placement`
|
|
115
|
+
- **Default:** `'right'`
|
|
116
|
+
- **Possible Values:** `'left' | 'right' | 'top' | 'bottom'`
|
|
99
117
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
| `placement` | `'left' \| 'right' \| 'top' \| 'bottom'` | `'right'` | Which edge the drawer slides from |
|
|
105
|
-
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'md'` | Width (for left/right) or height (for top/bottom) of drawer |
|
|
106
|
-
| `isClosePrevented` | `boolean` | `false` | If true, clicking the overlay won't close the drawer |
|
|
107
|
-
| `children` | `React.ReactNode` | - | Content of the drawer (typically sub-components) |
|
|
108
|
-
|
|
109
|
-
### Drawer.Overlay Props
|
|
118
|
+
```tsx
|
|
119
|
+
import React, { useState } from 'react';
|
|
120
|
+
import { Drawer } from '@app-studio/web';
|
|
121
|
+
import { Button, Text, Horizontal } from 'app-studio';
|
|
110
122
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
export const PlacementDrawers = () => {
|
|
124
|
+
const [placement, setPlacement] = useState<string | null>(null);
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<>
|
|
128
|
+
<Horizontal gap={10}>
|
|
129
|
+
{['left', 'right', 'top', 'bottom'].map((pos) => (
|
|
130
|
+
<Button key={pos} onClick={() => setPlacement(pos)}>
|
|
131
|
+
{pos}
|
|
132
|
+
</Button>
|
|
133
|
+
))}
|
|
134
|
+
</Horizontal>
|
|
135
|
+
|
|
136
|
+
<Drawer>
|
|
137
|
+
<Drawer.Overlay
|
|
138
|
+
isOpen={!!placement}
|
|
139
|
+
onClose={() => setPlacement(null)}
|
|
140
|
+
>
|
|
141
|
+
<Drawer.Container placement={placement as any}>
|
|
142
|
+
<Drawer.Header onClose={() => setPlacement(null)}>
|
|
143
|
+
<Text>Drawer from {placement}</Text>
|
|
144
|
+
</Drawer.Header>
|
|
145
|
+
<Drawer.Body>
|
|
146
|
+
<Text>Content</Text>
|
|
147
|
+
</Drawer.Body>
|
|
148
|
+
</Drawer.Container>
|
|
149
|
+
</Drawer.Overlay>
|
|
150
|
+
</Drawer>
|
|
151
|
+
</>
|
|
152
|
+
);
|
|
153
|
+
};
|
|
154
|
+
```
|
|
118
155
|
|
|
119
|
-
###
|
|
156
|
+
### **size**
|
|
157
|
+
The size of the drawer.
|
|
120
158
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'md'` | Size of the drawer |
|
|
125
|
-
| `children` | `React.ReactNode` | - | Drawer content |
|
|
159
|
+
- **Type:** `Size`
|
|
160
|
+
- **Default:** `'md'`
|
|
161
|
+
- **Possible Values:** `'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full'`
|
|
126
162
|
|
|
127
|
-
|
|
163
|
+
```tsx
|
|
164
|
+
import React, { useState } from 'react';
|
|
165
|
+
import { Drawer } from '@app-studio/web';
|
|
166
|
+
import { Button, Text, Horizontal } from 'app-studio';
|
|
128
167
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
168
|
+
export const SizedDrawers = () => {
|
|
169
|
+
const [size, setSize] = useState<string | null>(null);
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<>
|
|
173
|
+
<Horizontal gap={10}>
|
|
174
|
+
{['sm', 'md', 'lg', 'xl', 'full'].map((s) => (
|
|
175
|
+
<Button key={s} onClick={() => setSize(s)}>
|
|
176
|
+
{s}
|
|
177
|
+
</Button>
|
|
178
|
+
))}
|
|
179
|
+
</Horizontal>
|
|
180
|
+
|
|
181
|
+
<Drawer>
|
|
182
|
+
<Drawer.Overlay isOpen={!!size} onClose={() => setSize(null)}>
|
|
183
|
+
<Drawer.Container size={size as any}>
|
|
184
|
+
<Drawer.Header onClose={() => setSize(null)}>
|
|
185
|
+
<Text>Size: {size}</Text>
|
|
186
|
+
</Drawer.Header>
|
|
187
|
+
<Drawer.Body>
|
|
188
|
+
<Text>Drawer content</Text>
|
|
189
|
+
</Drawer.Body>
|
|
190
|
+
</Drawer.Container>
|
|
191
|
+
</Drawer.Overlay>
|
|
192
|
+
</Drawer>
|
|
193
|
+
</>
|
|
194
|
+
);
|
|
195
|
+
};
|
|
196
|
+
```
|
|
134
197
|
|
|
135
|
-
###
|
|
198
|
+
### **isClosePrevented**
|
|
199
|
+
Prevents the drawer from closing when clicking the overlay.
|
|
136
200
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
| `children` | `React.ReactNode` | - | Main content of the drawer |
|
|
201
|
+
- **Type:** `boolean`
|
|
202
|
+
- **Default:** `false`
|
|
140
203
|
|
|
141
|
-
|
|
204
|
+
```tsx
|
|
205
|
+
import React, { useState } from 'react';
|
|
206
|
+
import { Drawer } from '@app-studio/web';
|
|
207
|
+
import { Button, Text } from 'app-studio';
|
|
142
208
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
209
|
+
export const PreventCloseDrawer = () => {
|
|
210
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<>
|
|
214
|
+
<Button onClick={() => setIsOpen(true)}>Open</Button>
|
|
215
|
+
<Drawer>
|
|
216
|
+
<Drawer.Overlay
|
|
217
|
+
isOpen={isOpen}
|
|
218
|
+
onClose={() => setIsOpen(false)}
|
|
219
|
+
isClosePrevented
|
|
220
|
+
>
|
|
221
|
+
<Drawer.Container>
|
|
222
|
+
<Drawer.Header onClose={() => setIsOpen(false)}>
|
|
223
|
+
<Text>Must use close button</Text>
|
|
224
|
+
</Drawer.Header>
|
|
225
|
+
<Drawer.Body>
|
|
226
|
+
<Text>Click outside won't close this drawer</Text>
|
|
227
|
+
</Drawer.Body>
|
|
228
|
+
</Drawer.Container>
|
|
229
|
+
</Drawer.Overlay>
|
|
230
|
+
</Drawer>
|
|
231
|
+
</>
|
|
232
|
+
);
|
|
233
|
+
};
|
|
234
|
+
```
|
|
146
235
|
|
|
147
|
-
|
|
236
|
+
### **blur**
|
|
237
|
+
The degree of blurriness applied to the overlay.
|
|
148
238
|
|
|
149
|
-
|
|
239
|
+
- **Type:** `number`
|
|
150
240
|
|
|
151
241
|
```tsx
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
<Drawer.Header onClose={onClose}>Title</Drawer.Header>
|
|
156
|
-
<Drawer.Body>Content</Drawer.Body>
|
|
157
|
-
<Drawer.Footer>Actions</Drawer.Footer>
|
|
158
|
-
</Drawer.Container>
|
|
159
|
-
</Drawer.Overlay>
|
|
160
|
-
</Drawer>
|
|
161
|
-
```
|
|
242
|
+
import React, { useState } from 'react';
|
|
243
|
+
import { Drawer } from '@app-studio/web';
|
|
244
|
+
import { Button, Text } from 'app-studio';
|
|
162
245
|
|
|
163
|
-
|
|
246
|
+
export const BlurredDrawer = () => {
|
|
247
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
248
|
+
|
|
249
|
+
return (
|
|
250
|
+
<>
|
|
251
|
+
<Button onClick={() => setIsOpen(true)}>Open Blurred Drawer</Button>
|
|
252
|
+
<Drawer>
|
|
253
|
+
<Drawer.Overlay
|
|
254
|
+
isOpen={isOpen}
|
|
255
|
+
onClose={() => setIsOpen(false)}
|
|
256
|
+
blur={10}
|
|
257
|
+
>
|
|
258
|
+
<Drawer.Container>
|
|
259
|
+
<Drawer.Body>
|
|
260
|
+
<Text>Background is blurred</Text>
|
|
261
|
+
</Drawer.Body>
|
|
262
|
+
</Drawer.Container>
|
|
263
|
+
</Drawer.Overlay>
|
|
264
|
+
</Drawer>
|
|
265
|
+
</>
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
```
|
|
164
269
|
|
|
165
|
-
|
|
270
|
+
### **buttonPosition**
|
|
271
|
+
Position of the close button in the header.
|
|
166
272
|
|
|
167
|
-
|
|
273
|
+
- **Type:** `CloseButtonPosition`
|
|
274
|
+
- **Possible Values:** `'left' | 'right' | 'none'`
|
|
168
275
|
|
|
169
276
|
```tsx
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const handleSubmit = () => {
|
|
175
|
-
console.log('Form submitted:', formData);
|
|
176
|
-
setIsOpen(false);
|
|
177
|
-
};
|
|
277
|
+
import React, { useState } from 'react';
|
|
278
|
+
import { Drawer } from '@app-studio/web';
|
|
279
|
+
import { Button, Text } from 'app-studio';
|
|
178
280
|
|
|
281
|
+
export const ButtonPositionDrawer = () => {
|
|
282
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
283
|
+
|
|
179
284
|
return (
|
|
180
285
|
<>
|
|
181
|
-
<Button onClick={() => setIsOpen(true)}>Open
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
|
197
|
-
/>
|
|
198
|
-
</Drawer.Body>
|
|
199
|
-
<Drawer.Footer>
|
|
200
|
-
<Button variant="secondary" onClick={() => setIsOpen(false)}>
|
|
201
|
-
Cancel
|
|
202
|
-
</Button>
|
|
203
|
-
<Button onClick={handleSubmit}>Submit</Button>
|
|
204
|
-
</Drawer.Footer>
|
|
286
|
+
<Button onClick={() => setIsOpen(true)}>Open</Button>
|
|
287
|
+
<Drawer>
|
|
288
|
+
<Drawer.Overlay isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
289
|
+
<Drawer.Container>
|
|
290
|
+
<Drawer.Header
|
|
291
|
+
onClose={() => setIsOpen(false)}
|
|
292
|
+
buttonPosition="left"
|
|
293
|
+
>
|
|
294
|
+
<Text>Close button on left</Text>
|
|
295
|
+
</Drawer.Header>
|
|
296
|
+
<Drawer.Body>
|
|
297
|
+
<Text>Drawer content</Text>
|
|
298
|
+
</Drawer.Body>
|
|
299
|
+
</Drawer.Container>
|
|
300
|
+
</Drawer.Overlay>
|
|
205
301
|
</Drawer>
|
|
206
302
|
</>
|
|
207
303
|
);
|
|
208
|
-
}
|
|
304
|
+
};
|
|
209
305
|
```
|
|
210
306
|
|
|
211
|
-
###
|
|
307
|
+
### **Navigation Drawer**
|
|
308
|
+
A common use case for navigation menus.
|
|
212
309
|
|
|
213
310
|
```tsx
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
311
|
+
import React, { useState } from 'react';
|
|
312
|
+
import { Drawer } from '@app-studio/web';
|
|
313
|
+
import { Button, Text, Vertical } from 'app-studio';
|
|
314
|
+
|
|
315
|
+
export const NavigationDrawer = () => {
|
|
316
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
317
|
+
|
|
318
|
+
const menuItems = [
|
|
319
|
+
'Dashboard',
|
|
320
|
+
'Profile',
|
|
321
|
+
'Settings',
|
|
322
|
+
'Analytics',
|
|
323
|
+
'Help',
|
|
324
|
+
];
|
|
325
|
+
|
|
326
|
+
return (
|
|
327
|
+
<>
|
|
328
|
+
<Button onClick={() => setIsOpen(true)}>☰ Menu</Button>
|
|
329
|
+
<Drawer>
|
|
330
|
+
<Drawer.Overlay isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
331
|
+
<Drawer.Container placement="left" size="sm">
|
|
332
|
+
<Drawer.Header onClose={() => setIsOpen(false)}>
|
|
333
|
+
<Text fontSize={20} fontWeight="bold">Menu</Text>
|
|
334
|
+
</Drawer.Header>
|
|
335
|
+
<Drawer.Body>
|
|
336
|
+
<Vertical gap={0}>
|
|
337
|
+
{menuItems.map((item) => (
|
|
338
|
+
<Button
|
|
339
|
+
key={item}
|
|
340
|
+
variant="ghost"
|
|
341
|
+
onClick={() => {
|
|
342
|
+
console.log('Navigate to:', item);
|
|
343
|
+
setIsOpen(false);
|
|
344
|
+
}}
|
|
345
|
+
>
|
|
346
|
+
{item}
|
|
347
|
+
</Button>
|
|
348
|
+
))}
|
|
349
|
+
</Vertical>
|
|
350
|
+
</Drawer.Body>
|
|
351
|
+
</Drawer.Container>
|
|
352
|
+
</Drawer.Overlay>
|
|
353
|
+
</Drawer>
|
|
354
|
+
</>
|
|
355
|
+
);
|
|
356
|
+
};
|
|
226
357
|
```
|
|
227
358
|
|
|
228
|
-
###
|
|
359
|
+
### **Form Drawer**
|
|
360
|
+
Using drawer for forms and data entry.
|
|
229
361
|
|
|
230
362
|
```tsx
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
363
|
+
import React, { useState } from 'react';
|
|
364
|
+
import { Drawer } from '@app-studio/web';
|
|
365
|
+
import { Button, Text, Vertical } from 'app-studio';
|
|
366
|
+
import { TextField } from '@app-studio/web';
|
|
234
367
|
|
|
368
|
+
export const FormDrawer = () => {
|
|
369
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
370
|
+
|
|
235
371
|
return (
|
|
236
372
|
<>
|
|
237
|
-
<Button onClick={() =>
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
373
|
+
<Button onClick={() => setIsOpen(true)}>Add User</Button>
|
|
374
|
+
<Drawer>
|
|
375
|
+
<Drawer.Overlay isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
376
|
+
<Drawer.Container placement="right" size="md">
|
|
377
|
+
<Drawer.Header onClose={() => setIsOpen(false)}>
|
|
378
|
+
<Text fontSize={18} fontWeight="bold">Add New User</Text>
|
|
379
|
+
</Drawer.Header>
|
|
380
|
+
<Drawer.Body>
|
|
381
|
+
<Vertical gap={15}>
|
|
382
|
+
<TextField label="Name" placeholder="Enter name" />
|
|
383
|
+
<TextField label="Email" placeholder="Enter email" />
|
|
384
|
+
<TextField label="Role" placeholder="Enter role" />
|
|
385
|
+
</Vertical>
|
|
386
|
+
</Drawer.Body>
|
|
387
|
+
<Drawer.Footer>
|
|
388
|
+
<Horizontal gap={10} justifyContent="flex-end">
|
|
389
|
+
<Button
|
|
390
|
+
variant="outline"
|
|
391
|
+
onClick={() => setIsOpen(false)}
|
|
392
|
+
>
|
|
393
|
+
Cancel
|
|
394
|
+
</Button>
|
|
395
|
+
<Button
|
|
396
|
+
variant="filled"
|
|
397
|
+
onClick={() => {
|
|
398
|
+
console.log('Save user');
|
|
399
|
+
setIsOpen(false);
|
|
400
|
+
}}
|
|
401
|
+
>
|
|
402
|
+
Save
|
|
403
|
+
</Button>
|
|
404
|
+
</Horizontal>
|
|
405
|
+
</Drawer.Footer>
|
|
406
|
+
</Drawer.Container>
|
|
407
|
+
</Drawer.Overlay>
|
|
253
408
|
</Drawer>
|
|
254
409
|
</>
|
|
255
410
|
);
|
|
256
|
-
}
|
|
411
|
+
};
|
|
257
412
|
```
|
|
258
413
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
The Drawer component respects the `app-studio` theme. You can customize appearance using:
|
|
262
|
-
|
|
263
|
-
1. **CSS Classes** - Override via CSS
|
|
264
|
-
2. **ViewProps** - Pass style props to adjust appearance
|
|
265
|
-
3. **Placement and Size** - Primary customization levers
|
|
266
|
-
|
|
267
|
-
## Size Reference
|
|
268
|
-
|
|
269
|
-
| Size | Width/Height |
|
|
270
|
-
|------|-------------|
|
|
271
|
-
| `xs` | 320px |
|
|
272
|
-
| `sm` | 380px |
|
|
273
|
-
| `md` | 480px (default) |
|
|
274
|
-
| `lg` | 640px |
|
|
275
|
-
| `xl` | 768px |
|
|
276
|
-
| `full` | 100% |
|
|
277
|
-
|
|
278
|
-
## Best Practices
|
|
279
|
-
|
|
280
|
-
1. **Always provide onClose**: Ensure users can exit the drawer
|
|
281
|
-
2. **Clear call-to-action**: Make it obvious what the drawer is for
|
|
282
|
-
3. **Concise content**: Drawers work best for focused, task-specific content
|
|
283
|
-
4. **Footer buttons**: Use Footer component for action buttons
|
|
284
|
-
5. **Prevent accidental closes**: Use `isClosePrevented` for critical operations
|
|
285
|
-
6. **Keyboard support**: Ensure proper focus management with your content
|
|
286
|
-
7. **Mobile consideration**: Test drawer sizes on mobile - consider using `full` size on small screens
|
|
414
|
+
### **Details Drawer**
|
|
415
|
+
Showing detailed information in a drawer.
|
|
287
416
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
- Placements: `src/components/Drawer/Examples/DrawerPlacements.tsx`
|
|
293
|
-
- Sizes: `src/components/Drawer/Examples/DrawerSizes.tsx`
|
|
294
|
-
|
|
295
|
-
## Accessibility
|
|
296
|
-
|
|
297
|
-
- Drawer automatically manages focus when opening/closing
|
|
298
|
-
- Overlay click triggers `onClose` callback (unless `isClosePrevented`)
|
|
299
|
-
- Close button in Header provides clear exit path
|
|
300
|
-
- Built-in animations respect `prefers-reduced-motion` preferences
|
|
417
|
+
```tsx
|
|
418
|
+
import React, { useState } from 'react';
|
|
419
|
+
import { Drawer } from '@app-studio/web';
|
|
420
|
+
import { Button, Text, Vertical, Horizontal } from 'app-studio';
|
|
301
421
|
|
|
302
|
-
|
|
422
|
+
export const DetailsDrawer = () => {
|
|
423
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
424
|
+
|
|
425
|
+
return (
|
|
426
|
+
<>
|
|
427
|
+
<Button onClick={() => setIsOpen(true)}>View Details</Button>
|
|
428
|
+
<Drawer>
|
|
429
|
+
<Drawer.Overlay isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
430
|
+
<Drawer.Container placement="right" size="lg">
|
|
431
|
+
<Drawer.Header onClose={() => setIsOpen(false)}>
|
|
432
|
+
<Text fontSize={20} fontWeight="bold">Product Details</Text>
|
|
433
|
+
</Drawer.Header>
|
|
434
|
+
<Drawer.Body>
|
|
435
|
+
<Vertical gap={20}>
|
|
436
|
+
<div>
|
|
437
|
+
<Text fontSize={14} color="#6b7280">Name</Text>
|
|
438
|
+
<Text fontSize={16}>Premium Widget</Text>
|
|
439
|
+
</div>
|
|
440
|
+
<div>
|
|
441
|
+
<Text fontSize={14} color="#6b7280">Price</Text>
|
|
442
|
+
<Text fontSize={16}>$99.99</Text>
|
|
443
|
+
</div>
|
|
444
|
+
<div>
|
|
445
|
+
<Text fontSize={14} color="#6b7280">Description</Text>
|
|
446
|
+
<Text fontSize={16}>
|
|
447
|
+
A high-quality widget with advanced features
|
|
448
|
+
and premium materials.
|
|
449
|
+
</Text>
|
|
450
|
+
</div>
|
|
451
|
+
</Vertical>
|
|
452
|
+
</Drawer.Body>
|
|
453
|
+
<Drawer.Footer>
|
|
454
|
+
<Button onClick={() => setIsOpen(false)}>
|
|
455
|
+
Add to Cart
|
|
456
|
+
</Button>
|
|
457
|
+
</Drawer.Footer>
|
|
458
|
+
</Drawer.Container>
|
|
459
|
+
</Drawer.Overlay>
|
|
460
|
+
</Drawer>
|
|
461
|
+
</>
|
|
462
|
+
);
|
|
463
|
+
};
|
|
464
|
+
```
|
|
303
465
|
|
|
304
|
-
Works in all modern browsers that support CSS transforms and transitions.
|