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.
Files changed (34) hide show
  1. package/README.md +591 -284
  2. package/dist/controls/FormCheckboxField/FormCheckboxField.d.ts +4 -1
  3. package/dist/controls/FormCheckboxField/FormCheckboxField.d.ts.map +1 -1
  4. package/dist/controls/FormDateField/FormDateField.d.ts +3 -1
  5. package/dist/controls/FormDateField/FormDateField.d.ts.map +1 -1
  6. package/dist/controls/FormDateTextField/FormDateTextField.d.ts +4 -2
  7. package/dist/controls/FormDateTextField/FormDateTextField.d.ts.map +1 -1
  8. package/dist/controls/FormDropDownField/FormDropDownField.d.ts +4 -2
  9. package/dist/controls/FormDropDownField/FormDropDownField.d.ts.map +1 -1
  10. package/dist/controls/FormMaskField/FormMaskField.d.ts +3 -0
  11. package/dist/controls/FormMaskField/FormMaskField.d.ts.map +1 -1
  12. package/dist/controls/FormSwitch/FormSwitch.d.ts +3 -0
  13. package/dist/controls/FormSwitch/FormSwitch.d.ts.map +1 -1
  14. package/dist/controls/FormTextField/FormTextField.d.ts +3 -1
  15. package/dist/controls/FormTextField/FormTextField.d.ts.map +1 -1
  16. package/dist/index.es.js +2093 -2080
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.js +50 -50
  19. package/dist/index.js.map +1 -1
  20. package/dist/stories/FormCheckboxField.stories.d.ts +22 -0
  21. package/dist/stories/FormCheckboxField.stories.d.ts.map +1 -0
  22. package/dist/stories/FormDateField.stories.d.ts +10 -0
  23. package/dist/stories/FormDateField.stories.d.ts.map +1 -0
  24. package/dist/stories/FormDateTextField.stories.d.ts +8 -0
  25. package/dist/stories/FormDateTextField.stories.d.ts.map +1 -0
  26. package/dist/stories/FormDropDownField.stories.d.ts +8 -0
  27. package/dist/stories/FormDropDownField.stories.d.ts.map +1 -0
  28. package/dist/stories/FormMaskField.stories.d.ts +11 -0
  29. package/dist/stories/FormMaskField.stories.d.ts.map +1 -0
  30. package/dist/stories/FormSwitch.stories.d.ts +7 -0
  31. package/dist/stories/FormSwitch.stories.d.ts.map +1 -0
  32. package/dist/stories/FormTextField.stories.d.ts +8 -0
  33. package/dist/stories/FormTextField.stories.d.ts.map +1 -0
  34. 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 @your-org/form-fields @mui/material @emotion/react @emotion/styled formik @mui/x-date-pickers dayjs
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 | Default | Description |
219
- |------------|------------|---------|-----------------------------------------------|
220
- | `onChange` | `function` | - | Custom change handler that overrides Formik's |
221
- | `onBlur` | `function` | - | Custom blur handler that overrides Formik's |
222
- | `variant` | `'standard' | 'outlined' | 'filled'` | 'standard' | The variant of the MUI TextField. |
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={(values) => console.log(values)}
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: "(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
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 | Type | Default | Description |
349
- |------|------|---------|-------------|
350
- | `items` | `Array<{ id: string | number; description: string }>` | `[]` | Array of items to display in the dropdown |
351
- | `addInputSelect` | `boolean` | `false` | Whether to show a default "Select" option as the first item |
352
- | `selectText` | `string` | `'Select'` | Text to display for the default "Select" option |
353
- | `required` | `boolean` | `false` | Whether the field is required |
354
- | `disabled` | `boolean` | `false` | Whether the field is disabled |
355
- | `className` | `string` | - | Custom class name for the root element |
356
- | `helperText` | `string` | - | Helper text to display below the field |
357
- | `error` | `boolean` | - | Error state of the field (overrides Formik error state) |
358
- | `onChange` | `(value: any) => void` | - | Custom change handler |
359
- | `onBlur` | `(event: React.FocusEvent<HTMLInputElement>) => void` | - | Custom blur handler |
360
- | `variant` | `'standard' | 'outlined' | 'filled'` | 'standard' | The variant of the MUI TextField. |
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={(values) => console.log(values)}
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: "YYYY-MM-DD",
454
- long: "MM/DD/YYYY hh:mm A",
455
- custom: "DD MMMM YYYY hh:mm A",
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: "DD/MM/YYYY",
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: "MM/YYYY",
472
- long: "MMMM YYYY",
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-mask-field/date";
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 "formik";
504
- import { FormDateField, FormDateFieldProps } from "form-input-mask-field";
505
- import { FORM_DATE_FORMAT } from "form-input-mask-field/date";
506
- import dayjs from "dayjs";
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={(values) => console.log(values)}
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("Selected date:", value);
532
- console.log("Formatted value:", context.formattedValue);
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 | Default | Description |
545
- | ----------------- | ---------- | ------------------------ | --------------------------------------------- |
546
- | `format` | `string` | `FORM_DATE_FORMAT.short` | Date format string using dayjs format tokens |
547
- | `minDate` | `Dayjs` | - | Minimum selectable date |
548
- | `maxDate` | `Dayjs` | - | Maximum selectable date |
549
- | `disablePast` | `boolean` | `false` | Disable past dates |
550
- | `disableFuture` | `boolean` | `false` | Disable future dates |
551
- | `showTodayButton` | `boolean` | `false` | Show today button in the picker |
552
- | `readOnly` | `boolean` | `false` | Make the field read-only |
553
- | `showDateFormat` | `boolean` | `false` | Show the date format as helper text |
554
- | `onChange` | `function` | - | Custom change handler with additional context |
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, "day")}
603
- maxDate={dayjs().add(3, "month")}
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("Selected date:", value);
631
- console.log("Formatted value:", context.formattedValue);
632
- console.log("Validation error:", context.validationError);
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("Events cannot be scheduled on Sundays");
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-mask-field';
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 | Type | Default | Description |
719
- | -------------- | --------- | ------- | ------------------------------------------------ |
720
- | `id` | `string` | - | Unique identifier for the checkbox |
721
- | `label` | `string` | - | Label text displayed next to the checkbox |
722
- | `checked` | `boolean` | `false` | Whether the checkbox is checked |
723
- | `onChange` | `function`| - | Callback when checkbox state changes |
724
- | `disabled` | `boolean` | `false` | Disable the checkbox |
725
- | `required` | `boolean` | `false` | Mark the field as required |
726
- | `color` | `string` | 'primary'| Color of the checkbox when checked |
727
- | `size` | `string` | 'medium'| Size of the checkbox ('small' or 'medium') |
728
- | `labelPlacement`| `string` | 'end' | Position of the label ('end', 'start', 'top', 'bottom') |
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={(e) => setNotificationsEnabled(e.target.checked)}
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={(values) => console.log('Form values:', values)}
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={(e) => form.setFieldValue(field.name, e.target.checked)}
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={(e) => form.setFieldValue(field.name, e.target.checked)}
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((theme) => ({
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 | Default | Description |
873
- | ---------------- | ---------- | ------- | ------------------------------------------------ |
874
- | `label` | `string` | - | Label text displayed next to the switch |
875
- | `labelPlacement` | `string` | 'end' | Position of label ('top', 'start', 'bottom', 'end') |
876
- | `color` | `string` | 'primary'| Switch color ('primary', 'secondary', 'error', 'info', 'success', 'warning', 'default') |
877
- | `size` | `string` | 'medium'| Switch size ('small' or 'medium') |
878
- | `disabled` | `boolean` | `false` | Disable the switch |
879
- | `required` | `boolean` | `false` | Mark the field as required |
880
- | `onChange` | `function` | - | Custom change handler with context data |
881
- | `onBlur` | `function` | - | Custom blur handler |
882
- | `helperText` | `string` | - | Helper text to display below the switch |
883
- | `error` | `boolean` | `false` | Error state of the switch |
884
- | `className` | `string` | - | Custom class name for the root element |
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 | Required | Description |
889
- |--------------|------------------|----------|-----------------------------------------------|
890
- | `name` | `string` | Yes | Field name in Formik values |
891
- | `label` | `string` | No | Field label |
892
- | `helperText` | `string` | No | Custom helper text |
893
- | `error` | `boolean` | No | Error state (auto-managed by Formik) |
894
- | `disabled` | `boolean` | No | Disabled state |
895
- | `required` | `boolean` | No | Required field indicator |
896
- | Other | `SwitchProps` | No | All Material-UI Switch props are supported |
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={(values) => console.log('Form values:', values)}
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={(values) => {
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={(values) => console.log(values)}
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: "YYYY-MM-DD",
1039
- long: "MM/DD/YYYY hh:mm A",
1040
- custom: "DD MMMM YYYY hh:mm A"
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: "DD/MM/YYYY"
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: "MM/YYYY",
1057
- long: "MMMM YYYY"
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
- initialValues={{ eventDate: '' }}
1069
- onSubmit={(values) => console.log(values)}
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 | Type | Default | Description |
1087
- |------|------|---------|-------------|
1088
- | `format` | `string` | `FORM_DATE_FORMAT.long` | Date format string using day.js tokens |
1089
- | `required` | `boolean` | `false` | Whether the field is required |
1090
- | `disabled` | `boolean` | `false` | Whether the field is disabled |
1091
- | `className` | `string` | - | Custom class name for the root element |
1092
- | `helperText` | `string` | - | Helper text to display below the field |
1093
- | `error` | `boolean` | - | Error state of the field |
1094
- | `onChange` | `(value: Dayjs \| null) => void` | - | Custom change handler |
1095
- | `onBlur` | `(event: React.FocusEvent<HTMLInputElement>) => void` | - | Custom blur handler |
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 | Type | Required | Description |
1100
- |------|------|----------|-------------|
1101
- | `name` | `string` | Yes | Field name in Formik values |
1102
- | `label` | `string` | No | Label for the input field |
1103
- | `placeholder` | `string` | No | Placeholder text |
1104
- | `fullWidth` | `boolean` | No | If true, the input will take up the full width of its container |
1105
- | `margin` | `'none' \| 'dense' \| 'normal'` | No | If 'dense' or 'normal', will adjust vertical spacing |
1106
- | `size` | `'small' \| 'medium'` | No | The size of the text field |
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={(values) => {
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 "formik";
1227
- import { FormMaskField } from "form-input-mask-field";
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 | Default | Description |
1267
- | ------------------ | ---------- | ------- | -------------------------------------------------------------- |
1268
- | `mask` | `string` | - | Mask pattern using the characters above |
1269
- | `placeholderChar` | `string` | `'_'` | Character shown in placeholder for mask positions |
1270
- | `toUpperCase` | `boolean` | `false` | Convert input to uppercase automatically |
1271
- | `returnCleanValue` | `boolean` | `false` | Return unmasked value to Formik (true) or masked value (false) |
1272
- | `showMaskPattern` | `boolean` | `false` | Show the mask pattern as helper text below the input field |
1273
- | `showPlaceholder` | `boolean` | `false` | Show placeholder text with mask pattern in the input field |
1274
- | `onChange` | `function` | - | Custom change handler with masked, clean, and raw values |
1275
- | `variant` | `'standard' | 'outlined' | 'filled'` | 'standard' | The variant of the MUI TextField. |
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={(event) => {
1340
- console.log("Masked value:", event.target.value);
1341
- console.log("Clean value:", event.target.cleanValue);
1342
- console.log("Raw input:", event.target.rawValue);
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 "react";
1383
- import { Formik, Form, Field, FormikHelpers, FormikErrors } from "formik";
1384
- import Container from "@mui/material/Container";
1385
- import Typography from "@mui/material/Typography";
1386
- import Box from "@mui/material/Box";
1387
- import Button from "@mui/material/Button";
1388
- import { Grid } from "@mui/material";
1389
- import Paper from "@mui/material/Paper";
1390
- import Alert from "@mui/material/Alert";
1391
- import { ThemeProvider, createTheme } from "@mui/material/styles";
1392
- import CssBaseline from "@mui/material/CssBaseline";
1393
- import { FormMaskField } from "form-input-mask-field";
1394
- import "./App.css";
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: "#1976d2",
1433
+ main: '#1976d2',
1422
1434
  },
1423
1435
  secondary: {
1424
- main: "#dc004e",
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 = "Phone number is required";
1435
- } else if (values.phone.replace(/\D/g, "").length < 10) {
1436
- errors.phone = "Phone number must be 10 digits";
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 = "Date is required";
1452
+ errors.date = 'Date is required';
1441
1453
  }
1442
1454
 
1443
1455
  if (!values.creditCard) {
1444
- errors.creditCard = "Credit card is required";
1445
- } else if (values.creditCard.replace(/\D/g, "").length < 16) {
1446
- errors.creditCard = "Credit card must be 16 digits";
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 = "License plate is required";
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
- values: FormValues,
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("Form submitted! Check console for values.");
1483
+ alert('Form submitted! Check console for values.');
1475
1484
  setSubmitting(false);
1476
1485
  }, 400);
1477
1486
  };
1478
1487
 
1479
- const handleCustomChange =
1480
- (fieldName: keyof FormValues) => (event: FormFieldEvent) => {
1481
- console.log(`${fieldName} changed:`, {
1482
- masked: event.target.value,
1483
- clean: event.target.cleanValue,
1484
- raw: event.target.rawValue,
1485
- });
1486
- return event;
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
- variant="subtitle1"
1499
- align="center"
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("phone")}
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("creditCard")}
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("licensePlate")}
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("customCode")}
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: "#f5f5f5",
1655
+ backgroundColor: '#f5f5f5',
1657
1656
  p: 2,
1658
1657
  borderRadius: 1,
1659
- overflow: "auto",
1660
- fontSize: "0.875rem",
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
- Object.keys(touched).length > 0 && (
1672
- <Grid>
1673
- <Alert severity="error">
1674
- <Typography variant="h6" gutterBottom>
1675
- Form Validation Errors:
1676
- </Typography>
1677
- <ul>
1678
- {Object.entries(errors).map(
1679
- ([field, error]) =>
1680
- touched[field] && (
1681
- <li key={field}>
1682
- <strong>{field}:</strong> {error}
1683
- </li>
1684
- )
1685
- )}
1686
- </ul>
1687
- </Alert>
1688
- </Grid>
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 ? "Submitting..." : "Submit Form"}
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
  [![Buy Me a book](https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png)](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.