fabian-hiller / modular-forms

The modular and type-safe form library for SolidJS, Qwik and Preact
https://modularforms.dev
MIT License
1k stars 53 forks source link

Checkbox works improperly when use modular forms with kobalte #176

Open Tur8008 opened 8 months ago

Tur8008 commented 8 months ago

Hi, Can't make checkbox working properly when use modular forms with kobalte. Seems like I follow the manual but still doesn't work. I reproduced the wrong behavior here on stackblitz: https://stackblitz.com/edit/solidjs-templates-soysfz?file=src%2Fviews%2Fhome%2FHome.jsx The problem is the checkboxes get checked only if a user clicks on label but not on kobalte's Checkbox.control component. But if I remove checked attr from this line:

<For each={[
              { label: 'sunday', value: '1' },
              { label: 'monday', value: '2' },
              { label: 'tuesday', value: '3' },
            ]}
          >
            {({label, value})=>
              <Field name="weekdays" type="string[]">
                {(field, props) => (
                  <Checkbox
                    {...props}
                    label={label}
                    value={value}
                    checked={field.value?.includes(value)}
                  />
                )}
              </Field>
            }
          </For>

Kobalte's code start working but modular's doesn't get checked values -- logical. So I tend to think somethin wrong goes here with contains of checked attr.

fabian-hiller commented 8 months ago

Thanks for creating this issue! Unfortunately I am not able to keep up with the changes in Kobalte. I recommend to contact the Kobalte team for example in the SolidJS Discord. If you could fix it, feel free to become a contributor of Modular Forms by updating the code examples.

Tur8008 commented 8 months ago

Thank's for the answer. I've already written to discord channel of Kobalte and been waiting for the answer. Could you explain please the thing. I see that the problem is in setter of checked props. Kobalte's code gets props.checked but how it get's the setter of modular's Field component?

fabian-hiller commented 8 months ago

It is important to connect the native <input type="checkbox" /> element of Kobalte via the provided props of the Field component of Modular Forms to capture its value. Once that done you should try to pass the checked value stored in Modular Forms back to Kobalte to make the component controlled.

Tur8008 commented 8 months ago

I managed to make it work for the case of the single checkbox (by the way radio group has the same problem). Thank's to the issue on kobalte's github. The solution is in passing down to the <Checkbox.Root> component modular's setValue method. Like this:

   <Field name="singlebox" type="boolean">
            {(field, props) => (
              <Checkbox
                {...props}
                label="Single checkbox"
                error={field.error}
                checked={field.value}
                setValue={(v)=> setValue(aForm, 'singlebox', v)}
              />
            )}
          </Field>

And within Checkbox component we have

    <Kobalte.Root
        {...rootProps}
        validationState={props.error ? 'invalid' : 'valid'}
        class={styles.checkbox}
        onChange={(v)=>props.setValue(v)}
      >
        <Kobalte.Input {...inputProps} class={styles.checkbox__input} />
        <Kobalte.Control class={styles.checkbox__control}>
          <Kobalte.Indicator>x</Kobalte.Indicator>
        </Kobalte.Control>
        <Kobalte.Label class={styles.checkbox__label}>
          {props.label}
        </Kobalte.Label>
      </Kobalte.Root>
Works fine. 
But in more complex case that I'm needed now, I use checkbox array. I have such the code:
     <For
            each={[
              { label: 'sunday', value: '1' },
              { label: 'monday', value: '2' },
              { label: 'tuesday', value: '3' },
            ]}
          >
            {({ label, value }) => (
              <Field name="weekdays" type="string[]">
                {(field, props) => (
                  <Checkbox
                    {...props}
                    label={label}
                    value={value}
                    checked={field.value?.includes(value)}
                    setValue={(v)=>setValue(aForm, 'weekdays', v)}
                  />
                )}
              </Field>
            )}

It doesn't work because of in the line checked={field.value?.includes(value)} expression field.value that as I understood must return a value of type of Array but it gets bollean. I can't get how to solve it. May be you have an idea.

Tur8008 commented 8 months ago

I got almost all the answers here. There is also the bug (likely) with duplicating values within checkboxes array. But I think I can use it in my project right now.

Tur8008 commented 8 months ago

Thanks for creating this issue! Unfortunately I am not able to keep up with the changes in Kobalte. I recommend to contact the Kobalte team for example in the SolidJS Discord. If you could fix it, feel free to become a contributor of Modular Forms by updating the code examples.

How could I do that? I wish other developers have no problem with checkboxes and radio groups

fabian-hiller commented 8 months ago

How could I do that? I wish other developers have no problem with checkboxes and radio groups

At the bottom of each documentation page is an "Edit page" button. It will take you to the MDX file on GitHub, which you can edit there.