Skip to content

Compound fields

Using fieldsets, we can create independent groups of fields, allowing us to interact with this group of fields almost like a form, or it can be perceived as lenses.

import { bindField, reatomComponent } from "@reatom/react";
import { reatomField, reatomFieldSet, wrap, throwAbort } from "@reatom/core";
const toNumber = (value: string) => {
const parsed = Number(value)
return isNaN(parsed) ? throwAbort() : parsed
}
const reatomMinMaxFieldSet = (name: string) => {
const min = reatomField(0, {
name: `${name}.min`,
fromState: (state) => state.toString(),
toState: toNumber,
validate: ({ state }) => state > max() ? "Min must be less than max" : undefined,
validateOnBlur: true,
});
const max = reatomField(100, {
name: `${name}.max`,
fromState: (state) => state.toString(),
toState: toNumber,
validate: ({ state }) => state <= 0 ? "Max must be greater than 0" : undefined,
validateOnBlur: true,
});
return reatomFieldSet({ min, max }, name);
};

Now we can interact with these fields as a single unit, calculating focus and validation states for all fields at once, or even resetting the value of each field with a single call to the reset method.

const minMaxFieldSet = reatomMinMaxFieldSet("minMaxFieldSet");
const Fields = reatomComponent(() => (
<fieldset>
<input {...bindField(minMaxFieldSet.fields.min)} />
<input {...bindField(minMaxFieldSet.fields.max)} />
{minMaxFieldSet.focus().dirty && (
<button onClick={wrap(() => minMaxFieldSet.reset())}>Reset</button>
)}
{minMaxFieldSet.validation().errors && (
<span>{minMaxFieldSet.validation().errors[0]?.message}</span>
)}
</fieldset>
));