검색, 가상화 및 리치 항목 렌더링이 포함된 선택 가능한 항목 목록입니다.

Usage

v-model 지시문을 사용하여 ListBox의 값을 제어하거나 default-value prop의 상태를 제어할 필요가 없을 때 초기 값을 설정합니다.

France
Germany
Italy
Spain
Netherlands
Poland
Belgium
Portugal
Austria
Sweden
<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>

Items 파일

items prop을 다음 속성을 가진 오브젝트 배열로 사용합니다.

FranceThe Hexagon
GermanyThe Federal Republic
ItalyThe Boot
SpainThe Bull Skin
<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>

배열 배열을 items prop에 전달하여 개별 항목 그룹을 표시할 수도 있습니다.

France
Germany
Italy
Brazil
Argentina
<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>

Multiple 다중

multiple prop을 사용하여 여러 항목을 선택할 수 있습니다. 활성화되면 v-model가 배열이 됩니다.

France
Germany
Italy
Spain
<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 키

value-key prop.Defaults to undefined를 사용하여 전체 객체가 아닌 객체의 단일 속성을 바인딩하도록 선택할 수 있습니다.

France
Germany
Italy
Spain
<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 필터

filter 소품을 사용하여 필터 입력을 표시하거나 객체를 전달하여 Input 구성 요소를 사용자 정의합니다. 기본값은 false입니다.

France
Germany
Italy
Spain
Netherlands
Poland
<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>

선택된 아이콘

selected-icon 소품을 사용하여 항목을 선택할 때 아이콘을 사용자 정의합니다. 기본값은 i-lucide-check입니다.

France
Germany
Italy
Spain
<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>

Size 크기

size prop을 사용하여 ListBox의 크기를 변경합니다.

France
Germany
Italy
Spain
<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>

loading 중

loading prop을 사용하여 로딩 지시자를 표시하고, loading-icon prop을 사용하여 아이콘을 사용자 정의합니다.

<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>

비활성 화 됨

disabled prop을 사용하여 ListBox와의 사용자 상호 작용을 방지합니다.

France
Germany
Italy
Spain
<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>

examples 예제

With 아이템 타입

type 속성을 separator와 함께 사용하여 항목 사이의 구분 기호를 표시하거나 label를 사용하여 레이블을 표시할 수 있습니다.

Fruits
Apple
Banana
Blueberry
Grapes
Pineapple
Vegetables
Aubergine
Broccoli
Carrot
Courgette
Leek
<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 항목을 그룹 제목으로 사용할 때 배열 배열을 전달하여 레이블이 그룹과 함께 필터링되도록 합니다.

With 항목의 아이콘

icon 속성을 사용하여 Icon를 항목 내부에 표시할 수 있습니다.

Backlog
Todo
In Progress
Done
<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>

항목에 아바타 포함

avatar 속성을 사용하여 Avatar를 항목 내부에 표시할 수 있습니다.

benjamincanac
HugoRCD
atinux
romhml
<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>

With 칩 in items

chip 속성을 사용하여 Chip를 항목 안에 표시할 수 있습니다.

bug
feature
enhancement
<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>

항목에 설명 포함

description 속성을 사용하여 레이블 아래에 추가 텍스트를 표시할 수 있습니다.

FranceThe Hexagon
GermanyThe Federal Republic
ItalyThe Boot
SpainThe Bull Skin
<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 선택된 항목

default-value prop 또는 v-model 지시문을 사용하여 선택한 항목을 제어할 수 있습니다.

France
Germany
Italy
Spain
Netherlands
Poland
<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 검색 용어

v-model:search-term 지시문을 사용하여 검색 용어를 제어합니다.

France
<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>

Ignore 필터 포함

ignore-filter prop을 true로 설정하여 내부 검색을 비활성화하고 자신의 검색 논리를 사용합니다.

No data
<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를 사용하여 API 호출을 설명합니다.

With 필터 필드 포함

filter-fields Prop을 필드 배열과 함께 사용하여 필터링합니다. 기본값은 [labelKey]입니다.

No data
<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>

가상화 지원

virtualize prop을 사용하여 큰 목록에 대해 부울 또는 { 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 전송 리스트

Button 컨트롤을 사용하여 두 개의 ListBox 구성 요소를 구성하여 전송 목록 패턴을 빌드할 수 있습니다.

Available
France
Germany
Italy
Spain
Netherlands
Poland
Belgium
Portugal
Selected
No data
<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 사용

Props 코드 코드

Prop Default Type
as
'div'
any

The 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
T

The 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 v-model.

modelModifiers
Mod
defaultValue
_Number<_Optional<_Nullable<GetModelValue<T, VK, M, undefined>, Mod>, Mod>, Mod>

The default value when not controlled.

multiple
false
M

Whether multiple items can be selected.

valueKey
undefined
VK

When items is an array of objects, select the field to use as the value instead of the object itself.

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
any

The 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. { placeholder: 'Search...', variant: 'none' }

filterFields
[labelKey]
string[]

The fields to filter by.

ignoreFilter
false
boolean

When true, disable the default filters, useful for custom filtering (useAsyncData, useFetch, etc.).

selectedIcon
appConfig.ui.icons.check
any

The icon displayed when an item is selected.

virtualize
false
boolean | { overscan?: number ; estimateSize?: number | ((index: number) => number) | undefined; } | undefined

Enable 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): boolean

Use 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 true, prevents the user from interacting with listbox

highlightOnHover
true
boolean

When true, hover over item will trigger highlight

name
string

The name of the field. Submitted with its owning form as part of a name/value pair.

orientation
"vertical" | "horizontal"

The orientation of the listbox.
Mainly so arrow navigation is done accordingly (left & right vs. up & down)

required
boolean

When true, indicates that the user must set the value before the owning form can be submitted.

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; }

슬롯

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; }

Emits 파일

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]

Theme 테마

app.config.ts
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'
      }
    }
  }
})
vite.config.ts
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'
          }
        }
      }
    })
  ]
})
Some colors in compoundVariants are omitted for readability. Check out the source code on GitHub.

Changelog 파일

No recent changes