summaryrefslogtreecommitdiff
path: root/src/components/shared/Input.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/shared/Input.tsx')
-rw-r--r--src/components/shared/Input.tsx42
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}
+ />
+ );
+}