@app-studio/web 0.9.38 → 0.9.41
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/Title/Title/Title.style.d.ts +0 -1
- package/dist/web.cjs.development.js +0 -19
- 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 +0 -19
- package/dist/web.esm.js.map +1 -1
- package/dist/web.umd.development.js +0 -19
- 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 +4 -4
- package/docs/components/Alert.mdx +3 -3
- package/docs/components/AspectRatio.mdx +2 -2
- package/docs/components/Avatar.mdx +1 -1
- package/docs/components/Background.mdx +6 -6
- package/docs/components/Badge.mdx +11 -11
- package/docs/components/Button.mdx +7 -7
- package/docs/components/Card.mdx +15 -15
- package/docs/components/Carousel.mdx +13 -13
- package/docs/components/Center.mdx +22 -22
- package/docs/components/Chart.mdx +6 -6
- package/docs/components/ChatInput.mdx +7 -7
- package/docs/components/Checkbox.mdx +1 -1
- package/docs/components/ColorInput.mdx +4 -4
- package/docs/components/ComboBox.mdx +1 -1
- package/docs/components/ContextMenu.mdx +4 -4
- package/docs/components/CountryPicker.mdx +2 -2
- package/docs/components/DatePicker.mdx +1 -1
- package/docs/components/DragAndDrop.mdx +3 -3
- package/docs/components/Drawer.mdx +242 -102
- package/docs/components/Flow.mdx +3 -3
- package/docs/components/Form.mdx +4 -4
- package/docs/components/Formik.mdx +2 -2
- package/docs/components/Gradient.mdx +14 -14
- package/docs/components/Horizontal.mdx +1 -1
- package/docs/components/HoverCard.mdx +5 -5
- package/docs/components/Icon.mdx +10 -10
- package/docs/components/KanbanBoard.mdx +3 -3
- package/docs/components/Label.mdx +8 -8
- package/docs/components/Link.mdx +3 -3
- package/docs/components/Loader.mdx +12 -12
- package/docs/components/Menubar.mdx +2 -2
- package/docs/components/Message.mdx +5 -5
- package/docs/components/Modal.mdx +5 -5
- package/docs/components/Slider.mdx +1 -1
- package/docs/components/Tabs.mdx +1 -1
- package/docs/components/TagInput.mdx +15 -15
- package/docs/components/TextArea.mdx +3 -3
- package/docs/components/TextField.mdx +5 -5
- package/docs/components/Toggle.mdx +4 -4
- package/docs/components/ToggleGroup.mdx +9 -9
- package/docs/components/Tooltip.mdx +6 -6
- package/docs/components/Tree.mdx +4 -4
- package/docs/components/Uploader.mdx +2 -2
- package/docs/components/Vertical.mdx +22 -22
- package/package.json +2 -2
|
@@ -22,7 +22,7 @@ Optional color scheme string that might allow customization of the checkbox's ap
|
|
|
22
22
|
|
|
23
23
|
```tsx
|
|
24
24
|
import React from 'react';
|
|
25
|
-
import { Vertical } from 'app-studio';
|
|
25
|
+
import { Vertical } from '@app-studio/web';
|
|
26
26
|
|
|
27
27
|
import { Checkbox } from '../Checkbox';
|
|
28
28
|
|
|
@@ -34,7 +34,7 @@ Different visual styles for the color input.
|
|
|
34
34
|
|
|
35
35
|
```tsx
|
|
36
36
|
import React from 'react';
|
|
37
|
-
import { Vertical } from 'app-studio';
|
|
37
|
+
import { Vertical } from '@app-studio/web';
|
|
38
38
|
import { ColorInput } from '../ColorInput';
|
|
39
39
|
|
|
40
40
|
export const ColorInputVariants = () => {
|
|
@@ -67,7 +67,7 @@ Different sizes for the color input.
|
|
|
67
67
|
|
|
68
68
|
```tsx
|
|
69
69
|
import React from 'react';
|
|
70
|
-
import { Vertical } from 'app-studio';
|
|
70
|
+
import { Vertical } from '@app-studio/web';
|
|
71
71
|
import { ColorInput } from '../ColorInput';
|
|
72
72
|
|
|
73
73
|
export const ColorInputSizes = () => {
|
|
@@ -119,10 +119,10 @@ Color input integrated with form handling.
|
|
|
119
119
|
|
|
120
120
|
```tsx
|
|
121
121
|
import React, { useState } from 'react';
|
|
122
|
-
import { Vertical, Horizontal } from 'app-studio';
|
|
122
|
+
import { Vertical, Horizontal } from '@app-studio/web';
|
|
123
123
|
import { ColorInput } from '../ColorInput';
|
|
124
124
|
import { Button } from '../../Button/Button';
|
|
125
|
-
import { Text } from 'app-studio';
|
|
125
|
+
import { Text } from '@app-studio/web';
|
|
126
126
|
|
|
127
127
|
export const ColorInputForm = () => {
|
|
128
128
|
const [backgroundColor, setBackgroundColor] = useState('color.blue.500');
|
|
@@ -38,7 +38,7 @@ Optional callback function triggered when an item is selected.
|
|
|
38
38
|
```tsx
|
|
39
39
|
import React from 'react';
|
|
40
40
|
import { ComboBox } from '../ComboBox';
|
|
41
|
-
import { Vertical } from 'app-studio';
|
|
41
|
+
import { Vertical } from '@app-studio/web';
|
|
42
42
|
import { MessageLayout, showMessage } from '../../..';
|
|
43
43
|
|
|
44
44
|
export const OnSelectDemo = () => {
|
|
@@ -11,7 +11,7 @@ A context menu component that appears when right-clicking on an element.
|
|
|
11
11
|
```tsx
|
|
12
12
|
import React from 'react';
|
|
13
13
|
import { ContextMenu } from '../ContextMenu';
|
|
14
|
-
import { View, Text } from 'app-studio';
|
|
14
|
+
import { View, Text } from '@app-studio/web';
|
|
15
15
|
import { CopyIcon, EditIcon, DeleteIcon } from '../../Icon/Icon';
|
|
16
16
|
|
|
17
17
|
export const DefaultContextMenu = () => {
|
|
@@ -62,7 +62,7 @@ Create nested context menus with submenus.
|
|
|
62
62
|
```tsx
|
|
63
63
|
import React from 'react';
|
|
64
64
|
import { ContextMenu } from '../ContextMenu';
|
|
65
|
-
import { View, Text } from 'app-studio';
|
|
65
|
+
import { View, Text } from '@app-studio/web';
|
|
66
66
|
import {
|
|
67
67
|
CopyIcon,
|
|
68
68
|
EditIcon,
|
|
@@ -126,7 +126,7 @@ Different visual styles for the context menu.
|
|
|
126
126
|
```tsx
|
|
127
127
|
import React from 'react';
|
|
128
128
|
import { ContextMenu } from '../ContextMenu';
|
|
129
|
-
import { View, Text } from 'app-studio';
|
|
129
|
+
import { View, Text } from '@app-studio/web';
|
|
130
130
|
import { CopyIcon, EditIcon } from '../../Icon/Icon';
|
|
131
131
|
|
|
132
132
|
export const ContextMenuVariants = () => {
|
|
@@ -169,7 +169,7 @@ Customize the appearance of the context menu.
|
|
|
169
169
|
```tsx
|
|
170
170
|
import React from 'react';
|
|
171
171
|
import { ContextMenu } from '../ContextMenu';
|
|
172
|
-
import { View, Text } from 'app-studio';
|
|
172
|
+
import { View, Text } from '@app-studio/web';
|
|
173
173
|
import { CopyIcon, EditIcon } from '../../Icon/Icon';
|
|
174
174
|
|
|
175
175
|
export const CustomContextMenu = () => {
|
|
@@ -64,7 +64,7 @@ Optional shape of the CountryPicker for visual styles
|
|
|
64
64
|
import React from 'react';
|
|
65
65
|
import { CountryPicker } from '../../../Form/CountryPicker/CountryPicker';
|
|
66
66
|
|
|
67
|
-
import { Vertical } from 'app-studio';
|
|
67
|
+
import { Vertical } from '@app-studio/web';
|
|
68
68
|
|
|
69
69
|
import { Shape } from '../CountryPicker/CountryPicker.type';
|
|
70
70
|
|
|
@@ -90,7 +90,7 @@ Variant for different visual types of CountryPicker
|
|
|
90
90
|
import React from 'react';
|
|
91
91
|
import { CountryPicker } from '../../../Form/CountryPicker/CountryPicker';
|
|
92
92
|
|
|
93
|
-
import { Vertical } from 'app-studio';
|
|
93
|
+
import { Vertical } from '@app-studio/web';
|
|
94
94
|
|
|
95
95
|
import { Variant } from '../CountryPicker/CountryPicker.type';
|
|
96
96
|
|
|
@@ -11,7 +11,7 @@ A powerful drag and drop component for reordering lists and items with smooth an
|
|
|
11
11
|
```tsx
|
|
12
12
|
import React, { useState } from 'react';
|
|
13
13
|
import { DragAndDrop } from '@app-studio/web';
|
|
14
|
-
import { View, Text } from 'app-studio';
|
|
14
|
+
import { View, Text } from '@app-studio/web';
|
|
15
15
|
|
|
16
16
|
export const BasicDragAndDrop = () => {
|
|
17
17
|
const [items, setItems] = useState([
|
|
@@ -52,7 +52,7 @@ export const BasicDragAndDrop = () => {
|
|
|
52
52
|
```tsx
|
|
53
53
|
import React, { useState } from 'react';
|
|
54
54
|
import { DragAndDrop } from '@app-studio/web';
|
|
55
|
-
import { View, Text, Horizontal } from 'app-studio';
|
|
55
|
+
import { View, Text, Horizontal } from '@app-studio/web';
|
|
56
56
|
import { DragHandleIcon, EditIcon, DeleteIcon } from '@app-studio/web';
|
|
57
57
|
|
|
58
58
|
interface Task {
|
|
@@ -170,7 +170,7 @@ export const TaskDragAndDrop = () => {
|
|
|
170
170
|
```tsx
|
|
171
171
|
import React, { useState } from 'react';
|
|
172
172
|
import { DragAndDrop } from '@app-studio/web';
|
|
173
|
-
import { View, Text, Horizontal, Vertical } from 'app-studio';
|
|
173
|
+
import { View, Text, Horizontal, Vertical } from '@app-studio/web';
|
|
174
174
|
|
|
175
175
|
interface KanbanItem {
|
|
176
176
|
id: string;
|
|
@@ -1,29 +1,46 @@
|
|
|
1
|
-
# Drawer
|
|
1
|
+
# Drawer Component
|
|
2
2
|
|
|
3
|
-
A drawer
|
|
3
|
+
A flexible drawer/modal panel component that slides out from any edge of the screen. Useful for displaying additional content, forms, or settings without leaving the current page.
|
|
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.
|
|
4
17
|
|
|
5
|
-
### **Import**
|
|
6
18
|
```tsx
|
|
7
19
|
import { Drawer } from '@app-studio/web';
|
|
8
20
|
```
|
|
9
21
|
|
|
10
|
-
|
|
22
|
+
## Basic Usage
|
|
23
|
+
|
|
24
|
+
### Simple Drawer
|
|
25
|
+
|
|
11
26
|
```tsx
|
|
12
|
-
import
|
|
13
|
-
import { Drawer } from '
|
|
14
|
-
import { Button } from '
|
|
15
|
-
import { Vertical } from 'app-studio';
|
|
27
|
+
import { useState } from 'react';
|
|
28
|
+
import { Drawer } from '@app-studio/web';
|
|
29
|
+
import { Button } from '@app-studio/web';
|
|
16
30
|
|
|
17
|
-
export
|
|
31
|
+
export function DrawerExample() {
|
|
18
32
|
const [isOpen, setIsOpen] = useState(false);
|
|
19
33
|
|
|
20
34
|
return (
|
|
21
35
|
<>
|
|
22
36
|
<Button onClick={() => setIsOpen(true)}>Open Drawer</Button>
|
|
37
|
+
|
|
23
38
|
<Drawer isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
24
|
-
<Drawer.Header
|
|
39
|
+
<Drawer.Header onClose={() => setIsOpen(false)}>
|
|
40
|
+
Drawer Title
|
|
41
|
+
</Drawer.Header>
|
|
25
42
|
<Drawer.Body>
|
|
26
|
-
<p>
|
|
43
|
+
<p>Your content goes here</p>
|
|
27
44
|
</Drawer.Body>
|
|
28
45
|
<Drawer.Footer>
|
|
29
46
|
<Button onClick={() => setIsOpen(false)}>Close</Button>
|
|
@@ -31,134 +48,257 @@ export const DefaultDrawer = () => {
|
|
|
31
48
|
</Drawer>
|
|
32
49
|
</>
|
|
33
50
|
);
|
|
34
|
-
}
|
|
51
|
+
}
|
|
35
52
|
```
|
|
36
53
|
|
|
37
|
-
###
|
|
38
|
-
The `placement` prop determines which side of the screen the drawer will appear from. It can be `top`, `right`, `bottom`, or `left`.
|
|
54
|
+
### With Different Placements
|
|
39
55
|
|
|
40
56
|
```tsx
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
import { Horizontal } from 'app-studio';
|
|
57
|
+
<Drawer isOpen={isOpen} onClose={onClose} placement="left">
|
|
58
|
+
{/* Content */}
|
|
59
|
+
</Drawer>
|
|
45
60
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
61
|
+
<Drawer isOpen={isOpen} onClose={onClose} placement="right">
|
|
62
|
+
{/* Content */}
|
|
63
|
+
</Drawer>
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
};
|
|
65
|
+
<Drawer isOpen={isOpen} onClose={onClose} placement="top">
|
|
66
|
+
{/* Content */}
|
|
67
|
+
</Drawer>
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<Button onClick={() => openDrawer('right')}>Right</Button>
|
|
59
|
-
<Button onClick={() => openDrawer('bottom')}>Bottom</Button>
|
|
60
|
-
<Button onClick={() => openDrawer('left')}>Left</Button>
|
|
61
|
-
<Drawer isOpen={isOpen} onClose={() => setIsOpen(false)} placement={placement}>
|
|
62
|
-
<Drawer.Header>Drawer Title</Drawer.Header>
|
|
63
|
-
<Drawer.Body>
|
|
64
|
-
<p>This is the content of the drawer.</p>
|
|
65
|
-
</Drawer.Body>
|
|
66
|
-
</Drawer>
|
|
67
|
-
</Horizontal>
|
|
68
|
-
);
|
|
69
|
-
};
|
|
69
|
+
<Drawer isOpen={isOpen} onClose={onClose} placement="bottom">
|
|
70
|
+
{/* Content */}
|
|
71
|
+
</Drawer>
|
|
70
72
|
```
|
|
71
73
|
|
|
72
|
-
###
|
|
73
|
-
|
|
74
|
+
### With Different Sizes
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
// xs: 320px
|
|
78
|
+
<Drawer isOpen={isOpen} onClose={onClose} size="xs" />
|
|
79
|
+
|
|
80
|
+
// sm: 380px
|
|
81
|
+
<Drawer isOpen={isOpen} onClose={onClose} size="sm" />
|
|
82
|
+
|
|
83
|
+
// md: 480px (default)
|
|
84
|
+
<Drawer isOpen={isOpen} onClose={onClose} size="md" />
|
|
85
|
+
|
|
86
|
+
// lg: 640px
|
|
87
|
+
<Drawer isOpen={isOpen} onClose={onClose} size="lg" />
|
|
88
|
+
|
|
89
|
+
// xl: 768px
|
|
90
|
+
<Drawer isOpen={isOpen} onClose={onClose} size="xl" />
|
|
91
|
+
|
|
92
|
+
// full: 100% width/height
|
|
93
|
+
<Drawer isOpen={isOpen} onClose={onClose} size="full" />
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## API Reference
|
|
97
|
+
|
|
98
|
+
### Drawer Props
|
|
99
|
+
|
|
100
|
+
| Prop | Type | Default | Description |
|
|
101
|
+
|------|------|---------|-------------|
|
|
102
|
+
| `isOpen` | `boolean` | Required | Controls whether the drawer is visible |
|
|
103
|
+
| `onClose` | `() => void` | Required | Callback fired when the drawer should close |
|
|
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
|
|
110
|
+
|
|
111
|
+
| Prop | Type | Default | Description |
|
|
112
|
+
|------|------|---------|-------------|
|
|
113
|
+
| `isOpen` | `boolean` | Required | Controls overlay visibility |
|
|
114
|
+
| `onClose` | `() => void` | Required | Callback when overlay is clicked |
|
|
115
|
+
| `isClosePrevented` | `boolean` | `false` | Prevent closing on overlay click |
|
|
116
|
+
| `blur` | `number` | - | Optional blur amount for backdrop |
|
|
117
|
+
| `children` | `React.ReactNode` | - | Drawer container element |
|
|
118
|
+
|
|
119
|
+
### Drawer.Container Props
|
|
120
|
+
|
|
121
|
+
| Prop | Type | Default | Description |
|
|
122
|
+
|------|------|---------|-------------|
|
|
123
|
+
| `placement` | `'left' \| 'right' \| 'top' \| 'bottom'` | `'right'` | Placement of the drawer |
|
|
124
|
+
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'md'` | Size of the drawer |
|
|
125
|
+
| `children` | `React.ReactNode` | - | Drawer content |
|
|
126
|
+
|
|
127
|
+
### Drawer.Header Props
|
|
128
|
+
|
|
129
|
+
| Prop | Type | Default | Description |
|
|
130
|
+
|------|------|---------|-------------|
|
|
131
|
+
| `onClose` | `() => void` | - | Callback for close button |
|
|
132
|
+
| `buttonPosition` | `'left' \| 'right'` | `'right'` | Position of the close button |
|
|
133
|
+
| `children` | `React.ReactNode` | - | Header content (typically title text) |
|
|
134
|
+
|
|
135
|
+
### Drawer.Body Props
|
|
136
|
+
|
|
137
|
+
| Prop | Type | Default | Description |
|
|
138
|
+
|------|------|---------|-------------|
|
|
139
|
+
| `children` | `React.ReactNode` | - | Main content of the drawer |
|
|
140
|
+
|
|
141
|
+
### Drawer.Footer Props
|
|
142
|
+
|
|
143
|
+
| Prop | Type | Default | Description |
|
|
144
|
+
|------|------|---------|-------------|
|
|
145
|
+
| `children` | `React.ReactNode` | - | Footer content (typically action buttons) |
|
|
146
|
+
|
|
147
|
+
## Compound Components
|
|
148
|
+
|
|
149
|
+
The Drawer uses a compound component pattern for flexible composition:
|
|
74
150
|
|
|
75
151
|
```tsx
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
152
|
+
<Drawer isOpen={isOpen} onClose={onClose}>
|
|
153
|
+
<Drawer.Overlay>
|
|
154
|
+
<Drawer.Container>
|
|
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
|
+
```
|
|
162
|
+
|
|
163
|
+
However, you typically use the simpler form where the main Drawer component wraps the sub-components directly.
|
|
164
|
+
|
|
165
|
+
## Common Patterns
|
|
80
166
|
|
|
81
|
-
|
|
82
|
-
|
|
167
|
+
### Form in a Drawer
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
export function FormDrawer() {
|
|
83
171
|
const [isOpen, setIsOpen] = useState(false);
|
|
172
|
+
const [formData, setFormData] = useState({ name: '', email: '' });
|
|
84
173
|
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
setIsOpen(
|
|
174
|
+
const handleSubmit = () => {
|
|
175
|
+
console.log('Form submitted:', formData);
|
|
176
|
+
setIsOpen(false);
|
|
88
177
|
};
|
|
89
178
|
|
|
90
179
|
return (
|
|
91
|
-
|
|
92
|
-
<Button onClick={() =>
|
|
93
|
-
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<Drawer.Header>Drawer Title</Drawer.Header>
|
|
180
|
+
<>
|
|
181
|
+
<Button onClick={() => setIsOpen(true)}>Open Form</Button>
|
|
182
|
+
|
|
183
|
+
<Drawer isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
184
|
+
<Drawer.Header onClose={() => setIsOpen(false)}>
|
|
185
|
+
Create New Item
|
|
186
|
+
</Drawer.Header>
|
|
99
187
|
<Drawer.Body>
|
|
100
|
-
<
|
|
188
|
+
<input
|
|
189
|
+
placeholder="Name"
|
|
190
|
+
value={formData.name}
|
|
191
|
+
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
|
192
|
+
/>
|
|
193
|
+
<input
|
|
194
|
+
placeholder="Email"
|
|
195
|
+
value={formData.email}
|
|
196
|
+
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
|
197
|
+
/>
|
|
101
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>
|
|
102
205
|
</Drawer>
|
|
103
|
-
|
|
206
|
+
</>
|
|
104
207
|
);
|
|
105
|
-
}
|
|
208
|
+
}
|
|
106
209
|
```
|
|
107
210
|
|
|
108
|
-
###
|
|
109
|
-
The `isClosePrevented` prop prevents the drawer from closing when the overlay is clicked.
|
|
211
|
+
### Prevent Closing on Overlay Click
|
|
110
212
|
|
|
111
213
|
```tsx
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
214
|
+
<Drawer
|
|
215
|
+
isOpen={isOpen}
|
|
216
|
+
onClose={onClose}
|
|
217
|
+
isClosePrevented={true}
|
|
218
|
+
>
|
|
219
|
+
<Drawer.Header onClose={onClose}>
|
|
220
|
+
Important Action
|
|
221
|
+
</Drawer.Header>
|
|
222
|
+
<Drawer.Body>
|
|
223
|
+
This drawer can only be closed by clicking the close button
|
|
224
|
+
</Drawer.Body>
|
|
225
|
+
</Drawer>
|
|
226
|
+
```
|
|
115
227
|
|
|
116
|
-
|
|
117
|
-
|
|
228
|
+
### Nested Drawers
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
export function NestedDrawers() {
|
|
232
|
+
const [drawer1Open, setDrawer1Open] = useState(false);
|
|
233
|
+
const [drawer2Open, setDrawer2Open] = useState(false);
|
|
118
234
|
|
|
119
235
|
return (
|
|
120
236
|
<>
|
|
121
|
-
<Button onClick={() =>
|
|
122
|
-
|
|
123
|
-
|
|
237
|
+
<Button onClick={() => setDrawer1Open(true)}>Open First Drawer</Button>
|
|
238
|
+
|
|
239
|
+
<Drawer isOpen={drawer1Open} onClose={() => setDrawer1Open(false)} placement="left">
|
|
240
|
+
<Drawer.Header onClose={() => setDrawer1Open(false)}>
|
|
241
|
+
First Drawer
|
|
242
|
+
</Drawer.Header>
|
|
124
243
|
<Drawer.Body>
|
|
125
|
-
<
|
|
244
|
+
<Button onClick={() => setDrawer2Open(true)}>Open Second Drawer</Button>
|
|
126
245
|
</Drawer.Body>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
246
|
+
</Drawer>
|
|
247
|
+
|
|
248
|
+
<Drawer isOpen={drawer2Open} onClose={() => setDrawer2Open(false)} placement="right">
|
|
249
|
+
<Drawer.Header onClose={() => setDrawer2Open(false)}>
|
|
250
|
+
Second Drawer
|
|
251
|
+
</Drawer.Header>
|
|
252
|
+
<Drawer.Body>Content for second drawer</Drawer.Body>
|
|
130
253
|
</Drawer>
|
|
131
254
|
</>
|
|
132
255
|
);
|
|
133
|
-
}
|
|
256
|
+
}
|
|
134
257
|
```
|
|
135
258
|
|
|
136
|
-
|
|
259
|
+
## Styling & Customization
|
|
137
260
|
|
|
138
|
-
|
|
139
|
-
| Prop | Type | Default | Description |
|
|
140
|
-
| --- | --- | --- | --- |
|
|
141
|
-
| `placement` | `top` \| `right` \| `bottom` \| `left` | `right` | The placement of the drawer. |
|
|
142
|
-
| `size` | `xs` \| `sm` \| `md` \| `lg` \| `xl` | `md` | The size of the drawer. |
|
|
143
|
-
| `isOpen` | `boolean` | - | If `true`, the drawer will be open. |
|
|
144
|
-
| `onClose` | `() => void` | - | Callback fired when the drawer closes. |
|
|
145
|
-
| `isClosePrevented` | `boolean` | `false` | If `true`, the drawer will not close when clicking the overlay. |
|
|
146
|
-
| `children` | `React.ReactNode` | - | The children of the drawer. |
|
|
147
|
-
|
|
148
|
-
#### **Drawer.Header**
|
|
149
|
-
| Prop | Type | Default | Description |
|
|
150
|
-
| --- | --- | --- | --- |
|
|
151
|
-
| `onClose` | `() => void` | - | Callback fired when the close button is clicked. |
|
|
152
|
-
| `buttonPosition` | `left` \| `right` | `right` | The position of the close button. |
|
|
153
|
-
| `children` | `React.ReactNode` | - | The content of the drawer header. |
|
|
261
|
+
The Drawer component respects the `app-studio` theme. You can customize appearance using:
|
|
154
262
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
| `children` | `React.ReactNode` | - | The content of the drawer body. |
|
|
263
|
+
1. **CSS Classes** - Override via CSS
|
|
264
|
+
2. **ViewProps** - Pass style props to adjust appearance
|
|
265
|
+
3. **Placement and Size** - Primary customization levers
|
|
159
266
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
|
163
|
-
|
|
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
|
|
287
|
+
|
|
288
|
+
## Examples
|
|
289
|
+
|
|
290
|
+
Check out the example implementations:
|
|
291
|
+
- Default Drawer: `src/components/Drawer/Examples/DefaultDrawer.tsx`
|
|
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
|
|
301
|
+
|
|
302
|
+
## Browser Support
|
|
164
303
|
|
|
304
|
+
Works in all modern browsers that support CSS transforms and transitions.
|
package/docs/components/Flow.mdx
CHANGED
|
@@ -11,7 +11,7 @@ A component for creating interactive workflow diagrams and flowcharts with suppo
|
|
|
11
11
|
```tsx
|
|
12
12
|
import React, { useState } from 'react';
|
|
13
13
|
import { Flow } from '@app-studio/web';
|
|
14
|
-
import { View } from 'app-studio';
|
|
14
|
+
import { View } from '@app-studio/web';
|
|
15
15
|
|
|
16
16
|
export const BasicFlow = () => {
|
|
17
17
|
// Initial nodes and edges
|
|
@@ -55,7 +55,7 @@ export const BasicFlow = () => {
|
|
|
55
55
|
```tsx
|
|
56
56
|
import React, { useState } from 'react';
|
|
57
57
|
import { Flow } from '@app-studio/web';
|
|
58
|
-
import { View } from 'app-studio';
|
|
58
|
+
import { View } from '@app-studio/web';
|
|
59
59
|
import { FlowNode } from '@app-studio/web';
|
|
60
60
|
|
|
61
61
|
export const FlowWithNodeAddition = () => {
|
|
@@ -101,7 +101,7 @@ export const FlowWithNodeAddition = () => {
|
|
|
101
101
|
```tsx
|
|
102
102
|
import React, { useState } from 'react';
|
|
103
103
|
import { Flow } from '@app-studio/web';
|
|
104
|
-
import { View } from 'app-studio';
|
|
104
|
+
import { View } from '@app-studio/web';
|
|
105
105
|
import { FlowNode } from '@app-studio/web';
|
|
106
106
|
|
|
107
107
|
export const FlowWithDragAndDrop = () => {
|
package/docs/components/Form.mdx
CHANGED
|
@@ -46,7 +46,7 @@ import { Formik } from 'formik';
|
|
|
46
46
|
import * as Yup from 'yup';
|
|
47
47
|
import { FormikForm, FormikTextField, FormikCheckbox } from '@app-studio/web';
|
|
48
48
|
import { Button } from '@app-studio/web';
|
|
49
|
-
import { Vertical } from 'app-studio';
|
|
49
|
+
import { Vertical } from '@app-studio/web';
|
|
50
50
|
|
|
51
51
|
export const BasicForm = () => {
|
|
52
52
|
const initialValues = {
|
|
@@ -134,7 +134,7 @@ import {
|
|
|
134
134
|
FormikTagInput
|
|
135
135
|
} from '@app-studio/web';
|
|
136
136
|
import { Button } from '@app-studio/web';
|
|
137
|
-
import { Vertical } from 'app-studio';
|
|
137
|
+
import { Vertical } from '@app-studio/web';
|
|
138
138
|
|
|
139
139
|
export const AdvancedForm = () => {
|
|
140
140
|
const initialValues = {
|
|
@@ -254,7 +254,7 @@ import { Formik } from 'formik';
|
|
|
254
254
|
import * as Yup from 'yup';
|
|
255
255
|
import { FormikForm, FormikTextField, FormikPassword } from '@app-studio/web';
|
|
256
256
|
import { Button } from '@app-studio/web';
|
|
257
|
-
import { Vertical } from 'app-studio';
|
|
257
|
+
import { Vertical } from '@app-studio/web';
|
|
258
258
|
|
|
259
259
|
export const ValidationForm = () => {
|
|
260
260
|
const initialValues = {
|
|
@@ -342,7 +342,7 @@ import { Formik, FieldArray } from 'formik';
|
|
|
342
342
|
import * as Yup from 'yup';
|
|
343
343
|
import { FormikForm, FormikTextField } from '@app-studio/web';
|
|
344
344
|
import { Button } from '@app-studio/web';
|
|
345
|
-
import { Vertical, Horizontal } from 'app-studio';
|
|
345
|
+
import { Vertical, Horizontal } from '@app-studio/web';
|
|
346
346
|
import { PlusIcon, MinusIcon } from '@app-studio/web';
|
|
347
347
|
|
|
348
348
|
export const DynamicForm = () => {
|
|
@@ -18,7 +18,7 @@ import { FormikForm } from '../Formik.Form';
|
|
|
18
18
|
import { FormikTextField } from '../Formik.TextField';
|
|
19
19
|
import { FormikCheckbox } from '../Formik.Checkbox';
|
|
20
20
|
import { Button } from '../../Button/Button';
|
|
21
|
-
import { Vertical } from 'app-studio';
|
|
21
|
+
import { Vertical } from '@app-studio/web';
|
|
22
22
|
|
|
23
23
|
export const BasicFormExample = () => {
|
|
24
24
|
// Define initial values
|
|
@@ -204,7 +204,7 @@ import { Formik } from 'formik';
|
|
|
204
204
|
import * as Yup from 'yup';
|
|
205
205
|
import { FormikForm } from '../Formik.Form';
|
|
206
206
|
import { FormikChatInput } from '../Formik.ChatInput';
|
|
207
|
-
import { Button, Vertical, Text } from 'app-studio';
|
|
207
|
+
import { Button, Vertical, Text } from '@app-studio/web';
|
|
208
208
|
|
|
209
209
|
export const FormikChatInputExample = () => {
|
|
210
210
|
const mentionData = [
|