<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@dicehub/kappa/components/button";
import { Presence } from "@dicehub/kappa/components/presence";
const visible = ref(true);
const lifecycle = ref("Entered");
</script>
<template>
<Button
size="sm"
variant="outline"
:aria-expanded="visible"
aria-controls="presence-preview-panel"
@click="visible = !visible"
>
{{ visible ? "Hide status" : "Show status" }}
</Button>
<div class="presence-stage">
<Presence
id="presence-preview-panel"
:present="visible"
unmount-on-exit
@enter-complete="lifecycle = 'Entered'"
@exit-complete="lifecycle = 'Exited'"
>
<section aria-label="Service status">
<span class="status-signal" aria-hidden="true" />
<div>
<strong>Service online</strong>
<span>All checks completed.</span>
</div>
</section>
</Presence>
</div>
<output aria-live="polite">{{ lifecycle }}</output>
</template>Installation
Presence is part of the main Kappa package. It composes Ark UI's presence utility and uses Kappa's shared entrance and exit motion.
Barrel
import {
Presence,
usePresence,
} from "@dicehub/kappa";Granular
import {
Presence,
usePresence,
} from "@dicehub/kappa/components/presence";Usage
Bind present to application state. Presence waits for CSS motion before it hides content.
The latest settings are active.
<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@dicehub/kappa/components/button";
import { Presence } from "@dicehub/kappa/components/presence";
const visible = ref(true);
</script>
<template>
<Button size="sm" @click="visible = !visible">
{{ visible ? "Dismiss notice" : "Show notice" }}
</Button>
<div class="presence-stage">
<Presence :present="visible">
<p>The latest settings are active.</p>
</Presence>
</div>
</template>Composition
Presence <div | custom child>
└── conditionally present contentPresence renders one element by default. Use asChild when the semantic child must own the Ark state attributes and Kappa motion class.
Reference Behavior
Kappa follows Ark UI Presence for mount timing and lifecycle events. The component reads CSS animation state, so exit content remains available until motion completes.
Examples
Lazy Mount
Defer expensive content until it is first needed, then remove it after exit.
<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@dicehub/kappa/components/button";
import { Presence } from "@dicehub/kappa/components/presence";
const visible = ref(false);
</script>
<template>
<Button size="sm" variant="outline" @click="visible = !visible">
{{ visible ? "Unmount details" : "Mount details" }}
</Button>
<div class="presence-stage">
<Presence :present="visible" lazy-mount unmount-on-exit>
<section data-lazy-presence>
<div>
<strong>Deferred diagnostics</strong>
<span>Mounted only after the first request.</span>
</div>
</section>
</Presence>
</div>
</template>Custom Child
Merge presence behavior onto one direct semantic element.
<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@dicehub/kappa/components/button";
import { Presence } from "@dicehub/kappa/components/presence";
const visible = ref(true);
</script>
<template>
<Button size="sm" variant="outline" @click="visible = !visible">
{{ visible ? "Hide aside" : "Show aside" }}
</Button>
<div class="presence-stage">
<Presence :present="visible" as-child>
<aside aria-label="Processing note">
<div>
<strong>Processing continues</strong>
<span>You can leave this page safely.</span>
</div>
</aside>
</Presence>
</div>
</template>Accessibility
- Connect disclosure controls and content with
aria-controlsandaria-expanded. - Move focus before you hide content that contains the active element.
- Use an appropriate live region only when the state change needs an announcement.
- Kappa reduces the animation to one millisecond when reduced motion is requested.
API Reference
Presence
| Prop | Type | Default | Description |
|---|---|---|---|
present | boolean | false | Controls whether the content is present. |
lazyMount | boolean | false | Defers the first mount until content becomes present. |
unmountOnExit | boolean | false | Removes content after its exit animation completes. |
skipAnimationOnMount | boolean | false | Skips the initial entrance animation. |
immediate | boolean | false | Synchronizes state without waiting for the next frame. |
asChild | boolean | false | Merges presence behavior and Kappa attributes onto one direct child. |
Events
| Event | Description |
|---|---|
enterComplete | Emitted after the entrance animation completes. |
exitComplete | Emitted after the exit animation completes. |
Exports
| Export | Description |
|---|---|
Presence | Ark-backed Kappa presence and transition component. |
usePresence / usePresenceContext | Ark UI presence composables. |
PresenceProvider | Provides an external presence context. |
PresenceProps / PresenceEmits / PresenceSlots | Public Vue contracts. |