Presence
A shadcn-style presence utility built with Ark UI primitives.
Presence keeps exit state visible.
Toggle the panel to preview enter and exit transitions without wiring a full overlay component.
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Presence } from "@/components/ui/presence";
const PresenceDemo = () => {
const [present, setPresent] = useState(true);
return (
<div className="grid w-full max-w-md gap-4">
<Button
type="button"
variant="outline"
onClick={() => setPresent((value) => !value)}
>
{present ? "Hide panel" : "Show panel"}
</Button>
<Presence present={present}>
<div className="rounded-xl border border-border bg-card p-4 shadow-xs transition-all duration-200 data-[state=closed]:translate-y-2 data-[state=closed]:opacity-0 data-[state=open]:translate-y-0 data-[state=open]:opacity-100">
<p className="font-medium text-sm">
Presence keeps exit state visible.
</p>
<p className="mt-1 text-muted-foreground text-sm">
Toggle the panel to preview enter and exit transitions without
wiring a full overlay component.
</p>
</div>
</Presence>
</div>
);
};
export default PresenceDemo;
Installation
npx shadcn@latest add @ark-cn/presenceInstall the dependency required by this utility:
npm install @ark-ui/reactCopy the utility source into your app:
TSXcomponents/ui/presence.tsx
"use client";
import {
Presence as PresencePrimitive,
type PresenceProps as PresencePrimitiveProps,
PresenceProvider,
splitPresenceProps,
usePresence,
usePresenceContext,
} from "@ark-ui/react/presence";
import { cn } from "@/lib/utils";
export type PresenceProps = PresencePrimitiveProps;
export const Presence = ({ className, ...props }: PresenceProps) => (
<PresencePrimitive
className={cn(className)}
data-slot="presence"
{...props}
/>
);
export type {
PresenceBaseProps,
UsePresenceContext,
UsePresenceProps,
UsePresenceReturn,
} from "@ark-ui/react/presence";
export {
PresenceProvider,
splitPresenceProps,
usePresence,
usePresenceContext,
};
Update import aliases to match your project setup.
Usage
import { Presence } from "@/components/ui/presence"Examples
Default
Presence keeps exit state visible.
Toggle the panel to preview enter and exit transitions without wiring a full overlay component.
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Presence } from "@/components/ui/presence";
const PresenceDemo = () => {
const [present, setPresent] = useState(true);
return (
<div className="grid w-full max-w-md gap-4">
<Button
type="button"
variant="outline"
onClick={() => setPresent((value) => !value)}
>
{present ? "Hide panel" : "Show panel"}
</Button>
<Presence present={present}>
<div className="rounded-xl border border-border bg-card p-4 shadow-xs transition-all duration-200 data-[state=closed]:translate-y-2 data-[state=closed]:opacity-0 data-[state=open]:translate-y-0 data-[state=open]:opacity-100">
<p className="font-medium text-sm">
Presence keeps exit state visible.
</p>
<p className="mt-1 text-muted-foreground text-sm">
Toggle the panel to preview enter and exit transitions without
wiring a full overlay component.
</p>
</div>
</Presence>
</div>
);
};
export default PresenceDemo;
API reference
This utility mirrors the upstream Ark UI primitive.
See the ARK UI documentation for the full API.