import { h, type FunctionComponent } from 'preact' import { useCallback, useEffect, useRef, useState } from 'preact/hooks' import cn from 'classnames' import escapeRegex from '../utils/escape_regex.ts' export default function inputFactory(styles: { base?: string touched?: string element?: string label?: string statusIcon?: string noMargin?: string icon?: string labelIcon?: string center?: string }): FunctionComponent<{ autoFocus?: boolean autoComplete?: string className?: string defaultValue?: string disabled?: boolean name: string noMargin?: boolean label: string pattern?: string placeholder?: string required?: boolean type?: string showValidity?: boolean }> { const Input = ({ autoComplete, autoFocus, center, className, classNames, color, defaultValue, design, disabled, icon, label, name, noMargin, pattern, placeholder, required, sameAs, size = 'medium', type = 'text', value, showValidity = true, }) => { const [touched, setTouched] = useState(false) const inputRef = useRef() const onBlur = useCallback(() => setTouched(true), []) useEffect(() => { function onInput(e) { inputRef.current!.pattern = escapeRegex(e.target.value) } const form = inputRef.current!.form const resetTouched = setTouched.bind(null, false) form.addEventListener('reset', resetTouched) let sameAsInput if (sameAs) { sameAsInput = form[sameAs] sameAsInput.addEventListener('input', onInput) } return () => { form.removeEventListener('reset', resetTouched) if (sameAsInput) sameAsInput.removeEventListener('input', onInput) } }, []) useEffect(() => { if (autoFocus) inputRef.current.focus() }, [autoFocus]) const id = styles.element + '_' + name return (
{icon && (styles.icon || classNames?.icon) && (
)} {showValidity && } {/** *