koval-ui
Version:
React components collection with minimalistic design. Supports theming, layout, and input validation.
1 lines • 7.3 kB
Source Map (JSON)
{"version":3,"file":"Form.cjs","sources":["../../../../src/lib/Form/Form.tsx"],"sourcesContent":["import {type ChangeEvent, useCallback} from 'react';\nimport {forwardRef} from 'react';\nimport type {ReactNode, SyntheticEvent, FormHTMLAttributes, InvalidEvent} from 'react';\nimport classNames from 'classnames';\n\nimport type {LibraryProps, DataAttributes} from '@/internal/LibraryAPI';\nimport {useInternalRef} from '@/internal/hooks/useInternalRef.ts';\n\nimport {withFormProvider} from './withFormProvider.tsx';\nimport classes from './Form.module.css';\nimport {useFormActions, useFormSelectors} from './useFormContext.ts';\n\ntype FormState = Record<string, FormDataEntryValue>;\n\ntype Props = DataAttributes &\n LibraryProps & {\n /**\n * Set the name of the HTMLFormElement.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/name\n */\n name?: FormHTMLAttributes<HTMLFormElement>['name'];\n /**\n * Define whether inputted text is automatically capitalized and, if so, in what manner.\n * Relevant for mobile devices with virtual keyboards or voice input\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autocapitalize\n */\n autoCapitalize?: FormHTMLAttributes<HTMLFormElement>['autoCapitalize'];\n /**\n * Control autocomplete behavior\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete\n */\n autoComplete?: FormHTMLAttributes<HTMLFormElement>['autoComplete'];\n /**\n * Disable validation\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#novalidate\n */\n noValidate?: FormHTMLAttributes<HTMLFormElement>['noValidate'];\n /**\n * Callback when the form was submitted. Gets form state as a second parameter\n */\n onSubmit?: (event: SyntheticEvent<HTMLFormElement>, formState: FormState) => void;\n /**\n * Callback when the form has failed validation. Gets form state as a second parameter\n */\n onInvalid?: (event: InvalidEvent<HTMLFormElement>, formState: FormState) => void;\n /**\n * Callback when the form was reset. Gets form state as a second parameter\n */\n onReset?: (event: ChangeEvent<HTMLFormElement>, formState: FormState) => void;\n /**\n * Callback when the form content was change. Gets form state as a second parameter\n */\n onChange?: (event: ChangeEvent<HTMLFormElement>, formState: FormState) => void;\n children: ReactNode;\n };\n\nconst Form = forwardRef<HTMLFormElement, Props>(\n (\n {\n className,\n children,\n onSubmit = () => {},\n onReset = () => {},\n onChange = () => {},\n onInvalid = () => {},\n ...nativeProps\n },\n ref\n ) => {\n const {markAsPristine, markAsDirty} = useFormActions();\n const getFormState = useCallback((formElement: EventTarget & HTMLFormElement) => {\n const data = new FormData(formElement);\n const formState: FormState = {};\n for (const [key, value] of data.entries()) {\n formState[key] = value;\n }\n return formState;\n }, []);\n const handleSubmit = useCallback(\n (event: SyntheticEvent<HTMLFormElement, SubmitEvent>) => {\n event.preventDefault();\n const form = event.currentTarget as HTMLFormElement;\n // const data = new FormData(form);\n // data.set('bar', 'bar');\n const formState = getFormState(form);\n onSubmit(event, formState);\n },\n [getFormState, onSubmit]\n );\n\n const handleError = useCallback(\n (event: InvalidEvent<HTMLFormElement>) => {\n markAsDirty();\n const formState = getFormState(event.currentTarget);\n onInvalid(event, formState);\n },\n [getFormState, markAsDirty, onInvalid]\n );\n\n const handleReset = useCallback(\n (event: ChangeEvent<HTMLFormElement>) => {\n const formState = getFormState(event.currentTarget);\n markAsPristine();\n onReset(event, formState);\n },\n [getFormState, onReset, markAsPristine]\n );\n\n const {pristine} = useFormSelectors();\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLFormElement>) => {\n pristine && markAsDirty();\n const formState = getFormState(event.currentTarget);\n onChange(event, formState);\n },\n [getFormState, onChange, markAsDirty, pristine]\n );\n\n const innerRef = useInternalRef<HTMLFormElement>(ref);\n return (\n <form\n {...nativeProps}\n autoFocus={true}\n onSubmit={handleSubmit}\n onInvalid={handleError}\n onReset={handleReset}\n onChange={handleChange}\n ref={innerRef}\n className={classNames(classes.form, className)}>\n {children}\n </form>\n );\n }\n);\n\nForm.displayName = 'Form';\n\nexport {Form as FormVanilla};\n\nconst WrappedForm = withFormProvider(Form);\n\nexport {WrappedForm as Form};\n"],"names":["Form","forwardRef","className","children","onSubmit","onReset","onChange","onInvalid","nativeProps","ref","markAsPristine","markAsDirty","useFormActions","getFormState","useCallback","formElement","data","formState","key","value","handleSubmit","event","form","handleError","handleReset","pristine","useFormSelectors","handleChange","innerRef","useInternalRef","jsx","classNames","classes","WrappedForm","withFormProvider"],"mappings":"2UAwDMA,EAAOC,EAAA,WACT,CACI,CACI,UAAAC,EACA,SAAAC,EACA,SAAAC,EAAW,IAAM,CAAC,EAClB,QAAAC,EAAU,IAAM,CAAC,EACjB,SAAAC,EAAW,IAAM,CAAC,EAClB,UAAAC,EAAY,IAAM,CAAC,EACnB,GAAGC,GAEPC,IACC,CACD,KAAM,CAAC,eAAAC,EAAgB,YAAAC,CAAW,EAAIC,iBAAe,EAC/CC,EAAeC,cAAaC,GAA+C,CACvE,MAAAC,EAAO,IAAI,SAASD,CAAW,EAC/BE,EAAuB,CAAC,EAC9B,SAAW,CAACC,EAAKC,CAAK,IAAKH,EAAK,UAC5BC,EAAUC,CAAG,EAAIC,EAEd,OAAAF,CACX,EAAG,EAAE,EACCG,EAAeN,EAAA,YAChBO,GAAwD,CACrDA,EAAM,eAAe,EACrB,MAAMC,EAAOD,EAAM,cAGbJ,EAAYJ,EAAaS,CAAI,EACnClB,EAASiB,EAAOJ,CAAS,CAC7B,EACA,CAACJ,EAAcT,CAAQ,CAC3B,EAEMmB,EAAcT,EAAA,YACfO,GAAyC,CAC1BV,EAAA,EACN,MAAAM,EAAYJ,EAAaQ,EAAM,aAAa,EAClDd,EAAUc,EAAOJ,CAAS,CAC9B,EACA,CAACJ,EAAcF,EAAaJ,CAAS,CACzC,EAEMiB,EAAcV,EAAA,YACfO,GAAwC,CAC/B,MAAAJ,EAAYJ,EAAaQ,EAAM,aAAa,EACnCX,EAAA,EACfL,EAAQgB,EAAOJ,CAAS,CAC5B,EACA,CAACJ,EAAcR,EAASK,CAAc,CAC1C,EAEM,CAAC,SAAAe,CAAQ,EAAIC,mBAAiB,EAC9BC,EAAeb,EAAA,YAChBO,GAAwC,CACrCI,GAAYd,EAAY,EAClB,MAAAM,EAAYJ,EAAaQ,EAAM,aAAa,EAClDf,EAASe,EAAOJ,CAAS,CAC7B,EACA,CAACJ,EAAcP,EAAUK,EAAac,CAAQ,CAClD,EAEMG,EAAWC,iBAAgCpB,CAAG,EAEhD,OAAAqB,EAAA,IAAC,OAAA,CACI,GAAGtB,EACJ,UAAW,GACX,SAAUY,EACV,UAAWG,EACX,QAASC,EACT,SAAUG,EACV,IAAKC,EACL,UAAWG,EAAWC,UAAQ,KAAM9B,CAAS,EAC5C,SAAAC,CAAA,CACL,CAAA,CAGZ,EAEAH,EAAK,YAAc,OAIb,MAAAiC,EAAcC,mBAAiBlC,CAAI"}