@cwncollab-org/mui-component-kit 0.0.1
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/README.md +548 -0
- package/dist/common-dialogs/ConfirmDialog.d.ts +16 -0
- package/dist/common-dialogs/ConfirmDialog.d.ts.map +1 -0
- package/dist/common-dialogs/ConfirmDialog.js +22 -0
- package/dist/common-dialogs/ConfirmDialog.js.map +1 -0
- package/dist/common-dialogs/index.d.ts +4 -0
- package/dist/common-dialogs/index.d.ts.map +1 -0
- package/dist/common-dialogs/index.js +3 -0
- package/dist/common-dialogs/index.js.map +1 -0
- package/dist/common-dialogs/useConfirmDeleteDialog.d.ts +3 -0
- package/dist/common-dialogs/useConfirmDeleteDialog.d.ts.map +1 -0
- package/dist/common-dialogs/useConfirmDeleteDialog.js +19 -0
- package/dist/common-dialogs/useConfirmDeleteDialog.js.map +1 -0
- package/dist/common-dialogs/useConfirmDialog.d.ts +3 -0
- package/dist/common-dialogs/useConfirmDialog.d.ts.map +1 -0
- package/dist/common-dialogs/useConfirmDialog.js +10 -0
- package/dist/common-dialogs/useConfirmDialog.js.map +1 -0
- package/dist/dialogs/DialogCloseButton.d.ts +6 -0
- package/dist/dialogs/DialogCloseButton.d.ts.map +1 -0
- package/dist/dialogs/DialogCloseButton.js +8 -0
- package/dist/dialogs/DialogCloseButton.js.map +1 -0
- package/dist/dialogs/DialogsProvider.d.ts +3 -0
- package/dist/dialogs/DialogsProvider.d.ts.map +1 -0
- package/dist/dialogs/DialogsProvider.js +62 -0
- package/dist/dialogs/DialogsProvider.js.map +1 -0
- package/dist/dialogs/dialogsContext.d.ts +19 -0
- package/dist/dialogs/dialogsContext.d.ts.map +1 -0
- package/dist/dialogs/dialogsContext.js +3 -0
- package/dist/dialogs/dialogsContext.js.map +1 -0
- package/dist/dialogs/dialogsHooks.d.ts +6 -0
- package/dist/dialogs/dialogsHooks.d.ts.map +1 -0
- package/dist/dialogs/dialogsHooks.js +7 -0
- package/dist/dialogs/dialogsHooks.js.map +1 -0
- package/dist/dialogs/index.d.ts +5 -0
- package/dist/dialogs/index.d.ts.map +1 -0
- package/dist/dialogs/index.js +4 -0
- package/dist/dialogs/index.js.map +1 -0
- package/dist/dialogs/types.d.ts +12 -0
- package/dist/dialogs/types.d.ts.map +1 -0
- package/dist/dialogs/types.js +2 -0
- package/dist/dialogs/types.js.map +1 -0
- package/dist/form/Checkbox.d.ts +5 -0
- package/dist/form/Checkbox.d.ts.map +1 -0
- package/dist/form/Checkbox.js +9 -0
- package/dist/form/Checkbox.js.map +1 -0
- package/dist/form/DatePicker.d.ts +10 -0
- package/dist/form/DatePicker.d.ts.map +1 -0
- package/dist/form/DatePicker.js +34 -0
- package/dist/form/DatePicker.js.map +1 -0
- package/dist/form/MultiSelect.d.ts +22 -0
- package/dist/form/MultiSelect.d.ts.map +1 -0
- package/dist/form/MultiSelect.js +45 -0
- package/dist/form/MultiSelect.js.map +1 -0
- package/dist/form/Select.d.ts +21 -0
- package/dist/form/Select.d.ts.map +1 -0
- package/dist/form/Select.js +24 -0
- package/dist/form/Select.js.map +1 -0
- package/dist/form/SubscribeButton.d.ts +6 -0
- package/dist/form/SubscribeButton.d.ts.map +1 -0
- package/dist/form/SubscribeButton.js +9 -0
- package/dist/form/SubscribeButton.js.map +1 -0
- package/dist/form/SubscribeCheckbox.d.ts +5 -0
- package/dist/form/SubscribeCheckbox.d.ts.map +1 -0
- package/dist/form/SubscribeCheckbox.js +9 -0
- package/dist/form/SubscribeCheckbox.js.map +1 -0
- package/dist/form/SubscribeDatePicker.d.ts +10 -0
- package/dist/form/SubscribeDatePicker.d.ts.map +1 -0
- package/dist/form/SubscribeDatePicker.js +9 -0
- package/dist/form/SubscribeDatePicker.js.map +1 -0
- package/dist/form/SubscribeMultiSelect.d.ts +3 -0
- package/dist/form/SubscribeMultiSelect.d.ts.map +1 -0
- package/dist/form/SubscribeMultiSelect.js +9 -0
- package/dist/form/SubscribeMultiSelect.js.map +1 -0
- package/dist/form/SubscribeSelect.d.ts +3 -0
- package/dist/form/SubscribeSelect.d.ts.map +1 -0
- package/dist/form/SubscribeSelect.js +9 -0
- package/dist/form/SubscribeSelect.js.map +1 -0
- package/dist/form/SubscribeTextField.d.ts +3 -0
- package/dist/form/SubscribeTextField.d.ts.map +1 -0
- package/dist/form/SubscribeTextField.js +9 -0
- package/dist/form/SubscribeTextField.js.map +1 -0
- package/dist/form/SubscribeTimePicker.d.ts +10 -0
- package/dist/form/SubscribeTimePicker.d.ts.map +1 -0
- package/dist/form/SubscribeTimePicker.js +9 -0
- package/dist/form/SubscribeTimePicker.js.map +1 -0
- package/dist/form/TextField.d.ts +6 -0
- package/dist/form/TextField.d.ts.map +1 -0
- package/dist/form/TextField.js +18 -0
- package/dist/form/TextField.js.map +1 -0
- package/dist/form/TimePicker.d.ts +10 -0
- package/dist/form/TimePicker.d.ts.map +1 -0
- package/dist/form/TimePicker.js +34 -0
- package/dist/form/TimePicker.js.map +1 -0
- package/dist/form/formContext.d.ts +2 -0
- package/dist/form/formContext.d.ts.map +1 -0
- package/dist/form/formContext.js +3 -0
- package/dist/form/formContext.js.map +1 -0
- package/dist/form/formHooks.d.ts +68 -0
- package/dist/form/formHooks.d.ts.map +1 -0
- package/dist/form/formHooks.js +35 -0
- package/dist/form/formHooks.js.map +1 -0
- package/dist/form/index.d.ts +2 -0
- package/dist/form/index.d.ts.map +1 -0
- package/dist/form/index.js +2 -0
- package/dist/form/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/AppBar.d.ts +20 -0
- package/dist/layout/AppBar.d.ts.map +1 -0
- package/dist/layout/AppBar.js +17 -0
- package/dist/layout/AppBar.js.map +1 -0
- package/dist/layout/AppBarMenu.d.ts +12 -0
- package/dist/layout/AppBarMenu.d.ts.map +1 -0
- package/dist/layout/AppBarMenu.js +26 -0
- package/dist/layout/AppBarMenu.js.map +1 -0
- package/dist/layout/AppLayout.d.ts +23 -0
- package/dist/layout/AppLayout.d.ts.map +1 -0
- package/dist/layout/AppLayout.js +71 -0
- package/dist/layout/AppLayout.js.map +1 -0
- package/dist/layout/index.d.ts +4 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +3 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/layout/types.d.ts +11 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout/types.js +2 -0
- package/dist/layout/types.js.map +1 -0
- package/dist/table/index.d.ts +2 -0
- package/dist/table/index.d.ts.map +1 -0
- package/dist/table/index.js +2 -0
- package/dist/table/index.js.map +1 -0
- package/dist/table/materialRouterTableHooks.d.ts +28 -0
- package/dist/table/materialRouterTableHooks.d.ts.map +1 -0
- package/dist/table/materialRouterTableHooks.js +135 -0
- package/dist/table/materialRouterTableHooks.js.map +1 -0
- package/dist/tabs/RouterTab.d.ts +8 -0
- package/dist/tabs/RouterTab.d.ts.map +1 -0
- package/dist/tabs/RouterTab.js +7 -0
- package/dist/tabs/RouterTab.js.map +1 -0
- package/dist/tabs/TabLabel.d.ts +7 -0
- package/dist/tabs/TabLabel.d.ts.map +1 -0
- package/dist/tabs/TabLabel.js +7 -0
- package/dist/tabs/TabLabel.js.map +1 -0
- package/dist/tabs/index.d.ts +4 -0
- package/dist/tabs/index.d.ts.map +1 -0
- package/dist/tabs/index.js +4 -0
- package/dist/tabs/index.js.map +1 -0
- package/dist/tabs/removeTrailingSlash.d.ts +7 -0
- package/dist/tabs/removeTrailingSlash.d.ts.map +1 -0
- package/dist/tabs/removeTrailingSlash.js +9 -0
- package/dist/tabs/removeTrailingSlash.js.map +1 -0
- package/dist/tabs/removeTrailingSlash.test.d.ts +2 -0
- package/dist/tabs/removeTrailingSlash.test.d.ts.map +1 -0
- package/dist/tabs/removeTrailingSlash.test.js +19 -0
- package/dist/tabs/removeTrailingSlash.test.js.map +1 -0
- package/dist/tabs/routerTabHooks.d.ts +2 -0
- package/dist/tabs/routerTabHooks.d.ts.map +1 -0
- package/dist/tabs/routerTabHooks.js +9 -0
- package/dist/tabs/routerTabHooks.js.map +1 -0
- package/package.json +71 -0
package/README.md
ADDED
@@ -0,0 +1,548 @@
|
|
1
|
+
# Component Kit
|
2
|
+
|
3
|
+
> **Note**: This documentation was generated with the assistance of AI. While we strive for accuracy, please verify any code examples or implementation details in your specific use case.
|
4
|
+
|
5
|
+
A React component library built with TypeScript and Vite. This package provides a set of reusable components built on top of [Material-UI (MUI)](https://mui.com/) and [Tanstack Form](https://tanstack.com/form/latest) for form handling.
|
6
|
+
|
7
|
+
|
8
|
+
## Features
|
9
|
+
|
10
|
+
- Built on Material-UI
|
11
|
+
- Type-safe dialog management
|
12
|
+
- Lazy loading support
|
13
|
+
- Payload and result handling for dialogs
|
14
|
+
- Form components with TanStack Form integration
|
15
|
+
|
16
|
+
## Usage Examples
|
17
|
+
|
18
|
+
### Basic Dialog Usage
|
19
|
+
|
20
|
+
```tsx
|
21
|
+
import { DialogsProvider, useDialogs } from '@cwncollab-org/component-kit'
|
22
|
+
import ExampleDialog from './examples/ExampleDialog'
|
23
|
+
|
24
|
+
function App() {
|
25
|
+
return (
|
26
|
+
<DialogsProvider>
|
27
|
+
<AppPage />
|
28
|
+
</DialogsProvider>
|
29
|
+
)
|
30
|
+
}
|
31
|
+
|
32
|
+
function AppPage() {
|
33
|
+
const { openDialog } = useDialogs()
|
34
|
+
|
35
|
+
return (
|
36
|
+
<Button
|
37
|
+
variant='contained'
|
38
|
+
onClick={() => openDialog('example-dialog', ExampleDialog)}
|
39
|
+
>
|
40
|
+
Open Basic Dialog
|
41
|
+
</Button>
|
42
|
+
)
|
43
|
+
}
|
44
|
+
```
|
45
|
+
|
46
|
+
#### ExampleDialog Implementation
|
47
|
+
|
48
|
+
```tsx
|
49
|
+
import {
|
50
|
+
Dialog,
|
51
|
+
DialogTitle,
|
52
|
+
DialogContentText,
|
53
|
+
DialogContent,
|
54
|
+
DialogProps,
|
55
|
+
} from '@mui/material'
|
56
|
+
|
57
|
+
export default function ExampleDialog({ open, onClose, ...rest }: DialogProps) {
|
58
|
+
return (
|
59
|
+
<Dialog open={open} onClose={onClose} {...rest}>
|
60
|
+
<DialogTitle>Example Dialog</DialogTitle>
|
61
|
+
<DialogContent>
|
62
|
+
<DialogContentText>This is an example dialog</DialogContentText>
|
63
|
+
</DialogContent>
|
64
|
+
</Dialog>
|
65
|
+
)
|
66
|
+
}
|
67
|
+
```
|
68
|
+
|
69
|
+
### Dialog with Payload
|
70
|
+
|
71
|
+
```tsx
|
72
|
+
import { DialogsProvider, useDialogs } from '@cwncollab-org/component-kit'
|
73
|
+
import ExampleDialogWithPayload from './examples/ExampleDialogWithPayload'
|
74
|
+
|
75
|
+
function AppPage() {
|
76
|
+
const { openDialog } = useDialogs()
|
77
|
+
const [name, setName] = useState('')
|
78
|
+
|
79
|
+
return (
|
80
|
+
<>
|
81
|
+
<Input
|
82
|
+
value={name}
|
83
|
+
onChange={e => setName(e.target.value)}
|
84
|
+
placeholder='Enter your name'
|
85
|
+
/>
|
86
|
+
<Button
|
87
|
+
variant='contained'
|
88
|
+
onClick={() => {
|
89
|
+
openDialog(
|
90
|
+
'example-dialog-with-payload',
|
91
|
+
ExampleDialogWithPayload,
|
92
|
+
{ payload: { name } }
|
93
|
+
)
|
94
|
+
}}
|
95
|
+
>
|
96
|
+
Open Dialog with Payload
|
97
|
+
</Button>
|
98
|
+
</>
|
99
|
+
)
|
100
|
+
}
|
101
|
+
```
|
102
|
+
|
103
|
+
#### ExampleDialogWithPayload Implementation
|
104
|
+
|
105
|
+
```tsx
|
106
|
+
import {
|
107
|
+
Dialog,
|
108
|
+
DialogTitle,
|
109
|
+
DialogContentText,
|
110
|
+
DialogContent,
|
111
|
+
} from '@mui/material'
|
112
|
+
import { DialogProps } from '../lib'
|
113
|
+
|
114
|
+
type Payload = {
|
115
|
+
name: string
|
116
|
+
}
|
117
|
+
|
118
|
+
export default function ExampleDialogWithPayload({
|
119
|
+
open,
|
120
|
+
onClose,
|
121
|
+
payload,
|
122
|
+
...rest
|
123
|
+
}: DialogProps<Payload>) {
|
124
|
+
return (
|
125
|
+
<Dialog open={open} onClose={onClose} {...rest}>
|
126
|
+
<DialogTitle>Example Dialog</DialogTitle>
|
127
|
+
<DialogContent>
|
128
|
+
<DialogContentText>
|
129
|
+
This is an example dialog with payload {JSON.stringify(payload)}
|
130
|
+
</DialogContentText>
|
131
|
+
</DialogContent>
|
132
|
+
</Dialog>
|
133
|
+
)
|
134
|
+
}
|
135
|
+
```
|
136
|
+
|
137
|
+
### Dialog with Result
|
138
|
+
|
139
|
+
```tsx
|
140
|
+
import { DialogsProvider, useDialogs } from '@cwncollab-org/component-kit'
|
141
|
+
import ExampleDialogWithResult from './examples/ExampleDialogWithResult'
|
142
|
+
|
143
|
+
function AppPage() {
|
144
|
+
const { openDialog } = useDialogs()
|
145
|
+
const [result, setResult] = useState<{ name: string } | null>(null)
|
146
|
+
|
147
|
+
return (
|
148
|
+
<>
|
149
|
+
<Button
|
150
|
+
variant='contained'
|
151
|
+
onClick={async () => {
|
152
|
+
const result = await openDialog(
|
153
|
+
'example-dialog-with-result',
|
154
|
+
ExampleDialogWithResult,
|
155
|
+
{ payload: { name: 'Initial Name' } }
|
156
|
+
)
|
157
|
+
if (result?.success) {
|
158
|
+
setResult(result.data)
|
159
|
+
}
|
160
|
+
}}
|
161
|
+
>
|
162
|
+
Open Dialog with Result
|
163
|
+
</Button>
|
164
|
+
{result && (
|
165
|
+
<Typography variant='body1'>
|
166
|
+
Result: {result.name}
|
167
|
+
</Typography>
|
168
|
+
)}
|
169
|
+
</>
|
170
|
+
)
|
171
|
+
}
|
172
|
+
```
|
173
|
+
|
174
|
+
#### ExampleDialogWithResult Implementation
|
175
|
+
|
176
|
+
```tsx
|
177
|
+
import {
|
178
|
+
Dialog,
|
179
|
+
DialogTitle,
|
180
|
+
DialogContent,
|
181
|
+
Input,
|
182
|
+
DialogActions,
|
183
|
+
Button,
|
184
|
+
} from '@mui/material'
|
185
|
+
import { DialogProps } from '../lib'
|
186
|
+
import { useState } from 'react'
|
187
|
+
|
188
|
+
type Payload = {
|
189
|
+
name: string
|
190
|
+
}
|
191
|
+
|
192
|
+
type ResultData = {
|
193
|
+
name: string
|
194
|
+
}
|
195
|
+
|
196
|
+
export default function ExampleDialogWithResult({
|
197
|
+
open,
|
198
|
+
onClose,
|
199
|
+
payload,
|
200
|
+
...rest
|
201
|
+
}: DialogProps<Payload, ResultData>) {
|
202
|
+
const [name, setName] = useState(payload?.name || '')
|
203
|
+
return (
|
204
|
+
<Dialog open={open} onClose={onClose} {...rest}>
|
205
|
+
<DialogTitle>Example Dialog</DialogTitle>
|
206
|
+
<DialogContent>
|
207
|
+
<Input
|
208
|
+
value={name}
|
209
|
+
onChange={e => setName(e.target.value)}
|
210
|
+
placeholder='Name'
|
211
|
+
/>
|
212
|
+
</DialogContent>
|
213
|
+
<DialogActions>
|
214
|
+
<Button onClick={ev => onClose(ev, { success: true, data: { name } })}>
|
215
|
+
Save
|
216
|
+
</Button>
|
217
|
+
</DialogActions>
|
218
|
+
</Dialog>
|
219
|
+
)
|
220
|
+
}
|
221
|
+
```
|
222
|
+
|
223
|
+
### Lazy Loading Dialog
|
224
|
+
|
225
|
+
```tsx
|
226
|
+
import { DialogsProvider, useDialogs } from '@cwncollab-org/component-kit'
|
227
|
+
import { lazy } from 'react'
|
228
|
+
|
229
|
+
const ExampleDialog2 = lazy(() => import('./examples/ExampleDialog2'))
|
230
|
+
|
231
|
+
function AppPage() {
|
232
|
+
const { openDialog } = useDialogs()
|
233
|
+
|
234
|
+
return (
|
235
|
+
<Button
|
236
|
+
variant='contained'
|
237
|
+
onClick={() => openDialog('example-dialog2', ExampleDialog2)}
|
238
|
+
>
|
239
|
+
Open Lazy Loaded Dialog
|
240
|
+
</Button>
|
241
|
+
)
|
242
|
+
}
|
243
|
+
```
|
244
|
+
|
245
|
+
#### ExampleDialog2 Implementation
|
246
|
+
|
247
|
+
```tsx
|
248
|
+
import {
|
249
|
+
Dialog,
|
250
|
+
DialogTitle,
|
251
|
+
DialogContentText,
|
252
|
+
DialogContent,
|
253
|
+
DialogProps,
|
254
|
+
} from '@mui/material'
|
255
|
+
|
256
|
+
export default function ExampleDialog2({
|
257
|
+
open,
|
258
|
+
onClose,
|
259
|
+
...rest
|
260
|
+
}: DialogProps) {
|
261
|
+
return (
|
262
|
+
<Dialog open={open} onClose={onClose} {...rest}>
|
263
|
+
<DialogTitle>Example Dialog</DialogTitle>
|
264
|
+
<DialogContent>
|
265
|
+
<DialogContentText>This is an example dialog 2</DialogContentText>
|
266
|
+
</DialogContent>
|
267
|
+
</Dialog>
|
268
|
+
)
|
269
|
+
}
|
270
|
+
```
|
271
|
+
|
272
|
+
### Form Example with Zod Validation
|
273
|
+
|
274
|
+
```tsx
|
275
|
+
import { Box, Button, Paper, Stack, Typography } from '@mui/material'
|
276
|
+
import { useAppForm } from '@cwncollab-org/component-kit'
|
277
|
+
import { useState } from 'react'
|
278
|
+
import { z } from 'zod'
|
279
|
+
|
280
|
+
// Define your form schema with Zod
|
281
|
+
const formSchema = z.object({
|
282
|
+
username: z.string()
|
283
|
+
.min(1, 'Username is required')
|
284
|
+
.max(20, 'Username must be less than 20 characters')
|
285
|
+
.regex(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers, and underscores'),
|
286
|
+
email: z.string()
|
287
|
+
.email('Invalid email address')
|
288
|
+
.min(1, 'Email is required'),
|
289
|
+
age: z.number()
|
290
|
+
.min(18, 'You must be at least 18 years old')
|
291
|
+
.max(120, 'Please enter a valid age'),
|
292
|
+
subscribe: z.boolean()
|
293
|
+
.refine(val => val === true, 'You must subscribe to continue'),
|
294
|
+
role: z.string()
|
295
|
+
.min(1, 'Please select a role'),
|
296
|
+
birthDate: z.date()
|
297
|
+
.min(new Date('1900-01-01'), 'Please enter a valid birth date')
|
298
|
+
.max(new Date(), 'Birth date cannot be in the future'),
|
299
|
+
})
|
300
|
+
|
301
|
+
// Infer the form type from the schema
|
302
|
+
type FormValues = z.infer<typeof formSchema>
|
303
|
+
|
304
|
+
export function FormExample() {
|
305
|
+
const [value, setValue] = useState<FormValues>({
|
306
|
+
username: '',
|
307
|
+
email: '',
|
308
|
+
age: 18,
|
309
|
+
subscribe: false,
|
310
|
+
role: '',
|
311
|
+
birthDate: new Date(),
|
312
|
+
})
|
313
|
+
|
314
|
+
const form = useAppForm({
|
315
|
+
defaultValues: {
|
316
|
+
username: '',
|
317
|
+
email: '',
|
318
|
+
age: 18,
|
319
|
+
subscribe: false,
|
320
|
+
role: '',
|
321
|
+
birthDate: new Date(),
|
322
|
+
},
|
323
|
+
onSubmit: ({ value }) => {
|
324
|
+
setValue(value as FormValues)
|
325
|
+
},
|
326
|
+
// Add Zod validation
|
327
|
+
validators: { onChange: formSchema },
|
328
|
+
})
|
329
|
+
|
330
|
+
return (
|
331
|
+
<Paper sx={{ p: 2 }}>
|
332
|
+
<Box>
|
333
|
+
<Typography>Form Example with Zod Validation</Typography>
|
334
|
+
</Box>
|
335
|
+
<Box
|
336
|
+
component='form'
|
337
|
+
sx={{ py: 2 }}
|
338
|
+
onSubmit={e => {
|
339
|
+
e.preventDefault()
|
340
|
+
e.stopPropagation()
|
341
|
+
form.handleSubmit()
|
342
|
+
}}
|
343
|
+
>
|
344
|
+
<Stack spacing={2}>
|
345
|
+
<form.AppField
|
346
|
+
name='username'
|
347
|
+
children={field => (
|
348
|
+
<field.TextField
|
349
|
+
label='Username'
|
350
|
+
fullWidth
|
351
|
+
/>
|
352
|
+
)}
|
353
|
+
/>
|
354
|
+
<form.AppField
|
355
|
+
name='email'
|
356
|
+
children={field => (
|
357
|
+
<field.TextField
|
358
|
+
label='Email'
|
359
|
+
fullWidth
|
360
|
+
/>
|
361
|
+
)}
|
362
|
+
/>
|
363
|
+
<form.AppField
|
364
|
+
name='age'
|
365
|
+
children={field => (
|
366
|
+
<field.TextField
|
367
|
+
label='Age'
|
368
|
+
type='number'
|
369
|
+
fullWidth
|
370
|
+
/>
|
371
|
+
)}
|
372
|
+
/>
|
373
|
+
<form.AppField
|
374
|
+
name='birthDate'
|
375
|
+
children={field => (
|
376
|
+
<field.DatePicker
|
377
|
+
label='Birth Date'
|
378
|
+
/>
|
379
|
+
)}
|
380
|
+
/>
|
381
|
+
<form.AppField
|
382
|
+
name='role'
|
383
|
+
children={field => (
|
384
|
+
<field.Select
|
385
|
+
label='Role'
|
386
|
+
fullWidth
|
387
|
+
>
|
388
|
+
<MenuItem value=''>
|
389
|
+
<em>None</em>
|
390
|
+
</MenuItem>
|
391
|
+
<MenuItem value='admin'>Admin</MenuItem>
|
392
|
+
<MenuItem value='user'>User</MenuItem>
|
393
|
+
</field.Select>
|
394
|
+
)}
|
395
|
+
/>
|
396
|
+
<form.AppField
|
397
|
+
name='subscribe'
|
398
|
+
children={field => (
|
399
|
+
<field.Checkbox
|
400
|
+
label='Subscribe to newsletter'
|
401
|
+
/>
|
402
|
+
)}
|
403
|
+
/>
|
404
|
+
<form.AppForm>
|
405
|
+
<form.SubscribeButton type='submit' variant='contained'>
|
406
|
+
Submit
|
407
|
+
</form.SubscribeButton>
|
408
|
+
<form.SubscribeButton
|
409
|
+
type='reset'
|
410
|
+
variant='outlined'
|
411
|
+
onClick={() => form.reset()}
|
412
|
+
>
|
413
|
+
Reset
|
414
|
+
</form.SubscribeButton>
|
415
|
+
</form.AppForm>
|
416
|
+
<Typography variant='body1'>{JSON.stringify(value)}</Typography>
|
417
|
+
</Stack>
|
418
|
+
</Box>
|
419
|
+
</Paper>
|
420
|
+
)
|
421
|
+
}
|
422
|
+
```
|
423
|
+
|
424
|
+
### MultiSelect Component
|
425
|
+
|
426
|
+
The MultiSelect component provides a multiple selection dropdown with checkboxes, built on top of MUI's Select component and integrated with TanStack Form.
|
427
|
+
|
428
|
+
```tsx
|
429
|
+
import { useAppForm } from '@cwncollab-org/component-kit'
|
430
|
+
import { z } from 'zod'
|
431
|
+
|
432
|
+
// Define your form schema
|
433
|
+
const formSchema = z.object({
|
434
|
+
categories: z.array(z.string()).min(1, 'Please select at least one category'),
|
435
|
+
})
|
436
|
+
|
437
|
+
// Define your options
|
438
|
+
const categories = [
|
439
|
+
{ value: 'tech', label: 'Technology' },
|
440
|
+
{ value: 'sports', label: 'Sports' },
|
441
|
+
{ value: 'news', label: 'News' },
|
442
|
+
{ value: 'entertainment', label: 'Entertainment' },
|
443
|
+
{ value: 'science', label: 'Science' },
|
444
|
+
]
|
445
|
+
|
446
|
+
function MyForm() {
|
447
|
+
const form = useAppForm({
|
448
|
+
defaultValues: {
|
449
|
+
categories: [],
|
450
|
+
},
|
451
|
+
validators: {
|
452
|
+
onSubmit: formSchema,
|
453
|
+
},
|
454
|
+
onSubmit: ({ value }) => {
|
455
|
+
console.log('Selected categories:', value.categories)
|
456
|
+
},
|
457
|
+
})
|
458
|
+
|
459
|
+
return (
|
460
|
+
<form.AppField
|
461
|
+
name="categories"
|
462
|
+
children={field => (
|
463
|
+
<field.MultiSelect
|
464
|
+
label="Categories"
|
465
|
+
required
|
466
|
+
options={categories}
|
467
|
+
labelShrink
|
468
|
+
size="small"
|
469
|
+
fullWidth
|
470
|
+
// Optional: Sort selected values by label or value
|
471
|
+
sortSelected="label"
|
472
|
+
/>
|
473
|
+
)}
|
474
|
+
/>
|
475
|
+
)
|
476
|
+
}
|
477
|
+
```
|
478
|
+
|
479
|
+
#### MultiSelect Props
|
480
|
+
|
481
|
+
| Prop | Type | Default | Description |
|
482
|
+
|------|------|---------|-------------|
|
483
|
+
| `label` | `string` | - | The label text for the select field |
|
484
|
+
| `labelShrink` | `boolean` | `false` | Whether the label should shrink |
|
485
|
+
| `size` | `'small' \| 'medium'` | `'medium'` | The size of the select field |
|
486
|
+
| `fullWidth` | `boolean` | `false` | Whether the select should take full width |
|
487
|
+
| `options` | `Array<{ value: string, label: string }> \| string[]` | `[]` | The options to display in the select |
|
488
|
+
| `sortSelected` | `'label' \| 'value' \| false` | `false` | Sort selected values by label or value |
|
489
|
+
| `slotProps` | `object` | - | Props for underlying MUI components |
|
490
|
+
|
491
|
+
|
492
|
+
### Common Dialog Patterns
|
493
|
+
|
494
|
+
Here are some common dialog patterns you can implement using the component kit:
|
495
|
+
|
496
|
+
#### Confirmation Dialog
|
497
|
+
|
498
|
+
```tsx
|
499
|
+
import { useConfirmDialog } from '@cwncollab-org/component-kit'
|
500
|
+
|
501
|
+
function MyComponent() {
|
502
|
+
const confirm = useConfirmDialog()
|
503
|
+
|
504
|
+
const handleClick = async () => {
|
505
|
+
const result = await confirm({
|
506
|
+
title: 'Confirm',
|
507
|
+
message: 'Are you sure you want to add this item to cart?',
|
508
|
+
})
|
509
|
+
|
510
|
+
if (result) {
|
511
|
+
// Proceed
|
512
|
+
}
|
513
|
+
}
|
514
|
+
|
515
|
+
return (
|
516
|
+
<Button onClick={handleClick}>
|
517
|
+
Click
|
518
|
+
</Button>
|
519
|
+
)
|
520
|
+
}
|
521
|
+
```
|
522
|
+
|
523
|
+
#### Delete Confirmation Dialog
|
524
|
+
|
525
|
+
```tsx
|
526
|
+
import { useConfirmDeleteDialog } from '@cwncollab-org/component-kit'
|
527
|
+
|
528
|
+
function MyComponent() {
|
529
|
+
const confirmDelete = useConfirmDeleteDialog()
|
530
|
+
|
531
|
+
const handleDelete = async () => {
|
532
|
+
const result = await confirmDelete({
|
533
|
+
title: 'Delete Item',
|
534
|
+
message: 'Are you sure you want to delete this item? This action cannot be undone.',
|
535
|
+
})
|
536
|
+
|
537
|
+
if (result) {
|
538
|
+
// Proceed with deletion
|
539
|
+
}
|
540
|
+
}
|
541
|
+
|
542
|
+
return (
|
543
|
+
<Button onClick={handleDelete}>
|
544
|
+
Delete Item
|
545
|
+
</Button>
|
546
|
+
)
|
547
|
+
}
|
548
|
+
```
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { ButtonProps } from '@mui/material';
|
2
|
+
import { DialogProps } from '../dialogs/types';
|
3
|
+
export type ConfirmDialogOptions = {
|
4
|
+
title?: string;
|
5
|
+
message?: string | React.ReactNode;
|
6
|
+
confirmText?: string;
|
7
|
+
cancelText?: string;
|
8
|
+
slotProps?: {
|
9
|
+
confirm?: ButtonProps;
|
10
|
+
cancel?: ButtonProps;
|
11
|
+
};
|
12
|
+
};
|
13
|
+
type ConfirmDialogProps = DialogProps<ConfirmDialogOptions>;
|
14
|
+
export declare function ConfirmDialog(props: ConfirmDialogProps): import("react/jsx-runtime").JSX.Element;
|
15
|
+
export {};
|
16
|
+
//# sourceMappingURL=ConfirmDialog.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ConfirmDialog.d.ts","sourceRoot":"","sources":["../../src/lib/common-dialogs/ConfirmDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EAKZ,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAA;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,WAAW,CAAA;QACrB,MAAM,CAAC,EAAE,WAAW,CAAA;KACrB,CAAA;CACF,CAAA;AAED,KAAK,kBAAkB,GAAG,WAAW,CAAC,oBAAoB,CAAC,CAAA;AAE3D,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CA8BtD"}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
import { Button, DialogActions, DialogContent, DialogContentText, DialogTitle, } from '@mui/material';
|
3
|
+
import { Dialog } from '@mui/material';
|
4
|
+
export function ConfirmDialog(props) {
|
5
|
+
const { open, onClose, payload, ...rest } = props;
|
6
|
+
const title = payload?.title ?? '';
|
7
|
+
const message = payload?.message ?? '';
|
8
|
+
const confirmText = payload?.confirmText ?? 'Confirm';
|
9
|
+
const confirmProps = payload?.slotProps?.confirm ?? {
|
10
|
+
color: 'primary',
|
11
|
+
variant: 'contained',
|
12
|
+
};
|
13
|
+
confirmProps.onClick = () => onClose({}, { success: true });
|
14
|
+
const cancelText = payload?.cancelText ?? 'Cancel';
|
15
|
+
const cancelProps = payload?.slotProps?.cancel ?? {
|
16
|
+
color: 'primary',
|
17
|
+
variant: 'outlined',
|
18
|
+
};
|
19
|
+
cancelProps.onClick = () => onClose({}, { success: false });
|
20
|
+
return (_jsxs(Dialog, { open: open, onClose: onClose, maxWidth: 'sm', fullWidth: true, ...rest, children: [_jsx(DialogTitle, { children: title }), _jsx(DialogContent, { children: _jsx(DialogContentText, { children: message }) }), _jsxs(DialogActions, { sx: { px: 3, pb: 2 }, children: [_jsx(Button, { ...cancelProps, children: cancelText }), _jsx(Button, { ...confirmProps, children: confirmText })] })] }));
|
21
|
+
}
|
22
|
+
//# sourceMappingURL=ConfirmDialog.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ConfirmDialog.js","sourceRoot":"","sources":["../../src/lib/common-dialogs/ConfirmDialog.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,MAAM,EAEN,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,WAAW,GACZ,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAgBtC,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAA;IACjD,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAA;IAClC,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,EAAE,CAAA;IAEtC,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,SAAS,CAAA;IACrD,MAAM,YAAY,GAAG,OAAO,EAAE,SAAS,EAAE,OAAO,IAAI;QAClD,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,WAAW;KACrB,CAAA;IACD,YAAY,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;IAC3D,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,QAAQ,CAAA;IAClD,MAAM,WAAW,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI;QAChD,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,UAAU;KACpB,CAAA;IACD,WAAW,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;IAE3D,OAAO,CACL,MAAC,MAAM,IAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAC,IAAI,EAAC,SAAS,WAAK,IAAI,aACpE,KAAC,WAAW,cAAE,KAAK,GAAe,EAClC,KAAC,aAAa,cACZ,KAAC,iBAAiB,cAAE,OAAO,GAAqB,GAClC,EAChB,MAAC,aAAa,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,aACjC,KAAC,MAAM,OAAK,WAAW,YAAG,UAAU,GAAU,EAC9C,KAAC,MAAM,OAAK,YAAY,YAAG,WAAW,GAAU,IAClC,IACT,CACV,CAAA;AACH,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/common-dialogs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/common-dialogs/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useConfirmDeleteDialog.d.ts","sourceRoot":"","sources":["../../src/lib/common-dialogs/useConfirmDeleteDialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAGtD,wBAAgB,sBAAsB,eAEG,oBAAoB,mDAc5D"}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { useConfirmDialog } from './useConfirmDialog';
|
2
|
+
export function useConfirmDeleteDialog() {
|
3
|
+
const confirm = useConfirmDialog();
|
4
|
+
const confirmDelete = async (options) => {
|
5
|
+
return await confirm({
|
6
|
+
...options,
|
7
|
+
slotProps: {
|
8
|
+
...options?.slotProps,
|
9
|
+
confirm: {
|
10
|
+
color: 'error',
|
11
|
+
variant: 'contained',
|
12
|
+
...options?.slotProps?.confirm,
|
13
|
+
},
|
14
|
+
},
|
15
|
+
});
|
16
|
+
};
|
17
|
+
return confirmDelete;
|
18
|
+
}
|
19
|
+
//# sourceMappingURL=useConfirmDeleteDialog.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useConfirmDeleteDialog.js","sourceRoot":"","sources":["../../src/lib/common-dialogs/useConfirmDeleteDialog.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,MAAM,UAAU,sBAAsB;IACpC,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAA;IAClC,MAAM,aAAa,GAAG,KAAK,EAAE,OAA8B,EAAE,EAAE;QAC7D,OAAO,MAAM,OAAO,CAAC;YACnB,GAAG,OAAO;YACV,SAAS,EAAE;gBACT,GAAG,OAAO,EAAE,SAAS;gBACrB,OAAO,EAAE;oBACP,KAAK,EAAE,OAAO;oBACd,OAAO,EAAE,WAAW;oBACpB,GAAG,OAAO,EAAE,SAAS,EAAE,OAAO;iBAC/B;aACF;SACF,CAAC,CAAA;IACJ,CAAC,CAAA;IACD,OAAO,aAAa,CAAA;AACtB,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useConfirmDialog.d.ts","sourceRoot":"","sources":["../../src/lib/common-dialogs/useConfirmDialog.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAErE,wBAAgB,gBAAgB,eAEH,oBAAoB,mDAKhD"}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { useDialogs } from '../dialogs/dialogsHooks';
|
2
|
+
import { ConfirmDialog } from './ConfirmDialog';
|
3
|
+
export function useConfirmDialog() {
|
4
|
+
const { openDialog } = useDialogs();
|
5
|
+
const confirm = (options) => openDialog('confirm-dialog', ConfirmDialog, {
|
6
|
+
payload: options,
|
7
|
+
});
|
8
|
+
return confirm;
|
9
|
+
}
|
10
|
+
//# sourceMappingURL=useConfirmDialog.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useConfirmDialog.js","sourceRoot":"","sources":["../../src/lib/common-dialogs/useConfirmDialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAwB,MAAM,iBAAiB,CAAA;AAErE,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAAA;IACnC,MAAM,OAAO,GAAG,CAAC,OAA8B,EAAE,EAAE,CACjD,UAAU,CAAC,gBAAgB,EAAE,aAAa,EAAE;QAC1C,OAAO,EAAE,OAAO;KACjB,CAAC,CAAA;IACJ,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"DialogCloseButton.d.ts","sourceRoot":"","sources":["../../src/lib/dialogs/DialogCloseButton.tsx"],"names":[],"mappings":"AAGA,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAA;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,2CAW7C"}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import { IconButton } from '@mui/material';
|
3
|
+
import CloseIcon from '@mui/icons-material/Close';
|
4
|
+
export function DialogCloseButton(props) {
|
5
|
+
const { onClick } = props;
|
6
|
+
return (_jsx(IconButton, { sx: { position: 'absolute', right: 12, top: 12 }, onClick: onClick, children: _jsx(CloseIcon, {}) }));
|
7
|
+
}
|
8
|
+
//# sourceMappingURL=DialogCloseButton.js.map
|