Listbox
xph0000xUso
Utilice la directiva v-model para controlar el valor del Listbox o la prop default-value para establecer el valor inicial cuando no necesite controlar su estado.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
},
{
label: 'Netherlands',
icon: 'i-lucide-map-pin',
value: 'NL'
},
{
label: 'Poland',
icon: 'i-lucide-map-pin',
value: 'PL'
},
{
label: 'Belgium',
icon: 'i-lucide-map-pin',
value: 'BE'
},
{
label: 'Portugal',
icon: 'i-lucide-map-pin',
value: 'PT'
},
{
label: 'Austria',
icon: 'i-lucide-map-pin',
value: 'AT'
},
{
label: 'Sweden',
icon: 'i-lucide-map-pin',
value: 'SE'
}
])
const value = ref({
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
})
</script>
<template>
<UListbox v-model="value" :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
},
{
label: 'Netherlands',
icon: 'i-lucide-map-pin',
value: 'NL'
},
{
label: 'Poland',
icon: 'i-lucide-map-pin',
value: 'PL'
},
{
label: 'Belgium',
icon: 'i-lucide-map-pin',
value: 'BE'
},
{
label: 'Portugal',
icon: 'i-lucide-map-pin',
value: 'PT'
},
{
label: 'Austria',
icon: 'i-lucide-map-pin',
value: 'AT'
},
{
label: 'Sweden',
icon: 'i-lucide-map-pin',
value: 'SE'
}
])
const value = ref({
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
})
</script>
<template>
<UListbox v-model="value" :items="items" />
</template>Artículos
Utilice el prop items como una matriz de objetos con las siguientes propiedades:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- xx
onSelect?: (e: Event) => voidxx{lang="ts-type"} - x
class?: anyx{lang="ts-type"} (Edición española) - x
ui?: { label?: ClassNameValue, separator?: ClassNameValue, item?: ClassNameValue, itemLeadingIcon?: ClassNameValue, ... }x{lang="ts-type"}
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
description: 'The Hexagon',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
description: 'The Federal Republic',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
description: 'The Boot',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
description: 'The Bull Skin',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
description: 'The Hexagon',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
description: 'The Federal Republic',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
description: 'The Boot',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
description: 'The Bull Skin',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox :items="items" />
</template>También puede pasar una matriz de matrices al soporte items para mostrar grupos separados de elementos.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[][]>([
[
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
}
],
[
{
label: 'Brazil',
icon: 'i-lucide-map-pin',
value: 'BR'
},
{
label: 'Argentina',
icon: 'i-lucide-map-pin',
value: 'AR'
}
]
])
</script>
<template>
<UListbox :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[][]>([
[
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
}
],
[
{
label: 'Brazil',
icon: 'i-lucide-map-pin',
value: 'BR'
},
{
label: 'Argentina',
icon: 'i-lucide-map-pin',
value: 'AR'
}
]
])
</script>
<template>
<UListbox :items="items" />
</template>Multiplicación
Utilice el prop multiple para permitir la selección de varios elementos. Cuando esté habilitado, el v-model será una matriz.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox multiple :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox multiple :items="items" />
</template>Value Clave de seguridad
Puede optar por vincular una sola propiedad del objeto en lugar de todo el objeto utilizando la prop. value-key.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
const value = ref('FR')
</script>
<template>
<UListbox v-model="value" value-key="value" :items="items" class="w-full" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
const value = ref('FR')
</script>
<template>
<UListbox v-model="value" value-key="value" :items="items" class="w-full" />
</template>Filter (Edición española)
Utilice el prop filter para mostrar una entrada de filtro o pasar un objeto para personalizar el componente Input.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
},
{
label: 'Netherlands',
icon: 'i-lucide-map-pin',
value: 'NL'
},
{
label: 'Poland',
icon: 'i-lucide-map-pin',
value: 'PL'
}
])
</script>
<template>
<UListbox :filter="{
placeholder: 'Filter...',
icon: 'i-lucide-search'
}" :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
},
{
label: 'Netherlands',
icon: 'i-lucide-map-pin',
value: 'NL'
},
{
label: 'Poland',
icon: 'i-lucide-map-pin',
value: 'PL'
}
])
</script>
<template>
<UListbox :filter="{
placeholder: 'Filter...',
icon: 'i-lucide-search'
}" :items="items" />
</template>Icono seleccionado
Utilice el prop selected-icon para personalizar el icono cuando se selecciona un elemento.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
const value = ref('FR')
</script>
<template>
<UListbox v-model="value" selected-icon="i-lucide-flame" value-key="value" :items="items" class="w-full" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
const value = ref('FR')
</script>
<template>
<UListbox v-model="value" selected-icon="i-lucide-flame" value-key="value" :items="items" class="w-full" />
</template>Tamaño
Utilice el accesorio size para cambiar el tamaño del Listbox.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox size="xl" :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox size="xl" :items="items" />
</template>Cargando
Utilice el accesorio loading para mostrar un indicador de carga. Use el accesorio loading-icon para personalizar el icono.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
}
])
</script>
<template>
<UListbox loading :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
}
])
</script>
<template>
<UListbox loading :items="items" />
</template>Desactivado
Utilice el accesorio disabled para evitar cualquier interacción del usuario con el Listbox.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox disabled :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox disabled :items="items" />
</template>Ejemplos
Con tipo de elementos
Puede utilizar la propiedad type con separator para mostrar un separador entre elementos o label para mostrar una etiqueta.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[][]>([
[
{
type: 'label',
label: 'Fruits'
},
{
label: 'Apple'
},
{
label: 'Banana'
},
{
label: 'Blueberry'
},
{
label: 'Grapes'
},
{
label: 'Pineapple'
}
],
[
{
type: 'label',
label: 'Vegetables'
},
{
label: 'Aubergine'
},
{
label: 'Broccoli'
},
{
label: 'Carrot'
},
{
label: 'Courgette'
},
{
label: 'Leek'
}
]
])
</script>
<template>
<UListbox :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[][]>([
[
{
type: 'label',
label: 'Fruits'
},
{
label: 'Apple'
},
{
label: 'Banana'
},
{
label: 'Blueberry'
},
{
label: 'Grapes'
},
{
label: 'Pineapple'
}
],
[
{
type: 'label',
label: 'Vegetables'
},
{
label: 'Aubergine'
},
{
label: 'Broccoli'
},
{
label: 'Carrot'
},
{
label: 'Courgette'
},
{
label: 'Leek'
}
]
])
</script>
<template>
<UListbox :items="items" />
</template>label como encabezados de grupo, pase una matriz de matrices para que una etiqueta se filtre junto con su grupo al realizar una búsqueda.Con icono en elementos
Puede usar la propiedad icon para mostrar un Icon dentro de los elementos.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'Backlog',
icon: 'i-lucide-circle-help',
value: 'backlog'
},
{
label: 'Todo',
icon: 'i-lucide-circle-plus',
value: 'todo'
},
{
label: 'In Progress',
icon: 'i-lucide-circle-arrow-up',
value: 'in_progress'
},
{
label: 'Done',
icon: 'i-lucide-circle-check',
value: 'done'
}
])
</script>
<template>
<UListbox :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'Backlog',
icon: 'i-lucide-circle-help',
value: 'backlog'
},
{
label: 'Todo',
icon: 'i-lucide-circle-plus',
value: 'todo'
},
{
label: 'In Progress',
icon: 'i-lucide-circle-arrow-up',
value: 'in_progress'
},
{
label: 'Done',
icon: 'i-lucide-circle-check',
value: 'done'
}
])
</script>
<template>
<UListbox :items="items" />
</template>Con avatar en los elementos
Puede usar la propiedad avatar para mostrar un Avatar dentro de los elementos.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'benjamincanac',
avatar: {
src: 'https://github.com/benjamincanac.png'
}
},
{
label: 'HugoRCD',
avatar: {
src: 'https://github.com/HugoRCD.png'
}
},
{
label: 'atinux',
avatar: {
src: 'https://github.com/atinux.png'
}
},
{
label: 'romhml',
avatar: {
src: 'https://github.com/romhml.png'
}
}
])
</script>
<template>
<UListbox :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'benjamincanac',
avatar: {
src: 'https://github.com/benjamincanac.png'
}
},
{
label: 'HugoRCD',
avatar: {
src: 'https://github.com/HugoRCD.png'
}
},
{
label: 'atinux',
avatar: {
src: 'https://github.com/atinux.png'
}
},
{
label: 'romhml',
avatar: {
src: 'https://github.com/romhml.png'
}
}
])
</script>
<template>
<UListbox :items="items" />
</template>Con chip en artículos
Puede utilizar la propiedad chip para mostrar un Chip dentro de los elementos.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'bug',
chip: {
color: 'error'
}
},
{
label: 'feature',
chip: {
color: 'success'
}
},
{
label: 'enhancement',
chip: {
color: 'info'
}
}
])
</script>
<template>
<UListbox :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'bug',
chip: {
color: 'error'
}
},
{
label: 'feature',
chip: {
color: 'success'
}
},
{
label: 'enhancement',
chip: {
color: 'info'
}
}
])
</script>
<template>
<UListbox :items="items" />
</template>Con descripción en artículos
Vous pouvez utiliser la propriété description pour afficher du texte supplémentaire sous l'étiquette.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
description: 'The Hexagon',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
description: 'The Federal Republic',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
description: 'The Boot',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
description: 'The Bull Skin',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox :items="items" />
</template><script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items = ref<ListboxItem[]>([
{
label: 'France',
description: 'The Hexagon',
icon: 'i-lucide-map-pin',
value: 'FR'
},
{
label: 'Germany',
description: 'The Federal Republic',
icon: 'i-lucide-map-pin',
value: 'DE'
},
{
label: 'Italy',
description: 'The Boot',
icon: 'i-lucide-map-pin',
value: 'IT'
},
{
label: 'Spain',
description: 'The Bull Skin',
icon: 'i-lucide-map-pin',
value: 'ES'
}
])
</script>
<template>
<UListbox :items="items" />
</template>Control artículo (s) seleccionado (s)
Puede controlar el elemento seleccionado mediante la prop default-value o la directiva v-model.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items: ListboxItem[] = [
{ label: 'France', icon: 'i-lucide-map-pin', value: 'FR' },
{ label: 'Germany', icon: 'i-lucide-map-pin', value: 'DE' },
{ label: 'Italy', icon: 'i-lucide-map-pin', value: 'IT' },
{ label: 'Spain', icon: 'i-lucide-map-pin', value: 'ES' },
{ label: 'Netherlands', icon: 'i-lucide-map-pin', value: 'NL' },
{ label: 'Poland', icon: 'i-lucide-map-pin', value: 'PL' }
]
const value = ref<ListboxItem>(items[2]!)
</script>
<template>
<UListbox
v-model="value"
:items="items"
class="w-full"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items: ListboxItem[] = [
{ label: 'France', icon: 'i-lucide-map-pin', value: 'FR' },
{ label: 'Germany', icon: 'i-lucide-map-pin', value: 'DE' },
{ label: 'Italy', icon: 'i-lucide-map-pin', value: 'IT' },
{ label: 'Spain', icon: 'i-lucide-map-pin', value: 'ES' },
{ label: 'Netherlands', icon: 'i-lucide-map-pin', value: 'NL' },
{ label: 'Poland', icon: 'i-lucide-map-pin', value: 'PL' }
]
const value = ref<ListboxItem>(items[2]!)
</script>
<template>
<UListbox
v-model="value"
:items="items"
class="w-full"
/>
</template>
Control términos de búsqueda
Utilice la directiva v-model:search-term para controlar el término de búsqueda.
<script setup lang="ts">
const searchTerm = ref('F')
const items = ref([
{ label: 'France', icon: 'i-lucide-map-pin', value: 'FR' },
{ label: 'Germany', icon: 'i-lucide-map-pin', value: 'DE' },
{ label: 'Italy', icon: 'i-lucide-map-pin', value: 'IT' },
{ label: 'Spain', icon: 'i-lucide-map-pin', value: 'ES' },
{ label: 'Netherlands', icon: 'i-lucide-map-pin', value: 'NL' },
{ label: 'Poland', icon: 'i-lucide-map-pin', value: 'PL' }
])
const value = ref()
</script>
<template>
<UListbox v-model="value" v-model:search-term="searchTerm" filter :items="items" class="w-full" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
const searchTerm = ref('F')
const items = ref([
{ label: 'France', icon: 'i-lucide-map-pin', value: 'FR' },
{ label: 'Germany', icon: 'i-lucide-map-pin', value: 'DE' },
{ label: 'Italy', icon: 'i-lucide-map-pin', value: 'IT' },
{ label: 'Spain', icon: 'i-lucide-map-pin', value: 'ES' },
{ label: 'Netherlands', icon: 'i-lucide-map-pin', value: 'NL' },
{ label: 'Poland', icon: 'i-lucide-map-pin', value: 'PL' }
])
const value = ref()
</script>
<template>
<UListbox v-model="value" v-model:search-term="searchTerm" filter :items="items" class="w-full" />
</template>
Con filtro ignorar
Configure el prop ignore-filter en true para desactivar la búsqueda interna y utilizar su propia lógica de búsqueda.
<script setup lang="ts">
import { refDebounced } from '@vueuse/core'
const searchTerm = ref('')
const searchTermDebounced = refDebounced(searchTerm, 200)
const { data: users, status, execute } = await useLazyFetch('https://jsonplaceholder.typicode.com/users', {
key: 'listbox-users-search',
params: { q: searchTermDebounced },
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}`, loading: 'lazy' as const }
}))
},
immediate: false
})
onMounted(() => {
execute()
})
</script>
<template>
<UListbox
v-model:search-term="searchTerm"
:items="users || []"
:filter="{
icon: 'i-lucide-search',
loading: status === 'pending'
}"
ignore-filter
class="w-full"
/>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { refDebounced } from '@vueuse/core'
const searchTerm = ref('')
const searchTermDebounced = refDebounced(searchTerm, 200)
const { data: users, status, execute } = await useLazyFetch('https://jsonplaceholder.typicode.com/users', {
key: 'listbox-users-search',
params: { q: searchTermDebounced },
transform: (data: { id: number, name: string }[]) => {
return data?.map(user => ({
label: user.name,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}`, loading: 'lazy' as const }
}))
},
immediate: false
})
onMounted(() => {
execute()
})
</script>
<template>
<UListbox
v-model:search-term="searchTerm"
:items="users || []"
:filter="{
icon: 'i-lucide-search',
loading: status === 'pending'
}"
ignore-filter
class="w-full"
/>
</template>
refDebounced para refutar las llamadas a la API.Con campos de filtro
Utilice el prop filter-fields con una matriz de campos para filtrar.
<script setup lang="ts">
const { data: users, status, execute } = await useLazyFetch('https://jsonplaceholder.typicode.com/users', {
key: 'typicode-users-email',
transform: (data: { id: number, name: string, email: string }[]) => {
return data?.map(user => ({
label: user.name,
email: user.email,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}`, loading: 'lazy' as const }
}))
},
immediate: false
})
onMounted(() => {
execute()
})
</script>
<template>
<UListbox
:items="users || []"
:loading="status === 'pending'"
:filter-fields="['label', 'email']"
filter
class="w-full"
>
<template #item-label="{ item }">
{{ item.label }}
<span class="text-muted">
{{ item.email }}
</span>
</template>
</UListbox>
</template>
<script setup lang="ts">
import { onMounted } from 'vue'
const { data: users, status, execute } = await useLazyFetch('https://jsonplaceholder.typicode.com/users', {
key: 'typicode-users-email',
transform: (data: { id: number, name: string, email: string }[]) => {
return data?.map(user => ({
label: user.name,
email: user.email,
value: String(user.id),
avatar: { src: `https://i.pravatar.cc/120?img=${user.id}`, loading: 'lazy' as const }
}))
},
immediate: false
})
onMounted(() => {
execute()
})
</script>
<template>
<UListbox
:items="users || []"
:loading="status === 'pending'"
:filter-fields="['label', 'email']"
filter
class="w-full"
>
<template #item-label="{ item }">
{{ item.label }}
<span class="text-muted">
{{ item.email }}
</span>
</template>
</UListbox>
</template>
Con virtualización
Utilice el prop virtualize para habilitar la virtualización de listas grandes como un booleano o un objeto con opciones como { estimateSize: 32, overscan: 12 }.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items: ListboxItem[] = Array.from({ length: 1000 }, (_, i) => ({
label: `Item ${i + 1}`,
icon: 'i-lucide-file',
value: i + 1
}))
const value = ref<ListboxItem[]>([])
</script>
<template>
<UListbox
v-model="value"
:items="items"
multiple
virtualize
class="w-full"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items: ListboxItem[] = Array.from({ length: 1000 }, (_, i) => ({
label: `Item ${i + 1}`,
icon: 'i-lucide-file',
value: i + 1
}))
const value = ref<ListboxItem[]>([])
</script>
<template>
<UListbox
v-model="value"
:items="items"
multiple
virtualize
class="w-full"
/>
</template>
As una lista de transferencias
Puede componer dos componentes de Listbox con los controles Button para crear un patrón de lista de transferencia.
<script setup lang="ts">
import type { ListboxItem } from '@nuxt/ui'
const items: ListboxItem[] = [
{ label: 'France', icon: 'i-lucide-map-pin', value: 'FR' },
{ label: 'Germany', icon: 'i-lucide-map-pin', value: 'DE' },
{ label: 'Italy', icon: 'i-lucide-map-pin', value: 'IT' },
{ label: 'Spain', icon: 'i-lucide-map-pin', value: 'ES' },
{ label: 'Netherlands', icon: 'i-lucide-map-pin', value: 'NL' },
{ label: 'Poland', icon: 'i-lucide-map-pin', value: 'PL' },
{ label: 'Belgium', icon: 'i-lucide-map-pin', value: 'BE' },
{ label: 'Portugal', icon: 'i-lucide-map-pin', value: 'PT' }
]
const targetItems = ref<ListboxItem[]>([])
const sourceSelection = ref<ListboxItem[]>([])
const targetSelection = ref<ListboxItem[]>([])
const sourceItems = computed(() => items.filter(item => !targetItems.value.some(t => t.value === item.value)))
function transferSelected() {
targetItems.value = [...targetItems.value, ...sourceSelection.value]
sourceSelection.value = []
}
function removeSelected() {
targetItems.value = targetItems.value.filter(item => !targetSelection.value.some(t => t.value === item.value))
targetSelection.value = []
}
</script>
<template>
<div class="flex items-stretch gap-4 w-full">
<div class="flex flex-col flex-1 gap-1">
<span class="text-sm font-medium text-highlighted">Available</span>
<UListbox
v-model="sourceSelection"
:items="sourceItems"
multiple
filter
class="size-full"
/>
</div>
<div class="flex flex-col items-center justify-center gap-1">
<UButton
icon="i-lucide-chevron-right"
color="neutral"
variant="outline"
:disabled="!sourceSelection.length"
@click="transferSelected"
/>
<UButton
icon="i-lucide-chevron-left"
color="neutral"
variant="outline"
:disabled="!targetSelection.length"
@click="removeSelected"
/>
</div>
<div class="flex flex-col flex-1 gap-1">
<span class="text-sm font-medium text-highlighted">Selected</span>
<UListbox
v-model="targetSelection"
:items="targetItems"
multiple
filter
class="size-full"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import type { ListboxItem } from '@nuxt/ui'
const items: ListboxItem[] = [
{ label: 'France', icon: 'i-lucide-map-pin', value: 'FR' },
{ label: 'Germany', icon: 'i-lucide-map-pin', value: 'DE' },
{ label: 'Italy', icon: 'i-lucide-map-pin', value: 'IT' },
{ label: 'Spain', icon: 'i-lucide-map-pin', value: 'ES' },
{ label: 'Netherlands', icon: 'i-lucide-map-pin', value: 'NL' },
{ label: 'Poland', icon: 'i-lucide-map-pin', value: 'PL' },
{ label: 'Belgium', icon: 'i-lucide-map-pin', value: 'BE' },
{ label: 'Portugal', icon: 'i-lucide-map-pin', value: 'PT' }
]
const targetItems = ref<ListboxItem[]>([])
const sourceSelection = ref<ListboxItem[]>([])
const targetSelection = ref<ListboxItem[]>([])
const sourceItems = computed(() => items.filter(item => !targetItems.value.some(t => t.value === item.value)))
function transferSelected() {
targetItems.value = [...targetItems.value, ...sourceSelection.value]
sourceSelection.value = []
}
function removeSelected() {
targetItems.value = targetItems.value.filter(item => !targetSelection.value.some(t => t.value === item.value))
targetSelection.value = []
}
</script>
<template>
<div class="flex items-stretch gap-4 w-full">
<div class="flex flex-col flex-1 gap-1">
<span class="text-sm font-medium text-highlighted">Available</span>
<UListbox
v-model="sourceSelection"
:items="sourceItems"
multiple
filter
class="size-full"
/>
</div>
<div class="flex flex-col items-center justify-center gap-1">
<UButton
icon="i-lucide-chevron-right"
color="neutral"
variant="outline"
:disabled="!sourceSelection.length"
@click="transferSelected"
/>
<UButton
icon="i-lucide-chevron-left"
color="neutral"
variant="outline"
:disabled="!targetSelection.length"
@click="removeSelected"
/>
</div>
<div class="flex flex-col flex-1 gap-1">
<span class="text-sm font-medium text-highlighted">Selected</span>
<UListbox
v-model="targetSelection"
:items="targetItems"
multiple
filter
class="size-full"
/>
</div>
</div>
</template>
API (Edición española)
Props (accesorios)
| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
id | string | |
color | 'primary' | "primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral" |
size | 'md' | "sm" | "md" | "xs" | "lg" | "xl" |
items | TThe items to display in the list. | |
modelValue | _Number<_Optional<_Nullable<GetModelValue<T, VK, M, undefined>, Mod>, Mod>, Mod>The controlled value of the Listbox. Can be bound with | |
modelModifiers | Mod | |
defaultValue | _Number<_Optional<_Nullable<GetModelValue<T, VK, M, undefined>, Mod>, Mod>, Mod>The default value when not controlled. | |
multiple | false | MWhether multiple items can be selected. |
valueKey | undefined | VKWhen |
labelKey | 'label' | keyof Extract<NestedItem<T>, object> & string | DotPathKeys<Extract<NestedItem<T>, object>>The key used to get the label from the item. |
descriptionKey | 'description' | keyof Extract<NestedItem<T>, object> & string | DotPathKeys<Extract<NestedItem<T>, object>>The key used to get the description from the item. |
loading | boolean Whether the list is in a loading state. | |
loadingIcon | appConfig.ui.icons.loading | anyThe icon displayed when loading. |
filter | false | boolean | Omit<InputProps<AcceptableValue, ModelModifiers>, "modelValue" | "defaultValue"> Whether to display a filter input or not.
Can be an object to pass additional props to the input.
|
filterFields | [labelKey] | string[]The fields to filter by. |
ignoreFilter | false | boolean When |
selectedIcon | appConfig.ui.icons.check | anyThe icon displayed when an item is selected. |
virtualize | false | boolean | { overscan?: number ; estimateSize?: number | ((index: number) => number) | undefined; } | undefinedEnable virtualization for large lists. |
highlight | boolean Highlight the ring color like a focus state. | |
autofocus | boolean | |
autofocusDelay | 0 | number |
by | string | (a: AcceptableValue, b: AcceptableValue): booleanUse this to compare objects by a particular field, or pass your own comparison function for complete control over how objects are compared. | |
disabled | boolean When | |
highlightOnHover | true | boolean When |
name | stringThe name of the field. Submitted with its owning form as part of a name/value pair. | |
orientation | "vertical" | "horizontal"The orientation of the listbox. | |
required | boolean When | |
selectionBehavior | 'toggle' | "replace" | "toggle"How multiple selection should behave in the collection. |
searchTerm | '' | string |
ui | { root?: SlotClass; input?: SlotClass; content?: SlotClass; group?: SlotClass; label?: SlotClass; separator?: SlotClass; empty?: SlotClass; loading?: SlotClass; loadingIcon?: SlotClass; item?: SlotClass; itemLeadingIcon?: SlotClass; itemLeadingAvatar?: SlotClass; itemLeadingAvatarSize?: SlotClass; itemLeadingChip?: SlotClass; itemLeadingChipSize?: SlotClass; itemWrapper?: SlotClass; itemLabel?: SlotClass; itemDescription?: SlotClass; itemTrailing?: SlotClass; itemTrailingIcon?: SlotClass; } |
Slots
| Slot | Type |
|---|---|
loading | {} |
empty | { searchTerm: string; } |
item | { item: NestedItem<T>; index: number; ui: object; } |
item-leading | { item: NestedItem<T>; index: number; ui: object; } |
item-label | { item: NestedItem<T>; index: number; } |
item-description | { item: NestedItem<T>; index: number; } |
item-trailing | { item: NestedItem<T>; index: number; ui: object; } |
Emisiones
| Event | Type |
|---|---|
entryFocus | [event: CustomEvent<any>] |
highlight | [payload: { ref: HTMLElement; value: AcceptableValue; } | undefined] |
leave | [event: Event] |
change | [event: Event] |
update:modelValue | [value: _Number<_Optional<_Nullable<GetModelValue<T, VK, M, undefined>, Mod>, Mod>, Mod>] |
update:searchTerm | [value: string] |
Temas
export default defineAppConfig({
ui: {
listbox: {
slots: {
root: 'flex flex-col min-h-0 min-w-0 ring ring-inset ring-default rounded-lg overflow-hidden',
input: 'border-b border-default',
content: 'relative overflow-y-auto flex-1 max-h-60 scroll-py-1 focus:outline-none',
group: 'p-1 isolate',
label: 'font-semibold text-highlighted',
separator: '-mx-1 my-1 h-px bg-border',
empty: 'text-center text-muted',
loading: 'flex items-center justify-center text-muted',
loadingIcon: 'animate-spin shrink-0',
item: [
'group relative w-full flex items-start select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-md data-disabled:cursor-not-allowed data-disabled:opacity-75 text-default data-highlighted:not-data-disabled:text-highlighted data-highlighted:not-data-disabled:before:bg-elevated/50',
'transition-colors before:transition-colors'
],
itemLeadingIcon: [
'shrink-0 text-dimmed group-data-highlighted:not-group-data-disabled:text-default',
'transition-colors'
],
itemLeadingAvatar: 'shrink-0',
itemLeadingAvatarSize: '',
itemLeadingChip: 'shrink-0',
itemLeadingChipSize: '',
itemWrapper: 'flex-1 flex flex-col min-w-0',
itemLabel: 'truncate',
itemDescription: 'truncate text-muted',
itemTrailing: 'ms-auto inline-flex gap-1.5 items-center',
itemTrailingIcon: 'shrink-0'
},
variants: {
size: {
xs: {
label: 'p-1 text-[10px]/3 gap-1',
empty: 'py-3 text-xs',
loading: 'py-3',
loadingIcon: 'size-4',
item: 'p-1 text-xs gap-1',
itemLeadingIcon: 'size-4',
itemLeadingAvatarSize: '3xs',
itemLeadingChip: 'size-4',
itemLeadingChipSize: 'sm',
itemTrailingIcon: 'size-4'
},
sm: {
label: 'p-1.5 text-[10px]/3 gap-1.5',
empty: 'py-4 text-xs',
loading: 'py-4',
loadingIcon: 'size-4',
item: 'p-1.5 text-xs gap-1.5',
itemLeadingIcon: 'size-4',
itemLeadingAvatarSize: '3xs',
itemLeadingChip: 'size-4',
itemLeadingChipSize: 'sm',
itemTrailingIcon: 'size-4'
},
md: {
label: 'p-1.5 text-xs gap-1.5',
empty: 'py-6 text-sm',
loading: 'py-6',
loadingIcon: 'size-5',
item: 'p-1.5 text-sm gap-1.5',
itemLeadingIcon: 'size-5',
itemLeadingAvatarSize: '2xs',
itemLeadingChip: 'size-5',
itemLeadingChipSize: 'md',
itemTrailingIcon: 'size-5'
},
lg: {
label: 'p-2 text-xs gap-2',
empty: 'py-7 text-sm',
loading: 'py-7',
loadingIcon: 'size-5',
item: 'p-2 text-sm gap-2',
itemLeadingIcon: 'size-5',
itemLeadingAvatarSize: '2xs',
itemLeadingChip: 'size-5',
itemLeadingChipSize: 'md',
itemTrailingIcon: 'size-5'
},
xl: {
label: 'p-2 text-sm gap-2',
empty: 'py-8 text-base',
loading: 'py-8',
loadingIcon: 'size-6',
item: 'p-2 text-base gap-2',
itemLeadingIcon: 'size-6',
itemLeadingAvatarSize: 'xs',
itemLeadingChip: 'size-6',
itemLeadingChipSize: 'lg',
itemTrailingIcon: 'size-6',
itemDescription: 'text-sm'
}
},
color: {
primary: {
root: 'outline-primary/25 has-focus-visible:outline-3 has-focus-visible:ring-primary'
},
secondary: {
root: 'outline-secondary/25 has-focus-visible:outline-3 has-focus-visible:ring-secondary'
},
success: {
root: 'outline-success/25 has-focus-visible:outline-3 has-focus-visible:ring-success'
},
info: {
root: 'outline-info/25 has-focus-visible:outline-3 has-focus-visible:ring-info'
},
warning: {
root: 'outline-warning/25 has-focus-visible:outline-3 has-focus-visible:ring-warning'
},
error: {
root: 'outline-error/25 has-focus-visible:outline-3 has-focus-visible:ring-error'
},
neutral: {
root: 'outline-inverted/25 has-focus-visible:outline-3 has-focus-visible:ring-inverted'
}
},
virtualize: {
true: {
content: 'p-1 isolate'
},
false: {
content: 'divide-y divide-default'
}
},
disabled: {
true: {
root: 'opacity-75 cursor-not-allowed'
}
},
highlight: {
true: ''
}
},
compoundVariants: [
{
color: 'primary',
highlight: true,
class: {
root: 'ring ring-inset ring-primary'
}
},
{
color: 'neutral',
highlight: true,
class: {
root: 'ring ring-inset ring-inverted'
}
}
],
defaultVariants: {
color: 'primary',
size: 'md'
}
}
}
})import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
listbox: {
slots: {
root: 'flex flex-col min-h-0 min-w-0 ring ring-inset ring-default rounded-lg overflow-hidden',
input: 'border-b border-default',
content: 'relative overflow-y-auto flex-1 max-h-60 scroll-py-1 focus:outline-none',
group: 'p-1 isolate',
label: 'font-semibold text-highlighted',
separator: '-mx-1 my-1 h-px bg-border',
empty: 'text-center text-muted',
loading: 'flex items-center justify-center text-muted',
loadingIcon: 'animate-spin shrink-0',
item: [
'group relative w-full flex items-start select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-md data-disabled:cursor-not-allowed data-disabled:opacity-75 text-default data-highlighted:not-data-disabled:text-highlighted data-highlighted:not-data-disabled:before:bg-elevated/50',
'transition-colors before:transition-colors'
],
itemLeadingIcon: [
'shrink-0 text-dimmed group-data-highlighted:not-group-data-disabled:text-default',
'transition-colors'
],
itemLeadingAvatar: 'shrink-0',
itemLeadingAvatarSize: '',
itemLeadingChip: 'shrink-0',
itemLeadingChipSize: '',
itemWrapper: 'flex-1 flex flex-col min-w-0',
itemLabel: 'truncate',
itemDescription: 'truncate text-muted',
itemTrailing: 'ms-auto inline-flex gap-1.5 items-center',
itemTrailingIcon: 'shrink-0'
},
variants: {
size: {
xs: {
label: 'p-1 text-[10px]/3 gap-1',
empty: 'py-3 text-xs',
loading: 'py-3',
loadingIcon: 'size-4',
item: 'p-1 text-xs gap-1',
itemLeadingIcon: 'size-4',
itemLeadingAvatarSize: '3xs',
itemLeadingChip: 'size-4',
itemLeadingChipSize: 'sm',
itemTrailingIcon: 'size-4'
},
sm: {
label: 'p-1.5 text-[10px]/3 gap-1.5',
empty: 'py-4 text-xs',
loading: 'py-4',
loadingIcon: 'size-4',
item: 'p-1.5 text-xs gap-1.5',
itemLeadingIcon: 'size-4',
itemLeadingAvatarSize: '3xs',
itemLeadingChip: 'size-4',
itemLeadingChipSize: 'sm',
itemTrailingIcon: 'size-4'
},
md: {
label: 'p-1.5 text-xs gap-1.5',
empty: 'py-6 text-sm',
loading: 'py-6',
loadingIcon: 'size-5',
item: 'p-1.5 text-sm gap-1.5',
itemLeadingIcon: 'size-5',
itemLeadingAvatarSize: '2xs',
itemLeadingChip: 'size-5',
itemLeadingChipSize: 'md',
itemTrailingIcon: 'size-5'
},
lg: {
label: 'p-2 text-xs gap-2',
empty: 'py-7 text-sm',
loading: 'py-7',
loadingIcon: 'size-5',
item: 'p-2 text-sm gap-2',
itemLeadingIcon: 'size-5',
itemLeadingAvatarSize: '2xs',
itemLeadingChip: 'size-5',
itemLeadingChipSize: 'md',
itemTrailingIcon: 'size-5'
},
xl: {
label: 'p-2 text-sm gap-2',
empty: 'py-8 text-base',
loading: 'py-8',
loadingIcon: 'size-6',
item: 'p-2 text-base gap-2',
itemLeadingIcon: 'size-6',
itemLeadingAvatarSize: 'xs',
itemLeadingChip: 'size-6',
itemLeadingChipSize: 'lg',
itemTrailingIcon: 'size-6',
itemDescription: 'text-sm'
}
},
color: {
primary: {
root: 'outline-primary/25 has-focus-visible:outline-3 has-focus-visible:ring-primary'
},
secondary: {
root: 'outline-secondary/25 has-focus-visible:outline-3 has-focus-visible:ring-secondary'
},
success: {
root: 'outline-success/25 has-focus-visible:outline-3 has-focus-visible:ring-success'
},
info: {
root: 'outline-info/25 has-focus-visible:outline-3 has-focus-visible:ring-info'
},
warning: {
root: 'outline-warning/25 has-focus-visible:outline-3 has-focus-visible:ring-warning'
},
error: {
root: 'outline-error/25 has-focus-visible:outline-3 has-focus-visible:ring-error'
},
neutral: {
root: 'outline-inverted/25 has-focus-visible:outline-3 has-focus-visible:ring-inverted'
}
},
virtualize: {
true: {
content: 'p-1 isolate'
},
false: {
content: 'divide-y divide-default'
}
},
disabled: {
true: {
root: 'opacity-75 cursor-not-allowed'
}
},
highlight: {
true: ''
}
},
compoundVariants: [
{
color: 'primary',
highlight: true,
class: {
root: 'ring ring-inset ring-primary'
}
},
{
color: 'neutral',
highlight: true,
class: {
root: 'ring ring-inset ring-inverted'
}
}
],
defaultVariants: {
color: 'primary',
size: 'md'
}
}
}
})
]
})