form-input-fields
v1.0.24
Published
A customizable form field components built with TypeScript
Maintainers
Readme
Form Fields Components
A collection of Material-UI form field components with Formik integration.
Version 1.0.21
More control in the progress of development.
Storybook
View interactive examples and documentation at: https://formik-input-fields.netlify.app/
Installation
Prerequisites
Before installing the form-input-fields package, make sure you have the following peer dependencies installed in your project:
- React 16.8.0 or later
- React DOM 16.8.0 or later
- Material-UI (MUI) 5.0.0 or later
- Formik 2.0.0 or later
- @mui/x-date-pickers 6.0.0 or later
- dayjs 1.11.0 or later
Using npm
npm install form-input-fields @mui/material @emotion/react @emotion/styled formik @mui/x-date-pickers dayjsUsing yarn
yarn add form-input-fields @mui/material @emotion/react @emotion/styled formik @mui/x-date-pickers dayjsUsing pnpm
pnpm add form-input-fields @mui/material @emotion/react @emotion/styled formik @mui/x-date-pickers dayjsPeer Dependencies
Make sure your project includes these peer dependencies:
{
"devDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
"@mui/material": "^5.0.0",
"@emotion/react": "^11.0.0",
"@emotion/styled": "^11.0.0",
"formik": "^2.0.0",
"@mui/x-date-pickers": "^6.0.0",
"dayjs": "^1.11.0"
}
}TypeScript
This package includes TypeScript type definitions. No additional type packages are needed.
Browser Support
The form fields support all modern browsers including:
- Chrome (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- Edge (latest 2 versions)
For Internet Explorer 11 support, you'll need to include polyfills. See Browser Support for more details.
Next Steps
After installation, you can import and use the components in your application:
import { FormTextField, FormDateField, FormMaskField, FormSwitch } from 'form-input-fields';Troubleshooting
If you encounter any issues during installation, try the following:
Clear your package manager's cache:
npm cache clean --force # or yarn cache clean # or pnpm store pruneDelete
node_modulesandpackage-lock.json(oryarn.lock/pnpm-lock.yaml)Reinstall dependencies:
npm install # or yarn install # or pnpm install
If you're still experiencing issues, please reach me at [email protected] with details about your environment and the error message you're seeing.
Table of Contents
- FormTextField
- FormDropDownField
- FormDateField
- FormMaskField
- FormCheckboxField
- FormSwitch
- FormDateTextField
- Styling Form Controls
- History
FormTextField
A versatile text input field component that integrates Material-UI's TextField with Formik form handling.
Features
- Seamless Formik Integration: Automatically handles form state, validation, and error messages
- Material-UI Styling: Consistent look and feel with Material Design
- TypeScript Support: Fully typed component with proper type definitions
- Flexible Props: Supports all standard TextField props from Material-UI
- Error Handling: Built-in error state management with Formik
- Responsive Design: Works well across different screen sizes
Basic Usage
import { Formik, Field } from 'formik';
import { FormTextField } from 'form-input-fields';
<Formik initialValues={{ username: '' }} onSubmit={values => console.log(values)}>
<Field
component={FormTextField}
name="username"
label="Username"
placeholder="Enter your username"
/>
</Formik>;Props
The FormTextField component accepts all props from FormTextFieldProps, FieldProps (Formik), and Material-UI's TextFieldProps.
FormTextFieldProps Interface
| Prop | Type | Default | Description |
| ---------- | -------------------------------------- | ------------ | -------------------------------------------------------------------------------------- |
| onChange | function | - | Custom change handler that overrides Formik's |
| onBlur | function | - | Custom blur handler that overrides Formik's |
| variant | 'standard' \| 'outlined' \| 'filled' | 'standard' | The variant of the MUI TextField. |
| sx | SxProps<Theme> | - | The system prop that allows defining system overrides as well as additional CSS styles |
Common Props (from FieldProps & TextFieldProps)
| Prop | Type | Required | Description |
| ------------ | ---------------- | -------- | --------------------------------------------- |
| name | string | Yes | Field name in Formik values |
| label | string | No | Field label |
| helperText | string | No | Custom helper text |
| error | boolean | No | Error state (auto-managed by Formik) |
| disabled | boolean | No | Disabled state |
| required | boolean | No | Required field indicator |
| type | string | 'text' | Input type (text, email, password, etc.) |
| Other | TextFieldProps | No | All Material-UI TextField props are supported |
Examples
Basic Text Input
<Field
component={FormTextField}
name="username"
label="Username"
placeholder="Enter your username"
fullWidth
margin="normal"
variant="outlined" // <-- Example with outlined variant
/>Text Field with Formik
<Formik
initialValues={{ email: '' }}
validate={values => {
const errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) {
errors.email = 'Invalid email address';
}
return errors;
}}
onSubmit={values => console.log(values)}
>
{({ errors, touched }) => (
<Field
component={FormTextField}
name="email"
label="Email"
type="email"
error={touched.email && Boolean(errors.email)}
helperText={touched.email && errors.email}
required
/>
)}
</Formik>Custom Validation
<Field
component={FormTextField}
name="password"
label="Password"
type="password"
inputProps={{
minLength: 8,
pattern: '(?=.*d)(?=.*[a-z])(?=.*[A-Z]).{8,}',
}}
helperText="Must contain at least 8 characters, including uppercase, lowercase, and numbers"
required
/>FormDropDownField
A customizable dropdown/select component that integrates Material-UI's Select with Formik form handling.
Features
- Seamless Formik Integration: Automatically handles form state, validation, and error messages
- Material-UI Styling: Consistent look and feel with Material Design
- TypeScript Support: Fully typed component with proper type definitions
- Flexible Data Binding: Works with array of objects with
idanddescriptionproperties - Optional Default Selection: Add a default "Select" option with customizable text
- Form Validation: Built-in error state management with Formik
- Responsive Design: Works well across different screen sizes
Basic Usage
import { Formik, Field } from 'formik';
import { FormDropDownField } from 'form-input-fields';
const items = [
{ id: '1', description: 'Option 1' },
{ id: '2', description: 'Option 2' },
{ id: '3', description: 'Option 3' },
];
<Formik initialValues={{ category: '' }} onSubmit={values => console.log(values)}>
<Field
component={FormDropDownField}
name="category"
label="Category"
items={items}
addInputSelect={true}
/>
</Formik>;Props
The FormDropDownField component accepts all props from FormDropDownFieldProps, FieldProps (Formik), and Material-UI's TextFieldProps (with some exceptions).
FormDropDownFieldProps Interface
| Prop | Type | Default | Description |
| ---------------- | ------------------------------------------------------ | ------------ | -------------------------------------------------------------------------------------- |
| items | Array<{ id: string \| number; description: string }> | [] | Array of items to display in the dropdown |
| addInputSelect | boolean | false | Whether to show a default "Select" option as the first item |
| selectText | string | 'Select' | Text to display for the default "Select" option |
| required | boolean | false | Whether the field is required |
| disabled | boolean | false | Whether the field is disabled |
| className | string | - | Custom class name for the root element |
| helperText | string | - | Helper text to display below the field |
| error | boolean | - | Error state of the field (overrides Formik error state) |
| onChange | (value: any) => void | - | Custom change handler |
| onBlur | (event: React.FocusEvent<HTMLInputElement>) => void | - | Custom blur handler |
| variant | 'standard' \| 'outlined' \| 'filled' | 'standard' | The variant of the MUI TextField. |
| sx | SxProps<Theme> | - | The system prop that allows defining system overrides as well as additional CSS styles |
Examples
Basic Dropdown
const items = [
{ id: 'us', description: 'United States' },
{ id: 'ca', description: 'Canada' },
{ id: 'uk', description: 'United Kingdom' },
];
<Field
component={FormDropDownField}
name="country"
label="Country"
items={items}
fullWidth
variant="outlined" // <-- Example with outlined variant
/>;Dropdown with Default Selection
<Field
component={FormDropDownField}
name="category"
label="Category"
items={categories}
addInputSelect={true}
selectText="Select a category"
helperText="Please select a category from the list"
/>Required Dropdown with Validation
<Formik
initialValues={{ department: '' }}
validationSchema={Yup.object({
department: Yup.string().required('Department is required'),
})}
onSubmit={values => console.log(values)}
>
{({ errors, touched }) => (
<Form>
<Field
component={FormDropDownField}
name="department"
label="Department"
items={departments}
addInputSelect={true}
required
error={touched.department && Boolean(errors.department)}
helperText={touched.department && errors.department}
/>
<Button type="submit" variant="contained" color="primary">
Submit
</Button>
</Form>
)}
</Formik>FormDateField
A date input field component with Material-UI and Formik integration, powered by MUI X Date Pickers.
Features
- Material-UI Integration: Consistent styling with other form components
- Formik Integration: Seamless form state management with error handling
- Day.js Support: Lightweight date library for date manipulation
- Custom Date Formatting: Flexible date display formats
- Date Validation: Built-in min/max date validation
- Read-Only Support: Can be configured as read-only
- TypeScript Support: Full type safety with exported interfaces
- Helper Text Display: Show date format or custom helper text
- Today Button: Optional today button in date picker
Available Date Formats
The component uses predefined date format constants from date.ts:
FORM_DATE_FORMAT
export const FORM_DATE_FORMAT = {
short: 'YYYY-MM-DD',
long: 'MM/DD/YYYY hh:mm A',
custom: 'DD MMMM YYYY hh:mm A',
};DATE_PICKER_DATE_FORMAT
export const DATE_PICKER_DATE_FORMAT = {
short: 'DD/MM/YYYY',
};DATE_PICKER_MONTH_YEAR_FORMAT
export const DATE_PICKER_MONTH_YEAR_FORMAT = {
short: 'MM/YYYY',
long: 'MMMM YYYY',
};Importing Date Constants
import {
FORM_DATE_FORMAT,
DATE_PICKER_DATE_FORMAT,
DATE_PICKER_MONTH_YEAR_FORMAT
} from "form-input-fields/date";
// Use predefined formats
<Field
component={FormDateField}
name="birthDate"
format={FORM_DATE_FORMAT.short} // 'YYYY-MM-DD'
/>
// Or use custom format
<Field
component={FormDateField}
name="eventDate"
format="DD/MM/YYYY HH:mm" // Custom format
/>Usage with Formik
import { Formik, Field } from 'formik';
import { FormDateField, FormDateFieldProps } from 'form-input-fields';
import { FORM_DATE_FORMAT } from 'form-input-fields/date';
import dayjs from 'dayjs';
<Formik
initialValues={{ birthDate: null, appointmentDate: null }}
onSubmit={values => console.log(values)}
>
{/* Basic usage */}
<Field
component={FormDateField}
name="birthDate"
label="Birth Date"
format={FORM_DATE_FORMAT.short}
/>
{/* Advanced usage with validation */}
<Field
component={FormDateField}
name="appointmentDate"
label="Appointment Date"
format="DD/MM/YYYY"
minDate={dayjs()}
disablePast={true}
showTodayButton={true}
showDateFormat={true}
onChange={(value, context) => {
console.log('Selected date:', value);
console.log('Formatted value:', context.formattedValue);
}}
/>
</Formik>;Props
The FormDateField component accepts all props from FormDateFieldProps, FieldProps, and TextFieldProps.
FormDateFieldProps Interface
| Prop | Type | Default | Description |
| ----------------- | ---------------- | ------------------------ | -------------------------------------------------------------------------------------- |
| format | string | FORM_DATE_FORMAT.short | Date format string using dayjs format tokens |
| minDate | Dayjs | - | Minimum selectable date |
| maxDate | Dayjs | - | Maximum selectable date |
| disablePast | boolean | false | Disable past dates |
| disableFuture | boolean | false | Disable future dates |
| showTodayButton | boolean | false | Show today button in the picker |
| readOnly | boolean | false | Make the field read-only |
| showDateFormat | boolean | false | Show the date format as helper text |
| onChange | function | - | Custom change handler with additional context |
| sx | SxProps<Theme> | - | The system prop that allows defining system overrides as well as additional CSS styles |
Common Props (from FieldProps & TextFieldProps)
| Prop | Type | Required | Description |
| ------------ | ---------------- | -------- | --------------------------------------------- |
| name | string | Yes | Field name in Formik values |
| label | string | No | Field label |
| helperText | string | No | Custom helper text |
| error | boolean | No | Error state |
| disabled | boolean | No | Disabled state |
| Other | TextFieldProps | No | All Material-UI TextField props are supported |
Examples
Basic Date Input
<Field component={FormDateField} name="birthDate" label="Birth Date" format="DD/MM/YYYY" />Date with Validation
<Field
component={FormDateField}
name="startDate"
label="Start Date"
minDate={dayjs()}
disablePast={true}
showDateFormat={true}
helperText="Select a future date"
/>Appointment Scheduler
<Field
component={FormDateField}
name="appointmentDate"
label="Appointment Date"
format="DD MMMM YYYY"
minDate={dayjs().add(1, 'day')}
maxDate={dayjs().add(3, 'month')}
showTodayButton={true}
showDateFormat={true}
/>Read-Only Date Display
<Field
component={FormDateField}
name="createdDate"
label="Created Date"
format="DD/MM/YYYY HH:mm"
readOnly={true}
/>Custom Change Handler
<Field
component={FormDateField}
name="eventDate"
label="Event Date"
format="YYYY-MM-DD"
onChange={(value, context) => {
console.log('Selected date:', value);
console.log('Formatted value:', context.formattedValue);
console.log('Validation error:', context.validationError);
// Custom logic here
if (value && value.day() === 0) {
alert('Events cannot be scheduled on Sundays');
}
}}
/>Date Range (Start/End Dates)
<Field
component={FormDateField}
name="startDate"
label="Start Date"
format="DD/MM/YYYY"
maxDate={values.endDate ? dayjs(values.endDate) : undefined}
/>
<Field
component={FormDateField}
name="endDate"
label="End Date"
format="DD/MM/YYYY"
minDate={values.startDate ? dayjs(values.startDate) : undefined}
/>FormCheckboxField
A customizable checkbox component with Material-UI and Formik integration, providing consistent styling and behavior across your application.
Features
- Material-UI Integration: Consistent styling with Material-UI's design system
- Formik Integration: Seamless form state management with error handling
- Custom Styling: Easy customization through Material-UI's styling system
- TypeScript Support: Full type safety with exported interfaces
- Accessibility: Built with accessibility in mind, following WAI-ARIA guidelines
- Responsive Design: Works well on all screen sizes
Basic Usage
import { Formik, Field } from 'formik';
import { FormCheckboxField } from 'form-input-fields';
// Basic usage
<FormCheckboxField
id="terms"
label="I agree to the terms and conditions"
checked={false}
onChange={(e) => console.log('Checked:', e.target.checked)}
/>
// With Formik
<Formik
initialValues={{ termsAccepted: false }}
onSubmit={(values) => console.log(values)}
>
{({ values }) => (
<Field
name="termsAccepted"
component={({ field, form }) => (
<FormCheckboxField
{...field}
label="I agree to the terms and conditions"
checked={field.value}
onChange={(e) => {
form.setFieldValue(field.name, e.target.checked);
}}
/>
)}
/>
)}
</Formik>Props
The FormCheckboxField component accepts all props from FormCheckboxFieldProps and Material-UI's CheckboxProps.
FormCheckboxFieldProps Interface
| Prop | Type | Default | Description |
| ---------------- | ---------- | --------- | ------------------------------------------------------- |
| id | string | - | Unique identifier for the checkbox |
| label | string | - | Label text displayed next to the checkbox |
| checked | boolean | false | Whether the checkbox is checked |
| onChange | function | - | Callback when checkbox state changes |
| disabled | boolean | false | Disable the checkbox |
| required | boolean | false | Mark the field as required |
| color | string | 'primary' | Color of the checkbox when checked |
| size | string | 'medium' | Size of the checkbox ('small' or 'medium') |
| labelPlacement | string | 'end' | Position of the label ('end', 'start', 'top', 'bottom') |
Examples
Basic Checkbox
<FormCheckboxField
id="notifications"
label="Enable email notifications"
checked={notificationsEnabled}
onChange={e => setNotificationsEnabled(e.target.checked)}
color="secondary"
/>Checkbox with Formik
<Formik
initialValues={{
termsAccepted: false,
newsletter: true,
notifications: false,
}}
onSubmit={values => console.log('Form values:', values)}
>
{({ values }) => (
<Form>
<Field
name="termsAccepted"
component={({ field, form }) => (
<FormCheckboxField
{...field}
label="I agree to the terms and conditions"
checked={field.value}
onChange={e => form.setFieldValue(field.name, e.target.checked)}
required
/>
)}
/>
<Field
name="newsletter"
component={({ field, form }) => (
<FormCheckboxField
{...field}
label="Subscribe to newsletter"
checked={field.value}
onChange={e => form.setFieldValue(field.name, e.target.checked)}
color="secondary"
/>
)}
/>
<Button type="submit" variant="contained" color="primary">
Submit
</Button>
</Form>
)}
</Formik>Custom Styled Checkbox
import { makeStyles } from '@mui/styles';
const useStyles = makeStyles(theme => ({
root: {
margin: theme.spacing(1),
},
labelRoot: {
color: theme.palette.primary.main,
fontWeight: 500,
},
}));
function CustomCheckbox() {
const classes = useStyles();
return (
<FormCheckboxField
id="custom-checkbox"
label="Custom Styled Checkbox"
checked={false}
onChange={() => {}}
classes={{
root: classes.root,
label: classes.labelRoot,
}}
color="primary"
/>
);
}FormSwitch
A customizable switch component with Material-UI and Formik integration, providing consistent styling and behavior for boolean inputs across your application.
Features
- Material-UI Integration: Consistent styling with Material-UI's design system
- Formik Integration: Seamless form state management with error handling
- Flexible Label Placement: Support for different label positions
- TypeScript Support: Full type safety with exported interfaces
- Accessibility: Built with accessibility in mind, following WAI-ARIA guidelines
- Error Handling: Built-in error state management with Formik
- Responsive Design: Works well on all screen sizes
Basic Usage
import { Formik, Field } from 'formik';
import { FormSwitch } from 'form-input-fields';
// Basic usage
<FormSwitch
label="Enable Notifications"
checked={notificationsEnabled}
onChange={(e, checked) => setNotificationsEnabled(checked)}
/>
// With Formik
<Formik
initialValues={{ notifications: false }}
onSubmit={(values) => console.log(values)}
>
<Field
component={FormSwitch}
name="notifications"
label="Enable Notifications"
helperText="Receive email notifications"
/>
</Formik>Props
The FormSwitch component accepts all props from FormSwitchProps, FieldProps (Formik), and Material-UI's SwitchProps.
FormSwitchProps Interface
| Prop | Type | Default | Description |
| ---------------- | ---------------- | --------- | --------------------------------------------------------------------------------------- |
| label | string | - | Label text displayed next to the switch |
| labelPlacement | string | 'end' | Position of label ('top', 'start', 'bottom', 'end') |
| color | string | 'primary' | Switch color ('primary', 'secondary', 'error', 'info', 'success', 'warning', 'default') |
| size | string | 'medium' | Switch size ('small' or 'medium') |
| disabled | boolean | false | Disable the switch |
| required | boolean | false | Mark the field as required |
| onChange | function | - | Custom change handler with context data |
| onBlur | function | - | Custom blur handler |
| helperText | string | - | Helper text to display below the switch |
| error | boolean | false | Error state of the switch |
| className | string | - | Custom class name for the root element |
| sx | SxProps<Theme> | - | The system prop that allows defining system overrides as well as additional CSS styles |
Common Props (from FieldProps & SwitchProps)
| Prop | Type | Required | Description |
| ------------ | ------------- | -------- | ------------------------------------------ |
| name | string | Yes | Field name in Formik values |
| label | string | No | Field label |
| helperText | string | No | Custom helper text |
| error | boolean | No | Error state (auto-managed by Formik) |
| disabled | boolean | No | Disabled state |
| required | boolean | No | Required field indicator |
| Other | SwitchProps | No | All Material-UI Switch props are supported |
Examples
Basic Switch
<FormSwitch
label="Enable Dark Mode"
checked={darkModeEnabled}
onChange={(e, checked) => setDarkModeEnabled(checked)}
color="secondary"
size="small"
/>Switch with Formik
<Formik
initialValues={{
notifications: false,
darkMode: true,
autoSave: false,
}}
onSubmit={values => console.log('Form values:', values)}
>
<Form>
<Field
component={FormSwitch}
name="notifications"
label="Enable Notifications"
helperText="Receive email notifications"
color="primary"
/>
<Field
component={FormSwitch}
name="darkMode"
label="Dark Mode"
helperText="Use dark theme"
color="secondary"
labelPlacement="start"
/>
<Field
component={FormSwitch}
name="autoSave"
label="Auto Save"
helperText="Automatically save changes"
color="success"
size="small"
/>
<Button type="submit" variant="contained" color="primary">
Save Settings
</Button>
</Form>
</Formik>Custom Styled Switch
<FormSwitch
label="Custom Styled Switch"
checked={false}
onChange={(e, checked) => console.log('Switch toggled:', checked)}
className="custom-switch-class"
color="warning"
labelPlacement="top"
helperText="This is a custom styled switch"
/>Switch with Custom Change Handler
<Field
component={FormSwitch}
name="advancedMode"
label="Advanced Mode"
onChange={(e, checked, context) => {
console.log('Field name:', context.fieldName);
console.log('Formik value:', context.formikValue);
// Custom logic here
}}
helperText="Enable advanced features"
/>Switch with Validation
<Formik
initialValues={{ termsAccepted: false }}
validate={values => {
const errors = {};
if (!values.termsAccepted) {
errors.termsAccepted = 'You must accept the terms to continue';
}
return errors;
}}
onSubmit={values => console.log(values)}
>
<Form>
<Field
component={FormSwitch}
name="termsAccepted"
label="I accept the terms and conditions"
helperText="Please read and accept the terms"
required
/>
<Button type="submit" variant="contained" color="primary">
Continue
</Button>
</Form>
</Formik>FormDateTextField
A versatile date input field component that provides a text-based date picker with Formik integration and Material-UI styling.
Features
- Formik Integration: Seamlessly works with Formik for form state management
- Material-UI Styling: Consistent look and feel with Material Design
- Flexible Date Formatting: Supports custom date formats using day.js
- TypeScript Support: Fully typed component with proper type definitions
- Responsive Design: Works well across different screen sizes
- Accessibility: Built with accessibility in mind
Available Date Formats
The component uses predefined date format constants from date.ts:
FORM_DATE_FORMAT
export const FORM_DATE_FORMAT = {
short: 'YYYY-MM-DD',
long: 'MM/DD/YYYY hh:mm A',
custom: 'DD MMMM YYYY hh:mm A',
};DATE_PICKER_DATE_FORMAT
export const DATE_PICKER_DATE_FORMAT = {
short: 'DD/MM/YYYY',
};DATE_PICKER_MONTH_YEAR_FORMAT
export const DATE_PICKER_MONTH_YEAR_FORMAT = {
short: 'MM/YYYY',
long: 'MMMM YYYY',
};Basic Usage
import { Formik, Field } from 'formik';
import { FormDateTextField } from 'form-input-fields';
<Formik initialValues={{ eventDate: '' }} onSubmit={values => console.log(values)}>
<Field component={FormDateTextField} name="eventDate" label="Event Date" format="MM/DD/YYYY" />
</Formik>;Props
The FormDateTextField component accepts all props from FormDateTextFieldProps, FieldProps (Formik), and Material-UI's TextFieldProps (with some exclusions).
FormDateTextFieldProps Interface
| Prop | Type | Default | Description |
| ------------ | ----------------------------------------------------- | ----------------------- | -------------------------------------------------------------------------------------- |
| format | string | FORM_DATE_FORMAT.long | Date format string using day.js tokens |
| required | boolean | false | Whether the field is required |
| disabled | boolean | false | Whether the field is disabled |
| className | string | - | Custom class name for the root element |
| helperText | string | - | Helper text to display below the field |
| error | boolean | - | Error state of the field |
| onChange | (value: Dayjs \| null) => void | - | Custom change handler |
| onBlur | (event: React.FocusEvent<HTMLInputElement>) => void | - | Custom blur handler |
| sx | SxProps<Theme> | - | The system prop that allows defining system overrides as well as additional CSS styles |
Common Props (from FieldProps & TextFieldProps)
| Prop | Type | Required | Description |
| ------------- | ------------------------------- | -------- | --------------------------------------------------------------- |
| name | string | Yes | Field name in Formik values |
| label | string | No | Label for the input field |
| placeholder | string | No | Placeholder text |
| fullWidth | boolean | No | If true, the input will take up the full width of its container |
| margin | 'none' \| 'dense' \| 'normal' | No | If 'dense' or 'normal', will adjust vertical spacing |
| size | 'small' \| 'medium' | No | The size of the text field |
Examples
Basic Date Text Input
<FormDateTextField
name="birthDate"
label="Birth Date"
format="YYYY-MM-DD"
helperText="Enter your date of birth"
required
/>Date Text Field with Formik
import { Formik, Form, Field } from 'formik';
import { FormDateTextField, FormTextField } from 'form-input-fields';
import { Button } from '@mui/material';
const EventForm = () => (
<Formik
initialValues={{
eventName: '',
eventDate: '',
}}
onSubmit={values => {
console.log('Form submitted:', values);
}}
>
{({ isSubmitting }) => (
<Form>
<Field
name="eventName"
label="Event Name"
component={FormTextField}
fullWidth
margin="normal"
/>
<Field
component={FormDateTextField}
name="eventDate"
label="Event Date"
format="MM/DD/YYYY"
required
helperText="Select the event date"
margin="normal"
/>
<Button type="submit" variant="contained" color="primary" disabled={isSubmitting}>
Submit
</Button>
</Form>
)}
</Formik>
);Custom Date Format
<FormDateTextField
name="appointmentTime"
label="Appointment Time"
format="dddd, MMMM D, YYYY h:mm A"
helperText="Example: Monday, January 1, 2023 2:30 PM"
required
/>Disabled State
<FormDateTextField
name="purchaseDate"
label="Purchase Date"
value="2023-05-15"
disabled
helperText="This field cannot be modified"
/>With Error State
<FormDateTextField
name="expiryDate"
label="Expiry Date"
error={!!errors.expiryDate && touched.expiryDate}
helperText={touched.expiryDate && errors.expiryDate}
format="MM/DD/YYYY"
required
/>FormMaskField
A flexible form field component with advanced text masking capabilities.
Features
- Material-UI Integration: Consistent styling with other form components
- Formik Integration: Seamless form state management
- Flexible Masking: Pattern-based input masking with multiple character types
- Uppercase Conversion: Automatic text transformation
- TypeScript Support: Full type safety and IntelliSense
- Clean Value Option: Return masked or unmasked values to form state
Usage with Formik
import { Formik, Field } from 'formik';
import { FormMaskField } from 'form-input-fields';
<Formik initialValues={{ phoneNumber: '', gameCode: '' }} onSubmit={values => console.log(values)}>
<Field
component={FormMaskField}
name="phoneNumber"
label="Phone Number"
mask="(999) 999-9999"
placeholder="Enter phone number"
/>
<Field
component={FormMaskField}
name="gameCode"
label="Game Code"
mask="AAAAA"
toUpperCase={true}
returnCleanValue={true}
/>
</Formik>;Mask Pattern Characters
| Character | Description | Example |
| --------- | ---------------------------- | ------------------------ |
| 9 | Digit (0-9) | 999-99-9999 for SSN |
| A | Letter (a-z, A-Z) | AAA for country code |
| * | Alphanumeric (a-z, A-Z, 0-9) | ***-*** for mixed code |
| a | Lowercase letter (a-z) | aaa for lowercase only |
| Z | Uppercase letter (A-Z) | ZZZ for uppercase only |
| # | Hexadecimal (0-9, A-F, a-f) | ###### for hex color |
| Any other | Literal character | -, (, ), /, etc. |
Props
| Prop | Type | Default | Description |
| ------------------ | -------------------------------------- | ------------ | -------------------------------------------------------------------------------------- |
| mask | string | - | Mask pattern using the characters above |
| placeholderChar | string | '_' | Character shown in placeholder for mask positions |
| toUpperCase | boolean | false | Convert input to uppercase automatically |
| returnCleanValue | boolean | false | Return unmasked value to Formik (true) or masked value (false) |
| showMaskPattern | boolean | false | Show the mask pattern as helper text below the input field |
| showPlaceholder | boolean | false | Show placeholder text with mask pattern in the input field |
| onChange | function | - | Custom change handler with masked, clean, and raw values |
| variant | 'standard' \| 'outlined' \| 'filled' | 'standard' | The variant of the MUI TextField. |
| sx | SxProps<Theme> | - | The system prop that allows defining system overrides as well as additional CSS styles |
Plus all standard Material-UI TextField props and Formik FieldProps.
FormMaskFieldProps Interface
| Prop | Type | Default | Description |
| ------------------ | -------------------------------------- | ------------ | -------------------------------------------------------------------------------------- |
| mask | string | - | Mask pattern using the characters above |
| placeholderChar | string | '_' | Character shown in placeholder for mask positions |
| toUpperCase | boolean | false | Convert input to uppercase automatically |
| returnCleanValue | boolean | false | Return unmasked value to Formik (true) or masked value (false) |
| showMaskPattern | boolean | false | Show the mask pattern as helper text below the input field |
| showPlaceholder | boolean | false | Show placeholder text with mask pattern in the input field |
| onChange | function | - | Custom change handler with masked, clean, and raw values |
| variant | 'standard' \| 'outlined' \| 'filled' | 'standard' | The variant of the MUI TextField. |
| sx | SxProps<Theme> | - | The system prop that allows defining system overrides as well as additional CSS styles |
Examples
Phone Number
<Field
component={FormMaskField}
name="phone"
label="Phone Number"
mask="(999) 999-9999"
placeholder="(555) 123-4567"
variant="outlined" // <-- Example with outlined variant
/>Date Input
<Field
component={FormMaskField}
name="date"
label="Date"
mask="99/99/9999"
placeholder="MM/DD/YYYY"
/>Product Code (Uppercase)
<Field
component={FormMaskField}
name="productCode"
label="Product Code"
mask="AAA-999-AAA"
toUpperCase={true}
returnCleanValue={true}
/>Credit Card
<Field
component={FormMaskField}
name="creditCard"
label="Credit Card"
mask="9999 9999 9999 9999"
placeholder="1234 5678 9012 3456"
/>Custom Change Handler
<Field
component={FormMaskField}
name="customField"
label="Custom Field"
mask="999-AAA"
onChange={event => {
console.log('Masked value:', event.target.value);
console.log('Clean value:', event.target.cleanValue);
console.log('Raw input:', event.target.rawValue);
}}
variant="outlined" // <-- Example with outlined variant
/>Show Mask Pattern
<Field
component={FormMaskField}
name="gameCode"
label="Game Code"
mask="AAA-999"
showMaskPattern={true}
toUpperCase={true}
/>
// This will show "Pattern: AAA-999" as helper text below the inputShow Placeholder
<Field
component={FormMaskField}
name="phoneNumber"
label="Phone Number"
mask="(999) 999-9999"
showPlaceholder={true}
/>
// This will show "(___) ___-____" as placeholder text in the input fieldComplete Example Application
Here's a comprehensive example showing how to build a complete form application using FormMaskField with Material-UI and Formik:
App.tsx
import React from 'react';
import { Formik, Form, Field, FormikHelpers, FormikErrors } from 'formik';
import Container from '@mui/material/Container';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import { Grid } from '@mui/material';
import Paper from '@mui/material/Paper';
import Alert from '@mui/material/Alert';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { FormMaskField } from 'form-input-fields';
import './App.css';
interface FormValues {
phone: string;
date: string;
creditCard: string;
licensePlate: string;
hexColor: string;
customCode: string;
socialSecurity: string;
postalCode: string;
}
interface FormFieldEvent extends Omit<React.ChangeEvent<HTMLInputElement>, 'target'> {
target: HTMLInputElement & {
value: string;
cleanValue: string;
rawValue: string;
name: string;
};
}
// Create a Material-UI theme
const theme = createTheme({
palette: {
primary: {
main: '#1976d2',
},
secondary: {
main: '#dc004e',
},
},
});
// Validation schema
const validateForm = (values: FormValues): FormikErrors<FormValues> => {
const errors: Partial<FormValues> = {};
if (!values.phone) {
errors.phone = 'Phone number is required';
} else if (values.phone.replace(/\D/g, '').length < 10) {
errors.phone = 'Phone number must be 10 digits';
}
if (!values.date) {
errors.date = 'Date is required';
}
if (!values.creditCard) {
errors.creditCard = 'Credit card is required';
} else if (values.creditCard.replace(/\D/g, '').length < 16) {
errors.creditCard = 'Credit card must be 16 digits';
}
if (!values.licensePlate) {
errors.licensePlate = 'License plate is required';
}
return errors;
};
function App() {
const initialValues: FormValues = {
phone: '',
date: '',
creditCard: '',
licensePlate: '',
hexColor: '',
customCode: '',
socialSecurity: '',
postalCode: '',
};
const handleSubmit = (values: FormValues, { setSubmitting }: FormikHelpers<FormValues>) => {
console.log('Form Values:', values);
setTimeout(() => {
alert('Form submitted! Check console for values.');
setSubmitting(false);
}, 400);
};
const handleCustomChange = (fieldName: keyof FormValues) => (event: FormFieldEvent) => {
console.log(`${fieldName} changed:`, {
masked: event.target.value,
clean: event.target.cleanValue,
raw: event.target.rawValue,
});
return event;
};
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Container maxWidth="lg" sx={{ py: 4 }}>
<Typography variant="h3" component="h1" gutterBottom align="center">
FormMaskField Demo
</Typography>
<Typography variant="subtitle1" align="center" color="text.secondary" paragraph>
A comprehensive example showcasing the FormMaskField component with various mask patterns
and configurations
</Typography>
<Formik initialValues={initialValues} validate={validateForm} onSubmit={handleSubmit}>
{({ values, isSubmitting, errors, touched }) => (
<Form>
<Grid container spacing={3}>
{/* Basic Masks Section */}
<Grid>
<Paper elevation={2} sx={{ p: 3 }}>
<Typography variant="h5" gutterBottom>
Basic Input Masks
</Typography>
<Grid container spacing={2}>
<Grid>
<Field
name="phone"
component={FormMaskField}
label="Phone Number"
mask="(999) 999-9999"
showMaskPattern={true}
showPlaceholder={true}
helperText="US phone number format"
onChange={handleCustomChange('phone')}
variant="outlined" // <-- Example with outlined variant
/>
</Grid>
<Grid>
<Field
name="date"
component={FormMaskField}
label="Date"
mask="99/99/9999"
showMaskPattern={true}
showPlaceholder={true}
helperText="MM/DD/YYYY format"
/>
</Grid>
<Grid>
<Field
name="socialSecurity"
component={FormMaskField}
label="Social Security Number"
mask="999-99-9999"
showMaskPattern={true}
showPlaceholder={true}
returnCleanValue={true}
helperText="Clean value returned (no dashes)"
/>
</Grid>
<Grid>
<Field
name="postalCode"
component={FormMaskField}
label="ZIP Code"
mask="99999-9999"
showMaskPattern={true}
showPlaceholder={true}
helperText="US ZIP+4 format"
/>
</Grid>
</Grid>
</Paper>
</Grid>
{/* Advanced Masks Section */}
<Grid>
<Paper elevation={2} sx={{ p: 3 }}>
<Typography variant="h5" gutterBottom>
Advanced Input Masks
</Typography>
<Grid container spacing={2}>
<Grid>
<Field
name="creditCard"
component={FormMaskField}
label="Credit Card Number"
mask="9999-9999-9999-9999"
showMaskPattern={true}
showPlaceholder={true}
helperText="16-digit credit card number"
onChange={handleCustomChange('creditCard')}
/>
</Grid>
<Grid>
<Field
name="licensePlate"
component={FormMaskField}
label="License Plate"
mask="AAA-999"
toUpperCase={true}
showMaskPattern={true}
showPlaceholder={true}
helperText="3 letters + 3 numbers (auto uppercase)"
onChange={handleCustomChange('licensePlate')}
/>
</Grid>
<Grid>
<Field
name="hexColor"
component={FormMaskField}
label="Hex Color Code"
mask="#######"
toUpperCase={true}
showMaskPattern={true}
showPlaceholder={true}
placeholderChar="0"
helperText="6-digit hex color code"
/>
</Grid>
<Grid>
<Field
name="customCode"
component={FormMaskField}
label="Custom Code"
mask="**-999-AA"
toUpperCase={true}
returnCleanValue={true}
showMaskPattern={true}
showPlaceholder={true}
helperText="Alphanumeric + digits + letters"
onChange={handleCustomChange('customCode')}
/>
</Grid>
</Grid>
</Paper>
</Grid>
{/* Current Values Display */}
<Grid>
<Paper elevation={2} sx={{ p: 3 }}>
<Typography variant="h5" gutterBottom>
Current Form Values
</Typography>
<Box sx={{ mt: 2 }}>
<Typography
variant="body2"
component="pre"
sx={{
backgroundColor: '#f5f5f5',
p: 2,
borderRadius: 1,
overflow: 'auto',
fontSize: '0.875rem',
}}
>
{JSON.stringify(values, null, 2)}
</Typography>
</Box>
</Paper>
</Grid>
{/* Form Errors Display */}
{Object.keys(errors).length > 0 && Object.keys(touched).length > 0 && (
<Grid>
<Alert severity="error">
<Typography variant="h6" gutterBottom>
Form Validation Errors:
</Typography>
<ul>
{Object.entries(errors).map(
([field, error]) =>
touched[field] && (
<li key={field}>
<strong>{field}:</strong> {error}
</li>
),
)}
</ul>
</Alert>
</Grid>
)}
{/* Submit Button */}
<Grid>
<Box sx={{ display: 'flex', justifyContent: 'center', mt: 2 }}>
<Button
type="submit"
variant="contained"
size="large"
disabled={isSubmitting}
sx={{ minWidth: 200 }}
>
{isSubmitting ? 'Submitting...' : 'Submit Form'}
</Button>
</Box>
</Grid>
</Grid>
</Form>
)}
</Formik>
</Container>
</ThemeProvider>
);
}
export default App;App.css
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}Key Features Demonstrated
This example application showcases:
- Complete Form Integration: Full Formik integration with validation and error handling
- Multiple Mask Types: Phone numbers, dates, credit cards, license plates, hex colors, and custom codes
- Advanced Features:
- Uppercase conversion (
toUpperCase) - Clean value return (
returnCleanValue) - Custom placeholder characters (
placeholderChar) - Pattern display (
showMaskPattern) - Placeholder display (
showPlaceholder)
- Uppercase conversion (
- Custom Event Handling: onChange handlers that provide masked, clean, and raw values
- Material-UI Integration: Consistent styling with Material-UI theme and components
- Real-time Validation: Form validation with error display
- Live Value Display: Real-time display of current form values
- Responsive Layout: Grid-based responsive layout
Running the Example
To run this example:
- Install dependencies:
npm install - Start the development server:
npm run dev - Open your browser and navigate to the local development URL
- Interact with the form fields to see the masking in action
- Open browser console to see custom onChange event data
The example demonstrates how FormMaskField seamlessly integrates with existing Material-UI and Formik workflows while providing powerful input masking capabilities.
Support
If you like my work, you can support me here:
Testing
This package includes comprehensive test coverage for all form controls, ensuring reliability and proper functionality. Tests are written using Jest and React Testing Library.
Test Coverage
- FormTextField: 100+ test cases covering basic rendering, input handling, Formik integration, error handling, accessibility, and sx prop support
- FormDropDownField: Complete test suite for dropdown functionality, validation, and styling
- FormDateField: Tests for date picker integration, validation, and formatting
- FormDateTextField: Text-based date input testing with various formats
- FormMaskField: Extensive masking functionality tests including pattern validation and custom handlers
- FormCheckboxField: Checkbox state management and Formik integration tests
- FormSwitch: Switch component testing with various configurations
Running Tests
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
# Run tests in debug mode
npm run test:debugHistory
2025-11-11 - Storybook Documentation Site Created
Added interactive Storybook documentation at https://formik-input-fields.netlify.app
Created comprehensive Storybook documentation for all form field components:
- FormTextField: Stories for basic usage, variants, error states, and custom styling
- FormCheckboxField: Interactive checkbox examples with state management
- FormDateField: Date picker stories with various configurations and constraints
- FormDateTextField: Text-based date input with format variations
- FormDropDownField: Dropdown examples with default selections and validation
- FormMaskField: Extensive masking examples (phone, date, credit card, license plate, hex colors)
- FormSwitch: Switch component stories with different colors, sizes, and placements
- Form Fields Demo: Complete interactive demo showcasing all components in a comprehensive form
The Storybook site provides:
- Interactive component examples with live controls
- Comprehensive documentation for all props and features
- Real-time code generation showing implementation details
- Responsive design testing across different screen sizes
- Accessibility testing and validation
2025-11-10 - Enhanced Styling Support and Standardized Form Controls
Added sx prop support to all form controls
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:
FormTextFieldFormCheckboxFieldFormDateFieldFormDateTextFieldFormDropDownFieldFormMaskFieldFormSwitch
The sx prop follows Material-UI's sx system, allowing you to use CSS properties, theme values, and responsive design patterns.
Standardized FormControl wrapper pattern
All form controls now use a standardized FormControl wrapper pattern, ensuring consistent behavior, accessibility, and styling across all form components. This provides:
- Consistent structure across all form controls
- Improved accessibility with proper labeling and ARIA attributes
- Unified error display and management
- Better integration with Material-UI's styling system
- Enhanced Formik form state management
Added variant prop to controls
The following controls now accept a variant prop ('standard' | 'outlined' | 'filled'), which is passed to the underlying MUI TextField. The default is 'standard':
FormTextFieldFormDropDownFieldFormMaskField
This allows you to easily switch between Material-UI's standard, outlined, and filled input styles for these components.
Styling Form Controls
sx Prop Support
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.
Benefits of the sx Prop
- Direct Styling: Apply styles without creating separate CSS files or styled components
- Theme Integration: Access to your Material-UI theme values (colors, spacing, breakpoints)
- **Responsive Desi

