Animation Callbacks
onOpenComplete and onCloseComplete callback hooks.
Overview
Stacksheet provides two animation callbacks for timing side effects to the animation lifecycle. Pass them in the config:
const { StacksheetProvider, useSheet } = createStacksheet({
onOpenComplete: () => {
console.log("Top panel entrance animation finished");
},
onCloseComplete: (reason) => {
console.log("Stack fully closed via:", reason);
},
});onOpenComplete
Fires once when the top panel's entrance animation completes. It fires per panel entrance — when you push a new sheet, onOpenComplete fires again once the new sheet settles.
Use cases
- Auto-focus an input after the sheet finishes sliding in
- Start a timer or trigger a lazy data fetch
- Analytics — track when a sheet becomes visible
Behavior details
- Fires once per panel entrance (uses an internal
hasEnteredRefflag) - Resets when a panel is no longer on top (pushed down by a new sheet)
- Fires again when the panel returns to the top (via pop)
- Does not fire during exit animations
onCloseComplete
Fires when the last panel's exit animation completes — meaning the stack is fully closed and all exit animations have finished. Receives a CloseReason indicating how the sheet was dismissed.
onCloseComplete: (reason: CloseReason) => voidClose reasons
| Reason | Trigger |
|---|---|
"escape" | User pressed Escape or Android back gesture (CloseWatcher) |
"backdrop" | User clicked the backdrop overlay |
"swipe" | User dragged the sheet past the close threshold |
"programmatic" | close() or pop() called from code |
Use cases
- Clean up state after the sheet stack is dismissed
- Trigger navigation after a confirmation sheet closes
- Analytics — track sheet session duration and how it was dismissed
- Conditional logic — handle differently based on close reason
onCloseComplete: (reason) => {
if (reason === "programmatic") {
// User submitted the form, navigate to success
router.push("/success");
}
// Otherwise they dismissed — do nothing
},Behavior details
- Only fires when
stack.length === 0(all sheets have exited) - Powered by
<AnimatePresence onExitComplete>on the panel container - Does not fire when popping a single sheet from a multi-sheet stack
- The reason reflects how the last sheet was dismissed