shadcn-svelte
shadcn-svelte copied to clipboard
Add multiple={true} and {max} functionalities to <Form.Select>
Describe the feature in detail (code, mocks, or screenshots encouraged)
multiple={true} works with the basic <Select>
component, but <Form.Select>
hasn't implemented this yet, and can only handle single values. (I'm not sure if this is something that needs updating within Bits UI or shadcn-svelte.)
I'd also love to have a {max} prop to limit the max number of selections. Looks like bits-ui's <Select>
doesn't have this yet.
I tried svelte-multiselect
but it's styled totally differently, not using Tailwind at all.
I tried using the basic <Select>
component instead, and I can receive value updates with the onSelectedChange
callback, but I'm not sure how to manually update the values of the <Form>
component (don't quite grok how that's working via formsnap - I've always rolled my own form handlers with TRPC so this is new for me). Happy to use a workaround if anyone could point me in the right direction there.
Somebody made a Multiple Selector component for React built on shadcn
, not sure if this would be useful to look at:
https://shadcnui-expansions.typeart.cc/docs/multiple-selector
shadcn-svelte
is an amazing UI library (best I've seen in a couple years of working with Svelte), so I'm very grateful! This is the last little feature I need for complete form building in a new web app.
What type of pull request would this be?
New Feature
Provide relevant links or additional information.
No response
Maybe this is an Enhancement?
Ah, I figured out I can do something like this with Formsnap as a workaround:
<Form.Field {config} name="secondaryGenreIds" let:value let:setValue>
<Select.Root multiple={true} onSelectedChange={(items) => setValue(items?.map(item => item.value))}>
...
{#each value as _, i}
<input hidden aria-hidden="true" name="secondaryGenreIds" value={value[i]} />
{/each}
</Select.Root>
</Form.Field>
With this schema:
export const profileFormSchema = z.object({
secondaryGenreIds: z
.string().array().max(3, 'Choose up to 3 genres'),
})
})
The hidden inputs above, inside the {#each}
block, follow the convention from the Superforms docs here for using arrays of primitives without dataType="json"
. This leads to correct & valid data being received by the server (e.g. secondaryGenreIds: ['folk', 'jazz']
).
However, there's some strange validation error happening here (see attached video). It works fine after opening the select, selecting the first item, and then closing the select. But then, if I re-open the select, then close it again (or focus and unfocus any other form input), the errors
value changes from undefined
to {}
, which shows up as a red-label validation error even though there aren't any actual Zod errors.
I've been trying to dig into the code for Formsnap and SuperForms but can't figure out why this is happening. I'm guessing it's a problem with handling of arrays of primitives, but not sure how to rectify this or work around it (e.g. with a custom validator).
https://github.com/huntabyte/shadcn-svelte/assets/3757963/181639df-90dc-4940-8272-6c13901a0c98
@dkmooers How did you get Form.Field
to accept the array as a valid name? I seem to be running into the upstream issue where formsnap doesn't support Zod array types for multiselect: https://github.com/huntabyte/formsnap/issues/27
@bjornpijnacker Sorry for the delay! Welp, I thought I had it working since even though TS was complaining, I was still receiving the correct array of values on the server on form submit. But it looks like setting the multiselect values from my server load function isn't working properly. Sorry to disappoint. Want to +1 on this? https://github.com/huntabyte/formsnap/pull/86
Actually, this might be a separate issue. It looks like setting initial values even on single-selects isn't working:
https://github.com/huntabyte/shadcn-svelte/issues/717
So it could be that if that gets fixed, this multi-select initial select will work fine?
Closing as not relevant with updates to Formsnap and form components.
Just updated to Superforms v2 and the Formsnap rewrite, and this is indeed moot. Thanks for the great work @huntabyte!