T
TanStack3w ago
flat-fuchsia

generic Input element

i have this generic input element i register with the form, and reduces a whole lot of boilerplate, basically i pass down the field and then setup everything else as is, and is configurable from top down the issue is that this really is only working for fields that hold string | number values in the form i have a more complex field that's an array of objects. the field will only track one of the fields, and then i'll have basically a encode decode cycle where input reads value from form => encode to string => onchange code reads value from input => decode and map onto object this feels non-trivial to tack onto this generic component, and leads me to wonder if i'm overthinking it and there might be more straightforward way to handle this (without needing to recreate the below in every form field)
type SharedInputFromFieldProps<T extends string | number> = {
field: ReturnType<typeof useFieldContext<T>>;
transform?: (value: string) => T;
} & React.ComponentProps<typeof Input>;

export function SharedInputFromField<T extends string | number>(
props: SharedInputFromFieldProps<T>,
) {
const { className, field, transform, ...rest } = props;
return (
<Input
autoComplete="off"
id={field.name}
name={field.name}
value={field.state.value}
onChange={(e) => {
field.handleChange(
transform?.(e.target.value) ?? (e.target.value as T),
);
}}
onBlur={field.handleBlur}
className={cn("hover:bg-secondary/80", className)}
{...rest}
/>
);
}
type SharedInputFromFieldProps<T extends string | number> = {
field: ReturnType<typeof useFieldContext<T>>;
transform?: (value: string) => T;
} & React.ComponentProps<typeof Input>;

export function SharedInputFromField<T extends string | number>(
props: SharedInputFromFieldProps<T>,
) {
const { className, field, transform, ...rest } = props;
return (
<Input
autoComplete="off"
id={field.name}
name={field.name}
value={field.state.value}
onChange={(e) => {
field.handleChange(
transform?.(e.target.value) ?? (e.target.value as T),
);
}}
onBlur={field.handleBlur}
className={cn("hover:bg-secondary/80", className)}
{...rest}
/>
);
}
1 Reply
flat-fuchsia
flat-fuchsiaOP3w ago
nvm, didn't even realize there was an array mode.

Did you find this page helpful?