form-input-fields 1.0.16 → 1.0.18
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 +591 -284
- package/dist/controls/FormCheckboxField/FormCheckboxField.d.ts +4 -1
- package/dist/controls/FormCheckboxField/FormCheckboxField.d.ts.map +1 -1
- package/dist/controls/FormDateField/FormDateField.d.ts +3 -1
- package/dist/controls/FormDateField/FormDateField.d.ts.map +1 -1
- package/dist/controls/FormDateTextField/FormDateTextField.d.ts +4 -2
- package/dist/controls/FormDateTextField/FormDateTextField.d.ts.map +1 -1
- package/dist/controls/FormDropDownField/FormDropDownField.d.ts +4 -2
- package/dist/controls/FormDropDownField/FormDropDownField.d.ts.map +1 -1
- package/dist/controls/FormMaskField/FormMaskField.d.ts +3 -0
- package/dist/controls/FormMaskField/FormMaskField.d.ts.map +1 -1
- package/dist/controls/FormSwitch/FormSwitch.d.ts +3 -0
- package/dist/controls/FormSwitch/FormSwitch.d.ts.map +1 -1
- package/dist/controls/FormTextField/FormTextField.d.ts +3 -1
- package/dist/controls/FormTextField/FormTextField.d.ts.map +1 -1
- package/dist/index.es.js +2093 -2080
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +50 -50
- package/dist/index.js.map +1 -1
- package/dist/stories/FormCheckboxField.stories.d.ts +22 -0
- package/dist/stories/FormCheckboxField.stories.d.ts.map +1 -0
- package/dist/stories/FormDateField.stories.d.ts +10 -0
- package/dist/stories/FormDateField.stories.d.ts.map +1 -0
- package/dist/stories/FormDateTextField.stories.d.ts +8 -0
- package/dist/stories/FormDateTextField.stories.d.ts.map +1 -0
- package/dist/stories/FormDropDownField.stories.d.ts +8 -0
- package/dist/stories/FormDropDownField.stories.d.ts.map +1 -0
- package/dist/stories/FormMaskField.stories.d.ts +11 -0
- package/dist/stories/FormMaskField.stories.d.ts.map +1 -0
- package/dist/stories/FormSwitch.stories.d.ts +7 -0
- package/dist/stories/FormSwitch.stories.d.ts.map +1 -0
- package/dist/stories/FormTextField.stories.d.ts +8 -0
- package/dist/stories/FormTextField.stories.d.ts.map +1 -0
- package/package.json +14 -7
package/README.md
CHANGED
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
A collection of Material-UI form field components with Formik integration.
|
|
4
4
|
|
|
5
|
+
**Version 1.0.18**
|
|
6
|
+
|
|
5
7
|
More control in the progress of development.
|
|
6
8
|
|
|
9
|
+
## Storybook
|
|
10
|
+
|
|
11
|
+
View interactive examples and documentation at: [https://formik-input-fields.netlify.app/](https://formik-input-fields.netlify.app/)
|
|
12
|
+
|
|
7
13
|
## Installation
|
|
8
14
|
|
|
9
15
|
### Prerequisites
|
|
10
16
|
|
|
11
|
-
Before installing the form-fields package, make sure you have the following peer dependencies installed in your project:
|
|
17
|
+
Before installing the form-input-fields package, make sure you have the following peer dependencies installed in your project:
|
|
12
18
|
|
|
13
19
|
- React 16.8.0 or later
|
|
14
20
|
- React DOM 16.8.0 or later
|
|
@@ -20,13 +26,13 @@ Before installing the form-fields package, make sure you have the following peer
|
|
|
20
26
|
### Using npm
|
|
21
27
|
|
|
22
28
|
```bash
|
|
23
|
-
npm install form-fields @mui/material @emotion/react @emotion/styled formik @mui/x-date-pickers dayjs
|
|
29
|
+
npm install form-input-fields @mui/material @emotion/react @emotion/styled formik @mui/x-date-pickers dayjs
|
|
24
30
|
```
|
|
25
31
|
|
|
26
32
|
### Using yarn
|
|
27
33
|
|
|
28
34
|
```bash
|
|
29
|
-
yarn add
|
|
35
|
+
yarn add form-input-fields @mui/material @emotion/react @emotion/styled formik @mui/x-date-pickers dayjs
|
|
30
36
|
```
|
|
31
37
|
|
|
32
38
|
### Using pnpm
|
|
@@ -61,6 +67,7 @@ This package includes TypeScript type definitions. No additional type packages a
|
|
|
61
67
|
### Browser Support
|
|
62
68
|
|
|
63
69
|
The form fields support all modern browsers including:
|
|
70
|
+
|
|
64
71
|
- Chrome (latest 2 versions)
|
|
65
72
|
- Firefox (latest 2 versions)
|
|
66
73
|
- Safari (latest 2 versions)
|
|
@@ -81,6 +88,7 @@ import { FormTextField, FormDateField, FormMaskField, FormSwitch } from 'form-in
|
|
|
81
88
|
If you encounter any issues during installation, try the following:
|
|
82
89
|
|
|
83
90
|
1. Clear your package manager's cache:
|
|
91
|
+
|
|
84
92
|
```bash
|
|
85
93
|
npm cache clean --force
|
|
86
94
|
# or
|
|
@@ -102,7 +110,6 @@ If you encounter any issues during installation, try the following:
|
|
|
102
110
|
|
|
103
111
|
If you're still experiencing issues, please reach me at vladimir.vorobiev@gmail.com with details about your environment and the error message you're seeing.
|
|
104
112
|
|
|
105
|
-
|
|
106
113
|
## Table of Contents
|
|
107
114
|
|
|
108
115
|
- [FormTextField](#formtextfield)
|
|
@@ -173,6 +180,19 @@ If you're still experiencing issues, please reach me at vladimir.vorobiev@gmail.
|
|
|
173
180
|
- [Basic Date Text Input](#basic-date-text-input)
|
|
174
181
|
- [Date Text Field with Formik](#date-text-field-with-formik)
|
|
175
182
|
- [Custom Date Format](#custom-date-format)
|
|
183
|
+
- [Styling Form Controls](#styling-form-controls)
|
|
184
|
+
- [sx Prop Support](#sx-prop-support)
|
|
185
|
+
- [Benefits of the sx Prop](#benefits-of-the-sx-prop)
|
|
186
|
+
- [Using the sx Prop with Form Controls](#using-the-sx-prop-with-form-controls)
|
|
187
|
+
- [FormControl Wrapper Pattern](#formcontrol-wrapper-pattern)
|
|
188
|
+
- [FormControl Wrapper Benefits](#formcontrol-wrapper-benefits)
|
|
189
|
+
- [Example: FormControl Wrapper in Action](#example-formcontrol-wrapper-in-action)
|
|
190
|
+
- [Advanced Styling Examples](#advanced-styling-examples)
|
|
191
|
+
- [Custom Theme Integration](#custom-theme-integration)
|
|
192
|
+
- [Responsive Form Layout](#responsive-form-layout)
|
|
193
|
+
- [Conditional Styling Based on State](#conditional-styling-based-on-state)
|
|
194
|
+
- [Best Practices for Styling Form Controls](#best-practices-for-styling-form-controls)
|
|
195
|
+
- [Migration Guide](#migration-guide)
|
|
176
196
|
- [History](#history)
|
|
177
197
|
|
|
178
198
|
---
|
|
@@ -194,19 +214,16 @@ A versatile text input field component that integrates Material-UI's TextField w
|
|
|
194
214
|
|
|
195
215
|
```tsx
|
|
196
216
|
import { Formik, Field } from 'formik';
|
|
197
|
-
import { FormTextField } from 'form-fields';
|
|
217
|
+
import { FormTextField } from 'form-input-fields';
|
|
198
218
|
|
|
199
|
-
<Formik
|
|
200
|
-
initialValues={{ username: '' }}
|
|
201
|
-
onSubmit={(values) => console.log(values)}
|
|
202
|
-
>
|
|
219
|
+
<Formik initialValues={{ username: '' }} onSubmit={values => console.log(values)}>
|
|
203
220
|
<Field
|
|
204
221
|
component={FormTextField}
|
|
205
222
|
name="username"
|
|
206
223
|
label="Username"
|
|
207
224
|
placeholder="Enter your username"
|
|
208
225
|
/>
|
|
209
|
-
</Formik
|
|
226
|
+
</Formik>;
|
|
210
227
|
```
|
|
211
228
|
|
|
212
229
|
### Props
|
|
@@ -215,16 +232,17 @@ The FormTextField component accepts all props from `FormTextFieldProps`, `FieldP
|
|
|
215
232
|
|
|
216
233
|
#### FormTextFieldProps Interface
|
|
217
234
|
|
|
218
|
-
| Prop | Type
|
|
219
|
-
|
|
220
|
-
| `onChange` | `function`
|
|
221
|
-
| `onBlur` | `function`
|
|
222
|
-
| `variant` | `'standard'
|
|
235
|
+
| Prop | Type | Default | Description |
|
|
236
|
+
| ---------- | ---------------- | ---------- | -------------------------------------------------------------------------------------- | ---------- | --------------------------------- |
|
|
237
|
+
| `onChange` | `function` | - | Custom change handler that overrides Formik's |
|
|
238
|
+
| `onBlur` | `function` | - | Custom blur handler that overrides Formik's |
|
|
239
|
+
| `variant` | `'standard' | 'outlined' | 'filled'` | 'standard' | The variant of the MUI TextField. |
|
|
240
|
+
| `sx` | `SxProps<Theme>` | - | The system prop that allows defining system overrides as well as additional CSS styles |
|
|
223
241
|
|
|
224
242
|
#### Common Props (from FieldProps & TextFieldProps)
|
|
225
243
|
|
|
226
244
|
| Prop | Type | Required | Description |
|
|
227
|
-
|
|
245
|
+
| ------------ | ---------------- | -------- | --------------------------------------------- |
|
|
228
246
|
| `name` | `string` | Yes | Field name in Formik values |
|
|
229
247
|
| `label` | `string` | No | Field label |
|
|
230
248
|
| `helperText` | `string` | No | Custom helper text |
|
|
@@ -264,7 +282,7 @@ The FormTextField component accepts all props from `FormTextFieldProps`, `FieldP
|
|
|
264
282
|
}
|
|
265
283
|
return errors;
|
|
266
284
|
}}
|
|
267
|
-
onSubmit={
|
|
285
|
+
onSubmit={values => console.log(values)}
|
|
268
286
|
>
|
|
269
287
|
{({ errors, touched }) => (
|
|
270
288
|
<Field
|
|
@@ -290,7 +308,7 @@ The FormTextField component accepts all props from `FormTextFieldProps`, `FieldP
|
|
|
290
308
|
type="password"
|
|
291
309
|
inputProps={{
|
|
292
310
|
minLength: 8,
|
|
293
|
-
pattern:
|
|
311
|
+
pattern: '(?=.*d)(?=.*[a-z])(?=.*[A-Z]).{8,}',
|
|
294
312
|
}}
|
|
295
313
|
helperText="Must contain at least 8 characters, including uppercase, lowercase, and numbers"
|
|
296
314
|
required
|
|
@@ -325,10 +343,7 @@ const items = [
|
|
|
325
343
|
{ id: '3', description: 'Option 3' },
|
|
326
344
|
];
|
|
327
345
|
|
|
328
|
-
<Formik
|
|
329
|
-
initialValues={{ category: '' }}
|
|
330
|
-
onSubmit={(values) => console.log(values)}
|
|
331
|
-
>
|
|
346
|
+
<Formik initialValues={{ category: '' }} onSubmit={values => console.log(values)}>
|
|
332
347
|
<Field
|
|
333
348
|
component={FormDropDownField}
|
|
334
349
|
name="category"
|
|
@@ -336,7 +351,7 @@ const items = [
|
|
|
336
351
|
items={items}
|
|
337
352
|
addInputSelect={true}
|
|
338
353
|
/>
|
|
339
|
-
</Formik
|
|
354
|
+
</Formik>;
|
|
340
355
|
```
|
|
341
356
|
|
|
342
357
|
### Props
|
|
@@ -345,19 +360,20 @@ The FormDropDownField component accepts all props from `FormDropDownFieldProps`,
|
|
|
345
360
|
|
|
346
361
|
#### FormDropDownFieldProps Interface
|
|
347
362
|
|
|
348
|
-
| Prop
|
|
349
|
-
|
|
350
|
-
| `items`
|
|
351
|
-
| `addInputSelect` | `boolean`
|
|
352
|
-
| `selectText`
|
|
353
|
-
| `required`
|
|
354
|
-
| `disabled`
|
|
355
|
-
| `className`
|
|
356
|
-
| `helperText`
|
|
357
|
-
| `error`
|
|
358
|
-
| `onChange`
|
|
359
|
-
| `onBlur`
|
|
360
|
-
| `variant`
|
|
363
|
+
| Prop | Type | Default | Description |
|
|
364
|
+
| ---------------- | ----------------------------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------- | --------------------------------- |
|
|
365
|
+
| `items` | `Array<{ id: string | number; description: string }>` | `[]` | Array of items to display in the dropdown |
|
|
366
|
+
| `addInputSelect` | `boolean` | `false` | Whether to show a default "Select" option as the first item |
|
|
367
|
+
| `selectText` | `string` | `'Select'` | Text to display for the default "Select" option |
|
|
368
|
+
| `required` | `boolean` | `false` | Whether the field is required |
|
|
369
|
+
| `disabled` | `boolean` | `false` | Whether the field is disabled |
|
|
370
|
+
| `className` | `string` | - | Custom class name for the root element |
|
|
371
|
+
| `helperText` | `string` | - | Helper text to display below the field |
|
|
372
|
+
| `error` | `boolean` | - | Error state of the field (overrides Formik error state) |
|
|
373
|
+
| `onChange` | `(value: any) => void` | - | Custom change handler |
|
|
374
|
+
| `onBlur` | `(event: React.FocusEvent<HTMLInputElement>) => void` | - | Custom blur handler |
|
|
375
|
+
| `variant` | `'standard' | 'outlined' | 'filled'` | 'standard' | The variant of the MUI TextField. |
|
|
376
|
+
| `sx` | `SxProps<Theme>` | - | The system prop that allows defining system overrides as well as additional CSS styles |
|
|
361
377
|
|
|
362
378
|
### Examples
|
|
363
379
|
|
|
@@ -377,7 +393,7 @@ const items = [
|
|
|
377
393
|
items={items}
|
|
378
394
|
fullWidth
|
|
379
395
|
variant="outlined" // <-- Example with outlined variant
|
|
380
|
-
|
|
396
|
+
/>;
|
|
381
397
|
```
|
|
382
398
|
|
|
383
399
|
#### Dropdown with Default Selection
|
|
@@ -402,7 +418,7 @@ const items = [
|
|
|
402
418
|
validationSchema={Yup.object({
|
|
403
419
|
department: Yup.string().required('Department is required'),
|
|
404
420
|
})}
|
|
405
|
-
onSubmit={
|
|
421
|
+
onSubmit={values => console.log(values)}
|
|
406
422
|
>
|
|
407
423
|
{({ errors, touched }) => (
|
|
408
424
|
<Form>
|
|
@@ -450,9 +466,9 @@ The component uses predefined date format constants from `date.ts`:
|
|
|
450
466
|
|
|
451
467
|
```typescript
|
|
452
468
|
export const FORM_DATE_FORMAT = {
|
|
453
|
-
short:
|
|
454
|
-
long:
|
|
455
|
-
custom:
|
|
469
|
+
short: 'YYYY-MM-DD',
|
|
470
|
+
long: 'MM/DD/YYYY hh:mm A',
|
|
471
|
+
custom: 'DD MMMM YYYY hh:mm A',
|
|
456
472
|
};
|
|
457
473
|
```
|
|
458
474
|
|
|
@@ -460,7 +476,7 @@ export const FORM_DATE_FORMAT = {
|
|
|
460
476
|
|
|
461
477
|
```typescript
|
|
462
478
|
export const DATE_PICKER_DATE_FORMAT = {
|
|
463
|
-
short:
|
|
479
|
+
short: 'DD/MM/YYYY',
|
|
464
480
|
};
|
|
465
481
|
```
|
|
466
482
|
|
|
@@ -468,8 +484,8 @@ export const DATE_PICKER_DATE_FORMAT = {
|
|
|
468
484
|
|
|
469
485
|
```typescript
|
|
470
486
|
export const DATE_PICKER_MONTH_YEAR_FORMAT = {
|
|
471
|
-
short:
|
|
472
|
-
long:
|
|
487
|
+
short: 'MM/YYYY',
|
|
488
|
+
long: 'MMMM YYYY',
|
|
473
489
|
};
|
|
474
490
|
```
|
|
475
491
|
|
|
@@ -480,7 +496,7 @@ import {
|
|
|
480
496
|
FORM_DATE_FORMAT,
|
|
481
497
|
DATE_PICKER_DATE_FORMAT,
|
|
482
498
|
DATE_PICKER_MONTH_YEAR_FORMAT
|
|
483
|
-
} from "form-input-
|
|
499
|
+
} from "form-input-fields/date";
|
|
484
500
|
|
|
485
501
|
// Use predefined formats
|
|
486
502
|
<Field
|
|
@@ -500,14 +516,14 @@ import {
|
|
|
500
516
|
### Usage with Formik
|
|
501
517
|
|
|
502
518
|
```tsx
|
|
503
|
-
import { Formik, Field } from
|
|
504
|
-
import { FormDateField, FormDateFieldProps } from
|
|
505
|
-
import { FORM_DATE_FORMAT } from
|
|
506
|
-
import dayjs from
|
|
519
|
+
import { Formik, Field } from 'formik';
|
|
520
|
+
import { FormDateField, FormDateFieldProps } from 'form-input-fields';
|
|
521
|
+
import { FORM_DATE_FORMAT } from 'form-input-fields/date';
|
|
522
|
+
import dayjs from 'dayjs';
|
|
507
523
|
|
|
508
524
|
<Formik
|
|
509
525
|
initialValues={{ birthDate: null, appointmentDate: null }}
|
|
510
|
-
onSubmit={
|
|
526
|
+
onSubmit={values => console.log(values)}
|
|
511
527
|
>
|
|
512
528
|
{/* Basic usage */}
|
|
513
529
|
<Field
|
|
@@ -528,8 +544,8 @@ import dayjs from "dayjs";
|
|
|
528
544
|
showTodayButton={true}
|
|
529
545
|
showDateFormat={true}
|
|
530
546
|
onChange={(value, context) => {
|
|
531
|
-
console.log(
|
|
532
|
-
console.log(
|
|
547
|
+
console.log('Selected date:', value);
|
|
548
|
+
console.log('Formatted value:', context.formattedValue);
|
|
533
549
|
}}
|
|
534
550
|
/>
|
|
535
551
|
</Formik>;
|
|
@@ -541,17 +557,18 @@ The FormDateField component accepts all props from `FormDateFieldProps`, `FieldP
|
|
|
541
557
|
|
|
542
558
|
#### FormDateFieldProps Interface
|
|
543
559
|
|
|
544
|
-
| Prop | Type
|
|
545
|
-
| ----------------- |
|
|
546
|
-
| `format` | `string`
|
|
547
|
-
| `minDate` | `Dayjs`
|
|
548
|
-
| `maxDate` | `Dayjs`
|
|
549
|
-
| `disablePast` | `boolean`
|
|
550
|
-
| `disableFuture` | `boolean`
|
|
551
|
-
| `showTodayButton` | `boolean`
|
|
552
|
-
| `readOnly` | `boolean`
|
|
553
|
-
| `showDateFormat` | `boolean`
|
|
554
|
-
| `onChange` | `function`
|
|
560
|
+
| Prop | Type | Default | Description |
|
|
561
|
+
| ----------------- | ---------------- | ------------------------ | -------------------------------------------------------------------------------------- |
|
|
562
|
+
| `format` | `string` | `FORM_DATE_FORMAT.short` | Date format string using dayjs format tokens |
|
|
563
|
+
| `minDate` | `Dayjs` | - | Minimum selectable date |
|
|
564
|
+
| `maxDate` | `Dayjs` | - | Maximum selectable date |
|
|
565
|
+
| `disablePast` | `boolean` | `false` | Disable past dates |
|
|
566
|
+
| `disableFuture` | `boolean` | `false` | Disable future dates |
|
|
567
|
+
| `showTodayButton` | `boolean` | `false` | Show today button in the picker |
|
|
568
|
+
| `readOnly` | `boolean` | `false` | Make the field read-only |
|
|
569
|
+
| `showDateFormat` | `boolean` | `false` | Show the date format as helper text |
|
|
570
|
+
| `onChange` | `function` | - | Custom change handler with additional context |
|
|
571
|
+
| `sx` | `SxProps<Theme>` | - | The system prop that allows defining system overrides as well as additional CSS styles |
|
|
555
572
|
|
|
556
573
|
#### Common Props (from FieldProps & TextFieldProps)
|
|
557
574
|
|
|
@@ -569,12 +586,7 @@ The FormDateField component accepts all props from `FormDateFieldProps`, `FieldP
|
|
|
569
586
|
#### Basic Date Input
|
|
570
587
|
|
|
571
588
|
```tsx
|
|
572
|
-
<Field
|
|
573
|
-
component={FormDateField}
|
|
574
|
-
name="birthDate"
|
|
575
|
-
label="Birth Date"
|
|
576
|
-
format="DD/MM/YYYY"
|
|
577
|
-
/>
|
|
589
|
+
<Field component={FormDateField} name="birthDate" label="Birth Date" format="DD/MM/YYYY" />
|
|
578
590
|
```
|
|
579
591
|
|
|
580
592
|
#### Date with Validation
|
|
@@ -599,8 +611,8 @@ The FormDateField component accepts all props from `FormDateFieldProps`, `FieldP
|
|
|
599
611
|
name="appointmentDate"
|
|
600
612
|
label="Appointment Date"
|
|
601
613
|
format="DD MMMM YYYY"
|
|
602
|
-
minDate={dayjs().add(1,
|
|
603
|
-
maxDate={dayjs().add(3,
|
|
614
|
+
minDate={dayjs().add(1, 'day')}
|
|
615
|
+
maxDate={dayjs().add(3, 'month')}
|
|
604
616
|
showTodayButton={true}
|
|
605
617
|
showDateFormat={true}
|
|
606
618
|
/>
|
|
@@ -627,13 +639,13 @@ The FormDateField component accepts all props from `FormDateFieldProps`, `FieldP
|
|
|
627
639
|
label="Event Date"
|
|
628
640
|
format="YYYY-MM-DD"
|
|
629
641
|
onChange={(value, context) => {
|
|
630
|
-
console.log(
|
|
631
|
-
console.log(
|
|
632
|
-
console.log(
|
|
642
|
+
console.log('Selected date:', value);
|
|
643
|
+
console.log('Formatted value:', context.formattedValue);
|
|
644
|
+
console.log('Validation error:', context.validationError);
|
|
633
645
|
|
|
634
646
|
// Custom logic here
|
|
635
647
|
if (value && value.day() === 0) {
|
|
636
|
-
alert(
|
|
648
|
+
alert('Events cannot be scheduled on Sundays');
|
|
637
649
|
}
|
|
638
650
|
}}
|
|
639
651
|
/>
|
|
@@ -676,7 +688,7 @@ A customizable checkbox component with Material-UI and Formik integration, provi
|
|
|
676
688
|
|
|
677
689
|
```tsx
|
|
678
690
|
import { Formik, Field } from 'formik';
|
|
679
|
-
import { FormCheckboxField } from 'form-input-
|
|
691
|
+
import { FormCheckboxField } from 'form-input-fields';
|
|
680
692
|
|
|
681
693
|
// Basic usage
|
|
682
694
|
<FormCheckboxField
|
|
@@ -715,17 +727,17 @@ The FormCheckboxField component accepts all props from `FormCheckboxFieldProps`
|
|
|
715
727
|
|
|
716
728
|
#### FormCheckboxFieldProps Interface
|
|
717
729
|
|
|
718
|
-
| Prop
|
|
719
|
-
|
|
|
720
|
-
| `id`
|
|
721
|
-
| `label`
|
|
722
|
-
| `checked`
|
|
723
|
-
| `onChange`
|
|
724
|
-
| `disabled`
|
|
725
|
-
| `required`
|
|
726
|
-
| `color`
|
|
727
|
-
| `size`
|
|
728
|
-
| `labelPlacement
|
|
730
|
+
| Prop | Type | Default | Description |
|
|
731
|
+
| ---------------- | ---------- | --------- | ------------------------------------------------------- |
|
|
732
|
+
| `id` | `string` | - | Unique identifier for the checkbox |
|
|
733
|
+
| `label` | `string` | - | Label text displayed next to the checkbox |
|
|
734
|
+
| `checked` | `boolean` | `false` | Whether the checkbox is checked |
|
|
735
|
+
| `onChange` | `function` | - | Callback when checkbox state changes |
|
|
736
|
+
| `disabled` | `boolean` | `false` | Disable the checkbox |
|
|
737
|
+
| `required` | `boolean` | `false` | Mark the field as required |
|
|
738
|
+
| `color` | `string` | 'primary' | Color of the checkbox when checked |
|
|
739
|
+
| `size` | `string` | 'medium' | Size of the checkbox ('small' or 'medium') |
|
|
740
|
+
| `labelPlacement` | `string` | 'end' | Position of the label ('end', 'start', 'top', 'bottom') |
|
|
729
741
|
|
|
730
742
|
### Examples
|
|
731
743
|
|
|
@@ -736,7 +748,7 @@ The FormCheckboxField component accepts all props from `FormCheckboxFieldProps`
|
|
|
736
748
|
id="notifications"
|
|
737
749
|
label="Enable email notifications"
|
|
738
750
|
checked={notificationsEnabled}
|
|
739
|
-
onChange={
|
|
751
|
+
onChange={e => setNotificationsEnabled(e.target.checked)}
|
|
740
752
|
color="secondary"
|
|
741
753
|
/>
|
|
742
754
|
```
|
|
@@ -748,9 +760,9 @@ The FormCheckboxField component accepts all props from `FormCheckboxFieldProps`
|
|
|
748
760
|
initialValues={{
|
|
749
761
|
termsAccepted: false,
|
|
750
762
|
newsletter: true,
|
|
751
|
-
notifications: false
|
|
763
|
+
notifications: false,
|
|
752
764
|
}}
|
|
753
|
-
onSubmit={
|
|
765
|
+
onSubmit={values => console.log('Form values:', values)}
|
|
754
766
|
>
|
|
755
767
|
{({ values }) => (
|
|
756
768
|
<Form>
|
|
@@ -761,12 +773,12 @@ The FormCheckboxField component accepts all props from `FormCheckboxFieldProps`
|
|
|
761
773
|
{...field}
|
|
762
774
|
label="I agree to the terms and conditions"
|
|
763
775
|
checked={field.value}
|
|
764
|
-
onChange={
|
|
776
|
+
onChange={e => form.setFieldValue(field.name, e.target.checked)}
|
|
765
777
|
required
|
|
766
778
|
/>
|
|
767
779
|
)}
|
|
768
780
|
/>
|
|
769
|
-
|
|
781
|
+
|
|
770
782
|
<Field
|
|
771
783
|
name="newsletter"
|
|
772
784
|
component={({ field, form }) => (
|
|
@@ -774,12 +786,12 @@ The FormCheckboxField component accepts all props from `FormCheckboxFieldProps`
|
|
|
774
786
|
{...field}
|
|
775
787
|
label="Subscribe to newsletter"
|
|
776
788
|
checked={field.value}
|
|
777
|
-
onChange={
|
|
789
|
+
onChange={e => form.setFieldValue(field.name, e.target.checked)}
|
|
778
790
|
color="secondary"
|
|
779
791
|
/>
|
|
780
792
|
)}
|
|
781
793
|
/>
|
|
782
|
-
|
|
794
|
+
|
|
783
795
|
<Button type="submit" variant="contained" color="primary">
|
|
784
796
|
Submit
|
|
785
797
|
</Button>
|
|
@@ -793,7 +805,7 @@ The FormCheckboxField component accepts all props from `FormCheckboxFieldProps`
|
|
|
793
805
|
```tsx
|
|
794
806
|
import { makeStyles } from '@mui/styles';
|
|
795
807
|
|
|
796
|
-
const useStyles = makeStyles(
|
|
808
|
+
const useStyles = makeStyles(theme => ({
|
|
797
809
|
root: {
|
|
798
810
|
margin: theme.spacing(1),
|
|
799
811
|
},
|
|
@@ -805,7 +817,7 @@ const useStyles = makeStyles((theme) => ({
|
|
|
805
817
|
|
|
806
818
|
function CustomCheckbox() {
|
|
807
819
|
const classes = useStyles();
|
|
808
|
-
|
|
820
|
+
|
|
809
821
|
return (
|
|
810
822
|
<FormCheckboxField
|
|
811
823
|
id="custom-checkbox"
|
|
@@ -869,31 +881,32 @@ The FormSwitch component accepts all props from `FormSwitchProps`, `FieldProps`
|
|
|
869
881
|
|
|
870
882
|
#### FormSwitchProps Interface
|
|
871
883
|
|
|
872
|
-
| Prop | Type
|
|
873
|
-
| ---------------- |
|
|
874
|
-
| `label` | `string`
|
|
875
|
-
| `labelPlacement` | `string`
|
|
876
|
-
| `color` | `string`
|
|
877
|
-
| `size` | `string`
|
|
878
|
-
| `disabled` | `boolean`
|
|
879
|
-
| `required` | `boolean`
|
|
880
|
-
| `onChange` | `function`
|
|
881
|
-
| `onBlur` | `function`
|
|
882
|
-
| `helperText` | `string`
|
|
883
|
-
| `error` | `boolean`
|
|
884
|
-
| `className` | `string`
|
|
884
|
+
| Prop | Type | Default | Description |
|
|
885
|
+
| ---------------- | ---------------- | --------- | --------------------------------------------------------------------------------------- |
|
|
886
|
+
| `label` | `string` | - | Label text displayed next to the switch |
|
|
887
|
+
| `labelPlacement` | `string` | 'end' | Position of label ('top', 'start', 'bottom', 'end') |
|
|
888
|
+
| `color` | `string` | 'primary' | Switch color ('primary', 'secondary', 'error', 'info', 'success', 'warning', 'default') |
|
|
889
|
+
| `size` | `string` | 'medium' | Switch size ('small' or 'medium') |
|
|
890
|
+
| `disabled` | `boolean` | `false` | Disable the switch |
|
|
891
|
+
| `required` | `boolean` | `false` | Mark the field as required |
|
|
892
|
+
| `onChange` | `function` | - | Custom change handler with context data |
|
|
893
|
+
| `onBlur` | `function` | - | Custom blur handler |
|
|
894
|
+
| `helperText` | `string` | - | Helper text to display below the switch |
|
|
895
|
+
| `error` | `boolean` | `false` | Error state of the switch |
|
|
896
|
+
| `className` | `string` | - | Custom class name for the root element |
|
|
897
|
+
| `sx` | `SxProps<Theme>` | - | The system prop that allows defining system overrides as well as additional CSS styles |
|
|
885
898
|
|
|
886
899
|
#### Common Props (from FieldProps & SwitchProps)
|
|
887
900
|
|
|
888
|
-
| Prop | Type
|
|
889
|
-
|
|
890
|
-
| `name` | `string`
|
|
891
|
-
| `label` | `string`
|
|
892
|
-
| `helperText` | `string`
|
|
893
|
-
| `error` | `boolean`
|
|
894
|
-
| `disabled` | `boolean`
|
|
895
|
-
| `required` | `boolean`
|
|
896
|
-
| Other | `SwitchProps`
|
|
901
|
+
| Prop | Type | Required | Description |
|
|
902
|
+
| ------------ | ------------- | -------- | ------------------------------------------ |
|
|
903
|
+
| `name` | `string` | Yes | Field name in Formik values |
|
|
904
|
+
| `label` | `string` | No | Field label |
|
|
905
|
+
| `helperText` | `string` | No | Custom helper text |
|
|
906
|
+
| `error` | `boolean` | No | Error state (auto-managed by Formik) |
|
|
907
|
+
| `disabled` | `boolean` | No | Disabled state |
|
|
908
|
+
| `required` | `boolean` | No | Required field indicator |
|
|
909
|
+
| Other | `SwitchProps` | No | All Material-UI Switch props are supported |
|
|
897
910
|
|
|
898
911
|
### Examples
|
|
899
912
|
|
|
@@ -916,9 +929,9 @@ The FormSwitch component accepts all props from `FormSwitchProps`, `FieldProps`
|
|
|
916
929
|
initialValues={{
|
|
917
930
|
notifications: false,
|
|
918
931
|
darkMode: true,
|
|
919
|
-
autoSave: false
|
|
932
|
+
autoSave: false,
|
|
920
933
|
}}
|
|
921
|
-
onSubmit={
|
|
934
|
+
onSubmit={values => console.log('Form values:', values)}
|
|
922
935
|
>
|
|
923
936
|
<Form>
|
|
924
937
|
<Field
|
|
@@ -928,7 +941,7 @@ The FormSwitch component accepts all props from `FormSwitchProps`, `FieldProps`
|
|
|
928
941
|
helperText="Receive email notifications"
|
|
929
942
|
color="primary"
|
|
930
943
|
/>
|
|
931
|
-
|
|
944
|
+
|
|
932
945
|
<Field
|
|
933
946
|
component={FormSwitch}
|
|
934
947
|
name="darkMode"
|
|
@@ -937,7 +950,7 @@ The FormSwitch component accepts all props from `FormSwitchProps`, `FieldProps`
|
|
|
937
950
|
color="secondary"
|
|
938
951
|
labelPlacement="start"
|
|
939
952
|
/>
|
|
940
|
-
|
|
953
|
+
|
|
941
954
|
<Field
|
|
942
955
|
component={FormSwitch}
|
|
943
956
|
name="autoSave"
|
|
@@ -946,7 +959,7 @@ The FormSwitch component accepts all props from `FormSwitchProps`, `FieldProps`
|
|
|
946
959
|
color="success"
|
|
947
960
|
size="small"
|
|
948
961
|
/>
|
|
949
|
-
|
|
962
|
+
|
|
950
963
|
<Button type="submit" variant="contained" color="primary">
|
|
951
964
|
Save Settings
|
|
952
965
|
</Button>
|
|
@@ -989,14 +1002,14 @@ The FormSwitch component accepts all props from `FormSwitchProps`, `FieldProps`
|
|
|
989
1002
|
```tsx
|
|
990
1003
|
<Formik
|
|
991
1004
|
initialValues={{ termsAccepted: false }}
|
|
992
|
-
validate={
|
|
1005
|
+
validate={values => {
|
|
993
1006
|
const errors = {};
|
|
994
1007
|
if (!values.termsAccepted) {
|
|
995
1008
|
errors.termsAccepted = 'You must accept the terms to continue';
|
|
996
1009
|
}
|
|
997
1010
|
return errors;
|
|
998
1011
|
}}
|
|
999
|
-
onSubmit={
|
|
1012
|
+
onSubmit={values => console.log(values)}
|
|
1000
1013
|
>
|
|
1001
1014
|
<Form>
|
|
1002
1015
|
<Field
|
|
@@ -1006,7 +1019,7 @@ The FormSwitch component accepts all props from `FormSwitchProps`, `FieldProps`
|
|
|
1006
1019
|
helperText="Please read and accept the terms"
|
|
1007
1020
|
required
|
|
1008
1021
|
/>
|
|
1009
|
-
|
|
1022
|
+
|
|
1010
1023
|
<Button type="submit" variant="contained" color="primary">
|
|
1011
1024
|
Continue
|
|
1012
1025
|
</Button>
|
|
@@ -1035,9 +1048,9 @@ The component uses predefined date format constants from `date.ts`:
|
|
|
1035
1048
|
|
|
1036
1049
|
```typescript
|
|
1037
1050
|
export const FORM_DATE_FORMAT = {
|
|
1038
|
-
short:
|
|
1039
|
-
long:
|
|
1040
|
-
custom:
|
|
1051
|
+
short: 'YYYY-MM-DD',
|
|
1052
|
+
long: 'MM/DD/YYYY hh:mm A',
|
|
1053
|
+
custom: 'DD MMMM YYYY hh:mm A',
|
|
1041
1054
|
};
|
|
1042
1055
|
```
|
|
1043
1056
|
|
|
@@ -1045,7 +1058,7 @@ export const FORM_DATE_FORMAT = {
|
|
|
1045
1058
|
|
|
1046
1059
|
```typescript
|
|
1047
1060
|
export const DATE_PICKER_DATE_FORMAT = {
|
|
1048
|
-
short:
|
|
1061
|
+
short: 'DD/MM/YYYY',
|
|
1049
1062
|
};
|
|
1050
1063
|
```
|
|
1051
1064
|
|
|
@@ -1053,8 +1066,8 @@ export const DATE_PICKER_DATE_FORMAT = {
|
|
|
1053
1066
|
|
|
1054
1067
|
```typescript
|
|
1055
1068
|
export const DATE_PICKER_MONTH_YEAR_FORMAT = {
|
|
1056
|
-
short:
|
|
1057
|
-
long:
|
|
1069
|
+
short: 'MM/YYYY',
|
|
1070
|
+
long: 'MMMM YYYY',
|
|
1058
1071
|
};
|
|
1059
1072
|
```
|
|
1060
1073
|
|
|
@@ -1062,19 +1075,11 @@ export const DATE_PICKER_MONTH_YEAR_FORMAT = {
|
|
|
1062
1075
|
|
|
1063
1076
|
```tsx
|
|
1064
1077
|
import { Formik, Field } from 'formik';
|
|
1065
|
-
import { FormDateTextField } from 'form-fields';
|
|
1078
|
+
import { FormDateTextField } from 'form-input-fields';
|
|
1066
1079
|
|
|
1067
|
-
<Formik
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
>
|
|
1071
|
-
<Field
|
|
1072
|
-
component={FormDateTextField}
|
|
1073
|
-
name="eventDate"
|
|
1074
|
-
label="Event Date"
|
|
1075
|
-
format="MM/DD/YYYY"
|
|
1076
|
-
/>
|
|
1077
|
-
</Formik>
|
|
1080
|
+
<Formik initialValues={{ eventDate: '' }} onSubmit={values => console.log(values)}>
|
|
1081
|
+
<Field component={FormDateTextField} name="eventDate" label="Event Date" format="MM/DD/YYYY" />
|
|
1082
|
+
</Formik>;
|
|
1078
1083
|
```
|
|
1079
1084
|
|
|
1080
1085
|
### Props
|
|
@@ -1083,27 +1088,28 @@ The FormDateTextField component accepts all props from `FormDateTextFieldProps`,
|
|
|
1083
1088
|
|
|
1084
1089
|
#### FormDateTextFieldProps Interface
|
|
1085
1090
|
|
|
1086
|
-
| Prop
|
|
1087
|
-
|
|
1088
|
-
| `format`
|
|
1089
|
-
| `required`
|
|
1090
|
-
| `disabled`
|
|
1091
|
-
| `className`
|
|
1092
|
-
| `helperText` | `string`
|
|
1093
|
-
| `error`
|
|
1094
|
-
| `onChange`
|
|
1095
|
-
| `onBlur`
|
|
1091
|
+
| Prop | Type | Default | Description |
|
|
1092
|
+
| ------------ | ----------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------- |
|
|
1093
|
+
| `format` | `string` | `FORM_DATE_FORMAT.long` | Date format string using day.js tokens |
|
|
1094
|
+
| `required` | `boolean` | `false` | Whether the field is required |
|
|
1095
|
+
| `disabled` | `boolean` | `false` | Whether the field is disabled |
|
|
1096
|
+
| `className` | `string` | - | Custom class name for the root element |
|
|
1097
|
+
| `helperText` | `string` | - | Helper text to display below the field |
|
|
1098
|
+
| `error` | `boolean` | - | Error state of the field |
|
|
1099
|
+
| `onChange` | `(value: Dayjs \| null) => void` | - | Custom change handler |
|
|
1100
|
+
| `onBlur` | `(event: React.FocusEvent<HTMLInputElement>) => void` | - | Custom blur handler |
|
|
1101
|
+
| `sx` | `SxProps<Theme>` | - | The system prop that allows defining system overrides as well as additional CSS styles |
|
|
1096
1102
|
|
|
1097
1103
|
#### Common Props (from FieldProps & TextFieldProps)
|
|
1098
1104
|
|
|
1099
|
-
| Prop
|
|
1100
|
-
|
|
1101
|
-
| `name`
|
|
1102
|
-
| `label`
|
|
1103
|
-
| `placeholder` | `string`
|
|
1104
|
-
| `fullWidth`
|
|
1105
|
-
| `margin`
|
|
1106
|
-
| `size`
|
|
1105
|
+
| Prop | Type | Required | Description |
|
|
1106
|
+
| ------------- | ------------------------------- | -------- | --------------------------------------------------------------- |
|
|
1107
|
+
| `name` | `string` | Yes | Field name in Formik values |
|
|
1108
|
+
| `label` | `string` | No | Label for the input field |
|
|
1109
|
+
| `placeholder` | `string` | No | Placeholder text |
|
|
1110
|
+
| `fullWidth` | `boolean` | No | If true, the input will take up the full width of its container |
|
|
1111
|
+
| `margin` | `'none' \| 'dense' \| 'normal'` | No | If 'dense' or 'normal', will adjust vertical spacing |
|
|
1112
|
+
| `size` | `'small' \| 'medium'` | No | The size of the text field |
|
|
1107
1113
|
|
|
1108
1114
|
### Examples
|
|
1109
1115
|
|
|
@@ -1123,7 +1129,7 @@ The FormDateTextField component accepts all props from `FormDateTextFieldProps`,
|
|
|
1123
1129
|
|
|
1124
1130
|
```tsx
|
|
1125
1131
|
import { Formik, Form, Field } from 'formik';
|
|
1126
|
-
import { FormDateTextField, FormTextField } from 'form-fields';
|
|
1132
|
+
import { FormDateTextField, FormTextField } from 'form-input-fields';
|
|
1127
1133
|
import { Button } from '@mui/material';
|
|
1128
1134
|
|
|
1129
1135
|
const EventForm = () => (
|
|
@@ -1132,7 +1138,7 @@ const EventForm = () => (
|
|
|
1132
1138
|
eventName: '',
|
|
1133
1139
|
eventDate: '',
|
|
1134
1140
|
}}
|
|
1135
|
-
onSubmit={
|
|
1141
|
+
onSubmit={values => {
|
|
1136
1142
|
console.log('Form submitted:', values);
|
|
1137
1143
|
}}
|
|
1138
1144
|
>
|
|
@@ -1145,7 +1151,7 @@ const EventForm = () => (
|
|
|
1145
1151
|
fullWidth
|
|
1146
1152
|
margin="normal"
|
|
1147
1153
|
/>
|
|
1148
|
-
|
|
1154
|
+
|
|
1149
1155
|
<Field
|
|
1150
1156
|
component={FormDateTextField}
|
|
1151
1157
|
name="eventDate"
|
|
@@ -1155,13 +1161,8 @@ const EventForm = () => (
|
|
|
1155
1161
|
helperText="Select the event date"
|
|
1156
1162
|
margin="normal"
|
|
1157
1163
|
/>
|
|
1158
|
-
|
|
1159
|
-
<Button
|
|
1160
|
-
type="submit"
|
|
1161
|
-
variant="contained"
|
|
1162
|
-
color="primary"
|
|
1163
|
-
disabled={isSubmitting}
|
|
1164
|
-
>
|
|
1164
|
+
|
|
1165
|
+
<Button type="submit" variant="contained" color="primary" disabled={isSubmitting}>
|
|
1165
1166
|
Submit
|
|
1166
1167
|
</Button>
|
|
1167
1168
|
</Form>
|
|
@@ -1223,13 +1224,10 @@ A flexible form field component with advanced text masking capabilities.
|
|
|
1223
1224
|
### Usage with Formik
|
|
1224
1225
|
|
|
1225
1226
|
```tsx
|
|
1226
|
-
import { Formik, Field } from
|
|
1227
|
-
import { FormMaskField } from
|
|
1227
|
+
import { Formik, Field } from 'formik';
|
|
1228
|
+
import { FormMaskField } from 'form-input-fields';
|
|
1228
1229
|
|
|
1229
|
-
<Formik
|
|
1230
|
-
initialValues={{ phoneNumber: "", gameCode: "" }}
|
|
1231
|
-
onSubmit={(values) => console.log(values)}
|
|
1232
|
-
>
|
|
1230
|
+
<Formik initialValues={{ phoneNumber: '', gameCode: '' }} onSubmit={values => console.log(values)}>
|
|
1233
1231
|
<Field
|
|
1234
1232
|
component={FormMaskField}
|
|
1235
1233
|
name="phoneNumber"
|
|
@@ -1263,19 +1261,34 @@ import { FormMaskField } from "form-input-mask-field";
|
|
|
1263
1261
|
|
|
1264
1262
|
### Props
|
|
1265
1263
|
|
|
1266
|
-
| Prop | Type
|
|
1267
|
-
| ------------------ | ---------- |
|
|
1268
|
-
| `mask` | `string`
|
|
1269
|
-
| `placeholderChar` | `string`
|
|
1270
|
-
| `toUpperCase` | `boolean`
|
|
1271
|
-
| `returnCleanValue` | `boolean`
|
|
1272
|
-
| `showMaskPattern` | `boolean`
|
|
1273
|
-
| `showPlaceholder` | `boolean`
|
|
1274
|
-
| `onChange` | `function`
|
|
1275
|
-
| `variant`
|
|
1264
|
+
| Prop | Type | Default | Description |
|
|
1265
|
+
| ------------------ | ---------------- | ---------- | -------------------------------------------------------------------------------------- | ---------- | --------------------------------- |
|
|
1266
|
+
| `mask` | `string` | - | Mask pattern using the characters above |
|
|
1267
|
+
| `placeholderChar` | `string` | `'_'` | Character shown in placeholder for mask positions |
|
|
1268
|
+
| `toUpperCase` | `boolean` | `false` | Convert input to uppercase automatically |
|
|
1269
|
+
| `returnCleanValue` | `boolean` | `false` | Return unmasked value to Formik (true) or masked value (false) |
|
|
1270
|
+
| `showMaskPattern` | `boolean` | `false` | Show the mask pattern as helper text below the input field |
|
|
1271
|
+
| `showPlaceholder` | `boolean` | `false` | Show placeholder text with mask pattern in the input field |
|
|
1272
|
+
| `onChange` | `function` | - | Custom change handler with masked, clean, and raw values |
|
|
1273
|
+
| `variant` | `'standard' | 'outlined' | 'filled'` | 'standard' | The variant of the MUI TextField. |
|
|
1274
|
+
| `sx` | `SxProps<Theme>` | - | The system prop that allows defining system overrides as well as additional CSS styles |
|
|
1276
1275
|
|
|
1277
1276
|
Plus all standard Material-UI TextField props and Formik FieldProps.
|
|
1278
1277
|
|
|
1278
|
+
#### FormMaskFieldProps Interface
|
|
1279
|
+
|
|
1280
|
+
| Prop | Type | Default | Description |
|
|
1281
|
+
| ------------------ | ---------------- | ---------- | -------------------------------------------------------------------------------------- | ---------- | --------------------------------- |
|
|
1282
|
+
| `mask` | `string` | - | Mask pattern using the characters above |
|
|
1283
|
+
| `placeholderChar` | `string` | `'_'` | Character shown in placeholder for mask positions |
|
|
1284
|
+
| `toUpperCase` | `boolean` | `false` | Convert input to uppercase automatically |
|
|
1285
|
+
| `returnCleanValue` | `boolean` | `false` | Return unmasked value to Formik (true) or masked value (false) |
|
|
1286
|
+
| `showMaskPattern` | `boolean` | `false` | Show the mask pattern as helper text below the input field |
|
|
1287
|
+
| `showPlaceholder` | `boolean` | `false` | Show placeholder text with mask pattern in the input field |
|
|
1288
|
+
| `onChange` | `function` | - | Custom change handler with masked, clean, and raw values |
|
|
1289
|
+
| `variant` | `'standard' | 'outlined' | 'filled'` | 'standard' | The variant of the MUI TextField. |
|
|
1290
|
+
| `sx` | `SxProps<Theme>` | - | The system prop that allows defining system overrides as well as additional CSS styles |
|
|
1291
|
+
|
|
1279
1292
|
### Examples
|
|
1280
1293
|
|
|
1281
1294
|
#### Phone Number
|
|
@@ -1336,10 +1349,10 @@ Plus all standard Material-UI TextField props and Formik FieldProps.
|
|
|
1336
1349
|
name="customField"
|
|
1337
1350
|
label="Custom Field"
|
|
1338
1351
|
mask="999-AAA"
|
|
1339
|
-
onChange={
|
|
1340
|
-
console.log(
|
|
1341
|
-
console.log(
|
|
1342
|
-
console.log(
|
|
1352
|
+
onChange={event => {
|
|
1353
|
+
console.log('Masked value:', event.target.value);
|
|
1354
|
+
console.log('Clean value:', event.target.cleanValue);
|
|
1355
|
+
console.log('Raw input:', event.target.rawValue);
|
|
1343
1356
|
}}
|
|
1344
1357
|
variant="outlined" // <-- Example with outlined variant
|
|
1345
1358
|
/>
|
|
@@ -1379,19 +1392,19 @@ Here's a comprehensive example showing how to build a complete form application
|
|
|
1379
1392
|
### App.tsx
|
|
1380
1393
|
|
|
1381
1394
|
```tsx
|
|
1382
|
-
import React from
|
|
1383
|
-
import { Formik, Form, Field, FormikHelpers, FormikErrors } from
|
|
1384
|
-
import Container from
|
|
1385
|
-
import Typography from
|
|
1386
|
-
import Box from
|
|
1387
|
-
import Button from
|
|
1388
|
-
import { Grid } from
|
|
1389
|
-
import Paper from
|
|
1390
|
-
import Alert from
|
|
1391
|
-
import { ThemeProvider, createTheme } from
|
|
1392
|
-
import CssBaseline from
|
|
1393
|
-
import { FormMaskField } from
|
|
1394
|
-
import
|
|
1395
|
+
import React from 'react';
|
|
1396
|
+
import { Formik, Form, Field, FormikHelpers, FormikErrors } from 'formik';
|
|
1397
|
+
import Container from '@mui/material/Container';
|
|
1398
|
+
import Typography from '@mui/material/Typography';
|
|
1399
|
+
import Box from '@mui/material/Box';
|
|
1400
|
+
import Button from '@mui/material/Button';
|
|
1401
|
+
import { Grid } from '@mui/material';
|
|
1402
|
+
import Paper from '@mui/material/Paper';
|
|
1403
|
+
import Alert from '@mui/material/Alert';
|
|
1404
|
+
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
|
1405
|
+
import CssBaseline from '@mui/material/CssBaseline';
|
|
1406
|
+
import { FormMaskField } from 'form-input-fields';
|
|
1407
|
+
import './App.css';
|
|
1395
1408
|
|
|
1396
1409
|
interface FormValues {
|
|
1397
1410
|
phone: string;
|
|
@@ -1404,8 +1417,7 @@ interface FormValues {
|
|
|
1404
1417
|
postalCode: string;
|
|
1405
1418
|
}
|
|
1406
1419
|
|
|
1407
|
-
interface FormFieldEvent
|
|
1408
|
-
extends Omit<React.ChangeEvent<HTMLInputElement>, "target"> {
|
|
1420
|
+
interface FormFieldEvent extends Omit<React.ChangeEvent<HTMLInputElement>, 'target'> {
|
|
1409
1421
|
target: HTMLInputElement & {
|
|
1410
1422
|
value: string;
|
|
1411
1423
|
cleanValue: string;
|
|
@@ -1418,10 +1430,10 @@ interface FormFieldEvent
|
|
|
1418
1430
|
const theme = createTheme({
|
|
1419
1431
|
palette: {
|
|
1420
1432
|
primary: {
|
|
1421
|
-
main:
|
|
1433
|
+
main: '#1976d2',
|
|
1422
1434
|
},
|
|
1423
1435
|
secondary: {
|
|
1424
|
-
main:
|
|
1436
|
+
main: '#dc004e',
|
|
1425
1437
|
},
|
|
1426
1438
|
},
|
|
1427
1439
|
});
|
|
@@ -1431,23 +1443,23 @@ const validateForm = (values: FormValues): FormikErrors<FormValues> => {
|
|
|
1431
1443
|
const errors: Partial<FormValues> = {};
|
|
1432
1444
|
|
|
1433
1445
|
if (!values.phone) {
|
|
1434
|
-
errors.phone =
|
|
1435
|
-
} else if (values.phone.replace(/\D/g,
|
|
1436
|
-
errors.phone =
|
|
1446
|
+
errors.phone = 'Phone number is required';
|
|
1447
|
+
} else if (values.phone.replace(/\D/g, '').length < 10) {
|
|
1448
|
+
errors.phone = 'Phone number must be 10 digits';
|
|
1437
1449
|
}
|
|
1438
1450
|
|
|
1439
1451
|
if (!values.date) {
|
|
1440
|
-
errors.date =
|
|
1452
|
+
errors.date = 'Date is required';
|
|
1441
1453
|
}
|
|
1442
1454
|
|
|
1443
1455
|
if (!values.creditCard) {
|
|
1444
|
-
errors.creditCard =
|
|
1445
|
-
} else if (values.creditCard.replace(/\D/g,
|
|
1446
|
-
errors.creditCard =
|
|
1456
|
+
errors.creditCard = 'Credit card is required';
|
|
1457
|
+
} else if (values.creditCard.replace(/\D/g, '').length < 16) {
|
|
1458
|
+
errors.creditCard = 'Credit card must be 16 digits';
|
|
1447
1459
|
}
|
|
1448
1460
|
|
|
1449
1461
|
if (!values.licensePlate) {
|
|
1450
|
-
errors.licensePlate =
|
|
1462
|
+
errors.licensePlate = 'License plate is required';
|
|
1451
1463
|
}
|
|
1452
1464
|
|
|
1453
1465
|
return errors;
|
|
@@ -1455,36 +1467,32 @@ const validateForm = (values: FormValues): FormikErrors<FormValues> => {
|
|
|
1455
1467
|
|
|
1456
1468
|
function App() {
|
|
1457
1469
|
const initialValues: FormValues = {
|
|
1458
|
-
phone:
|
|
1459
|
-
date:
|
|
1460
|
-
creditCard:
|
|
1461
|
-
licensePlate:
|
|
1462
|
-
hexColor:
|
|
1463
|
-
customCode:
|
|
1464
|
-
socialSecurity:
|
|
1465
|
-
postalCode:
|
|
1470
|
+
phone: '',
|
|
1471
|
+
date: '',
|
|
1472
|
+
creditCard: '',
|
|
1473
|
+
licensePlate: '',
|
|
1474
|
+
hexColor: '',
|
|
1475
|
+
customCode: '',
|
|
1476
|
+
socialSecurity: '',
|
|
1477
|
+
postalCode: '',
|
|
1466
1478
|
};
|
|
1467
1479
|
|
|
1468
|
-
const handleSubmit = (
|
|
1469
|
-
|
|
1470
|
-
{ setSubmitting }: FormikHelpers<FormValues>
|
|
1471
|
-
) => {
|
|
1472
|
-
console.log("Form Values:", values);
|
|
1480
|
+
const handleSubmit = (values: FormValues, { setSubmitting }: FormikHelpers<FormValues>) => {
|
|
1481
|
+
console.log('Form Values:', values);
|
|
1473
1482
|
setTimeout(() => {
|
|
1474
|
-
alert(
|
|
1483
|
+
alert('Form submitted! Check console for values.');
|
|
1475
1484
|
setSubmitting(false);
|
|
1476
1485
|
}, 400);
|
|
1477
1486
|
};
|
|
1478
1487
|
|
|
1479
|
-
const handleCustomChange =
|
|
1480
|
-
(fieldName
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
};
|
|
1488
|
+
const handleCustomChange = (fieldName: keyof FormValues) => (event: FormFieldEvent) => {
|
|
1489
|
+
console.log(`${fieldName} changed:`, {
|
|
1490
|
+
masked: event.target.value,
|
|
1491
|
+
clean: event.target.cleanValue,
|
|
1492
|
+
raw: event.target.rawValue,
|
|
1493
|
+
});
|
|
1494
|
+
return event;
|
|
1495
|
+
};
|
|
1488
1496
|
|
|
1489
1497
|
return (
|
|
1490
1498
|
<ThemeProvider theme={theme}>
|
|
@@ -1494,21 +1502,12 @@ function App() {
|
|
|
1494
1502
|
FormMaskField Demo
|
|
1495
1503
|
</Typography>
|
|
1496
1504
|
|
|
1497
|
-
<Typography
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
color="text.secondary"
|
|
1501
|
-
paragraph
|
|
1502
|
-
>
|
|
1503
|
-
A comprehensive example showcasing the FormMaskField component with
|
|
1504
|
-
various mask patterns and configurations
|
|
1505
|
+
<Typography variant="subtitle1" align="center" color="text.secondary" paragraph>
|
|
1506
|
+
A comprehensive example showcasing the FormMaskField component with various mask patterns
|
|
1507
|
+
and configurations
|
|
1505
1508
|
</Typography>
|
|
1506
1509
|
|
|
1507
|
-
<Formik
|
|
1508
|
-
initialValues={initialValues}
|
|
1509
|
-
validate={validateForm}
|
|
1510
|
-
onSubmit={handleSubmit}
|
|
1511
|
-
>
|
|
1510
|
+
<Formik initialValues={initialValues} validate={validateForm} onSubmit={handleSubmit}>
|
|
1512
1511
|
{({ values, isSubmitting, errors, touched }) => (
|
|
1513
1512
|
<Form>
|
|
1514
1513
|
<Grid container spacing={3}>
|
|
@@ -1529,7 +1528,7 @@ function App() {
|
|
|
1529
1528
|
showMaskPattern={true}
|
|
1530
1529
|
showPlaceholder={true}
|
|
1531
1530
|
helperText="US phone number format"
|
|
1532
|
-
onChange={handleCustomChange(
|
|
1531
|
+
onChange={handleCustomChange('phone')}
|
|
1533
1532
|
variant="outlined" // <-- Example with outlined variant
|
|
1534
1533
|
/>
|
|
1535
1534
|
</Grid>
|
|
@@ -1591,7 +1590,7 @@ function App() {
|
|
|
1591
1590
|
showMaskPattern={true}
|
|
1592
1591
|
showPlaceholder={true}
|
|
1593
1592
|
helperText="16-digit credit card number"
|
|
1594
|
-
onChange={handleCustomChange(
|
|
1593
|
+
onChange={handleCustomChange('creditCard')}
|
|
1595
1594
|
/>
|
|
1596
1595
|
</Grid>
|
|
1597
1596
|
|
|
@@ -1605,7 +1604,7 @@ function App() {
|
|
|
1605
1604
|
showMaskPattern={true}
|
|
1606
1605
|
showPlaceholder={true}
|
|
1607
1606
|
helperText="3 letters + 3 numbers (auto uppercase)"
|
|
1608
|
-
onChange={handleCustomChange(
|
|
1607
|
+
onChange={handleCustomChange('licensePlate')}
|
|
1609
1608
|
/>
|
|
1610
1609
|
</Grid>
|
|
1611
1610
|
|
|
@@ -1634,7 +1633,7 @@ function App() {
|
|
|
1634
1633
|
showMaskPattern={true}
|
|
1635
1634
|
showPlaceholder={true}
|
|
1636
1635
|
helperText="Alphanumeric + digits + letters"
|
|
1637
|
-
onChange={handleCustomChange(
|
|
1636
|
+
onChange={handleCustomChange('customCode')}
|
|
1638
1637
|
/>
|
|
1639
1638
|
</Grid>
|
|
1640
1639
|
</Grid>
|
|
@@ -1653,11 +1652,11 @@ function App() {
|
|
|
1653
1652
|
variant="body2"
|
|
1654
1653
|
component="pre"
|
|
1655
1654
|
sx={{
|
|
1656
|
-
backgroundColor:
|
|
1655
|
+
backgroundColor: '#f5f5f5',
|
|
1657
1656
|
p: 2,
|
|
1658
1657
|
borderRadius: 1,
|
|
1659
|
-
overflow:
|
|
1660
|
-
fontSize:
|
|
1658
|
+
overflow: 'auto',
|
|
1659
|
+
fontSize: '0.875rem',
|
|
1661
1660
|
}}
|
|
1662
1661
|
>
|
|
1663
1662
|
{JSON.stringify(values, null, 2)}
|
|
@@ -1667,32 +1666,29 @@ function App() {
|
|
|
1667
1666
|
</Grid>
|
|
1668
1667
|
|
|
1669
1668
|
{/* Form Errors Display */}
|
|
1670
|
-
{Object.keys(errors).length > 0 &&
|
|
1671
|
-
|
|
1672
|
-
<
|
|
1673
|
-
<
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
<
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
)}
|
|
1669
|
+
{Object.keys(errors).length > 0 && Object.keys(touched).length > 0 && (
|
|
1670
|
+
<Grid>
|
|
1671
|
+
<Alert severity="error">
|
|
1672
|
+
<Typography variant="h6" gutterBottom>
|
|
1673
|
+
Form Validation Errors:
|
|
1674
|
+
</Typography>
|
|
1675
|
+
<ul>
|
|
1676
|
+
{Object.entries(errors).map(
|
|
1677
|
+
([field, error]) =>
|
|
1678
|
+
touched[field] && (
|
|
1679
|
+
<li key={field}>
|
|
1680
|
+
<strong>{field}:</strong> {error}
|
|
1681
|
+
</li>
|
|
1682
|
+
),
|
|
1683
|
+
)}
|
|
1684
|
+
</ul>
|
|
1685
|
+
</Alert>
|
|
1686
|
+
</Grid>
|
|
1687
|
+
)}
|
|
1690
1688
|
|
|
1691
1689
|
{/* Submit Button */}
|
|
1692
1690
|
<Grid>
|
|
1693
|
-
<Box
|
|
1694
|
-
sx={{ display: "flex", justifyContent: "center", mt: 2 }}
|
|
1695
|
-
>
|
|
1691
|
+
<Box sx={{ display: 'flex', justifyContent: 'center', mt: 2 }}>
|
|
1696
1692
|
<Button
|
|
1697
1693
|
type="submit"
|
|
1698
1694
|
variant="contained"
|
|
@@ -1700,7 +1696,7 @@ function App() {
|
|
|
1700
1696
|
disabled={isSubmitting}
|
|
1701
1697
|
sx={{ minWidth: 200 }}
|
|
1702
1698
|
>
|
|
1703
|
-
{isSubmitting ?
|
|
1699
|
+
{isSubmitting ? 'Submitting...' : 'Submit Form'}
|
|
1704
1700
|
</Button>
|
|
1705
1701
|
</Box>
|
|
1706
1702
|
</Grid>
|
|
@@ -1801,8 +1797,64 @@ If you like my work, you can support me here:
|
|
|
1801
1797
|
|
|
1802
1798
|
[](https://coff.ee/vavanv)
|
|
1803
1799
|
|
|
1800
|
+
## Testing
|
|
1801
|
+
|
|
1802
|
+
This package includes comprehensive test coverage for all form controls, ensuring reliability and proper functionality. Tests are written using Jest and React Testing Library.
|
|
1803
|
+
|
|
1804
|
+
### Test Coverage
|
|
1805
|
+
|
|
1806
|
+
- **FormTextField**: 100+ test cases covering basic rendering, input handling, Formik integration, error handling, accessibility, and sx prop support
|
|
1807
|
+
- **FormDropDownField**: Complete test suite for dropdown functionality, validation, and styling
|
|
1808
|
+
- **FormDateField**: Tests for date picker integration, validation, and formatting
|
|
1809
|
+
- **FormDateTextField**: Text-based date input testing with various formats
|
|
1810
|
+
- **FormMaskField**: Extensive masking functionality tests including pattern validation and custom handlers
|
|
1811
|
+
- **FormCheckboxField**: Checkbox state management and Formik integration tests
|
|
1812
|
+
- **FormSwitch**: Switch component testing with various configurations
|
|
1813
|
+
|
|
1814
|
+
### Running Tests
|
|
1815
|
+
|
|
1816
|
+
```bash
|
|
1817
|
+
# Run all tests
|
|
1818
|
+
npm test
|
|
1819
|
+
|
|
1820
|
+
# Run tests in watch mode
|
|
1821
|
+
npm run test:watch
|
|
1822
|
+
|
|
1823
|
+
# Run tests with coverage
|
|
1824
|
+
npm run test:coverage
|
|
1825
|
+
|
|
1826
|
+
# Run tests in debug mode
|
|
1827
|
+
npm run test:debug
|
|
1828
|
+
```
|
|
1829
|
+
|
|
1804
1830
|
## History
|
|
1805
1831
|
|
|
1832
|
+
### 2025-11-10 - Enhanced Styling Support and Standardized Form Controls
|
|
1833
|
+
|
|
1834
|
+
#### Added `sx` prop support to all form controls
|
|
1835
|
+
|
|
1836
|
+
All form controls now support the `sx` prop for custom styling, providing a powerful and flexible way to apply styles directly to your form components:
|
|
1837
|
+
|
|
1838
|
+
- `FormTextField`
|
|
1839
|
+
- `FormCheckboxField`
|
|
1840
|
+
- `FormDateField`
|
|
1841
|
+
- `FormDateTextField`
|
|
1842
|
+
- `FormDropDownField`
|
|
1843
|
+
- `FormMaskField`
|
|
1844
|
+
- `FormSwitch`
|
|
1845
|
+
|
|
1846
|
+
The `sx` prop follows Material-UI's sx system, allowing you to use CSS properties, theme values, and responsive design patterns.
|
|
1847
|
+
|
|
1848
|
+
#### Standardized FormControl wrapper pattern
|
|
1849
|
+
|
|
1850
|
+
All form controls now use a standardized `FormControl` wrapper pattern, ensuring consistent behavior, accessibility, and styling across all form components. This provides:
|
|
1851
|
+
|
|
1852
|
+
- Consistent structure across all form controls
|
|
1853
|
+
- Improved accessibility with proper labeling and ARIA attributes
|
|
1854
|
+
- Unified error display and management
|
|
1855
|
+
- Better integration with Material-UI's styling system
|
|
1856
|
+
- Enhanced Formik form state management
|
|
1857
|
+
|
|
1806
1858
|
### Added `variant` prop to controls
|
|
1807
1859
|
|
|
1808
1860
|
The following controls now accept a `variant` prop (`'standard' | 'outlined' | 'filled'`), which is passed to the underlying MUI TextField. The default is `'standard'`:
|
|
@@ -1812,3 +1864,258 @@ The following controls now accept a `variant` prop (`'standard' | 'outlined' | '
|
|
|
1812
1864
|
- `FormMaskField`
|
|
1813
1865
|
|
|
1814
1866
|
This allows you to easily switch between Material-UI's standard, outlined, and filled input styles for these components.
|
|
1867
|
+
|
|
1868
|
+
---
|
|
1869
|
+
|
|
1870
|
+
## Styling Form Controls
|
|
1871
|
+
|
|
1872
|
+
### sx Prop Support
|
|
1873
|
+
|
|
1874
|
+
All form controls now support the `sx` prop for custom styling, providing a powerful and flexible way to apply styles directly to your form components. The `sx` prop follows Material-UI's sx system, allowing you to use CSS properties, theme values, and responsive design patterns.
|
|
1875
|
+
|
|
1876
|
+
#### Benefits of the sx Prop
|
|
1877
|
+
|
|
1878
|
+
- **Direct Styling**: Apply styles without creating separate CSS files or styled components
|
|
1879
|
+
- **Theme Integration**: Access to your Material-UI theme values (colors, spacing, breakpoints)
|
|
1880
|
+
- **Responsive Design**: Easily apply different styles at different breakpoints
|
|
1881
|
+
- **Dynamic Styling**: Use conditional styling based on component state or props
|
|
1882
|
+
- **Performance**: Optimized style application by Material-UI
|
|
1883
|
+
|
|
1884
|
+
#### Using the sx Prop with Form Controls
|
|
1885
|
+
|
|
1886
|
+
```tsx
|
|
1887
|
+
import { Formik, Field } from 'formik';
|
|
1888
|
+
import { FormTextField, FormDropDownField, FormSwitch } from 'form-input-fields';
|
|
1889
|
+
|
|
1890
|
+
// Basic sx prop usage
|
|
1891
|
+
<Field
|
|
1892
|
+
component={FormTextField}
|
|
1893
|
+
name="username"
|
|
1894
|
+
label="Username"
|
|
1895
|
+
sx={{
|
|
1896
|
+
backgroundColor: 'background.paper',
|
|
1897
|
+
borderRadius: 2,
|
|
1898
|
+
'& .MuiOutlinedInput-root': {
|
|
1899
|
+
'& fieldset': {
|
|
1900
|
+
borderColor: 'primary.main',
|
|
1901
|
+
},
|
|
1902
|
+
},
|
|
1903
|
+
}}
|
|
1904
|
+
/>
|
|
1905
|
+
|
|
1906
|
+
// Responsive styling with sx
|
|
1907
|
+
<Field
|
|
1908
|
+
component={FormDropDownField}
|
|
1909
|
+
name="category"
|
|
1910
|
+
label="Category"
|
|
1911
|
+
items={categories}
|
|
1912
|
+
sx={{
|
|
1913
|
+
width: { xs: '100%', md: '50%' },
|
|
1914
|
+
mx: { xs: 0, md: 2 },
|
|
1915
|
+
}}
|
|
1916
|
+
/>
|
|
1917
|
+
|
|
1918
|
+
// Conditional styling with sx
|
|
1919
|
+
<Field
|
|
1920
|
+
component={FormSwitch}
|
|
1921
|
+
name="notifications"
|
|
1922
|
+
label="Enable Notifications"
|
|
1923
|
+
sx={{
|
|
1924
|
+
'& .MuiSwitch-switchBase.Mui-checked': {
|
|
1925
|
+
color: 'success.main',
|
|
1926
|
+
},
|
|
1927
|
+
'& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': {
|
|
1928
|
+
backgroundColor: 'success.main',
|
|
1929
|
+
},
|
|
1930
|
+
}}
|
|
1931
|
+
/>
|
|
1932
|
+
```
|
|
1933
|
+
|
|
1934
|
+
### FormControl Wrapper Pattern
|
|
1935
|
+
|
|
1936
|
+
All form controls now use a standardized `FormControl` wrapper pattern, ensuring consistent behavior, accessibility, and styling across all form components. This pattern provides:
|
|
1937
|
+
|
|
1938
|
+
- **Consistent Structure**: All form controls follow the same DOM structure
|
|
1939
|
+
- **Accessibility**: Proper labeling and ARIA attributes
|
|
1940
|
+
- **Error Handling**: Consistent error display and management
|
|
1941
|
+
- **Styling Integration**: Seamless integration with Material-UI's styling system
|
|
1942
|
+
|
|
1943
|
+
#### FormControl Wrapper Benefits
|
|
1944
|
+
|
|
1945
|
+
1. **Consistent Labeling**: All controls properly associate labels with form inputs
|
|
1946
|
+
2. **Error State Management**: Unified error display and styling
|
|
1947
|
+
3. **Helper Text**: Consistent helper text positioning and styling
|
|
1948
|
+
4. **Form Integration**: Better integration with Formik's form state management
|
|
1949
|
+
5. **Accessibility**: Improved screen reader support and keyboard navigation
|
|
1950
|
+
|
|
1951
|
+
#### Example: FormControl Wrapper in Action
|
|
1952
|
+
|
|
1953
|
+
```tsx
|
|
1954
|
+
// Before (inconsistent structure)
|
|
1955
|
+
<div className="custom-field">
|
|
1956
|
+
<label>Field Label</label>
|
|
1957
|
+
<input />
|
|
1958
|
+
<span className="error">Error message</span>
|
|
1959
|
+
</div>
|
|
1960
|
+
|
|
1961
|
+
// After (standardized FormControl wrapper)
|
|
1962
|
+
<FormControl
|
|
1963
|
+
error={hasError}
|
|
1964
|
+
fullWidth
|
|
1965
|
+
variant="outlined"
|
|
1966
|
+
sx={{ mb: 2 }}
|
|
1967
|
+
>
|
|
1968
|
+
<InputLabel htmlFor="field-id">Field Label</InputLabel>
|
|
1969
|
+
<Field
|
|
1970
|
+
component={FormTextField}
|
|
1971
|
+
id="field-id"
|
|
1972
|
+
name="fieldName"
|
|
1973
|
+
label="Field Label"
|
|
1974
|
+
/>
|
|
1975
|
+
<FormHelperText>{hasError ? errorMessage : helperText}</FormHelperText>
|
|
1976
|
+
</FormControl>
|
|
1977
|
+
```
|
|
1978
|
+
|
|
1979
|
+
### Advanced Styling Examples
|
|
1980
|
+
|
|
1981
|
+
#### Custom Theme Integration
|
|
1982
|
+
|
|
1983
|
+
```tsx
|
|
1984
|
+
import { useTheme } from '@mui/material/styles';
|
|
1985
|
+
|
|
1986
|
+
function ThemedForm() {
|
|
1987
|
+
const theme = useTheme();
|
|
1988
|
+
|
|
1989
|
+
return (
|
|
1990
|
+
<Field
|
|
1991
|
+
component={FormTextField}
|
|
1992
|
+
name="customField"
|
|
1993
|
+
label="Custom Styled Field"
|
|
1994
|
+
sx={{
|
|
1995
|
+
// Using theme values
|
|
1996
|
+
backgroundColor: theme.palette.grey[50],
|
|
1997
|
+
borderColor: theme.palette.primary.main,
|
|
1998
|
+
|
|
1999
|
+
// Hover effects
|
|
2000
|
+
'&:hover': {
|
|
2001
|
+
backgroundColor: theme.palette.grey[100],
|
|
2002
|
+
},
|
|
2003
|
+
|
|
2004
|
+
// Focus styles
|
|
2005
|
+
'& .Mui-focused': {
|
|
2006
|
+
borderColor: theme.palette.secondary.main,
|
|
2007
|
+
},
|
|
2008
|
+
|
|
2009
|
+
// Custom styles for different states
|
|
2010
|
+
'&.Mui-error': {
|
|
2011
|
+
borderColor: theme.palette.error.main,
|
|
2012
|
+
},
|
|
2013
|
+
}}
|
|
2014
|
+
/>
|
|
2015
|
+
);
|
|
2016
|
+
}
|
|
2017
|
+
```
|
|
2018
|
+
|
|
2019
|
+
#### Responsive Form Layout
|
|
2020
|
+
|
|
2021
|
+
```tsx
|
|
2022
|
+
<Box sx={{ display: 'flex', flexDirection: { xs: 'column', md: 'row' }, gap: 2 }}>
|
|
2023
|
+
<Field
|
|
2024
|
+
component={FormTextField}
|
|
2025
|
+
name="firstName"
|
|
2026
|
+
label="First Name"
|
|
2027
|
+
sx={{
|
|
2028
|
+
flex: 1,
|
|
2029
|
+
// Mobile-first responsive design
|
|
2030
|
+
minWidth: { xs: '100%', sm: 200 },
|
|
2031
|
+
}}
|
|
2032
|
+
/>
|
|
2033
|
+
|
|
2034
|
+
<Field
|
|
2035
|
+
component={FormTextField}
|
|
2036
|
+
name="lastName"
|
|
2037
|
+
label="Last Name"
|
|
2038
|
+
sx={{
|
|
2039
|
+
flex: 1,
|
|
2040
|
+
minWidth: { xs: '100%', sm: 200 },
|
|
2041
|
+
}}
|
|
2042
|
+
/>
|
|
2043
|
+
</Box>
|
|
2044
|
+
```
|
|
2045
|
+
|
|
2046
|
+
#### Conditional Styling Based on State
|
|
2047
|
+
|
|
2048
|
+
```tsx
|
|
2049
|
+
<Field
|
|
2050
|
+
component={FormSwitch}
|
|
2051
|
+
name="premiumFeature"
|
|
2052
|
+
label="Enable Premium Features"
|
|
2053
|
+
sx={{
|
|
2054
|
+
// Style based on checked state
|
|
2055
|
+
'& .MuiSwitch-switchBase': {
|
|
2056
|
+
color: theme => (premiumEnabled ? theme.palette.success.main : 'default'),
|
|
2057
|
+
},
|
|
2058
|
+
|
|
2059
|
+
// Animation for state changes
|
|
2060
|
+
transition: 'all 0.3s ease',
|
|
2061
|
+
|
|
2062
|
+
// Custom styling when disabled
|
|
2063
|
+
'&.Mui-disabled': {
|
|
2064
|
+
opacity: 0.6,
|
|
2065
|
+
},
|
|
2066
|
+
}}
|
|
2067
|
+
/>
|
|
2068
|
+
```
|
|
2069
|
+
|
|
2070
|
+
### Best Practices for Styling Form Controls
|
|
2071
|
+
|
|
2072
|
+
1. **Use Theme Values**: Always prefer theme values over hardcoded colors and sizes
|
|
2073
|
+
2. **Responsive Design**: Use breakpoints to ensure your forms work on all screen sizes
|
|
2074
|
+
3. **Consistent Spacing**: Use the spacing scale for margins and padding
|
|
2075
|
+
4. **Accessibility**: Ensure color contrast and focus states are properly styled
|
|
2076
|
+
5. **Performance**: Avoid overly complex selectors in the sx prop for better performance
|
|
2077
|
+
|
|
2078
|
+
### Migration Guide
|
|
2079
|
+
|
|
2080
|
+
If you're upgrading from a previous version, here's how to migrate to the new styling system:
|
|
2081
|
+
|
|
2082
|
+
#### Old Approach (Custom CSS Classes)
|
|
2083
|
+
|
|
2084
|
+
```tsx
|
|
2085
|
+
// Before
|
|
2086
|
+
<Field component={FormTextField} name="username" className="custom-text-field" label="Username" />
|
|
2087
|
+
```
|
|
2088
|
+
|
|
2089
|
+
```css
|
|
2090
|
+
/* In your CSS file */
|
|
2091
|
+
.custom-text-field {
|
|
2092
|
+
background-color: #f5f5f5;
|
|
2093
|
+
border-radius: 8px;
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
.custom-text-field .MuiOutlinedInput-root {
|
|
2097
|
+
border-color: #1976d2;
|
|
2098
|
+
}
|
|
2099
|
+
```
|
|
2100
|
+
|
|
2101
|
+
#### New Approach (sx Prop)
|
|
2102
|
+
|
|
2103
|
+
```tsx
|
|
2104
|
+
// After
|
|
2105
|
+
<Field
|
|
2106
|
+
component={FormTextField}
|
|
2107
|
+
name="username"
|
|
2108
|
+
label="Username"
|
|
2109
|
+
sx={{
|
|
2110
|
+
backgroundColor: 'background.paper',
|
|
2111
|
+
borderRadius: 2,
|
|
2112
|
+
'& .MuiOutlinedInput-root': {
|
|
2113
|
+
'& fieldset': {
|
|
2114
|
+
borderColor: 'primary.main',
|
|
2115
|
+
},
|
|
2116
|
+
},
|
|
2117
|
+
}}
|
|
2118
|
+
/>
|
|
2119
|
+
```
|
|
2120
|
+
|
|
2121
|
+
The new approach provides better theme integration, responsive design capabilities, and improved maintainability.
|