Skip to content

Commit

Permalink
feat(mutiselect): expose select all as slot to allow customization
Browse files Browse the repository at this point in the history
docs(multiselect): add new story for select all slot
docs(multiselect): add select all slot to vuepress docs entry
  • Loading branch information
gretchelin committed Dec 12, 2022
1 parent 6434a28 commit 2fd336f
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 14 deletions.
28 changes: 28 additions & 0 deletions docs/components/multi-select.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,34 @@ Slot Props

<LivePreview src="components-multiselect--custom-max-selection" />

### select-all
Allows custom render for select all option. This will only be run if [`selectAll`](#selectAll) props is set to valid value.

Slot Props

| Prop | Value | Description |
|-------------|------------|---------------------------------------------------------|
| `iSelected` | `boolean` | A flag to indicate if all options is currently selected |
| `onClick` | `function` | Callback to toggle select all state |

```vue
<v-multi-select
select-all
>
<template v-slot:select-all='{onClick, isSelected}'>
<div class="p-4 bg-white sticky left-0 top-0 hover:bg-[gainsboro] border-b-[1px] border-b-grey-500"
style="z-index: 1;"
@click='onClick'
>
{{isSelected ? ' v ' : ''}}
Select All
</div>
</template>
</v-multi-select>
```

<LivePreview src="components-multiselect--custom-select-all" />


## CSS Variables

Expand Down
45 changes: 45 additions & 0 deletions packages/multi-select/src/VMultiSelect.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,51 @@ export const CustomMaxSelection = (args) => ({
`,
});

export const CustomSelectAll = (args) => ({
components: {VMultiSelect},
setup() {
const schema = object({
genre: array().required().min(1).label('Genre'),
});

const {handleSubmit, resetForm, values} = useForm({
validationSchema: schema,
initialValues: {
genre: [...genreItems]
}
});

const onSubmit = handleSubmit((values) => {
alert(JSON.stringify(values));
});

const genres = ref(genreItems);

return {onSubmit, resetForm, values, genres};
},
template: `
<form @submit="onSubmit" class="border-none">
<v-multi-select
name="genre"
label="Genre"
placeholder="Choose your prefered genres"
select-all
:items="genres"
>
<template v-slot:select-all='{onClick, isSelected}'>
<div class="px-4 py-8 bg-white font-bold sticky left-0 -top-[0.25rem] hover:bg-[gainsboro] border-b-[1px] border-b-grey-500"
style="z-index: 1;"
@click='onClick'
>
{{isSelected ? ' v ' : ''}}
Select All
</div>
</template>
</v-multi-select>
</form>
`,
});

export const CssVars = () => ({
components: {
VMultiSelect,
Expand Down
48 changes: 34 additions & 14 deletions packages/multi-select/src/VMultiSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ watch(
</slot>
</template>
</div>

<input
:id="id"
type="text"
Expand Down Expand Up @@ -491,26 +492,45 @@ watch(
Loading...
</div>
<template v-else-if="filteredItems.length">
<template v-if="$slots.prependOption">
<div
:ref="(el) => setRefItem(el)"
class="v-multi-select-item group"
:class="[
itemClass,
{
'v-multi-select-item--focused': focus === index,
'v-multi-select-item--active': isSelected(item, index),
},
]"
>
test
</div>
</template>

<template v-if="selectAll">
<div class="v-multi-select-item" @click="toggleSelectAll">
<div
:class="[
<slot name="select-all" :onClick="toggleSelectAll" :isSelected='isAllSelected'>
<div class="v-multi-select-item" @click="toggleSelectAll">
<div
:class="[
isAllSelected ? 'font-medium' : 'font-normal',
'block truncate',
]"
>
{{ isAllSelected ? 'Deselect All' : 'Select All' }}
</div>
<div v-if="isAllSelected" class="v-multi-select-item-check">
<Icon
name="heroicons:check"
class="w-5 h-5"
aria-hidden="true"
/>
>
{{ isAllSelected ? 'Deselect All' : 'Select All' }}
</div>
<div v-if="isAllSelected" class="v-multi-select-item-check">
<Icon
name="heroicons:check"
class="w-5 h-5"
aria-hidden="true"
/>
</div>
</div>
</div>
<div class="border-b h-1"></div>
<div class="border-b h-1"></div>
</slot>
</template>

<template
v-for="(item, index) in filteredItems"
:key="item.value"
Expand Down

0 comments on commit 2fd336f

Please sign in to comment.