diff --git a/.umirc.ts b/.dumirc.ts similarity index 53% rename from .umirc.ts rename to .dumirc.ts index 174b7cb..184d7b2 100644 --- a/.umirc.ts +++ b/.dumirc.ts @@ -2,9 +2,11 @@ import { defineConfig } from 'dumi'; export default defineConfig({ - title: 'rc-steps', - favicon: 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', - logo: 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', + favicons: ['https://avatars0.githubusercontent.com/u/9441414?s=200&v=4'], + themeConfig: { + name: 'rc-steps', + logo: 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', + }, outputPath: '.doc', exportStatic: {}, base: '/rc-steps', diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0b2ccda..6bfd63e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] jobs: setup: @@ -15,7 +15,7 @@ jobs: - uses: actions/setup-node@v1 with: - node-version: '12' + node-version: '18' - name: cache package-lock.json uses: actions/cache@v2 @@ -24,7 +24,7 @@ jobs: key: lock-${{ github.sha }} - name: create package-lock.json - run: npm i --package-lock-only + run: npm i --package-lock-only --ignore-scripts - name: hack for singe file run: | diff --git a/.gitignore b/.gitignore index 20175fb..4e0115a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -.storybook .iml *.log .idea/ @@ -32,3 +31,9 @@ yarn.lock .doc .umi .npmrc + +# dumi +.dumi/tmp +.dumi/tmp-test +.dumi/tmp-production +.env.local \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 7d0de5d..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -lint-staged diff --git a/README.md b/README.md index 639693d..b2baf4a 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ React steps component. npm install rc-steps ``` +
+ ```jsx | pure @@ -179,7 +181,7 @@ https://react-component.github.io/steps/ ## Development -``` +```bash npm install npm start ``` diff --git a/docs/demo/alternativeLabel.md b/docs/demo/alternativeLabel.md index c7a9e4d..df38db7 100644 --- a/docs/demo/alternativeLabel.md +++ b/docs/demo/alternativeLabel.md @@ -1,2 +1,8 @@ -## alternativeLabel - +--- +title: alternativeLabel +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/composable.md b/docs/demo/composable.md index 66ebf27..a80e956 100644 --- a/docs/demo/composable.md +++ b/docs/demo/composable.md @@ -1,2 +1,8 @@ -## composable - +--- +title: composable +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/custom-svg-icon.md b/docs/demo/custom-svg-icon.md index ce06214..9a515a3 100644 --- a/docs/demo/custom-svg-icon.md +++ b/docs/demo/custom-svg-icon.md @@ -1,2 +1,8 @@ -## custom-svg-icon - +--- +title: custom-svg-icon +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/customIcon.md b/docs/demo/customIcon.md index f030be6..a62695b 100644 --- a/docs/demo/customIcon.md +++ b/docs/demo/customIcon.md @@ -1,2 +1,8 @@ -## customIcon - +--- +title: customIcon +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/dynamic.md b/docs/demo/dynamic.md index 6a63df6..6731934 100644 --- a/docs/demo/dynamic.md +++ b/docs/demo/dynamic.md @@ -1,2 +1,8 @@ -## dynamic - +--- +title: dynamic +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/errorStep.md b/docs/demo/errorStep.md index aa7bc51..c16e78c 100644 --- a/docs/demo/errorStep.md +++ b/docs/demo/errorStep.md @@ -1,2 +1,8 @@ -## errorStep - +--- +title: errorStep +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/inline.md b/docs/demo/inline.md index a2a1908..e9b23a3 100644 --- a/docs/demo/inline.md +++ b/docs/demo/inline.md @@ -1,2 +1,8 @@ -## inline - +--- +title: inline +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/nav-base.md b/docs/demo/nav-base.md index 1a3780d..8cc337a 100644 --- a/docs/demo/nav-base.md +++ b/docs/demo/nav-base.md @@ -1,2 +1,8 @@ -## nav-base - +--- +title: nav-base +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/nextStep.md b/docs/demo/nextStep.md index 0c3455c..6791800 100644 --- a/docs/demo/nextStep.md +++ b/docs/demo/nextStep.md @@ -1,2 +1,8 @@ -## nextStep - +--- +title: nextStep +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/progressDot.md b/docs/demo/progressDot.md index 04048c9..a60e710 100644 --- a/docs/demo/progressDot.md +++ b/docs/demo/progressDot.md @@ -1,2 +1,8 @@ -## progressDot - +--- +title: progressDot +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/simple.md b/docs/demo/simple.md index fb1a674..89ac535 100644 --- a/docs/demo/simple.md +++ b/docs/demo/simple.md @@ -1,2 +1,8 @@ -## simple - +--- +title: simple +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/smallSize.md b/docs/demo/smallSize.md index fdae263..d4f0370 100644 --- a/docs/demo/smallSize.md +++ b/docs/demo/smallSize.md @@ -1,2 +1,8 @@ -## smallSize - +--- +title: smallSize +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/stepIcon.md b/docs/demo/stepIcon.md index 10700f5..692787e 100644 --- a/docs/demo/stepIcon.md +++ b/docs/demo/stepIcon.md @@ -1,2 +1,8 @@ -## stepIcon - +--- +title: stepIcon +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/vertical.md b/docs/demo/vertical.md index fb63b5c..80da355 100644 --- a/docs/demo/vertical.md +++ b/docs/demo/vertical.md @@ -1,2 +1,8 @@ -## vertical - +--- +title: vertical +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/demo/verticalSmall.md b/docs/demo/verticalSmall.md index e3af00e..e1b597d 100644 --- a/docs/demo/verticalSmall.md +++ b/docs/demo/verticalSmall.md @@ -1,2 +1,8 @@ -## verticalSmall - +--- +title: verticalSmall +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/examples/inline.jsx b/docs/examples/inline.jsx index 9bcf911..fbea806 100644 --- a/docs/examples/inline.jsx +++ b/docs/examples/inline.jsx @@ -6,31 +6,41 @@ export default () => { const [current, setCurrent] = useState(0); return ( - ( - React.cloneElement(stepItem, { title: item.description }) - )} - /> - ) + <> + + +
+ + React.cloneElement(stepItem, { title: item.description })} + /> + + ); }; diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..3358d44 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,7 @@ +--- +hero: + title: rc-steps + description: React Steps Component +--- + + diff --git a/package.json b/package.json index 1909571..affd22b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-steps", - "version": "6.0.0", + "version": "6.0.1", "description": "steps ui component for react", "keywords": [ "react", @@ -38,7 +38,7 @@ "docs:deploy": "gh-pages -d .doc", "gh-pages": "npm run docs:build && npm run docs:deploy", "lint": "eslint src/ --ext .ts,.tsx,.jsx,.js,.md", - "prepare": "husky install", + "prepare": "husky install && dumi setup", "prepublishOnly": "npm run compile && np --yolo --no-publish", "prettier": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"", "postpublish": "npm run gh-pages", @@ -59,20 +59,21 @@ "@rc-component/father-plugin": "^1.0.1", "@types/classnames": "^2.2.9", "@types/enzyme": "^3.10.11", - "@types/jest": "^26.0.5", + "@types/jest": "^29.4.0", "@types/react": "^16.9.2", "@types/react-dom": "^18.0.11", - "@umijs/fabric": "^2.10.0", + "@umijs/fabric": "^3.0.0", "cross-env": "^7.0.0", - "dumi": "^1.1.38", + "dumi": "^2.0.0", "enzyme": "^3.1.0", "enzyme-adapter-react-16": "^1.0.1", "enzyme-to-json": "^3.1.2", "eslint": "^7.1.0", "father": "^4", "gh-pages": "^4.0.0", + "glob": "^10.0.0", "husky": "^8.0.1", - "less": "^3.11.2", + "less": "^4.1.3", "lint-staged": "^13.0.3", "np": "^7.6.0", "prettier": "^2.5.1", @@ -81,7 +82,7 @@ "rc-tools": "^9.6.1", "react": "^16.0.0", "react-dom": "^16.0.0", - "typescript": "^4.5.4", + "typescript": "^5.0.0", "umi-test": "^1.9.7" }, "peerDependencies": { diff --git a/script/update-content.js b/script/update-content.js new file mode 100644 index 0000000..880494b --- /dev/null +++ b/script/update-content.js @@ -0,0 +1,34 @@ +/* + 用于 dumi 改造使用, + 可用于将 examples 的文件批量修改为 demo 引入形式, + 其他项目根据具体情况使用。 +*/ + +const fs = require('fs'); +const glob = require('glob'); + +const paths = glob.sync('./docs/examples/*.jsx'); + +paths.forEach(path => { + const name = path.split('/').pop().split('.')[0]; + fs.writeFile( + `./docs/demo/${name}.md`, + `--- +title: ${name} +nav: + title: Demo + path: /demo +--- + + +`, + 'utf8', + function(error) { + if(error){ + console.log(error); + return false; + } + console.log(`${name} 更新成功~`); + } + ) +}); diff --git a/src/Step.tsx b/src/Step.tsx index 75c710b..c85dd24 100644 --- a/src/Step.tsx +++ b/src/Step.tsx @@ -1,6 +1,7 @@ /* eslint react/prop-types: 0 */ import * as React from 'react'; import classNames from 'classnames'; +import KeyCode from 'rc-util/lib/KeyCode'; import type { Status, Icons } from './interface'; import type { StepIconRender, ProgressDotRender } from './Steps'; @@ -29,7 +30,7 @@ export interface StepProps { onStepClick?: (index: number) => void; progressDot?: ProgressDotRender | boolean; stepIcon?: StepIconRender; - render?: (stepItem: React.ReactNode) => React.ReactNode; + render?: (stepItem: React.ReactElement) => React.ReactNode; } function Step(props: StepProps) { @@ -58,14 +59,31 @@ function Step(props: StepProps) { ...restProps } = props; - const onInternalClick: React.MouseEventHandler = (...args) => { - if (onClick) { - onClick(...args); - } + // ========================= Click ========================== + const clickable = !!onStepClick && !disabled; - onStepClick(stepIndex); - }; + const accessibilityProps: { + role?: string; + tabIndex?: number; + onClick?: React.MouseEventHandler; + onKeyDown?: React.KeyboardEventHandler; + } = {}; + if (clickable) { + accessibilityProps.role = 'button'; + accessibilityProps.tabIndex = 0; + accessibilityProps.onClick = (e) => { + onClick?.(e); + onStepClick(stepIndex); + }; + accessibilityProps.onKeyDown = (e) => { + const { which } = e; + if (which === KeyCode.ENTER || which === KeyCode.SPACE) { + onStepClick(stepIndex); + } + }; + } + // ========================= Render ========================= const renderIconNode = () => { let iconNode; const iconClassName = classNames(`${prefixCls}-icon`, `${iconPrefix}icon`, { @@ -119,25 +137,19 @@ function Step(props: StepProps) { const mergedStatus = status || 'wait'; - const classString = classNames(`${prefixCls}-item`, `${prefixCls}-item-${mergedStatus}`, className, { - [`${prefixCls}-item-custom`]: icon, - [`${prefixCls}-item-active`]: active, - [`${prefixCls}-item-disabled`]: disabled === true, - }); + const classString = classNames( + `${prefixCls}-item`, + `${prefixCls}-item-${mergedStatus}`, + className, + { + [`${prefixCls}-item-custom`]: icon, + [`${prefixCls}-item-active`]: active, + [`${prefixCls}-item-disabled`]: disabled === true, + }, + ); const stepItemStyle = { ...style }; - const accessibilityProps: { - role?: string; - tabIndex?: number; - onClick?: React.MouseEventHandler; - } = {}; - if (onStepClick && !disabled) { - accessibilityProps.role = 'button'; - accessibilityProps.tabIndex = 0; - accessibilityProps.onClick = onInternalClick; - } - - let stepNode: React.ReactNode = ( + let stepNode: React.ReactElement = (
{tailContent}
@@ -160,12 +172,11 @@ function Step(props: StepProps) {
); - if (render) { - stepNode = render(stepNode) || null; + stepNode = (render(stepNode) || null) as React.ReactElement; } - return stepNode as React.ReactElement; + return stepNode; } export default Step; diff --git a/src/Steps.tsx b/src/Steps.tsx index 5ea4416..1e228b9 100644 --- a/src/Steps.tsx +++ b/src/Steps.tsx @@ -40,7 +40,7 @@ export interface StepsProps { initial?: number; icons?: Icons; items?: StepProps[]; - itemRender?: (item: StepProps, stepItem: React.ReactNode) => React.ReactNode; + itemRender?: (item: StepProps, stepItem: React.ReactElement) => React.ReactNode; onChange?: (current: number) => void; } diff --git a/tests/index.test.tsx b/tests/index.test.tsx index 547c877..bb5a65e 100644 --- a/tests/index.test.tsx +++ b/tests/index.test.tsx @@ -257,9 +257,7 @@ describe('Steps', () => { disabled: true, }, ]} - itemRender={(item, stepItem) => ( - React.cloneElement(stepItem, { title: item.description }) - )} + itemRender={(item, stepItem) => React.cloneElement(stepItem, { title: item.description })} />, ); expect(wrapper).toMatchSnapshot(); @@ -470,4 +468,28 @@ describe('Steps', () => { wrapper.find('.rc-steps-item-container').at(2).simulate('click'); expect(onChange).not.toBeCalled(); }); + + it('key board support', () => { + const onChange = jest.fn(); + const wrapper = mount( + , + ); + + wrapper.find('[role="button"]').at(1).simulate('keydown', { which: 13 }); + + expect(onChange).toBeCalledWith(1); + }); }); diff --git a/tsconfig.json b/tsconfig.json index 13d9699..089dee5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ "esModuleInterop": true, "paths": { "@/*": ["src/*"], - "@@/*": ["src/.umi/*"], + "@@/*": ["dumi/tmp/*"], "rc-steps": ["src/index.ts"] } }