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

pull/48/MERGE
Vben 2024-09-01 22:33:11 +08:00 committed by GitHub
parent 67f3d63066
commit 3f2dcb8281
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 93 additions and 36 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -50,6 +50,16 @@ export interface DrawerProps {
* @default true * @default true
*/ */
modal?: boolean; modal?: boolean;
/**
*
* @default true
*/
showCancelButton?: boolean;
/**
*
* @default true
*/
showConfirmButton?: boolean;
/** /**
* *
*/ */

View File

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

View File

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

View File

@ -75,6 +75,16 @@ export interface ModalProps {
* @default true * @default true
*/ */
modal?: boolean; modal?: boolean;
/**
*
* @default true
*/
showCancelButton?: boolean;
/**
*
* @default true
*/
showConfirmButton?: boolean;
/** /**
* *
*/ */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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" class="hover:bg-accent flex w-full items-center justify-between rounded-md px-2 py-2"
disabled disabled
> >
<span class="text-sm"><slot></slot></span> <span class="text-sm">
<slot></slot>
</span>
<ToggleGroup <ToggleGroup
v-model="modelValue" v-model="modelValue"
class="gap-2" class="gap-2"

View File

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