ソースを参照

feat: v3 progress taro适配 (#555)

* feat: progress 百分比不同尺寸样式增加
Drjingfubo 4 年 前
コミット
78a3f762aa

+ 11 - 0
src/config.json

@@ -419,6 +419,17 @@
           "show": true,
           "desc": "轻提示",
           "author": "undo"
+        },
+        {
+          "version": "3.0.0",
+          "name": "Progress",
+          "taro": true,
+          "sort": 8,
+          "cName": "进度条",
+          "type": "component",
+          "show": true,
+          "desc": "用来展示进度",
+          "author": "Drjingubo"
         }
       ]
     },

+ 127 - 0
src/packages/__VUE/progress/demo.vue

@@ -0,0 +1,127 @@
+<template>
+  <div class="demo full">
+    <h4>基本用法</h4>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="30" />
+      </nut-cell>
+    </div>
+
+    <p>线形进度条-设置颜色高度</p>
+    <div>
+      <nut-cell>
+        <nut-progress
+          percentage="30"
+          stroke-color=" rgba(250,44,25,0.47)"
+          stroke-width="20"
+          text-color="red"
+        />
+      </nut-cell>
+    </div>
+    <p>线形进度条-百分比不显示</p>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="50" :show-text="false" stroke-height="24" />
+      </nut-cell>
+    </div>
+    <p>线形进度条-百分比外显</p>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="30" />
+      </nut-cell>
+    </div>
+    <p>线形进度条-百分比内显</p>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="60" :text-inside="true" />
+      </nut-cell>
+    </div>
+    <p>线形进度条-自定义尺寸(内置"small","base","large"三种规格)</p>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="30" :text-inside="true" size="small">
+        </nut-progress>
+      </nut-cell>
+      <nut-cell>
+        <nut-progress percentage="50" :text-inside="true" size="base">
+        </nut-progress>
+      </nut-cell>
+      <nut-cell>
+        <nut-progress percentage="70" :text-inside="true" size="large">
+        </nut-progress>
+      </nut-cell>
+    </div>
+    <p>线形进度条-状态显示</p>
+    <div>
+      <nut-cell>
+        <nut-progress
+          percentage="30"
+          stroke-color="linear-gradient(270deg, rgba(18,126,255,1) 0%,rgba(32,147,255,1) 32.815625%,rgba(13,242,204,1) 100%)"
+          status="active"
+        />
+      </nut-cell>
+      <nut-cell>
+        <nut-progress
+          percentage="50"
+          :stroke-width="strokeWidth"
+          status="icon"
+        />
+      </nut-cell>
+      <nut-cell>
+        <nut-progress
+          percentage="100"
+          stroke-color="linear-gradient(90deg, rgba(180,236,81,1) 0%,rgba(66,147,33,1) 100%)"
+          stroke-width="15"
+          status="icon"
+          icon-name="issue"
+          icon-color="red"
+        />
+      </nut-cell>
+    </div>
+    <h4>设置百分比</h4>
+    <div>
+      <nut-cell>
+        <nut-progress :percentage="val" />
+      </nut-cell>
+      <nut-cell>
+        <nut-button type="default" @click="setReduceVal">减少</nut-button>
+        <nut-button type="danger" @click="setAddVal">增加</nut-button>
+      </nut-cell>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { ref } from 'vue';
+import { createComponent } from '../../utils/create';
+const { createDemo } = createComponent('progress');
+export default createDemo({
+  props: {},
+  setup() {
+    const val = ref(0);
+    const setAddVal = () => {
+      if (val.value >= 100) {
+        return false;
+      }
+      val.value += 10;
+    };
+    const setReduceVal = () => {
+      if (val.value <= 0) {
+        return false;
+      }
+      val.value -= 10;
+    };
+    return {
+      val,
+      setAddVal,
+      setReduceVal
+    };
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.nut-button {
+  margin-right: 10px;
+}
+</style>

+ 85 - 0
src/packages/__VUE/progress/doc.md

@@ -0,0 +1,85 @@
+# Progress 进度条
+
+### 介绍
+
+展示操作或任务的当前进度,比如上传文件。
+
+### 安装
+
+``` javascript
+import { createApp } from 'vue';
+//vue
+import { Progress } from '@nutui/nutui';
+//taro
+import { Progress } from '@nutui/nutui-taro';
+
+const app = createApp();
+app.use(Progress);
+
+```
+
+## 代码示例
+
+### 基础用法
+
+```html
+<nut-progress percentage="30"></nut-progress>
+```
+### 设置高度和颜色
+
+```html
+<nut-progress percentage="30" stroke-color="pink" stroke-width="20"></nut-progress>
+```
+### 设置百分比不显示
+
+```html
+<nut-progress percentage="50" :show-text="false"></nut-progress>
+```
+### 设置百分比外显
+
+```html
+<nut-progress percentage="60" :text-inside="false" stroke-height="24"></nut-progress>
+```
+
+### 设置百分比内显
+
+```html
+<nut-progress percentage="60" :text-inside="true" stroke-width="24"></nut-progress>
+```
+
+## 自定义尺寸
+
+内置 **small**,**base**,**large** 三种规格供使用。
+```html
+<nut-progress size="small" percentage="30" text-inside="true" ></nut-progress>
+<nut-progress size="base" percentage="50" text-inside="true"></nut-progress>
+<nut-progress size="large" percentage="70"  text-inside="true"></nut-progress>
+```
+### 设置状态显示
+
+```html
+//动态展示
+<nut-progress 
+   percentage="30" 
+   stroke-color="linear-gradient(270deg, rgba(18,126,255,1) 0%,rgba(32,147,255,1) 32.815625%,rgba(13,242,204,1) 100%)" 
+   status="active">
+</nut-progress>
+// 展示icon
+<nut-progress percentage="50" stroke-color="#f30" stroke-width="15" ></nut-progress>
+<nut-progress percentage="100" stroke-color="#1890ff" stroke-width="15" status="success"></nut-progress>
+```
+
+## Prop
+
+| 字段 | 说明 | 类型 | 默认值
+|----- | ----- | ----- | -----
+| percentage | 百分比 | Number | 0
+| stroke-color | 进度条背景色 | String | #f30
+| stroke-width | 进度条宽度 | String | ''
+| size | 进度条及文字尺寸,可选值small/base/large | String | -
+| show-text | 是否显示进度条文字内容 | Boolean | true
+| text-inside | 进度条文字显示位置(false:外显,true:内显) | Boolean | false
+| text-color | 进度条文字颜色设置 | String | #333
+| status | 进度条当前状态,active(展示动画效果)/icon(展示icon标签) | String | text
+| icon-name | icon名称 | String | checked
+| icon-color | icon颜色 | String | #439422

+ 103 - 0
src/packages/__VUE/progress/index.scss

@@ -0,0 +1,103 @@
+.nut-progress {
+  width: 100%;
+  position: relative;
+  display: flex;
+  .nut-progress-outer {
+    flex: 1;
+    background-color: #f3f3f3;
+    border-radius: 12px;
+    height: 10px;
+    .nut-progress-inner {
+      width: 30%;
+      height: 100%;
+      border-radius: 12px;
+      background: linear-gradient(
+        268deg,
+        rgba(250, 44, 25, 1) 0%,
+        rgba(250, 63, 25, 1) 44.59259259%,
+        rgba(250, 89, 25, 1) 83.40740741%,
+        rgba(250, 100, 25, 1) 100%
+      );
+      -webkit-transition: all 0.4s;
+      transition: all 0.4s;
+      position: relative;
+      .nut-progress-text {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        color: #fff;
+      }
+    }
+    .nut-active {
+      &:before {
+        content: '';
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        border-radius: 10px;
+        animation: progressActive 2s ease-in-out infinite;
+      }
+    }
+    @keyframes progressActive {
+      0% {
+        background: rgba(255, 255, 255, 0.1);
+        width: 0;
+      }
+      20% {
+        background: rgba(255, 255, 255, 0.5);
+        width: 0;
+      }
+      to {
+        background: rgba(255, 255, 255, 0);
+        width: 100%;
+      }
+    }
+    &.nut-progress-small {
+      height: 5px;
+      .nut-progress-text {
+        font-size: 7px;
+        line-height: 10px;
+        padding: 2px 4px;
+        top: -100%;
+      }
+    }
+    &.nut-progress-base {
+      height: 10px;
+      .nut-progress-text {
+        font-size: 9px;
+        line-height: 13px;
+      }
+    }
+    &.nut-progress-large {
+      height: 15px;
+      .nut-progress-text {
+        font-size: 13px;
+        line-height: 18px;
+      }
+    }
+  }
+  .nut-progress-outer-part {
+    width: 90%;
+  }
+  .nut-progress-text {
+    padding: 0 5px;
+    font-size: 13px;
+    line-height: 1;
+  }
+  .nut-progress-insidetext {
+    padding: 3px 5px 3px 6px;
+    background: rgba(250, 44, 25, 1);
+    border-radius: 5px;
+    position: absolute;
+    transition: all 0.4s;
+    top: -26%;
+  }
+  .nut-icon-success,
+  .nut-icon-fail {
+    width: 10px;
+    height: 10px;
+    display: inline-block;
+  }
+}

+ 152 - 0
src/packages/__VUE/progress/index.taro.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class="nut-progress">
+    <div
+      class="nut-progress-outer"
+      ref="progressOuter"
+      :class="[
+        showText && !textInside ? 'nut-progress-outer-part' : '',
+        size ? 'nut-progress-' + size : ''
+      ]"
+      :style="{ height: height }"
+    >
+      <div
+        :class="['nut-progress-inner', status == 'active' ? 'nut-active' : '']"
+        :style="bgStyle"
+      >
+        <div
+          class="nut-progress-text nut-progress-insidetext"
+          :style="{ lineHeight: height, left: left }"
+          v-if="showText && textInside"
+        >
+          <span :style="textStyle">{{ percentage }}%</span>
+        </div>
+      </div>
+    </div>
+    <div
+      class="nut-progress-text"
+      :style="{ lineHeight: height }"
+      v-if="showText && !textInside"
+    >
+      <template v-if="status == 'text' || status == 'active'">
+        <span :style="textStyle">{{ percentage }}%</span>
+      </template>
+      <template v-else-if="status == 'icon'">
+        <nut-icon size="16px" :name="iconName" :color="iconColor"></nut-icon>
+      </template>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import {
+  computed,
+  onMounted,
+  provide,
+  reactive,
+  nextTick,
+  ref,
+  getCurrentInstance,
+  watch
+} from 'vue';
+import { createComponent } from '../../utils/create';
+import Taro, { eventCenter } from '@tarojs/taro';
+const { create } = createComponent('progress');
+export default create({
+  props: {
+    percentage: {
+      type: [Number, String],
+      default: 0,
+      required: true
+    },
+    size: {
+      type: String,
+      default: 'base'
+    },
+    status: {
+      type: String,
+      default: 'text'
+    },
+    strokeWidth: {
+      type: [Number, String],
+      default: ''
+    },
+    textInside: {
+      type: Boolean,
+      default: false
+    },
+    showText: {
+      type: Boolean,
+      default: true
+    },
+    strokeColor: {
+      type: String,
+      default: ''
+    },
+    textColor: {
+      tyep: String,
+      default: ''
+    },
+    iconName: {
+      type: String,
+      default: 'checked'
+    },
+    iconColor: {
+      type: String,
+      default: '#439422'
+    }
+  },
+  setup(props, { emit }) {
+    const height = ref(props.strokeWidth + 'px');
+    const progressOuter = ref();
+    const left = ref();
+    const bgStyle = computed(() => {
+      return {
+        width: props.percentage + '%',
+        background: props.strokeColor || ''
+      };
+    });
+    const textStyle = computed(() => {
+      return {
+        color: props.textColor || ''
+      };
+    });
+    const slideLeft = async (values: String | Number) => {
+      if (Taro.getEnv() === 'WEB') {
+        left.value =
+          progressOuter.value.offsetWidth * Number(values) * 0.01 - 4 + 'px';
+      } else {
+        setTimeout(() => {
+          const query = (Taro.createSelectorQuery() as any).in(
+            getCurrentInstance
+          );
+          query
+            .select('.nut-progress-outer')
+            .boundingClientRect((rec: any) => {
+              left.value = rec.width * Number(values) * 0.01 - 4 + 'px';
+            })
+            .exec();
+        }, 200);
+      }
+    };
+    watch(
+      () => props.percentage,
+      (values) => {
+        slideLeft(values);
+      },
+      { immediate: true }
+    );
+    onMounted(() => {});
+    return {
+      height,
+      bgStyle,
+      textStyle,
+      progressOuter,
+      left
+    };
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>

+ 145 - 0
src/packages/__VUE/progress/index.vue

@@ -0,0 +1,145 @@
+<template>
+  <div class="nut-progress">
+    <div
+      class="nut-progress-outer"
+      ref="progressOuter"
+      :class="[
+        showText && !textInside ? 'nut-progress-outer-part' : '',
+        size ? 'nut-progress-' + size : ''
+      ]"
+      :style="{ height: height }"
+    >
+      <div
+        :class="['nut-progress-inner', status == 'active' ? 'nut-active' : '']"
+        :style="bgStyle"
+      >
+        <div
+          class="nut-progress-text nut-progress-insidetext"
+          :style="{ lineHeight: height, left: left }"
+          v-if="showText && textInside"
+        >
+          <span :style="textStyle">{{ percentage }}%</span>
+        </div>
+      </div>
+    </div>
+    <div
+      class="nut-progress-text"
+      :style="{ lineHeight: height }"
+      v-if="showText && !textInside"
+    >
+      <template v-if="status == 'active' || status == ''">
+        <span :style="textStyle">{{ percentage }}%</span>
+      </template>
+      <template v-else-if="status == 'icon'">
+        <nut-icon size="16px" :name="iconName" :color="iconColor"></nut-icon>
+      </template>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import {
+  computed,
+  onMounted,
+  provide,
+  reactive,
+  nextTick,
+  ref,
+  watch
+} from 'vue';
+import { createComponent } from '../../utils/create';
+const { create } = createComponent('progress');
+export default create({
+  props: {
+    percentage: {
+      type: [Number, String],
+      default: 0,
+      required: true
+    },
+    size: {
+      type: String,
+      default: 'base'
+    },
+    status: {
+      type: String,
+      default: ''
+    },
+    strokeWidth: {
+      type: [Number, String],
+      default: ''
+    },
+    textInside: {
+      type: Boolean,
+      default: false
+    },
+    showText: {
+      type: Boolean,
+      default: true
+    },
+    strokeColor: {
+      type: String,
+      default: ''
+    },
+    textColor: {
+      tyep: String,
+      default: ''
+    },
+    iconName: {
+      type: String,
+      default: 'checked'
+    },
+    iconColor: {
+      type: String,
+      default: '#439422'
+    }
+  },
+  setup(props, { emit }) {
+    const height = ref(props.strokeWidth + 'px');
+    const progressOuter = ref();
+    const left = ref();
+    const bgStyle = computed(() => {
+      return {
+        width: props.percentage + '%',
+        background: props.strokeColor || ''
+      };
+    });
+    const textStyle = computed(() => {
+      return {
+        color: props.textColor || ''
+      };
+    });
+
+    watch(
+      () => props.percentage,
+      (values) => {
+        console.log(
+          'progressOuter.value.offsetWidth',
+          progressOuter.value.offsetWidth
+        );
+
+        console.log('values', values);
+
+        left.value =
+          progressOuter.value.offsetWidth * Number(values) * 0.01 - 4 + 'px';
+      }
+    );
+    onMounted(() => {
+      left.value =
+        progressOuter.value.offsetWidth * Number(props.percentage) * 0.01 -
+        4 +
+        'px';
+    });
+    return {
+      height,
+      bgStyle,
+      textStyle,
+      progressOuter,
+      left
+    };
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>

+ 2 - 1
src/sites/mobile-taro/vue/src/app.config.ts

@@ -18,7 +18,8 @@ export default {
         'pages/swiper/index',
         'pages/drag/index',
         'pages/steps/index',
-        'pages/infiniteloading/index'
+        'pages/infiniteloading/index',
+        'pages/progress/index'
       ]
     },
     {

+ 3 - 0
src/sites/mobile-taro/vue/src/feedback/pages/progress/index.config.ts

@@ -0,0 +1,3 @@
+export default {
+  navigationBarTitleText: 'Progress'
+};

+ 123 - 0
src/sites/mobile-taro/vue/src/feedback/pages/progress/index.vue

@@ -0,0 +1,123 @@
+<template>
+  <div class="demo full">
+    <h4>基本用法</h4>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="30" />
+      </nut-cell>
+    </div>
+
+    <p>线形进度条-设置颜色高度</p>
+    <div>
+      <nut-cell>
+        <nut-progress
+          percentage="30"
+          stroke-color=" rgba(250,44,25,0.47)"
+          stroke-width="20"
+          text-color="red"
+        />
+      </nut-cell>
+    </div>
+    <p>线形进度条-百分比不显示</p>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="50" :show-text="false" stroke-height="24" />
+      </nut-cell>
+    </div>
+    <p>线形进度条-百分比外显</p>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="30" />
+      </nut-cell>
+    </div>
+    <p>线形进度条-百分比内显</p>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="60" :text-inside="true" />
+      </nut-cell>
+    </div>
+    <p>线形进度条-自定义尺寸(内置"small","base","large"三种规格)</p>
+    <div>
+      <nut-cell>
+        <nut-progress percentage="30" size="small"> </nut-progress>
+      </nut-cell>
+      <nut-cell>
+        <nut-progress percentage="50" :text-inside="true" size="base">
+        </nut-progress>
+      </nut-cell>
+      <nut-cell>
+        <nut-progress percentage="70" size="large"> </nut-progress>
+      </nut-cell>
+    </div>
+    <p>线形进度条-状态显示</p>
+    <div>
+      <nut-cell>
+        <nut-progress
+          percentage="30"
+          stroke-color="linear-gradient(270deg, rgba(18,126,255,1) 0%,rgba(32,147,255,1) 32.815625%,rgba(13,242,204,1) 100%)"
+          status="active"
+        />
+      </nut-cell>
+      <nut-cell>
+        <nut-progress
+          percentage="50"
+          :stroke-width="strokeWidth"
+          status="wrong"
+        />
+      </nut-cell>
+      <nut-cell>
+        <nut-progress
+          percentage="100"
+          stroke-color="linear-gradient(90deg, rgba(180,236,81,1) 0%,rgba(66,147,33,1) 100%)"
+          stroke-width="15"
+          status="success"
+          icon-name="issue"
+          icon-color="red"
+        />
+      </nut-cell>
+    </div>
+    <h4>设置百分比</h4>
+    <div>
+      <nut-cell>
+        <nut-progress :percentage="val" />
+      </nut-cell>
+      <nut-cell>
+        <nut-button type="default" @click="setReduceVal">减少</nut-button>
+        <nut-button type="danger" @click="setAddVal">增加</nut-button>
+      </nut-cell>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { ref } from 'vue';
+export default {
+  props: {},
+  setup() {
+    const val = ref(0);
+    const setAddVal = () => {
+      if (val.value >= 100) {
+        return false;
+      }
+      val.value += 10;
+    };
+    const setReduceVal = () => {
+      if (val.value <= 0) {
+        return false;
+      }
+      val.value -= 10;
+    };
+    return {
+      val,
+      setAddVal,
+      setReduceVal
+    };
+  }
+};
+</script>
+
+<style lang="scss">
+.nut-button {
+  margin-right: 10px;
+}
+</style>