Stacksheetv1.1.4

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 hasEnteredRef flag)
  • 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) => void

Close reasons

ReasonTrigger
"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

On this page