Use o componente Accordion para exibir uma lista de itens recolhíveis.
<script setup lang="ts">
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Is Nitro UI free to use?',
content: 'Yes! Nitro UI is completely free and open source under the MIT license. All 125+ components are available to everyone.'
},
{
label: 'Can I use Nitro UI with Vue without Nuxt?',
content: 'Yes! While optimized for Nuxt, Nitro UI works perfectly with standalone Vue projects via our Vite plugin. You can follow the [installation guide](/docs/getting-started/installation/vue) to get started.'
},
{
label: 'Is Nitro UI production-ready?',
content: 'Yes! Nitro UI is used in production by thousands of applications with extensive tests, regular updates, and active maintenance.'
}
])
</script>
<template>
<NAccordion :items="items" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Is Nitro UI free to use?',
content: 'Yes! Nitro UI is completely free and open source under the MIT license. All 125+ components are available to everyone.'
},
{
label: 'Can I use Nitro UI with Vue without Nuxt?',
content: 'Yes! While optimized for Nuxt, Nitro UI works perfectly with standalone Vue projects via our Vite plugin. You can follow the [installation guide](/docs/getting-started/installation/vue) to get started.'
},
{
label: 'Is Nitro UI production-ready?',
content: 'Yes! Nitro UI is used in production by thousands of applications with extensive tests, regular updates, and active maintenance.'
}
])
</script>
<template>
<NAccordion :items="items" />
</template>
Use a prop items como um array de objetos com as seguintes propriedades:
label?: stringicon?: stringtrailingIcon?: stringcontent?: stringvalue?: stringdisabled?: booleanslot?: stringclass?: anyui?: { item?: ClassNameValue, header?: ClassNameValue, trigger?: ClassNameValue, leadingIcon?: ClassNameValue, label?: ClassNameValue, trailingIcon?: ClassNameValue, content?: ClassNameValue, body?: ClassNameValue }<script setup lang="ts">
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion :items="items" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion :items="items" />
</template>
Defina a prop type como multiple para permitir que vários itens fiquem ativos ao mesmo tempo. O padrão é single.
<script setup lang="ts">
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion type="multiple" :items="items" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion type="multiple" :items="items" />
</template>
Quando type é single, você pode definir a prop collapsible como false para evitar que o item ativo seja recolhido.
<script setup lang="ts">
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion :collapsible="false" :items="items" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion :collapsible="false" :items="items" />
</template>
Use a prop unmount-on-hide para evitar que o conteúdo seja desmontado quando o accordion é recolhido. O padrão é true.
<script setup lang="ts">
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion :unmount-on-hide="false" :items="items" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion :unmount-on-hide="false" :items="items" />
</template>
Use a propriedade disabled para desabilitar o Accordion.
Você também pode desabilitar um item específico usando a propriedade disabled no objeto do item.
<script setup lang="ts">
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.',
disabled: true
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion disabled :items="items" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.',
disabled: true
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion disabled :items="items" />
</template>
Use a prop trailing-icon para personalizar o Icon à direita de cada item. O padrão é i-lucide-chevron-down.
trailingIcon no objeto do item.<script setup lang="ts">
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.',
trailingIcon: 'i-lucide-plus'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion trailing-icon="i-lucide-arrow-down" :items="items" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { AccordionItem } from '@nitro/ui'
const items = ref<AccordionItem[]>([
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.',
trailingIcon: 'i-lucide-plus'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
])
</script>
<template>
<NAccordion trailing-icon="i-lucide-arrow-down" :items="items" />
</template>
Você pode controlar o item ativo usando a prop default-value ou a diretiva v-model com o value do item. Se nenhum value for fornecido, o padrão é o índice como string.
value-key para alterar a chave usada para corresponder os itens quando um v-model ou default-value é fornecido.type="multiple", certifique-se de passar um array para a prop default-value ou para a diretiva v-model.Use o composable useSortable de @vueuse/integrations para habilitar a funcionalidade de arrastar e soltar no Accordion. Essa integração envolve o Sortable.js para oferecer uma experiência de arrastar e soltar fluida.
Use o slot #body para personalizar o corpo de cada item.
#body inclui alguns estilos predefinidos; use o slot #content se você quiser começar do zero.Use o slot #content para personalizar o conteúdo de cada item.
Use a propriedade slot para personalizar um item específico.
Você terá acesso aos seguintes slots:
#{{ item.slot }}#{{ item.slot }}-bodyVocê pode usar o componente MDC do @nuxtjs/mdc para renderizar markdown nos itens do accordion.
| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
items | T[] | |
trailingIcon | appConfig.ui.icons.chevronDown | anyThe icon displayed on the right side of the trigger. |
labelKey | 'label' | keyof Extract<NestedItem<T>, object> & string | DotPathKeys<Extract<NestedItem<T>, object>>The key used to get the label from the item. |
collapsible | true | boolean When type is "single", allows closing content when clicking trigger for an open item. When type is "multiple", this prop has no effect. |
defaultValue | string | string[]The default active value of the item(s). Use when you do not need to control the state of the item(s). | |
modelValue | string | string[]The controlled value of the active item(s). Use this when you need to control the state of the items. Can be binded with | |
type | 'single' | "single" | "multiple"Determines whether a "single" or "multiple" items can be selected at a time. This prop will overwrite the inferred type from |
disabled | false | boolean When |
unmountOnHide | true | boolean When |
ui | { root?: SlotClass; item?: SlotClass; header?: SlotClass; trigger?: SlotClass; content?: SlotClass; body?: SlotClass; leadingIcon?: SlotClass; trailingIcon?: SlotClass; label?: SlotClass; } |
| Slot | Type |
|---|---|
leading | { item: T; index: number; open: boolean; ui: object; } |
default | { item: T; index: number; open: boolean; } |
trailing | { item: T; index: number; open: boolean; ui: object; } |
content | { item: T; index: number; open: boolean; ui: object; } |
body | { item: T; index: number; open: boolean; ui: object; } |
| Event | Type |
|---|---|
update:modelValue | [value: string | string[] | undefined] |
export default defineAppConfig({
ui: {
accordion: {
slots: {
root: 'w-full',
item: 'border-b border-default last:border-b-0',
header: 'flex',
trigger: 'group flex-1 flex items-center gap-1.5 font-medium text-sm py-3.5 focus-visible:outline-primary min-w-0',
content: 'data-[state=open]:animate-[accordion-down_200ms_ease-out] data-[state=closed]:animate-[accordion-up_200ms_ease-out] overflow-hidden focus:outline-none',
body: 'text-sm pb-3.5',
leadingIcon: 'shrink-0 size-5',
trailingIcon: 'shrink-0 size-5 ms-auto group-data-[state=open]:rotate-180 transition-transform duration-200',
label: 'text-start break-words'
},
variants: {
disabled: {
true: {
trigger: 'cursor-not-allowed opacity-75'
}
}
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nitro/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
accordion: {
slots: {
root: 'w-full',
item: 'border-b border-default last:border-b-0',
header: 'flex',
trigger: 'group flex-1 flex items-center gap-1.5 font-medium text-sm py-3.5 focus-visible:outline-primary min-w-0',
content: 'data-[state=open]:animate-[accordion-down_200ms_ease-out] data-[state=closed]:animate-[accordion-up_200ms_ease-out] overflow-hidden focus:outline-none',
body: 'text-sm pb-3.5',
leadingIcon: 'shrink-0 size-5',
trailingIcon: 'shrink-0 size-5 ms-auto group-data-[state=open]:rotate-180 transition-transform duration-200',
label: 'text-start break-words'
},
variants: {
disabled: {
true: {
trigger: 'cursor-not-allowed opacity-75'
}
}
}
}
}
})
]
})