瀏覽代碼

fix(@vben/web-ele): fixed some style issues in dark mode (#4298)

Vben 7 月之前
父節點
當前提交
3f2dcb8281

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

@@ -74,6 +74,8 @@ const [Drawer, drawerApi] = useVbenDrawer({
 | closeOnPressEscape | esc 关闭弹窗 | `boolean` | `true` |
 | confirmText | 确认按钮文本 | `string\|slot` | `确认` |
 | cancelText | 取消按钮文本 | `string\|slot` | `取消` |
+| showCancelButton | 显示取消按钮 | `boolean` | `true` |
+| showConfirmButton | 显示确认按钮文本 | `boolean` | `true` |
 | class | modal的class,宽度通过这个配置 | `string` | - |
 | contentClass | modal内容区域的class | `string` | - |
 | footerClass | modal底部区域的class | `string` | - |

+ 2 - 0
docs/src/components/common-ui/vben-modal.md

@@ -84,6 +84,8 @@ const [Modal, modalApi] = useVbenModal({
 | closeOnPressEscape | esc 关闭弹窗 | `boolean` | `true` |
 | confirmText | 确认按钮文本 | `string\|slot` | `确认` |
 | cancelText | 取消按钮文本 | `string\|slot` | `取消` |
+| showCancelButton | 显示取消按钮 | `boolean` | `true` |
+| showConfirmButton | 显示确认按钮文本 | `boolean` | `true` |
 | class | modal的class,宽度通过这个配置 | `string` | - |
 | contentClass | modal内容区域的class | `string` | - |
 | footerClass | modal底部区域的class | `string` | - |

+ 4 - 1
packages/@core/ui-kit/layout-ui/src/components/layout-content.vue

@@ -5,6 +5,7 @@ import type { CSSProperties } from 'vue';
 import { computed } from 'vue';
 
 import { useContentStyle } from '@vben-core/composables';
+import { Slot } from '@vben-core/shadcn-ui';
 
 interface Props {
   /**
@@ -54,7 +55,9 @@ const style = computed((): CSSProperties => {
 
 <template>
   <main ref="contentElement" :style="style" class="bg-background-deep relative">
-    <slot :overlay-style="overlayStyle" name="overlay"></slot>
+    <Slot :style="overlayStyle">
+      <slot name="overlay"></slot>
+    </Slot>
     <slot></slot>
   </main>
 </template>

+ 6 - 2
packages/@core/ui-kit/layout-ui/src/components/layout-sidebar.vue

@@ -217,13 +217,17 @@ function handleMouseenter() {
   if (!expandOnHovering.value) {
     collapse.value = false;
   }
-  isLocked.value = true;
+  if (props.isSidebarMixed) {
+    isLocked.value = true;
+  }
   expandOnHovering.value = true;
 }
 
 function handleMouseleave() {
   emit('leave');
-  isLocked.value = false;
+  if (props.isSidebarMixed) {
+    isLocked.value = false;
+  }
   if (expandOnHover.value) {
     return;
   }

+ 2 - 2
packages/@core/ui-kit/layout-ui/src/vben-layout.vue

@@ -534,8 +534,8 @@ function handleHeaderToggle() {
       >
         <slot name="content"></slot>
 
-        <template #overlay="{ overlayStyle }">
-          <slot :overlay-style="overlayStyle" name="content-overlay"></slot>
+        <template #overlay>
+          <slot name="content-overlay"></slot>
         </template>
       </LayoutContent>
 

+ 2 - 0
packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts

@@ -36,6 +36,8 @@ export class DrawerApi {
       isOpen: false,
       loading: false,
       modal: true,
+      showCancelButton: true,
+      showConfirmButton: true,
       title: '',
     };
 

+ 10 - 0
packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts

@@ -50,6 +50,16 @@ export interface DrawerProps {
    * @default true
    */
   modal?: boolean;
+  /**
+   * 是否显示取消按钮
+   * @default true
+   */
+  showCancelButton?: boolean;
+  /**
+   * 是否显示确认按钮
+   * @default true
+   */
+  showConfirmButton?: boolean;
   /**
    * 弹窗标题
    */

+ 8 - 1
packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue

@@ -54,6 +54,8 @@ const cancelText = usePriorityValue('cancelText', props, state);
 const confirmText = usePriorityValue('confirmText', props, state);
 const closeOnClickModal = usePriorityValue('closeOnClickModal', props, state);
 const closeOnPressEscape = usePriorityValue('closeOnPressEscape', props, state);
+const showCancelButton = usePriorityValue('showCancelButton', props, state);
+const showConfirmButton = usePriorityValue('showConfirmButton', props, state);
 
 watch(
   () => showLoading.value,
@@ -167,12 +169,17 @@ function pointerDownOutside(e: Event) {
       >
         <slot name="prepend-footer"></slot>
         <slot name="footer">
-          <VbenButton variant="ghost" @click="() => drawerApi?.onCancel()">
+          <VbenButton
+            v-if="showCancelButton"
+            variant="ghost"
+            @click="() => drawerApi?.onCancel()"
+          >
             <slot name="cancelText">
               {{ cancelText || $t('cancel') }}
             </slot>
           </VbenButton>
           <VbenButton
+            v-if="showConfirmButton"
             :loading="confirmLoading"
             @click="() => drawerApi?.onConfirm()"
           >

+ 2 - 0
packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts

@@ -40,6 +40,8 @@ export class ModalApi {
       isOpen: false,
       loading: false,
       modal: true,
+      showCancelButton: true,
+      showConfirmButton: true,
       title: '',
     };
 

+ 10 - 0
packages/@core/ui-kit/popup-ui/src/modal/modal.ts

@@ -75,6 +75,16 @@ export interface ModalProps {
    * @default true
    */
   modal?: boolean;
+  /**
+   * 是否显示取消按钮
+   * @default true
+   */
+  showCancelButton?: boolean;
+  /**
+   * 是否显示确认按钮
+   * @default true
+   */
+  showConfirmButton?: boolean;
   /**
    * 弹窗标题
    */

+ 8 - 1
packages/@core/ui-kit/popup-ui/src/modal/modal.vue

@@ -69,6 +69,8 @@ const draggable = usePriorityValue('draggable', props, state);
 const fullscreenButton = usePriorityValue('fullscreenButton', props, state);
 const closeOnClickModal = usePriorityValue('closeOnClickModal', props, state);
 const closeOnPressEscape = usePriorityValue('closeOnPressEscape', props, state);
+const showCancelButton = usePriorityValue('showCancelButton', props, state);
+const showConfirmButton = usePriorityValue('showConfirmButton', props, state);
 
 const shouldFullscreen = computed(
   () => (fullscreen.value && header.value) || isMobile.value,
@@ -238,12 +240,17 @@ function pointerDownOutside(e: Event) {
       >
         <slot name="prepend-footer"></slot>
         <slot name="footer">
-          <VbenButton variant="ghost" @click="() => modalApi?.onCancel()">
+          <VbenButton
+            v-if="showCancelButton"
+            variant="ghost"
+            @click="() => modalApi?.onCancel()"
+          >
             <slot name="cancelText">
               {{ cancelText || $t('cancel') }}
             </slot>
           </VbenButton>
           <VbenButton
+            v-if="showConfirmButton"
             :loading="confirmLoading"
             @click="() => modalApi?.onConfirm()"
           >

+ 1 - 1
packages/@core/ui-kit/shadcn-ui/src/index.ts

@@ -1,2 +1,2 @@
 export * from './components';
-export { VisuallyHidden } from 'radix-vue';
+export { Slot, VisuallyHidden } from 'radix-vue';

+ 22 - 9
packages/effects/hooks/src/use-design-tokens.ts

@@ -1,6 +1,6 @@
 import { reactive, watch } from 'vue';
 
-import { preferences } from '@vben/preferences';
+import { preferences, usePreferences } from '@vben/preferences';
 import { convertToRgb, updateCSSVariables } from '@vben/utils';
 
 /**
@@ -160,53 +160,64 @@ export function useNaiveDesignTokens() {
 }
 
 export function useElementPlusDesignTokens() {
+  const { isDark } = usePreferences();
   const rootStyles = getComputedStyle(document.documentElement);
 
+  const getCssVariableValueRaw = (variable: string) => {
+    return rootStyles.getPropertyValue(variable);
+  };
+
   const getCssVariableValue = (variable: string, isColor: boolean = true) => {
-    const value = rootStyles.getPropertyValue(variable);
+    const value = getCssVariableValueRaw(variable);
     return isColor ? convertToRgb(`hsl(${value})`) : value;
   };
+
   watch(
     () => preferences.theme,
     () => {
       const background = getCssVariableValue('--background');
       const border = getCssVariableValue('--border');
+      const accent = getCssVariableValue('--accent');
+
       const variables: Record<string, string> = {
         '--el-bg-color': background,
         '--el-bg-color-overlay': getCssVariableValue('--popover'),
         '--el-bg-color-page': getCssVariableValue('--background-deep'),
         '--el-border-color': border,
         '--el-border-color-dark': border,
+        '--el-border-color-hover': accent,
         '--el-border-color-light': border,
         '--el-border-color-lighter': border,
-        '--el-border-radius-base': getCssVariableValue('--radius', false),
 
+        '--el-border-radius-base': getCssVariableValue('--radius', false),
         '--el-color-danger': getCssVariableValue('--destructive-500'),
         '--el-color-danger-dark-2': getCssVariableValue('--destructive'),
         '--el-color-danger-light-3': getCssVariableValue('--destructive-400'),
         '--el-color-danger-light-5': getCssVariableValue('--destructive-300'),
         '--el-color-danger-light-7': getCssVariableValue('--destructive-200'),
         '--el-color-danger-light-8': getCssVariableValue('--destructive-100'),
-        '--el-color-danger-light-9': getCssVariableValue('--destructive-50'),
 
+        '--el-color-danger-light-9': getCssVariableValue('--destructive-50'),
         '--el-color-error': getCssVariableValue('--destructive-500'),
         '--el-color-error-dark-2': getCssVariableValue('--destructive'),
         '--el-color-error-light-3': getCssVariableValue('--destructive-400'),
         '--el-color-error-light-5': getCssVariableValue('--destructive-300'),
         '--el-color-error-light-7': getCssVariableValue('--destructive-200'),
         '--el-color-error-light-8': getCssVariableValue('--destructive-100'),
-        '--el-color-error-light-9': getCssVariableValue('--destructive-50'),
 
+        '--el-color-error-light-9': getCssVariableValue('--destructive-50'),
         '--el-color-info-light-8': border,
-        '--el-color-info-light-9': background,
 
+        '--el-color-info-light-9': background,
         '--el-color-primary': getCssVariableValue('--primary-500'),
         '--el-color-primary-dark-2': getCssVariableValue('--primary'),
         '--el-color-primary-light-3': getCssVariableValue('--primary-400'),
         '--el-color-primary-light-5': getCssVariableValue('--primary-300'),
         '--el-color-primary-light-7': getCssVariableValue('--primary-200'),
         '--el-color-primary-light-8': getCssVariableValue('--primary-100'),
-        '--el-color-primary-light-9': getCssVariableValue('--primary-50'),
+        '--el-color-primary-light-9': isDark.value
+          ? accent
+          : getCssVariableValue('--primary-50'),
 
         '--el-color-success': getCssVariableValue('--success-500'),
         '--el-color-success-dark-2': getCssVariableValue('--success'),
@@ -214,18 +225,20 @@ export function useElementPlusDesignTokens() {
         '--el-color-success-light-5': getCssVariableValue('--success-300'),
         '--el-color-success-light-7': getCssVariableValue('--success-200'),
         '--el-color-success-light-8': getCssVariableValue('--success-100'),
-        '--el-color-success-light-9': getCssVariableValue('--success-50'),
 
+        '--el-color-success-light-9': getCssVariableValue('--success-50'),
         '--el-color-warning': getCssVariableValue('--warning-500'),
         '--el-color-warning-dark-2': getCssVariableValue('--warning'),
         '--el-color-warning-light-3': getCssVariableValue('--warning-400'),
         '--el-color-warning-light-5': getCssVariableValue('--warning-300'),
         '--el-color-warning-light-7': getCssVariableValue('--warning-200'),
         '--el-color-warning-light-8': getCssVariableValue('--warning-100'),
-        '--el-color-warning-light-9': getCssVariableValue('--warning-50'),
 
+        '--el-color-warning-light-9': getCssVariableValue('--warning-50'),
         '--el-fill-color-blank': background,
+        '--el-fill-color-light': getCssVariableValue('--accent'),
         '--el-text-color-primary': getCssVariableValue('--foreground'),
+
         '--el-text-color-regular': getCssVariableValue('--foreground'),
       };
       updateCSSVariables(variables, `__vben_design_styles__`);

+ 1 - 5
packages/effects/layouts/src/basic/content/content-spinner.vue

@@ -1,16 +1,12 @@
 <script lang="ts" setup>
-import type { CSSProperties } from 'vue';
-
 import { VbenSpinner } from '@vben-core/shadcn-ui';
 
 import { useContentSpinner } from './use-content-spinner';
 
 defineOptions({ name: 'LayoutContentSpinner' });
 
-defineProps<{ overlayStyle: CSSProperties }>();
-
 const { spinning } = useContentSpinner();
 </script>
 <template>
-  <VbenSpinner :spinning="spinning" :style="overlayStyle" />
+  <VbenSpinner :spinning="spinning" />
 </template>

+ 2 - 5
packages/effects/layouts/src/basic/layout.vue

@@ -295,11 +295,8 @@ const headerSlots = computed(() => {
     <template #content>
       <LayoutContent />
     </template>
-    <template
-      v-if="preferences.transition.loading"
-      #content-overlay="{ overlayStyle }"
-    >
-      <LayoutContentSpinner :overlay-style="overlayStyle" />
+    <template v-if="preferences.transition.loading" #content-overlay>
+      <LayoutContentSpinner />
     </template>
 
     <!-- 页脚 -->

+ 3 - 1
packages/effects/layouts/src/widgets/preferences/blocks/toggle-item.vue

@@ -23,7 +23,9 @@ const modelValue = defineModel<string>();
     class="hover:bg-accent flex w-full items-center justify-between rounded-md px-2 py-2"
     disabled
   >
-    <span class="text-sm"><slot></slot></span>
+    <span class="text-sm">
+      <slot></slot>
+    </span>
     <ToggleGroup
       v-model="modelValue"
       class="gap-2"

+ 8 - 8
playground/src/router/routes/modules/examples.ts

@@ -15,14 +15,6 @@ const routes: RouteRecordRaw[] = [
     name: 'Examples',
     path: '/examples',
     children: [
-      {
-        name: 'EllipsisExample',
-        path: '/examples/ellipsis',
-        component: () => import('#/views/examples/ellipsis/index.vue'),
-        meta: {
-          title: $t('page.examples.ellipsis.title'),
-        },
-      },
       {
         name: 'ModalExample',
         path: '/examples/modal',
@@ -39,6 +31,14 @@ const routes: RouteRecordRaw[] = [
           title: $t('page.examples.drawer.title'),
         },
       },
+      {
+        name: 'EllipsisExample',
+        path: '/examples/ellipsis',
+        component: () => import('#/views/examples/ellipsis/index.vue'),
+        meta: {
+          title: $t('page.examples.ellipsis.title'),
+        },
+      },
     ],
   },
 ];