mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-27 18:30:35 +01:00
chore(SelectMenu): handle multiple default display + specific placeholder
This commit is contained in:
@@ -6,10 +6,10 @@ const selected = ref(people[3])
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<USelectMenu v-slot="{ open }" v-model="selected" :options="people">
|
<USelectMenu v-slot="{ open }" v-model="selected" :options="people">
|
||||||
<UButton>
|
<UButton color="gray">
|
||||||
{{ selected }}
|
{{ selected }}
|
||||||
|
|
||||||
<UIcon name="i-heroicons-chevron-right-20-solid" class="w-5 h-5 transition-transform" :class="[open && 'transform rotate-90']" />
|
<UIcon name="i-heroicons-chevron-right-20-solid" class="w-5 h-5 transition-transform text-gray-400 dark:text-gray-500" :class="[open && 'transform rotate-90']" />
|
||||||
</UButton>
|
</UButton>
|
||||||
</USelectMenu>
|
</USelectMenu>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -5,10 +5,5 @@ const selected = ref([])
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<USelectMenu v-model="selected" :options="people" multiple>
|
<USelectMenu v-model="selected" :options="people" multiple placeholder="Select people" />
|
||||||
<template #label>
|
|
||||||
<span v-if="selected.length" class="font-medium truncate">{{ selected.join(', ') }}</span>
|
|
||||||
<span v-else class="block truncate text-gray-400 dark:text-gray-500">Select people</span>
|
|
||||||
</template>
|
|
||||||
</USelectMenu>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<script setup>
|
||||||
|
const people = ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
|
||||||
|
|
||||||
|
const selected = ref([])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<USelectMenu v-model="selected" :options="people" multiple>
|
||||||
|
<template #label>
|
||||||
|
<span v-if="selected.length" class="truncate">{{ selected.join(', ') }}</span>
|
||||||
|
<span v-else>Select people</span>
|
||||||
|
</template>
|
||||||
|
</USelectMenu>
|
||||||
|
</template>
|
||||||
@@ -10,6 +10,8 @@ headlessui:
|
|||||||
|
|
||||||
The SelectMenu component renders by default a [Select](/forms/select) component and is based on the `ui.select` preset. You can use most of the Select props to configure the display if you don't want to override the default slot such as [color](/forms/select#style), [variant](/forms/select#style), [size](/forms/select#size), [placeholder](/forms/select#placeholder), [icon](/forms/select#icon), [disabled](/forms/select#disabled), etc.
|
The SelectMenu component renders by default a [Select](/forms/select) component and is based on the `ui.select` preset. You can use most of the Select props to configure the display if you don't want to override the default slot such as [color](/forms/select#style), [variant](/forms/select#style), [size](/forms/select#size), [placeholder](/forms/select#placeholder), [icon](/forms/select#icon), [disabled](/forms/select#disabled), etc.
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
Like the Select component, you can use the `options` prop to pass an array of strings or objects.
|
Like the Select component, you can use the `options` prop to pass an array of strings or objects.
|
||||||
|
|
||||||
::component-example
|
::component-example
|
||||||
@@ -30,7 +32,9 @@ const selected = ref(people[0])
|
|||||||
```
|
```
|
||||||
::
|
::
|
||||||
|
|
||||||
You can use the `multiple` prop to select multiple values but you have to override the `#label` slot and handle the display yourself.
|
### Multiple
|
||||||
|
|
||||||
|
You can use the `multiple` prop to select multiple values.
|
||||||
|
|
||||||
::component-example
|
::component-example
|
||||||
#default
|
#default
|
||||||
@@ -39,7 +43,29 @@ You can use the `multiple` prop to select multiple values but you have to overri
|
|||||||
#code
|
#code
|
||||||
```vue
|
```vue
|
||||||
<script setup>
|
<script setup>
|
||||||
const people = ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
|
const people = [...]
|
||||||
|
|
||||||
|
const selected = ref([])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<USelectMenu v-model="selected" :options="people" multiple placeholder="Select people" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
::
|
||||||
|
|
||||||
|
### Slots
|
||||||
|
|
||||||
|
You can override the `#label` slot and handle the display yourself.
|
||||||
|
|
||||||
|
::component-example
|
||||||
|
#default
|
||||||
|
:select-menu-example-multiple-slot{class="max-w-[12rem] w-full"}
|
||||||
|
|
||||||
|
#code
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
const people = [...]
|
||||||
|
|
||||||
const selected = ref([])
|
const selected = ref([])
|
||||||
</script>
|
</script>
|
||||||
@@ -47,15 +73,15 @@ const selected = ref([])
|
|||||||
<template>
|
<template>
|
||||||
<USelectMenu v-model="selected" :options="people" multiple>
|
<USelectMenu v-model="selected" :options="people" multiple>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span v-if="selected.length" class="font-medium truncate">{{ selected.join(', ') }}</span>
|
<span v-if="selected.length" class="truncate">{{ selected.join(', ') }}</span>
|
||||||
<span v-else class="block truncate text-gray-400 dark:text-gray-500">Select people</span>
|
<span v-else>Select people</span>
|
||||||
</template>
|
</template>
|
||||||
</USelectMenu>
|
</USelectMenu>
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
::
|
::
|
||||||
|
|
||||||
You can also override the default slot entirely.
|
You can also override the `#default` slot entirely.
|
||||||
|
|
||||||
::component-example
|
::component-example
|
||||||
#default
|
#default
|
||||||
@@ -64,14 +90,14 @@ You can also override the default slot entirely.
|
|||||||
#code
|
#code
|
||||||
```vue
|
```vue
|
||||||
<script setup>
|
<script setup>
|
||||||
const people = ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
|
const people = [...]
|
||||||
|
|
||||||
const selected = ref(people[3])
|
const selected = ref(people[3])
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<USelectMenu v-slot="{ open }" v-model="selected" :options="people">
|
<USelectMenu v-slot="{ open }" v-model="selected" :options="people">
|
||||||
<UButton>
|
<UButton color="gray">
|
||||||
{{ selected }}
|
{{ selected }}
|
||||||
|
|
||||||
<UIcon name="i-heroicons-chevron-right-20-solid" class="w-5 h-5 transition-transform" :class="[open && 'transform rotate-90']" />
|
<UIcon name="i-heroicons-chevron-right-20-solid" class="w-5 h-5 transition-transform" :class="[open && 'transform rotate-90']" />
|
||||||
@@ -81,6 +107,8 @@ const selected = ref(people[3])
|
|||||||
```
|
```
|
||||||
::
|
::
|
||||||
|
|
||||||
|
### Objects
|
||||||
|
|
||||||
You can pass an array of objects to `options` and either compare on the whole object or use the `by` prop to compare on a specific key. You can configure which field will be used to display the label through the `option-attribute` prop that defaults to `label`.
|
You can pass an array of objects to `options` and either compare on the whole object or use the `by` prop to compare on a specific key. You can configure which field will be used to display the label through the `option-attribute` prop that defaults to `label`.
|
||||||
|
|
||||||
::component-example
|
::component-example
|
||||||
|
|||||||
@@ -345,6 +345,7 @@ const textarea = {
|
|||||||
|
|
||||||
const select = {
|
const select = {
|
||||||
...input,
|
...input,
|
||||||
|
placeholder: 'text-gray-900 dark:text-white',
|
||||||
default: {
|
default: {
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
color: 'white',
|
color: 'white',
|
||||||
|
|||||||
@@ -207,7 +207,6 @@ export default defineComponent({
|
|||||||
return classNames(
|
return classNames(
|
||||||
ui.value.base,
|
ui.value.base,
|
||||||
ui.value.rounded,
|
ui.value.rounded,
|
||||||
ui.value.placeholder,
|
|
||||||
ui.value.size[props.size],
|
ui.value.size[props.size],
|
||||||
props.padded && ui.value.padding[props.size],
|
props.padded && ui.value.padding[props.size],
|
||||||
variant?.replaceAll('{color}', props.color),
|
variant?.replaceAll('{color}', props.color),
|
||||||
|
|||||||
@@ -34,8 +34,9 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<slot name="label">
|
<slot name="label">
|
||||||
<span v-if="modelValue" class="block truncate">{{ typeof modelValue === 'string' ? modelValue : modelValue[optionAttribute] }}</span>
|
<span v-if="multiple && Array.isArray(modelValue) && modelValue.length" class="block truncate">{{ modelValue.length }} selected</span>
|
||||||
<span v-else class="block truncate text-gray-400 dark:text-gray-500">{{ placeholder || ' ' }}</span>
|
<span v-else-if="!multiple && modelValue" class="block truncate">{{ typeof modelValue === 'string' ? modelValue : modelValue[optionAttribute] }}</span>
|
||||||
|
<span v-else class="block truncate" :class="ui.placeholder">{{ placeholder || ' ' }}</span>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
||||||
<span v-if="trailingIcon" :class="trailingIconClass">
|
<span v-if="trailingIcon" :class="trailingIconClass">
|
||||||
@@ -268,7 +269,6 @@ export default defineComponent({
|
|||||||
return classNames(
|
return classNames(
|
||||||
uiSelect.value.base,
|
uiSelect.value.base,
|
||||||
uiSelect.value.rounded,
|
uiSelect.value.rounded,
|
||||||
uiSelect.value.placeholder,
|
|
||||||
'text-left cursor-default',
|
'text-left cursor-default',
|
||||||
uiSelect.value.size[props.size],
|
uiSelect.value.size[props.size],
|
||||||
uiSelect.value.gap[props.size],
|
uiSelect.value.gap[props.size],
|
||||||
|
|||||||
Reference in New Issue
Block a user