Full Code of react-component/steps for AI

master 674846852bbb cached
71 files
101.5 KB
30.3k tokens
24 symbols
1 requests
Download .txt
Repository: react-component/steps
Branch: master
Commit: 674846852bbb
Files: 71
Total size: 101.5 KB

Directory structure:
gitextract_zrdxiemy/

├── .dumirc.ts
├── .editorconfig
├── .eslintrc.js
├── .fatherrc.ts
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── main.yml
├── .gitignore
├── .prettierrc
├── HISTORY.md
├── LICENSE.md
├── README.md
├── assets/
│   ├── custom-icon.less
│   ├── iconfont.less
│   ├── index.less
│   ├── inline.less
│   ├── label-placement.less
│   ├── nav.less
│   ├── progress-dot.less
│   ├── small.less
│   ├── variables.less
│   └── vertical.less
├── bunfig.toml
├── docs/
│   ├── demo/
│   │   ├── alternativeLabel.md
│   │   ├── composable.md
│   │   ├── custom-svg-icon.md
│   │   ├── customIcon.md
│   │   ├── dynamic.md
│   │   ├── errorStep.md
│   │   ├── inline.md
│   │   ├── nav-base.md
│   │   ├── nextStep.md
│   │   ├── progressDot.md
│   │   ├── simple.md
│   │   ├── smallSize.md
│   │   ├── stepIcon.md
│   │   ├── vertical.md
│   │   └── verticalSmall.md
│   ├── examples/
│   │   ├── alternativeLabel.jsx
│   │   ├── composable.jsx
│   │   ├── custom-svg-icon.jsx
│   │   ├── customIcon.jsx
│   │   ├── dynamic.jsx
│   │   ├── errorStep.jsx
│   │   ├── inline.jsx
│   │   ├── nav-base.jsx
│   │   ├── nextStep.css
│   │   ├── nextStep.jsx
│   │   ├── progressDot.jsx
│   │   ├── simple.jsx
│   │   ├── smallSize.jsx
│   │   ├── stepIcon.jsx
│   │   ├── vertical.jsx
│   │   └── verticalSmall.jsx
│   └── index.md
├── index.js
├── jest.config.js
├── package.json
├── script/
│   └── update-content.js
├── src/
│   ├── Context.ts
│   ├── Rail.tsx
│   ├── Step.tsx
│   ├── StepIcon.tsx
│   ├── Steps.tsx
│   ├── UnstableContext.ts
│   ├── index.ts
│   └── interface.ts
├── tests/
│   ├── __snapshots__/
│   │   └── index.test.tsx.snap
│   ├── index.test.tsx
│   ├── semantic.test.tsx
│   └── setup.js
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .dumirc.ts
================================================
import { defineConfig } from 'dumi';
import path from 'path';

export default defineConfig({
  alias: {
    '@rc-component/steps$': path.resolve('src'),
    '@rc-component/steps/es': path.resolve('src'),
  },
  mfsu: false,
  favicons: ['https://avatars0.githubusercontent.com/u/9441414?s=200&v=4'],
  themeConfig: {
    name: 'Steps',
    logo: 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4',
  },
});

================================================
FILE: .editorconfig
================================================
# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*.{js,css}]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2

================================================
FILE: .eslintrc.js
================================================
const base = require('@umijs/fabric/dist/eslint');

module.exports = {
  ...base,
  rules: {
    ...base.rules,
    'arrow-parens': 0,
    'react/sort-comp': 0,
  },
};


================================================
FILE: .fatherrc.ts
================================================
import { defineConfig } from 'father';

export default defineConfig({
  plugins: ['@rc-component/father-plugin'],
});


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: npm
  directory: "/"
  schedule:
    interval: daily
    time: "21:00"
  open-pull-requests-limit: 10
  ignore:
  - dependency-name: "@types/react-dom"
    versions:
    - 17.0.0
    - 17.0.1
    - 17.0.2
  - dependency-name: "@types/react"
    versions:
    - 17.0.0
    - 17.0.1
    - 17.0.2
    - 17.0.3
  - dependency-name: less
    versions:
    - 4.1.0


================================================
FILE: .github/workflows/main.yml
================================================
name: ✅ test
on: [push, pull_request]
jobs:
  test:
    uses: react-component/rc-test/.github/workflows/test.yml@main
    secrets: inherit

================================================
FILE: .gitignore
================================================
.iml
*.log
.idea/
.ipr
.iws
*~
~*
*.diff
*.patch
*.bak
.DS_Store
Thumbs.db
.project
.*proj
.svn/
*.swp
*.swo
*.pyc
*.pyo
.build
node_modules
.cache
dist
assets/**/*.css
build
lib
es
coverage
package-lock.json
pnpm-lock.yaml
yarn.lock
.doc
.umi
.npmrc

# dumi
.dumi/tmp
.dumi/tmp-test
.dumi/tmp-production
.env.local

bun.lockb

================================================
FILE: .prettierrc
================================================
{
  "singleQuote": true,
  "trailingComma": "all",
  "proseWrap": "never",
  "printWidth": 100
}

================================================
FILE: HISTORY.md
================================================
# History
----

## 3.6.0

- Remove babel-runtime and prop-types
- Fix icon missing #85

## 3.5.0

- Support `navigation` type & `disabled` prop.

## 3.4.0

- Support `onChange` event.

## 3.3.0

- Add `icons` prop for change preset icon.

## 3.2.0

- Add `initial` prop.

## 3.1.0

- Add `tailContent`.

## 3.0.0

- Rewrite from bottom.

## 2.5.1

* Support react@15.5

## 2.5.0

* Refactor for last tail style.

## 2.4.0

* Refactor for extra width of tail. https://github.com/ant-design/ant-design/issues/5083

## 2.3.0

* Add new step style of prop `progressDot`.

## 2.2.0

* `icon` can be React.Node now.

## 2.1.0

* Add `labelPlacement`, support vertial title and description

## 2.0.0

* Refactor for better layout

## 1.5

* add `status` property of `Steps`

## 1.4

* update react to 0.14

## 1.3

* add `current` property of `Steps`

## 1.2.3

* fix publish

## 1.2.2

* remove vertical `maxDescriptionWidth`

## 1.2.1

* fix vertical `maxDescriptionWidth`

## 1.2.0

* add vertical steps

## 1.1.4

* fix layout algorithm

## 1.1.3

* support `iconPrefix` property, default is `rc`

## 1.1.2

* fix bugs

## 1.1.1

* support `maxDescriptionWidth` property, default is 120

## 1.1.0

* support `prefixCls` property, default is `rc-steps`


================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)

Copyright (c) 2014-present yiminghe

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# @rc-component/steps

---

React steps component.

[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Test coverage][codecov-image]][codecov-url]
[![npm download][download-image]][download-url]
[![bundle size][bundlephobia-image]][bundlephobia-url]

[npm-image]: http://img.shields.io/npm/v/@rc-component/steps.svg?style=flat-square
[npm-url]: http://npmjs.org/package/@rc-component/steps
[travis-image]: https://img.shields.io/travis/react-component/steps.svg?style=flat-square
[travis-url]: https://travis-ci.org/react-component/steps
[codecov-image]: https://img.shields.io/codecov/c/github/react-component/steps/master.svg?style=flat-square
[codecov-url]: https://codecov.io/gh/react-component/steps/branch/master
[download-image]: https://img.shields.io/npm/dm/@rc-component/steps.svg?style=flat-square
[download-url]: https://npmjs.org/package/@rc-component/steps
[bundlephobia-url]: https://bundlephobia.com/result?p=@rc-component/steps
[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/@rc-component/steps

## Usage

```bash
npm install @rc-component/steps
```

<br>

```jsx | pure
<Steps current={1}>
  <Steps.Step title="first" />
  <Steps.Step title="second" />
  <Steps.Step title="third" />
</Steps>
```

## Example

https://steps.vercel.app/

## API

<table class="table table-bordered table-striped">
  <thead>
    <tr>
      <th style="width: 100px;">name</th>
      <th style="width: 50px;">type</th>
      <th style="width: 50px;">default</th>
      <th>description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>type</td>
      <td>string</td>
      <td>default</td>
      <td>diretypetion of Steps, could be `default` `navigation` `inline`</td>
    </tr>
    <tr>
      <td>direction</td>
      <td>string</td>
      <td>horizontal</td>
      <td>direction of Steps, enum: `horizontal` or `vertical`</td>
    </tr>
    <tr>
      <td>current</td>
      <td>number</td>
      <td>0</td>
      <td>index of current step</td>
    </tr>
    <tr>
      <td>initial</td>
      <td>number</td>
      <td>0</td>
      <td>index initial</td>
    </tr>
    <tr>
      <td>size</td>
      <td>string</td>
      <td></td>
      <td>size of Steps, could be `small`</td>
    </tr>
    <tr>
      <td>titlePlacement</td>
      <td>string</td>
      <td></td>
      <td>placement of step title, could be `vertical`</td>
    </tr>
    <tr>
      <td>status</td>
      <td>string</td>
      <td>wait</td>
      <td>status of current Steps, could be `error` `process` `finish` `wait`</td>
    </tr>
    <tr>
      <td>icons</td>
      <td>{ finish: ReactNode, error: ReactNode }</td>
      <td></td>
      <td>specify the default finish icon and error icon</td>
    </tr>
    <tr>
      <td>itemRender</td>
      <td>(item: StepProps, stepItem: React.ReactNode) => React.ReactNode</td>
      <td></td>
      <td>custom step item renderer</td>
    </tr>
    <tr>
      <td>onChange</td>
      <td>(current: number) => void</td>
      <td></td>
      <td>Trigger when Step changed</td>
    </tr>
  </tbody>
</table>

### Steps.Step

<table class="table table-bordered table-striped">
  <thead>
    <tr>
      <th style="width: 100px;">name</th>
      <th style="width: 50px;">type</th>
      <th style="width: 50px;">default</th>
      <th>description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>title</td>
      <td>ReactNode</td>
      <td></td>
      <td>title of step item</td>
    </tr>
    <tr>
      <td>subTitle</td>
      <td>ReactNode</td>
      <td></td>
      <td>subTitle of step item</td>
    </tr>
    <tr>
      <td>description</td>
      <td>ReactNode</td>
      <td></td>
      <td>description of step item</td>
    </tr>
    <tr>
      <td>icon</td>
      <td>ReactNode</td>
      <td></td>
      <td>set icon of step item</td>
    </tr>
    <tr>
      <td>status</td>
      <td>string</td>
      <td></td>
      <td>status of current Steps, could be `error` `process` `finish` `wait`</td>
    </tr>
    <tr>
      <td>tailContent</td>
      <td>ReactNode</td>
      <td></td>
      <td>content above tail</td>
    </tr>
    <tr>
      <td>disabled</td>
      <td>bool</td>
      <td>false</td>
      <td>disabled step when onChange exist</td>
    </tr>
    <tr>
      <td>render</td>
      <td>(stepItem: React.ReactNode) => React.ReactNode</td>
      <td></td>
      <td>custom step item renderer</td>
    </tr>
  </tbody>
</table>

## Development

```bash
npm install
npm start
```

## License

@rc-component/steps is released under the MIT license.


================================================
FILE: assets/custom-icon.less
================================================
@import 'variables';

.@{stepsPrefixClass}-item-custom {
  .@{stepsPrefixClass}-item-icon {
    background: none;
    border: 0;
    width: auto;
    height: auto;
    > .@{stepsPrefixClass}-icon {
      font-size: 20px;
      top: 1px;
      width: 20px;
      height: 20px;
    }
  }
  &.@{stepsPrefixClass}-item-process {
    .@{stepsPrefixClass}-item-icon > .@{stepsPrefixClass}-icon {
      color: @process-icon-color;
    }
  }
}


================================================
FILE: assets/iconfont.less
================================================
@icon-url               : "//at.alicdn.com/t/font_1434092639_4910953";
.ie-rotate(@rotation) {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation);
}
.rotate(@degrees) {
  -webkit-transform: rotate(@degrees);
  -ms-transform: rotate(@degrees); // IE9 only
  -o-transform: rotate(@degrees);
  transform: rotate(@degrees);
}
.animation(@animation) {
  -webkit-animation: @animation;
  -o-animation: @animation;
  animation: @animation;
}
// font-face
// @icon-url: 字体源文件的地址
@font-face {
  font-family: 'anticon';
  src: url('@{icon-url}.eot'); /* IE9*/
  src: url('@{icon-url}.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('@{icon-url}.woff') format('woff'), /* chrome、firefox */
  url('@{icon-url}.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
  url('@{icon-url}.svg#iconfont') format('svg'); /* iOS 4.1- */
}

.rcicon {
  position: relative;
  display: inline-block;
  font-style: normal;
  vertical-align: baseline;
  text-align: center;
  text-transform: none;
  text-rendering: auto;
  // 更好地渲染字体
  -webkit-font-smoothing: antialiased;
  -webkit-text-stroke-width: 0px;
  -moz-osx-font-smoothing: grayscale;

  &:before {
    display: block;
    font-family: "anticon" !important;
  }
}
// 方向性图标
.rcicon-step-backward:before          {content:"\e662";}
.rcicon-step-forward                  {.ie-rotate(2);}
.rcicon-step-forward:before           {content:"\e662";.rotate(180deg);}
.rcicon-fast-backward:before          {content:"\e62a";}
.rcicon-fast-forward                  {.ie-rotate(2);}
.rcicon-fast-forward:before           {content:"\e62a";.rotate(180deg);}
.rcicon-shrink:before                 {content:"\e65f";}
.rcicon-arrow-salt:before             {content:"\e608";}
.rcicon-caret-down:before             {content:"\e60f";}
.rcicon-caret-left                    {.ie-rotate(1);}
.rcicon-caret-left:before             {content:"\e60f";.rotate(90deg);}
.rcicon-caret-up                      {.ie-rotate(2);}
.rcicon-caret-up:before               {content:"\e60f";.rotate(180deg);}
.rcicon-caret-right                   {.ie-rotate(3);}
.rcicon-caret-right:before            {content:"\e60f";.rotate(270deg);}
.rcicon-caret-circle-right:before     {content:"\e60d";}
.rcicon-caret-circle-left             {.ie-rotate(2);}
.rcicon-caret-circle-left:before      {content:"\e60d";.rotate(180deg);}
.rcicon-caret-circle-o-right:before   {content:"\e60e";}
.rcicon-caret-circle-o-left           {.ie-rotate(2);}
.rcicon-caret-circle-o-left:before    {content:"\e60e";.rotate(180deg);}
.rcicon-circle-right:before           {content:"\e602";}
.rcicon-circle-left                   {.ie-rotate(2);}
.rcicon-circle-left:before            {content:"\e602";.rotate(180deg);}
.rcicon-circle-o-right:before         {content:"\e603";}
.rcicon-circle-o-left                 {.ie-rotate(2);}
.rcicon-circle-o-left:before          {content:"\e603";.rotate(180deg);}
.rcicon-double-right:before           {content:"\e604";}
.rcicon-double-left                   {.ie-rotate(2);}
.rcicon-double-left:before            {content:"\e604";.rotate(180deg);}
.rcicon-verticle-right:before         {content:"\e605";}
.rcicon-verticle-left                 {.ie-rotate(2);}
.rcicon-verticle-left:before          {content:"\e605";.rotate(180deg);}
.rcicon-forward:before                {content:"\e630";}
.rcicon-backward                      {.ie-rotate(2);}
.rcicon-backward:before               {content:"\e630";.rotate(180deg);}
.rcicon-rollback:before               {content:"\e65a";}
.rcicon-retweet:before                {content:"\e659";}

.rcicon-right:before                  {content:"\e611";}
.rcicon-down                          {.ie-rotate(1);}
.rcicon-down:before                   {content:"\e611";.rotate(90deg);}
.rcicon-left                          {.ie-rotate(2);}
.rcicon-left:before                   {content:"\e611";.rotate(180deg);}
.rcicon-up                            {.ie-rotate(3);}
.rcicon-up:before                     {content:"\e611";.rotate(270deg);}

// 提示性图标
.rcicon-question:before               {content:"\e655";}
.rcicon-question-circle:before        {content:"\e656";}
.rcicon-question-circle-o:before      {content:"\e657";}
.rcicon-plus:before                   {content:"\e651";}
.rcicon-plus-circle:before            {content:"\e652";}
.rcicon-plus-circle-o:before          {content:"\e653";}
.rcicon-pause:before                  {content:"\e64c";}
.rcicon-pause-circle:before           {content:"\e64d";}
.rcicon-pause-circle-o:before         {content:"\e64e";}
.rcicon-minus:before                  {content:"\e646";}
.rcicon-minus-circle:before           {content:"\e647";}
.rcicon-minus-circle-o:before         {content:"\e648";}
.rcicon-info-circle:before            {content:"\e637";}
.rcicon-info-circle-o:before          {content:"\e638";}
.rcicon-info:before                   {content:"\e63a";}
.rcicon-exclamation:before            {content:"\e627";}
.rcicon-exclamation-circle:before     {content:"\e628";}
.rcicon-exclamation-circle-o:before   {content:"\e629";}
.rcicon-cross:before                  {content:"\e61e";}
.rcicon-cross-circle:before           {content:"\e61f";}
.rcicon-cross-circle-o:before         {content:"\e620";}
.rcicon-check:before                  {content:"\e613";}
.rcicon-check-circle:before           {content:"\e614";}
.rcicon-check-circle-o:before         {content:"\e615";}
.rcicon-clock-circle:before           {content:"\e616";}
.rcicon-clock-circle-o:before         {content:"\e617";}

// 网站通用图标
.rcicon-lock:before                   {content:"\e641";}
.rcicon-android:before                {content:"\e601";}
.rcicon-apple:before                  {content:"\e606";}
.rcicon-area-chart:before             {content:"\e607";}
.rcicon-bar-chart:before              {content:"\e609";}
.rcicon-bars:before                   {content:"\e60a";}
.rcicon-book:before                   {content:"\e60b";}
.rcicon-calendar:before               {content:"\e60c";}
.rcicon-cloud:before                  {content:"\e618";}
.rcicon-cloud-download:before         {content:"\e619";}
.rcicon-code:before                   {content:"\e61a";}
.rcicon-copy:before                   {content:"\e61c";}
.rcicon-credit-card:before            {content:"\e61d";}
.rcicon-delete:before                 {content:"\e621";}
.rcicon-desktop:before                {content:"\e622";}
.rcicon-download-line:before          {content:"\e623";}
.rcicon-edit:before                   {content:"\e624";}
.rcicon-ellipsis:before               {content:"\e625";}
.rcicon-environment:before            {content:"\e626";}
.rcicon-file:before                   {content:"\e62c";}
.rcicon-file-text:before              {content:"\e62d";}
.rcicon-folder:before                 {content:"\e62e";}
.rcicon-folder-open:before            {content:"\e62f";}
.rcicon-github:before                 {content:"\e631";}
.rcicon-hdd:before                    {content:"\e632";}
.rcicon-frown:before                  {content:"\e633";}
.rcicon-meh:before                    {content:"\e634";}
.rcicon-inbox:before                  {content:"\e635";}
.rcicon-laptop:before                 {content:"\e63d";}
.rcicon-large:before                  {content:"\e63e";}
.rcicon-line-chart:before             {content:"\e63f";}
.rcicon-link:before                   {content:"\e640";}
.rcicon-logout:before                 {content:"\e642";}
.rcicon-mail:before                   {content:"\e643";}
.rcicon-menu-fold:before              {content:"\e644";}
.rcicon-menu-unfold:before            {content:"\e645";}
.rcicon-mobile:before                 {content:"\e649";}
.rcicon-notification:before           {content:"\e64a";}
.rcicon-paper-clip:before             {content:"\e64b";}
.rcicon-picture:before                {content:"\e64f";}
.rcicon-pie-chart:before              {content:"\e650";}
.rcicon-poweroff:before               {content:"\e654";}
.rcicon-reload:before                 {content:"\e658";}
.rcicon-search:before                 {content:"\e65b";}
.rcicon-setting:before                {content:"\e65c";}
.rcicon-share-alt:before              {content:"\e65d";}
.rcicon-shopping-cart:before          {content:"\e65e";}
.rcicon-smile:before                  {content:"\e661";}
.rcicon-tablet:before                 {content:"\e664";}
.rcicon-tag:before                    {content:"\e665";}
.rcicon-tags:before                   {content:"\e666";}
.rcicon-to-top:before                  {content:"\e667";}
.rcicon-unlock:before                 {content:"\e668";}
.rcicon-upload:before                 {content:"\e669";}
.rcicon-user:before                   {content:"\e66a";}
.rcicon-video-camera:before           {content:"\e66b";}
.rcicon-windows:before                {content:"\e66c";}
.rcicon-loading:before {
  display: inline-block;
  .animation(loadingCircle 1.0s infinite linear);
  content:"\e610";
}

:root {
  .rcicon-step-forward,
  .rcicon-fast-forward,
  .rcicon-left,
  .rcicon-up,
  .rcicon-down,
  .rcicon-caret-left,
  .rcicon-caret-up,
  .rcicon-caret-right,
  .rcicon-caret-circle-left,
  .rcicon-caret-circle-o-left,
  .rcicon-circle-left,
  .rcicon-circle-o-left,
  .rcicon-double-left,
  .rcicon-verticle-left,
  .rcicon-backward {
    filter: none;
  }
}


================================================
FILE: assets/index.less
================================================
@import 'variables';

.@{stepsPrefixClass} {
  font-size: 0;
  width: 100%;
  line-height: 1.5;
  display: flex;

  &,
  * {
    box-sizing: border-box;
  }
}

.@{stepsPrefixClass}-item {
  position: relative;
  display: inline-block;
  vertical-align: top;
  flex: 1;
  // overflow: hidden;

  &:last-child {
    flex: none;
  }

  &:last-child &-title:after {
    display: none;
  }

  &-icon,
  &-section {
    display: inline-block;
    vertical-align: top;
  }

  &-icon {
    flex: none;
    border: 1px solid @wait-icon-color;
    width: 26px;
    height: 26px;
    line-height: 26px;
    text-align: center;
    border-radius: 26px;
    font-size: 14px;
    transition:
      background-color 0.3s,
      border-color 0.3s;

    > .@{stepsPrefixClass}-icon {
      line-height: 1;
      top: -1px;
      color: @primary-color;
      position: relative;

      &.rcicon {
        font-size: 12px;
        position: relative;
        top: -2px;
      }
    }
  }

  &-section {
    margin-top: 3px;
  }
  &-title {
    font-size: 14px;
    color: #666;
    font-weight: bold;
    display: inline-block;
    position: relative;
  }
  &-subtitle {
    font-size: 12px;
    display: inline-block;
    color: #999;
  }
  &-description {
    font-size: 12px;
    color: #999;
  }
  .step-item-status(wait);
  .step-item-status(process);
  &-process &-icon {
    background: @process-icon-color;
    > .@{stepsPrefixClass}-icon {
      color: #fff;
    }
  }
  .step-item-status(finish);
  .step-item-status(error);

  &.@{stepsPrefixClass}-next-error .@{stepsPrefixClass}-item-title:after {
    background: @error-icon-color;
  }
}

.@{stepsPrefixClass}-horizontal:not(.@{stepsPrefixClass}-label-vertical) {
  .@{stepsPrefixClass}-item {
    &-description {
      max-width: @stepDescriptionMaxWidth;
    }
  }
}

.step-item-status(@status) {
  @icon-color: '@{status}-icon-color';
  @title-color: '@{status}-title-color';
  @description-color: '@{status}-description-color';
  @tail-color: '@{status}-tail-color';
  &-@{status} &-icon {
    border-color: @@icon-color;
    background-color: #fff;
    > .@{stepsPrefixClass}-icon {
      color: @@icon-color;
      .@{stepsPrefixClass}-icon-dot {
        background: @@icon-color;
      }
    }
  }
  &-@{status} &-title {
    color: @@title-color;
  }
  &-@{status} &-description {
    color: @@description-color;
  }
}

// @import 'custom-icon';
// @import 'small';
// @import 'vertical';
// @import 'label-placement';
// @import 'progress-dot';
// @import 'nav';
// @import 'inline';

// ======================= Horizontal =======================
.verticalFlex() {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.@{stepsPrefixClass} {
  .@{stepsPrefixClass}-item {
    &-section {
      min-width: 0;
    }

    &-header {
      display: flex;
      gap: 8px;
      align-items: center;
    }

    // Ellipsis
    &-title,
    &-subtitle,
    &-description {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }
}

.@{stepsPrefixClass}-horizontal {
  .@{stepsPrefixClass}-item {
    flex: 1;
    position: relative;
    min-width: 0;

    &-rail {
      height: 1px;
      background: @process-tail-color;
    }
  }

  // Label Vertical
  &.@{stepsPrefixClass}-label-vertical {
    .@{stepsPrefixClass}-item {
      .verticalFlex();
      padding-inline: 8px;

      &-section {
        .verticalFlex();
      }

      &-rail {
        position: absolute;
        top: 13px;
        left: calc(50% + 13px);
        width: 100%;
      }
    }
  }

  // Label Horizontal
  &.@{stepsPrefixClass}-label-horizontal {
    .@{stepsPrefixClass}-item {
      display: flex;

      &:last-child {
        flex: none;
      }

      &-section {
        flex: 1;
      }

      &-rail {
        flex: 1;
        min-width: 0;
      }
    }
  }
}

// ======================== Vertical ========================
.@{stepsPrefixClass}-vertical {
}


================================================
FILE: assets/inline.less
================================================
@import 'variables';

.@{stepsPrefixClass}-inline {
  width: auto;
  display: inline-flex;

  .@{stepsPrefixClass}-item {
    flex: none;


    &-icon {
      width: 6px;
      height: 6px;
      margin-left: calc(50% - 3px);
      > .@{stepsPrefixClass}-icon {
        top: 0;
      }
      .@{stepsPrefixClass}-icon-dot {
        border-radius: 3px;
      }
    }
    
    &-section {
      width: auto;
      margin-top: 7px;
    }
    &-title {
      color: rgba(0, 0, 0, 0.25);
      font-size: 12px;
      line-height: 20px;
      font-weight: normal;
      margin-bottom: 2px;
    }
    &-description {
      display: none;
    }

    &-finish {
      .@{stepsPrefixClass}-item-icon .@{stepsPrefixClass}-icon .@{stepsPrefixClass}-icon-dot {
        background-color: @process-tail-color;
      }
    }
    &-wait {
      .@{stepsPrefixClass}-item-icon .@{stepsPrefixClass}-icon .@{stepsPrefixClass}-icon-dot {
        background-color: #fff;
        border: 1px solid @process-tail-color;
      }
    }
  }
}


================================================
FILE: assets/label-placement.less
================================================
@import 'variables';

.@{stepsPrefixClass}-label-vertical {
  .@{stepsPrefixClass}-item {
    overflow: visible;
    &-section {
      display: block;
      text-align: center;
      margin-top: 8px;
      width: @stepDescriptionMaxWidth;
    }
    &-icon {
      display: inline-block;
      margin-left: 36px;
    }
    &-title {
      padding-right: 0;
      &:after {
        display: none;
      }
    }
    &-description {
      text-align: left;
    }
  }
}


================================================
FILE: assets/nav.less
================================================
@import 'variables';

.@{stepsPrefixClass}-navigation {
  padding-top: 8px;
  &.@{stepsPrefixClass}-horizontal {
    .@{stepsPrefixClass}-item-description {
      max-width: @stepNavContentMaxWidth;
    }
  }

  .@{stepsPrefixClass}-item {
    box-sizing: border-box;
    text-align: center;
    overflow: visible;


    &-title {
      max-width: @stepNavContentMaxWidth;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
  
      &:after {
        display: none;
      }
    }

    &:last-child {
      flex: 1;
      &:after {
        display: none;
      }
    }

    &:after {
      content: '';
      display: inline-block;
      width: 16px;
      height: 16px;
      border: 1px solid #ccc;
      border-bottom: none;
      border-left: none;
      transform: rotate(45deg);
      position: absolute;
      top: 50%;
      left: 100%;
      margin-top: -12px;
      margin-left: -8px;
    }

  }
}


================================================
FILE: assets/progress-dot.less
================================================
@import 'variables';

.@{stepsPrefixClass}-dot {
  .@{stepsPrefixClass}-item {
    &-icon {
      padding-right: 0;
      width: 5px;
      height: 5px;
      line-height: 5px;
      border: 0;
      margin-left: 48px;
      .@{stepsPrefixClass}-icon-dot {
        float: left;
        width: 100%;
        height: 100%;
        border-radius: 2.5px;
      }
    }
    &-process &-icon {
      top: -1px;
      width: 7px;
      height: 7px;
      line-height: 7px;
      .@{stepsPrefixClass}-icon-dot {
        border-radius: 3.5px;
      }
    }
  }
}


================================================
FILE: assets/small.less
================================================
@import 'variables';

.@{stepsPrefixClass}-small {
  .@{stepsPrefixClass}-item-icon {
    width: 18px;
    height: 18px;
    line-height: 18px;
    text-align: center;
    border-radius: 18px;
    font-size: 12px;
    margin-right: 10px;
    > .@{stepsPrefixClass}-icon {
      font-size: 12px;
      font-size: ~"9px \9"; // ie8-9
      transform: scale(.75);
      top: -1px;
    }
  }
  .@{stepsPrefixClass}-item-section {
    margin-top: 0;
  }
  .@{stepsPrefixClass}-item-title {
    font-size: 12px;
    margin-bottom: 4px;
    color: #666;
    font-weight: bold;
  }
  .@{stepsPrefixClass}-item-description {
    font-size: 12px;
    color: #999;
  }

  .@{stepsPrefixClass}-item-custom .@{stepsPrefixClass}-item-icon  {
    width: inherit;
    height: inherit;
    line-height: inherit;
    border-radius: 0;
    border: 0;
    background: none;
    > .@{stepsPrefixClass}-icon {
      font-size: 20px;
      top: -2.5px;
      transform: none;
    }
  }
}


================================================
FILE: assets/variables.less
================================================
@stepsPrefixClass: ~"rc-steps";
@stepDescriptionMaxWidth: 100px;
@stepNavContentMaxWidth: 140px;
@primary-color: #108ee9;
@process-icon-color: @primary-color;
@process-title-color: rgba(0,0,0,.65);
@process-description-color: @process-title-color;
@process-tail-color: #e9e9e9;
@wait-icon-color: #ccc;
@wait-title-color: rgba(0,0,0,.43);
@wait-description-color: @wait-title-color;
@wait-tail-color: @process-tail-color;
@finish-icon-color: @process-icon-color;
@finish-title-color: @wait-title-color;
@finish-description-color: @finish-title-color;
@finish-tail-color: @process-icon-color;
@error-icon-color: #f50;
@error-title-color: @error-icon-color;
@error-description-color: @error-icon-color;
@error-tail-color: @process-tail-color;


================================================
FILE: assets/vertical.less
================================================
@import 'variables';

.@{stepsPrefixClass}-vertical {
  display: block;
  .@{stepsPrefixClass}-item {
    display: block;
    overflow: visible;
    &-icon {
      float: left;
      &-inner {
        margin-right: 16px;
      }
    }
    &-section {
      min-height: 48px;
      overflow: hidden;
      display: block;
    }
    &-title {
      line-height: 26px;
      &:after {
        display: none;
      }
    }
    &-description {
      padding-bottom: 12px;
    }
  }

  &.@{stepsPrefixClass}-small {
    .@{stepsPrefixClass}-item-title {
      line-height: 18px;
    }
  }
}


================================================
FILE: bunfig.toml
================================================
[install]
peer = false

================================================
FILE: docs/demo/alternativeLabel.md
================================================
---
title: alternativeLabel
nav:
  title: Demo
  path: /demo
---

<code src="../examples/alternativeLabel.jsx"></code>


================================================
FILE: docs/demo/composable.md
================================================
---
title: composable
nav:
  title: Demo
  path: /demo
---

<code src="../examples/composable.jsx"></code>


================================================
FILE: docs/demo/custom-svg-icon.md
================================================
---
title: custom-svg-icon
nav:
  title: Demo
  path: /demo
---

<code src="../examples/custom-svg-icon.jsx"></code>


================================================
FILE: docs/demo/customIcon.md
================================================
---
title: customIcon
nav:
  title: Demo
  path: /demo
---

<code src="../examples/customIcon.jsx"></code>


================================================
FILE: docs/demo/dynamic.md
================================================
---
title: dynamic
nav:
  title: Demo
  path: /demo
---

<code src="../examples/dynamic.jsx"></code>


================================================
FILE: docs/demo/errorStep.md
================================================
---
title: errorStep
nav:
  title: Demo
  path: /demo
---

<code src="../examples/errorStep.jsx"></code>


================================================
FILE: docs/demo/inline.md
================================================
---
title: inline
nav:
  title: Demo
  path: /demo
---

<code src="../examples/inline.jsx"></code>


================================================
FILE: docs/demo/nav-base.md
================================================
---
title: nav-base
nav:
  title: Demo
  path: /demo
---

<code src="../examples/nav-base.jsx"></code>


================================================
FILE: docs/demo/nextStep.md
================================================
---
title: nextStep
nav:
  title: Demo
  path: /demo
---

<code src="../examples/nextStep.jsx"></code>


================================================
FILE: docs/demo/progressDot.md
================================================
---
title: progressDot
nav:
  title: Demo
  path: /demo
---

<code src="../examples/progressDot.jsx"></code>


================================================
FILE: docs/demo/simple.md
================================================
---
title: simple
nav:
  title: Demo
  path: /demo
---

<code src="../examples/simple.jsx"></code>


================================================
FILE: docs/demo/smallSize.md
================================================
---
title: smallSize
nav:
  title: Demo
  path: /demo
---

<code src="../examples/smallSize.jsx"></code>


================================================
FILE: docs/demo/stepIcon.md
================================================
---
title: stepIcon
nav:
  title: Demo
  path: /demo
---

<code src="../examples/stepIcon.jsx"></code>


================================================
FILE: docs/demo/vertical.md
================================================
---
title: vertical
nav:
  title: Demo
  path: /demo
---

<code src="../examples/vertical.jsx"></code>


================================================
FILE: docs/demo/verticalSmall.md
================================================
---
title: verticalSmall
nav:
  title: Demo
  path: /demo
---

<code src="../examples/verticalSmall.jsx"></code>


================================================
FILE: docs/examples/alternativeLabel.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

const description =
  '这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊';

export default () => (
  <Steps
    titlePlacement="vertical"
    current={1}
    items={[
      {
        title: '已完成',
        description,
        status: 'wait',
      },
      {
        title: '进行中',
        description,
        status: 'wait',
        subTitle: '剩余 00:00:07',
      },
      undefined,
      {
        title: '待运行',
        description,
        status: 'process',
      },
      false,
      {
        title: '待运行',
        description,
        status: 'finish',
        disabled: true,
      },
      null,
    ]}
  />
);


================================================
FILE: docs/examples/composable.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

const description =
  '这里是多信息的描述啊描述啊描述啊描述啊哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶';

export default () => (
  <Steps
    current={1}
    items={[
      {
        title: '已完成',
        description,
      },
      {
        title: '进行中',
        description,
      },
      {
        title: '进行中',
        description,
        style: { fontWeight: 'bold', fontStyle: 'italic' },
      },
      {
        title: '待运行',
        description,
      },
    ]}
  />
);


================================================
FILE: docs/examples/custom-svg-icon.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

function getFinishIcon() {
  const path =
    'M923 283.6c-13.4-31.1-32.6-58.9-56.9-82.8-24.3-23.8-52.' +
    '5-42.4-84-55.5-32.5-13.5-66.9-20.3-102.4-20.3-49.3 0-97.4 13.5-139' +
    '.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5' +
    '-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 ' +
    '55.5-24.4 23.9-43.5 51.7-56.9 82.8-13.9 32.3-21 66.6-21 101.9 0 33' +
    '.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99' +
    '.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.' +
    '7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 10' +
    '1.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 ' +
    '20.3-103.3 0.1-35.3-7-69.6-20.9-101.9z';
  return (
    <svg
      width="1em"
      height="1em"
      fill="currentColor"
      viewBox="0 0 1024 1024"
      style={{ verticalAlign: '-.125em' }}
    >
      <path d={path} />
    </svg>
  );
}

function getErrorIcon() {
  const path1 =
    'M512 0C229.2 0 0 229.2 0 512s229.2 512 512 512 512-229' +
    '.2 512-512S794.8 0 512 0zm311.1 823.1c-40.4 40.4-87.5 72.2-139.9 9' +
    '4.3C629 940.4 571.4 952 512 952s-117-11.6-171.2-34.5c-52.4-22.2-99' +
    '.4-53.9-139.9-94.3-40.4-40.4-72.2-87.5-94.3-139.9C83.6 629 72 571.' +
    '4 72 512s11.6-117 34.5-171.2c22.2-52.4 53.9-99.4 94.3-139.9 40.4-4' +
    '0.4 87.5-72.2 139.9-94.3C395 83.6 452.6 72 512 72s117 11.6 171.2 3' +
    '4.5c52.4 22.2 99.4 53.9 139.9 94.3 40.4 40.4 72.2 87.5 94.3 139.9C' +
    '940.4 395 952 452.6 952 512s-11.6 117-34.5 171.2c-22.2 52.4-53.9 9' +
    '9.5-94.4 139.9z';
  const path2 =
    'M640.3 765.5c-19.9 0-36-16.1-36-36 0-50.9-41.4-92.3-92' +
    '.3-92.3s-92.3 41.4-92.3 92.3c0 19.9-16.1 36-36 36s-36-16.1-36-36c0' +
    '-90.6 73.7-164.3 164.3-164.3s164.3 73.7 164.3 164.3c0 19.9-16.1 36' +
    '-36 36zM194.2 382.4a60 60 0 1 0 120 0 60 60 0 1 0-120 0zM709.5 382' +
    '.4a60 60 0 1 0 120 0 60 60 0 1 0-120 0z';
  return (
    <svg
      width="1em"
      height="1em"
      fill="currentColor"
      viewBox="0 0 1024 1024"
      style={{ verticalAlign: '-.125em' }}
    >
      <path d={path1} />
      <path d={path2} />
    </svg>
  );
}

const icons = {
  finish: getFinishIcon(),
  error: getErrorIcon(),
};

const description = 'This is a description';

export default () => (
  <Steps
    current={1}
    status="error"
    icons={icons}
    items={[
      { title: 'Finished', description },
      { title: 'In Process', description },
      { title: 'Waiting', description },
    ]}
  />
);


================================================
FILE: docs/examples/customIcon.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

// eslint-disable-next-line react/prop-types
const Icon = ({ type }) => <i className={`rcicon rcicon-${type}`} />;

export default () => (
  <Steps
    current={1}
    items={[
      { title: '步骤1', icon: <Icon type="cloud" /> },
      { title: '步骤2', icon: 'apple' },
      { title: '步骤1', icon: 'github' },
    ]}
  />
);


================================================
FILE: docs/examples/dynamic.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React, { useState } from 'react';
import Steps from '@rc-component/steps';

export default () => {
  const [items, setItems] = useState([
    {
      title: '已完成',
      description:
        '这里是多信息的描述啊描述啊描述啊描述啊哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶',
    },
    {
      title: '进行中',
      description:
        '这里是多信息的描述啊描述啊描述啊描述啊哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶',
    },
    {
      title: '待运行',
      description:
        '这里是多信息的描述啊描述啊描述啊描述啊哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶',
    },
    {
      title: '待运行',
      description:
        '这里是多信息的描述啊描述啊描述啊描述啊哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶',
    },
  ]);

  const addStep = () => {
    const newSteps = [...items];
    newSteps.push({
      title: '待运行',
      description: '新的节点',
    });
    setItems(newSteps);
  };
  return (
    <div>
      <button type="button" onClick={addStep}>
        Add new step
      </button>
      <Steps items={items} />
    </div>
  );
};


================================================
FILE: docs/examples/errorStep.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

const description =
  '这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊';

export default () => (
  <Steps
    current={2}
    status="error"
    items={[
      {
        title: '已完成',
        description,
      },
      {
        title: '进行中',
        description,
      },
      {
        title: '待运行',
        description,
      },
      {
        title: '待运行',
        description,
      },
    ]}
  />
);


================================================
FILE: docs/examples/inline.jsx
================================================
import '../../assets/index.less';
import React, { useState } from 'react';
import Steps from '@rc-component/steps';

export default () => {
  const [current, setCurrent] = useState(0);

  return (
    <>
      <button
        onClick={() => {
          setCurrent(0);
        }}
      >
        Current: {current}
      </button>

      <br />

      <Steps
        type="inline"
        current={current}
        onChange={setCurrent}
        items={[
          {
            title: '开发',
            description: '开发阶段:开发中',
          },
          {
            title: '测试',
            description: '测试阶段:测试中',
          },
          {
            title: '预发',
            description: '预发阶段:预发中',
          },
          {
            title: '发布',
            description: '发布阶段:发布中',
          },
        ]}
        itemRender={(item, stepItem) => React.cloneElement(stepItem, { title: item.description })}
      />
    </>
  );
};


================================================
FILE: docs/examples/nav-base.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React, { useState } from 'react';
import Steps from '@rc-component/steps';

export default () => {
  const [current, setCurrent] = useState(0);

  const onChange = (current) => {
    // eslint-disable-next-line no-console
    console.log('onChange:', current);
    setCurrent(current);
  };

  const containerStyle = {
    border: '1px solid rgb(235, 237, 240)',
    marginBottom: 24,
  };

  const description = 'This is a description.';

  return (
    <div>
      <Steps
        style={containerStyle}
        type="navigation"
        current={current}
        onChange={onChange}
        items={[
          {
            title: 'Step 1',
            status: 'finish',
            subTitle: '剩余 00:00:05 超长隐藏',
            description,
          },
          {
            title: 'Step 2',
            status: 'process',
            description,
          },
          {
            title: 'Step 3',
            status: 'wait',
            description,
            disabled: true,
          },
        ]}
      />
      <Steps
        style={containerStyle}
        type="navigation"
        current={current}
        onChange={onChange}
        items={[
          {
            title: 'Step 1',
            status: 'finish',
            subTitle: '剩余 00:00:05 超长隐藏',
          },
          {
            title: 'Step 2',
            status: 'process',
          },
          {
            title: 'Step 3',
            status: 'wait',
          },
          {
            title: 'Step 3',
            status: 'wait',
          },
        ]}
      />
    </div>
  );
};


================================================
FILE: docs/examples/nextStep.css
================================================
.my-step-form {
  width: 100%;
}
.my-step-form > div {
  margin-bottom: 20px;
}
.my-step-container {
  width: 100%;
}


================================================
FILE: docs/examples/nextStep.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import './nextStep.css';
import React from 'react';
import Steps from '@rc-component/steps';

function generateRandomSteps() {
  const n = Math.floor(Math.random() * 3) + 3;
  const arr = [];
  for (let i = 0; i < n; i++) {
    arr.push({
      title: `步骤${i + 1}`,
    });
  }
  return arr;
}
const steps = generateRandomSteps();

class MyForm extends React.Component {
  state = {
    currentStep: Math.floor(Math.random() * steps.length),
  };

  nextStep = () => {
    const { currentStep } = this.state;
    let s = currentStep + 1;
    if (s === steps.length) {
      s = 0;
    }
    this.setState({
      currentStep: s,
    });
  };

  render() {
    const { currentStep: cs } = this.state;
    this.stepsRefs = [];
    return (
      <form className="my-step-form">
        <div>这个demo随机生成3~6个步骤,初始随机进行到其中一个步骤</div>
        <div>当前正在执行第{cs + 1}步</div>
        <div className="my-step-container">
          <Steps
            current={cs}
            items={steps.map((s, i) => ({
              ref: (c) => {
                this.stepsRefs[i] = c;
              },
              key: i,
              title: s.title,
            }))}
          />
        </div>

        <div>
          <button type="button" onClick={this.nextStep}>
            下一步
          </button>
        </div>
      </form>
    );
  }
}

export default MyForm;


================================================
FILE: docs/examples/progressDot.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

const description =
  '这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊';

export default () => (
  <Steps
    progressDot
    size="small"
    current={1}
    items={[
      {
        title: '已完成',
        description,
      },
      {
        title: '进行中',
        description,
      },
      {
        title: '待运行',
        description,
      },
      {
        title: '待运行',
        description,
      },
      {
        title: '待运行',
        description,
      },
    ]}
  />
);


================================================
FILE: docs/examples/simple.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

const description =
  '这里是多信息的描述啊描述啊描述啊描述啊哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶哦耶';

const ControlSteps = () => {
  const [current, setCurrent] = React.useState(0);
  return (
    <Steps
      current={current}
      onChange={(val) => {
        // eslint-disable-next-line no-console
        console.log('Change:', val);
        setCurrent(val);
      }}
      items={[
        {
          title: '已完成',
        },
        {
          title: '进行中',
        },
        {
          title: '待运行',
          description: 'Hello World!',
        },
        {
          title: '待运行',
        },
      ]}
    />
  );
};

export default () => (
  <div>
    <Steps
      current={1}
      items={[
        {
          title: '已完成',
        },
        {
          title: '进行中',
        },
        {
          title: '待运行',
        },
        {
          title: '待运行',
        },
      ]}
    />
    <Steps
      current={1}
      style={{ marginTop: 40 }}
      items={[
        {
          title: '已完成',
          description,
        },
        {
          title: '进行中',
          subTitle: '剩余 00:00:07',
          description,
        },
        {
          title: '待运行',
          description,
        },
        {
          title: '待运行',
          description,
        },
      ]}
    />
    <Steps
      current={1}
      style={{ marginTop: 40 }}
      status="error"
      items={[
        {
          title: '已完成',
          description,
        },
        {
          title: '进行中',
          subTitle: '剩余 00:00:07',
          description,
        },
        {
          title: '待运行',
          description,
        },
        {
          title: '待运行',
          description,
        },
      ]}
    />
    <ControlSteps />
  </div>
);


================================================
FILE: docs/examples/smallSize.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

// eslint-disable-next-line react/prop-types
const Icon = ({ type }) => <i className={`rcicon rcicon-${type}`} />;

export default () => (
  <div>
    <Steps
      size="small"
      current={1}
      items={[
        {
          title: '已完成',
        },
        {
          title: '进行中',
        },
        {
          title: '待运行',
        },
        {
          title: '待运行',
        },
      ]}
    />
    <Steps
      size="small"
      current={1}
      style={{ marginTop: 40 }}
      items={[
        {
          title: '步骤1',
        },
        {
          title: '步骤2',
          icon: <Icon type="cloud" />,
        },
        {
          title: '步骤3',
          icon: 'apple',
        },
        {
          title: '待运行',
          icon: 'github',
        },
      ]}
    />
  </div>
);


================================================
FILE: docs/examples/stepIcon.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

function stepIcon({ status, node }) {
  const isProcessing = status === 'process';
  return isProcessing ? <div style={{ backgroundColor: 'blue' }}>{node}</div> : node;
}

export default () => {
  const [current, setCurrent] = React.useState(0);
  return (
    <>
      <button
        type="button"
        onClick={() => {
          setCurrent((current + 1) % 5);
        }}
      >
        loop
      </button>
      <Steps
        stepIcon={stepIcon}
        current={current}
        items={[
          {
            title: '已完成',
          },
          {
            title: '进行中',
          },
          {
            title: '待运行',
          },
          {
            title: '待运行',
          },
          {
            title: '待运行',
          },
        ]}
      />
    </>
  );
};


================================================
FILE: docs/examples/vertical.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

const description =
  '这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊';

export default () => (
  <Steps
    direction="vertical"
    items={[
      {
        title: '已完成',
        description,
      },
      {
        title: '进行中',
        description,
      },
      {
        title: '待运行',
        description,
      },
      {
        title: '待运行',
        description,
      },
    ]}
  />
);


================================================
FILE: docs/examples/verticalSmall.jsx
================================================
import '../../assets/index.less';
import '../../assets/iconfont.less';
import React from 'react';
import Steps from '@rc-component/steps';

const description =
  '这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊这里是多信息的描述啊';

export default () => (
  <Steps
    direction="vertical"
    size="small"
    items={[
      {
        title: '已完成',
        description,
      },
      {
        title: '进行中',
        description,
      },
      {
        title: '待运行',
        description,
      },
      {
        title: '待运行',
        description,
      },
    ]}
  />
);


================================================
FILE: docs/index.md
================================================
---
hero:
  title: "@rc-component/steps"
  description: React Steps Component
---

<embed src="../README.md"></embed>


================================================
FILE: index.js
================================================
'use strict';

module.exports = require('./src/');

================================================
FILE: jest.config.js
================================================
module.exports = {
  setupFiles: ['./tests/setup.js'],
};

================================================
FILE: package.json
================================================
{
  "name": "@rc-component/steps",
  "version": "1.2.2",
  "description": "steps ui component for react",
  "keywords": [
    "react",
    "react-component",
    "react-steps"
  ],
  "homepage": "http://github.com/react-component/steps",
  "bugs": {
    "url": "http://github.com/react-component/steps/issues"
  },
  "repository": {
    "type": "git",
    "url": " git+ssh://git@github.com/react-component/steps.git"
  },
  "license": "MIT",
  "maintainers": [
    {
      "name": "afc163",
      "email": "afc163@gmail.com"
    }
  ],
  "main": "./lib/index",
  "module": "./es/index",
  "types": "./lib/index.d.ts",
  "files": [
    "assets/*.css",
    "es",
    "lib"
  ],
  "scripts": {
    "compile": "father build && lessc assets/index.less assets/index.css",
    "coverage": "rc-test --coverage",
    "docs:build": "dumi build",
    "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 && dumi setup",
    "prepublishOnly": "npm run compile && rc-np",
    "prettier": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
    "postpublish": "npm run gh-pages",
    "start": "dumi dev",
    "test": "rc-test",
    "now-build": "npm run docs:build"
  },
  "lint-staged": {
    "**/*.{js,jsx,tsx,ts,md,json}": [
      "prettier --write"
    ]
  },
  "dependencies": {
    "@rc-component/util": "^1.2.1",
    "clsx": "^2.1.1"
  },
  "devDependencies": {
    "@rc-component/father-plugin": "^2.0.2",
    "@rc-component/np": "^1.0.0",
    "@testing-library/jest-dom": "^6.4.5",
    "@testing-library/react": "^15.0.6",
    "@types/jest": "^29.4.0",
    "@types/node": "^24.5.2",
    "@types/react": "^18.0.28",
    "@types/react-dom": "^18.0.11",
    "@umijs/fabric": "^4.0.1",
    "dumi": "^2.0.0",
    "eslint": "^8.55.0",
    "eslint-plugin-jest": "^27.6.0",
    "eslint-plugin-unicorn": "^50.0.1",
    "father": "^4",
    "gh-pages": "^6.1.0",
    "glob": "^10.0.0",
    "husky": "^8.0.1",
    "less": "^4.1.3",
    "lint-staged": "^15.2.0",
    "prettier": "^3.1.0",
    "rc-test": "^7.0.9",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "typescript": "^5.0.0"
  },
  "peerDependencies": {
    "react": ">=16.9.0",
    "react-dom": ">=16.9.0"
  },
  "engines": {
    "node": ">=8.x"
  }
}


================================================
FILE: script/update-content.js
================================================
/*
  用于 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
---

<code src="../examples/${name}.jsx"></code>
`,
    'utf8',
    function(error) {
      if(error){
        console.log(error);
        return false;
      }
      console.log(`${name} 更新成功~`);
    }
  )
});


================================================
FILE: src/Context.ts
================================================
import * as React from 'react';
import type { ComponentType, StepsProps } from './Steps';

export interface StepsContextProps {
  prefixCls: string;
  classNames: NonNullable<StepsProps['classNames']>;
  styles: NonNullable<StepsProps['styles']>;
  ItemComponent: ComponentType;
}

export const StepsContext = React.createContext<StepsContextProps>(null!);


================================================
FILE: src/Rail.tsx
================================================
import * as React from 'react';
import { clsx } from 'clsx';
import type { Status } from './Steps';

export interface RailProps {
  prefixCls: string;
  className: string;
  style: React.CSSProperties;
  status: Status;
}

export default function Rail(props: RailProps) {
  const { prefixCls, className, style, status } = props;
  const railCls = `${prefixCls}-rail`;

  // ============================= render =============================
  return <div className={clsx(railCls, `${railCls}-${status}`, className)} style={style} />;
}


================================================
FILE: src/Step.tsx
================================================
/* eslint react/prop-types: 0 */
import * as React from 'react';
import { clsx } from 'clsx';
import KeyCode from '@rc-component/util/lib/KeyCode';
import type { Status, StepItem, StepsProps } from './Steps';
import Rail from './Rail';
import { UnstableContext } from './UnstableContext';
import StepIcon, { StepIconSemanticContext } from './StepIcon';
import { StepsContext } from './Context';

function hasContent<T>(value: T) {
  return value !== undefined && value !== null;
}

export interface StepProps {
  // style
  prefixCls?: string;
  classNames: StepsProps['classNames'];
  styles: StepsProps['styles'];

  // data
  data: StepItem;
  nextStatus?: Status;
  active?: boolean;
  index: number;
  last: boolean;

  // render
  iconRender?: StepsProps['iconRender'];
  icon?: React.ReactNode;
  itemRender?: StepsProps['itemRender'];
  itemWrapperRender?: StepsProps['itemWrapperRender'];

  // Event
  onClick: (index: number) => void;
}

export default function Step(props: StepProps) {
  const {
    // style
    prefixCls,
    classNames,
    styles,

    // data
    data,
    last,
    nextStatus,
    active,
    index,

    // render
    itemRender,
    iconRender,
    itemWrapperRender,

    // events
    onClick,
  } = props;

  const itemCls = `${prefixCls}-item`;

  // ======================== Contexts ========================
  const { railFollowPrevStatus } = React.useContext(UnstableContext);
  const { ItemComponent } = React.useContext(StepsContext);

  // ========================== Data ==========================
  const {
    onClick: onItemClick,
    title,
    subTitle,
    content,
    description,
    disabled,
    icon,
    status,

    className,
    style,
    classNames: itemClassNames = {},
    styles: itemStyles = {},

    ...restItemProps
  } = data;

  const mergedContent = content ?? description;

  const renderInfo = {
    item: {
      ...data,
      content: mergedContent,
    },
    index,
    active,
  };

  // ========================= Click ==========================
  const clickable = !!(onClick || onItemClick) && !disabled;

  const accessibilityProps: {
    role?: string;
    tabIndex?: number;
    onClick?: React.MouseEventHandler<HTMLLIElement>;
    onKeyDown?: React.KeyboardEventHandler<HTMLLIElement>;
  } = {};

  if (clickable) {
    accessibilityProps.role = 'button';
    accessibilityProps.tabIndex = 0;
    accessibilityProps.onClick = (e) => {
      onItemClick?.(e);
      onClick(index);
    };

    accessibilityProps.onKeyDown = (e) => {
      const { which } = e;
      if (which === KeyCode.ENTER || which === KeyCode.SPACE) {
        onClick(index);
      }
    };
  }

  // ========================= Render =========================
  const mergedStatus = status || 'wait';

  const hasTitle = hasContent(title);
  const hasSubTitle = hasContent(subTitle);

  const classString = clsx(
    itemCls,
    `${itemCls}-${mergedStatus}`,
    {
      [`${itemCls}-custom`]: icon,
      [`${itemCls}-active`]: active,
      [`${itemCls}-disabled`]: disabled === true,
      [`${itemCls}-empty-header`]: !hasTitle && !hasSubTitle,
    },
    className,
    classNames.item,
    itemClassNames.root,
  );

  let iconNode = <StepIcon />;
  if (iconRender) {
    iconNode = iconRender(iconNode, {
      ...renderInfo,
      components: {
        Icon: StepIcon,
      },
    }) as React.ReactElement;
  }

  const wrapperNode = (
    <div
      className={clsx(`${itemCls}-wrapper`, classNames.itemWrapper, itemClassNames.wrapper)}
      style={{ ...styles.itemWrapper, ...itemStyles.wrapper }}
    >
      {/* Icon */}
      <StepIconSemanticContext.Provider
        value={{
          className: itemClassNames.icon,
          style: itemStyles.icon,
        }}
      >
        {iconNode}
      </StepIconSemanticContext.Provider>

      <div
        className={clsx(`${itemCls}-section`, classNames.itemSection, itemClassNames.section)}
        style={{ ...styles.itemSection, ...itemStyles.section }}
      >
        <div
          className={clsx(`${itemCls}-header`, classNames.itemHeader, itemClassNames.header)}
          style={{ ...styles.itemHeader, ...itemStyles.header }}
        >
          {hasTitle && (
            <div
              className={clsx(`${itemCls}-title`, classNames.itemTitle, itemClassNames.title)}
              style={{ ...styles.itemTitle, ...itemStyles.title }}
            >
              {title}
            </div>
          )}
          {hasSubTitle && (
            <div
              title={typeof subTitle === 'string' ? subTitle : undefined}
              className={clsx(
                `${itemCls}-subtitle`,
                classNames.itemSubtitle,
                itemClassNames.subtitle,
              )}
              style={{ ...styles.itemSubtitle, ...itemStyles.subtitle }}
            >
              {subTitle}
            </div>
          )}

          {!last && (
            <Rail
              prefixCls={itemCls}
              className={clsx(classNames.itemRail, itemClassNames.rail)}
              style={{ ...styles.itemRail, ...itemStyles.rail }}
              status={railFollowPrevStatus ? status : nextStatus}
            />
          )}
        </div>
        {hasContent(mergedContent) && (
          <div
            className={clsx(`${itemCls}-content`, classNames.itemContent, itemClassNames.content)}
            style={{ ...styles.itemContent, ...itemStyles.content }}
          >
            {mergedContent}
          </div>
        )}
      </div>
    </div>
  );

  let stepNode: React.ReactNode = (
    <ItemComponent
      {...restItemProps}
      {...accessibilityProps}
      className={classString}
      style={{
        ...styles.item,
        ...itemStyles.root,
        ...style,
      }}
    >
      {itemWrapperRender ? itemWrapperRender(wrapperNode) : wrapperNode}
    </ItemComponent>
  );

  if (itemRender) {
    stepNode = (itemRender(stepNode, renderInfo) || null) as React.ReactElement;
  }

  return stepNode;
}


================================================
FILE: src/StepIcon.tsx
================================================
import * as React from 'react';
import { clsx } from 'clsx';
import { StepsContext } from './Context';
import pickAttrs from '@rc-component/util/lib/pickAttrs';

export interface StepIconSemanticContextProps {
  className?: string;
  style?: React.CSSProperties;
}

export const StepIconSemanticContext = React.createContext<StepIconSemanticContextProps>({});

export type StepIconProps = React.HTMLAttributes<HTMLDivElement>;

const StepIcon = React.forwardRef<HTMLDivElement, StepIconProps>((props, ref) => {
  const { className, style, children, ...restProps } = props;

  const { prefixCls, classNames, styles } = React.useContext(StepsContext);
  const { className: itemClassName, style: itemStyle } = React.useContext(StepIconSemanticContext);

  const itemCls = `${prefixCls}-item`;

  return (
    <div
      {...pickAttrs(restProps, false)}
      ref={ref}
      className={clsx(`${itemCls}-icon`, classNames.itemIcon, itemClassName, className)}
      style={{ ...styles.itemIcon, ...itemStyle, ...style }}
    >
      {children}
    </div>
  );
});

export default StepIcon;


================================================
FILE: src/Steps.tsx
================================================
/* eslint react/no-did-mount-set-state: 0, react/prop-types: 0 */
import { clsx } from 'clsx';
import React from 'react';
import Step from './Step';
import { StepsContext, type StepsContextProps } from './Context';
import type StepIcon from './StepIcon';

export type Status = 'error' | 'process' | 'finish' | 'wait';

const EmptyObject = {};

export type SemanticName =
  | 'root'
  | 'item'
  | 'itemWrapper'
  | 'itemHeader'
  | 'itemTitle'
  | 'itemSubtitle'
  | 'itemSection'
  | 'itemContent'
  | 'itemIcon'
  | 'itemRail';

export type ItemSemanticName =
  | 'root'
  | 'wrapper'
  | 'header'
  | 'title'
  | 'subtitle'
  | 'section'
  | 'content'
  | 'icon'
  | 'rail';

export type ComponentType = React.ComponentType<any> | string;

export type StepItem = {
  /** @deprecated Please use `content` instead. */
  description?: React.ReactNode;
  content?: React.ReactNode;
  disabled?: boolean;
  icon?: React.ReactNode;
  status?: Status;
  subTitle?: React.ReactNode;
  title?: React.ReactNode;
  classNames?: Partial<Record<ItemSemanticName, string>>;
  styles?: Partial<Record<ItemSemanticName, React.CSSProperties>>;
} & Pick<React.HtmlHTMLAttributes<HTMLLIElement>, 'onClick' | 'className' | 'style'>;

export type StepIconRender = (info: {
  index: number;
  status: Status;
  title: React.ReactNode;
  // @deprecated Please use `content` instead.
  description: React.ReactNode;
  content: React.ReactNode;
  node: React.ReactNode;
}) => React.ReactNode;

export type RenderInfo = {
  index: number;
  active: boolean;
  item: StepItem;
};

export interface StepsProps {
  // style
  prefixCls?: string;
  style?: React.CSSProperties;
  className?: string;
  classNames?: Partial<Record<SemanticName, string>>;
  styles?: Partial<Record<SemanticName, React.CSSProperties>>;
  rootClassName?: string;

  // layout
  orientation?: 'horizontal' | 'vertical';
  titlePlacement?: 'horizontal' | 'vertical';

  // a11y
  /** Internal usage of antd. Do not deps on this. */
  components?: {
    root?: ComponentType;
    item?: ComponentType;
  };

  // data
  status?: Status;
  current?: number;
  initial?: number;
  items?: StepItem[];
  onChange?: (current: number) => void;

  // render
  iconRender?: (
    originNode: React.ReactElement,
    info: RenderInfo & {
      components: {
        Icon: typeof StepIcon;
      };
    },
  ) => React.ReactNode;
  itemRender?: (originNode: React.ReactElement, info: RenderInfo) => React.ReactNode;
  itemWrapperRender?: (originNode: React.ReactElement) => React.ReactNode;
}

export default function Steps(props: StepsProps) {
  const {
    // style
    prefixCls = 'rc-steps',
    style,
    className,
    classNames = EmptyObject as NonNullable<StepsProps['classNames']>,
    styles = EmptyObject as NonNullable<StepsProps['styles']>,
    rootClassName,

    // layout
    orientation,
    titlePlacement,
    components,

    // data
    status = 'process',
    current = 0,
    initial = 0,
    onChange,
    items,

    // render
    iconRender,
    itemRender,
    itemWrapperRender,

    ...restProps
  } = props;

  // ============================= layout =============================
  const isVertical = orientation === 'vertical';
  const mergedOrientation = isVertical ? 'vertical' : 'horizontal';
  const mergeTitlePlacement =
    !isVertical && titlePlacement === 'vertical' ? 'vertical' : 'horizontal';

  // ============================= styles =============================
  const classString = clsx(
    prefixCls,
    `${prefixCls}-${mergedOrientation}`,
    `${prefixCls}-title-${mergeTitlePlacement}`,
    rootClassName,
    className,
    classNames.root,
  );

  // ============================== Data ==============================
  const mergedItems = React.useMemo(() => (items || []).filter(Boolean), [items]);
  const statuses = React.useMemo(
    () =>
      mergedItems.map(({ status: itemStatus }, index) => {
        const stepNumber = initial + index;

        if (!itemStatus) {
          if (stepNumber === current) {
            return status;
          } else if (stepNumber < current) {
            return 'finish';
          }
          return 'wait';
        }

        return itemStatus;
      }),
    [mergedItems, status, current, initial],
  );

  // ============================= events =============================
  const onStepClick = (next: number) => {
    if (onChange && current !== next) {
      onChange(next);
    }
  };

  // =========================== components ===========================
  const { root: RootComponent = 'div', item: ItemComponent = 'div' } = components || {};

  // ============================ contexts ============================
  const stepIconContext = React.useMemo<StepsContextProps>(
    () => ({
      prefixCls,
      classNames,
      styles,
      ItemComponent,
    }),
    [prefixCls, classNames, styles, ItemComponent],
  );

  // ============================= render =============================
  const renderStep = (item: StepItem, index: number) => {
    const stepIndex = initial + index;

    const itemStatus = statuses[index];
    const nextStatus = statuses[index + 1];

    const data = {
      ...item,
      status: itemStatus,
    };

    return (
      <Step
        key={stepIndex}
        // Style
        prefixCls={prefixCls}
        classNames={classNames}
        styles={styles}
        // Data
        data={data}
        nextStatus={nextStatus}
        active={stepIndex === current}
        index={stepIndex}
        last={mergedItems.length - 1 === index}
        // Render
        iconRender={iconRender}
        itemRender={itemRender}
        itemWrapperRender={itemWrapperRender}
        onClick={onChange && onStepClick}
      />
    );
  };

  return (
    <RootComponent
      className={classString}
      style={{
        ...style,
        ...styles?.root,
      }}
      {...restProps}
    >
      <StepsContext.Provider value={stepIconContext}>
        {mergedItems.map<React.ReactNode>(renderStep)}
      </StepsContext.Provider>
    </RootComponent>
  );
}


================================================
FILE: src/UnstableContext.ts
================================================
import * as React from 'react';

export interface UnstableContextProps {
  /**
   * Used for Timeline component `reverse` prop.
   * Safe to remove if refactor.
   */
  railFollowPrevStatus?: boolean;
}

export const UnstableContext = React.createContext<UnstableContextProps>({});


================================================
FILE: src/index.ts
================================================
import Steps, { type StepsProps } from './Steps';
import Step from './Step';

export { Step };
export type { StepsProps };
export { UnstableContext } from './UnstableContext';
export default Steps;


================================================
FILE: src/interface.ts
================================================



================================================
FILE: tests/__snapshots__/index.test.tsx.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Steps components 1`] = `
<ol
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <li
    class="rc-steps-item rc-steps-item-process rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            test
          </div>
        </div>
      </div>
    </div>
  </li>
</ol>
`;

exports[`Steps render renders correctly 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-process rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders current correctly 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-finish"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-finish"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-finish"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-process"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-process rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders progressDot correctly 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-process rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders progressDot function correctly 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-process rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders status correctly 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-finish"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-finish"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-finish"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-error"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-error rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders step with description 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-process rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders step with description and status 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-wait rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-process"
          />
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-process"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-finish"
          />
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-finish"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders stepIcon function correctly 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-process rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders titlePlacement correctly 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-vertical"
>
  <div
    class="rc-steps-item rc-steps-item-process rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders vertical correctly 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
  direction="vertical"
>
  <div
    class="rc-steps-item rc-steps-item-process rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps render renders with falsy children 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-wait rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            已完成
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            进行中
          </div>
          <div
            class="rc-steps-item-subtitle"
            title="剩余 00:00:07"
          >
            剩余 00:00:07
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-process"
          />
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-process"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-finish"
          />
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-finish rc-steps-item-disabled"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            待运行
          </div>
        </div>
        <div
          class="rc-steps-item-content"
        >
          xx
        </div>
      </div>
    </div>
  </div>
</div>
`;

exports[`Steps should render customIcon correctly 1`] = `
<div
  class="rc-steps rc-steps-horizontal rc-steps-title-horizontal"
>
  <div
    class="rc-steps-item rc-steps-item-finish rc-steps-item-custom"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            步骤1
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-process"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-process rc-steps-item-custom rc-steps-item-active"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            步骤2
          </div>
          <div
            class="rc-steps-item-rail rc-steps-item-rail-wait"
          />
        </div>
      </div>
    </div>
  </div>
  <div
    class="rc-steps-item rc-steps-item-wait rc-steps-item-custom"
  >
    <div
      class="rc-steps-item-wrapper"
    >
      <div
        class="rc-steps-item-icon"
      />
      <div
        class="rc-steps-item-section"
      >
        <div
          class="rc-steps-item-header"
        >
          <div
            class="rc-steps-item-title"
          >
            步骤3
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
`;


================================================
FILE: tests/index.test.tsx
================================================
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import Steps from '../src';

describe('Steps', () => {
  describe('render', () => {
    const description = 'xx';

    const setSteps = (props) => (
      <Steps
        items={[
          {
            title: '已完成',
          },
          {
            title: '进行中',
          },
          {
            title: '待运行',
          },
          {
            title: '待运行',
          },
        ]}
        {...props}
      />
    );

    it('renders correctly', () => {
      const { container } = render(setSteps({}));
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders without items', () => {
      expect(() => {
        render(setSteps({ items: undefined }));
      }).not.toThrow();
    });

    it('renders current correctly', () => {
      const { container } = render(setSteps({ current: 2 }));
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders status correctly', () => {
      const { container } = render(setSteps({ current: 2, status: 'error' }));
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders vertical correctly', () => {
      const { container } = render(setSteps({ direction: 'vertical' }));
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders titlePlacement correctly', () => {
      const { container } = render(setSteps({ titlePlacement: 'vertical' }));
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders progressDot correctly', () => {
      const { container } = render(setSteps({ progressDot: true }));
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders progressDot function correctly', () => {
      const { container } = render(setSteps({ progressDot: () => <span>a</span> }));
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders stepIcon function correctly', () => {
      const { container } = render(setSteps({ stepIcon: () => <span>a</span> }));
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders step with description', () => {
      const { container } = render(
        <Steps
          items={[
            {
              title: '已完成',
              description,
            },
            {
              title: '进行中',
              description,
            },
            {
              title: '待运行',
              description,
            },
            {
              title: '待运行',
              description,
            },
          ]}
        />,
      );
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders step with description and status', () => {
      const { container } = render(
        <Steps
          items={[
            {
              title: '已完成',
              description,
              status: 'wait',
            },
            {
              title: '进行中',
              description,
              status: 'wait',
            },
            {
              title: '待运行',
              description,
              status: 'process',
            },
            {
              title: '待运行',
              description,
              status: 'finish',
            },
          ]}
        />,
      );
      expect(container.firstChild).toMatchSnapshot();
    });

    it('renders with falsy children', () => {
      const { container } = render(
        <Steps
          items={[
            {
              title: '已完成',
              description: 'xx',
              status: 'wait',
            },
            {
              title: '进行中',
              description: 'xx',
              status: 'wait',
              subTitle: '剩余 00:00:07',
            },
            undefined,
            {
              title: '待运行',
              description: 'xx',
              status: 'process',
            },
            // @ts-ignore
            false,
            {
              title: '待运行',
              description: 'xx',
              status: 'finish',
              disabled: true,
            },
            null,
          ]}
        />,
      );
      expect(container.firstChild).toMatchSnapshot();
    });
  });

  it('should render customIcon correctly', () => {
    const Icon = ({ type }) => <i className={`rcicon rcicon-${type}`} />;
    const { container } = render(
      <Steps
        current={1}
        items={[
          {
            title: '步骤1',
            icon: <Icon type="cloud" />,
          },
          {
            title: '步骤2',
            icon: 'apple',
          },
          {
            title: '步骤3',
            icon: 'github',
          },
        ]}
      />,
    );
    expect(container.firstChild).toMatchSnapshot();
  });

  it('onChange', () => {
    const onChange = jest.fn();
    const { container } = render(
      <Steps
        onChange={onChange}
        items={[
          {
            title: '已完成',
          },
          {
            title: '进行中',
          },
          {
            title: '待运行',
          },
          {
            title: '待运行',
          },
        ]}
      />,
    );
    const items = container.querySelectorAll('.rc-steps-item');
    fireEvent.click(items[1]);
    expect(onChange).toHaveBeenCalledTimes(1);
  });

  it('items out of render function', () => {
    const items = [
      {
        title: '已完成',
      },
      {
        title: '进行中',
      },
    ];

    let current = 0;
    const onChange = (val) => {
      current = val;
    };
    const { container, rerender } = render(
      <Steps current={current} onChange={onChange} items={items} key={current} />,
    );

    const step = container.querySelectorAll('.rc-steps-item')[1];
    fireEvent.click(step);
    rerender(<Steps current={current} onChange={onChange} items={items} key={current} />);
    expect(container.querySelectorAll('.rc-steps-item')[1].classList).toContain(
      'rc-steps-item-process',
    );
  });

  it('onClick', () => {
    const onClick = jest.fn();
    const onChange = jest.fn();
    const { container } = render(
      <Steps
        onChange={onChange}
        items={[
          {
            title: '已完成',
            onClick,
          },
          {
            title: '进行中',
          },
          {
            title: '待运行',
          },
          {
            title: '待运行',
          },
        ]}
      />,
    );

    const btn = container.querySelectorAll('.rc-steps-item')[0];
    fireEvent.click(btn);
    expect(onClick).toHaveBeenCalled();
  });

  it('disabled', () => {
    const onChange = jest.fn();
    const { container } = render(
      <Steps onChange={onChange} items={[{}, {}, { disabled: true }]} />,
    );

    const items = container.querySelectorAll('.rc-steps-item');
    fireEvent.click(items[2]);
    expect(onChange).not.toBeCalled();
  });

  it('key board support', () => {
    const onChange = jest.fn();
    const { container } = render(
      <Steps
        current={0}
        onChange={onChange}
        items={[
          {
            title: 'Finished',
            description: 'This is a description',
          },
          {
            title: 'Waiting',
            description: 'This is a description',
          },
        ]}
      />,
    );

    const button = container.querySelectorAll('[role="button"]')[1];
    fireEvent.keyDown(button, { key: 'Enter', keyCode: 13, which: 13 });

    expect(onChange).toHaveBeenCalledWith(1);
  });

  it('itemRender', () => {
    const { container } = render(
      <Steps
        items={[
          {
            title: 'test',
          },
        ]}
        itemRender={(oriNode) => {
          return <div className="bamboo">{oriNode}</div>;
        }}
      />,
    );

    expect(container.querySelector('.bamboo')).toBeTruthy();
    expect(container.querySelectorAll('.bamboo')).toHaveLength(1);
    expect(container.querySelector('.rc-steps-item')).toBeTruthy();
  });

  it('itemWrapperRender', () => {
    const { container } = render(
      <Steps
        items={[
          {
            title: 'test',
          },
        ]}
        itemWrapperRender={(oriNode) => {
          return <div className="bamboo">{oriNode}</div>;
        }}
      />,
    );

    expect(container.querySelector('.bamboo')).toBeTruthy();
    expect(container.querySelectorAll('.bamboo')).toHaveLength(1);
    expect(container.querySelector('.rc-steps-item')).toBeTruthy();
    expect(container.querySelector('.rc-steps-item > .bamboo')).toBeTruthy();
  });

  it('iconRender', () => {
    const { container } = render(
      <Steps
        items={[
          {
            title: 'test',
          },
        ]}
        iconRender={(_, { components: { Icon } }) => {
          return <Icon className="bamboo">little</Icon>;
        }}
      />,
    );

    const iconEle = container.querySelector('.rc-steps-item-icon')!;
    expect(iconEle).toHaveClass('bamboo');
    expect(iconEle.textContent).toBe('little');
  });

  it('components', () => {
    const { container } = render(
      <Steps
        components={{
          root: 'ol',
          item: 'li',
        }}
        items={[
          {
            title: 'test',
          },
        ]}
      />,
    );

    expect(container.firstChild).toMatchSnapshot();
  });
});


================================================
FILE: tests/semantic.test.tsx
================================================
import React from 'react';
import { render } from '@testing-library/react';
import Steps, { type StepsProps } from '../src';
import type { ItemSemanticName, SemanticName } from '../src/Steps';

describe('Steps.Semantic', () => {
  const renderSteps = (props: Partial<StepsProps>) => (
    <Steps
      items={Array.from({ length: 3 }, (_, index) => ({
        title: `Step ${index + 1}`,
        subTitle: `SubTitle ${index + 1}`,
        content: `Content ${index + 1}`,
      }))}
      {...props}
    />
  );

  it('semantic structure', () => {
    const classNames: Record<SemanticName, string> = {
      root: 'custom-root',
      item: 'custom-item',
      itemWrapper: 'custom-item-wrapper',
      itemIcon: 'custom-item-icon',
      itemSection: 'custom-item-section',
      itemHeader: 'custom-item-header',
      itemTitle: 'custom-item-title',
      itemSubtitle: 'custom-item-subtitle',
      itemContent: 'custom-item-content',
      itemRail: 'custom-item-rail',
    };

    const classNamesTargets: Record<SemanticName, string> = {
      root: 'rc-steps',
      item: 'rc-steps-item',
      itemWrapper: 'rc-steps-item-wrapper',
      itemIcon: 'rc-steps-item-icon',
      itemSection: 'rc-steps-item-section',
      itemHeader: 'rc-steps-item-header',
      itemTitle: 'rc-steps-item-title',
      itemSubtitle: 'rc-steps-item-subtitle',
      itemContent: 'rc-steps-item-content',
      itemRail: 'rc-steps-item-rail',
    };

    const styles: Record<SemanticName, Record<string, any>> = {
      root: { color: 'red' },
      item: { color: 'blue' },
      itemWrapper: { color: 'green' },
      itemIcon: { color: 'yellow' },
      itemSection: { color: 'purple' },
      itemHeader: { color: 'orange' },
      itemTitle: { color: 'pink' },
      itemSubtitle: { color: 'cyan' },
      itemContent: { color: 'magenta' },
      itemRail: { color: 'lime' },
    };

    const { container } = render(
      renderSteps({
        classNames,
        styles,
      }),
    );

    Object.keys(classNames).forEach((key) => {
      const className = classNames[key as SemanticName];
      const oriClassName = classNamesTargets[key as SemanticName];
      const style = styles[key as SemanticName];

      const element = container.querySelector<HTMLElement>(`.${className}`);
      expect(element).toBeTruthy();
      expect(element).toHaveClass(oriClassName);
      expect(element).toHaveStyle(style);
    });
  });

  it('item semantic structure', () => {
    const classNames: Record<ItemSemanticName, string> = {
      root: 'custom-root',
      wrapper: 'custom-wrapper',
      header: 'custom-header',
      title: 'custom-title',
      subtitle: 'custom-subtitle',
      section: 'custom-section',
      content: 'custom-content',
      icon: 'custom-icon',
      rail: 'custom-rail',
    };

    const classNamesTargets: Record<ItemSemanticName, string> = {
      root: 'rc-steps-item',
      wrapper: 'rc-steps-item-wrapper',
      header: 'rc-steps-item-header',
      title: 'rc-steps-item-title',
      subtitle: 'rc-steps-item-subtitle',
      section: 'rc-steps-item-section',
      content: 'rc-steps-item-content',
      icon: 'rc-steps-item-icon',
      rail: 'rc-steps-item-rail',
    };

    const styles: Record<ItemSemanticName, Record<string, any>> = {
      root: { color: 'red' },
      wrapper: { color: 'green' },
      header: { color: 'orange' },
      title: { color: 'pink' },
      subtitle: { color: 'cyan' },
      section: { color: 'purple' },
      content: { color: 'magenta' },
      icon: { color: 'yellow' },
      rail: { color: 'lime' },
    };

    const { container } = render(
      renderSteps({
        items: Array.from({ length: 2 }, (_, index) => ({
          title: `Title ${index + 1}`,
          subTitle: `SubTitle ${index + 1}`,
          content: `Content ${index + 1}`,
          classNames,
          styles,
        })),
      }),
    );

    Object.keys(classNames).forEach((key) => {
      const className = classNames[key as SemanticName];
      const oriClassName = classNamesTargets[key as SemanticName];
      const style = styles[key as SemanticName];

      const element = container.querySelector<HTMLElement>(`.${className}`);
      expect(element).toBeTruthy();
      expect(element).toHaveClass(oriClassName);
      expect(element).toHaveStyle(style);
    });
  });
});


================================================
FILE: tests/setup.js
================================================
global.requestAnimationFrame = global.requestAnimationFrame || function raf(cb) {
  return setTimeout(cb, 0);
};


================================================
FILE: tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "esnext",
    "moduleResolution": "node",
    "baseUrl": "./",
    "jsx": "preserve",
    "declaration": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "paths": {
      "@/*": ["src/*"],
      "@@/*": ["dumi/tmp/*"],
      "@rc-component/steps": ["src/index.ts"]
    }
  }
}
Download .txt
gitextract_zrdxiemy/

├── .dumirc.ts
├── .editorconfig
├── .eslintrc.js
├── .fatherrc.ts
├── .github/
│   ├── dependabot.yml
│   └── workflows/
│       └── main.yml
├── .gitignore
├── .prettierrc
├── HISTORY.md
├── LICENSE.md
├── README.md
├── assets/
│   ├── custom-icon.less
│   ├── iconfont.less
│   ├── index.less
│   ├── inline.less
│   ├── label-placement.less
│   ├── nav.less
│   ├── progress-dot.less
│   ├── small.less
│   ├── variables.less
│   └── vertical.less
├── bunfig.toml
├── docs/
│   ├── demo/
│   │   ├── alternativeLabel.md
│   │   ├── composable.md
│   │   ├── custom-svg-icon.md
│   │   ├── customIcon.md
│   │   ├── dynamic.md
│   │   ├── errorStep.md
│   │   ├── inline.md
│   │   ├── nav-base.md
│   │   ├── nextStep.md
│   │   ├── progressDot.md
│   │   ├── simple.md
│   │   ├── smallSize.md
│   │   ├── stepIcon.md
│   │   ├── vertical.md
│   │   └── verticalSmall.md
│   ├── examples/
│   │   ├── alternativeLabel.jsx
│   │   ├── composable.jsx
│   │   ├── custom-svg-icon.jsx
│   │   ├── customIcon.jsx
│   │   ├── dynamic.jsx
│   │   ├── errorStep.jsx
│   │   ├── inline.jsx
│   │   ├── nav-base.jsx
│   │   ├── nextStep.css
│   │   ├── nextStep.jsx
│   │   ├── progressDot.jsx
│   │   ├── simple.jsx
│   │   ├── smallSize.jsx
│   │   ├── stepIcon.jsx
│   │   ├── vertical.jsx
│   │   └── verticalSmall.jsx
│   └── index.md
├── index.js
├── jest.config.js
├── package.json
├── script/
│   └── update-content.js
├── src/
│   ├── Context.ts
│   ├── Rail.tsx
│   ├── Step.tsx
│   ├── StepIcon.tsx
│   ├── Steps.tsx
│   ├── UnstableContext.ts
│   ├── index.ts
│   └── interface.ts
├── tests/
│   ├── __snapshots__/
│   │   └── index.test.tsx.snap
│   ├── index.test.tsx
│   ├── semantic.test.tsx
│   └── setup.js
└── tsconfig.json
Download .txt
SYMBOL INDEX (24 symbols across 9 files)

FILE: docs/examples/custom-svg-icon.jsx
  function getFinishIcon (line 6) | function getFinishIcon() {
  function getErrorIcon (line 31) | function getErrorIcon() {

FILE: docs/examples/nextStep.jsx
  function generateRandomSteps (line 7) | function generateRandomSteps() {
  class MyForm (line 19) | class MyForm extends React.Component {
    method render (line 35) | render() {

FILE: docs/examples/stepIcon.jsx
  function stepIcon (line 6) | function stepIcon({ status, node }) {

FILE: src/Context.ts
  type StepsContextProps (line 4) | interface StepsContextProps {

FILE: src/Rail.tsx
  type RailProps (line 5) | interface RailProps {
  function Rail (line 12) | function Rail(props: RailProps) {

FILE: src/Step.tsx
  function hasContent (line 11) | function hasContent<T>(value: T) {
  type StepProps (line 15) | interface StepProps {
  function Step (line 38) | function Step(props: StepProps) {

FILE: src/StepIcon.tsx
  type StepIconSemanticContextProps (line 6) | interface StepIconSemanticContextProps {
  type StepIconProps (line 13) | type StepIconProps = React.HTMLAttributes<HTMLDivElement>;

FILE: src/Steps.tsx
  type Status (line 8) | type Status = 'error' | 'process' | 'finish' | 'wait';
  type SemanticName (line 12) | type SemanticName =
  type ItemSemanticName (line 24) | type ItemSemanticName =
  type ComponentType (line 35) | type ComponentType = React.ComponentType<any> | string;
  type StepItem (line 37) | type StepItem = {
  type StepIconRender (line 50) | type StepIconRender = (info: {
  type RenderInfo (line 60) | type RenderInfo = {
  type StepsProps (line 66) | interface StepsProps {
  function Steps (line 106) | function Steps(props: StepsProps) {

FILE: src/UnstableContext.ts
  type UnstableContextProps (line 3) | interface UnstableContextProps {
Condensed preview — 71 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (116K chars).
[
  {
    "path": ".dumirc.ts",
    "chars": 416,
    "preview": "import { defineConfig } from 'dumi';\nimport path from 'path';\n\nexport default defineConfig({\n  alias: {\n    '@rc-compone"
  },
  {
    "path": ".editorconfig",
    "chars": 191,
    "preview": "# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines with a newline ending every file\n[*.{js,css}]\nend_of_lin"
  },
  {
    "path": ".eslintrc.js",
    "chars": 169,
    "preview": "const base = require('@umijs/fabric/dist/eslint');\n\nmodule.exports = {\n  ...base,\n  rules: {\n    ...base.rules,\n    'arr"
  },
  {
    "path": ".fatherrc.ts",
    "chars": 118,
    "preview": "import { defineConfig } from 'father';\n\nexport default defineConfig({\n  plugins: ['@rc-component/father-plugin'],\n});\n"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 400,
    "preview": "version: 2\nupdates:\n- package-ecosystem: npm\n  directory: \"/\"\n  schedule:\n    interval: daily\n    time: \"21:00\"\n  open-p"
  },
  {
    "path": ".github/workflows/main.yml",
    "chars": 138,
    "preview": "name: ✅ test\non: [push, pull_request]\njobs:\n  test:\n    uses: react-component/rc-test/.github/workflows/test.yml@main\n  "
  },
  {
    "path": ".gitignore",
    "chars": 326,
    "preview": ".iml\n*.log\n.idea/\n.ipr\n.iws\n*~\n~*\n*.diff\n*.patch\n*.bak\n.DS_Store\nThumbs.db\n.project\n.*proj\n.svn/\n*.swp\n*.swo\n*.pyc\n*.pyo"
  },
  {
    "path": ".prettierrc",
    "chars": 96,
    "preview": "{\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"proseWrap\": \"never\",\n  \"printWidth\": 100\n}"
  },
  {
    "path": "HISTORY.md",
    "chars": 1249,
    "preview": "# History\n----\n\n## 3.6.0\n\n- Remove babel-runtime and prop-types\n- Fix icon missing #85\n\n## 3.5.0\n\n- Support `navigation`"
  },
  {
    "path": "LICENSE.md",
    "chars": 1083,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014-present yiminghe\n\nPermission is hereby granted, free of charge, to any person "
  },
  {
    "path": "README.md",
    "chars": 4535,
    "preview": "# @rc-component/steps\n\n---\n\nReact steps component.\n\n[![NPM version][npm-image]][npm-url]\n[![build status][travis-image]]"
  },
  {
    "path": "assets/custom-icon.less",
    "chars": 436,
    "preview": "@import 'variables';\n\n.@{stepsPrefixClass}-item-custom {\n  .@{stepsPrefixClass}-item-icon {\n    background: none;\n    bo"
  },
  {
    "path": "assets/iconfont.less",
    "chars": 9287,
    "preview": "@icon-url               : \"//at.alicdn.com/t/font_1434092639_4910953\";\n.ie-rotate(@rotation) {\n  filter: progid:DXImageT"
  },
  {
    "path": "assets/index.less",
    "chars": 3946,
    "preview": "@import 'variables';\n\n.@{stepsPrefixClass} {\n  font-size: 0;\n  width: 100%;\n  line-height: 1.5;\n  display: flex;\n\n  &,\n "
  },
  {
    "path": "assets/inline.less",
    "chars": 1016,
    "preview": "@import 'variables';\n\n.@{stepsPrefixClass}-inline {\n  width: auto;\n  display: inline-flex;\n\n  .@{stepsPrefixClass}-item "
  },
  {
    "path": "assets/label-placement.less",
    "chars": 465,
    "preview": "@import 'variables';\n\n.@{stepsPrefixClass}-label-vertical {\n  .@{stepsPrefixClass}-item {\n    overflow: visible;\n    &-s"
  },
  {
    "path": "assets/nav.less",
    "chars": 938,
    "preview": "@import 'variables';\n\n.@{stepsPrefixClass}-navigation {\n  padding-top: 8px;\n  &.@{stepsPrefixClass}-horizontal {\n    .@{"
  },
  {
    "path": "assets/progress-dot.less",
    "chars": 554,
    "preview": "@import 'variables';\n\n.@{stepsPrefixClass}-dot {\n  .@{stepsPrefixClass}-item {\n    &-icon {\n      padding-right: 0;\n    "
  },
  {
    "path": "assets/small.less",
    "chars": 965,
    "preview": "@import 'variables';\n\n.@{stepsPrefixClass}-small {\n  .@{stepsPrefixClass}-item-icon {\n    width: 18px;\n    height: 18px;"
  },
  {
    "path": "assets/variables.less",
    "chars": 740,
    "preview": "@stepsPrefixClass: ~\"rc-steps\";\n@stepDescriptionMaxWidth: 100px;\n@stepNavContentMaxWidth: 140px;\n@primary-color: #108ee9"
  },
  {
    "path": "assets/vertical.less",
    "chars": 585,
    "preview": "@import 'variables';\n\n.@{stepsPrefixClass}-vertical {\n  display: block;\n  .@{stepsPrefixClass}-item {\n    display: block"
  },
  {
    "path": "bunfig.toml",
    "chars": 22,
    "preview": "[install]\npeer = false"
  },
  {
    "path": "docs/demo/alternativeLabel.md",
    "chars": 119,
    "preview": "---\ntitle: alternativeLabel\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/alternativeLabel.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/composable.md",
    "chars": 107,
    "preview": "---\ntitle: composable\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/composable.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/custom-svg-icon.md",
    "chars": 117,
    "preview": "---\ntitle: custom-svg-icon\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/custom-svg-icon.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/customIcon.md",
    "chars": 107,
    "preview": "---\ntitle: customIcon\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/customIcon.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/dynamic.md",
    "chars": 101,
    "preview": "---\ntitle: dynamic\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/dynamic.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/errorStep.md",
    "chars": 105,
    "preview": "---\ntitle: errorStep\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/errorStep.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/inline.md",
    "chars": 99,
    "preview": "---\ntitle: inline\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/inline.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/nav-base.md",
    "chars": 103,
    "preview": "---\ntitle: nav-base\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/nav-base.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/nextStep.md",
    "chars": 103,
    "preview": "---\ntitle: nextStep\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/nextStep.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/progressDot.md",
    "chars": 109,
    "preview": "---\ntitle: progressDot\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/progressDot.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/simple.md",
    "chars": 99,
    "preview": "---\ntitle: simple\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/simple.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/smallSize.md",
    "chars": 105,
    "preview": "---\ntitle: smallSize\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/smallSize.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/stepIcon.md",
    "chars": 103,
    "preview": "---\ntitle: stepIcon\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/stepIcon.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/vertical.md",
    "chars": 103,
    "preview": "---\ntitle: vertical\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/vertical.jsx\"></code>\n"
  },
  {
    "path": "docs/demo/verticalSmall.md",
    "chars": 113,
    "preview": "---\ntitle: verticalSmall\nnav:\n  title: Demo\n  path: /demo\n---\n\n<code src=\"../examples/verticalSmall.jsx\"></code>\n"
  },
  {
    "path": "docs/examples/alternativeLabel.jsx",
    "chars": 763,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/composable.jsx",
    "chars": 586,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/custom-svg-icon.jsx",
    "chars": 2690,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/customIcon.jsx",
    "chars": 464,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/dynamic.jsx",
    "chars": 968,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React, { useState } from 'react';\nimport S"
  },
  {
    "path": "docs/examples/errorStep.jsx",
    "chars": 552,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/inline.jsx",
    "chars": 936,
    "preview": "import '../../assets/index.less';\nimport React, { useState } from 'react';\nimport Steps from '@rc-component/steps';\n\nexp"
  },
  {
    "path": "docs/examples/nav-base.jsx",
    "chars": 1651,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React, { useState } from 'react';\nimport S"
  },
  {
    "path": "docs/examples/nextStep.css",
    "chars": 118,
    "preview": ".my-step-form {\n  width: 100%;\n}\n.my-step-form > div {\n  margin-bottom: 20px;\n}\n.my-step-container {\n  width: 100%;\n}\n"
  },
  {
    "path": "docs/examples/nextStep.jsx",
    "chars": 1416,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport './nextStep.css';\nimport React from 'react"
  },
  {
    "path": "docs/examples/progressDot.jsx",
    "chars": 626,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/simple.jsx",
    "chars": 1863,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/smallSize.jsx",
    "chars": 939,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/stepIcon.jsx",
    "chars": 929,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/vertical.jsx",
    "chars": 542,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/examples/verticalSmall.jsx",
    "chars": 559,
    "preview": "import '../../assets/index.less';\nimport '../../assets/iconfont.less';\nimport React from 'react';\nimport Steps from '@rc"
  },
  {
    "path": "docs/index.md",
    "chars": 118,
    "preview": "---\nhero:\n  title: \"@rc-component/steps\"\n  description: React Steps Component\n---\n\n<embed src=\"../README.md\"></embed>\n"
  },
  {
    "path": "index.js",
    "chars": 50,
    "preview": "'use strict';\n\nmodule.exports = require('./src/');"
  },
  {
    "path": "jest.config.js",
    "chars": 57,
    "preview": "module.exports = {\n  setupFiles: ['./tests/setup.js'],\n};"
  },
  {
    "path": "package.json",
    "chars": 2332,
    "preview": "{\n  \"name\": \"@rc-component/steps\",\n  \"version\": \"1.2.2\",\n  \"description\": \"steps ui component for react\",\n  \"keywords\": "
  },
  {
    "path": "script/update-content.js",
    "chars": 573,
    "preview": "/*\n  用于 dumi 改造使用,\n  可用于将 examples 的文件批量修改为 demo 引入形式,\n  其他项目根据具体情况使用。\n*/\n\nconst fs = require('fs');\nconst glob = requir"
  },
  {
    "path": "src/Context.ts",
    "chars": 357,
    "preview": "import * as React from 'react';\nimport type { ComponentType, StepsProps } from './Steps';\n\nexport interface StepsContext"
  },
  {
    "path": "src/Rail.tsx",
    "chars": 536,
    "preview": "import * as React from 'react';\nimport { clsx } from 'clsx';\nimport type { Status } from './Steps';\n\nexport interface Ra"
  },
  {
    "path": "src/Step.tsx",
    "chars": 5989,
    "preview": "/* eslint react/prop-types: 0 */\nimport * as React from 'react';\nimport { clsx } from 'clsx';\nimport KeyCode from '@rc-c"
  },
  {
    "path": "src/StepIcon.tsx",
    "chars": 1085,
    "preview": "import * as React from 'react';\nimport { clsx } from 'clsx';\nimport { StepsContext } from './Context';\nimport pickAttrs "
  },
  {
    "path": "src/Steps.tsx",
    "chars": 6054,
    "preview": "/* eslint react/no-did-mount-set-state: 0, react/prop-types: 0 */\nimport { clsx } from 'clsx';\nimport React from 'react'"
  },
  {
    "path": "src/UnstableContext.ts",
    "chars": 282,
    "preview": "import * as React from 'react';\n\nexport interface UnstableContextProps {\n  /**\n   * Used for Timeline component `reverse"
  },
  {
    "path": "src/index.ts",
    "chars": 198,
    "preview": "import Steps, { type StepsProps } from './Steps';\nimport Step from './Step';\n\nexport { Step };\nexport type { StepsProps "
  },
  {
    "path": "src/interface.ts",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "tests/__snapshots__/index.test.tsx.snap",
    "chars": 27338,
    "preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Steps components 1`] = `\n<ol\n  class=\"rc-steps rc-steps-horizontal "
  },
  {
    "path": "tests/index.test.tsx",
    "chars": 9290,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport Steps from '../src';\n\ndesc"
  },
  {
    "path": "tests/semantic.test.tsx",
    "chars": 4353,
    "preview": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport Steps, { type StepsProps } from '../s"
  },
  {
    "path": "tests/setup.js",
    "chars": 113,
    "preview": "global.requestAnimationFrame = global.requestAnimationFrame || function raf(cb) {\n  return setTimeout(cb, 0);\n};\n"
  },
  {
    "path": "tsconfig.json",
    "chars": 331,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"baseUrl\": \"./\",\n    \"jsx\": \"preser"
  }
]

About this extraction

This page contains the full source code of the react-component/steps GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 71 files (101.5 KB), approximately 30.3k tokens, and a symbol index with 24 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!