Browse Source

fix: popover/navbar props (#1044)

* upd: navbar单元测试
liqiong-lab 3 years ago
parent
commit
9bfc26cb56

+ 16 - 0
src/packages/__VUE/navbar/__test__/__snapshots__/navbar.spec.ts.snap

@@ -0,0 +1,16 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render left slot correctly 1`] = `"<view class=\\"nut-navbar__left\\"><i class=\\"nutui-iconfont nut-icon nut-icon-left\\" style=\\"color: rgb(151, 151, 151);\\" src=\\"\\"></i>Custom Left</view>"`;
+
+exports[`should render left slot correctly 2`] = `
+"<view class=\\"nut-navbar__right\\">
+  <!--v-if-->Custom Right
+</view>"
+`;
+
+exports[`should render title slot correctly 1`] = `
+"<view class=\\"nut-navbar__title\\">
+  <!--v-if-->
+  <!--v-if-->
+</view>"
+`;

+ 55 - 0
src/packages/__VUE/navbar/__test__/navbar.spec.ts

@@ -0,0 +1,55 @@
+import { mount, config } from '@vue/test-utils';
+import NavBar from '../index.vue';
+
+import NutIcon from '../../icon/index.vue';
+
+beforeAll(() => {
+  config.global.components = {
+    NutIcon
+  };
+});
+
+afterAll(() => {
+  config.global.components = {};
+});
+
+test('should render left slot correctly', () => {
+  const wrapper = mount(NavBar, {
+    slots: {
+      left: () => 'Custom Left'
+    }
+  });
+
+  expect(wrapper.find('.nut-navbar__left').html()).toMatchSnapshot();
+});
+
+test('should render left slot correctly', () => {
+  const wrapper = mount(NavBar, {
+    slots: {
+      right: () => 'Custom Right'
+    }
+  });
+
+  expect(wrapper.find('.nut-navbar__right').html()).toMatchSnapshot();
+});
+
+test('should render title slot correctly', () => {
+  const wrapper = mount(NavBar, {
+    slots: {
+      title: () => 'Custom Title'
+    }
+  });
+
+  expect(wrapper.find('.nut-navbar__title').html()).toMatchSnapshot();
+});
+
+test('should emit click-right event when clicking right text', () => {
+  const wrapper = mount(NavBar, {
+    props: {
+      desc: 'right'
+    }
+  });
+
+  wrapper.find('.right_text').trigger('click');
+  expect(wrapper.emitted('on-click-right')).toBeTruthy();
+});

+ 39 - 34
src/packages/__VUE/navbar/demo.vue

@@ -1,38 +1,45 @@
 <template>
   <div class="demo full">
     <h2>基础用法</h2>
+
+    <nut-navbar @on-click-back="back" @on-click-title="title" title="订单详情">
+      <template #left>
+        <div>返回</div>
+      </template>
+      <template #right>
+        <nut-icon class="right" name="share-n"></nut-icon>
+      </template>
+    </nut-navbar>
+
     <nut-navbar
       @on-click-back="back"
       @on-click-title="title"
-      @on-click-send="send"
-      title="订单详情"
-      icon="share-n"
-    ></nut-navbar>
-    <nut-navbar
-      @on-click-back="back"
-      @on-click-title="title"
-      @on-click-clear="clear"
+      @on-click-right="rightClick"
       title="浏览记录"
       desc="清空"
     ></nut-navbar>
+
     <nut-navbar
       :left-show="false"
+      @on-click-back="back"
       @on-click-title="title"
       @on-click-icon="icon"
-      @on-click-clear="edit"
-      @on-click-send="more"
+      @on-click-right="rightClick"
       title="购物车"
       titIcon="cart2"
       desc="编辑"
       icon="more-x"
-    ></nut-navbar>
+    >
+      <template #right>
+        <nut-icon class="right" name="more-x"></nut-icon>
+      </template>
+    </nut-navbar>
 
     <h2>自定义导航栏中间内容</h2>
     <nut-navbar
       @on-click-back="back"
       @on-click-title="title"
-      @on-click-clear="edit"
-      @on-click-send="list"
+      @on-click-right="rightClick"
       desc="编辑"
       icon="horizontal-n"
     >
@@ -42,10 +49,14 @@
           <nut-tabpane title="店铺"> </nut-tabpane>
         </nut-tabs>
       </template>
+
+      <template #right>
+        <nut-icon class="right" name="more-x"></nut-icon>
+      </template>
     </nut-navbar>
 
     <h2>多tab切换导航</h2>
-    <nut-navbar @on-click-back="back" @on-click-send="list" icon="more-x">
+    <nut-navbar @on-click-back="back" icon="more-x">
       <template #content>
         <nut-tabs v-model="tab2value" @click="changeTabList">
           <nut-tabpane title="商品"> </nut-tabpane>
@@ -55,7 +66,11 @@
         </nut-tabs>
       </template>
       <template #icons>
-        <nut-icon class="icon" name="share" @on-click-slot-send="morelist"></nut-icon>
+        <nut-icon class="icon" name="share"></nut-icon>
+      </template>
+
+      <template #right>
+        <nut-icon class="right" name="horizontal-n"></nut-icon>
       </template>
     </nut-navbar>
   </div>
@@ -66,7 +81,7 @@ import { ref } from 'vue';
 import { createComponent } from '../../utils/create';
 const { createDemo } = createComponent('navbar');
 export default createDemo({
-  setup(props, { emit }) {
+  setup({}) {
     const tab1value = ref(0);
     const tab2value = ref(0);
     const methods = {
@@ -79,23 +94,9 @@ export default createDemo({
       icon() {
         alert('icon');
       },
-      send() {
-        alert('发送');
-      },
-      edit() {
-        alert('编辑');
-      },
-      more() {
-        alert('更多');
-      },
-      clear() {
-        alert('清空');
-      },
-      list() {
-        alert('列表');
-      },
-      morelist() {
-        alert('多个更多');
+
+      rightClick() {
+        alert('右侧点击事件');
       },
       changeTab(tab: any) {
         tab1value.value = tab.paneKey as number;
@@ -114,4 +115,8 @@ export default createDemo({
 });
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.right {
+  margin-left: 10px;
+}
+</style>

+ 43 - 50
src/packages/__VUE/navbar/doc.md

@@ -29,31 +29,38 @@ app.use(TabPane);
 :::demo
 ```html
   <template>
-<nut-navbar
-      @on-click-back="back"
-      @on-click-title="title"
-      @on-click-send="send"
-      title="订单详情"
-      icon="share-n"
-    ></nut-navbar>
+    <nut-navbar @on-click-back="back" @on-click-title="title" title="订单详情">
+      <template #left>
+        <div>返回</div>
+      </template>
+      <template #right>
+        <nut-icon class="right" name="share-n"></nut-icon>
+      </template>
+    </nut-navbar>
+
     <nut-navbar
       @on-click-back="back"
       @on-click-title="title"
-      @on-click-clear="clear"
+      @on-click-right="rightClick"
       title="浏览记录"
       desc="清空"
     ></nut-navbar>
+
     <nut-navbar
       :left-show="false"
+      @on-click-back="back"
       @on-click-title="title"
       @on-click-icon="icon"
-      @on-click-clear="edit"
-      @on-click-send="more"
+      @on-click-right="rightClick"
       title="购物车"
       titIcon="cart2"
       desc="编辑"
       icon="more-x"
-    ></nut-navbar>
+    >
+      <template #right>
+        <nut-icon class="right" name="more-x"></nut-icon>
+      </template>
+    </nut-navbar>
   
   </template>
 
@@ -68,21 +75,9 @@ app.use(TabPane);
       title() {
         alert('header头部, 点击title');
       },
-      icon() {
-        alert('icon');
-      },
-      send() {
-        alert('发送');
-      },
-      edit() {
-        alert('编辑');
-      },
-      more() {
-        alert('更多');
-      },
-      clear() {
-        alert('清空');
-      },
+      rightClick() {
+        alert('右侧点击事件');
+      }
     };
 
     return {
@@ -99,12 +94,11 @@ app.use(TabPane);
 
 :::demo
 ```html
-<template>
- <nut-navbar
+  <template>
+   <nut-navbar
       @on-click-back="back"
       @on-click-title="title"
-      @on-click-clear="edit"
-      @on-click-send="list"
+      @on-click-right="rightClick"
       desc="编辑"
       icon="horizontal-n"
     >
@@ -114,6 +108,10 @@ app.use(TabPane);
           <nut-tabpane title="店铺"> </nut-tabpane>
         </nut-tabs>
       </template>
+
+      <template #right>
+        <nut-icon class="right" name="more-x"></nut-icon>
+      </template>
     </nut-navbar>
   </template>
 
@@ -129,11 +127,8 @@ app.use(TabPane);
         title () {
           alert('header头部, 点击title');
         },
-        edit () {
-          alert('编辑');
-        },
-        list () {
-          alert('列表');
+        rightClick() {
+          alert('右侧点击事件');
         },
         changeTab(tab: any) {
           tab1value.value = tab.paneKey as number;
@@ -155,8 +150,8 @@ app.use(TabPane);
 
 :::demo
 ```html
-<template>
-   <nut-navbar @on-click-back="back" @on-click-send="list" icon="more-x">
+  <template>
+    <nut-navbar @on-click-back="back" icon="more-x">
       <template #content>
         <nut-tabs v-model="tab2value" @click="changeTabList">
           <nut-tabpane title="商品"> </nut-tabpane>
@@ -166,7 +161,11 @@ app.use(TabPane);
         </nut-tabs>
       </template>
       <template #icons>
-        <nut-icon class="icon" name="share" @on-click-slot-send="morelist"></nut-icon>
+        <nut-icon class="icon" name="share"></nut-icon>
+      </template>
+
+      <template #right>
+        <nut-icon class="right" name="horizontal-n"></nut-icon>
       </template>
     </nut-navbar>
   </template>
@@ -180,12 +179,6 @@ app.use(TabPane);
         back() {
           alert('header头部, 点击返回');
         },
-        list() {
-          alert('列表');
-        },
-        morelist () {
-          alert('多个更多');
-        },
         changeTabList(tab: any) {
           tab2value.value = tab.paneKey as number;
         }
@@ -207,19 +200,19 @@ app.use(TabPane);
 |-----------------|------------------------------------------------------------------------------------------------|---------|---------|
 | title           | 标题名称                                                                                       | String  | -       |
 | desc            | 右侧描述                                                                                       | String  | -       |
-| left-show        | 是否展示左侧箭头                                                                              | Boolean | false   |
-| icon            | 左侧 [图标名称](#/icon) 或图片链接                                                             | String  | -       |
-| tit-icon         | 标题带icon                                                         | String  | -       |                                          
+| left-show        | 是否展示左侧箭头                                                                               | Boolean | false   |
+| tit-icon         | 标题中插入icon                                                                                    | String  |-|                                          
 
 ### Event
 | 名称  | 说明     | 回调参数    |
 |-------|----------|-------------|
 | title | 点击页面标题事件 | event:Event |
-| right | 点击右侧按钮事件 | event:Event |
-| back | 点击返回上一页事件 | event:Event |
+| right-click | 点击右侧按钮事件 | event:Event |
+| back | 左侧图标返回点击事件 | event:Event |
 
 ### Slot
 | 名称  | 说明     | 回调参数    |
 |-------|----------|-------------|
-| icons | 增加右侧图标 |  |
+| left | 自定义左侧内容 |  |
+| right | 自定义右侧内容 |  |
 | content |  自定义导航栏中间内容 |  |

+ 2 - 0
src/packages/__VUE/navbar/index.scss

@@ -41,6 +41,8 @@
     min-width: 53%;
     margin: 0 auto;
     text-align: center;
+    display: flex;
+    justify-content: center;
     &.icon {
       .icon {
         margin-left: 13px;

+ 13 - 48
src/packages/__VUE/navbar/index.vue

@@ -2,22 +2,20 @@
   <view :class="classes">
     <view class="nut-navbar__left">
       <nut-icon v-if="leftShow" color="#979797" name="left" @click="handleLeft"></nut-icon>
+      <slot name="left"></slot>
     </view>
+
     <view class="nut-navbar__title" :class="{ icon }">
       <view v-if="title" @click="handleCenter">{{ title }}</view>
       <nut-icon v-if="titIcon" class="icon" :name="titIcon" @click="handleCenterIcon"></nut-icon>
       <slot name="content"></slot>
     </view>
-    <view class="nut-navbar__right" :class="{ icon }" v-if="desc || icon">
-      <view v-if="desc" :style="{ 'text-align': descTextAlign }" @click="handleClear">{{ desc }}</view>
-      <template v-if="icon">
-        <view @click="handleSends">
-          <slot name="icons"></slot>
-        </view>
-      </template>
-      <view>
-        <nut-icon v-if="icon" class="rightIcon" :name="icon" @click="handleSend"></nut-icon>
-      </view>
+
+    <view class="nut-navbar__right" :class="{ icon }">
+      <view v-if="desc" class="right_text" :style="{ 'text-align': descTextAlign }" @click="handleRight">{{
+        desc
+      }}</view>
+      <slot name="right"></slot>
     </view>
   </view>
 </template>
@@ -28,30 +26,16 @@ import { createComponent } from '../../utils/create';
 const { componentName, create } = createComponent('navbar');
 export default create({
   props: {
-    leftShow: { type: Boolean, default: true }, //左侧  是否显示返回
+    leftShow: { type: Boolean, default: true }, //左侧  是否显示返回icon
     title: { type: String, default: '' }, //中间  文字标题
     titIcon: { type: String, default: '' }, //中间  标题icon
-    icon: { type: String, default: '' }, //右侧   按钮图标
     desc: { type: String, default: '' }, //右侧   按钮文字
     defaultIndex: {
       type: Number,
       default: 0
     }
   },
-  emits: [
-    'click',
-    'on-click-back',
-    'on-click-title',
-    'on-click-right',
-    'on-click-desc',
-    'on-click-icon',
-    'on-click-more',
-    'on-click-clear',
-    'on-click-send',
-    'on-click-slot',
-    'on-click-slot-send',
-    'switch-tab'
-  ],
+  emits: ['click', 'on-click-back', 'on-click-title', 'on-click-icon', 'on-click-right'],
   setup(props, { emit }) {
     const activeIndex = ref(props.defaultIndex);
     const classes = computed(() => {
@@ -72,24 +56,8 @@ export default create({
       emit('on-click-icon');
     }
 
-    function handleClear() {
-      emit('on-click-clear');
-    }
-
-    function handleMore() {
-      emit('on-click-more');
-    }
-
-    function handleSend() {
-      emit('on-click-send');
-    }
-
-    function handleSlot() {
-      emit('on-click-slot');
-    }
-
-    function handleSends() {
-      emit('on-click-slot-send');
+    function handleRight() {
+      emit('on-click-right');
     }
 
     return {
@@ -97,10 +65,7 @@ export default create({
       handleLeft,
       handleCenter,
       handleCenterIcon,
-      handleClear,
-      handleSend,
-      handleSlot,
-      handleSends,
+      handleRight,
       activeIndex
     };
   }

+ 23 - 0
src/packages/__VUE/popover/__test__/__snapshots__/popover.spec.ts.snap

@@ -0,0 +1,23 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should change icon class prefix when using icon prop 1`] = `
+"<view class=\\"nut-popover nut-popover--light\\">
+  <div></div>
+  <!--v-if-->
+</view>"
+`;
+
+exports[`should change icon class prefix when using icon-prefix prop 1`] = `
+"<view class=\\"nut-popover nut-popover--light\\">
+  <div></div>
+  <!--v-if-->
+</view>"
+`;
+
+exports[`should locate to reference element when showed 1`] = `""`;
+
+exports[`should locate to reference element when showed 2`] = `""`;
+
+exports[`should locate to reference element when showed 3`] = `""`;
+
+exports[`should watch placement prop and update location 1`] = `""`;

+ 111 - 0
src/packages/__VUE/popover/__test__/popover.spec.ts

@@ -0,0 +1,111 @@
+import { mount, config } from '@vue/test-utils';
+import Popover from '../index.vue';
+
+import NutIcon from '../../icon/index.vue';
+
+beforeAll(() => {
+  config.global.components = {
+    NutIcon
+  };
+});
+
+afterAll(() => {
+  config.global.components = {};
+});
+
+const baseActions = [
+  {
+    name: '选项一',
+    icon: 'my2'
+  },
+  {
+    name: '选项二',
+    icon: 'cart2'
+  },
+  {
+    name: '选项三',
+    icon: 'location2'
+  }
+];
+
+test('should emit click event when clicking the list', async () => {
+  const wrapper = mount(Popover, {
+    props: {
+      visible: true,
+      list: baseActions
+    }
+  });
+  await wrapper.find('.title-item').trigger('click');
+  expect(wrapper.emitted('choose')![0]).toEqual([baseActions[0], 0]);
+});
+
+test('should not emit click event when the list is disabled', () => {
+  const wrapper = mount(Popover, {
+    props: {
+      visible: true,
+      list: [
+        {
+          name: '选项一',
+          disabled: true
+        }
+      ]
+    }
+  });
+
+  wrapper.find('.title-item').trigger('click');
+  expect(wrapper.emitted('choose')).toBeFalsy();
+});
+
+test('should close popover when clicking the list', async () => {
+  const wrapper = mount(Popover, {
+    props: {
+      visible: true,
+      actions: baseActions
+    }
+  });
+
+  await wrapper.find('.more-background').trigger('click');
+  expect(wrapper.emitted('update:visible')![0]).toEqual([false]);
+});
+
+test('should locate to reference element when showed', async () => {
+  const root = document.createElement('div');
+  const wrapper = mount(Popover, {
+    props: {
+      teleport: root
+    }
+  });
+
+  expect(root.innerHTML).toMatchSnapshot();
+
+  await wrapper.setProps({ visible: true });
+  expect(root.innerHTML).toMatchSnapshot();
+
+  await wrapper.setProps({ visible: false });
+  expect(root.innerHTML).toMatchSnapshot();
+});
+
+test('should watch placement prop and update location', async () => {
+  const root = document.createElement('div');
+  const wrapper = mount(Popover, {
+    props: {
+      visible: true
+    }
+  });
+
+  await wrapper.setProps({
+    location: 'right'
+  });
+
+  expect(root.innerHTML).toMatchSnapshot();
+});
+
+test('should change icon class prefix when using icon prop', () => {
+  const wrapper = mount(Popover, {
+    props: {
+      list: [{ icon: 'success', name: 'foo' }]
+    }
+  });
+
+  expect(wrapper.html()).toMatchSnapshot();
+});

+ 4 - 1
src/packages/__VUE/popover/index.vue

@@ -160,7 +160,10 @@ export default create({
       emit('update:visible', false);
     };
 
-    const chooseItem = (item: unknown, index: number) => {
+    const chooseItem = (item: any, index: number) => {
+      if (item.disabled) {
+        return;
+      }
       emit('choose', item, index);
     };
 

+ 21 - 0
src/packages/__VUE/skeleton/__test__/__snapshots__/skeleton.spec.ts.snap

@@ -1,5 +1,25 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+<<<<<<< HEAD
+exports[`should change avatar shape when using avatar-shape prop 1`] = `"<nut-avatar class=\\"avatarClass avatarClass--square\\" shape=\\"square\\" style=\\"width: 50px; height: 50px;\\" bg-color=\\"rgb(239, 239, 239)\\"></nut-avatar>"`;
+
+exports[`should change avatar size when using avatar-size prop: 20px 1`] = `"20px"`;
+
+exports[`should change avatar size when using avatar-size prop: 20px 2`] = `"20px"`;
+
+exports[`should render with row width array correctly 1`] = `
+"<view class=\\"skeleton\\" rowwidth=\\"100%,30,5rem\\">
+  <view class=\\"skeleton-animation\\"></view>
+  <view class=\\"content\\">
+    <!--v-if-->
+    <!--v-if-->
+    <view class=\\"content-line\\">
+      <view class=\\"title\\"></view>
+      <view class=\\"blockClass\\" style=\\"width: 100px; height: 100px;\\"></view>
+      <view class=\\"blockClass\\" style=\\"width: 100px; height: 100px;\\"></view>
+      <view class=\\"blockClass\\" style=\\"width: 100px; height: 100px;\\"></view>
+      <view class=\\"blockClass\\" style=\\"width: 100px; height: 100px;\\"></view>
+=======
 exports[`should change avatar shape when using avatarShape prop 1`] = `
 "<view style=\\"width: 50px; height: 50px; background-color: rgb(239, 239, 239);\\" class=\\"nut-avatar avatar-normal avatar-square avatarClass avatarClass--square\\"><i class=\\"nutui-iconfont nut-icon nut-icon- icon\\" src=\\"\\"></i>
   <!--v-if-->
@@ -19,6 +39,7 @@ exports[`should render default slot 1`] = `
     <view class=\\"content-line\\">
       <view class=\\"title\\"></view>
       <view class=\\"blockClass\\" style=\\"width: 100px; height: 100px;\\"></view>
+>>>>>>> master/next
     </view>
   </view>
 </view>"

+ 3 - 0
src/packages/__VUE/tag/__test__/__snapshots__/tag.spec.ts.snap

@@ -11,9 +11,12 @@ exports[`should render border-color correctly 1`] = `
   <!--v-if-->
 </view>"
 `;
+<<<<<<< HEAD
+=======
 
 exports[`should render textColor correctly 1`] = `
 "<view class=\\"nut-tag nut-tag--default nut-tag--plain\\" style=\\"background: red; color: blue;\\">
   <!--v-if-->
 </view>"
 `;
+>>>>>>> master/next