form-atoms / form-atoms

Atomic form primitives for Jotai

Home Page:https://codesandbox.io/s/getting-started-with-form-atoms-v2-ddhgq2?file=/src/App.tsx

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Boolean field atom does not fit `useFieldAtom` type.

MiroslavPetrik opened this issue · comments

Having atom with boolean value will display type error with the useFieldAtom

As a reproduction demo I have simple form with 2 checkbox inputs:
https://codesandbox.io/s/form-atoms-boolean-checkbox-field-9nv7jo?file=/src/components/checkbox-field.tsx:660-719

Expected behavior
There should be no type error.

I believe this was partly fixed for the <Field /> component in
#11.

Open question:
There is the InputField which is still constrained to the string | number | string[] and perhaps could be extended to allow boolean, as checkboxes are regular inputs of type checkbox. I believe that would be misleading, as the onChange handler for the input should be changed as well, as it uses event.target.checked instead of event.target.value https://codesandbox.io/s/form-atoms-boolean-checkbox-field-9nv7jo?file=/src/components/input-field.tsx:691-766.
So my question is whats the direction with the InputField? Would it be feasible in the future to have its props properly typed with discriminant types for various inputs e.g. of type file and others?

Appreciate your efforts but as it relates to the abstractions this library is solving, you're philosphically incorrect. It is trivially easy for people to use <Field> or alternatively create a useCheckboxFieldAtom hook in userland. It does not need to be part of this library.
#19 (comment)

I am genuinely not seeing where the deficiency is. Here's what I do in my projects:

<Field
  atom={fieldAtoms.tos}
  render={(state, actions) => (
    <Checkbox.Label>
      <Checkbox checked={state.value} onCheckedChange={actions.setValue} />
      <span>
        I have read and agree to the{" "}
        <a href="/tos" rel="noreferrer noopener" target="_blank">
          Terms of Service
        </a>
      </span>
    </Checkbox.Label>
  )}
/>

Thank you for the quick reply, but still this is not settled for me.

I agree that the useCheckboxFieldAtom is a thing for userland, or other layer built on these excellent primitives.
From your comment I understand that the useFieldAtomProps is intended for the InputField (the props are for react component...) and so it makes sense to have the narrow type. So yes I was a bit hasty in removing it from there.

Next, given the useFieldAtom uses the useFieldAtomProps hook, it cannot have wider generic type. And this is where I think the deficiency lies. I think there should be useInputFieldAtom which would use the useFieldAtomProps, and the useFieldAtom should have unconstrained generic type.

That way you would have symmetry between hooks & react components:

  • useFieldAtom, <Field />, state, actions
  • useInputFieldAtom, <InputField />, state, actions, props

That was my mental model just from how the things are named.
Originally I stepped into this error not on the checkbox, but on upload input where I have object atom like {url: string, id: string}. Thats why I reffered to the original issue #11 .

Let me know if I should just re-learn, or if the naming will be adjusted to match the meaning.

Simply put, I imagine the fieldAtom as the most generic thing:

const aField = fieldAtom({ value: { /*anything */} });
// ...
const {state, actions} = useFieldAtom(aField);

That in turn can be used to construct the more specific hooks, like the Checkbox one.

That way you would have symmetry between hooks & react components:

  • useFieldAtom, , state, actions
  • useInputFieldAtom, , state, actions, props

This makes sense to me. I think we can discuss a new major to make this breaking change happen.