diff --git a/src-next/progress/README.md b/src-next/progress/README.md
new file mode 100644
index 000000000..a03e5b158
--- /dev/null
+++ b/src-next/progress/README.md
@@ -0,0 +1,63 @@
+# Progress
+
+### Install
+
+```js
+import Vue from 'vue';
+import { Progress } from 'vant';
+
+Vue.use(Progress);
+```
+
+## Usage
+
+### Basic Usage
+
+Use 'percentage' prop to set current progress
+
+```html
+
+```
+
+### Stroke Width
+
+```html
+
+```
+
+### Inactive
+
+```html
+
+```
+
+### Custom Style
+
+Use `pivot-text` to custom text,use `color` to custom bar color
+
+```html
+
+
+
+```
+
+## API
+
+### Props
+
+| Attribute | Description | Type | Default |
+| --- | --- | --- | --- |
+| percentage | Percentage | _number \| string_ | `0` |
+| stroke-width `v2.2.1` | Stroke width | _number \| string_ | `4px` |
+| color | Color | _string_ | `#1989fa` |
+| track-color `v2.2.9` | Track color | _string_ | `#e5e5e5` |
+| pivot-text | Pivot text | _string_ | percentage |
+| pivot-color | Pivot text background color | _string_ | inherit progress color |
+| text-color | Pivot text color | _string_ | `white` |
+| inactive | Whether to be gray | _boolean_ | `false` |
+| show-pivot | Whether to show text | _boolean_ | `true` |
diff --git a/src-next/progress/README.zh-CN.md b/src-next/progress/README.zh-CN.md
new file mode 100644
index 000000000..856b9e8a1
--- /dev/null
+++ b/src-next/progress/README.zh-CN.md
@@ -0,0 +1,67 @@
+# Progress 进度条
+
+### 引入
+
+```js
+import Vue from 'vue';
+import { Progress } from 'vant';
+
+Vue.use(Progress);
+```
+
+## 代码演示
+
+### 基础用法
+
+进度条默认为蓝色,使用`percentage`属性来设置当前进度
+
+```html
+
+```
+
+### 线条粗细
+
+通过`stroke-width`可以设置进度条的粗细
+
+```html
+
+```
+
+### 置灰
+
+设置`inactive`属性后进度条将置灰
+
+```html
+
+```
+
+### 样式定制
+
+可以使用`pivot-text`属性自定义文字,`color`属性自定义进度条颜色
+
+```html
+
+
+
+```
+
+## API
+
+### Props
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| percentage | 进度百分比 | _number \| string_ | `0` |
+| stroke-width `v2.2.1` | 进度条粗细,默认单位为`px` | _number \| string_ | `4px` |
+| color | 进度条颜色 | _string_ | `#1989fa` |
+| track-color `v2.2.9` | 轨道颜色 | _string_ | `#e5e5e5` |
+| pivot-text | 进度文字内容 | _string_ | 百分比 |
+| pivot-color | 进度文字背景色 | _string_ | 同进度条颜色 |
+| text-color | 进度文字颜色 | _string_ | `white` |
+| inactive | 是否置灰 | _boolean_ | `false` |
+| show-pivot | 是否显示进度文字 | _boolean_ | `true` |
diff --git a/src-next/progress/demo/index.vue b/src-next/progress/demo/index.vue
new file mode 100644
index 000000000..f07c9d46f
--- /dev/null
+++ b/src-next/progress/demo/index.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src-next/progress/index.js b/src-next/progress/index.js
new file mode 100644
index 000000000..f12ca19a9
--- /dev/null
+++ b/src-next/progress/index.js
@@ -0,0 +1,84 @@
+import { createNamespace, isDef, addUnit } from '../utils';
+
+const [createComponent, bem] = createNamespace('progress');
+
+export default createComponent({
+ props: {
+ color: String,
+ inactive: Boolean,
+ pivotText: String,
+ textColor: String,
+ pivotColor: String,
+ trackColor: String,
+ strokeWidth: [Number, String],
+ percentage: {
+ type: [Number, String],
+ required: true,
+ validator: (value) => value >= 0 && value <= 100,
+ },
+ showPivot: {
+ type: Boolean,
+ default: true,
+ },
+ },
+
+ data() {
+ return {
+ pivotWidth: 0,
+ progressWidth: 0,
+ };
+ },
+
+ mounted() {
+ this.setWidth();
+ },
+
+ watch: {
+ showPivot: 'setWidth',
+ pivotText: 'setWidth',
+ },
+
+ methods: {
+ setWidth() {
+ this.$nextTick(() => {
+ this.progressWidth = this.$el.offsetWidth;
+ this.pivotWidth = this.$refs.pivot ? this.$refs.pivot.offsetWidth : 0;
+ });
+ },
+ },
+
+ render() {
+ const { pivotText, percentage } = this;
+ const text = isDef(pivotText) ? pivotText : percentage + '%';
+ const showPivot = this.showPivot && text;
+ const background = this.inactive ? '#cacaca' : this.color;
+
+ const pivotStyle = {
+ color: this.textColor,
+ left: `${((this.progressWidth - this.pivotWidth) * percentage) / 100}px`,
+ background: this.pivotColor || background,
+ };
+
+ const portionStyle = {
+ background,
+ width: (this.progressWidth * percentage) / 100 + 'px',
+ };
+
+ const wrapperStyle = {
+ background: this.trackColor,
+ height: addUnit(this.strokeWidth),
+ };
+
+ return (
+
+
+ {showPivot && (
+
+ {text}
+
+ )}
+
+
+ );
+ },
+});
diff --git a/src-next/progress/index.less b/src-next/progress/index.less
new file mode 100644
index 000000000..984948680
--- /dev/null
+++ b/src-next/progress/index.less
@@ -0,0 +1,32 @@
+@import '../style/var';
+
+.van-progress {
+ position: relative;
+ height: @progress-height;
+ background: @progress-background-color;
+ border-radius: @progress-height;
+
+ &__portion {
+ position: absolute;
+ left: 0;
+ height: 100%;
+ background: @progress-color;
+ border-radius: inherit;
+ }
+
+ &__pivot {
+ position: absolute;
+ top: 50%;
+ box-sizing: border-box;
+ min-width: 3.6em;
+ padding: @progress-pivot-padding;
+ color: @progress-pivot-text-color;
+ font-size: @progress-pivot-font-size;
+ line-height: @progress-pivot-line-height;
+ text-align: center;
+ word-break: keep-all;
+ background-color: @progress-pivot-background-color;
+ border-radius: 1em;
+ transform: translate(0, -50%);
+ }
+}
diff --git a/src-next/progress/test/__snapshots__/demo.spec.js.snap b/src-next/progress/test/__snapshots__/demo.spec.js.snap
new file mode 100644
index 000000000..66c2e29a9
--- /dev/null
+++ b/src-next/progress/test/__snapshots__/demo.spec.js.snap
@@ -0,0 +1,20 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders demo correctly 1`] = `
+
+`;
diff --git a/src-next/progress/test/__snapshots__/index.spec.js.snap b/src-next/progress/test/__snapshots__/index.spec.js.snap
new file mode 100644
index 000000000..47201dd08
--- /dev/null
+++ b/src-next/progress/test/__snapshots__/index.spec.js.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`calc width 1`] = `
`;
+
+exports[`calc width 2`] = `test
`;
diff --git a/src-next/progress/test/demo.spec.js b/src-next/progress/test/demo.spec.js
new file mode 100644
index 000000000..5c70922b5
--- /dev/null
+++ b/src-next/progress/test/demo.spec.js
@@ -0,0 +1,4 @@
+import Demo from '../demo';
+import { snapshotDemo } from '../../../test/demo';
+
+snapshotDemo(Demo);
diff --git a/src-next/progress/test/index.spec.js b/src-next/progress/test/index.spec.js
new file mode 100644
index 000000000..252abf346
--- /dev/null
+++ b/src-next/progress/test/index.spec.js
@@ -0,0 +1,28 @@
+import Progress from '..';
+import { mount, later } from '../../../test';
+
+test('calc width', async () => {
+ const wrapper = mount(Progress, {
+ propsData: {
+ showPivot: false,
+ percentage: 100,
+ },
+ });
+ await later();
+ expect(wrapper).toMatchSnapshot();
+
+ wrapper.vm.showPivot = true;
+ wrapper.vm.pivotText = 'test';
+ await later();
+ expect(wrapper).toMatchSnapshot();
+});
+
+test('track color prop', async () => {
+ const wrapper = mount(Progress, {
+ propsData: {
+ trackColor: 'green',
+ },
+ });
+
+ expect(wrapper.element.style.background).toEqual('green');
+});
diff --git a/vant.config.js b/vant.config.js
index e81e090aa..5ee9aaf2c 100644
--- a/vant.config.js
+++ b/vant.config.js
@@ -257,10 +257,10 @@ module.exports = {
// path: 'notice-bar',
// title: 'NoticeBar 通知栏',
// },
- // {
- // path: 'progress',
- // title: 'Progress 进度条',
- // },
+ {
+ path: 'progress',
+ title: 'Progress 进度条',
+ },
{
path: 'skeleton',
title: 'Skeleton 骨架屏',
@@ -591,10 +591,10 @@ module.exports = {
// path: 'notice-bar',
// title: 'NoticeBar',
// },
- // {
- // path: 'progress',
- // title: 'Progress',
- // },
+ {
+ path: 'progress',
+ title: 'Progress',
+ },
{
path: 'skeleton',
title: 'Skeleton',