diff --git a/CHANGELOG.md b/CHANGELOG.md index 28d46115bf1..8134f02c5b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## [`master`](https://github.com/elastic/eui/tree/master) -No public interface changes since `0.0.42`. +- Added `status` prop to `EuiStep` for additional styling ([#673](https://github.com/elastic/eui/pull/673)) ## [`0.0.42`](https://github.com/elastic/eui/tree/v0.0.42) diff --git a/src-docs/src/views/steps/status.js b/src-docs/src/views/steps/status.js new file mode 100644 index 00000000000..18b53c81958 --- /dev/null +++ b/src-docs/src/views/steps/status.js @@ -0,0 +1,69 @@ + +import React, { + Component, + Fragment, +} from 'react'; + +import { + EuiSpacer, + EuiSteps, + EuiButton, +} from '../../../../src/components'; + +export default class extends Component { + + constructor(props) { + super(props); + + this.state = { + status: 'incomplete', + }; + + this.handleComplete = this.handleComplete.bind(this); + } + + handleComplete() { + this.setState({ + status: 'complete', + }); + } + + render() { + + let button; + if (this.state.status === "incomplete") { + button = ( + You complete me + ); + } + + const firstSetOfSteps = [ + { + title: 'Normal step', + children:

Do this first

, + }, + { + title: 'Push the button to complete this final step', + children: ( + +

+ I am a fancy button just waiting to be pushed! +

+ + {button} +
+ ), + status: this.state.status, + }, + ]; + + return ( +
+ + +
+ ); + } +} diff --git a/src-docs/src/views/steps/steps_example.js b/src-docs/src/views/steps/steps_example.js index 1722dd04e50..aa7fb26eb72 100644 --- a/src-docs/src/views/steps/steps_example.js +++ b/src-docs/src/views/steps/steps_example.js @@ -9,6 +9,7 @@ import { import { EuiCode, EuiSteps, + EuiStep, } from '../../../../src/components'; import Steps from './steps'; @@ -27,6 +28,10 @@ import StepsHorizontal from './steps_horizontal'; const stepsHorizontalSource = require('!!raw-loader!./steps_horizontal'); const stepsHorizontalHtml = renderToHtml(StepsHorizontal); +import Status from './status'; +const statusSource = require('!!raw-loader!./status'); +const statusHtml = renderToHtml(Steps); + export const StepsExample = { title: 'Steps', sections: [{ @@ -42,7 +47,7 @@ export const StepsExample = { Numbered steps

), - props: { EuiSteps }, + props: { EuiSteps, EuiStep }, demo: , }, { @@ -87,6 +92,24 @@ export const StepsExample = { ), demo: , }, + { + title: 'Steps status', + source: [{ + type: GuideSectionTypes.JS, + code: statusSource, + }, { + type: GuideSectionTypes.HTML, + code: statusHtml, + }], + text: ( +

+ Steps can optionally include status prop with + a value of complete or incomplete. This + is used mostly as a final step when you need to make some sort of final check. +

+ ), + demo: , + }, { title: 'Horizontal', source: [{ diff --git a/src/components/index.js b/src/components/index.js index a1f1c7c02c7..6bc10cff422 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -234,6 +234,7 @@ export { } from './spacer'; export { + EuiStep, EuiSteps, EuiSubSteps, EuiStepsHorizontal, diff --git a/src/components/steps/__snapshots__/step.test.js.snap b/src/components/steps/__snapshots__/step.test.js.snap index 78aad488456..bf044f3553a 100644 --- a/src/components/steps/__snapshots__/step.test.js.snap +++ b/src/components/steps/__snapshots__/step.test.js.snap @@ -11,9 +11,13 @@ exports[`EuiStep is rendered 1`] = ` > Step +
+ 1 +

First step

diff --git a/src/components/steps/__snapshots__/steps.test.js.snap b/src/components/steps/__snapshots__/steps.test.js.snap index 0bdafa76406..4f2467bce8c 100644 --- a/src/components/steps/__snapshots__/steps.test.js.snap +++ b/src/components/steps/__snapshots__/steps.test.js.snap @@ -14,9 +14,13 @@ exports[`EuiSteps renders step title inside "headingElement" element 1`] = ` > Step +
+ 1 +

first title

@@ -36,9 +40,13 @@ exports[`EuiSteps renders step title inside "headingElement" element 1`] = ` > Step +
+ 2 +

second title

@@ -58,9 +66,13 @@ exports[`EuiSteps renders step title inside "headingElement" element 1`] = ` > Step +
+ 3 +

third title

@@ -89,9 +101,13 @@ exports[`EuiSteps renders steps 1`] = ` > Step +
+ 1 +

first title

@@ -111,9 +127,13 @@ exports[`EuiSteps renders steps 1`] = ` > Step +
+ 2 +

second title

@@ -133,9 +153,13 @@ exports[`EuiSteps renders steps 1`] = ` > Step +
+ 3 +

third title

@@ -164,9 +188,13 @@ exports[`EuiSteps renders steps with firstStepNumber 1`] = ` > Step +
+ 10 +

first title

@@ -186,9 +214,13 @@ exports[`EuiSteps renders steps with firstStepNumber 1`] = ` > Step +
+ 11 +

second title

@@ -208,9 +240,13 @@ exports[`EuiSteps renders steps with firstStepNumber 1`] = ` > Step +
+ 12 +

third title

diff --git a/src/components/steps/_steps.scss b/src/components/steps/_steps.scss index e0c6f014413..2343c6d42cb 100644 --- a/src/components/steps/_steps.scss +++ b/src/components/steps/_steps.scss @@ -12,18 +12,33 @@ line-height: $euiStepNumberSize; /* 1 */ } - .euiStep__title { - font-weight: $euiFontWeightMedium; + .euiStep__circle { + @include createStepsNumber(); + + margin-right: $euiStepNumberMargin; + vertical-align: top; /* 1 */ - &::before { - content: attr(data-step-num); // Get the number from the data attribute - @include createStepsNumber(); + &.euiStep__circle--incomplete { + background-color: transparent; + border: solid 2px $euiColorPrimary; + color: $euiColorDarkShade; + } + + &.euiStep__circle--complete { + animation: euiGrow $euiAnimSpeedFast $euiAnimSlightBounce; + } - margin-right: $euiStepNumberMargin; - vertical-align: top; /* 1 */ + .euiStep__circleIcon { + position: relative; + top: -2px; } } + .euiStep__title { + font-weight: $euiFontWeightMedium; + display: inline-block; + } + .euiStep__content { border-left: $euiBorderThick; padding: $euiSize $euiSize $euiSizeXL; @@ -36,4 +51,3 @@ margin-left: ($euiStepNumberSize/2) - 1px; } } - diff --git a/src/components/steps/index.js b/src/components/steps/index.js index 2ec2fba1f9a..9f063b5aaab 100644 --- a/src/components/steps/index.js +++ b/src/components/steps/index.js @@ -1,3 +1,7 @@ +export { + EuiStep, +} from './step'; + export { EuiSteps, } from './steps'; diff --git a/src/components/steps/step.js b/src/components/steps/step.js index 162bb32424f..770dbf5c03d 100644 --- a/src/components/steps/step.js +++ b/src/components/steps/step.js @@ -10,15 +10,35 @@ import { EuiTitle, } from '../title'; +import { + EuiIcon, +} from '../icon'; + export const EuiStep = ({ className, children, headingElement, step, title, + status, ...rest }) => { const classes = classNames('euiStep', className); + const circleClasses = classNames( + 'euiStep__circle', + { + 'euiStep__circle--complete': (status === "complete"), + 'euiStep__circle--incomplete': (status === "incomplete"), + } + ); + + let numberOrIcon; + if (status === "complete") { + numberOrIcon = ; + } else if (status !== "incomplete") { + numberOrIcon = step; + } + return (
Step - +
+ {numberOrIcon} +
+ + {React.createElement(headingElement, null, title)} @@ -41,8 +65,18 @@ export const EuiStep = ({ EuiStep.propTypes = { children: PropTypes.node.isRequired, + /** + * Will replace the number provided in props.step with alternate styling + */ + status: PropTypes.oneOf(['complete', 'incomplete']), + /** + * The number of the step in the list of steps + */ step: PropTypes.number.isRequired, title: PropTypes.string.isRequired, + /** + * The HTML tag used for the title + */ headingElement: PropTypes.string.isRequired, }; diff --git a/src/components/steps/steps.js b/src/components/steps/steps.js index e888f90c202..7fa47e881c7 100644 --- a/src/components/steps/steps.js +++ b/src/components/steps/steps.js @@ -9,6 +9,7 @@ function renderSteps(steps, firstStepNumber, headingElement) { className, children, title, + status, ...rest } = step; @@ -19,6 +20,7 @@ function renderSteps(steps, firstStepNumber, headingElement) { headingElement={headingElement} step={firstStepNumber + index} title={title} + status={status} {...rest} > {children} @@ -53,8 +55,17 @@ const stepPropType = PropTypes.shape({ EuiSteps.propTypes = { className: PropTypes.string, + /** + * The number the steps should begin from + */ firstStepNumber: PropTypes.number, + /** + * The HTML tag used for the title + */ headingElement: PropTypes.string, + /** + * An array of individal step objects + */ steps: PropTypes.arrayOf(stepPropType).isRequired, };