ソースを参照

fix(actionsheet): add new props (#1194)

Drjingfubo 3 年 前
コミット
663ad1757b

+ 8 - 4
src/packages/__VUE/actionsheet/__test__/__snapshots__/index.spec.ts.snap

@@ -10,12 +10,16 @@ exports[`should render sure actionsheet when use custom props 1`] = `
       <view class=\\"nut-popup round popup-bottom popclass\\" style=\\"z-index: 2000; animation-duration: 0.3s;\\">
         <view class=\\"nut-actionsheet-panel\\">
           <!--v-if-->
-          <!--v-if-->
-          <view class=\\"nut-actionsheet-menu\\">
-            <view class=\\"nut-actionsheet-item\\" style=\\"color: rgb(26, 26, 26);\\">选项一<view class=\\"subdesc\\">描述信息</view>
+          <view>
+            <!--v-if-->
+            <view class=\\"nut-actionsheet-menu\\">
+              <view class=\\"nut-actionsheet-item\\">
+                <view>选项一</view>
+                <view class=\\"subdesc\\">描述信息</view>
+              </view>
             </view>
+            <!--v-if-->
           </view>
-          <!--v-if-->
         </view>
         <!--v-if-->
       </view>

+ 28 - 4
src/packages/__VUE/actionsheet/demo.vue

@@ -20,8 +20,20 @@
       <div class="selected-option" v-html="state.val4"></div>
     </nut-cell>
 
+    <h2>自定义</h2>
+
+    <nut-cell :isLink="true" @click="switchActionSheet('isVisible5')">
+      <span><label>自定义内容</label></span>
+      <div class="selected-option"></div>
+    </nut-cell>
+
     <!-- demo 基础用法 -->
-    <nut-actionsheet v-model:visible="state.isVisible1" :menu-items="menuItemsOne" @choose="chooseItem">
+    <nut-actionsheet
+      :safe-area-inset-bottom="true"
+      v-model:visible="state.isVisible1"
+      :menu-items="menuItemsOne"
+      @choose="chooseItem"
+    >
     </nut-actionsheet>
     <!-- demo(带取消按钮) -->
     <nut-actionsheet
@@ -34,6 +46,7 @@
     <!-- 展示描述信息 -->
     <nut-actionsheet
       v-model:visible="state.isVisible3"
+      title="标题"
       :description="state.desc"
       :menu-items="menuItemsTwo"
       @choose="chooseItemThree"
@@ -48,6 +61,10 @@
       @choose="chooseItemFour"
       :choose-tag-value="state.chooseTagValue"
     ></nut-actionsheet>
+    <!-- 自定义面板-->
+    <nut-actionsheet v-model:visible="state.isVisible5" title="标题">
+      <div class="custom-content">自定义内容</div>
+    </nut-actionsheet>
   </div>
 </template>
 
@@ -56,7 +73,9 @@ import { reactive } from 'vue';
 interface Item {
   name: string;
   subname?: string;
+  color?: string;
   disable?: boolean;
+  loading?: boolean;
 }
 export default {
   props: {},
@@ -72,7 +91,7 @@ export default {
       val3: '',
       val4: '',
       desc: '这是一段描述信息',
-      chooseTagValue: '着色选项'
+      chooseTagValue: '选中选项'
     });
     const menuItemsOne: Item[] = [
       {
@@ -94,16 +113,21 @@ export default {
       },
       {
         name: '选项三',
+        color: 'red',
         subname: '描述信息'
       }
     ];
     const menuItemsThree: Item[] = [
       {
-        name: '着色选项'
+        name: '选中选项'
       },
       {
         name: '禁用选项',
         disable: true
+      },
+      {
+        name: '加载选项',
+        loading: true
       }
     ];
     const switchActionSheet = (param: 'isVisible1' | 'isVisible2' | 'isVisible3' | 'isVisible4') => {
@@ -148,7 +172,7 @@ export default {
 .nut-cell {
   justify-content: space-between;
 }
-.myContent {
+.custom-content {
   padding: 10px 10px 160px;
 }
 </style>

+ 17 - 6
src/packages/__VUE/actionsheet/doc.md

@@ -265,21 +265,32 @@ export default {
 
 | 字段             | 说明                                   | 类型    | 默认值    |
 |------------------|----------------------------------------|---------|-----------|
-| cancel-txt       | 取消文案                               | String  | '取消'    |
+| v-model:visible       | 遮罩层可见                             | Boolean | false|
 | menu-items       | 列表项                                 | Array   | [ ]       |
-| option-tag       | 设置列表项展示使用参数                 | String  | 'name'    |
-| v-model:visible       | 遮罩层可见                             | Boolean | false     |
-| option-sub-tag   | 设置列表项描述展示使用参数             | String  | 'subname' |
+| option-tag       | 设置列表项标题展示使用参数                 | String  | 'name'    |
+| option-sub-tag   | 设置列表项二级标题展示使用参数             | String  | 'subname' |
 | choose-tag-value | 设置选中项的值,和'option-tag'的值对应 | String  | ''        |
+| color            | 选中项颜色,当 choose-tag-value == option-tag的值 生效  | String  | '#ee0a24' |
 | title            | 设置列表项标题                         | String  | ''        |
 | description      | 设置列表项副标题/描述                  | String  | ''        |
-| color            | 高亮颜色                               | String  | '#ee0a24' |
+| cancel-txt       | 取消文案                               | String  | '取消'   |
 | close-abled      | 遮罩层是否可关闭                       | Boolean | true      |
+|safe-area-inset-bottom	|是否开启iphone系列全面屏底部安全区适配|	Boolean	|false
 
+## menu-items数据结构
+
+| 字段   | 说明               | 类型                          |
+|--------|--------------------|-----------------------------------|
+| name | 标题      | String    |
+| subname | 二级标题 | String          |
+| color | 选项字体颜色(选中项颜色层级>选项字体颜色) | String          |
+| loading | 是否为loading状态 | Boolean          |
+| disable | 是否为禁用状态 | Boolean       |
 
 ## Event
 
 | 字段   | 说明               | 回调参数                          |
 |--------|--------------------|-----------------------------------|
 | choose | 选择之后触发       | 选中列表项item, 选中的索引值index |
-| cancel | 点击取消文案时触发 | 无                                |
+| cancel | 点击取消文案时触发 | 无                                |
+| close | 点击遮罩层时触发 | event: Event                              |

+ 8 - 0
src/packages/__VUE/actionsheet/index.scss

@@ -1,5 +1,9 @@
 .nut-actionsheet-panel {
   display: block;
+  &.nut-actionsheet-safebottom {
+    margin-bottom: constant(safe-area-inset-bottom);
+    margin-bottom: env(safe-area-inset-bottom);
+  }
   .nut-actionsheet-title {
     display: block;
     padding: 10px;
@@ -49,6 +53,7 @@
   .desc {
     font-size: $actionsheet-item-font-size;
     color: #999;
+    cursor: default;
   }
 
   .subdesc {
@@ -61,6 +66,9 @@
     color: #e1e1e1 !important;
     cursor: not-allowed;
   }
+  .nut-actionsheet-item-loading {
+    cursor: default;
+  }
 
   .nut-actionsheet-cancel {
     margin-top: 5px;

+ 36 - 40
src/packages/__VUE/actionsheet/index.taro.vue

@@ -1,43 +1,36 @@
 <template>
   <view :class="classes">
-    <nut-popup
-      pop-class="popclass"
-      :visible="visible"
-      position="bottom"
-      round
-      @click-overlay="close"
-    >
-      <view class="nut-actionsheet-panel">
+    <nut-popup pop-class="popclass" :visible="visible" position="bottom" round @click-overlay="close">
+      <view class="nut-actionsheet-panel" :class="{ 'nut-actionsheet-safebottom': safeAreaInsetBottom }">
         <view v-if="title" class="nut-actionsheet-title">{{ title }}</view>
-        <view class="nut-actionsheet-item desc" v-if="description">{{
-          description
-        }}</view>
-        <view class="nut-actionsheet-menu" v-if="menuItems.length">
-          <view
-            v-for="(item, index) of menuItems"
-            class="nut-actionsheet-item"
-            :class="{ 'nut-actionsheet-item-disabled': item.disable }"
-            :style="{ color: isHighlight(item) }"
-            :key="index"
-            @click="chooseItem(item, index)"
-            >{{ item[optionTag]
-            }}<view class="subdesc">{{ item[optionSubTag] }}</view>
+        <slot></slot>
+        <view v-if="!slotDefault">
+          <view class="nut-actionsheet-item desc" v-if="description">{{ description }}</view>
+          <view class="nut-actionsheet-menu" v-if="menuItems.length">
+            <view
+              v-for="(item, index) of menuItems"
+              class="nut-actionsheet-item"
+              :class="{ 'nut-actionsheet-item-disabled': item.disable, 'nut-actionsheet-item-loading': item.loading }"
+              :style="{ color: isHighlight(item) || item.color }"
+              :key="index"
+              @click="chooseItem(item, index)"
+            >
+              <nut-icon v-if="item.loading" name="loading"> </nut-icon>
+              <view v-else> {{ item[optionTag] }}</view>
+              <view class="subdesc">{{ item[optionSubTag] }}</view>
+            </view>
+          </view>
+          <view class="nut-actionsheet-cancel" v-if="cancelTxt" @click="cancelActionSheet">
+            {{ cancelTxt }}
           </view>
-        </view>
-        <view
-          class="nut-actionsheet-cancel"
-          v-if="cancelTxt"
-          @click="cancelActionSheet"
-        >
-          {{ cancelTxt }}
         </view>
       </view>
     </nut-popup>
   </view>
 </template>
-<script>
+<script lang="ts">
 import { createComponent } from '../../utils/create';
-import { computed } from 'vue';
+import { computed, useSlots } from 'vue';
 const { componentName, create } = createComponent('actionsheet');
 import { popupProps } from '../popup/index.vue';
 export default create({
@@ -74,11 +67,16 @@ export default create({
     menuItems: {
       type: Array,
       default: () => []
+    },
+    safeAreaInsetBottom: {
+      type: Boolean,
+      default: false
     }
   },
-  emits: ['cancel', 'choose', 'update:visible'],
+  emits: ['cancel', 'choose', 'update:visible', 'close'],
 
   setup(props, { emit }) {
+    const slotDefault = !!useSlots().default;
     const classes = computed(() => {
       const prefixCls = componentName;
       return {
@@ -86,11 +84,8 @@ export default create({
       };
     });
 
-    const isHighlight = (item) => {
-      return props.chooseTagValue &&
-        props.chooseTagValue === item[props.optionTag]
-        ? props.color
-        : '#1a1a1a';
+    const isHighlight = (item: { [x: string]: string }) => {
+      return props.chooseTagValue && props.chooseTagValue === item[props.optionTag] ? props.color : '';
     };
 
     const cancelActionSheet = () => {
@@ -98,19 +93,20 @@ export default create({
       emit('update:visible', false);
     };
 
-    const chooseItem = (item, index) => {
-      if (!item.disable) {
+    const chooseItem = (item: { disable: boolean; loading: boolean }, index: any) => {
+      if (!item.disable && !item.loading) {
         emit('choose', item, index);
         emit('update:visible', false);
       }
     };
 
-    const close = () => {
-      emit('close');
+    const close = (e: Event) => {
+      emit('close', e);
       emit('update:visible', false);
     };
 
     return {
+      slotDefault,
       isHighlight,
       cancelActionSheet,
       chooseItem,

+ 32 - 20
src/packages/__VUE/actionsheet/index.vue

@@ -8,22 +8,28 @@
       round
       @click-overlay="close"
     >
-      <view class="nut-actionsheet-panel">
+      <view class="nut-actionsheet-panel" :class="{ 'nut-actionsheet-safebottom': safeAreaInsetBottom }">
         <view v-if="title" class="nut-actionsheet-title">{{ title }}</view>
-        <view class="nut-actionsheet-item desc" v-if="description">{{ description }}</view>
-        <view class="nut-actionsheet-menu" v-if="menuItems.length">
-          <view
-            v-for="(item, index) of menuItems"
-            class="nut-actionsheet-item"
-            :class="{ 'nut-actionsheet-item-disabled': item.disable }"
-            :style="{ color: isHighlight(item) }"
-            :key="index"
-            @click="chooseItem(item, index)"
-            >{{ item[optionTag] }}<view class="subdesc">{{ item[optionSubTag] }}</view>
+        <slot></slot>
+        <view v-if="!slotDefault">
+          <view class="nut-actionsheet-item desc" v-if="description">{{ description }}</view>
+          <view class="nut-actionsheet-menu" v-if="menuItems.length">
+            <view
+              v-for="(item, index) of menuItems"
+              class="nut-actionsheet-item"
+              :class="{ 'nut-actionsheet-item-disabled': item.disable, 'nut-actionsheet-item-loading': item.loading }"
+              :style="{ color: isHighlight(item) || item.color }"
+              :key="index"
+              @click="chooseItem(item, index)"
+            >
+              <nut-icon v-if="item.loading" name="loading"> </nut-icon>
+              <view v-else> {{ item[optionTag] }}</view>
+              <view class="subdesc">{{ item[optionSubTag] }}</view>
+            </view>
+          </view>
+          <view class="nut-actionsheet-cancel" v-if="cancelTxt" @click="cancelActionSheet">
+            {{ cancelTxt }}
           </view>
-        </view>
-        <view class="nut-actionsheet-cancel" v-if="cancelTxt" @click="cancelActionSheet">
-          {{ cancelTxt }}
         </view>
       </view>
     </nut-popup>
@@ -31,7 +37,7 @@
 </template>
 <script lang="ts">
 import { createComponent } from '../../utils/create';
-import { computed } from 'vue';
+import { computed, useSlots } from 'vue';
 import { popupProps } from '../popup/index.vue';
 const { componentName, create } = createComponent('actionsheet');
 export default create({
@@ -72,11 +78,16 @@ export default create({
     isWrapTeleport: {
       type: Boolean,
       default: true
+    },
+    safeAreaInsetBottom: {
+      type: Boolean,
+      default: false
     }
   },
   emits: ['cancel', 'close', 'choose', 'update:visible'],
 
   setup(props, { emit }) {
+    const slotDefault = !!useSlots().default;
     const classes = computed(() => {
       const prefixCls = componentName;
       return {
@@ -85,7 +96,7 @@ export default create({
     });
 
     const isHighlight = (item: { [x: string]: string }) => {
-      return props.chooseTagValue && props.chooseTagValue === item[props.optionTag] ? props.color : '#1a1a1a';
+      return props.chooseTagValue && props.chooseTagValue === item[props.optionTag] ? props.color : '';
     };
 
     const cancelActionSheet = () => {
@@ -93,19 +104,20 @@ export default create({
       emit('update:visible', false);
     };
 
-    const chooseItem = (item: { disable: any }, index: any) => {
-      if (!item.disable) {
+    const chooseItem = (item: { disable: boolean; loading: boolean }, index: any) => {
+      if (!item.disable && !item.loading) {
         emit('choose', item, index);
         emit('update:visible', false);
       }
     };
 
-    const close = () => {
-      emit('close');
+    const close = (e: Event) => {
+      emit('close', e);
       emit('update:visible', false);
     };
 
     return {
+      slotDefault,
       isHighlight,
       cancelActionSheet,
       chooseItem,

+ 32 - 16
src/sites/mobile-taro/vue/src/feedback/pages/actionsheet/index.vue

@@ -1,19 +1,11 @@
 <template>
   <div class="demo">
     <h2>基本用法</h2>
-    <nut-cell
-      :show-icon="true"
-      :isLink="true"
-      @click="switchActionSheet('isVisible1')"
-    >
+    <nut-cell :show-icon="true" :isLink="true" @click="switchActionSheet('isVisible1')">
       <span><label>基础用法</label></span>
       <div class="selected-option" v-html="state.val1"></div>
     </nut-cell>
-    <nut-cell
-      :showIcon="true"
-      :isLink="true"
-      @click="switchActionSheet('isVisible2')"
-    >
+    <nut-cell :showIcon="true" :isLink="true" @click="switchActionSheet('isVisible2')">
       <span><label>展示取消按钮</label></span>
       <div class="selected-option" v-html="state.val2"></div>
     </nut-cell>
@@ -25,10 +17,19 @@
 
     <nut-cell :isLink="true" @click="switchActionSheet('isVisible4')">
       <span><label>选项状态</label></span>
+      <div class="selected-option" v-html="state.val4"></div>
+    </nut-cell>
+
+    <h2>自定义</h2>
+
+    <nut-cell :isLink="true" @click="switchActionSheet('isVisible5')">
+      <span><label>自定义内容</label></span>
+      <div class="selected-option"></div>
     </nut-cell>
 
     <!-- demo 基础用法 -->
     <nut-actionsheet
+      :safe-area-inset-bottom="true"
       v-model:visible="state.isVisible1"
       :menu-items="menuItemsOne"
       @choose="chooseItem"
@@ -45,6 +46,7 @@
     <!-- 展示描述信息 -->
     <nut-actionsheet
       v-model:visible="state.isVisible3"
+      title="标题"
       :description="state.desc"
       :menu-items="menuItemsTwo"
       @choose="chooseItemThree"
@@ -56,8 +58,13 @@
       v-model:visible="state.isVisible4"
       cancel-txt="取消"
       :menu-items="menuItemsThree"
+      @choose="chooseItemFour"
       :choose-tag-value="state.chooseTagValue"
     ></nut-actionsheet>
+    <!-- 自定义面板-->
+    <nut-actionsheet v-model:visible="state.isVisible5" title="标题">
+      <div class="custom-content">自定义内容</div>
+    </nut-actionsheet>
   </div>
 </template>
 
@@ -66,7 +73,9 @@ import { reactive } from 'vue';
 interface Item {
   name: string;
   subname?: string;
+  color?: string;
   disable?: boolean;
+  loading?: boolean;
 }
 export default {
   props: {},
@@ -82,7 +91,7 @@ export default {
       val3: '',
       val4: '',
       desc: '这是一段描述信息',
-      chooseTagValue: '着色选项'
+      chooseTagValue: '选中选项'
     });
     const menuItemsOne: Item[] = [
       {
@@ -104,21 +113,24 @@ export default {
       },
       {
         name: '选项三',
+        color: 'red',
         subname: '描述信息'
       }
     ];
     const menuItemsThree: Item[] = [
       {
-        name: '着色选项'
+        name: '选中选项'
       },
       {
         name: '禁用选项',
         disable: true
+      },
+      {
+        name: '加载选项',
+        loading: true
       }
     ];
-    const switchActionSheet = (
-      param: 'isVisible1' | 'isVisible2' | 'isVisible3' | 'isVisible4'
-    ) => {
+    const switchActionSheet = (param: 'isVisible1' | 'isVisible2' | 'isVisible3' | 'isVisible4') => {
       state[param] = !state[param];
     };
 
@@ -133,6 +145,9 @@ export default {
     function chooseItemThree(itemParams: Item) {
       state.val3 = itemParams.name;
     }
+    function chooseItemFour(itemParams: Item) {
+      state.val4 = itemParams.name;
+    }
 
     return {
       state,
@@ -142,6 +157,7 @@ export default {
       chooseItem,
       chooseItemTwo,
       chooseItemThree,
+      chooseItemFour,
       switchActionSheet
     };
   }
@@ -156,7 +172,7 @@ export default {
 .nut-cell {
   justify-content: space-between;
 }
-.myContent {
+.custom-content {
   padding: 10px 10px 160px;
 }
 </style>