diff --git a/docs/src/pages/component-api/MobileStepper/MobileStepper.md b/docs/src/pages/component-api/MobileStepper/MobileStepper.md new file mode 100644 index 00000000000000..cfa97aa210cd74 --- /dev/null +++ b/docs/src/pages/component-api/MobileStepper/MobileStepper.md @@ -0,0 +1,34 @@ +# MobileStepper + + + +## Props +| Name | Type | Default | Description | +|:-----|:-----|:--------|:------------| +| activeStep | number | `0` | Specifies the currently active step. | +| disableBack | bool | `false` | Set to disable the back button. | +| disableNext | bool | `false` | Set to disable the next button. | +| kind | `text`, `dots` or `progress` | `dots` | Defines the kind of mobile stepper to use. | +| onBack | function | | Supplied to the onClick attribute of the back button. | +| onNext | function | | Supplied to the onClick attribute of the next button. | +| steps | number | | The total amount of steps. | + + +Any other properties supplied will be spread to the root element. + +## Classes + +You can overrides all the class names injected by Material-UI thanks to the `classes` property. +This property accepts the following keys: +- `mobileStepper` +- `button` +- `dots` +- `dot` +- `dotActive` + +Have a look at [overriding with class names](/customization/overrides#overriding-with-class-names) +section for more detail. + +If using the `overrides` key of the theme as documented +[here](/customization/themes#customizing-all-instances-of-a-component-type), +you need to use the following style sheet name: `MuiAppBar`. diff --git a/docs/src/pages/component-demos/mobile-stepper/DotsMobileStepper.js b/docs/src/pages/component-demos/mobile-stepper/DotsMobileStepper.js new file mode 100644 index 00000000000000..32b62c2f0b1d6f --- /dev/null +++ b/docs/src/pages/component-demos/mobile-stepper/DotsMobileStepper.js @@ -0,0 +1,66 @@ +// @flow + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles, createStyleSheet } from 'material-ui/styles'; +import MobileStepper from 'material-ui/MobileStepper'; + +const styleSheet = createStyleSheet('DotsMobileStepper', { + root: { + position: 'relative', + marginTop: 30, + width: '100%', + }, + mobileStepper: { + // TODO: Ensure this class takes precedence and remove the !important + position: 'relative !important', + }, +}); + +class DotsMobileStepper extends Component { + static propTypes = { + classes: PropTypes.object.isRequired, + } + + constructor(props) { + super(props); + this.state = { + activeStep: 0, + }; + } + + handleOnNext = () => { + const activeStep = this.state.activeStep === 5 ? 5 : this.state.activeStep + 1; + this.setState({ + activeStep, + }); + } + + handleOnBack = () => { + const activeStep = this.state.activeStep === 0 ? 0 : this.state.activeStep - 1; + this.setState({ + activeStep, + }); + } + + render() { + const classes = this.props.classes; + return ( +
+ +
+ ); + } +} + + +export default withStyles(styleSheet)(DotsMobileStepper); diff --git a/docs/src/pages/component-demos/mobile-stepper/mobile-stepper.md b/docs/src/pages/component-demos/mobile-stepper/mobile-stepper.md new file mode 100644 index 00000000000000..987f5b1630e4fc --- /dev/null +++ b/docs/src/pages/component-demos/mobile-stepper/mobile-stepper.md @@ -0,0 +1,12 @@ +--- +components: MobileStepper +--- + +# MobileStepper + +The [MobileStepper](https://material.io/guidelines/layout/structure.html#structure-mobile-stepper) implements a compact stepper suitable for a mobile device. + +## Mobile Stepper - Dots + +{{demo='pages/component-demos/mobile-stepper/DotsMobileStepper.js'}} + diff --git a/docs/src/pages/getting-started/supported-components.md b/docs/src/pages/getting-started/supported-components.md index dc239579be2e2a..e25578f7f8b37f 100644 --- a/docs/src/pages/getting-started/supported-components.md +++ b/docs/src/pages/getting-started/supported-components.md @@ -96,6 +96,7 @@ to discuss the approach before submitting a PR. - [Steppers](https://www.google.com/design/spec/components/steppers.html) - [Horizontal](https://www.google.com/design/spec/components/steppers.html#steppers-types-of-steppers) - [Vertical](https://www.google.com/design/spec/components/steppers.html#steppers-types-of-steppers) + - [MobileStepper](https://www.google.com/design/spec/components/mobile-stepper.html) - **[Tabs](https://www.google.com/design/spec/components/tabs.html) ✓** - Usage - **[Mobile (Full width)](https://www.google.com/design/spec/components/tabs.html#tabs-usage) ✓** diff --git a/src/MobileStepper/MobileStepper.js b/src/MobileStepper/MobileStepper.js new file mode 100644 index 00000000000000..2dd0cd406af55f --- /dev/null +++ b/src/MobileStepper/MobileStepper.js @@ -0,0 +1,159 @@ +// @flow weak + +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { createStyleSheet } from 'jss-theme-reactor'; +import withStyles from '../styles/withStyles'; +import Paper from '../Paper'; +import Button from '../Button'; +import KeyboardArrowLeft from '../svg-icons/keyboard-arrow-left'; +import KeyboardArrowRight from '../svg-icons/keyboard-arrow-right'; + +export const styleSheet = createStyleSheet('MuiMobileStepper', theme => ({ + mobileStepper: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + width: '100%', + position: 'fixed', + bottom: 0, + left: 0, + zIndex: theme.zIndex.mobileStepper, + backgroundColor: theme.palette.background.paper, + padding: '6px', + }, + button: {}, + dots: { + display: 'flex', + flexDirection: 'row', + }, + dot: { + backgroundColor: theme.palette.action.disabled, + borderRadius: '50%', + width: '10px', + height: '10px', + margin: '0 2px', + }, + dotActive: { + backgroundColor: theme.palette.primary[500], + }, +})); + +function MobileStepper(props) { + const { + activeStep, + buttonClassName: buttonClassNameProp, + classes, + className: classNameProp, + disableBack, + disableNext, + dotClassName: dotClassNameProp, + dotsClassName: dotsClassNameProp, + kind, + onBack, + onNext, + steps, + ...other + } = props; + + const className = classNames(classes.mobileStepper, classNameProp); + + const dotsClassName = classNames( + { + [classes.dots]: true, + }, + dotsClassNameProp, + ); + const buttonClassName = classNames( + { + [classes.button]: true, + }, + buttonClassNameProp, + ); + + return ( + + + {kind === 'dots' && +
+ {Array.from(Array(steps)).map((_, step) => { + const dotClassName = classNames( + { + [classes.dot]: true, + [classes.dotActive]: step === activeStep, + }, + dotClassNameProp, + ); + return
; // eslint-disable-line react/no-array-index-key,max-len + })} +
} + + + ); +} + +MobileStepper.propTypes = { + /** + * Set the active step (zero based index). This will enable `Step` control helpers. + */ + activeStep: PropTypes.number, + /** + * @ignore + */ + buttonClassName: PropTypes.string, + /** + * Useful to extend the style applied to components. + */ + classes: PropTypes.object.isRequired, + /** + * @ignore + */ + className: PropTypes.string, + /** + * Set to true to disable the back button. + */ + disableBack: PropTypes.bool, + /** + * Set to true to disable the next button. + */ + disableNext: PropTypes.bool, + /** + * @ignore + */ + dotClassName: PropTypes.string, + /** + * @ignore + */ + dotsClassName: PropTypes.string, + /** + * The kind of mobile stepper to use. + */ + kind: PropTypes.oneOf(['text', 'dots', 'progress']), + /** + * Passed into the onTouchTap prop of the Back button. + */ + onBack: PropTypes.func.isRequired, + /** + * Passed into the onTouchTap prop of the Next button. + */ + onNext: PropTypes.func.isRequired, + /** + * The total steps. + */ + steps: PropTypes.number.isRequired, +}; + +MobileStepper.defaultProps = { + activeStep: 0, + kind: 'dots', + disableBack: false, + disableNext: false, +}; + +export default withStyles(styleSheet)(MobileStepper); diff --git a/src/MobileStepper/index.js b/src/MobileStepper/index.js new file mode 100644 index 00000000000000..dbd564de92a83f --- /dev/null +++ b/src/MobileStepper/index.js @@ -0,0 +1,3 @@ +// @flow + +export { default } from './MobileStepper'; diff --git a/src/styles/zIndex.js b/src/styles/zIndex.js index f522efbb7ad5b2..5e1ae4bc8932ff 100644 --- a/src/styles/zIndex.js +++ b/src/styles/zIndex.js @@ -12,4 +12,5 @@ export default { popover: 2100, snackbar: 2900, tooltip: 3000, + mobileStepper: 1100, };