diff --git a/react/Stepper.jsx b/react/Stepper.jsx
new file mode 100644
index 0000000..f5ea1e5
--- /dev/null
+++ b/react/Stepper.jsx
@@ -0,0 +1,48 @@
+import PropTypes from 'prop-types'
+import React from 'react'
+import {pickRest} from '../lib/utils'
+
+import Icon from './Icon'
+
+// Step
+export const Step = () => null
+
+Step.propTypes = {
+ active: PropTypes.bool,
+ complete: PropTypes.bool,
+ title: PropTypes.string.isRequired
+}
+
+// Stepper
+export class Stepper extends React.Component {
+ static propTypes = {
+ children: PropTypes.any.isRequired,
+ index: PropTypes.number.isRequired,
+ vertical: PropTypes.bool
+ }
+
+ render () {
+ const [mods, {children, ...rest}] = pickRest(this.props, ['vertical'])
+
+ let content = null
+ const steps = (Array.isArray(children) ? children : [children]).map((s, i) => {
+ const active = i === this.props.index
+ const complete = i < this.props.index
+ if (active) content = s.props.children
+ return (
+
+
{active || complete ? : i}
+
{s.props.title}
+
+
+ )
+ })
+
+ return (
+
+ )
+ }
+}
diff --git a/sass/_library.scss b/sass/_library.scss
index 4cf8f20..c9bf50a 100644
--- a/sass/_library.scss
+++ b/sass/_library.scss
@@ -13,6 +13,7 @@
@import 'inc/pagination';
@import 'inc/panel';
@import 'inc/reset';
+@import 'inc/stepper';
@import 'inc/tab';
@import 'inc/text';
@import 'inc/tooltip';
diff --git a/sass/inc/_stepper.scss b/sass/inc/_stepper.scss
new file mode 100644
index 0000000..b5fbfc3
--- /dev/null
+++ b/sass/inc/_stepper.scss
@@ -0,0 +1,59 @@
+
+.stepper {
+ &__content {
+ padding: 32px;
+ }
+
+ &__steps {
+
+ }
+
+ &__step {
+ color: $secondary;
+ display: inline-block;
+ font-size: 14px;
+ line-height: 19px;
+
+ $self: &;
+
+ &--active {
+ #{$self}__indicator {
+ background-color: $primary;
+ color: $white;
+ padding: 9px 12px;
+ }
+ }
+
+ &--complete {
+ #{$self}__indicator {
+ background-color: $black;
+ color: $secondary;
+ padding: 9px 12px;
+ }
+ }
+
+ &__bar {
+ border-top: 1px solid $secondary;
+ display: inline-block;
+ height: 5px;
+ margin-right: 21px;
+ margin-top: -2px;
+ min-width: 100px;
+ width: 100px;
+ }
+
+ &__indicator {
+ background-color: $black;
+ border-radius: 50%;
+ color: $white;
+ font-size: 16px;
+ height: 35px;
+ line-height: 21px;
+ margin-right: 9px;
+ padding: 7px 13px;
+ width: 35px;
+ }
+
+ &__title { margin-right: 40px; }
+ }
+}
diff --git a/test/Stepper.test.js b/test/Stepper.test.js
new file mode 100644
index 0000000..eacc090
--- /dev/null
+++ b/test/Stepper.test.js
@@ -0,0 +1,55 @@
+/* global describe, it */
+import React from 'react'
+import expect from 'must'
+import { shallow } from 'enzyme'
+import Button from '../react/Button'
+import {Step, Stepper} from '../react/Stepper'
+
+describe('', () => {
+ const wrapper = shallow(Testing)
+
+ it('renders no children', () => {
+ expect(wrapper.children()).to.have.length(0)
+ })
+})
+
+describe('', () => {
+ let index = 0
+ const handleBack = () => { index-- }
+ const handleNext = () => { index++ }
+ const wrapper = shallow(
+
+
+ Alpha
+
+
+
+ Bravo
+
+
+
+
+ )
+
+ it('renders as a div', () => {
+ expect(wrapper.is('div')).to.be.true()
+ expect(wrapper.hasClass('stepper')).to.be.true()
+ })
+
+ it('moves index for next step', () => {
+ wrapper.find('.stepper__content').childAt(1).simulate('click')
+ expect(index).to.equal(1)
+ })
+
+ it('converts children into array if single step', () => {
+ const wrapper2 = shallow(
+
+
+ Alpha
+
+
+
+ )
+ expect(!!wrapper2).to.be.true()
+ })
+})
diff --git a/todo/App.jsx b/todo/App.jsx
index ee11e96..57beb1b 100644
--- a/todo/App.jsx
+++ b/todo/App.jsx
@@ -14,6 +14,7 @@ import {Navbar, NavbarLink} from '../react/Navbar'
import PaginationDemo from './Section/PaginationDemo'
import PanelDemo from './Section/PanelDemo'
import SelectInputDemo from './Section/SelectInputDemo'
+import StepperDemo from './Section/StepperDemo'
import TabDemo from './Section/TabDemo'
import TextInputDemo from './Section/TextInputDemo'
import TooltipDemo from './Section/TooltipDemo'
@@ -59,6 +60,7 @@ class App extends React.Component {
+
diff --git a/todo/Section/StepperDemo.jsx b/todo/Section/StepperDemo.jsx
new file mode 100644
index 0000000..417d02a
--- /dev/null
+++ b/todo/Section/StepperDemo.jsx
@@ -0,0 +1,38 @@
+import React from 'react'
+
+import Button from '../../react/Button'
+import {Step, Stepper} from '../../react/Stepper'
+
+export default class StepperDemo extends React.Component {
+ state = {
+ index: 0
+ }
+
+ handleBack = () => this.setState({index: this.state.index <= 0 ? 0 : this.state.index - 1})
+
+ handleNext = () => this.setState({index: this.state.index >= 2 ? 2 : this.state.index + 1})
+
+ render () {
+ return (
+
+
Stepper
+
+
+ How do we know that rain isn't tears falling from sad clouds?
+
+
+
+ They could be but you've never asked a cloud, have you?
+
+
+
+
+ Birds fly but ostriches can’t and they are birds. I wonder if there is a reason behind that.
+
+
+
+
+
+ )
+ }
+}