diff --git a/.gitignore b/.gitignore index 5918e42..50eb572 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ assets/**/*.css build lib es +coverage diff --git a/.travis.yml b/.travis.yml index 9f73cf1..c269d26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ notifications: - yesmeck@gmail.com node_js: -- node +- 10 before_install: - | diff --git a/HISTORY.md b/HISTORY.md index 5f4ae97..3a90521 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,11 @@ # History ---- -## 3.230 +## 3.4.0 + +- Support `onChange` event. + +## 3.3.0 - Add `icons` prop for change preset icon. diff --git a/README.md b/README.md index f42a03a..b00d30c 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,12 @@ online example: http://react-component.github.io/steps/examples/ spicify the default finish icon and error icon + + onChange + (current: number) => void + + Trigger when Step changed + diff --git a/assets/index.less b/assets/index.less index 0c4052a..984ddd5 100644 --- a/assets/index.less +++ b/assets/index.less @@ -19,6 +19,15 @@ flex: 1; overflow: hidden; + &[role='button'] { + cursor: pointer; + transition: all .3s; + + &:hover { + opacity: 0.7; + } + } + &:last-child { flex: none; } diff --git a/examples/simple.js b/examples/simple.js index abc76c3..bced147 100644 --- a/examples/simple.js +++ b/examples/simple.js @@ -7,6 +7,24 @@ import Steps, { Step } from 'rc-steps'; const container = document.getElementById('__react-content'); const description = '这里是多信息的描述啊描述啊描述啊描述啊哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶'; +const ControlSteps = () => { + const [current, setCurrent] = React.useState(0); + return ( + { + console.log('Change:', val); + setCurrent(val); + }} + > + + + + + + ); +}; + ReactDOM.render(
@@ -27,5 +45,7 @@ ReactDOM.render( -
-, container); + + , + container, +); diff --git a/now.json b/now.json new file mode 100644 index 0000000..67a2ef2 --- /dev/null +++ b/now.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "name": "rc-steps", + "builds": [ + { + "src": "package.json", + "use": "@now/static-build", + "config": { "distDir": "build" } + } + ] +} \ No newline at end of file diff --git a/package.json b/package.json index 44347b5..e381f93 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-steps", - "version": "3.3.0", + "version": "3.4.1", "description": "steps ui component for react", "keywords": [ "react", @@ -43,7 +43,8 @@ "lint:fix": "rc-tools run lint --fix", "test": "jest", "prepublish": "rc-tools run guard", - "coverage": "jest --coverage && cat ./coverage/lcov.info | coveralls" + "coverage": "jest --coverage && cat ./coverage/lcov.info | coveralls", + "now-build": "npm run build" }, "jest": { "setupFiles": [ @@ -60,7 +61,7 @@ } }, "devDependencies": { - "coveralls": "^2.11.15", + "coveralls": "^3.0.4", "enzyme": "^3.0.0", "enzyme-adapter-react-16": "^1.0.1", "enzyme-to-json": "^3.0.0", diff --git a/src/Step.jsx b/src/Step.jsx index 12e80df..1ca5601 100644 --- a/src/Step.jsx +++ b/src/Step.jsx @@ -24,6 +24,7 @@ export default class Step extends React.Component { PropTypes.string, ]), stepNumber: PropTypes.string, + stepIndex: PropTypes.number, description: PropTypes.any, title: PropTypes.any, progressDot: PropTypes.oneOfType([ @@ -35,7 +36,20 @@ export default class Step extends React.Component { finish: PropTypes.node, error: PropTypes.node, }), + onClick: PropTypes.func, + onStepClick: PropTypes.func, }; + + onClick = (...args) => { + const { onClick, onStepClick, stepIndex } = this.props; + + if (onClick) { + onClick(...args); + } + + onStepClick(stepIndex); + }; + renderIconNode() { const { prefixCls, progressDot, stepNumber, status, title, description, icon, @@ -66,7 +80,7 @@ export default class Step extends React.Component { } else if (icons && icons.error && status === 'error') { iconNode = {icons.error}; } else if (icon || status === 'finish' || status === 'error') { - iconNode = ; + iconNode = {stepNumber}; } else { iconNode = {stepNumber}; } @@ -79,7 +93,7 @@ export default class Step extends React.Component { status = 'wait', iconPrefix, icon, wrapperStyle, adjustMarginRight, stepNumber, description, title, progressDot, tailContent, - icons, + icons, stepIndex, onStepClick, onClick, ...restProps, } = this.props; @@ -96,8 +110,18 @@ export default class Step extends React.Component { if (adjustMarginRight) { stepItemStyle.marginRight = adjustMarginRight; } + + const accessibilityProps = {}; + if (onStepClick) { + accessibilityProps.role = 'button'; + accessibilityProps.tabIndex = 0; + accessibilityProps.onClick = this.onClick; + } + return (
{ + const { onChange, current } = this.props; + if (onChange && current !== next) { + onChange(next); + } + }; + calcStepOffsetWidth = () => { if (isFlexSupported()) { return; @@ -92,7 +101,7 @@ export default class Steps extends Component { const { prefixCls, style = {}, className, children, direction, labelPlacement, iconPrefix, status, size, current, progressDot, initial, - icons, + icons, onChange, ...restProps, } = this.props; const { lastStepOffsetWidth, flexSupported } = this.state; @@ -103,6 +112,7 @@ export default class Steps extends Component { [`${prefixCls}-${size}`]: size, [`${prefixCls}-label-${adjustedlabelPlacement}`]: direction === 'horizontal', [`${prefixCls}-dot`]: !!progressDot, + [`${prefixCls}-flex-not-supported`]: !flexSupported, }); return ( @@ -115,11 +125,13 @@ export default class Steps extends Component { const stepNumber = initial + index; const childProps = { stepNumber: `${stepNumber + 1}`, + stepIndex: stepNumber, prefixCls, iconPrefix, wrapperStyle: style, progressDot, icons, + onStepClick: onChange && this.onStepClick, ...child.props, }; if (!flexSupported && direction !== 'vertical' && index !== lastIndex) { diff --git a/tests/index.test.js b/tests/index.test.js index 6af0a23..4e8e107 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render } from 'enzyme'; +import { mount, render } from 'enzyme'; import Steps, { Step } from '../src'; describe('Steps', () => { @@ -166,4 +166,18 @@ describe('Steps', () => { expect(wrapper).toMatchSnapshot(); }); }); + + it('onChange', () => { + const onChange = jest.fn(); + const wrapper = mount( + + + + + + ); + + wrapper.find(Step).at(1).simulate('click'); + expect(onChange).toBeCalledWith(1); + }); });