DisclosureIcon

An indicator that turns as a region opens and closes.

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

Usage

import { DisclosureIcon } from '@hina-ui/vue'
ts

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

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

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

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’s aria-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