From 398e203dde9bb53b77b85a7ddc42fb2d0d4ed01a Mon Sep 17 00:00:00 2001 From: dustinengle Date: Mon, 3 Sep 2018 18:08:59 -0700 Subject: [PATCH] fixes #13 adds horizontal stepp --- react/Stepper.jsx | 48 +++++++++++++++++++++++++++++ sass/_library.scss | 1 + sass/inc/_stepper.scss | 59 ++++++++++++++++++++++++++++++++++++ test/Stepper.test.js | 55 +++++++++++++++++++++++++++++++++ todo/App.jsx | 2 ++ todo/Section/StepperDemo.jsx | 38 +++++++++++++++++++++++ 6 files changed, 203 insertions(+) create mode 100644 react/Stepper.jsx create mode 100644 sass/inc/_stepper.scss create mode 100644 test/Stepper.test.js create mode 100644 todo/Section/StepperDemo.jsx 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 ( +
+
{steps}
+
{content}
+
+ ) + } +} 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.

+ + +
+
+
+ ) + } +}