thaw-ui / thaw

An easy to use leptos component library
https://thawui.vercel.app
MIT License
206 stars 21 forks source link

feat: Add support for multiple options in Select #166

Closed tqwewe closed 2 months ago

tqwewe commented 2 months ago

Adds support for selecting multiple options in the Select component using closable tags.

This should close https://github.com/thaw-ui/thaw/issues/101

https://github.com/thaw-ui/thaw/assets/16362377/a9e98c60-31a9-4c7c-8281-ec6dd6548b67

Issues:

luoxiaozero commented 2 months ago

Looks very cool. Maybe we can split it into a separate component (Multiselect).

tqwewe commented 2 months ago

I was considering that, it would also mean it's no longer a breaking change. Though I'm not sure how this could be done without duplicating so much of the code?

tqwewe commented 2 months ago

I wonder if it's worth having a prop to override the entire view rendering of the label? For example, you might want to have custom behaviour where the label is just text with a number of items selected: eg "Categories (2 selected)"

luoxiaozero commented 2 months ago

like https://www.naiveui.com/en-US/os-theme/components/select#max-tag-count.vue ?

tqwewe commented 2 months ago

Hmm not really limiting, I mean more like custom render function for the label itself. https://ant.design/components/select#select-demo-custom-label-render

For users who want to render anything they want. In my personal use case, I want a filter called "Bookmakers", and I don't want to render all the bookmakers selected, instead I only want to show the number of bookmakers selected.

[ Bookmakers (3) ]
- [x] Betfair
- [x] Sportsbet
- [x] Tab
- [ ] Pinnacle

This could be done with something like:

view! {
    <MultiSelect
        label=|values| view! { {format!("Bookmakers ({})", values.len()) }
        values
        options
    />
}
luoxiaozero commented 2 months ago

We can do this by adding a label slot.

view! {
    <Multiselect
        values
        options
    >
         <MultiselectLabel slot>
              {format!("Bookmakers ({})", values.len())
        <MultiselectLabel>
   </Multiselect>
}
tqwewe commented 2 months ago

@luoxiaozero I've separated them into separate components. I also renamed it from MultiSelect into SelectMulti so it would be found in the docs beside Select (alphabetical).

I also implemented the SelectLabel slot for the selects.

We should also probably include a dropdown arrow in the select component. But maybe that can be a separate PR?

luoxiaozero commented 2 months ago

I've separated them into separate components. I also renamed it from MultiSelect into SelectMulti so it would be found in the docs beside Select (alphabetical).

I think the name MultiSelect is better, we can put the MultiSelect documentation and code into Select to solve this problem.

We should also probably include a dropdown arrow in the select component. But maybe that can be a separate PR?

Agree.

tqwewe commented 2 months ago

Great I've pushed another commit with these changes

tqwewe commented 2 months ago

Actually I've just gone ahead and added the dropdown arrow to the select component. Was quite a simple task so thought I'd add it here.

Screenshot 2024-04-20 at 2 05 35 PM
tqwewe commented 2 months ago

I'm just trying to debug why it's looking a little different in my personal project when using this fork. The alignment isn't correct.

Screenshot 2024-04-20 at 2 22 53 PM

I've been digging through the styles but not sure what's different.

Edit

I've fixed this by setting the font-size of the select component to 14px.

tqwewe commented 2 months ago

I've just implemented a clear button, when you hover over a multi select, it shows a little x button where the arrow is allowing you to clear all items.

Additionally, clicking on the select input box itself will toggle the menu, where previously clicking the input wouldn't hide it.

tqwewe commented 2 months ago

I'd also like to share this screenshot of what I've implemented in my project where I'm using this fork and the <SelectLabel slot> slot to customize the label.

Screenshot 2024-04-22 at 10 53 35 PM

It's an alternative version of the multi select, where it has a label, and shows a <Tag> beside it with the number of items selected. Perhaps something like this might be of interest to people in the future?

luoxiaozero commented 2 months ago

No more problems, now merge.