diff options
Diffstat (limited to 'src/components/shared/Input.tsx')
| -rw-r--r-- | src/components/shared/Input.tsx | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/components/shared/Input.tsx b/src/components/shared/Input.tsx new file mode 100644 index 0000000..901aeb5 --- /dev/null +++ b/src/components/shared/Input.tsx @@ -0,0 +1,42 @@ +import cx from 'clsx'; +import React from 'react'; + +import s0 from './Input.module.scss'; + +const { useState, useRef, useEffect, useCallback } = React; + +export default function Input({ + className, + ...props +}: React.InputHTMLAttributes<HTMLInputElement>) { + return <input className={cx(s0.input, className)} {...props} />; +} + +export function SelfControlledInput({ + value, + className, + ...restProps +}: React.InputHTMLAttributes<HTMLInputElement>) { + const [internalValue, setInternalValue] = useState(value); + const refValue = useRef(value); + useEffect(() => { + if (refValue.current !== value) { + // ideally we should only do this when this input is not focused + setInternalValue(value); + } + refValue.current = value; + }, [value]); + const onChange = useCallback( + (e: React.ChangeEvent<HTMLInputElement>) => setInternalValue(e.target.value), + [setInternalValue], + ); + + return ( + <input + className={cx(s0.input, className)} + value={internalValue} + onChange={onChange} + {...restProps} + /> + ); +} |
