Forráskód Böngészése

feat: drawer close icon placement (#5269)

Netfan 4 hónapja
szülő
commit
376aad5d26

+ 3 - 0
docs/src/components/common-ui/vben-drawer.md

@@ -84,6 +84,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
 | isOpen | 弹窗打开状态 | `boolean` | `false` |
 | loading | 弹窗加载状态 | `boolean` | `false` |
 | closable | 显示关闭按钮 | `boolean` | `true` |
+| closeIconPlacement | 关闭按钮位置 | `'left'\|'right'` | `right` |
 | modal | 显示遮罩 | `boolean` | `true` |
 | header | 显示header | `boolean` | `true` |
 | footer | 显示footer | `boolean\|slot` | `true` |
@@ -129,6 +130,8 @@ const [Drawer, drawerApi] = useVbenDrawer({
 | default        | 默认插槽 - 弹窗内容 |
 | prepend-footer | 取消按钮左侧        |
 | append-footer  | 取消按钮右侧        |
+| close-icon     | 关闭按钮图标        |
+| extra          | 额外内容(标题右侧)  |
 
 ### modalApi
 

+ 7 - 1
packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts

@@ -6,6 +6,8 @@ import type { Component, Ref } from 'vue';
 
 export type DrawerPlacement = 'bottom' | 'left' | 'right' | 'top';
 
+export type CloseIconPlacement = 'left' | 'right';
+
 export interface DrawerProps {
   /**
    * 是否挂载到内容区域
@@ -18,10 +20,14 @@ export interface DrawerProps {
   cancelText?: string;
   class?: ClassType;
   /**
-   * 是否显示右上角的关闭按钮
+   * 是否显示关闭按钮
    * @default true
    */
   closable?: boolean;
+  /**
+   * 关闭按钮的位置
+   */
+  closeIconPlacement?: CloseIconPlacement;
   /**
    * 点击弹窗遮罩是否关闭弹窗
    * @default true

+ 27 - 5
packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue

@@ -10,6 +10,7 @@ import {
 } from '@vben-core/composables';
 import { X } from '@vben-core/icons';
 import {
+  Separator,
   Sheet,
   SheetClose,
   SheetContent,
@@ -33,6 +34,7 @@ interface Props extends DrawerProps {
 
 const props = withDefaults(defineProps<Props>(), {
   appendToMain: false,
+  closeIconPlacement: 'right',
   drawerApi: undefined,
   zIndex: 1000,
 });
@@ -155,11 +157,29 @@ const getAppendTo = computed(() => {
             headerClass,
             {
               'px-4 py-3': closable,
+              'pl-2': closable && closeIconPlacement === 'left',
             },
           )
         "
       >
-        <div>
+        <div class="flex items-center">
+          <SheetClose
+            v-if="closable && closeIconPlacement === 'left'"
+            as-child
+            class="data-[state=open]:bg-secondary ml-[2px] cursor-pointer rounded-full opacity-80 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none"
+          >
+            <slot name="close-icon">
+              <VbenIconButton>
+                <X class="size-4" />
+              </VbenIconButton>
+            </slot>
+          </SheetClose>
+          <Separator
+            v-if="closable && closeIconPlacement === 'left'"
+            class="ml-1 mr-2 h-8"
+            decorative
+            orientation="vertical"
+          />
           <SheetTitle v-if="title" class="text-left">
             <slot name="title">
               {{ title }}
@@ -184,13 +204,15 @@ const getAppendTo = computed(() => {
         <div class="flex-center">
           <slot name="extra"></slot>
           <SheetClose
-            v-if="closable"
+            v-if="closable && closeIconPlacement === 'right'"
             as-child
             class="data-[state=open]:bg-secondary ml-[2px] cursor-pointer rounded-full opacity-80 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none"
           >
-            <VbenIconButton>
-              <X class="size-4" />
-            </VbenIconButton>
+            <slot name="close-icon">
+              <VbenIconButton>
+                <X class="size-4" />
+              </VbenIconButton>
+            </slot>
           </SheetClose>
         </div>
       </SheetHeader>