UNPKG

koval-ui

Version:

React components collection with minimalistic design. Supports theming, layout, and input validation.

1 lines 8.91 kB
{"version":3,"file":"InputNumeric.cjs","sources":["../../../../src/lib/InputNumeric/InputNumeric.tsx"],"sourcesContent":["import type {ChangeEvent, KeyboardEvent, InputHTMLAttributes} from 'react';\nimport {forwardRef, useCallback} from 'react';\nimport classNames from 'classnames';\n\nimport type {DataAttributes, LibraryProps} from '@/internal/LibraryAPI';\nimport type {CallbackPropsTextual, ValidationProps, NativePropsTextual} from '@/internal/inputs';\nimport {\n useRevalidateOnFormChange,\n useExternalValidation,\n useValidationIcon,\n ValidationState,\n useValidation,\n} from '@/internal/inputs';\nimport {IconNumeric} from '@/internal/Icons';\nimport {useInternalId} from '@/internal/hooks/useInternalId.ts';\nimport {useInternalRef} from '@/internal/hooks/useInternalRef.ts';\n\nimport classes from './InputNumeric.module.css';\n\nenum Modes {\n natural = 'natural',\n integer = 'integer',\n floating = 'floating',\n scientific = 'scientific',\n}\n\nconst patternMapping = {\n [Modes.natural]: '(?:0|[1-9]\\\\d*)',\n [Modes.integer]: '[+\\\\-]?(?:0|[1-9]\\\\d*)',\n [Modes.floating]: '[+\\\\-]?(?:0|[1-9]\\\\d*)(?:\\\\.\\\\d+)?',\n [Modes.scientific]: '[+\\\\-]?(?:0|[1-9]\\\\d*)(?:\\\\.\\\\d+)?(?:[eE][+\\\\-]?\\\\d+)?',\n};\n\nexport type Props = DataAttributes &\n LibraryProps &\n Omit<NativePropsTextual, 'pattern' | 'inputMode' | 'autoComplete'> &\n CallbackPropsTextual &\n ValidationProps & {\n /**\n * Specify the amount of increment/decrement applied to the value when the user presses arrow keys\n */\n step?: number;\n /**\n * Define the width of the input in characters\n */\n size?: InputHTMLAttributes<HTMLInputElement>['size'];\n /** Select a mode of numeric input. `scientific` mode disables arrow stepper */\n mode?: keyof typeof Modes;\n };\n\nexport const InputNumeric = forwardRef<HTMLInputElement, Props>(\n (\n {\n className,\n placeholder = '',\n disabled,\n value,\n onChange = () => {},\n onFocus = () => {},\n onBlur = () => {},\n onKeyDown = () => {},\n onKeyUp = () => {},\n defaultValue,\n validation,\n errorMessage,\n id: idProp,\n step = 1,\n size = 12,\n mode = Modes.natural,\n revalidateOnFormChange,\n displayIcon = true,\n ...nativeProps\n },\n ref\n ) => {\n const inputRef = useInternalRef(ref);\n\n const id = useInternalId(idProp);\n\n const hasValidators = Boolean(validation) || Boolean(nativeProps.required);\n\n const {validateTextual, validity, setValidity} = useValidation({validation, hasValidators});\n\n useRevalidateOnFormChange(inputRef, validateTextual, revalidateOnFormChange);\n useExternalValidation({errorMessage, inputRef, setValidity, validation});\n\n const ValidationIcon = useValidationIcon(validity);\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n onChange(event);\n },\n [onChange]\n );\n\n const handleInvalid = useCallback(() => {\n setValidity(ValidationState.error);\n }, [setValidity]);\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n const inputValue = (event.target as HTMLInputElement).value;\n if (event.key === 'ArrowUp' && mode !== Modes.scientific) {\n const nextValue = Number(inputValue || 0) + step;\n (event.target as HTMLInputElement).value = nextValue.toString();\n }\n if (event.key === 'ArrowDown' && mode !== Modes.scientific) {\n const nextValue = Number(inputValue || 0) - step;\n (event.target as HTMLInputElement).value = nextValue.toString();\n }\n onKeyDown(event);\n },\n [mode, onKeyDown, step]\n );\n\n const handleKeyUp = useCallback(\n (event: KeyboardEvent<HTMLInputElement>) => {\n if (\n (event.key === 'ArrowDown' || event.key === 'ArrowUp') &&\n mode !== Modes.scientific\n ) {\n event.currentTarget.reportValidity();\n onChange(event as unknown as ChangeEvent<HTMLInputElement>);\n }\n onKeyUp(event);\n },\n [mode, onChange, onKeyUp]\n );\n\n const pattern = patternMapping[mode];\n\n return (\n <div\n className={classNames(\n classes.wrapper,\n {[classes.withValidationIcon]: displayIcon},\n className\n )}>\n <label className={classes.prefix} htmlFor={id}>\n <IconNumeric />\n </label>\n <input\n {...nativeProps}\n autoComplete=\"off\"\n ref={inputRef}\n size={size}\n id={id}\n type=\"text\"\n inputMode=\"decimal\"\n pattern={pattern}\n placeholder={placeholder}\n className={classes.input}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n onKeyUp={handleKeyUp}\n onKeyDown={handleKeyDown}\n onInvalid={handleInvalid}\n onInput={validateTextual}\n />\n {displayIcon && validity && <ValidationIcon />}\n </div>\n );\n }\n);\n\nInputNumeric.displayName = 'InputNumeric';\n"],"names":["patternMapping","InputNumeric","forwardRef","className","placeholder","disabled","value","onChange","onFocus","onBlur","onKeyDown","onKeyUp","defaultValue","validation","errorMessage","idProp","step","size","mode","revalidateOnFormChange","displayIcon","nativeProps","ref","inputRef","useInternalRef","id","useInternalId","hasValidators","validateTextual","validity","setValidity","useValidation","useRevalidateOnFormChange","useExternalValidation","ValidationIcon","useValidationIcon","handleChange","useCallback","event","handleInvalid","ValidationState","handleKeyDown","inputValue","nextValue","handleKeyUp","pattern","jsxs","classNames","classes","jsx","IconNumeric"],"mappings":"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"}