Introducing PrimeReact v11-alpha 🎉Discover Now

useMotion

Hook that manages enter/leave animations with CSS class transitions and visibility control.

Usage#

import { useMotion } from '@primereact/core/motion';
 
const ref = React.useRef<HTMLDivElement>(undefined);
const motion = useMotion({
    elementRef: ref,
    visible: isOpen,
    name: 'fade'
});
 
return <>{motion.state.rendered && <div ref={ref} {...motion.rootProps}></div>}</>;

useMotion manages enter/leave animations on a single element, returning rootProps for hidden styles and state.rendered for conditional mounting.

Features#

  • CSS class-based enter/leave animation lifecycle ({name}-enter-from, {name}-enter-active, {name}-enter-to, {name}-leave-from, {name}-leave-active, {name}-leave-to)
  • Automatic mount/unmount via state.rendered with mountOnEnter and unmountOnLeave
  • Three hide strategies: display, visibility, none
  • CSS variable injection for element dimensions (--{prefix}-height, --{prefix}-width)
  • Imperative enter(), leave(), cancel(), update() methods
  • Eight lifecycle callbacks (onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled)

Behavior#

Animation Name#

Use name to define the CSS class prefix for animation phases. The hook applies six classes during the transition lifecycle.

const motion = useMotion({ elementRef: ref, visible, name: 'slide' });
.slide-enter-from {
    opacity: 0;
    transform: translateY(-10px);
}
.slide-enter-active {
    transition: all 200ms ease-out;
}
.slide-enter-to {
    opacity: 1;
    transform: translateY(0);
}
 
.slide-leave-from {
    opacity: 1;
    transform: translateY(0);
}
.slide-leave-active {
    transition: all 200ms ease-in;
}
.slide-leave-to {
    opacity: 0;
    transform: translateY(-10px);
}

Hide Strategy#

Use hideStrategy to control how closed content is hidden.

const motion = useMotion({ elementRef: ref, visible, hideStrategy: 'display' });
ValueBehavior
'display'Applies display: none (default)
'visibility'Applies visibility: hidden and max-height: 0
'none'No automatic hiding — CSS animations handle it entirely

CSS Variable Prefix#

Use cssVarPrefix to inject element dimension variables during animations. These variables are set on the element and can be used in CSS for height/width-based transitions.

const motion = useMotion({ elementRef: ref, visible, cssVarPrefix: 'panel-content' });
VariableDescription
--panel-content-heightSet to the scroll height on enter, 0px on leave
--panel-content-widthSet to the scroll width on enter, 0px on leave
.collapsible-enter-active,
.collapsible-leave-active {
    transition: max-height 300ms ease;
    overflow: hidden;
}
 
.collapsible-enter-to,
.collapsible-leave-from {
    max-height: var(--panel-content-height);
}
 
.collapsible-enter-from,
.collapsible-leave-to {
    max-height: 0;
}

Mount and Unmount#

Use mountOnEnter and unmountOnLeave to control DOM presence. When both are true (default), the element is only in the DOM while visible.

const motion = useMotion({ elementRef: ref, visible, mountOnEnter: true, unmountOnLeave: true });
 
{
    motion.state.rendered && (
        <div ref={ref} {...motion.rootProps}>
            Only in DOM when visible
        </div>
    );
}

Set unmountOnLeave to false to keep the element in the DOM after leave animation completes.

Appear on Mount#

Set appear to run the enter animation on initial mount when visible is true.

const motion = useMotion({ elementRef: ref, visible: true, appear: true, name: 'fade' });

Without appear, the element is immediately visible on mount without animation.

Disabled#

Set disabled to skip all animations. The element is shown/hidden instantly.

const motion = useMotion({ elementRef: ref, visible, disabled: true });

Custom Class Names#

Override individual phase classes instead of using the name prefix.

const motion = useMotion({
    elementRef: ref,
    visible,
    enterFromClassName: 'opacity-0',
    enterActiveClassName: 'transition-opacity duration-200',
    enterToClassName: 'opacity-100',
    leaveFromClassName: 'opacity-100',
    leaveActiveClassName: 'transition-opacity duration-200',
    leaveToClassName: 'opacity-0'
});

Lifecycle Callbacks#

Use lifecycle callbacks to run logic at specific animation phases.

const motion = useMotion({
    elementRef: ref,
    visible,
    name: 'fade',
    onBeforeEnter: (e) => {
        /* prepare element */
    },
    onAfterEnter: () => {
        /* animation complete */
    },
    onBeforeLeave: (e) => {
        /* cleanup before hide */
    },
    onAfterLeave: () => {
        /* fully hidden */
    }
});
CallbackPhase
onBeforeEnterBefore enter transition starts
onEnterEnter transition starts
onAfterEnterEnter transition ends
onEnterCancelledEnter transition cancelled
onBeforeLeaveBefore leave transition starts
onLeaveLeave transition starts
onAfterLeaveLeave transition ends
onLeaveCancelledLeave transition cancelled

Imperative Methods#

Use enter(), leave(), and cancel() to control animations programmatically.

const motion = useMotion({ elementRef: ref, visible, name: 'fade' });
 
// Trigger animations manually
motion.enter();
motion.leave();
motion.cancel();

update() reconfigures the motion instance with new props on an element.

motion.update(element, { name: 'slide', duration: 300 });

API#

useMotion#

NameTypeDefault
elementRefHTMLElement | RefObject<HTMLElement>—
The ref of the element to apply the motion to.
visiblebooleanfalse
Whether the element is visible or not.
mountOnEnterbooleantrue
Whether the motion should be applied when the element is mounted.
unmountOnLeavebooleantrue
Whether the element should be unmounted when the motion is not applied.
namestring—
The name of the motion. It can be a predefined motion name or a custom one. phases: [name]-enter [name]-enter-active [name]-enter-to [name]-leave [name]-leave-active [name]-leave-to
typeMotionType—
The type of the motion, valid values 'transition' and 'animation'.
disabledbooleanfalse
Whether the motion is disabled.
appearbooleanfalse
Whether the motion should appear.
enterbooleantrue
Whether the motion should enter.
leavebooleantrue
Whether the motion should leave.
durationMotionDuration—
The duration of the motion.
hideStrategy"none" | "display" | "visibility"—
The hide strategy of the motion. - `'display'` - hides with `display: none` - `'visibility'` - hides with `visibility: hidden` - `'none'` - no hiding, CSS handles it (e.g. height-based)
cssVarPrefixstring—
CSS variable prefix for motion-related variables (e.g. `'p'` produces `--p-height` ).
enterFromClassNamestring—
The enter from class of the motion.
enterToClassNamestring—
The enter to class of the motion.
enterActiveClassNamestring—
The enter active class of the motion.
leaveFromClassNamestring—
The leave from class of the motion.
leaveToClassNamestring—
The leave to class of the motion.
leaveActiveClassNamestring—
The leave active class of the motion.
onBeforeEnter(event?: MotionEvent) => void—
Callback fired before the enter transition/animation starts.
onEnter(event?: MotionEvent) => void—
Callback fired when the enter transition/animation starts.
onAfterEnter(event?: MotionEvent) => void—
Callback fired after the enter transition/animation ends.
onEnterCancelled(event?: MotionEvent) => void—
Callback fired when the enter transition/animation is cancelled.
onBeforeLeave(event?: MotionEvent) => void—
Callback fired before the leave transition/animation starts.
onLeave(event?: MotionEvent) => void—
Callback fired when the leave transition/animation starts.
onAfterLeave(event?: MotionEvent) => void—
Callback fired after the leave transition/animation ends.
onLeaveCancelled(event?: MotionEvent) => void—
Callback fired when the leave transition/animation is cancelled.