<script setup lang="ts">
import { ref } from 'vue'
import { Button, Card, Drawer, OverlayBranch, Text } from '@hina-ui/vue'
const open = ref(false)
const count = ref(0)
</script>
<template>
<Drawer v-model:open="open" title="Reading settings">
<Button variant="outline" tone="neutral">Open drawer</Button>
<template #content>
<Text tone="muted">
The card in the bottom corner is outside the drawer. Pressing its button leaves the drawer
open.
</Text>
</template>
</Drawer>
<Teleport to="body">
<OverlayBranch v-if="open" class="fixed start-4 bottom-4 z-[calc(var(--hn-z-overlay)+1)] w-56">
<Card class="flex flex-col gap-2 p-3 shadow-lg">
<Text size="sm" tone="muted">Outside layer</Text>
<Button size="sm" @click="count++">Clicked {{ count }} times</Button>
</Card>
</OverlayBranch>
</Teleport>
</template>
vue
Usage
import { OverlayBranch } from '@hina-ui/vue'
ts
OverlayBranch wraps another layer of the page that you manage yourself, such as a hand-built guide layer or a floating toolbar. While a Dialog, Drawer, Sheet, modal Popover or menu is open, the overlay treats its content as its own:
- Pressing or focusing an element in it does not close the overlay and does not fire
interactOutside. - It is not set to
aria-hidden, so screen readers can reach it. - It is not affected by the
pointer-eventsrestriction the overlay puts on the rest of the page. - The focus trap lets focus move into it.
as sets the rendered tag, div by default. asChild hands this behaviour to its only child and renders no node of its own.
Behavior
- It registers when mounted and unregisters when unmounted; a branch mounted after an overlay opened works too.
- While an overlay sets
pointer-events: noneonbody, the branch root keeps its ownpointer-events. A transparent full-screen root withpointer-events: nonedoes not block the overlay; parts of it that take input setpointer-events: autothemselves. The branch’s inline style is restored when the overlay closes. - The overlay’s Tab loop does not include the branch. When focus moves from the branch to an element outside both the overlay and the branch, it returns to the overlay.
- Stacking is up to you. To sit over overlays, render the branch under
bodywith az-indexabove--hn-z-overlay. Inside a container that forms a stacking context, such as one with az-indexor atransform, the branch’sz-indexonly counts within that container and the overlay’s scrim covers it.
API
| Prop | Type | Default | Description |
|---|---|---|---|
as | string | 'div' | The rendered tag |
asChild | boolean | false | Renders no node of its own and hands its behaviour to its only child |
| Slot | Description |
|---|---|
default | Content of the layer |