<script setup lang="ts">
import { Button, DisclosureIcon, DropdownMenu, DropdownMenuItem } from '@hina-ui/vue'
</script>
<template>
<DropdownMenu label="Sort by">
<Button variant="outline" tone="neutral">
<template #trailing>
<DisclosureIcon />
</template>
Recently updated
</Button>
<template #content>
<DropdownMenuItem>Recently updated</DropdownMenuItem>
<DropdownMenuItem>Release date</DropdownMenuItem>
<DropdownMenuItem>Most saved</DropdownMenuItem>
</template>
</DropdownMenu>
</template>
Usage
import { DisclosureIcon } from '@hina-ui/vue'
The indicator is the arrow on a disclosure control that turns as the region opens. Every disclosure component shares this one piece, and most of the time you never place it yourself: CollapsibleTrigger brings its own, and so will Accordion, Select and Tree.
There is one case that needs it: when the trigger comes from the caller. A DropdownMenu trigger is any control at all, and Collapsible behaves the same way once it goes through as-child.
Drop it into the trigger and stop there — no classes, no transition to handle. The trigger carries the marker the indicator looks for.
Examples
Direction
down rests pointing down and turns a half circle, which suits dropdowns and accordions. end rests pointing to the end of the line and turns a quarter, which suits sidebar groups and tree nodes.
<script setup lang="ts">
import { Button, DisclosureIcon, DropdownMenu, DropdownMenuItem, Inline } from '@hina-ui/vue'
</script>
<template>
<Inline>
<DropdownMenu label="Opens downwards">
<Button variant="outline" tone="neutral">
<template #trailing>
<DisclosureIcon />
</template>
down
</Button>
<template #content>
<DropdownMenuItem>Rests pointing down</DropdownMenuItem>
<DropdownMenuItem>Turns a half circle</DropdownMenuItem>
</template>
</DropdownMenu>
<DropdownMenu label="Opens a level">
<Button variant="outline" tone="neutral">
<template #trailing>
<DisclosureIcon direction="end" />
</template>
end
</Button>
<template #content>
<DropdownMenuItem>Rests pointing to the line end</DropdownMenuItem>
<DropdownMenuItem>Turns a quarter</DropdownMenuItem>
</template>
</DropdownMenu>
</Inline>
</template>
It is end rather than right so the whole thing can flip in right-to-left languages.
Another glyph
The default slot replaces the glyph while the component keeps owning the rotation. A plus turned a quarter lands exactly on a cross.
<script setup lang="ts">
import { Plus } from '@lucide/vue'
import { Button, DisclosureIcon, DropdownMenu, DropdownMenuItem } from '@hina-ui/vue'
</script>
<template>
<DropdownMenu label="Add to">
<Button variant="outline" tone="neutral">
<template #trailing>
<DisclosureIcon direction="end">
<Plus />
</DisclosureIcon>
</template>
Add to
</Button>
<template #content>
<DropdownMenuItem>Want to read</DropdownMenuItem>
<DropdownMenuItem>Reading</DropdownMenuItem>
<DropdownMenuItem>Read</DropdownMenuItem>
</template>
</DropdownMenu>
</template>
When the state lives outside
Pass open when the state is held in a variable of your own rather than on an ancestor trigger. Once passed, the indicator stops reading its ancestors.
open: false
<script setup lang="ts">
import { ref } from 'vue'
import { Button, DisclosureIcon, Inline, Text } from '@hina-ui/vue'
const open = ref(false)
</script>
<template>
<Inline>
<Button variant="soft" tone="neutral" @click="open = !open">
<template #trailing>
<DisclosureIcon :open="open" />
</template>
State held outside
</Button>
<Text tone="muted" size="sm">open: {{ open }}</Text>
</Inline>
</template>
Boundary
This is a state indicator, not a direction marker. The > between breadcrumbs and the arrow at the end of a submenu never change with a state; they keep their own static icons.
Accessibility
- The indicator is always
aria-hidden. The open state is already announced through the trigger’saria-expanded, and saying it twice is noise. - It is not focusable, so the keyboard never stops on it.
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
direction | 'down' | 'end' | 'down' | Resting orientation, which also sets a half or a quarter turn |
open | boolean | — | State to use; without it the indicator reads the ancestor trigger |
class | string | — | Classes appended to the root |
Slots
| Slot | Description |
|---|---|
default | Replaces the glyph; the component still owns the turn |