<script setup lang="ts">
import { ACollapsibleContent, ACollapsibleRoot, ACollapsibleTrigger } from 'akar';
</script>
<template>
<ACollapsibleRoot
class="text-sm w-[300px]"
>
<div class="flex items-center justify-between">
<span class="text-stone-800 font-medium dark:text-white"> @bebedag starred 3 repos </span>
<ACollapsibleTrigger
class="group color-primary outline-none border rounded-full inline-flex size-6 transition-colors-280 items-center justify-center data-[state=closed]:bg-white data-[state=open]:(bg-background-accented) hover:(bg-background-accented)"
>
<i
class="group-data-[state=open]:i-lucide:x group-data-[state=closed]:i-lucide:arrow-down size-3.5"
/>
</ACollapsibleTrigger>
</div>
<div class="mt-2 p-2 border border-border-accented rounded-lg bg-white">
<span class="color-primary">akar</span>
</div>
<ACollapsibleContent class="overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down">
<div class="my-2 p-2 border border-border-accented rounded-lg bg-white">
<span class="color-primary">@vuejs/core</span>
</div>
<div class="my-2 p-2 border border-border-accented rounded-lg bg-white">
<span class="color-primary">@vinicunca/perkakas</span>
</div>
</ACollapsibleContent>
</ACollapsibleRoot>
</template>
Import the components and piece the parts together.
<script setup>
import { ACollapsibleContent, ACollapsibleRoot, ACollapsibleTrigger } from 'akar';
</script>
<template>
<ACollapsibleRoot>
<ACollapsibleTrigger />
<ACollapsibleContent />
</ACollapsibleRoot>
</template>
One benefit of using Akar is its flexibility and low-level control over the components. However, this also means that you may need to manually construct more complex UI elements by combining multiple Akar components together.
If you feel there's a lot of elements that needs to be constructed manually using Akar, consider using Pohon UI instead. It provides a higher-level abstraction over Akar components with pre-defined styles and behaviors that can help you build UIs faster.
Contains all the parts of a collapsible
| Prop | Default | Type |
|---|---|---|
as | 'div' | APrimitiveAsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
defaultOpen | false | booleanThe open state of the collapsible when it is initially rendered. |
disabled | booleanWhen | |
open | boolean | |
unmountOnHide | true | booleanWhen |
| Event | Type |
|---|---|
update:open | [value: boolean]Event handler called when the open state of the collapsible changes. |
| Slot | Type |
|---|---|
open | booleanThe controlled open state of the collapsible. Can be binded with |
| Attribute | Value |
|---|---|
[data-state] | 'open' | 'closed' |
[data-disabled] | Present when disabled |
The button that toggles the collapsible
| Prop | Default | Type |
|---|---|---|
as | 'button' | APrimitiveAsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
| Attribute | Value |
|---|---|
[data-state] | 'open' | 'closed' |
[data-disabled] | Present when disabled |
The component that contains the collapsible content.
| Prop | Default | Type |
|---|---|---|
as | 'div' | APrimitiveAsTag | ComponentThe element or component this component should render as. Can be overwritten by |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
forceMount | booleanUsed to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries. |
| Event | Type |
|---|---|
contentFound | [(void)?] |
| Attribute | Value |
|---|---|
[data-state] | 'open' | 'closed' |
[data-disabled] | Present when disabled |
| Variable | Description |
|---|---|
--akar-collapsible-content-width | The width of the content when it opens/closes |
--akar-collapsible-content-height | The height of the content when it opens/closes |
Use the --akar-collapsible-content-width and/or --akar-collapsible-content-height CSS variables to animate the size of the content when it opens/closes. Here's a demo:
// index.vue
<script setup>
import { ACollapsibleContent, ACollapsibleRoot, ACollapsibleTrigger } from 'akar';
import './styles.css';
</script>
<template>
<ACollapsibleRoot>
<ACollapsibleTrigger>…</ACollapsibleTrigger>
<ACollapsibleContent class="ACollapsibleContent">
…
</ACollapsibleContent>
</ACollapsibleRoot>
</template>
/* styles.css */
.ACollapsibleContent {
overflow: hidden;
}
.ACollapsibleContent[data-state='open'] {
animation: collapsible-down 300ms ease-out;
}
.ACollapsibleContent[data-state='closed'] {
animation: collapsible-up 300ms ease-out;
}
@keyframes collapsible-down {
from {
height: 0;
}
to {
height: var(--akar-collapsible-content-height);
}
}
@keyframes collapsible-up {
from {
height: var(--akar-collapsible-content-height);
}
to {
height: 0;
}
}
animate-collapsible-up and animate-collapsible-down are available right out of the box, saving you the step of manually creating them.By default hidden content will be removed, use :unmountOnHide="false" to keep the content always available.
This will also allow browser to search the hidden text, and open the collapsible.
<script setup>
import { ACollapsibleRoot } from 'akar';
</script>
<template>
<ACollapsibleRoot :unmount-on-hide="false">
…
</ACollapsibleRoot>
</template>
Adheres to the Disclosure WAI-ARIA design pattern.
| Key | Description |
|---|---|
Space | Opens/closes the collapsible |
Enter | Opens/closes the collapsible |