Documentation Index
Fetch the complete documentation index at: https://mintlify.com/zayne-labs/ui/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Presence component enables animation of component mount and unmount transitions. It keeps components in the DOM during exit animations and provides hooks for advanced animation control.
Import
import { Presence, usePresence } from "@zayne-labs/ui-react/common/presence";
Presence Component
Props
Whether the component should be present in the DOM.
children
React.ReactElement | ((props: RenderPropContext) => React.ReactElement)
required
A single React element with a ref prop, or a render function that receives presence context.
variant
'animation' | 'transition'
default:"'animation'"
The type of CSS animation to use. Use ‘animation’ for CSS animations and ‘transition’ for CSS transitions.
When true, forces the component to always be mounted regardless of the present state.
Callback invoked when the exit animation completes.
Additional CSS class names to apply.
usePresence Hook
function usePresence(options: UsePresenceOptions): UsePresenceResult
Options
Whether the component should be present.
variant
'animation' | 'transition'
default:"'animation'"
The type of CSS animation being used.
Callback invoked when exit completes.
Returns
Whether the element is currently present in the state machine.
isPresentOrIsTransitionComplete
Whether the element is present or has completed its transition.
Whether a transition should start.
Ref to attach to the animated element.
propGetters
{ getPresenceProps: (props) => props }
Prop getter function for applying presence attributes.
Type Definitions
type RenderPropContext = {
isPresent: boolean;
isPresentOrIsTransitionComplete: boolean;
shouldStartTransition: boolean;
};
type UsePresenceResult = {
isPresent: boolean;
isPresentOrIsTransitionComplete: boolean;
propGetters: {
getPresenceProps: (innerProps: InferProps<HTMLElement>) => InferProps<HTMLElement>;
};
ref: React.Ref<HTMLElement>;
shouldStartTransition: boolean;
};
Data Attributes
The component adds these data attributes for styling:
data-present: “true” when the element is present
data-present-or-transition-complete: “true” when present or transition is complete
data-state: Current state (“mounted”, “unmountSuspended”, “unmounted”)
data-transition: “active” or “inactive” (only when variant="transition")
Usage Examples
Basic Animation
function AnimatedBox() {
const [show, setShow] = useState(true);
return (
<>
<button onClick={() => setShow(!show)}>Toggle</button>
<Presence present={show}>
<div className="box">I will animate!</div>
</Presence>
</>
);
}
.box {
animation: fadeIn 300ms ease-out;
}
.box[data-state="unmountSuspended"] {
animation: fadeOut 300ms ease-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
CSS Transitions
<Presence present={isOpen} variant="transition">
<div className="modal">Modal Content</div>
</Presence>
.modal {
opacity: 0;
transform: scale(0.95);
transition: opacity 200ms, transform 200ms;
}
.modal[data-transition="active"] {
opacity: 1;
transform: scale(1);
}
Render Function
<Presence present={visible}>
{({ isPresent, shouldStartTransition }) => (
<div
className="alert"
data-visible={isPresent}
data-animating={shouldStartTransition}
>
Alert message
</div>
)}
</Presence>
Exit Callback
<Presence
present={isShowing}
onExitComplete={() => {
console.log('Animation finished!');
onClose();
}}
>
<Notification>Your changes have been saved.</Notification>
</Presence>
Force Mount
<Presence present={isActive} forceMount>
<div className="overlay" aria-hidden={!isActive}>
Content always in DOM
</div>
</Presence>
Using the Hook
function CustomAnimatedComponent({ visible }) {
const {
isPresent,
shouldStartTransition,
propGetters,
ref
} = usePresence({ present: visible });
if (!isPresent) return null;
return (
<div
ref={ref}
{...propGetters.getPresenceProps({
className: 'custom-component'
})}
>
Content with custom animation logic
</div>
);
}
Conditional Content Based on State
<Presence present={isPending} variant="transition">
{({ shouldStartTransition }) => (
<LoadingSpinner active={shouldStartTransition} />
)}
</Presence>
Notes
- The component uses a state machine internally to manage mount/unmount states
- For
variant="animation", it detects animation name changes to determine when to suspend unmounting
- For
variant="transition", it listens to transitionrun and transitionend events
- The child element must accept a
ref prop
- Only one child element is allowed (or a render function that returns one element)
- The component sets
animationFillMode: 'forwards' during exit to prevent flashing
- Based on Radix UI’s Presence implementation