<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro" rel="stylesheet">
<div class="pen">
</div>
<a class="created-by" target="_blank" href="https://popmotion.io/pose">
  Pen created with
  <img src="https://user-images.githubusercontent.com/7850794/36951814-dbd58448-1fff-11e8-8fc7-4b03531ddffb.png" alt="Popmotion Pose" height="30" />
</a>
body {
  --pink: #FF1C68;
  --green: #14D790;
  --blue: #198FE3;
  --white: #fff;
  background: var(--white);
  font-family: 'PT Sans', sans-serif;
  height: 100vh;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}

.pen {
  flex: 1 1 100%;
}

.created-by {
  flex: 0 0 50px;
  background: #fff;
  color: #222;
  text-decoration: none;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding-right: 30px;
  
  img {
    margin-left: 10px;
    transform: translateY(-3px);
  }
}

.logo {
  margin-left: 10px;
}

.pen {
  display: flex;
  justify-content: center;
  align-items: center;
}

.container {
  width: 300px;
  height: 75px;
  border-radius: 5px;
  background-color: #eee;
  position: relative;
}

.slidable {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: #eee;
  border-radius: 5px;
  box-shadow: 0 1px 0 0 rgba(0,0,0,0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 14px;
}

.icon {
  width: 50px;
  height: 50px;
  background: white;
  position: absolute;
  border-radius: 50%;
  top: calc(50% - 25px);
}

.accept {
  right: 20px;
}

.reject {
  left: 20px;
}
const { decay, spring, transform, value } = popmotion
const { pipe, conditional, clamp, interpolate } = transform

const Slidable = posed.div({
  draggable: 'x',
  dragEnd: {
    transition: ({ from, to, velocity }) =>
      spring({ from, to, velocity, stiffness: 750, damping: 50 })
  }
})

const Container = posed.div({
  passive: {
    backgroundColor: ['x', v => v >= 0 ? '#FF1C68' : '#14D790', true]
  }
})

const AcceptIcon = posed.div({
  passive: {
    scale: ['x', pipe(
      interpolate([-200, 0], [1, 0]),
      clamp(0, 1)
    ), true]
  }
})

const RejectIcon = posed.div({
  passive: {
    scale: ['x', pipe(
      interpolate([0, 200], [0, 1]),
      clamp(0, 1)
    ), true]
  }
})

class Example extends React.Component {
  x = value(0)

  render() {
    const valuesMap = { x: this.x }

    return (
      <Container className="container" parentValues={valuesMap}>
        <AcceptIcon className="icon accept" parentValues={valuesMap} />
        <RejectIcon className="icon reject" parentValues={valuesMap} />
        <Slidable className="slidable" values={valuesMap}>Slide me</Slidable>
      </Container>
    )
  }
}

ReactDOM.render(
  <Example />,
  document.querySelector('.pen')
);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/react-pose@1.1.4/dist/react-pose.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react/16.3.1/umd/react.development.js
  3. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.1/umd/react-dom.development.js