diff --git a/docs/app/Examples/elements/Step/Content/Descriptions.js b/docs/app/Examples/elements/Step/Content/Descriptions.js
new file mode 100644
index 0000000000..0df71028ec
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Content/Descriptions.js
@@ -0,0 +1,32 @@
+import React from 'react'
+import { Step } from 'stardust'
+
+const { Description, Group, Title } = Step
+
+const Descriptions = () => (
+
+
+
+ Shipping
+ Choose your shipping options
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
+
+export default Descriptions
diff --git a/docs/app/Examples/elements/Step/Content/Icons.js b/docs/app/Examples/elements/Step/Content/Icons.js
new file mode 100644
index 0000000000..82345ba888
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Content/Icons.js
@@ -0,0 +1,25 @@
+import React from 'react'
+import { Icon, Step } from 'stardust'
+
+const { Content, Description, Group, Title } = Step
+
+const Icons = () => (
+
+
+
+
+ Shipping
+ Choose your shipping options
+
+
+
+
+
+
+
+
+
+
+)
+
+export default Icons
diff --git a/docs/app/Examples/elements/Step/Content/Links.js b/docs/app/Examples/elements/Step/Content/Links.js
new file mode 100644
index 0000000000..757d714440
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Content/Links.js
@@ -0,0 +1,37 @@
+import React, { Component } from 'react'
+import { Step } from 'stardust'
+
+class ClickableStep extends Component {
+ state = {}
+
+ handleClick = () => this.setState({ active: !this.state.active })
+
+ render() {
+ return
+ }
+}
+
+const Links = () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
+
+export default Links
diff --git a/docs/app/Examples/elements/Step/Content/index.js b/docs/app/Examples/elements/Step/Content/index.js
new file mode 100644
index 0000000000..6626abedf4
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Content/index.js
@@ -0,0 +1,27 @@
+import React from 'react'
+import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample'
+import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'
+
+const Content = () => (
+
+
+
+
+
+
+
+)
+
+export default Content
diff --git a/docs/app/Examples/elements/Step/Groups/Groups.js b/docs/app/Examples/elements/Step/Groups/Groups.js
new file mode 100644
index 0000000000..aa048fb094
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Groups/Groups.js
@@ -0,0 +1,36 @@
+import React from 'react'
+import { Icon, Step } from 'stardust'
+
+const { Content, Description, Group, Title } = Step
+const steps = [
+ { icon: 'truck', title: 'Shipping', description: 'Choose your shipping options' },
+ { active: true, icon: 'payment', title: 'Billing', description: 'Enter billing information' },
+ { disabled: true, icon: 'info', title: 'Confirm Order' },
+]
+
+const Groups = () => (
+
+
+
+
+
+ Shipping
+ Choose your shipping options
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
+
+export default Groups
diff --git a/docs/app/Examples/elements/Step/Groups/Ordered.js b/docs/app/Examples/elements/Step/Groups/Ordered.js
new file mode 100644
index 0000000000..6f6cea92f3
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Groups/Ordered.js
@@ -0,0 +1,32 @@
+import React from 'react'
+import { Step } from 'stardust'
+
+const { Content, Description, Group, Title } = Step
+const steps = [
+ { completed: true, title: 'Shipping', description: 'Choose your shipping options' },
+ { completed: true, title: 'Billing', description: 'Enter billing information' },
+ { active: true, title: 'Confirm Order', description: 'Verify order details' },
+]
+
+const Ordered = () => (
+
+
+
+
+ Shipping
+ Choose your shipping options
+
+
+
+
+
+
+
+
+
+
+
+
+)
+
+export default Ordered
diff --git a/docs/app/Examples/elements/Step/Groups/Vertical.js b/docs/app/Examples/elements/Step/Groups/Vertical.js
new file mode 100644
index 0000000000..57be572006
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Groups/Vertical.js
@@ -0,0 +1,36 @@
+import React from 'react'
+import { Icon, Step } from 'stardust'
+
+const { Content, Description, Group, Title } = Step
+const steps = [
+ { completed: true, icon: 'truck', title: 'Shipping', description: 'Choose your shipping options' },
+ { completed: true, icon: 'credit card', title: 'Billing', description: 'Enter billing information' },
+ { active: true, icon: 'info', title: 'Confirm Order', description: 'Verify order details' },
+]
+
+const Vertical = () => (
+
+
+
+
+
+ Shipping
+ Choose your shipping options
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
+
+export default Vertical
diff --git a/docs/app/Examples/elements/Step/Groups/index.js b/docs/app/Examples/elements/Step/Groups/index.js
new file mode 100644
index 0000000000..e8a45c8f40
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Groups/index.js
@@ -0,0 +1,36 @@
+import React from 'react'
+import { Message } from 'stardust'
+
+import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample'
+import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'
+
+// TODO: Update usage after v1 API
+
+const Groups = () => (
+
+
+
+ Steps will automatically stack on mobile. To make steps automatically stack for tablet use the tablet
+ stackable variation.
+
+
+
+
+
+
+
+)
+
+export default Groups
diff --git a/docs/app/Examples/elements/Step/States/Active.js b/docs/app/Examples/elements/Step/States/Active.js
new file mode 100644
index 0000000000..b7e1092c47
--- /dev/null
+++ b/docs/app/Examples/elements/Step/States/Active.js
@@ -0,0 +1,20 @@
+import React from 'react'
+import { Icon, Step } from 'stardust'
+
+const { Content, Description, Group, Title } = Step
+
+const Active = () => (
+
+
+
+
+ Billing
+ Enter billing information
+
+
+
+
+
+)
+
+export default Active
diff --git a/docs/app/Examples/elements/Step/States/Completed.js b/docs/app/Examples/elements/Step/States/Completed.js
new file mode 100644
index 0000000000..0c70e3b681
--- /dev/null
+++ b/docs/app/Examples/elements/Step/States/Completed.js
@@ -0,0 +1,20 @@
+import React from 'react'
+import { Step } from 'stardust'
+
+const { Group } = Step
+
+const Completed = () => (
+
+
+
+
+
+
+
+
+
+
+
+)
+
+export default Completed
diff --git a/docs/app/Examples/elements/Step/States/Disabled.js b/docs/app/Examples/elements/Step/States/Disabled.js
new file mode 100644
index 0000000000..5cca943d07
--- /dev/null
+++ b/docs/app/Examples/elements/Step/States/Disabled.js
@@ -0,0 +1,10 @@
+import React from 'react'
+import { Step } from 'stardust'
+
+const Disabled = () => (
+
+ Billing
+
+)
+
+export default Disabled
diff --git a/docs/app/Examples/elements/Step/States/index.js b/docs/app/Examples/elements/Step/States/index.js
new file mode 100644
index 0000000000..87b14460cb
--- /dev/null
+++ b/docs/app/Examples/elements/Step/States/index.js
@@ -0,0 +1,29 @@
+import React from 'react'
+import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample'
+import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'
+
+const States = () => (
+
+
+
+
+
+
+
+
+
+)
+
+export default States
diff --git a/docs/app/Examples/elements/Step/Types/Basic.js b/docs/app/Examples/elements/Step/Types/Basic.js
new file mode 100644
index 0000000000..73843aa500
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Types/Basic.js
@@ -0,0 +1,10 @@
+import React from 'react'
+import { Step } from 'stardust'
+
+const Basic = () => (
+
+ Shipping
+
+)
+
+export default Basic
diff --git a/docs/app/Examples/elements/Step/Types/index.js b/docs/app/Examples/elements/Step/Types/index.js
new file mode 100644
index 0000000000..6dc89e427f
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Types/index.js
@@ -0,0 +1,17 @@
+import React from 'react'
+import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample'
+import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'
+
+const Types = () => (
+
+
+
+
+
+)
+
+export default Types
diff --git a/docs/app/Examples/elements/Step/Variations/Fluid.js b/docs/app/Examples/elements/Step/Variations/Fluid.js
new file mode 100644
index 0000000000..298bf35d20
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Variations/Fluid.js
@@ -0,0 +1,19 @@
+import React from 'react'
+import { Grid, Step } from 'stardust'
+
+const Fluid = () => (
+
+
+
+
+
+
+
+
+
+ The steps take up the entire column width
+
+
+)
+
+export default Fluid
diff --git a/docs/app/Examples/elements/Step/Variations/Sizes.js b/docs/app/Examples/elements/Step/Variations/Sizes.js
new file mode 100644
index 0000000000..2f9983b49f
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Variations/Sizes.js
@@ -0,0 +1,38 @@
+import React from 'react'
+import { Step } from 'stardust'
+
+const steps = [
+ { icon: 'truck', title: 'Shipping', description: 'Choose your shipping options' },
+ { active: true, icon: 'payment', title: 'Billing', description: 'Enter billing information' },
+ { disabled: true, icon: 'info', title: 'Confirm Order', description: 'Verify order details' },
+]
+const simpleSteps = [
+ { icon: 'truck', title: 'Shipping' },
+ { active: true, icon: 'payment', title: 'Billing' },
+]
+
+const Sizes = () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+)
+
+export default Sizes
diff --git a/docs/app/Examples/elements/Step/Variations/Stackable.js b/docs/app/Examples/elements/Step/Variations/Stackable.js
new file mode 100644
index 0000000000..c1611b97e1
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Variations/Stackable.js
@@ -0,0 +1,12 @@
+import React from 'react'
+import { Step } from 'stardust'
+
+const Stackable = () => (
+
+
+
+
+
+)
+
+export default Stackable
diff --git a/docs/app/Examples/elements/Step/Variations/index.js b/docs/app/Examples/elements/Step/Variations/index.js
new file mode 100644
index 0000000000..f9baedac18
--- /dev/null
+++ b/docs/app/Examples/elements/Step/Variations/index.js
@@ -0,0 +1,27 @@
+import React from 'react'
+import ComponentExample from 'docs/app/Components/ComponentDoc/ComponentExample'
+import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'
+
+const Variations = () => (
+
+
+
+
+
+
+
+)
+
+export default Variations
diff --git a/docs/app/Examples/elements/Step/index.js b/docs/app/Examples/elements/Step/index.js
new file mode 100644
index 0000000000..520826a0a0
--- /dev/null
+++ b/docs/app/Examples/elements/Step/index.js
@@ -0,0 +1,19 @@
+import React from 'react'
+
+import Content from './Content'
+import Groups from './Groups'
+import States from './States'
+import Types from './Types'
+import Variations from './Variations'
+
+const StepExamples = () => (
+
+
+
+
+
+
+
+)
+
+export default StepExamples
diff --git a/src/elements/Step/Step.js b/src/elements/Step/Step.js
new file mode 100644
index 0000000000..4510beaec0
--- /dev/null
+++ b/src/elements/Step/Step.js
@@ -0,0 +1,104 @@
+import cx from 'classnames'
+import React, { PropTypes } from 'react'
+
+import META from '../../utils/Meta'
+import { customPropTypes, iconPropRenderer, getUnhandledProps, useKeyOnly } from '../../utils/propUtils'
+import StepContent from './StepContent'
+import StepDescription from './StepDescription'
+import StepGroup from './StepGroup'
+import StepTitle from './StepTitle'
+
+/** A step shows the completion status of an activity in a series of activities. */
+function Step(props) {
+ const {
+ active, className, children, completed, description, disabled, icon, href, link, onClick, title,
+ } = props
+ const classes = cx(
+ useKeyOnly(active, 'active'),
+ useKeyOnly(completed, 'completed'),
+ useKeyOnly(disabled, 'disabled'),
+ useKeyOnly(link, 'link'),
+ className,
+ 'step',
+ )
+ const rest = getUnhandledProps(Step, props)
+
+ const handleClick = (e) => {
+ if (onClick) onClick(e)
+ }
+ const StepComponent = href || onClick ? 'a' : 'div'
+
+ return (
+
+ {!children && iconPropRenderer(icon)}
+ {children || }
+
+ )
+}
+
+Step._meta = {
+ name: 'Step',
+ type: META.type.element,
+}
+
+Step.propTypes = {
+ /** A step can be highlighted as active. */
+ active: PropTypes.bool,
+
+ /** Classes that will be added to the Step className. */
+ className: PropTypes.string,
+
+ /** Primary content of the Step. Mutually exclusive with description and title props. */
+ children: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['description', 'title']),
+ PropTypes.node,
+ ]),
+
+ /** A step can show that a user has completed it. */
+ completed: PropTypes.bool,
+
+ /** Shorthand prop for StepDescription. Mutually exclusive with children. */
+ description: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['children']),
+ PropTypes.node,
+ ]),
+
+ /** Show that the Loader is inactive. */
+ disabled: PropTypes.bool,
+
+ /** A step can contain an icon. */
+ icon: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['children']),
+ PropTypes.node,
+ ]),
+
+ /** A step can be link. */
+ link: PropTypes.bool,
+
+ /** Render as an `a` tag instead of a `div` and adds the href attribute. */
+ href: PropTypes.string,
+
+ /** Render as an `a` tag instead of a `div` and called with event on Step click. */
+ onClick: PropTypes.func,
+
+ /** A step can show a ordered sequence of steps. Passed from StepGroup. */
+ ordered: PropTypes.bool,
+
+ /** Shorthand prop for StepTitle. Mutually exclusive with children. */
+ title: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['children']),
+ PropTypes.node,
+ ]),
+}
+
+Step.Content = StepContent
+Step.Description = StepDescription
+Step.Group = StepGroup
+Step.Title = StepTitle
+
+export default Step
diff --git a/src/elements/Step/StepContent.js b/src/elements/Step/StepContent.js
new file mode 100644
index 0000000000..776d481ca7
--- /dev/null
+++ b/src/elements/Step/StepContent.js
@@ -0,0 +1,55 @@
+import React, { PropTypes } from 'react'
+import cx from 'classnames'
+
+import META from '../../utils/Meta'
+import { customPropTypes, getUnhandledProps } from '../../utils/propUtils'
+import StepDescription from './StepDescription'
+import StepTitle from './StepTitle'
+
+function StepContent(props) {
+ const { className, children, description, title } = props
+ const classes = cx(className, 'content')
+ const rest = getUnhandledProps(StepContent, props)
+
+ if (children) {
+ return { children }
+ }
+
+ return (
+
+ { title && }
+ { description && }
+
+ )
+}
+
+StepContent._meta = {
+ name: 'StepContent',
+ parent: 'Step',
+ type: META.type.element,
+}
+
+StepContent.propTypes = {
+ /** Classes that will be added to the StepContent className. */
+ className: PropTypes.string,
+
+ /** Primary content of StepContent. Mutually exclusive with description and title props. */
+ children: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['description', 'title']),
+ PropTypes.node,
+ ]),
+
+ /** Primary content of the StepDescription. Mutually exclusive with children. */
+ description: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['children']),
+ PropTypes.node,
+ ]),
+
+ /** Primary content of the StepTitle. Mutually exclusive with children. */
+ title: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['children']),
+ PropTypes.node,
+ ]),
+}
+
+export default StepContent
diff --git a/src/elements/Step/StepDescription.js b/src/elements/Step/StepDescription.js
new file mode 100644
index 0000000000..a8403de00b
--- /dev/null
+++ b/src/elements/Step/StepDescription.js
@@ -0,0 +1,38 @@
+import cx from 'classnames'
+import React, { PropTypes } from 'react'
+
+import META from '../../utils/Meta'
+import { customPropTypes, getUnhandledProps } from '../../utils/propUtils'
+
+function StepDescription(props) {
+ const { className, children, description } = props
+ const classes = cx(className, 'description')
+ const rest = getUnhandledProps(StepDescription, props)
+
+ return { children || description }
+}
+
+StepDescription._meta = {
+ name: 'StepDescription',
+ parent: 'Step',
+ type: META.type.element,
+}
+
+StepDescription.propTypes = {
+ /** Classes that will be added to the StepDescription className. */
+ className: PropTypes.string,
+
+ /** Primary content of the StepDescription. Mutually exclusive with description prop. */
+ children: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['description']),
+ PropTypes.node,
+ ]),
+
+ /** Primary content of the StepDescription. Mutually exclusive with children. */
+ description: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['children']),
+ PropTypes.node,
+ ]),
+}
+
+export default StepDescription
diff --git a/src/elements/Step/StepGroup.js b/src/elements/Step/StepGroup.js
new file mode 100644
index 0000000000..431ea3990d
--- /dev/null
+++ b/src/elements/Step/StepGroup.js
@@ -0,0 +1,80 @@
+import _ from 'lodash'
+import cx from 'classnames'
+import React, { PropTypes } from 'react'
+
+import META from '../../utils/Meta'
+import { customPropTypes, getUnhandledProps, useValueAndKey, useKeyOnly } from '../../utils/propUtils'
+import * as sui from '../../utils/semanticUtils'
+import Step from './Step'
+
+function StepGroup(props) {
+ const { className, children, fluid, items, ordered, size, stackable, vertical } = props
+ const classes = cx(
+ 'ui',
+ useKeyOnly(fluid, 'fluid'),
+ useKeyOnly(ordered, 'ordered'),
+ useValueAndKey(stackable, 'stackable'),
+ useKeyOnly(vertical, 'vertical'),
+ size,
+ className,
+ 'steps',
+ )
+ const rest = getUnhandledProps(StepGroup, props)
+
+ const content = items
+ ? items.map(item => {
+ const key = item.key || [item.title, item.description].join('-')
+ return
+ }) : children
+
+ return {content}
+}
+
+StepGroup._meta = {
+ name: 'StepGroup',
+ parent: 'Step',
+ props: {
+ sizes: _.without(sui.sizes, 'medium'),
+ stackable: ['tablet'],
+ },
+ type: META.type.element,
+}
+
+StepGroup.propTypes = {
+ /** Classes that will be added to the StepGroup className. */
+ className: PropTypes.string,
+
+ /** Primary content of the StepGroup. Mutually exclusive with items prop. */
+ children: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['items']),
+ PropTypes.node,
+ ]),
+
+ /** A fluid step takes up the width of its container. */
+ fluid: PropTypes.bool,
+
+ /** Primary content of the StepGroup. Mutually exclusive with items children. */
+ items: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['description', 'title']),
+ PropTypes.arrayOf(PropTypes.shape({
+ description: PropTypes.node,
+ icon: PropTypes.node,
+ key: PropTypes.string,
+ title: PropTypes.node,
+ })),
+ ]),
+
+ /** A step can show a ordered sequence of steps. */
+ ordered: PropTypes.bool,
+
+ /** Steps can have different sizes. */
+ size: PropTypes.oneOf(StepGroup._meta.props.sizes),
+
+ /** A step can stack vertically only on smaller screens. */
+ stackable: PropTypes.oneOf(StepGroup._meta.props.stackable),
+
+ /** A step can be displayed stacked vertically. */
+ vertical: PropTypes.bool,
+}
+
+export default StepGroup
diff --git a/src/elements/Step/StepTitle.js b/src/elements/Step/StepTitle.js
new file mode 100644
index 0000000000..aedcb45df1
--- /dev/null
+++ b/src/elements/Step/StepTitle.js
@@ -0,0 +1,38 @@
+import cx from 'classnames'
+import React, { PropTypes } from 'react'
+
+import META from '../../utils/Meta'
+import { customPropTypes, getUnhandledProps } from '../../utils/propUtils'
+
+function StepTitle(props) {
+ const { className, children, title } = props
+ const classes = cx(className, 'title')
+ const rest = getUnhandledProps(StepTitle, props)
+
+ return { children || title }
+}
+
+StepTitle._meta = {
+ name: 'StepTitle',
+ parent: 'Step',
+ type: META.type.element,
+}
+
+StepTitle.propTypes = {
+ /** Classes that will be added to the StepTitle className. */
+ className: PropTypes.string,
+
+ /** Primary content of the StepTitle. Mutually exclusive with title prop. */
+ children: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['title']),
+ PropTypes.node,
+ ]),
+
+ /** Primary content of the StepTitle. Mutually exclusive with children. */
+ title: customPropTypes.all([
+ customPropTypes.mutuallyExclusive(['children']),
+ PropTypes.node,
+ ]),
+}
+
+export default StepTitle
diff --git a/src/index.js b/src/index.js
index 2e8c46287a..3c6bfa8569 100644
--- a/src/index.js
+++ b/src/index.js
@@ -55,6 +55,7 @@ export const ListItem = deprecateComponent('ListItem', 'Use "List.Item" instead.
export Segment from './elements/Segment/Segment'
export Segments from './elements/Segment/SegmentSegments'
+export Step from './elements/Step/Step'
export Rail from './elements/Rail/Rail'
// ----------------------------------------
diff --git a/test/specs/elements/Step/Step-test.js b/test/specs/elements/Step/Step-test.js
new file mode 100644
index 0000000000..1eca600a32
--- /dev/null
+++ b/test/specs/elements/Step/Step-test.js
@@ -0,0 +1,71 @@
+import faker from 'faker'
+import React from 'react'
+
+import * as common from 'test/specs/commonTests'
+import sandbox from 'test/utils/Sandbox-util'
+import Step from 'src/elements/Step/Step'
+import StepContent from 'src/elements/Step/StepContent'
+import StepDescription from 'src/elements/Step/StepDescription'
+import StepTitle from 'src/elements/Step/StepTitle'
+
+describe('Step', () => {
+ common.isConformant(Step)
+ common.implementsIconProp(Step)
+ common.hasSubComponents(Step, [StepContent, StepDescription, StepTitle])
+ common.propKeyOnlyToClassName(Step, 'active')
+ common.propKeyOnlyToClassName(Step, 'completed')
+ common.propKeyOnlyToClassName(Step, 'disabled')
+ common.propKeyOnlyToClassName(Step, 'link')
+ common.rendersChildren(Step)
+
+ it('renders only children by default', () => {
+ shallow({faker.hacker.phrase()})
+ .should.not.have.descendants('StepContent')
+ })
+
+ it('renders Description component', () => {
+ const wrapper = mount()
+
+ wrapper.should.have.descendants('StepContent')
+ wrapper.find('StepContent').should.have.descendants('StepDescription')
+ })
+
+ it('renders Title component', () => {
+ const wrapper = mount()
+
+ wrapper.should.have.descendants('StepContent')
+ wrapper.find('StepContent').should.have.descendants('StepTitle')
+ })
+
+ describe('renders different elements', () => {
+ it(' by default', () => {
+ shallow(
).should.have.tagName('div')
+ })
+
+ it('
with `href` prop', () => {
+ const url = faker.internet.url()
+ const wrapper = shallow()
+
+ wrapper.should.have.tagName('a')
+ wrapper.should.have.attr('href', url)
+ })
+
+ describe('onClick prop', () => {
+ it('can be omitted', () => {
+ const click = () => mount({faker.hacker.phrase()}).simulate('click')
+ expect(click).to.not.throw()
+ })
+
+ it('renders and handles click', () => {
+ const handleClick = sandbox.spy()
+ const wrapper = mount()
+
+ wrapper.should.have.tagName('a')
+ wrapper.simulate('click')
+
+ handleClick.should.have.been.calledOnce()
+ handleClick.should.have.been.calledWithMatch({})
+ })
+ })
+ })
+})
diff --git a/test/specs/elements/Step/StepContent-test.js b/test/specs/elements/Step/StepContent-test.js
new file mode 100644
index 0000000000..b1448c3906
--- /dev/null
+++ b/test/specs/elements/Step/StepContent-test.js
@@ -0,0 +1,30 @@
+import faker from 'faker'
+import React from 'react'
+
+import * as common from 'test/specs/commonTests'
+import StepContent from 'src/elements/Step/StepContent'
+import StepDescription from 'src/elements/Step/StepDescription'
+import StepTitle from 'src/elements/Step/StepTitle'
+
+describe('StepContent', () => {
+ common.isConformant(StepContent)
+ common.rendersChildren(StepContent)
+
+ describe('description prop', () => {
+ it('renders description component', () => {
+ const text = faker.hacker.phrase()
+
+ shallow()
+ .should.contain()
+ })
+ })
+
+ describe('title prop', () => {
+ it('renders title component', () => {
+ const text = faker.hacker.phrase()
+
+ shallow()
+ .should.contain()
+ })
+ })
+})
diff --git a/test/specs/elements/Step/StepDescription-test.js b/test/specs/elements/Step/StepDescription-test.js
new file mode 100644
index 0000000000..7ade4c1d5f
--- /dev/null
+++ b/test/specs/elements/Step/StepDescription-test.js
@@ -0,0 +1,26 @@
+import faker from 'faker'
+import React from 'react'
+
+import * as common from 'test/specs/commonTests'
+import StepDescription from 'src/elements/Step/StepDescription'
+
+describe('StepDescription', () => {
+ common.isConformant(StepDescription)
+ common.rendersChildren(StepDescription)
+
+ describe('description prop', () => {
+ it('renders child text', () => {
+ const text = faker.hacker.phrase()
+
+ shallow()
+ .should.contain.text(text)
+ })
+
+ it('renders child node', () => {
+ const child =
+
+ shallow()
+ .should.contain(child)
+ })
+ })
+})
diff --git a/test/specs/elements/Step/StepGroup-test.js b/test/specs/elements/Step/StepGroup-test.js
new file mode 100644
index 0000000000..2779ca7a44
--- /dev/null
+++ b/test/specs/elements/Step/StepGroup-test.js
@@ -0,0 +1,44 @@
+import faker from 'faker'
+import React from 'react'
+import * as common from 'test/specs/commonTests'
+import Step from 'src/elements/Step/Step'
+import StepGroup from 'src/elements/Step/StepGroup'
+
+describe('StepGroup', () => {
+ common.isConformant(StepGroup)
+ common.hasUIClassName(StepGroup)
+ common.propKeyOnlyToClassName(StepGroup, 'fluid')
+ common.propKeyOnlyToClassName(StepGroup, 'ordered')
+ common.propKeyAndValueToClassName(StepGroup, 'stackable')
+ common.propKeyOnlyToClassName(StepGroup, 'vertical')
+
+ describe('renders children', () => {
+ const firstText = faker.hacker.phrase()
+ const secondText = faker.hacker.phrase()
+
+ it('with `children` prop', () => {
+ const wrapper = mount(
+
+ {firstText}
+ {secondText}
+
+ )
+ .find('Step')
+
+ wrapper.first().should.contain.text(firstText)
+ wrapper.last().should.contain.text(secondText)
+ })
+
+ it('with `items` prop', () => {
+ const items = [
+ { title: firstText },
+ { title: secondText },
+ ]
+
+ const wrapper = mount().find('Step')
+
+ wrapper.first().find('StepTitle').should.contain.text(firstText)
+ wrapper.last().find('StepTitle').should.contain.text(secondText)
+ })
+ })
+})
diff --git a/test/specs/elements/Step/StepTitle-test.js b/test/specs/elements/Step/StepTitle-test.js
new file mode 100644
index 0000000000..18d5887099
--- /dev/null
+++ b/test/specs/elements/Step/StepTitle-test.js
@@ -0,0 +1,26 @@
+import faker from 'faker'
+import React from 'react'
+
+import * as common from 'test/specs/commonTests'
+import StepTitle from 'src/elements/Step/StepTitle'
+
+describe('StepTitle', () => {
+ common.isConformant(StepTitle)
+ common.rendersChildren(StepTitle)
+
+ describe('description prop', () => {
+ it('renders child text', () => {
+ const text = faker.hacker.phrase()
+
+ shallow()
+ .should.contain.text(text)
+ })
+
+ it('renders child node', () => {
+ const child =
+
+ shallow()
+ .should.contain(child)
+ })
+ })
+})