svelte-multiselect
svelte-multiselect copied to clipboard
Option grouping
This is a perfect little component. In some cases where there are many fields it would be nice if a single Multiselect could contain several options, perhaps like this:
<script>
import MultiSelect from 'svelte-multiselect'
const genreTags = [`Rock`, `Electronic`, `Opera`]
const keyTags = [`C`, `D`, `E`, `F`, `G`, `A`, `B`]
const scaleTags = [`Major`, `Minor`]
let selectedTags = []
</script>
<MultiSelect
bind:selectedTags
options={[genreTags, keyTags, scaleTags]}
maxSelect={[null, 1, 1]}
required={[true, true, false]}
placeholder="Select Tags"
/>
I need this in my app - are you open to an PR (if this isn't already supported)?
Why do they need to be in 1 multi-select? And what would the UI for that look like? How would you have 3 dropdowns in one component? Maybe you can elaborate on your use case.
Hey thanks for the quick reply - I'm referring to a binding to the HTML optgroup
element
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup
Ah, you're talking about grouping of options. Yes, I'd be happy to take a PR for that.
I should say upfront though, this sounds like a fair amount of work if you want to do it right. Your example suggests that you don't just want option grouping in the UI but for the groups to have separate maxSelect
and required
attributes. That raises some questions:
- What should happen when users create new options (when
allowUserOptions=true
)? Which group should the new option be added to? - Does each group have separate
defaultDisabledTitle
?
Yes, exactly - not quite just the grouping of options, since the intention is to group other attributes from Multiselect
like maxSelect
....
-
allowUserOptions
could be either disabled for this feature or treated in the same way ie:boolean | boolean[]
. When more than one option allows user options theoptgroup label
could be required for input - for example, input text like:genre=Electronic
for something like the following:
<script>
import MultiSelect from 'svelte-multiselect'
const genreTags = {label: "Genre", options: [`Rock`, `Electronic`, `Opera`]}
const keyTags = {label: "Key", options: [`C`, `D`, `E`, `F`, `G`, `A`, `B`]}
const scaleTags = {label: "Scale", options: [`Major`, `Minor`]}
let selectedTags = []
</script>
<MultiSelect
bind:selected
options={[genreTags, keyTags, scaleTags]}
maxSelect={[null, 1, 1]}
required={[true, true, false] }
allowUserOptions={ [true, false, true] }
placeholder="Select Tags"
/>
- I'm not sure I can see a strong use case for this
- Let's go with disabling
allowUserOptions
entirely when options are grouped for now. - Fair point. We'll stick with a single
defaultDisabledTitle
for all groups.
As I said, happy to take a PR for this. Though the default way to group options should be an object of arrays imo:
<script>
import MultiSelect from 'svelte-multiselect'
const options: Record<string, Option[]> = {
Genre: [`Rock`, `Electronic`, `Opera`],
Key: [`C`, `D`, `E`, `F`, `G`, `A`, `B`],
Scale: [`Major`, `Minor`],
}
let selected = []
</script>
<MultiSelect
bind:selected
{options}
maxSelect={[null, 1, 1]}
required={[true, true, false]}
allowUserOptions={[true, false, true]}
placeholder="Select Tags"
/>
We can expand to
options: Record<string, { label: string, options: Option[], required: boolean, maxSelect: number | null }>
later.
Sorry @janosh bit too pressured at work to get onto doing this properly - working around it for now. Anyone else wants to jump in please do