UNPKG

@syncfusion/react-inputs

Version:

Syncfusion React Input package is a feature-rich collection of UI components, including Textbox, Textarea, Numeric-textbox and Form, designed to capture user input in React applications.

469 lines (468 loc) 16.3 kB
import * as React from 'react'; import { FormHTMLAttributes } from 'react'; /** * Specifies the possible value types for form fields. */ export type FormValueType = string | number | boolean | Date | File | FileList | string[] | number[] | React.ReactNode | null | undefined; /** * Defines the structure for a validation rule in the form system. * * A ValidationRule is a two-part array containing: * - A validation condition (as boolean, RegExp, number, function, etc.) * - An optional custom error message to show when validation fails * * The first element's type depends on the specific rule: * - For boolean rules (like 'required'): true/false * - For pattern rules (like 'email', 'regex'): RegExp object * - For range rules: number or number[] (min/max values) * - For equality checks: string (field name to compare with) * - For custom validation: () => boolean function * * ```tsx * const requiredRule: ValidationRule = [true, 'This field is required']; * ``` */ export type ValidationRule = [boolean | RegExp | number | number[] | string | Date | (() => boolean), string?]; /** * Defines the comprehensive set of validation rules that can be applied to form fields. * * This interface outlines all available validation types that can be configured for * each field in the form. Each validation type accepts a ValidationRule containing * both the validation criteria and an optional custom error message. */ export interface FieldValidationRules { /** * Validates that the field has a non-empty value. When configured with [true], the field cannot be empty, null, or undefined. * * ```tsx * required: [true, 'This field must be filled in'] * ``` */ required?: ValidationRule; /** * Validates that the input conforms to a standard email address format. Checks for proper formatting with @ symbol and domain structure. * * ```tsx * email: [true, 'Please enter a valid email address'] * ``` */ email?: ValidationRule; /** * Validates that the input is a properly formatted URL. Checks for proper protocol, domain structure, and path format. * * ```tsx * url: [true, 'Please enter a valid website URL'] * ``` */ url?: ValidationRule; /** * Validates that the input can be parsed as a valid date. Uses Date.parse() to validate the string can be converted to a date. * * ```tsx * date: [true, 'Please enter a valid date'] * ``` */ date?: ValidationRule; /** * Validates that the input follows ISO date format (YYYY-MM-DD). Ensures strict compliance with the ISO date standard. * * ```tsx * dateIso: [true, 'Date must be in YYYY-MM-DD format'] * ``` */ dateIso?: ValidationRule; /** * Validates that the input contains a valid numeric value. Ensures the field can be converted to a number without errors. * * ```tsx * number: [true, 'Please enter a number'] * ``` */ number?: ValidationRule; /** * Validates that the input contains only numeric digits (0-9). Rejects inputs containing decimal points, signs, letter characters or spaces. * * ```tsx * digits: [true, 'Please enter only numeric digits'] * ``` */ digits?: ValidationRule; /** * Validates that the input is a valid credit card number. Checks length (13-16 digits) and applies Luhn algorithm validation. * * ```tsx * creditCard: [true, 'Invalid credit card number'] * ``` */ creditCard?: ValidationRule; /** * Validates that a string has at least the specified minimum length. Takes a number as the first parameter in the validation rule. * * ```tsx * minLength: [6, 'Must be at least 6 characters long'] * ``` */ minLength?: ValidationRule; /** * Validates that a string doesn't exceed the specified maximum length. Takes a number as the first parameter in the validation rule. * * ```tsx * maxLength: [100, 'Cannot exceed 100 characters'] * ``` */ maxLength?: ValidationRule; /** * Validates that a string's length falls within the specified range. Takes an array of two numbers [min, max] as the first parameter. * * ```tsx * rangeLength: [[8, 16], 'Must be between 8 and 16 characters'] * ``` */ rangeLength?: ValidationRule; /** * Validates that a numeric value is at least the specified minimum. Takes a number as the first parameter in the validation rule. * * ```tsx * min: [18, 'Value must be at least 18'] * ``` */ min?: ValidationRule; /** * Validates that a numeric value doesn't exceed the specified maximum. Takes a number as the first parameter in the validation rule. * * ```tsx * max: [100, 'Value cannot exceed 100'] * ``` */ max?: ValidationRule; /** * Validates that a numeric value falls within the specified range. Takes an array of two numbers [min, max] as the first parameter. * * ```tsx * range: [[1, 10], 'Value must be between 1 and 10'] * ``` */ range?: ValidationRule; /** * Validates that the input matches the specified regular expression pattern. Takes a RegExp object or a string pattern as the first parameter. * * ```tsx * regex: [/^[A-Z][a-z]+$/, 'Must start with capital letter followed by lowercase letters'] * ``` */ regex?: ValidationRule; /** * Validates that the input conforms to a standard telephone number format. Checks for proper formatting of phone numbers with optional country code. * * ```tsx * tel: [true, 'Please enter a valid phone number'] * ``` */ tel?: ValidationRule; /** * Validates that the field's value exactly matches another field's value. Takes the name of another field as the first parameter. * * ```tsx * equalTo: ['password', 'Passwords must match'] * ``` */ equalTo?: ValidationRule; /** * Allows for completely custom validation logic as a function. * * This function receives the field value and should return either: * - A string containing an error message if validation fails * - null if validation passes * * ```tsx * customValidator: (value) => { * if (typeof value === 'string' && !value.includes('@company.com')) { * return 'Email must be a company email'; * } * return null; * } * ``` */ customValidator?: (value: FormValueType) => string | null; } /** * Defines the complete validation schema for a form by mapping field names to their validation rules. * * This interface creates a dictionary where each key is a field name and each value * is an object containing all validation rules that apply to that field. The ValidationRules * object is passed to the Form component to establish the validation criteria for the entire form. * * ```tsx * const validationSchema: ValidationRules = { * username: { * required: [true, 'Username is required'], * minLength: [3, 'Username must be at least 3 characters'] * }, * * email: { * required: [true, 'Email is required'], * email: [true, 'Please enter a valid email address'] * } * }; * ``` */ export interface ValidationRules { [fieldName: string]: FieldValidationRules; } /** * Specifies the state and callback properties provided by the Form component. * * The FormState interface provides comprehensive access to the form's state * and behavior through the onFormStateChange callback. It allows parent components * to build custom form UIs with full access to validation state, field values, and form event handlers. */ export interface FormState { /** * Specifies the current values for all form fields indexed by field name. * Access individual values using: values.fieldName * * ```tsx * const username = formState.values.username; * ``` */ values: Record<string, FormValueType>; /** * Specifies the current validation errors for all fields indexed by field name. * Fields without errors won't appear in this object. * */ errors: Record<string, string>; /** * Specifies which fields in the form are valid (have no validation errors). * */ valid: Record<string, boolean>; /** * Specifies if the form can be submitted. True when all fields are valid; * otherwise, all fields are marked as touched when attempted to submit. */ allowSubmit: boolean; /** * Specifies if the form has been submitted at least once. * True after a submission attempt regardless of validation result. */ submitted: boolean; /** * Specifies which fields in the form have been modified from their initial values. * */ modified: Record<string, boolean>; /** * Specifies which fields have been touched (blurred after interaction). * Useful for determining when to display validation messages. * */ touched: Record<string, boolean>; /** * Specifies which fields have been visited (received focus). * */ visited: Record<string, boolean>; /** * Specifies a dictionary of field names for easy access to form fields. * */ fieldNames: Record<string, string>; /** * Specifies the callback function to handle field value changes. * Use this instead of directly modifying input elements. * * @param name - The name of the field to update * @param options - Object containing the new value for the field. * @event onChange */ onChange(name: string, options: { value: FormValueType; }): void; /** * Specifies the callback function for when a field loses focus. * * @param fieldName - The name of the field that lost focus. * @event onBlur */ onBlur(fieldName: string): void; /** * Specifies the callback function for when a field receives focus. * Records the field as visited. * * @param fieldName - The name of the field that received focus. * @event onFocus */ onFocus(fieldName: string): void; /** * Specifies the callback function to reset the form to its initial state. * Clears all values, errors, and interaction states. * * @event onFormReset */ onFormReset(): void; /** * Specifies the callback function to submit the form. * Can be used with a submit button's onClick event. * * @param event - The synthetic event from the form submission. * @event onSubmit */ onSubmit(event: React.SyntheticEvent): void; } /** * Specifies initial values for form fields. Maps field names to their default values when the form loads. * * ```tsx * const initialValues: FormInitialValues = { * username: 'john_doe' * }; * ``` */ export interface FormInitialValues { [fieldName: string]: FormValueType; } /** * Specifies the props interface for the Form component. */ export interface FormProps { /** * Specifies the validation rules for each form field. This object defines constraints that form fields must satisfy. */ rules: ValidationRules; /** * Specifies the callback fired when form is submitted and all validation rules pass. * * @param {Record<string, FormValueType>} data - Specifies the form data containing all field values * @event onSubmit */ onSubmit?: (data: Record<string, FormValueType>) => void; /** * Specifies the callback fired when form state changes. * This can be used to access form state from parent components for custom UI rendering. * * @param {FormState} formState - The current state of the form * @event onFormStateChange */ onFormStateChange?: (formState: FormState) => void; /** * Specifies the initial values for form fields. These values populate the form. * * @default - */ initialValues?: FormInitialValues; /** * Specifies whether to trigger validation on every input change. When true, validation occurs on each keystroke, providing immediate feedback. * * @default false */ validateOnChange?: boolean; } /** * Specifies the FormValidator interface for imperative methods. */ export interface IFormValidator extends FormProps { /** * Validates the entire form against all defined rules. * * @returns {boolean} - Returns true if the form is valid, false otherwise. */ validate(): boolean; /** * Resets the form to its initial state, clearing all values, errors, and interaction states. * * @returns {void} */ reset(): void; /** * Validates a specific field against its defined rules. * * @param {string} fieldName - Specifies the name of the field to validate * @returns {boolean} - Returns true if the field is valid, false otherwise */ validateField(fieldName: string): boolean; /** * Provides access to the underlying HTML form element. * * @private */ element?: HTMLFormElement; } type FormComponentProps = FormProps & Omit<FormHTMLAttributes<HTMLFormElement>, 'onSubmit'>; /** * Provides a form component with built-in validation functionality. Manages form state tracking, * field validation, and submission handling. * * ```typescript * import { Form, FormField, FormState } from '@syncfusion/react-inputs'; * * const [formState, setFormState] = useState<FormState>(); * * <Form * rules={{ username: { required: [true, 'Username is required'] } }} * onSubmit={data => console.log(data)} * onFormStateChange={setFormState} > * <FormField name="username"> * <input * name="username" * value={(formState?.values.username || '') as string} * onChange={(e) => formState?.onChange('username', { value: e.target.value })} * onBlur={() => formState?.onBlur('username')} * onFocus={() => formState?.onFocus('username')} * /> * {formState?.errors?.username && (<div className="error">{formState.errors.username}</div>)} * </FormField> * <button type="submit">Submit</button> * </Form> * ``` */ export declare const Form: React.ForwardRefExoticComponent<FormComponentProps & React.RefAttributes<IFormValidator>>; /** * Specifies the properties for the FormField component. */ export interface FormFieldProps { /** * Specifies the name of the field that must match a key in the rules object. This is required for proper validation. */ name: string; /** * Specifies the children content for the form field. Children should include the actual form control elements like inputs, textarea, etc. */ children: React.ReactNode; } /** * Specifies a component that connects form inputs with validation rules. The FormField component provides * an easy way to integrate form controls with the Form validation system, handling state management and * validation automatically. * * ```typescript * const [formState, setFormState] = useState<FormState>(); * * <Form * rules={{ * username: { required: [true, 'Username is required'] } * }} * onSubmit={data => console.log(data)} * onFormStateChange={setFormState} * > * <FormField name="username"> * <input * name="username" * value={formState?.values.username || ''} * onChange={(e) => formState?.onChange('username', { value: e.target.value })} * onBlur={() => formState?.onBlur('username')} * onFocus={() => formState?.onFocus('username')} * /> * {formState?.touched?.username && formState?.errors?.username && ( * <div className="error">{formState.errors.username}</div> * )} * </FormField> * <button type="submit">Submit</button> * </Form> * ``` * * @param {IFormFieldProps} props - Specifies the form field configuration properties * @returns {React.ReactNode} - Returns the children with access to form validation context */ export declare const FormField: React.FC<FormFieldProps>; export {};