Ver Fonte

feat: 函数式弹框组件添加全屏、退出全屏操作按钮 (#546)

feat: 函数式弹框组件添加全屏、退出全屏操作按钮
许诺 há 1 ano atrás
pai
commit
0b8412c109

+ 48 - 9
src/components/ReDialog/index.vue

@@ -1,13 +1,17 @@
 <script setup lang="ts">
-import { computed } from "vue";
-import { isFunction } from "@pureadmin/utils";
 import {
-  type DialogOptions,
-  type ButtonProps,
-  type EventType,
+  closeDialog,
   dialogStore,
-  closeDialog
+  type EventType,
+  type ButtonProps,
+  type DialogOptions
 } from "./index";
+import { ref, computed } from "vue";
+import { isFunction } from "@pureadmin/utils";
+import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
+import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
+
+const fullscreen = ref(false);
 
 const footerButtons = computed(() => {
   return (options: DialogOptions) => {
@@ -47,11 +51,22 @@ const footerButtons = computed(() => {
   };
 });
 
+const fullscreenClass = computed(() => {
+  return [
+    "el-icon",
+    "el-dialog__close",
+    "-translate-x-2",
+    "cursor-pointer",
+    "hover:!text-[red]"
+  ];
+});
+
 function eventsCallBack(
   event: EventType,
   options: DialogOptions,
   index: number
 ) {
+  fullscreen.value = options?.fullscreen ?? false;
   if (options?.[event] && isFunction(options?.[event])) {
     return options?.[event]({ options, index });
   }
@@ -69,25 +84,49 @@ function handleClose(
 
 <template>
   <el-dialog
+    class="pure-dialog"
     v-for="(options, index) in dialogStore"
     :key="index"
     v-bind="options"
     v-model="options.visible"
-    @opened="eventsCallBack('open', options, index)"
+    :fullscreen="fullscreen ? true : options?.fullscreen ? true : false"
     @close="handleClose(options, index)"
+    @opened="eventsCallBack('open', options, index)"
     @openAutoFocus="eventsCallBack('openAutoFocus', options, index)"
     @closeAutoFocus="eventsCallBack('closeAutoFocus', options, index)"
   >
     <!-- header -->
     <template
-      v-if="options?.headerRenderer"
+      v-if="options?.fullscreenIcon || options?.headerRenderer"
       #header="{ close, titleId, titleClass }"
     >
+      <div
+        v-if="options?.fullscreenIcon"
+        class="flex items-center justify-between"
+      >
+        <span :id="titleId" :class="titleClass">{{ options?.title }}</span>
+        <i
+          v-if="!options?.fullscreen"
+          :class="fullscreenClass"
+          @click="fullscreen = !fullscreen"
+        >
+          <IconifyIconOffline
+            class="pure-dialog-svg"
+            :icon="
+              options?.fullscreen
+                ? ExitFullscreen
+                : fullscreen
+                ? ExitFullscreen
+                : Fullscreen
+            "
+          />
+        </i>
+      </div>
       <component
+        v-else
         :is="options?.headerRenderer({ close, titleId, titleClass })"
       />
     </template>
-    <!-- default -->
     <component
       v-bind="options?.props"
       :is="options.contentRenderer({ options, index })"

+ 3 - 1
src/components/ReDialog/type.ts

@@ -15,8 +15,10 @@ type DialogProps = {
   title?: string;
   /** `Dialog` 的宽度,默认 `50%` */
   width?: string | number;
-  /** 是否为全屏 `Dialog`,默认 `false` */
+  /** 是否为全屏 `Dialog`(会一直处于全屏状态,除非弹框关闭),默认 `false`,`fullscreen` 和 `fullscreenIcon` 都传时只有 `fullscreen` 会生效 */
   fullscreen?: boolean;
+  /** 是否显示全屏操作图标,默认 `false`,`fullscreen` 和 `fullscreenIcon` 都传时只有 `fullscreen` 会生效 */
+  fullscreenIcon?: boolean;
   /** `Dialog CSS` 中的 `margin-top` 值,默认 `15vh` */
   top?: string;
   /** 是否需要遮罩层,默认 `true` */

+ 4 - 0
src/style/dark.scss

@@ -110,6 +110,10 @@ html.dark {
       &:hover {
         color: rgb(255 255 255 / 85%) !important;
         background-color: rgb(255 255 255 / 12%);
+
+        .pure-dialog-svg {
+          color: rgb(255 255 255 / 85%) !important;
+        }
       }
     }
   }

+ 17 - 0
src/style/element-plus.scss

@@ -69,6 +69,19 @@
   }
 }
 
+.pure-dialog {
+  .pure-dialog-svg {
+    color: var(--el-color-info);
+  }
+
+  .el-dialog__headerbtn {
+    top: 20px;
+    right: 14px;
+    width: 24px;
+    height: 24px;
+  }
+}
+
 /* 全局覆盖element-plus的el-dialog、el-drawer、el-message-box、el-notification组件右上角关闭图标的样式,表现更鲜明 */
 .el-dialog__headerbtn,
 .el-message-box__headerbtn {
@@ -94,6 +107,10 @@
       color: rgb(0 0 0 / 88%) !important;
       text-decoration: none;
       background-color: rgb(0 0 0 / 6%);
+
+      .pure-dialog-svg {
+        color: rgb(0 0 0 / 88%) !important;
+      }
     }
   }
 }

+ 1 - 1
src/views/able/timeline.vue

@@ -70,7 +70,7 @@ const activities = [
           placement="bottom"
         >
           <div class="message">
-            vue-pure-admin是基于Vue3.0+TypeScript+Vite2.0+Element-Plus编写的一套后台管理系统
+            vue-pure-admin是基于Vue3.0+TypeScript+Vite+Element-Plus编写的一套后台管理系统
           </div>
         </el-timeline-item>
       </el-timeline>

+ 5 - 5
src/views/about/index.vue

@@ -28,19 +28,19 @@ Object.keys(devDependencies).forEach(key => {
 
 <template>
   <div>
-    <el-card class="box-card mb-4" shadow="never">
+    <el-card class="mb-4 box-card" shadow="never">
       <template #header>
         <div class="card-header">
           <span class="font-medium">关于</span>
         </div>
       </template>
       <span style="font-size: 15px">
-        Pure-Admin 是一个基于Vue3、Vite2、TypeScript、Element-Plus
+        Pure-Admin 是一个基于Vue3、Vite、TypeScript、Element-Plus
         的中后台解决方案,它可以帮助您快速搭建企业级中后台,提供现成的开箱解决方案及丰富的示例。原则上不收取任何费用及版权,可以放心使用,不过如需二次开源(比如用此平台二次开发并开源)请联系作者获取许可!
       </span>
     </el-card>
 
-    <el-card class="box-card m-4" shadow="never">
+    <el-card class="m-4 box-card" shadow="never">
       <template #header>
         <div class="card-header">
           <span class="font-medium">项目信息</span>
@@ -49,7 +49,7 @@ Object.keys(devDependencies).forEach(key => {
       <PureDescriptions :columns="columns" border :column="3" align="left" />
     </el-card>
 
-    <el-card class="box-card m-4" shadow="never">
+    <el-card class="m-4 box-card" shadow="never">
       <template #header>
         <div class="card-header">
           <span class="font-medium">生产环境依赖</span>
@@ -73,7 +73,7 @@ Object.keys(devDependencies).forEach(key => {
       </el-descriptions>
     </el-card>
 
-    <el-card class="box-card m-4" shadow="never">
+    <el-card class="m-4 box-card" shadow="never">
       <template #header>
         <div class="card-header">
           <span class="font-medium">开发环境依赖</span>

+ 9 - 0
src/views/components/dialog/index.vue

@@ -35,6 +35,14 @@ function onFullscreenClick() {
   });
 }
 
+function onFullscreenIconClick() {
+  addDialog({
+    title: "全屏按钮",
+    fullscreenIcon: true,
+    contentRenderer: () => <p>弹框内容-全屏按钮</p>
+  });
+}
+
 function onModalClick() {
   addDialog({
     title: "无背景遮罩层",
@@ -394,6 +402,7 @@ function onBeforeSureClick() {
       <el-button @click="onBaseClick"> 基本使用 </el-button>
       <el-button @click="onDraggableClick"> 可拖拽 </el-button>
       <el-button @click="onFullscreenClick"> 全屏 </el-button>
+      <el-button @click="onFullscreenIconClick"> 全屏按钮 </el-button>
       <el-button @click="onModalClick"> 无背景遮罩层 </el-button>
       <el-button @click="onStyleClick"> 自定义弹出位置 </el-button>
       <el-button @click="onoOpenDelayClick"> 延时2秒打开弹框 </el-button>

+ 1 - 0
src/views/system/dept/hook.tsx

@@ -120,6 +120,7 @@ export function useDept() {
       },
       width: "40%",
       draggable: true,
+      fullscreenIcon: true,
       closeOnClickModal: false,
       contentRenderer: () => h(editForm, { ref: formRef }),
       beforeSure: (done, { options }) => {