form-input-fields 1.0.15 → 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 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 @your-org/form-fields @mui/material @emotion/react @emotion/styled formik @mui/x-date-pickers dayjs
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 | 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. |
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={(values) => console.log(values)}
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: "(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}"
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 | 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. |
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={(values) => console.log(values)}
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: "YYYY-MM-DD",
454
- long: "MM/DD/YYYY hh:mm A",
455
- custom: "DD MMMM YYYY hh:mm A",
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: "DD/MM/YYYY",
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: "MM/YYYY",
472
- long: "MMMM YYYY",
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-mask-field/date";
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 "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";
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={(values) => console.log(values)}
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("Selected date:", value);
532
- console.log("Formatted value:", context.formattedValue);
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, "day")}
603
- maxDate={dayjs().add(3, "month")}
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("Selected date:", value);
631
- console.log("Formatted value:", context.formattedValue);
632
- console.log("Validation error:", context.validationError);
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("Events cannot be scheduled on Sundays");
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-mask-field';
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 | 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') |
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={(e) => setNotificationsEnabled(e.target.checked)}
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={(values) => console.log('Form values:', values)}
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={(e) => form.setFieldValue(field.name, e.target.checked)}
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={(e) => form.setFieldValue(field.name, e.target.checked)}
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((theme) => ({
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 | 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 |
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 | 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 |
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={(values) => console.log('Form values:', values)}
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={(values) => {
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={(values) => console.log(values)}
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: "YYYY-MM-DD",
1039
- long: "MM/DD/YYYY hh:mm A",
1040
- custom: "DD MMMM YYYY hh:mm A"
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: "DD/MM/YYYY"
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: "MM/YYYY",
1057
- long: "MMMM YYYY"
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
- 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>
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 | 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 |
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 | 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 |
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={(values) => {
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 "formik";
1227
- import { FormMaskField } from "form-input-mask-field";
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 | 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. |
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={(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);
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 "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";
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: "#1976d2",
1429
+ main: '#1976d2',
1422
1430
  },
1423
1431
  secondary: {
1424
- main: "#dc004e",
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 = "Phone number is required";
1435
- } else if (values.phone.replace(/\D/g, "").length < 10) {
1436
- errors.phone = "Phone number must be 10 digits";
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 = "Date is required";
1448
+ errors.date = 'Date is required';
1441
1449
  }
1442
1450
 
1443
1451
  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";
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 = "License plate is required";
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
- values: FormValues,
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("Form submitted! Check console for values.");
1479
+ alert('Form submitted! Check console for values.');
1475
1480
  setSubmitting(false);
1476
1481
  }, 400);
1477
1482
  };
1478
1483
 
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
- };
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
- 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
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("phone")}
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("creditCard")}
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("licensePlate")}
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("customCode")}
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: "#f5f5f5",
1651
+ backgroundColor: '#f5f5f5',
1657
1652
  p: 2,
1658
1653
  borderRadius: 1,
1659
- overflow: "auto",
1660
- fontSize: "0.875rem",
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
- 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
- )}
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 ? "Submitting..." : "Submit Form"}
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
  [![Buy Me a book](https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png)](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.