Pose

Declarative motion system for React, React Native, and vanilla JS

JavaScript power, CSS simplicity

Magic animations

By default, Pose will figure out the animation based on the properties being animated.

// React Pose
const Box = posed.div({
  left: { x: 100 },
  right: { x: -100 }
})

({ position }) => <Box pose={position} />

Animate anything

Numbers, units, colors, box shadows, radial gradients, path definitions - Pose animates them all.

popped: {
  x: -10,
  y: -10,
  background: 'rgba(161, 0, 246, 1)',
  boxShadow: '10px 10px 20px rgba(161, 0, 246, 0.2)',
  transition: { duration: 700 }
}

Declarative

Pose's declarative API enforces the separation of business and animation logic.

// Vanilla
poser.set('open')

// React
({ isOpen }) =>
  <Component pose={isOpen ? 'open' : 'closed'} />

Custom animations

Use the power of Popmotion or React Animated to create complex custom animations.

const Circle = posed.div({
  attention: {
    scale: 1.3,
    transition: {
      type: 'spring',
      stiffness: 200,
      damping: 0
    }
  }
})

Orchestrate

Pose's component tree makes coordinating animations across multiple elements as easy as animating one.

// React Native Pose
const Parent = posed.View(config)
const Child = posed.Image(childConfig)

({ items }) => (
  <Parent pose="open">
    {items.map(item => <Child />)}
  </Parent>
)

Interactivity

Draggable elements are just a prop away, with more options coming soon.

Drag
const Box = posed.div({
  draggable: 'x',
  dragBounds: { left: '-100%', right: '100%' }
})

// Note: 'dragBounds' not yet available for React Native

Passive values

Link values to the status of other values on the same poser or their parent.

Drag
// Vanilla & React Pose uses Popmotion's functional pipelines
passive: {
  opacity: ['x', interpolate(
    [-200, -100, 100, 200],
    [0, 1, 1, 0]
  )]
}

// React Native Pose uses React Animated's interpolate function
passive: {
  opacity: ['x', {
    inputRange: [-200, -100, 100, 200],
    outputRange: [0, 1, 1, 0]
  }]
}

FLIPpin' great

Slow flow-breaking animations can be easily converted to fast transforms. Plus, an imperative FLIP API allows the poser to respond to DOM operations.

// Vanilla & React Pose only
await poser.set('childOut')
await poser.flip(() => {
  poser.clearChildren()
  parentElement.removeChild(parent.firstChild)
  parentElement.appendChild(newChild)
  poser.addChild(newChild, childProps)
})
poser.set('childIn')

Awesome with React DOM

The freedom to use any animation, automatic child binding, FLIP-enhanced enter/exit transitions and more.

// PoseGroup currently React DOM only

const Item = posed.li()

const List = ({ items }) => (
  <ul>
    <PoseGroup>
      {items.map(item => <Item key={item.key} />)}
    </PoseGroup>
  </ul>
)

Pose is a continuing project to simplify the creation of fluid and playful interfaces.