Browse Source

Merge branch 'next' of https://github.com/jdf2e/nutui into next

Drjnigfubo 3 years ago
parent
commit
09228f8143

+ 1 - 1
src/packages/__VUE/form/common.ts

@@ -87,7 +87,7 @@ export const component = {
         const { required, validator, regex, message } = _rules.shift() as FormItemRule;
         const errorMsg = { prop, message };
         if (required) {
-          if (!value) {
+          if (value === '' || value === undefined || value === null) {
             return _Promise(errorMsg);
           }
         }

+ 3 - 2
src/packages/__VUE/icon/demo.vue

@@ -80,14 +80,15 @@ export default createDemo({
   setup() {
     initTranslate();
     const copyTag = (name: string) => {
-      const text = `<nut-icon name="${name}"></nut-icon>`;
+      const text = `<nut-icon name="${name}"></nut-icon>`;
+      const displayText = `&lt;nut-icon name="${name}"&gt;&lt;/nut-icon&gt;`;
       const input = document.createElement('input');
       document.body.appendChild(input);
       input.setAttribute('value', text);
       input.select();
       if (document.execCommand('copy')) {
         document.execCommand('copy');
-        Toast.text(`${translate('copyToast')}: <br/>${text}`);
+        Toast.text(`${translate('copyToast')}: <br/>${displayText}`);
       }
       document.body.removeChild(input);
     };

+ 16 - 0
src/packages/__VUE/inputnumber/__tests__/index.spec.ts

@@ -163,3 +163,19 @@ test('should update input value when inputValue overlimit', async () => {
 
   expect((wrapper.emitted('update:modelValue')![0] as any[])[0]).toEqual('100');
 });
+
+test('should render icon when iconLeft and iconRight props setted', async () => {
+  const wrapper = mount(InputNumber, {
+    props: {
+      iconLeft: 'left',
+      iconRight: 'right',
+      fontClassName: 'n-nutui-iconfont',
+      classPrefix: 'n-nut-icon'
+    }
+  });
+
+  const iconList = wrapper.findAll('.nut-icon');
+  expect(iconList.length).toBe(2);
+  expect(iconList[0].html()).toContain('n-nut-icon-left');
+  expect(iconList[1].html()).toContain('n-nut-icon-right');
+});

+ 10 - 3
src/packages/__VUE/inputnumber/demo.vue

@@ -24,7 +24,7 @@
     <nut-cell>
       <nut-inputnumber v-model="state.val6" step="0.1" decimal-places="1" readonly />
     </nut-cell>
-    <h2>{{ translate('asyc') }}</h2>
+    <h2>{{ translate('async') }}</h2>
     <nut-cell>
       <nut-inputnumber :model-value="state.val8" @change="onChange" />
     </nut-cell>
@@ -32,6 +32,10 @@
     <nut-cell>
       <nut-inputnumber v-model="state.val7" button-size="30" input-width="50" />
     </nut-cell>
+    <h2>{{ translate('icon') }}</h2>
+    <nut-cell>
+      <nut-inputnumber icon-left="left" icon-right="right" v-model="state.val9" />
+    </nut-cell>
   </div>
 </template>
 
@@ -49,8 +53,9 @@ const initTranslate = () =>
       disable: '禁用操作',
       readonly: '只读禁用输入框',
       decimal: '支持小数',
-      asyn: '支持异步修改',
+      async: '支持异步修改',
       size: '自定义按钮大小',
+      icon: '自定义图标',
       content1: '异步演示 2 秒后更改',
       content2: '超出限制事件触发'
     },
@@ -61,8 +66,9 @@ const initTranslate = () =>
       disable: 'Disable operation',
       readonly: 'Read only disable input box',
       decimal: 'Support decimal',
-      asyc: 'Support asynchronous modification',
+      async: 'Support asynchronous modification',
       size: 'Custom button size',
+      icon: 'Custom icon name',
       content1: 'Asynchronous presentation changes in 2 seconds',
       content2: 'Trigger of limit exceeding event'
     }
@@ -82,6 +88,7 @@ export default createDemo({
       val6: 5.5,
       val7: 1,
       val8: 1,
+      val9: 1,
       step: 1.1
     });
 

+ 25 - 0
src/packages/__VUE/inputnumber/doc.en-US.md

@@ -216,6 +216,27 @@ Asynchronous modification through `change` event and `model-value`
 ```
 
 :::
+### Custsom icon name 
+
+:::demo
+
+```html
+<template>
+  <nut-inputnumber icon-left="left" icon-right="right" v-model="value" />
+</template>
+<script lang="ts">
+  import { ref } from 'vue';
+  export default {
+    props: {},
+    setup() {
+      const value = ref(1);
+      return { value };
+    },
+  };
+</script>
+```
+
+:::
 
 ## API
 
@@ -232,6 +253,10 @@ Asynchronous modification through `change` event and `model-value`
 | decimal-places | Set reserved decimal places           | String、Number | `0`        |
 | disabled       | Disable all features               | Boolean        | false      |
 | readonly       | Read only status disables input box operation behavior | Boolean        | false      |
+| icon-left`v3.2.2`  | Left icon name             | String         | `minus`     |
+| icon-right`v3.2.2` | Right icon name             | String         | `plus`      |
+| font-class-name `v3.2.2` | Custom icon font base class name | String   | `nutui-iconfont` |
+| class-prefix `v3.2.2` | Custom icon class name prefix for using custom icons | String   | `nut-icon`  |
 
 ### Events
 

+ 25 - 0
src/packages/__VUE/inputnumber/doc.md

@@ -216,6 +216,27 @@ app.use(InputNumber).use(Icon);
 ```
 
 :::
+### 自定义按钮图标
+
+:::demo
+
+```html
+<template>
+  <nut-inputnumber icon-left="left" icon-right="right" v-model="value" />
+</template>
+<script lang="ts">
+  import { ref } from 'vue';
+  export default {
+    props: {},
+    setup() {
+      const value = ref(1);
+      return { value };
+    },
+  };
+</script>
+```
+
+:::
 
 ## API
 
@@ -232,6 +253,10 @@ app.use(InputNumber).use(Icon);
 | decimal-places | 设置保留的小数位           | String、Number | `0`        |
 | disabled       | 禁用所有功能               | Boolean        | false      |
 | readonly       | 只读状态禁用输入框操作行为 | Boolean        | false      |
+| icon-left `v3.2.2`  | 左侧操作符图标名,同 Icon 组件 name 属性 | String  | `minus` |
+| icon-right `v3.2.2` | 右侧操作符图标名,同 Icon 组件 name 属性 | String  | `plus`  |
+| font-class-name `v3.2.2` | 自定义icon 字体基础类名 | String   | `nutui-iconfont` |
+| class-prefix `v3.2.2` | 自定义icon 类名前缀,用于使用自定义图标 | String   | `nut-icon`  |
 
 ### Events
 

+ 12 - 2
src/packages/__VUE/inputnumber/index.taro.vue

@@ -1,10 +1,11 @@
 <template>
   <view :class="classes" :style="{ height: pxCheck(buttonSize) }">
     <nut-icon
-      name="minus"
+      :name="iconLeft"
       class="nut-inputnumber__icon"
       :class="{ 'nut-inputnumber__icon--disabled': !reduceAllow() }"
       :size="buttonSize"
+      v-bind="$attrs"
       @click="reduce"
     >
     </nut-icon>
@@ -25,10 +26,11 @@
       @focus="focus"
     />
     <nut-icon
-      name="plus"
+      :name="iconRight"
       class="nut-inputnumber__icon"
       :class="{ 'nut-inputnumber__icon--disabled': !addAllow() }"
       :size="buttonSize"
+      v-bind="$attrs"
       @click="add"
     >
     </nut-icon>
@@ -76,6 +78,14 @@ export default create({
     readonly: {
       type: Boolean,
       default: false
+    },
+    iconLeft: {
+      type: String,
+      default: 'minus'
+    },
+    iconRight: {
+      type: String,
+      default: 'plus'
     }
   },
   emits: ['update:modelValue', 'change', 'blur', 'focus', 'reduce', 'add', 'overlimit'],

+ 12 - 2
src/packages/__VUE/inputnumber/index.vue

@@ -1,10 +1,11 @@
 <template>
   <view :class="classes" :style="{ height: pxCheck(buttonSize) }">
     <nut-icon
-      name="minus"
+      :name="iconLeft"
       class="nut-inputnumber__icon"
       :class="{ 'nut-inputnumber__icon--disabled': !reduceAllow() }"
       :size="buttonSize"
+      v-bind="$attrs"
       @click="reduce"
     >
     </nut-icon>
@@ -21,10 +22,11 @@
       @focus="focus"
     />
     <nut-icon
-      name="plus"
+      :name="iconRight"
       class="nut-inputnumber__icon"
       :class="{ 'nut-inputnumber__icon--disabled': !addAllow() }"
       :size="buttonSize"
+      v-bind="$attrs"
       @click="add"
     >
     </nut-icon>
@@ -72,6 +74,14 @@ export default create({
     readonly: {
       type: Boolean,
       default: false
+    },
+    iconLeft: {
+      type: String,
+      default: 'minus'
+    },
+    iconRight: {
+      type: String,
+      default: 'plus'
     }
   },
   emits: ['update:modelValue', 'change', 'blur', 'focus', 'reduce', 'add', 'overlimit'],

+ 1 - 0
src/packages/__VUE/picker/Column.vue

@@ -275,6 +275,7 @@ export default create({
     // 惯性滚动结束
     const stopMomentum = () => {
       moving.value = false;
+      touchTime.value = 0;
       setChooseValue();
     };
 

+ 11 - 19
src/packages/__VUE/picker/ColumnTaro.vue

@@ -18,7 +18,12 @@
           {{ item.text }}
         </view>
         <!-- 平铺 -->
-        <view class="nut-picker-roller-item-tile" v-if="item && item.text && !threeDimensional">
+        <view
+          class="nut-picker-roller-item-tile"
+          ref="listbox"
+          :id="'listbox' + refRandomId"
+          v-if="item && item.text && !threeDimensional"
+        >
           {{ item.text }}
         </view>
       </template>
@@ -278,6 +283,7 @@ export default create({
     // 惯性滚动结束
     const stopMomentum = () => {
       moving.value = false;
+      touchTime.value = 0;
       setChooseValue();
     };
 
@@ -290,8 +296,10 @@ export default create({
     watch(
       () => props.column,
       (val) => {
-        state.transformY = 0;
-        modifyStatus(false);
+        if (props.column && props.column.length > 0) {
+          state.transformY = 0;
+          modifyStatus(false);
+        }
       },
       {
         deep: true
@@ -309,22 +317,6 @@ export default create({
       }
     );
 
-    watch(
-      () => props.itemShow,
-      (val) => {
-        if (val) {
-          setTimeout(() => {
-            getReference();
-          }, 200);
-        } else {
-          state.transformY = 0;
-        }
-      },
-      {
-        deep: true
-      }
-    );
-
     onMounted(() => {
       setTimeout(() => {
         getReference();

+ 0 - 19
src/packages/__VUE/picker/demo.vue

@@ -129,25 +129,6 @@
     >
       <nut-button block type="primary" @click="alwaysFun">{{ translate('always') }}</nut-button></nut-picker
     >
-
-    <!-- <h2>异步获取</h2>
-    <nut-cell
-      :title="translate('validTime')"
-      :desc="effect"
-      @click="
-        () => {
-          showJK = true;
-        }
-      "
-    ></nut-cell>
-    <nut-picker
-      v-model:visible="showJK"
-      :columns="jkColumns"
-      :title="translate('chooseDate')"
-      @confirm="(options) => confirm('effect', options)"
-      @change="changeJK"
-    ></nut-picker
-    > -->
   </div>
 </template>
 <script lang="ts">

+ 1 - 0
src/packages/__VUE/picker/index.scss

@@ -46,6 +46,7 @@
     align-items: center;
     justify-content: center;
     min-width: 50px;
+    height: 100%;
   }
   &__left {
     color: $picker-cancel-color;

+ 19 - 2
src/packages/__VUE/picker/index.taro.vue

@@ -23,6 +23,7 @@
         <view class="nut-picker__hairline"></view>
         <view class="nut-picker__columnitem" v-for="(column, columnIndex) in columnsList" :key="columnIndex">
           <nut-picker-column
+            :ref="swipeRef"
             :itemShow="show"
             :column="column"
             :readonly="readonly"
@@ -101,6 +102,14 @@ export default create({
     // 选中项
     let defaultValues = ref<(number | string)[]>(props.modelValue);
 
+    const pickerColumn = ref<any[]>([]);
+
+    const swipeRef = (el: any) => {
+      if (el && pickerColumn.value.length < columnsList.value.length) {
+        pickerColumn.value.push(el);
+      }
+    };
+
     const classes = computed(() => {
       const prefixCls = componentName;
       return {
@@ -207,6 +216,11 @@ export default create({
     };
 
     const confirmHandler = () => {
+      pickerColumn.value.length > 0 &&
+        pickerColumn.value.forEach((column) => {
+          column.stopMomentum();
+        });
+
       if (defaultValues.value && !defaultValues.value.length) {
         columnsList.value.forEach((columns) => {
           defaultValues.value.push(columns[0].value);
@@ -222,7 +236,6 @@ export default create({
     };
 
     onMounted(() => {
-      console.log('更新');
       if (props.visible) state.show = props.visible;
     });
 
@@ -256,6 +269,8 @@ export default create({
       () => props.visible,
       (val) => {
         state.show = val;
+        console.log(defaultValues.value);
+        if (val) pickerColumn.value = [];
       }
     );
 
@@ -276,7 +291,9 @@ export default create({
       changeHandler,
       confirmHandler,
       defaultValues,
-      translate
+      translate,
+      pickerColumn,
+      swipeRef
     };
   }
 });

+ 17 - 4
src/packages/__VUE/picker/index.vue

@@ -26,6 +26,7 @@
         <view class="nut-picker__hairline"></view>
         <view class="nut-picker__columnitem" v-for="(column, columnIndex) in columnsList" :key="columnIndex">
           <nut-picker-column
+            :ref="swipeRef"
             :itemShow="show"
             :column="column"
             :readonly="readonly"
@@ -52,7 +53,6 @@ import { createComponent } from '@/packages/utils/create';
 import popup, { popupProps } from '../popup/index.vue';
 import column from './Column.vue';
 const { componentName, create, translate } = createComponent('picker');
-// import { PickerColumnOption, PickerOption, TouchParams } from './types';
 
 export interface PickerOption {
   text: string | number;
@@ -116,7 +116,13 @@ export default create({
     // 选中项
     let defaultValues = ref<(number | string)[]>(props.modelValue);
 
-    const wrapHeight = ref();
+    const pickerColumn = ref<any[]>([]);
+
+    const swipeRef = (el: any) => {
+      if (el && pickerColumn.value.length < columnsList.value.length) {
+        pickerColumn.value.push(el);
+      }
+    };
 
     const classes = computed(() => {
       const prefixCls = componentName;
@@ -223,9 +229,13 @@ export default create({
     };
 
     const confirmHandler = () => {
+      pickerColumn.value.length > 0 &&
+        pickerColumn.value.forEach((column) => {
+          column.stopMomentum();
+        });
+
       if (defaultValues.value && !defaultValues.value.length) {
         columnsList.value.forEach((columns) => {
-          // console.log(columns);
           defaultValues.value.push(columns[0].value);
           selectedOptions.value.push(columns[0]);
         });
@@ -272,6 +282,7 @@ export default create({
       () => props.visible,
       (val) => {
         state.show = val;
+        if (val) pickerColumn.value = [];
       }
     );
 
@@ -292,7 +303,9 @@ export default create({
       changeHandler,
       confirmHandler,
       defaultValues,
-      translate
+      translate,
+      pickerColumn,
+      swipeRef
     };
   }
 });

+ 2 - 2
src/packages/__VUE/radio/index.taro.vue

@@ -15,7 +15,7 @@ export default create({
       default: 'round' // button
     },
     label: {
-      type: [String, Number],
+      type: [String, Number, Boolean],
       default: ''
     },
     iconName: {
@@ -43,7 +43,7 @@ export default create({
     let parent: any = inject('parent', null);
 
     const isCurValue = computed(() => {
-      return parent.label.value == props.label;
+      return parent.label.value === props.label;
     });
 
     const color = computed(() => {

+ 2 - 2
src/packages/__VUE/radio/index.vue

@@ -15,7 +15,7 @@ export default create({
       default: 'round' // button
     },
     label: {
-      type: [String, Number],
+      type: [String, Number, Boolean],
       default: ''
     },
     iconName: {
@@ -43,7 +43,7 @@ export default create({
     let parent: any = inject('parent', null);
 
     const isCurValue = computed(() => {
-      return parent.label.value == props.label;
+      return parent.label.value === props.label;
     });
 
     const color = computed(() => {

+ 8 - 1
src/sites/mobile-taro/vue/project.private.config.json

@@ -51,9 +51,16 @@
           "query": "",
           "launchMode": "default",
           "scene": null
+        },
+        {
+          "name": "dentry/pages/picker/index",
+          "pathName": "dentry/pages/picker/index",
+          "query": "",
+          "launchMode": "default",
+          "scene": null
         }
       ]
     }
   },
-  "projectname": "NutUI-Taro"
+  "projectname": "vue"
 }

+ 23 - 1
src/sites/mobile-taro/vue/src/dentry/pages/picker/index.vue

@@ -38,6 +38,25 @@
     >
     </nut-picker>
 
+    <h2>平铺展示</h2>
+    <nut-cell
+      title="请选择城市"
+      :desc="title"
+      @click="
+        () => {
+          showTitle = true;
+        }
+      "
+    ></nut-cell>
+    <nut-picker
+      v-model:visible="showTitle"
+      :columns="columns"
+      title="城市选择"
+      :three-dimensional="false"
+      @confirm="(options) => confirm('title', options)"
+    >
+    </nut-picker>
+
     <h2>多列样式</h2>
     <nut-cell
       title="请选择时间"
@@ -246,6 +265,7 @@ export default {
     const showAsync = ref(false);
     const showEffect = ref(false);
     const showPort = ref(false);
+    const showTitle = ref(false);
 
     const desc = reactive({
       index: '',
@@ -253,7 +273,8 @@ export default {
       multiple: '',
       cascader: '',
       async: '',
-      effect: ''
+      effect: '',
+      title: ''
     });
 
     const open = (index: number) => {
@@ -359,6 +380,7 @@ export default {
       alwaysFun,
       columsNum,
       showPort,
+      showTitle,
       portColumns,
       portChange
     };