mui-design-system 0.0.32 → 0.0.34
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 +644 -10
- package/dist/components/form/components/UFTextField.js +2 -2
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# mui-design-system
|
|
2
2
|
|
|
3
|
-
Design system based on MUI (Material UI) with custom theme, form components, and utilities.
|
|
3
|
+
Design system based on MUI (Material UI) with custom theme, form components, table, and utilities.
|
|
4
|
+
|
|
5
|
+
---
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -8,7 +10,7 @@ Design system based on MUI (Material UI) with custom theme, form components, and
|
|
|
8
10
|
npm install mui-design-system
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
### Peer dependencies
|
|
12
14
|
|
|
13
15
|
Install in your project if not already present:
|
|
14
16
|
|
|
@@ -17,27 +19,657 @@ Install in your project if not already present:
|
|
|
17
19
|
- `@emotion/react`, `@emotion/styled`
|
|
18
20
|
- `styled-components` (^6.1.8)
|
|
19
21
|
- `stylis-plugin-rtl` (for RTL)
|
|
22
|
+
- For form: `react-hook-form` (^7.51.2)
|
|
23
|
+
- For table: `@tanstack/react-table` (^8.17.3)
|
|
24
|
+
|
|
25
|
+
---
|
|
20
26
|
|
|
21
|
-
##
|
|
27
|
+
## Quick start
|
|
22
28
|
|
|
23
29
|
```tsx
|
|
24
30
|
import { ReactCacheProvider, themeOptions, Form, colors } from 'mui-design-system';
|
|
31
|
+
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
|
32
|
+
|
|
33
|
+
const theme = createTheme(themeOptions('light', false)); // mode, isRtl
|
|
34
|
+
|
|
35
|
+
<ThemeProvider theme={theme}>
|
|
36
|
+
<ReactCacheProvider isRtl={false}>
|
|
37
|
+
<App />
|
|
38
|
+
</ReactCacheProvider>
|
|
39
|
+
</ThemeProvider>
|
|
40
|
+
|
|
41
|
+
// Colors from subpath
|
|
42
|
+
import { colors } from 'mui-design-system/colors/index';
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Exports overview
|
|
48
|
+
|
|
49
|
+
| Category | Exports |
|
|
50
|
+
|----------|---------|
|
|
51
|
+
| Theme & providers | `themeOptions`, `ReactCacheProvider`, `NextCacheProvider` |
|
|
52
|
+
| Form | `Form`, `FormProvider`, and all UF* field components + `CheckboxList` |
|
|
53
|
+
| Table | `CustomTable`, `useTable` |
|
|
54
|
+
| OTP | `OTPInput` |
|
|
55
|
+
| Methods | `debounce`, `result`, `deepMerge` |
|
|
56
|
+
| Colors | `colors` (from `mui-design-system/colors/index`) |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 1. Theme & providers
|
|
61
|
+
|
|
62
|
+
### `themeOptions(mode, isRtl)`
|
|
63
|
+
|
|
64
|
+
Builds MUI `ThemeOptions` (palette, typography, components, direction).
|
|
65
|
+
|
|
66
|
+
| Parameter | Type | Description |
|
|
67
|
+
|-----------|------|-------------|
|
|
68
|
+
| `mode` | `'light' \| 'dark'` | Palette mode |
|
|
69
|
+
| `isRtl` | `boolean` | RTL/LTR direction |
|
|
25
70
|
|
|
26
|
-
|
|
27
|
-
|
|
71
|
+
**Example:**
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { createTheme } from '@mui/material/styles';
|
|
75
|
+
import { themeOptions } from 'mui-design-system';
|
|
76
|
+
|
|
77
|
+
const theme = createTheme(themeOptions('light', false));
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### `ReactCacheProvider`
|
|
83
|
+
|
|
84
|
+
Emotion cache provider for React apps (non-Next). Use for correct RTL/LTR styling with the theme.
|
|
85
|
+
|
|
86
|
+
**Props:**
|
|
87
|
+
|
|
88
|
+
| Prop | Type | Default | Description |
|
|
89
|
+
|------|------|---------|-------------|
|
|
90
|
+
| `children` | `ReactNode` | — | App content |
|
|
91
|
+
| `isRtl` | `boolean` | — | Use RTL cache (with stylis-plugin-rtl) |
|
|
92
|
+
|
|
93
|
+
**Example:**
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { ReactCacheProvider } from 'mui-design-system';
|
|
97
|
+
|
|
98
|
+
<ReactCacheProvider isRtl={false}>
|
|
28
99
|
<App />
|
|
29
100
|
</ReactCacheProvider>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### `NextCacheProvider`
|
|
106
|
+
|
|
107
|
+
Provider for Next.js (with `@mui/material-nextjs`). In the current version it mainly wraps `children`; use Next’s config for RTL if needed.
|
|
108
|
+
|
|
109
|
+
**Props:** `children`, `isRtl`
|
|
110
|
+
|
|
111
|
+
**Example:**
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import { NextCacheProvider } from 'mui-design-system';
|
|
115
|
+
|
|
116
|
+
<NextCacheProvider isRtl={false}>
|
|
117
|
+
<App />
|
|
118
|
+
</NextCacheProvider>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 2. Form
|
|
124
|
+
|
|
125
|
+
Form is built on **react-hook-form** and a **schema** array that describes each field.
|
|
126
|
+
|
|
127
|
+
### `Form`
|
|
128
|
+
|
|
129
|
+
Renders form fields from a `schema` and a react-hook-form instance.
|
|
130
|
+
|
|
131
|
+
**Props:**
|
|
132
|
+
|
|
133
|
+
| Prop | Type | Default | Description |
|
|
134
|
+
|------|------|---------|-------------|
|
|
135
|
+
| `schema` | `TFormSchema` | — | Array of field configs |
|
|
136
|
+
| `form` | `UseFormReturn<any>` | — | Return value of `useForm()` |
|
|
137
|
+
| `gridContainerProps` | `GridProps` | — | Grid container props |
|
|
138
|
+
| `gridItemProps` | `GridProps` | — | Props for each grid item |
|
|
139
|
+
| `itemProps` | `any` | — | Shared item props |
|
|
140
|
+
| `labelsProps` | `Partial<TypographyProps>` | — | Label typography/style |
|
|
141
|
+
| `hideRequiredStar` | `boolean` | `false` | Hide required asterisk |
|
|
142
|
+
| `inputLabelMode` | `'static' \| 'relative'` | `'static'` | Label placement |
|
|
143
|
+
| `inputVariants` | `'outlined' \| 'filled' \| 'standard'` | `'outlined'` | Text field variant |
|
|
144
|
+
| `withoutHelperText` | `boolean` | — | Hide helper text |
|
|
145
|
+
| `disabled` | `boolean` | — | Disable entire form |
|
|
146
|
+
|
|
147
|
+
**Schema item shape (summary):** `name`, `label`, `type`, `rules` (react-hook-form), `defaultValue`, `placeholder`, `options` (for select/radio/etc.), `props` / `itemProps` per type.
|
|
148
|
+
|
|
149
|
+
**Schema field types:** `'text'`, `'email'`, `'password'`, `'number'`, `'tel'`, `'text-area'`, `'select'`, `'multi-select'`, `'auto-complete'`, `'radio'`, `'checkbox'`, `'multi-checkbox'`, `'switch'`, `'date-picker'`, `'time'`, `'currency'`, `'uploader'`.
|
|
150
|
+
|
|
151
|
+
**Example:**
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
import { useForm } from 'react-hook-form';
|
|
155
|
+
import { Form } from 'mui-design-system';
|
|
156
|
+
|
|
157
|
+
const schema = [
|
|
158
|
+
{ name: 'email', label: 'Email', type: 'email', rules: { required: true } },
|
|
159
|
+
{ name: 'age', label: 'Age', type: 'number' },
|
|
160
|
+
{
|
|
161
|
+
name: 'country',
|
|
162
|
+
label: 'Country',
|
|
163
|
+
type: 'select',
|
|
164
|
+
options: [
|
|
165
|
+
{ value: 'us', label: 'United States' },
|
|
166
|
+
{ value: 'uk', label: 'United Kingdom' },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
const MyForm = () => {
|
|
172
|
+
const form = useForm({ defaultValues: { email: '', age: 0, country: '' } });
|
|
173
|
+
return (
|
|
174
|
+
<form onSubmit={form.handleSubmit((data) => console.log(data))}>
|
|
175
|
+
<Form schema={schema} form={form} />
|
|
176
|
+
<button type="submit">Submit</button>
|
|
177
|
+
</form>
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### `FormProvider`
|
|
185
|
+
|
|
186
|
+
Provides form theme and optional custom inputs. Wrap your form when you need default styling or custom field types.
|
|
187
|
+
|
|
188
|
+
**Props:** `children`, `theme?` (TFormTheme), `customInputs?`
|
|
189
|
+
|
|
190
|
+
**Example:**
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { FormProvider, Form } from 'mui-design-system';
|
|
194
|
+
|
|
195
|
+
<FormProvider theme={{ text: { /* default TextField props */ } }}>
|
|
196
|
+
<Form schema={schema} form={form} />
|
|
197
|
+
</FormProvider>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### Form field components (UF*)
|
|
203
|
+
|
|
204
|
+
These are used internally by `Form` but can also be used standalone with react-hook-form’s `register` / `control`. All are wrapped with an error boundary when exported.
|
|
205
|
+
|
|
206
|
+
#### `UFTextField`
|
|
207
|
+
|
|
208
|
+
Text input for `text`, `email`, `password`, `number`, `tel`.
|
|
209
|
+
|
|
210
|
+
**Example:**
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
import { useForm } from 'react-hook-form';
|
|
214
|
+
import { UFTextField } from 'mui-design-system';
|
|
215
|
+
|
|
216
|
+
const MyField = () => {
|
|
217
|
+
const form = useForm({ defaultValues: { username: '' } });
|
|
218
|
+
return (
|
|
219
|
+
<UFTextField
|
|
220
|
+
form={form}
|
|
221
|
+
name="username"
|
|
222
|
+
label="Username"
|
|
223
|
+
type="text"
|
|
224
|
+
placeholder="Enter username"
|
|
225
|
+
/>
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
#### `UFTextArea`
|
|
233
|
+
|
|
234
|
+
Multiline text field.
|
|
235
|
+
|
|
236
|
+
**Example:**
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
import { Form, useForm } from 'mui-design-system';
|
|
240
|
+
|
|
241
|
+
const schema = [
|
|
242
|
+
{ name: 'bio', label: 'Bio', type: 'text-area', placeholder: 'Tell us about yourself' },
|
|
243
|
+
];
|
|
244
|
+
const form = useForm({ defaultValues: { bio: '' } });
|
|
245
|
+
<Form schema={schema} form={form} />;
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
#### `UFSelect`
|
|
251
|
+
|
|
252
|
+
Single select dropdown.
|
|
253
|
+
|
|
254
|
+
**Example:**
|
|
255
|
+
|
|
256
|
+
```tsx
|
|
257
|
+
const schema = [
|
|
258
|
+
{
|
|
259
|
+
name: 'city',
|
|
260
|
+
label: 'City',
|
|
261
|
+
type: 'select',
|
|
262
|
+
options: [
|
|
263
|
+
{ value: 'ny', label: 'New York' },
|
|
264
|
+
{ value: 'la', label: 'Los Angeles' },
|
|
265
|
+
],
|
|
266
|
+
},
|
|
267
|
+
];
|
|
268
|
+
<Form schema={schema} form={form} />;
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
#### `UFMultiSelect`
|
|
274
|
+
|
|
275
|
+
Multi-select dropdown.
|
|
276
|
+
|
|
277
|
+
**Example:**
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
const schema = [
|
|
281
|
+
{
|
|
282
|
+
name: 'tags',
|
|
283
|
+
label: 'Tags',
|
|
284
|
+
type: 'multi-select',
|
|
285
|
+
options: [
|
|
286
|
+
{ value: 'a', label: 'Tag A' },
|
|
287
|
+
{ value: 'b', label: 'Tag B' },
|
|
288
|
+
],
|
|
289
|
+
},
|
|
290
|
+
];
|
|
291
|
+
<Form schema={schema} form={form} />;
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
#### `UFAutoComplete`
|
|
297
|
+
|
|
298
|
+
Autocomplete with search, options, and optional async loading.
|
|
299
|
+
|
|
300
|
+
**Example:**
|
|
301
|
+
|
|
302
|
+
```tsx
|
|
303
|
+
const schema = [
|
|
304
|
+
{
|
|
305
|
+
name: 'country',
|
|
306
|
+
label: 'Country',
|
|
307
|
+
type: 'auto-complete',
|
|
308
|
+
options: countries,
|
|
309
|
+
onSearch: (value) => fetchCountries(value),
|
|
310
|
+
isLoading: loading,
|
|
311
|
+
},
|
|
312
|
+
];
|
|
313
|
+
<Form schema={schema} form={form} />;
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
#### `UFCheckbox`
|
|
319
|
+
|
|
320
|
+
Single checkbox.
|
|
321
|
+
|
|
322
|
+
**Example:**
|
|
323
|
+
|
|
324
|
+
```tsx
|
|
325
|
+
const schema = [
|
|
326
|
+
{ name: 'agree', label: 'I agree to terms', type: 'checkbox' },
|
|
327
|
+
];
|
|
328
|
+
<Form schema={schema} form={form} />;
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
#### `UFMultiCheckbox` / `CheckboxList`
|
|
334
|
+
|
|
335
|
+
List of checkboxes; used for multi-checkbox fields.
|
|
336
|
+
|
|
337
|
+
**Example:**
|
|
338
|
+
|
|
339
|
+
```tsx
|
|
340
|
+
const schema = [
|
|
341
|
+
{
|
|
342
|
+
name: 'interests',
|
|
343
|
+
label: 'Interests',
|
|
344
|
+
type: 'multi-checkbox',
|
|
345
|
+
options: [
|
|
346
|
+
{ value: 'sports', label: 'Sports' },
|
|
347
|
+
{ value: 'music', label: 'Music' },
|
|
348
|
+
],
|
|
349
|
+
},
|
|
350
|
+
];
|
|
351
|
+
<Form schema={schema} form={form} />;
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
---
|
|
30
355
|
|
|
31
|
-
|
|
356
|
+
#### `UFRadio`
|
|
357
|
+
|
|
358
|
+
Radio group.
|
|
359
|
+
|
|
360
|
+
**Example:**
|
|
361
|
+
|
|
362
|
+
```tsx
|
|
363
|
+
const schema = [
|
|
364
|
+
{
|
|
365
|
+
name: 'gender',
|
|
366
|
+
label: 'Gender',
|
|
367
|
+
type: 'radio',
|
|
368
|
+
options: [
|
|
369
|
+
{ value: 'm', label: 'Male' },
|
|
370
|
+
{ value: 'f', label: 'Female' },
|
|
371
|
+
],
|
|
372
|
+
},
|
|
373
|
+
];
|
|
374
|
+
<Form schema={schema} form={form} />;
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
#### `UFSwitch`
|
|
380
|
+
|
|
381
|
+
Toggle switch.
|
|
382
|
+
|
|
383
|
+
**Example:**
|
|
384
|
+
|
|
385
|
+
```tsx
|
|
386
|
+
const schema = [
|
|
387
|
+
{ name: 'notifications', label: 'Enable notifications', type: 'switch' },
|
|
388
|
+
];
|
|
389
|
+
<Form schema={schema} form={form} />;
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
#### `UFDatePicker`
|
|
395
|
+
|
|
396
|
+
Date picker field.
|
|
397
|
+
|
|
398
|
+
**Example:**
|
|
399
|
+
|
|
400
|
+
```tsx
|
|
401
|
+
const schema = [
|
|
402
|
+
{ name: 'birthDate', label: 'Birth date', type: 'date-picker' },
|
|
403
|
+
];
|
|
404
|
+
<Form schema={schema} form={form} />;
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
#### `UFTime`
|
|
410
|
+
|
|
411
|
+
Time input (hours/minutes).
|
|
412
|
+
|
|
413
|
+
**Example:**
|
|
414
|
+
|
|
415
|
+
```tsx
|
|
416
|
+
const schema = [
|
|
417
|
+
{ name: 'appointmentTime', label: 'Time', type: 'time' },
|
|
418
|
+
];
|
|
419
|
+
<Form schema={schema} form={form} />;
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
#### `UFCurrency`
|
|
425
|
+
|
|
426
|
+
Numeric/currency input with formatting.
|
|
427
|
+
|
|
428
|
+
**Example:**
|
|
429
|
+
|
|
430
|
+
```tsx
|
|
431
|
+
const schema = [
|
|
432
|
+
{ name: 'price', label: 'Price', type: 'currency', placeholder: '0.00' },
|
|
433
|
+
];
|
|
434
|
+
<Form schema={schema} form={form} />;
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
#### `UFUploader`
|
|
440
|
+
|
|
441
|
+
File upload with optional multiple files and delete handler.
|
|
442
|
+
|
|
443
|
+
**Example:**
|
|
444
|
+
|
|
445
|
+
```tsx
|
|
446
|
+
const schema = [
|
|
447
|
+
{
|
|
448
|
+
name: 'attachments',
|
|
449
|
+
label: 'Attachments',
|
|
450
|
+
type: 'uploader',
|
|
451
|
+
multiple: true,
|
|
452
|
+
onDelete: (index) => removeFile(index),
|
|
453
|
+
},
|
|
454
|
+
];
|
|
455
|
+
<Form schema={schema} form={form} />;
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## 3. Table
|
|
461
|
+
|
|
462
|
+
### `useTable`
|
|
463
|
+
|
|
464
|
+
Hook that builds a **@tanstack/react-table** instance and returns `table`, `pagination`, and optional selection/expand helpers for `CustomTable`.
|
|
465
|
+
|
|
466
|
+
**Parameters (`IUseTableProps`):** `columns`, `data`, `pageSize?`, `multiSelect?`, `onSelectRow?`, `getRowId?`, `renderSubComponent?`, `getRowCanExpand?`, `state?`, and other react-table options.
|
|
467
|
+
|
|
468
|
+
**Returns:** `{ table, pagination, selectedRows, renderSubComponent }`.
|
|
469
|
+
|
|
470
|
+
**Example:**
|
|
471
|
+
|
|
472
|
+
```tsx
|
|
473
|
+
import { useTable, CustomTable } from 'mui-design-system';
|
|
474
|
+
|
|
475
|
+
const columns = [
|
|
476
|
+
{ accessorKey: 'name', header: 'Name' },
|
|
477
|
+
{ accessorKey: 'age', header: 'Age' },
|
|
478
|
+
];
|
|
479
|
+
const data = [
|
|
480
|
+
{ id: '1', name: 'Alice', age: 28 },
|
|
481
|
+
{ id: '2', name: 'Bob', age: 32 },
|
|
482
|
+
];
|
|
483
|
+
|
|
484
|
+
const MyTable = () => {
|
|
485
|
+
const { table, pagination, renderSubComponent } = useTable({
|
|
486
|
+
columns,
|
|
487
|
+
data,
|
|
488
|
+
pageSize: 10,
|
|
489
|
+
});
|
|
490
|
+
return (
|
|
491
|
+
<CustomTable
|
|
492
|
+
table={table}
|
|
493
|
+
pagination={pagination}
|
|
494
|
+
renderSubComponent={renderSubComponent}
|
|
495
|
+
/>
|
|
496
|
+
);
|
|
497
|
+
};
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
### `CustomTable`
|
|
503
|
+
|
|
504
|
+
Table UI with header, body, loading skeleton, pagination, optional row selection (radio/checkbox) and expandable rows.
|
|
505
|
+
|
|
506
|
+
**Props (`ICustomTable`):** `id?`, `table`, `pagination?`, `variant?` (`'zebra' | 'linear'`), `isLoading?`, `wrapperStackProps?`, `footerProps?`, `onClickRow?`, `renderSubComponent?`, `withRadio?`, `withSelect?`, `withIndex?`, `rowStyle?`, `cellsStyle?`, `headerStyle?`, `headerTypoProps?`, `checkboxProps?`, `radioProps?`, `emptyListComponent?`, `rowBorderRadius?`, `borderRadius?`.
|
|
507
|
+
|
|
508
|
+
**Example:**
|
|
509
|
+
|
|
510
|
+
```tsx
|
|
511
|
+
import { useTable, CustomTable } from 'mui-design-system';
|
|
512
|
+
|
|
513
|
+
const columns = [
|
|
514
|
+
{ accessorKey: 'name', header: 'Name' },
|
|
515
|
+
{ accessorKey: 'email', header: 'Email' },
|
|
516
|
+
];
|
|
517
|
+
const data = [
|
|
518
|
+
{ id: '1', name: 'Alice', email: 'alice@example.com' },
|
|
519
|
+
{ id: '2', name: 'Bob', email: 'bob@example.com' },
|
|
520
|
+
];
|
|
521
|
+
|
|
522
|
+
const DataTable = () => {
|
|
523
|
+
const { table, pagination } = useTable({ columns, data, pageSize: 5 });
|
|
524
|
+
return (
|
|
525
|
+
<CustomTable
|
|
526
|
+
id="users-table"
|
|
527
|
+
table={table}
|
|
528
|
+
pagination={pagination}
|
|
529
|
+
variant="zebra"
|
|
530
|
+
emptyListComponent="No users found"
|
|
531
|
+
/>
|
|
532
|
+
);
|
|
533
|
+
};
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
## 4. OTP Input
|
|
539
|
+
|
|
540
|
+
### `OTPInput`
|
|
541
|
+
|
|
542
|
+
Multi-digit OTP input (one box per digit).
|
|
543
|
+
|
|
544
|
+
**Props:** `valueLength`, `value?`, `onChange`, `size?`, `gap?`, `inputStyle?`, `activeInputStyle?`, `onFinish?`, `onBack?`, `containerProp?`, `readonly?`, `disabled?`, `isError?`.
|
|
545
|
+
|
|
546
|
+
**Example:**
|
|
547
|
+
|
|
548
|
+
```tsx
|
|
549
|
+
import { useState } from 'react';
|
|
550
|
+
import { OTPInput } from 'mui-design-system';
|
|
551
|
+
|
|
552
|
+
const VerifyCode = () => {
|
|
553
|
+
const [otp, setOtp] = useState('');
|
|
554
|
+
return (
|
|
555
|
+
<OTPInput
|
|
556
|
+
valueLength={6}
|
|
557
|
+
value={otp}
|
|
558
|
+
onChange={setOtp}
|
|
559
|
+
onFinish={(val) => console.log('OTP completed:', val)}
|
|
560
|
+
gap={2}
|
|
561
|
+
/>
|
|
562
|
+
);
|
|
563
|
+
};
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## 5. Methods
|
|
569
|
+
|
|
570
|
+
### `debounce(func, wait, immediate?)`
|
|
571
|
+
|
|
572
|
+
Debounces a function (e.g. for search input).
|
|
573
|
+
|
|
574
|
+
**Example:**
|
|
575
|
+
|
|
576
|
+
```tsx
|
|
577
|
+
import { debounce } from 'mui-design-system';
|
|
578
|
+
|
|
579
|
+
const handleSearch = debounce((query: string) => {
|
|
580
|
+
fetchSuggestions(query);
|
|
581
|
+
}, 300);
|
|
582
|
+
|
|
583
|
+
// In JSX: <Input onChange={(e) => handleSearch(e.target.value)} />
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
### `result(object, key, defaultValue?)`
|
|
589
|
+
|
|
590
|
+
Reads a value from an object with optional default or lazy default (function).
|
|
591
|
+
|
|
592
|
+
**Example:**
|
|
593
|
+
|
|
594
|
+
```tsx
|
|
595
|
+
import { result } from 'mui-design-system';
|
|
596
|
+
|
|
597
|
+
const userName = result(user, 'name', 'Guest');
|
|
598
|
+
const value = result(config, 'key', () => computeExpensiveDefault());
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
### `deepMerge<T>(...objects)`
|
|
604
|
+
|
|
605
|
+
Deep-merges objects. Arrays and non-object values are overwritten.
|
|
606
|
+
|
|
607
|
+
**Example:**
|
|
608
|
+
|
|
609
|
+
```tsx
|
|
610
|
+
import { deepMerge } from 'mui-design-system';
|
|
611
|
+
|
|
612
|
+
const merged = deepMerge(
|
|
613
|
+
{ a: 1, b: { x: 1 } },
|
|
614
|
+
{ b: { y: 2 }, c: 3 }
|
|
615
|
+
);
|
|
616
|
+
// { a: 1, b: { x: 1, y: 2 }, c: 3 }
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
## 6. Colors
|
|
622
|
+
|
|
623
|
+
Color palettes are available from the colors subpath.
|
|
624
|
+
|
|
625
|
+
**Example:**
|
|
626
|
+
|
|
627
|
+
```tsx
|
|
32
628
|
import { colors } from 'mui-design-system/colors/index';
|
|
629
|
+
|
|
630
|
+
// Each color has keys 50–900
|
|
631
|
+
colors.blue[500]; // "#1e88e5"
|
|
632
|
+
colors.grey[700]; // "#535353"
|
|
633
|
+
|
|
634
|
+
// Available: yellow, blue, green, orange, red, purple, grey
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
**TypeScript types:** `TColors`, `ColorScale` (`"50" | "100" | ... | "900"`), `IColor`.
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
## Export tree (summary)
|
|
642
|
+
|
|
33
643
|
```
|
|
644
|
+
mui-design-system
|
|
645
|
+
├── themeOptions
|
|
646
|
+
├── ReactCacheProvider
|
|
647
|
+
├── NextCacheProvider
|
|
648
|
+
├── Form
|
|
649
|
+
├── FormProvider
|
|
650
|
+
├── UFTextField, UFTextArea, UFSelect, UFMultiSelect, UFAutoComplete
|
|
651
|
+
├── UFCheckbox, UFMultiCheckbox, CheckboxList
|
|
652
|
+
├── UFRadio, UFSwitch
|
|
653
|
+
├── UFDatePicker, UFTime, UFCurrency, UFUploader
|
|
654
|
+
├── CustomTable
|
|
655
|
+
├── useTable
|
|
656
|
+
├── OTPInput
|
|
657
|
+
├── debounce, result, deepMerge
|
|
658
|
+
└── (colors from mui-design-system/colors/index)
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
---
|
|
34
662
|
|
|
35
|
-
##
|
|
663
|
+
## Not exported from main entry
|
|
36
664
|
|
|
37
|
-
-
|
|
38
|
-
- **`mui-design-system/colors/index`:** Color palettes.
|
|
665
|
+
These exist in the library but are not re-exported from the main package. You can add them to `index.ts` if needed:
|
|
39
666
|
|
|
40
|
-
|
|
667
|
+
- **`useEffectOnce`** — Hook that runs an effect once (mount) with cleanup. File: `src/lib/hooks/useEffectOnce.ts`
|
|
668
|
+
- **`useFormContext`** — Access form context (theme, custom inputs) when inside `FormProvider`. File: `src/lib/context/FormContext.tsx`
|
|
669
|
+
|
|
670
|
+
---
|
|
671
|
+
|
|
672
|
+
## Build (for maintainers)
|
|
41
673
|
|
|
42
674
|
From repo root:
|
|
43
675
|
|
|
@@ -51,6 +683,8 @@ Or from this directory (after `npm install` here):
|
|
|
51
683
|
npm run build
|
|
52
684
|
```
|
|
53
685
|
|
|
686
|
+
---
|
|
687
|
+
|
|
54
688
|
## License
|
|
55
689
|
|
|
56
690
|
ISC
|
|
@@ -14,8 +14,8 @@ const UFTextField = ({ form, name, type = 'text', defaultValue, label, rules, re
|
|
|
14
14
|
const textFieldMergedProps = deepMerge(themeProp, itemProps, props);
|
|
15
15
|
const handleKeyDown = (e, onChange) => {
|
|
16
16
|
const value = e?.target?.value;
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const isNumericOnly = type === "number" || type === "tel";
|
|
18
|
+
if (isNumericOnly && !checkIfNumber(value)) {
|
|
19
19
|
e.preventDefault();
|
|
20
20
|
}
|
|
21
21
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mui-design-system",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.34",
|
|
4
4
|
"description": "MUI-based design system with theme, form components, and utilities",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "tsc && node copy-files.js",
|
|
26
26
|
"prepublishOnly": "npm run build",
|
|
27
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
27
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
28
|
+
"publish": "npm publish"
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {
|
|
30
31
|
"react-window": "^1.8.10",
|