UNPKG

pagamio-frontend-commons-lib

Version:

Pagamio library for Frontend reusable components like the form engine and table container

312 lines (311 loc) 10 kB
import type { Control, FieldErrors, FieldValues, RegisterOptions } from 'react-hook-form'; import type React from 'react'; export interface ActionProps { field: string; options?: SelectOption[] | string[]; value?: any; label?: string; hideField?: boolean; fieldInnitialData?: Field; validation?: ValidationRule; } export interface SelectOption { label: string; value: string; id?: number; } export interface BaseInputProps { field: Field; error?: { message?: string; }; value?: any; options?: Array<SelectOption | string>; onChange: (value: any) => void; onBlur?: () => void; name: string; ref?: React.Ref<any>; control?: Control<any>; } /** * Represents the state of a form, including validation errors and optional message */ export type FormState = { errors?: { name?: string[]; email?: string[]; password?: string[]; }; message?: string; } | undefined; /** * Defines the structure of control fields used in authentication forms */ export type ControlFields = { username: string; password: string; emailAddress?: string; profile?: string; role?: string; }; /** * Reference object exposing form control methods */ export interface FormRef { reset: () => void; setValue?: (name: string, value: any) => void; } /** * Props for the FormEngine component which handles form rendering and submission */ export interface FormEngineProps<T extends Record<string, any>> { /** Array of field definitions that make up the form */ fields: Field[]; /** Callback function called when the form is submitted */ onSubmit: (data: any) => Promise<void>; /** Layout direction of the form */ layout?: 'vertical' | 'horizontal'; /** Initial values for form fields */ initialValues?: any; /** Custom tailwind class for the Form Engine */ className?: string; /** Custom tailwind class for the submit button */ submitButtonClass?: string; /** Flag to disable automatic form submission trigger */ isNotTrigger?: boolean; /** Flag to show or hide the cancel button */ showCancelButton?: boolean; /** Flag dynamic display submit button text */ submitButtonText?: string; /** Show submitting indicator text */ showSubmittingText?: boolean; /** Callback function called when form cancellation is requested */ onCancel: () => void; /** Callback function called whenever a field value changes */ getFieldValues?: (fields: T) => void; /** Optional persistence key for form data */ persistenceKey?: string; /** * Optional ref to expose form control methods. * When not provided, the form will automatically reset after successful submission. * When provided, the parent component controls form reset behavior. */ formRef?: React.MutableRefObject<FormRef | undefined>; } /** * Defines validation rules that can be applied to form fields */ export type ValidationRule = { /** Required field validation with optional custom message */ required?: string | { value: boolean; message: string; }; /** Minimum value/length validation with message */ min?: { value: string | number; message: string; }; /** Pattern validation with message */ pattern?: { value: RegExp; message: string; }; /** Custom validation function */ validate?: (value: any) => boolean | string; /** Dependency validation - applies validation based on another field's value */ dependency?: DependencyValidation | DependencyValidation[]; }; /** * Defines a dependency validation rule */ export interface DependencyValidation { /** The field this validation depends on */ field: string; /** Condition function that determines if validation should be applied */ condition: (value: any) => boolean; /** Validation rules to apply when condition is true */ validationToApply: Omit<ValidationRule, 'dependency'>; } /** * Available field types supported by the form engine */ export type FieldType = 'card-expiry-input' | 'checkbox' | 'credit-card' | 'date' | 'email' | 'file' | 'multi-select' | 'number' | 'password' | 'radio' | 'searchable-multi-select' | 'select' | 'switch' | 'tel' | 'text' | 'textarea' | 'time'; /** * Defines the structure of a form field */ export interface Field { /** Field identifier */ name: string; /** Display label for the field */ label: string; /** Type of input field */ type: FieldType; /** Placeholder text for the field */ placeholder?: string; /** Number of grids a field will span */ gridSpan?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12; /** Whether the field is checked (for checkbox/switch types) */ checked?: boolean; /** To hide or show the upload button when the field is type file */ hideUploadButton?: boolean; /** To validate file types say .png, .pdf etc */ allowedFileTypes?: string[]; /** To hide or show a preview of uploaded image */ showFileUploadPreview?: boolean; /** To display file upload helper text */ fileUploadHelperText?: string; /** Default country for phone input */ defaultCountry?: string; /** Disables the field */ disabled?: boolean; /** Validation rules for the field */ validation?: ValidationRule; /** Options for select, multi-select, and radio fields */ options?: Array<SelectOption | string>; /** callback for searchable select, multi-select */ onSearch?: (value: string) => void; /** callback for onChange event */ onChange?: (value: string) => void; isHidden?: boolean; } export interface DependentFieldUpdate { field: string; dependencies?: string[]; action: (value: any, isInitialLoad?: boolean) => Promise<ActionProps> | ActionProps; } /** * Props for the Form component wrapper */ export interface FormProps { /** Array of field definitions */ fieldDefinitions: Field[]; /** Form submission handler */ onFormSubmit: (data: any) => void; /** Initial form values */ initialValues?: any; /** Form layout direction */ layout?: 'vertical' | 'horizontal'; /** Flag to disable automatic form submission */ isNotTrigger?: boolean; /** Flag to hide or show the cancel button */ showCancelButton?: boolean; /** Form cancellation handler */ onFormCancel: () => void; } /** * Props for the FieldWrapper component that provides layout and error handling */ export interface FieldWrapperProps { /** Field definition */ field: Field; /** React Hook Form control object */ control: Control; /** Form validation errors */ errors: FieldErrors; /** Layout direction */ layout: 'vertical' | 'horizontal'; /** All field values for dependency tracking */ allFieldValues?: Record<string, any>; /** Field update callbacks */ onFieldUpdate?: Record<string, DependentFieldUpdate[]>; /** Update field options callback */ updateFieldOptions?: (field: string, options: Array<SelectOption | string>) => void; /** Update field label callback */ updateFieldLabel?: (fieldName: string, newLabelName: string) => void; /** Hide field callback */ hideInputField?: (fieldName: string, hidden: boolean) => void; /** Add new field callback */ addField?: (field: Field) => void; /** Set value function from useForm */ setValue?: (name: string, value: any) => void; /** Clear errors function from useForm */ clearErrors?: (field: string) => void; /** Get values function from useForm */ getValues?: () => Record<string, any>; } /** * Props for basic input components */ export interface InputProps extends BaseInputProps { /** Field configuration */ field: Field; /** Validation error if any */ error?: { message: string; }; } /** * Props for input components with options (select, radio, etc.) */ export interface InputOptionsProps { /** Field configuration including validation rules */ field: { validation: Omit<RegisterOptions<FieldValues, string>, 'valueAsNumber' | 'valueAsDate' | 'setValueAs' | 'disabled'> | undefined; name: string; label: string; options: SelectOption[] | string[]; disabled?: boolean; }; /** Validation error if any */ error?: { message: string; }; /** React Hook Form control object */ control: Control<any>; } /** * Props for select input components */ export interface InputSelectProps extends BaseInputProps { /** Validation error if any */ error?: { message: string; }; } /** * Props for switch/toggle input components */ export interface InputSwitchProps { /** Field configuration */ field: any; /** Validation error if any */ error?: { message: string; }; value?: boolean; onChange?: (checked: boolean) => void; } /** * Option structure for the searchable multi-select */ export interface SearchableMultiSelectOption { value: string; label: string; } /** * Form persistence context data structure */ export interface FormPersistenceData { /** Form field values */ values: Record<string, any>; /** Timestamp when the data was last updated */ lastUpdated: number; /** Whether the form is dirty (has changes) */ isDirty: boolean; } /** * Form persistence context type */ export interface FormPersistenceContextType { /** Get persisted form data by key */ getFormData: (key: string) => FormPersistenceData | null; /** Set persisted form data by key */ setFormData: (key: string, data: Partial<FormPersistenceData>) => void; /** Clear persisted form data by key */ clearFormData: (key: string) => void; /** Clear all persisted form data */ clearAllFormData: () => void; /** Check if form has persisted data */ hasFormData: (key: string) => boolean; }