React Pose has been deprecated in favour of Framer Motion. Read the upgrade guide
posed
posed
is used to create animated and interactive components that you can reuse throughout your React site.
Import
import posed from 'react-pose'
Usage
Create a posed component
posed
can be used to create posed components in two ways:
- Recommended: Create HTML & SVG elements (eg
posed.div
) - Advanced: Convert existing components (eg
posed(Component)
)
HTML & SVG elements
pose
isn’t called directly, instead we pass a pose config object to posed.div
, posed.button
etc. Every HTML and SVG element is supported:
const DraggableCircle = posed.circle({
draggable: 'x',
dragBounds: { left: 0, right: 100 }
})
export default ({ radius }) => <DraggableCircle r={radius} />
Existing components
Existing components can be converted to posed components by calling posed
directly:
const PosedComponent = posed(MyComponent)(poseProps)
For performance and layout calculations, React Pose requires a reference to the underlying DOM element. So, the component to be animated must pass forward a ref using the React.forwardRef
function:
const MyComponent = forwardRef((props, ref) => (
<div ref={ref} {...props} />
));
const PosedComponent = posed(MyComponent)({
draggable: true
});
export default () => <PosedComponent pose={isOpen ? 'open' : 'closed'} />
Many CSS-in-JS libraries like Styled Components will automatically do this for you.
For FLIP support in a PoseGroup
component, it optionally needs to pass on the style
prop:
const MyComponent = forwardRef(({ style }, ref) => (
<div ref={ref} style={style} />
));
Set a pose
Poses can be set via the pose
property. This can either be a string, or an array of strings to reference multiple poses:
const Sidebar = posed.nav({
open: { x: '0%' },
closed: { x: '-100%' }
})
export default ({ isOpen }) => <Sidebar pose={isOpen ? 'open' : 'closed'} />
Children
Using a posed component creates a new tree of posed components. Any children that are also posed components are automatically added to this tree.
This means that orchestrating animations through React trees becomes trivial, as a pose only has to be set on a parent. Any children with that pose defined will also animate:
const Sidebar = posed.nav({
open: { x: '0%', staggerChildren: 100 },
closed: { x: '-100%' }
})
const NavItem = posed.li({
open: { opacity: 1 },
closed: { opacity: 0 }
})
export default ({ isOpen, navItems }) => (
<Sidebar pose={isOpen ? 'open' : 'closed'}>
<ul>
{navItems.map(({ url, name }) => (
<NavItem>
<a href={url}>{name}</a>
</NavItem>
))}
</ul>
</Sidebar>
)
In tandem with the PoseGroup
component, this capability can be used to orchestrate sophisticated enter
and exit
animations.
This behaviour can be overridden by passing newTree
to a posed component, which will ignore any parent posed components and create a new tree.
Styling
Posed components are normal components, so they can be used with any CSS styling solution. For instance:
Styled Components
const sidebarProps = {
open: { x: '0%' },
closed: { x: '-100%' }
}
const Sidebar = styled(posed.nav(sidebarProps))`
className
() => <Sidebar pose="closed" className="my-class" />
Props
pose
pose?: string | string[]
The name or names of the current pose.
initialPose
initialPose?: string | string[]
The name of one or more poses to set to before the component mounts. Once the component mounts, it will transition from this pose into pose
.
poseKey
poseKey?: string | number
If poseKey
changes, it’ll force the posed component to transition to the current pose
, even if it hasn’t changed.
This won’t be required for the majority of use-cases. But we might have something like a paginated where we pass the x offset to the component but the pose itself doesn’t change:
const Slider = posed.div({
nextItem: {
x: ({ target }) => target
}
})
({ target }) => <Slider pose="nextItem" poseKey={target} target={target} />
withParent
withParent?: boolean = true
If set to false
, this component won’t subscribe to its parent posed component and create root for any further child components.
onPoseComplete
onPoseComplete?: Function
A callback that fires whenever a pose has finished transitioning.
onValueChange
onValueChange?: { [key: string]: any }
onValueChange
is a map of functions, each corresponding to a value being animated by the posed component and will fire when that value changes.
onDragStart/onDragEnd
onDragStart/onDragEnd: (e: Event) => void
Callbacks that fire when dragging starts or ends. Note: These props are immutable and can’t be changed after mounting.
onPressStart/onPressEnd
onPressStart/onPressEnd: (e: Event) => void
Callbacks that fire when pressing starts or ends. Note: These props are immutable and can’t be changed after mounting.
ref
ref?: RefObject | (ref: Element) => void
An optional ref property. If a function, will call with the posed DOM element when it mounts, and null
when it unmounts.
Alternatively, it can be passed a ref object (created from React.createRef
).
values/parentValues
values?: { [key: string]: Value }
Normally, Pose generates Popmotion value
for each animating property. It then passes these down to any posed children so passive
values can link to them.
Novel hierarchies, where the posed tree and the React component tree diverge, can be achieved by creating your own values map, and passing that to a single posed component.
This same map can then be passed to multiple other posed component’s parentValues
property in order to establish a parent-children relationship even between sibling components.
…props
...props: { [key: string]: any }
When a new pose is entered, any remaining props set on a component will be used to resolve that pose’s dynamic props:
const Component = posed.div({
visible: { opacity: 1, y: 0 },
hidden: {
opacity: 0,
y: ({ i }) => i * 50
}
})
// Later
({ isVisibile, i }) => (
<Component pose={isVisible ? 'visible' : 'hidden'} i={i} />
)