Pose

Declarative motion system for HTML, SVG, React & React Native

CSS simplicity meets JavaScript power

Magic animations

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

const config = {
  left: { x: 100 },
  right: { x: -100 }
}

// Vanilla
const poser = pose(element, config)
poser.set('left')

// React Native
const Box = posed.View(config)
() => <Box pose="left" />

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 config = {
  attention: { scale: 1.3, transition: looseSpring }
}

// Vanilla & React DOM use Popmotion
const looseSpring = (props) =>
  spring({ ...props, stiffness: 200, damping: 0 })

// React Native uses Animated
const looseSpring = ({ value, toValue }) =>
  spring(value, { toValue, stiffness: 200, damping: 0 })

Orchestrate

Pose's parent-child system makes quick work of coordinating animations across multiple elements.

// Vanilla
const parent = pose(element, config)
items.forEach(item => parent.addChild(item, childConfig))
parent.set('open')

// React Native
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 config = {
  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 DOM
passive: {
  opacity: ['x', interpolate(
    [-200, -100, 100, 200],
    [0, 1, 1, 0]
  )]
}

// React Native
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 DOM 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.