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 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
- ## Peer dependencies
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
- ## Usage
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
- // With React
27
- <ReactCacheProvider themeOptions={themeOptions}>
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
- // Colors subpath
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
- ## Exports
663
+ ## Not exported from main entry
36
664
 
37
- - **Main:** Theme providers (`ReactCacheProvider`, `NextCacheProvider`), form components, `themeOptions`, methods, etc.
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
- ## Building (for maintainers)
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
- if (type === "number" &&
18
- !checkIfNumber(value)) {
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.32",
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",