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