78 lines
1.8 KiB
TypeScript
78 lines
1.8 KiB
TypeScript
import { h } from 'preact'
|
|
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
|
|
import cn from 'classnames'
|
|
|
|
/**
|
|
* @param {{
|
|
* base?: string
|
|
* touched?: string
|
|
* element?: string
|
|
* label?: string
|
|
* }} styles
|
|
* @returns {import('preact').FunctionComponent<{
|
|
* autoFocus?: boolean
|
|
* className?: string
|
|
* defaultChecked?: boolean
|
|
* disabled?: boolean
|
|
* name: string
|
|
* label?: string
|
|
* required?: boolean
|
|
* }>}
|
|
*/
|
|
export default function checkboxFactory(styles) {
|
|
const Checkbox = ({
|
|
autoFocus,
|
|
className,
|
|
defaultChecked,
|
|
disabled,
|
|
name,
|
|
label,
|
|
onChange,
|
|
required,
|
|
style = 'normal',
|
|
value = 'true',
|
|
}) => {
|
|
const [touched, setTouched] = useState(false)
|
|
const checkboxRef = useRef<HTMLInputElement>()
|
|
|
|
const onBlur = useCallback(() => setTouched(true), [])
|
|
|
|
useEffect(() => {
|
|
const form = checkboxRef.current.form
|
|
const resetTouched = setTouched.bind(null, false)
|
|
|
|
form.addEventListener('reset', resetTouched)
|
|
|
|
return () => form.removeEventListener('reset', resetTouched)
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (autoFocus) checkboxRef.current.focus()
|
|
}, [autoFocus])
|
|
|
|
return (
|
|
<label className={cn(styles.base, styles[style], touched && styles.touched, className)}>
|
|
<input
|
|
autoFocus={autoFocus}
|
|
className={styles.element}
|
|
defaultChecked={defaultChecked}
|
|
disabled={disabled}
|
|
name={name}
|
|
onBlur={onBlur}
|
|
onChange={onChange}
|
|
ref={checkboxRef}
|
|
required={required}
|
|
type='checkbox'
|
|
value={value}
|
|
/>
|
|
|
|
<i />
|
|
|
|
{label && <span className={styles.label}>{label}</span>}
|
|
</label>
|
|
)
|
|
}
|
|
|
|
return Checkbox
|
|
}
|