Browse Source

upd: navbar 新增顶部固定props及安全区适配 (#1058)

liqiong-lab 3 years ago
parent
commit
a14ad754f9

+ 1 - 3
src/packages/__VUE/backtop/__tests__/__snapshots__/backtop.spec.ts.snap

@@ -1,5 +1,3 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should allow to use the elId prop 1`] = `""`;
-
-exports[`should allow to use the teleport prop 1`] = `""`;
+exports[`should allow to use the elId prop 1`] = `"<div class=\\"nut-backtop\\" style=\\"right: 10px; bottom: 20px; z-index: 10;\\"><i class=\\"nutui-iconfont nut-icon nut-icon-top nut-backtop-main\\" style=\\"font-size: 19px; width: 19px; height: 19px;\\" src=\\"\\"></i></div>"`;

+ 4 - 4
src/packages/__VUE/backtop/__tests__/backtop.spec.ts

@@ -56,11 +56,11 @@ test('backtop style', () => {
 });
 
 test('should allow to use the elId prop', () => {
-  const root = document.createElement('div');
-  mount(BackTop, {
+  const wrapper = mount(BackTop, {
     props: {
-      elId: root
+      elId: () => 'elId'
     }
   });
-  expect(root.innerHTML).toMatchSnapshot();
+
+  expect(wrapper.html()).toMatchSnapshot();
 });

+ 12 - 7
src/packages/__VUE/backtop/demo.vue

@@ -26,13 +26,11 @@
     <div class="text-data">我是测试数据23</div>
     <div class="text-data">我是测试数据24</div>
     <nut-backtop @click="handleClick" el-id="elId" :distance="100" :bottom="90">
-      <view>无</view>
+      <view class="backtop-demo"
+        ><nut-icon size="12px" class="nut-backtop-main" name="top"></nut-icon><view class="title">顶部</view></view
+      >
     </nut-backtop>
-    <nut-backtop
-      @click="handleClick"
-      el-id="elId"
-      :distance="200"
-    ></nut-backtop>
+    <nut-backtop @click="handleClick" el-id="elId" :distance="200"></nut-backtop>
   </div>
 </template>
 
@@ -62,7 +60,6 @@ export default createDemo({
     padding-left: 16px;
     display: flex;
     align-items: center;
-    width: 100%;
     height: 46px;
     background: rgba(255, 255, 255, 1);
     border-radius: 7px;
@@ -71,5 +68,13 @@ export default createDemo({
     font-size: 13px;
     color: rgba(102, 102, 102, 1);
   }
+  .backtop-demo {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    .title {
+      font-size: 12px;
+    }
+  }
 }
 </style>

+ 2 - 0
src/packages/__VUE/navbar/doc.md

@@ -199,6 +199,8 @@ app.use(TabPane);
 | desc            | 右侧描述                                                                                       | String  | -       |
 | left-show        | 是否展示左侧箭头                                                                               | Boolean | false   |
 | tit-icon         | 标题中插入icon                                                                                    | String  |-|                                          
+| fixed           | 是否固定到顶部                                                                                       | Boolean  | false       |
+| safe-area-inset-top           | 是否开启顶部安全区适配                                                                                       | Boolean  | false       |
 
 ### Event
 | 名称  | 说明     | 回调参数    |

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

@@ -14,6 +14,16 @@
   &:active::before {
     opacity: 0.1;
   }
+  &--fixed {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+  }
+  &--safe-area-inset-top {
+    padding-top: constant(safe-area-inset-top);
+    padding-top: env(safe-area-inset-top);
+  }
   &--clickable {
     &::before {
       position: absolute;
@@ -43,6 +53,13 @@
     text-align: center;
     display: flex;
     justify-content: center;
+    .title {
+      width: 100px;
+      display: -webkit-box;
+      -webkit-box-orient: vertical;
+      -webkit-line-clamp: 1;
+      overflow: hidden;
+    }
     &.icon {
       .icon {
         margin-left: 13px;

+ 23 - 63
src/packages/__VUE/navbar/index.taro.vue

@@ -2,71 +2,52 @@
   <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">
-      <view v-if="title" class="text__title" @click="handleCenter">{{ title }}</view>
+      <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" v-if="desc || icon">
-      <view v-if="desc" @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">
+      <view v-if="desc" class="right_text" @click="handleRight">{{ desc }}</view>
+      <slot name="right"></slot>
     </view>
   </view>
 </template>
 
 <script lang="ts">
-import { computed, ref } from 'vue';
+import { computed, toRefs } from 'vue';
 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
+    fixed: {
+      type: Boolean,
+      default: false
+    },
+    safeAreaInsetTop: {
+      type: Boolean,
+      default: false
     }
   },
-  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 { fixed, safeAreaInsetTop } = toRefs(props);
     const classes = computed(() => {
       const prefixCls = componentName;
       return {
-        [prefixCls]: true
+        [prefixCls]: true,
+        [`${prefixCls}--fixed`]: fixed.value,
+        [`${prefixCls}--safe-area-inset-top`]: safeAreaInsetTop.value
       };
     });
 
-    function switchTitle(id: number, name: string) {
-      activeIndex.value = id;
-      // console.log(id);
-      emit('switch-tab', activeIndex.value, name);
-    }
-
     function handleLeft() {
       emit('on-click-back');
     }
@@ -78,24 +59,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 {
@@ -103,12 +68,7 @@ export default create({
       handleLeft,
       handleCenter,
       handleCenterIcon,
-      handleClear,
-      handleSend,
-      handleSlot,
-      handleSends,
-      switchTitle,
-      activeIndex
+      handleRight
     };
   }
 });

+ 14 - 9
src/packages/__VUE/navbar/index.vue

@@ -6,7 +6,7 @@
     </view>
 
     <view class="nut-navbar__title">
-      <view v-if="title" @click="handleCenter">{{ title }}</view>
+      <view v-if="title" class="title" @click="handleCenter">{{ title }}</view>
       <nut-icon v-if="titIcon" class="icon" :name="titIcon" @click="handleCenterIcon"></nut-icon>
       <slot name="content"></slot>
     </view>
@@ -19,7 +19,7 @@
 </template>
 
 <script lang="ts">
-import { computed, ref } from 'vue';
+import { computed, toRefs } from 'vue';
 import { createComponent } from '../../utils/create';
 const { componentName, create } = createComponent('navbar');
 export default create({
@@ -28,18 +28,24 @@ export default create({
     title: { type: String, default: '' }, //中间  文字标题
     titIcon: { type: String, default: '' }, //中间  标题icon
     desc: { type: String, default: '' }, //右侧   按钮文字
-    defaultIndex: {
-      type: Number,
-      default: 0
+    fixed: {
+      type: Boolean,
+      default: false
+    },
+    safeAreaInsetTop: {
+      type: Boolean,
+      default: false
     }
   },
   emits: ['click', 'on-click-back', 'on-click-title', 'on-click-icon', 'on-click-right'],
   setup(props, { emit }) {
-    const activeIndex = ref(props.defaultIndex);
+    const { fixed, safeAreaInsetTop } = toRefs(props);
     const classes = computed(() => {
       const prefixCls = componentName;
       return {
-        [prefixCls]: true
+        [prefixCls]: true,
+        [`${prefixCls}--fixed`]: fixed.value,
+        [`${prefixCls}--safe-area-inset-top`]: safeAreaInsetTop.value
       };
     });
 
@@ -63,8 +69,7 @@ export default create({
       handleLeft,
       handleCenter,
       handleCenterIcon,
-      handleRight,
-      activeIndex
+      handleRight
     };
   }
 });

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

@@ -7,13 +7,6 @@ exports[`should change icon class prefix when using icon prop 1`] = `
 </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`] = `""`;

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

@@ -68,23 +68,6 @@ test('should close popover when clicking the list', async () => {
   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, {

+ 6 - 1
src/packages/__VUE/tag/demo.vue

@@ -3,7 +3,7 @@
     <nut-cell-group title="基础用法">
       <nut-cell title="primary 类型">
         <template v-slot:link>
-          <nut-tag type="primary">标签</nut-tag>
+          <nut-tag type="primary" @click="click">标签</nut-tag>
         </template>
       </nut-cell>
       <nut-cell title="success 类型">
@@ -78,8 +78,13 @@ export default createDemo({
       show.value = false;
     };
 
+    const click = () => {
+      alert('点击事件');
+    };
+
     return {
       close,
+      click,
       show
     };
   }

+ 1 - 0
src/packages/__VUE/tag/doc.md

@@ -159,4 +159,5 @@ export default {
 
 | 事件名称 | 说明     | 回调参数 |
 |----------|----------|----------|
+| click    | 点击事件 | event    |
 | close    | 关闭事件 | event    |

+ 9 - 3
src/packages/__VUE/tag/index.taro.vue

@@ -1,5 +1,5 @@
 <template>
-  <view :class="classes" :style="getStyle()">
+  <view :class="classes" :style="getStyle()" @click="onClose">
     <slot></slot>
     <nut-icon class="nut-tag--close" v-if="closeable" name="close" size="11" @click="onClose"></nut-icon>
   </view>
@@ -37,7 +37,7 @@ export default create({
       default: false
     }
   },
-  emits: ['close'],
+  emits: ['close', 'click'],
   setup(props, { emit }) {
     const { type, color, plain, round, mark, textColor } = toRefs(props);
 
@@ -78,10 +78,16 @@ export default create({
       emit('close', event);
     };
 
+    const onClick = (event: MouseEvent) => {
+      event.stopPropagation();
+      emit('click', event);
+    };
+
     return {
       classes,
       getStyle,
-      onClose
+      onClose,
+      onClick
     };
   }
 });

+ 9 - 3
src/packages/__VUE/tag/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <view :class="classes" :style="getStyle()">
+  <view :class="classes" :style="getStyle()" @click="onClick">
     <slot></slot>
     <nut-icon class="nut-tag--close" v-if="closeable" name="close" size="12" @click="onClose"></nut-icon>
   </view>
@@ -36,7 +36,7 @@ export default create({
       default: false
     }
   },
-  emits: ['close'],
+  emits: ['close', 'click'],
   setup(props, { emit }) {
     const { type, color, plain, round, mark, textColor } = toRefs(props);
 
@@ -77,10 +77,16 @@ export default create({
       emit('close', event);
     };
 
+    const onClick = (event: MouseEvent) => {
+      event.stopPropagation();
+      emit('click', event);
+    };
+
     return {
       classes,
       getStyle,
-      onClose
+      onClose,
+      onClick
     };
   }
 });

+ 34 - 40
src/sites/mobile-taro/vue/src/nav/pages/navbar/index.vue

@@ -1,51 +1,55 @@
 <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"
-      desc="编辑"
-      icon="horizontal-n"
-    >
+    <nut-navbar @on-click-back="back" @on-click-title="title" @on-click-right="rightClick" desc="编辑">
       <template #content>
         <nut-tabs v-model="tab1value" @click="changeTab">
           <nut-tabpane title="商品"> </nut-tabpane>
           <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">
       <template #content>
         <nut-tabs v-model="tab2value" @click="changeTabList">
           <nut-tabpane title="商品"> </nut-tabpane>
@@ -55,7 +59,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>
@@ -64,7 +72,7 @@
 <script lang="ts">
 import { ref, defineComponent } from 'vue';
 export default defineComponent({
-  setup(props, { emit }) {
+  setup({}) {
     const tab1value = ref(0);
     const tab2value = ref(0);
     const methods = {
@@ -77,23 +85,9 @@ export default defineComponent({
       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;