Skip to content

Instantly share code, notes, and snippets.

@swissmanu
Last active January 16, 2019 08:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swissmanu/fec6008a2aa44f301fd696439af0f67b to your computer and use it in GitHub Desktop.
Save swissmanu/fec6008a2aa44f301fd696439af0f67b to your computer and use it in GitHub Desktop.
function Input<T>({
value,
onChange,
children,
serialize,
deserialize
}: {
value: T;
deserialize: (value: T) => string | null;
serialize: (rawValue: string | null) => T;
onChange: (value: T) => void;
children: (
props: { value: T; rawValue: string; onChange: (e: React.SyntheticEvent) => void }
) => React.ReactElement<{}>;
}) {
return children({
value,
rawValue: deserialize(value),
onChange: (e: React.SyntheticEvent) => {
e.preventDefault();
onChange(serialize((e.target as HTMLInputElement).value));
}
});
}
function TextInput({ value, onChange }: { value: string; onChange: (value: string) => void }) {
return (
<Input value={value} onChange={onChange} serialize={r => r} deserialize={v => v}>
{p => <input value={p.rawValue} onChange={p.onChange} type="text" />}
</Input>
);
}
function BooleanInput({ value, onChange }: { value: boolean; onChange: (value: boolean) => void }) {
return (
<Input value={value} onChange={onChange} serialize={r => r === 'true'} deserialize={v => (v ? 'true' : 'false')}>
{p => <input checked={p.value} onChange={p.onChange} value="true" type="checkbox" />}
</Input>
);
}
function NumberInput({ value, onChange }: { value: number; onChange: (value: number) => void }) {
return (
<Input value={value} onChange={onChange} serialize={r => Number.parseInt(r, 10)} deserialize={v => `${v}`}>
{(p) => <input value={p.rawValue} onChange={p.onChange} type="number" />}
</Input>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment