koval-ui
Version:
React components collection with minimalistic design. Supports theming, layout, and input validation.
1 lines • 6.96 kB
Source Map (JSON)
{"version":3,"file":"InputFile.cjs","sources":["../../../../src/lib/InputFile/InputFile.tsx"],"sourcesContent":["import type {ChangeEvent, InputHTMLAttributes} from 'react';\nimport {useMemo} from 'react';\nimport {useState} from 'react';\nimport {forwardRef, useCallback} from 'react';\nimport classNames from 'classnames';\nimport {useLocalTheme} from 'css-vars-hook';\n\nimport {IconFile} from '@/internal/Icons';\nimport type {DataAttributes, LibraryProps} from '@/internal/LibraryAPI';\nimport type {NativePropsTextual, CallbackPropsTextual, ValidationProps} from '@/internal/inputs';\nimport {\n useRevalidateOnFormChange,\n useExternalValidation,\n useValidationIcon,\n ValidationState,\n useValidation,\n} from '@/internal/inputs';\nimport {useInternalId} from '@/internal/hooks/useInternalId.ts';\nimport {useInternalRef} from '@/internal/hooks/useInternalRef.ts';\n\nimport classes from './InputFile.module.css';\n\nexport type Props = DataAttributes &\n LibraryProps &\n Omit<NativePropsTextual, 'inputMode' | 'maxLength' | 'minLength' | 'pattern' | 'readOnly'> &\n ValidationProps &\n CallbackPropsTextual & {\n accept?: InputHTMLAttributes<HTMLInputElement>['accept'];\n multiple?: InputHTMLAttributes<HTMLInputElement>['multiple'];\n };\n\nexport const InputFile = forwardRef<HTMLInputElement, Props>(\n (\n {\n id: idProp,\n className,\n placeholder = '',\n disabled,\n value,\n onChange = () => {},\n onFocus = () => {},\n onBlur = () => {},\n onKeyDown = () => {},\n onKeyUp = () => {},\n defaultValue,\n size = 16,\n errorMessage,\n revalidateOnFormChange,\n validation,\n displayIcon = true,\n ...nativeProps\n },\n ref\n ) => {\n const {LocalRoot} = useLocalTheme();\n const theme = useMemo(\n () => ({\n 'input-width': `${size}ch`,\n }),\n [size]\n );\n\n const id = useInternalId(idProp);\n const [filename, setFileName] = useState('');\n const hasValidators = Boolean(validation);\n const {validateTextual, validity, setValidity} = useValidation({\n validation,\n hasValidators,\n });\n const inputRef = useInternalRef(ref);\n useExternalValidation({errorMessage, inputRef, setValidity, validation});\n useRevalidateOnFormChange(inputRef, validateTextual, revalidateOnFormChange);\n\n const ValidationIcon = useValidationIcon(validity);\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n onChange(event);\n setFileName(event.target.files![0].name);\n },\n [onChange, setFileName]\n );\n\n const handleInvalid = useCallback(() => {\n setFileName('');\n setValidity(ValidationState.error);\n }, [setValidity]);\n return (\n <LocalRoot\n theme={theme}\n className={classNames(\n classes['input-file'],\n {[classes.withValidationIcon]: displayIcon},\n className\n )}>\n <div className={classes.toggle}>\n <input\n {...nativeProps}\n id={id}\n type=\"file\"\n placeholder={placeholder}\n className={classes.input}\n ref={inputRef}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n onKeyUp={onKeyUp}\n onKeyDown={onKeyDown}\n onInvalid={handleInvalid}\n onInput={validateTextual}\n />\n <IconFile className={classNames(classes.icon)} />\n </div>\n <label htmlFor={id} className={classes.label}>\n {filename || placeholder}\n </label>\n {displayIcon && validity && <ValidationIcon className={classes.validity} />}\n </LocalRoot>\n );\n }\n);\n\nInputFile.displayName = 'InputFile';\n"],"names":["InputFile","forwardRef","idProp","className","placeholder","disabled","value","onChange","onFocus","onBlur","onKeyDown","onKeyUp","defaultValue","size","errorMessage","revalidateOnFormChange","validation","displayIcon","nativeProps","ref","LocalRoot","useLocalTheme","theme","useMemo","id","useInternalId","filename","setFileName","useState","hasValidators","validateTextual","validity","setValidity","useValidation","inputRef","useInternalRef","useExternalValidation","useRevalidateOnFormChange","ValidationIcon","useValidationIcon","handleChange","useCallback","event","handleInvalid","ValidationState","jsxs","classNames","classes","jsx","IconFile"],"mappings":"2qBA+BaA,EAAYC,EAAA,WACrB,CACI,CACI,GAAIC,EACJ,UAAAC,EACA,YAAAC,EAAc,GACd,SAAAC,EACA,MAAAC,EACA,SAAAC,EAAW,IAAM,CAAC,EAClB,QAAAC,EAAU,IAAM,CAAC,EACjB,OAAAC,EAAS,IAAM,CAAC,EAChB,UAAAC,EAAY,IAAM,CAAC,EACnB,QAAAC,EAAU,IAAM,CAAC,EACjB,aAAAC,EACA,KAAAC,EAAO,GACP,aAAAC,EACA,uBAAAC,EACA,WAAAC,EACA,YAAAC,EAAc,GACd,GAAGC,GAEPC,IACC,CACK,KAAA,CAAC,UAAAC,CAAS,EAAIC,gBAAc,EAC5BC,EAAQC,EAAA,QACV,KAAO,CACH,cAAe,GAAGV,CAAI,IAAA,GAE1B,CAACA,CAAI,CACT,EAEMW,EAAKC,gBAAcvB,CAAM,EACzB,CAACwB,EAAUC,CAAW,EAAIC,EAAAA,SAAS,EAAE,EACrCC,EAAgB,EAAQb,EACxB,CAAC,gBAAAc,EAAiB,SAAAC,EAAU,YAAAC,CAAA,EAAeC,EAAAA,cAAc,CAC3D,WAAAjB,EACA,cAAAa,CAAA,CACH,EACKK,EAAWC,iBAAehB,CAAG,EACnCiB,EAAAA,sBAAsB,CAAC,aAAAtB,EAAc,SAAAoB,EAAU,YAAAF,EAAa,WAAAhB,EAAW,EAC7CqB,4BAAAH,EAAUJ,EAAiBf,CAAsB,EAErE,MAAAuB,EAAiBC,oBAAkBR,CAAQ,EAC3CS,EAAeC,EAAA,YAChBC,GAAyC,CACtCnC,EAASmC,CAAK,EACdf,EAAYe,EAAM,OAAO,MAAO,CAAC,EAAE,IAAI,CAC3C,EACA,CAACnC,EAAUoB,CAAW,CAC1B,EAEMgB,EAAgBF,EAAAA,YAAY,IAAM,CACpCd,EAAY,EAAE,EACdK,EAAYY,kBAAgB,KAAK,CAAA,EAClC,CAACZ,CAAW,CAAC,EAEZ,OAAAa,EAAA,KAACzB,EAAA,CACG,MAAAE,EACA,UAAWwB,EACPC,EAAAA,QAAQ,YAAY,EACpB,CAAC,CAACA,EAAAA,QAAQ,kBAAkB,EAAG9B,CAAW,EAC1Cd,CACJ,EACA,SAAA,CAAC0C,EAAA,KAAA,MAAA,CAAI,UAAWE,EAAAA,QAAQ,OACpB,SAAA,CAAAC,EAAA,IAAC,QAAA,CACI,GAAG9B,EACJ,GAAAM,EACA,KAAK,OACL,YAAApB,EACA,UAAW2C,EAAQ,QAAA,MACnB,IAAKb,EACL,SAAA7B,EACA,MAAAC,EACA,aAAAM,EACA,SAAU4B,EACV,OAAA/B,EACA,QAAAD,EACA,QAAAG,EACA,UAAAD,EACA,UAAWiC,EACX,QAASb,CAAA,CACb,QACCmB,EAAS,SAAA,CAAA,UAAWH,EAAWC,EAAAA,QAAQ,IAAI,CAAG,CAAA,CAAA,EACnD,EACAC,EAAAA,IAAC,SAAM,QAASxB,EAAI,UAAWuB,EAAQ,QAAA,MAClC,YAAY3C,CACjB,CAAA,EACCa,GAAec,GAAYiB,MAACV,EAAe,CAAA,UAAWS,UAAQ,QAAU,CAAA,CAAA,CAAA,CAC7E,CAAA,CAGZ,EAEA/C,EAAU,YAAc"}