<script lang="ts" setup>
import { ADropdownMenuContent, ADropdownMenuGroup, ADropdownMenuItem, ADropdownMenuLabel, ADropdownMenuPortal, ADropdownMenuRoot, ADropdownMenuSub, ADropdownMenuSubContent, ADropdownMenuSubTrigger, ADropdownMenuTrigger } from 'akar';
const contentClasses = 'rounded-md bg-background flex flex-col min-w-32 ring ring-ring shadow-lg origin-$akar-context-menu-content-transform-origin overflow-hidden animate-in fade-in-80 data-[state=closed]:(animate-out fade-out-0 zoom-out-95) data-[state=open]:(animate-in fade-in-0 zoom-in-95) data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2';
const itemClasses = 'group text-sm color-text p-1.5 outline-none flex gap-1.5 w-full select-none transition-colors-280 items-start relative data-[highlighted]:color-text-highlighted data-[state=open]:color-text-highlighted before:(rounded-md content-empty transition-colors-280 inset-px absolute -z-1) data-[disabled]:(opacity-75 cursor-not-allowed) data-[highlighted]:before:bg-background-elevated/50 data-[state=open]:before:bg-background-elevated/50';
const leadingIconClasses = 'shrink-0 color-text-dimmed group-data-[highlighted]:color-text group-data-[state=open]:color-text transition-colors-280 size-5';
</script>
<template>
<ADropdownMenuRoot>
<ADropdownMenuTrigger
class="text-sm color-text font-500 px-2.5 py-1.5 rounded-md bg-background inline-flex gap-1.5 ring ring-ring-accented ring-inset transition-colors-280 items-center focus:outline-none active:bg-background-elevated hover:bg-background-elevated focus-visible:(ring-2 ring-ring-inverted)"
aria-label="Customise options"
>
<i class="i-lucide:menu" />
</ADropdownMenuTrigger>
<ADropdownMenuPortal>
<ADropdownMenuContent
:class="contentClasses"
:side-offset="5"
>
<div class="flex-1 relative overflow-y-auto scroll-py-1 divide-divide divide-y">
<ADropdownMenuGroup class="p-1 isolate">
<ADropdownMenuLabel class="text-sm color-text-highlighted font-semibold p-1.5 flex gap-1.5 w-full items-center">
<span class="align-middle rounded-full bg-background-elevated inline-flex shrink-0 size-5 select-none items-center justify-center">
<img
src="https://github.com/praburangki.png"
class="rounded-inherit size-full object-cover"
>
</span>
<span class="text-start flex flex-1 flex-col min-w-0">
My account
</span>
</ADropdownMenuLabel>
</ADropdownMenuGroup>
<ADropdownMenuGroup class="p-1 isolate">
<ADropdownMenuSub>
<ADropdownMenuSubTrigger
as="button"
:class="itemClasses"
>
<span class="text-start flex flex-1 flex-col min-w-0">
<span class="truncate">Appearance</span>
<span class="color-text-muted truncate">Change the appearance of the app</span>
</span>
<span class="ms-auto inline-flex gap-1.5 items-center"><span class="i-lucide:chevron-right shrink-0 size-5" /></span>
</ADropdownMenuSubTrigger>
<ADropdownMenuPortal>
<ADropdownMenuSubContent :class="contentClasses">
<div class="flex-1 relative overflow-y-auto scroll-py-1 divide-divide divide-y">
<ADropdownMenuGroup class="p-1 isolate">
<ADropdownMenuItem as-child>
<button :class="itemClasses">
<span
class="i-lucide:monitor"
:class="leadingIconClasses"
/>
<span class="text-start flex flex-1 flex-col min-w-0"><span class="truncate">System</span></span>
</button>
</ADropdownMenuItem>
<ADropdownMenuItem as-child>
<button :class="itemClasses">
<span
class="i-lucide:sun"
:class="leadingIconClasses"
/>
<span class="text-start flex flex-1 flex-col min-w-0"><span class="truncate">Light</span></span>
</button>
</ADropdownMenuItem>
<ADropdownMenuItem as-child>
<button :class="itemClasses">
<span
class="i-lucide:moon"
:class="leadingIconClasses"
/>
<span class="text-start flex flex-1 flex-col min-w-0"><span class="truncate">Dark</span></span>
</button>
</ADropdownMenuItem>
</ADropdownMenuGroup>
</div>
</ADropdownMenuSubContent>
</ADropdownMenuPortal>
</ADropdownMenuSub>
</ADropdownMenuGroup>
<ADropdownMenuGroup class="p-1 isolate">
<ADropdownMenuItem as-child>
<button :class="itemClasses">
Show Sidebar
</button>
</ADropdownMenuItem>
<ADropdownMenuItem as-child>
<button :class="itemClasses">
Show Toolbar
</button>
</ADropdownMenuItem>
<ADropdownMenuItem
as-child
disabled
>
<button :class="itemClasses">
Collapse Pinned Tabs
</button>
</ADropdownMenuItem>
</ADropdownMenuGroup>
</div>
</ADropdownMenuContent>
</ADropdownMenuPortal>
</ADropdownMenuRoot>
</template>
Import all parts and piece them together.
<script setup lang="ts">
import {
ADropdownMenuArrow,
ADropdownMenuCheckboxItem,
ADropdownMenuContent,
ADropdownMenuGroup,
ADropdownMenuItem,
ADropdownMenuItemIndicator,
ADropdownMenuLabel,
ADropdownMenuPortal,
ADropdownMenuRadioGroup,
ADropdownMenuRadioItem,
ADropdownMenuRoot,
ADropdownMenuSeparator,
ADropdownMenuSub,
ADropdownMenuSubContent,
ADropdownMenuSubTrigger,
ADropdownMenuTrigger,
} from 'akar';
</script>
<template>
<ADropdownMenuRoot>
<ADropdownMenuTrigger />
<ADropdownMenuPortal>
<ADropdownMenuContent>
<ADropdownMenuLabel />
<ADropdownMenuItem />
<ADropdownMenuGroup>
<ADropdownMenuItem />
</ADropdownMenuGroup>
<ADropdownMenuCheckboxItem>
<ADropdownMenuItemIndicator />
</ADropdownMenuCheckboxItem>
<ADropdownMenuRadioGroup>
<ADropdownMenuRadioItem>
<ADropdownMenuItemIndicator />
</ADropdownMenuRadioItem>
</ADropdownMenuRadioGroup>
<ADropdownMenuSub>
<ADropdownMenuSubTrigger />
<ADropdownMenuPortal>
<ADropdownMenuSubContent />
</ADropdownMenuPortal>
</ADropdownMenuSub>
<ADropdownMenuSeparator />
<ADropdownMenuArrow />
</ADropdownMenuContent>
</ADropdownMenuPortal>
</ADropdownMenuRoot>
</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 dropdown menu.
| Prop | Default | Type |
|---|---|---|
defaultOpen | booleanThe open state of the dropdown menu when it is initially rendered. Use when you do not need to control its open state. | |
dir | 'ltr' | 'rtl'The reading direction of the combobox when applicable. If omitted, inherits globally from | |
modal | true | booleanThe modality of the dropdown menu. When set to |
open | boolean |
| Event | Type |
|---|---|
update:open | [payload: boolean]Event handler called when the open state of the dialog changes. |
| Slot | Type |
|---|---|
open | booleanThe controlled open state of the menu. Can be used as |
The button that toggles the dropdown menu. By default, the ADropdownMenuContent will position itself against the trigger.
| 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. | |
disabled | booleanWhen |
| Attribute | Value |
|---|---|
[data-state] | 'open' | 'closed' |
[data-disabled] | Present when disabled |