Browse Source

新增指示器组件 (#900)

* feat(indicator): 增加指示器组件
senyawang 4 years ago
parent
commit
8ed3699b64

+ 11 - 0
src/config.json

@@ -589,6 +589,17 @@
           "author": "richard1015"
         },
         {
+          "version": "3.0.0",
+          "name": "Indicator",
+          "type": "component",
+          "cName": "指示器",
+          "desc": "显示一个任务或流程的进度,常用语开通流程。",
+          "sort": 11,
+          "taro": true,
+          "show": true,
+          "author": "senyawang"
+        },
+        {
           "version": "3.1.13",
           "name": "Grid",
           "type": "component",

+ 32 - 0
src/packages/__VUE/indicator/__tests__/indicator.spec.ts

@@ -0,0 +1,32 @@
+import { shallowMount } from '@vue/test-utils';
+import Indicator from '../index.vue';
+test('test size && current', async () => {
+  const wrapper = shallowMount(Indicator, {
+    props: {
+      size: 5,
+      current: 3
+    }
+  });
+
+  expect(wrapper.findAll('.nut-indicator--dot').length).toBe(4);
+  expect(wrapper.findAll('.nut-indicator--number').length).toBe(1);
+  const number = wrapper.find(':nth-of-type(3)');
+  expect(number.classes()).toContain('nut-indicator--number');
+});
+test('test block && align && fillZero', () => {
+  const wrapper = shallowMount(Indicator, {
+    props: {
+      size: 5,
+      current: 3,
+      block: true,
+      align: 'right',
+      fillZero: true
+    }
+  });
+
+  const indicator = wrapper.find('.nut-indicator');
+  expect(indicator.classes()).toContain('nut-indicator--block');
+  expect(indicator.classes()).toContain('nut-indicator--align__right');
+  const firstChild = wrapper.findAll('.nut-indicator--number')[0];
+  expect(firstChild.text()).toBe('03');
+});

+ 45 - 0
src/packages/__VUE/indicator/demo.vue

@@ -0,0 +1,45 @@
+<template>
+  <div class="demo">
+    <h2>基础用法</h2>
+    <nut-cell>
+      <nut-indicator :size="3" :current="3">step1</nut-indicator>
+    </nut-cell>
+    <nut-cell>
+      <nut-row>
+        <nut-col :span="12">
+          <nut-button size="small" type="primary">主要按钮</nut-button>
+        </nut-col>
+        <nut-col :span="12">
+          <nut-indicator :block="true" align="right" :size="6" :current="5">step1</nut-indicator>
+        </nut-col>
+      </nut-row>
+    </nut-cell>
+    <h2>block用法</h2>
+    <nut-cell>
+      <nut-indicator :block="true" algin="center" :size="6" :current="5">step1</nut-indicator>
+    </nut-cell>
+    <nut-cell>
+      <nut-indicator :block="true" align="left" :size="6" :current="1">step1</nut-indicator>
+    </nut-cell>
+    <nut-cell>
+      <nut-indicator :block="true" align="right" :size="6" :current="5">step1</nut-indicator>
+    </nut-cell>
+    <h2>不补0</h2>
+    <nut-cell>
+      <nut-indicator :fill-zero="false" :size="6" :current="5">step1</nut-indicator>
+    </nut-cell>
+  </div>
+</template>
+
+<script lang="ts">
+import { createComponent } from '../../utils/create';
+const { createDemo } = createComponent('Indicator');
+export default createDemo({
+  props: {},
+  setup() {
+    return {};
+  }
+});
+</script>
+
+<style lang="scss" scoped></style>

+ 71 - 0
src/packages/__VUE/indicator/doc.md

@@ -0,0 +1,71 @@
+# Indicator组件
+
+### 介绍
+
+显示一个任务或流程的进度,常用语开通流程。
+
+### 安装
+
+```javascript
+import { createApp } from 'vue';
+// vue
+import { Indicator } from '@nutui/nutui'
+// taro
+import { Indicator } from '@nutui/nutui-taro'
+
+const app = createApp();
+
+app.use(Indicator);
+
+```
+
+### 基础用法
+
+```html
+  <nut-cell>
+    <nut-indicator :size="3" :current="3">step1</nut-indicator>
+  </nut-cell>
+  <nut-cell>
+    <nut-row>
+      <nut-col :span="12">
+        <nut-button size="small" type="primary">主要按钮</nut-button>
+      </nut-col>
+      <nut-col :span="12">
+        <nut-indicator :block="true" align="right" :size="6" :current="5">step1</nut-indicator>
+      </nut-col>
+    </nut-row>
+  </nut-cell>
+```
+
+### block用法
+```html
+    <nut-cell>
+      <nut-indicator :block="true" algin="center" :size="6" :current="5">step1</nut-indicator>
+    </nut-cell>
+    <nut-cell>
+      <nut-indicator :block="true" align="left" :size="6" :current="1">step1</nut-indicator>
+    </nut-cell>
+    <nut-cell>
+      <nut-indicator :block="true" align="right" :size="6" :current="5">step1</nut-indicator>
+    </nut-cell>
+```
+
+### 不补0
+```html
+    <nut-cell>
+      <nut-indicator :fill-zero="false" :size="6" :current="5">step1</nut-indicator>
+    </nut-cell>
+```
+
+
+## API
+
+### Props
+
+| 参数         | 说明                             | 类型   | 默认值           |
+|--------------|----------------------------------|--------|------------------|
+| current  | 当前步骤               | Number | 1              |
+| size       | 步骤长度                         | Number | 3               |
+| block | 是否启用块级布局     | Boolean | false |
+| align | 对齐方式,仅在block为true时生效, 可选值 'left', 'right', 'center'| String | left |
+| fill-zero     | 单数前面是否补0                      | Boolean | true        |

+ 48 - 0
src/packages/__VUE/indicator/index.scss

@@ -0,0 +1,48 @@
+.nut-indicator {
+  &--block {
+    display: block;
+    width: 100%;
+  }
+  &--align__left {
+    text-align: left;
+  }
+  &--align__right {
+    text-align: right;
+  }
+  &--align__center {
+    text-align: center;
+  }
+  &--dot,
+  &--number {
+    margin: 0 4px;
+    &:first-child {
+      margin-left: 0;
+    }
+    &:last-child {
+      margin-right: 0;
+    }
+  }
+  &--dot {
+    display: inline-block;
+    vertical-align: middle;
+    width: $indicator-dot-size;
+    height: $indicator-dot-size;
+    border-radius: 50%;
+    background-color: $indicator-dot-color;
+  }
+  &--number {
+    display: inline-block;
+    position: relative;
+    width: $indicator-size;
+    height: $indicator-size;
+    text-align: center;
+    font-size: 10px;
+    line-height: $indicator-size;
+    color: $indicator-white;
+    vertical-align: middle;
+    border: 1px solid $indicator-white;
+    border-radius: 50%;
+    background-color: $indicator-color;
+    box-shadow: 0 0 1px 1px $indicator-color;
+  }
+}

+ 58 - 0
src/packages/__VUE/indicator/index.taro.vue

@@ -0,0 +1,58 @@
+<template>
+  <view :class="classes">
+    <template v-for="item in size" :key="item">
+      <view v-if="item === current" :class="`${componentName}--number`">
+        {{ fillZero && item < 10 ? `0${item}` : item }}
+      </view>
+      <view v-else :class="`${componentName}--dot`"></view>
+    </template>
+  </view>
+</template>
+<script lang="ts">
+import Taro from '@tarojs/taro';
+
+import { toRefs, computed } from 'vue';
+import { createComponent } from '../../utils/create';
+const { componentName, create } = createComponent('indicator');
+
+export default create({
+  props: {
+    size: {
+      type: Number,
+      default: 3,
+      required: true
+    },
+    current: {
+      type: Number,
+      default: 1,
+      required: true
+    },
+    block: {
+      type: Boolean,
+      default: false
+    },
+    align: {
+      type: String,
+      default: 'center'
+    },
+    fillZero: {
+      type: Boolean,
+      default: true
+    }
+  },
+  setup(props) {
+    const { block, align } = toRefs(props);
+
+    const classes = computed(() => {
+      const prefixCls = componentName;
+      return {
+        [prefixCls]: true,
+        [`${prefixCls}--block`]: block.value,
+        [`${prefixCls}--align__${align.value}`]: block.value && align.value
+      };
+    });
+
+    return { classes, componentName };
+  }
+});
+</script>

+ 56 - 0
src/packages/__VUE/indicator/index.vue

@@ -0,0 +1,56 @@
+<template>
+  <view :class="classes">
+    <template v-for="item in size" :key="item">
+      <view v-if="item === current" :class="`${componentName}--number`">
+        {{ fillZero && item < 10 ? `0${item}` : item }}
+      </view>
+      <view v-else :class="`${componentName}--dot`"></view>
+    </template>
+  </view>
+</template>
+<script lang="ts">
+import { toRefs, computed } from 'vue';
+import { createComponent } from '../../utils/create';
+const { componentName, create } = createComponent('indicator');
+
+export default create({
+  props: {
+    size: {
+      type: Number,
+      default: 3,
+      required: true
+    },
+    current: {
+      type: Number,
+      default: 1,
+      required: true
+    },
+    block: {
+      type: Boolean,
+      default: false
+    },
+    align: {
+      type: String,
+      default: 'center'
+    },
+    fillZero: {
+      type: Boolean,
+      default: true
+    }
+  },
+  setup(props) {
+    const { block, align } = toRefs(props);
+
+    const classes = computed(() => {
+      const prefixCls = componentName;
+      return {
+        [prefixCls]: true,
+        [`${prefixCls}--block`]: block.value,
+        [`${prefixCls}--align__${align.value}`]: block.value && align.value
+      };
+    });
+
+    return { classes, componentName };
+  }
+});
+</script>

+ 8 - 0
src/packages/styles/variables.scss

@@ -368,6 +368,14 @@ $tabs-vertical-titles-item-height: 40px !default;
 $tabs-vertical-titles-item-active-line-height: 14px !default;
 $tabs-vertical-titles-width: 100px !default;
 
+// indicator
+$indicator-color: $primary-color !default;
+$indicator-dot-color: $disable-color !default;
+$indicator-white: $white !default;
+$indicator-size: 18px !default;
+$indicator-dot-size: $indicator-size / 3 !default;
+$indicator-border-size: $indicator-size + 2 !default;
+
 // menu
 $nut-menu-bar-line-height: 46px !default;
 $nut-menu-bar-border-bottom-color: #eaf0fb !default;

+ 1 - 0
src/sites/mobile-taro/vue/package.json

@@ -38,6 +38,7 @@
     "@babel/runtime": "^7.7.7",
     "@nutui/nutui-taro": "^3.0.2",
     "@tarojs/components": "^3.3.0-alpha.8",
+    "@tarojs/mini-runner": "^3.3.16",
     "@tarojs/runtime": "^3.3.0-alpha.8",
     "@tarojs/taro": "^3.3.0-alpha.8",
     "vue": "^3.0.0"

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

@@ -50,6 +50,7 @@ export default {
         'pages/elevator/index',
         'pages/menu/index',
         'pages/pagination/index',
+        'pages/indicator/index',
         'pages/grid/index'
       ]
     },

+ 3 - 0
src/sites/mobile-taro/vue/src/nav/pages/indicator/index.config.ts

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

+ 34 - 0
src/sites/mobile-taro/vue/src/nav/pages/indicator/index.vue

@@ -0,0 +1,34 @@
+<template>
+  <div class="demo">
+    <h2>基础用法</h2>
+    <nut-cell>
+      <nut-indicator :size="3" :current="3">step1</nut-indicator>
+    </nut-cell>
+    <nut-cell>
+      <nut-row>
+        <nut-col :span="12">
+          <nut-button size="small" type="primary">主要按钮</nut-button>
+        </nut-col>
+        <nut-col :span="12">
+          <nut-indicator :block="true" align="right" :size="6" :current="5">step1</nut-indicator>
+        </nut-col>
+      </nut-row>
+    </nut-cell>
+    <h2>block用法</h2>
+    <nut-cell>
+      <nut-indicator :block="true" algin="center" :size="6" :current="5">step1</nut-indicator>
+    </nut-cell>
+    <nut-cell>
+      <nut-indicator :block="true" align="left" :size="6" :current="1">step1</nut-indicator>
+    </nut-cell>
+    <nut-cell>
+      <nut-indicator :block="true" align="right" :size="6" :current="5">step1</nut-indicator>
+    </nut-cell>
+    <h2>不补0</h2>
+    <nut-cell>
+      <nut-indicator :fillZero="false" :size="6" :current="5">step1</nut-indicator>
+    </nut-cell>
+  </div>
+</template>
+
+<script lang="ts"></script>