diff --git a/src/components/Steps.js b/src/components/Steps.js index 3ed8eb8ac..511138aff 100644 --- a/src/components/Steps.js +++ b/src/components/Steps.js @@ -4,52 +4,88 @@ import classNames from 'classnames'; import Icon from './Icon.js'; import styles from './Steps.scss'; -const Steps = ({ complete, step, steps }) => { - const className = `${styles.steps} ${complete ? styles.complete : ''}`; +const Steps = ({ collapse, complete, step, steps }) => { + const className = classNames({ + [styles.complete]: complete, + [styles.steps]: true, + 'm-0': true + }); + const activeStep = steps[step]; + const activeStepClasses = classNames({ + 'text-gray-dark': !complete, + 'text-success': complete, + 'hidden-sm-up': collapse !== true, + 'text-center': true + }); + return ( -
    - {steps.map((name, index) => { - const stepComplete = !complete && index < step; - const stepActive = !complete && index === step; - - const liClasses = classNames({ - [styles.step]: true, - [styles.complete]: stepComplete, - [styles.active]: stepActive, - }); - - const bubbleClasses = classNames({ - [styles.bubble]: true, - 'text-success': complete, - 'bg-primary': stepActive, - 'text-primary': stepComplete, - 'text-white': stepActive, - }); - - const textClasses = classNames({ - [styles.text]: true, - 'text-primary': stepComplete, - 'text-muted': !complete && index > step, - 'text-success': complete, - }); - - return ( -
  1. -
    - {complete || stepComplete ? : index + 1} -
    -
    {name}
    -
  2. - ); - })} -
+
+
    + {steps.map((name, index) => { + const stepComplete = !complete && index < step; + const stepActive = !complete && index === step; + + const liClasses = classNames({ + [styles.step]: true, + [styles.complete]: stepComplete, + [styles.active]: stepActive, + 'text-success': complete, + 'text-primary': !complete && (stepComplete || stepActive), + 'text-muted': !(stepComplete || stepActive || complete) + }); + + const bubbleClasses = classNames({ + [styles.bubble]: true, + 'text-success': complete, + 'bg-primary': stepActive, + 'text-primary': stepActive || stepComplete, + 'text-muted': !stepComplete && !stepActive + }); + + const iconClasses = classNames({ + 'text-primary': stepComplete, + 'text-white': stepActive, + 'text-gray-dark': !(complete || stepComplete || stepActive), + 'text-success': complete + }); + + const textClasses = classNames({ + 'hidden-xs-down': collapse !== false, + 'text-primary': stepComplete, + 'text-muted': !complete && index > step, + 'text-success': complete, + 'text-gray-dark': stepActive, + }); + + return ( +
  1. +
    + {complete || stepComplete ? : index + 1} +
    + {collapse !== true ? : null} +
  2. + ); + })} +
+ {collapse !== false ? +
+ +
: null} +
); }; Steps.propTypes = { - step: PropTypes.number, - steps: PropTypes.array.isRequired, - complete: PropTypes.bool + collapse: PropTypes.bool, + complete: PropTypes.bool, + step: PropTypes.number.isRequired, + steps: PropTypes.array.isRequired +}; + +Steps.defaultProps = { + complete: false, + step: 0, + steps: [] }; export default Steps; diff --git a/src/components/Steps.scss b/src/components/Steps.scss index 36b6973e5..4873ad825 100644 --- a/src/components/Steps.scss +++ b/src/components/Steps.scss @@ -1,9 +1,6 @@ // TODO these colors need to instead come from Bootstrap classes like muted/info/success/etc for theming: $line: 1px; -$done: #0275d8; // Saffron color-primary -$active: #0275d8; -$todo: #818a91; // Saffron color-muted -$complete: #21971d; // Saffron color-success +$todo: #818a91; // Saffron color-muted, needs to be text-muted .steps { align-items: flex-start; @@ -31,16 +28,16 @@ $complete: #21971d; // Saffron color-success background-image: linear-gradient(to right, transparent 50%, $todo 50%, $todo 100%); } &.complete { - background-image: linear-gradient(to right, transparent 50%, $done 50%, $done 100%); + background-image: linear-gradient(to right, transparent 50%, currentColor 50%, currentColor 100%); } } &:last-child { background-image: linear-gradient(to right, $todo 50%, transparent 50%, transparent 100%); &.active { - background-image: linear-gradient(to right, $done 50%, transparent 50%, transparent 100%); + background-image: linear-gradient(to right, currentColor 50%, transparent 50%, transparent 100%); } &.complete { - background-image: linear-gradient(to right, $done 50%, transparent 50%, transparent 100%); + background-image: linear-gradient(to right, currentColor 50%, transparent 50%, transparent 100%); } } @@ -59,34 +56,31 @@ $complete: #21971d; // Saffron color-success } &.active { - background-image: linear-gradient(to right, $done 50%, $todo 50%, $todo 100%); + background-image: linear-gradient(to right, currentColor 50%, $todo 50%, $todo 100%); .bubble { - border: $line solid $active; + border: $line solid currentColor; } } &.complete { - background-image: linear-gradient(to right, $done, $done); + background-image: linear-gradient(to right, currentColor, currentColor); .bubble { - border: $line solid $done; + border: $line solid currentColor; } } } &.complete { .step { - background-image: linear-gradient(to right, $complete, $complete); + background-image: linear-gradient(to right, currentColor, currentColor); .bubble { - border: $line solid $complete; - } - .text { - opacity: .5; + border: $line solid currentColor; } &:first-child { - background-image: linear-gradient(to right, transparent 50%, $complete 50%, $complete 100%); + background-image: linear-gradient(to right, transparent 50%, currentColor 50%, currentColor 100%); } &:last-child { - background-image: linear-gradient(to right, $complete 50%, transparent 50%, transparent 100%); + background-image: linear-gradient(to right, currentColor 50%, transparent 50%, transparent 100%); } } } diff --git a/test/components/Steps.spec.js b/test/components/Steps.spec.js index c9a75e59e..8ccbd9704 100644 --- a/test/components/Steps.spec.js +++ b/test/components/Steps.spec.js @@ -4,14 +4,45 @@ import { mount } from 'enzyme'; import { Steps } from '../../src'; +const steps = ['Alpha', 'Bravo', 'Charlie', 'Delta']; + describe('', () => { it('should render correctly', () => { - const steps = ['Alpha', 'Bravo', 'Charlie', 'Delta']; const component = mount(); assert(component); }); - it('should show correct number of steps'); - it('should activated the current step'); - it('should show complete correctly'); + it('should show correct number of steps', () => { + const component = mount(); + assert.equal(component.find('li').length, steps.length); + }); + + it('should activate the current step', () => { + const component = mount(); + assert.equal(component.find('label.text-gray-dark').text(), steps[2]); + }); + + it('should show complete correctly', () => { + const component = mount(); + assert.equal(component.find('li.text-success').length, steps.length); + }); + + describe('collapse', () => { + it('should default to showing responsive step labels', () => { + const component = mount(); + assert.equal(component.find('label').length, steps.length + 1); + assert.equal(component.find('label.hidden-xs-down').length, steps.length); + assert.equal(component.find('.hidden-sm-up label').length, 1); + }); + + it('should only show non-responsive step labels when collapse=false', () => { + const component = mount(); + assert.equal(component.find('label').length, steps.length); + }); + + it('should only show active step label when collapse=true', () => { + const component = mount(); + assert.equal(component.find('label').length, 1); + }); + }); });