Skip to content

Instantly share code, notes, and snippets.

@meesvandongen
Created July 3, 2020 20:08
Show Gist options
  • Save meesvandongen/c983281e0edd066dfb0de6734214060b to your computer and use it in GitHub Desktop.
Save meesvandongen/c983281e0edd066dfb0de6734214060b to your computer and use it in GitHub Desktop.
import React, { useEffect, useRef } from "react";
type TextInputProps = {
onChange: (value: string) => void;
value: string;
id?: string;
type: "text";
};
type NumberInputProps = {
onChange: (value: number) => void;
value: number;
id?: string;
type: "number";
};
type GenericInputProps = TextInputProps | NumberInputProps;
const isNumberInput = (
genericInputProps: GenericInputProps
): genericInputProps is NumberInputProps => {
return genericInputProps.type === "number";
};
export const GenericInput = (props: GenericInputProps) => {
const ref = useRef<HTMLInputElement>(null);
// For undo functionality, we have to listen to changes and set state manually when redux updates. (on blur, on undo, on redo)
useEffect(() => {
if (ref.current) {
if (typeof props.value === "number") {
ref.current.value = String(props.value);
} else {
ref.current.value = props.value;
}
}
}, [props.value]);
return (
<input
ref={ref}
type={props.type}
id={props.id}
className="border-gray-500 border-2 p-2 rounded"
onBlur={(e) => {
const val = e.target.value;
if (isNumberInput(props)) {
props.onChange(Number(val));
} else {
props.onChange(val);
}
}}
defaultValue={props.value}
/>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment