perf: reorganize the icons and reduce the volume

This commit is contained in:
vince 2024-07-17 22:25:27 +08:00
parent cb161eab89
commit 910a3553ac
54 changed files with 341 additions and 404 deletions

View File

@ -4,7 +4,7 @@ import { useRouter } from 'vue-router';
import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
import { LOGIN_PATH } from '@vben/constants';
import { IcRoundCreditScore, MdiDriveDocument, MdiGithub } from '@vben/icons';
import { BookOpenText, CircleHelp, MdiGithub } from '@vben/icons';
import {
BasicLayout,
LockScreen,
@ -61,7 +61,7 @@ const menus = computed(() => [
target: '_blank',
});
},
icon: MdiDriveDocument,
icon: BookOpenText,
text: $t('widgets.document'),
},
{
@ -79,7 +79,7 @@ const menus = computed(() => [
target: '_blank',
});
},
icon: IcRoundCreditScore,
icon: CircleHelp,
text: $t('widgets.qa'),
},
]);

View File

@ -7,6 +7,7 @@ const routes: RouteRecordRaw[] = [
{
component: BasicLayout,
meta: {
icon: 'lucide:layout-dashboard',
order: -1,
title: $t('page.dashboard.title'),
},
@ -20,6 +21,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('#/views/dashboard/analytics/index.vue'),
meta: {
affixTab: true,
icon: 'lucide:area-chart',
title: $t('page.dashboard.analytics'),
},
},

View File

@ -24,7 +24,7 @@ const routes: RouteRecordRaw[] = [
component: () => import('#/views/_core/vben/about/index.vue'),
meta: {
badgeType: 'dot',
icon: 'mdi:creative-commons',
icon: 'lucide:copyright',
title: $t('page.vben.about'),
},
},
@ -33,7 +33,7 @@ const routes: RouteRecordRaw[] = [
path: 'document',
component: IFrameView,
meta: {
icon: 'mdi:flame-circle',
icon: 'lucide:book-open-text',
iframeSrc: 'https://doc.vvbin.cn/',
keepAlive: true,
title: $t('page.vben.document'),

View File

@ -66,7 +66,7 @@
"@vue/test-utils": "^2.4.6",
"cross-env": "^7.0.3",
"cspell": "^8.11.0",
"husky": "^9.0.11",
"husky": "^9.1.0",
"is-ci": "^3.0.1",
"jsdom": "^24.1.0",
"rimraf": "^6.0.1",

View File

@ -4,12 +4,7 @@ import type { Preferences } from './types';
import { markRaw, reactive, readonly, watch } from 'vue';
import {
StorageManager,
generatorColorVariables,
merge,
updateCSSVariables,
} from '@vben-core/toolkit';
import { StorageManager, merge } from '@vben-core/toolkit';
import {
breakpointsTailwind,
@ -18,7 +13,7 @@ import {
} from '@vueuse/core';
import { defaultPreferences } from './config';
import { BUILT_IN_THEME_PRESETS } from './constants';
import { updateCSSVariables } from './update-css-variables';
const STORAGE_KEY = 'preferences';
const STORAGE_KEY_LOCALE = `${STORAGE_KEY}-locale`;
@ -48,11 +43,10 @@ class PreferenceManager {
});
constructor() {
this.cache = new StorageManager();
// this.flattenedState = reactive(flattenObject(this.state));
this.savePreferences = useDebounceFn(
(preference: Preferences) => this._savePreferences(preference),
100,
200,
);
}
@ -76,7 +70,7 @@ class PreferenceManager {
const themeUpdates = updates.theme || {};
const appUpdates = updates.app || {};
if (themeUpdates && Object.keys(themeUpdates).length > 0) {
this.updateTheme(this.state);
updateCSSVariables(this.state);
}
if (
@ -130,7 +124,7 @@ class PreferenceManager {
this.updatePreferences({
theme: { mode: isDark ? 'dark' : 'light' },
});
this.updateTheme(this.state);
updateCSSVariables(this.state);
});
}
@ -153,101 +147,6 @@ class PreferenceManager {
}
}
/**
* CSS
* @param preference - HSL CSS
*/
private updateMainColors(preference: Preferences) {
if (!preference.theme) {
return;
}
const { colorDestructive, colorPrimary, colorSuccess, colorWarning } =
preference.theme;
const colorVariables = generatorColorVariables([
{ color: colorPrimary, name: 'primary' },
{ alias: 'warning', color: colorWarning, name: 'yellow' },
{ alias: 'success', color: colorSuccess, name: 'green' },
{ alias: 'destructive', color: colorDestructive, name: 'red' },
]);
if (colorPrimary) {
document.documentElement.style.setProperty(
'--primary',
colorVariables['--primary-500'],
);
}
if (colorVariables['--green-500']) {
colorVariables['--success'] = colorVariables['--green-500'];
}
if (colorVariables['--yellow-500']) {
colorVariables['--warning'] = colorVariables['--yellow-500'];
}
if (colorVariables['--red-500']) {
colorVariables['--destructive'] = colorVariables['--red-500'];
}
updateCSSVariables(colorVariables);
}
/**
*
* @param preferences -
*/
private updateTheme(preferences: Preferences) {
// 当修改到颜色变量时,更新 css 变量
const root = document.documentElement;
if (!root) {
return;
}
const theme = preferences?.theme ?? {};
const { builtinType, colorPrimary, mode, radius } = theme;
if (Reflect.has(theme, 'mode')) {
const dark = isDarkTheme(mode);
root.classList.toggle('dark', dark);
}
if (Reflect.has(theme, 'builtinType')) {
const rootTheme = root.dataset.theme;
if (rootTheme !== builtinType) {
root.dataset.theme = builtinType;
}
}
const currentBuiltType = BUILT_IN_THEME_PRESETS.find(
(item) => item.type === builtinType,
);
let builtinTypeColorPrimary: string | undefined = '';
if (currentBuiltType) {
const isDark = isDarkTheme(this.state.theme.mode);
const color = isDark
? currentBuiltType.darkPrimaryColor || currentBuiltType.primaryColor
: currentBuiltType.primaryColor;
builtinTypeColorPrimary = color || currentBuiltType.color;
}
if (
builtinTypeColorPrimary ||
Reflect.has(theme, 'colorPrimary') ||
Reflect.has(theme, 'colorDestructive') ||
Reflect.has(theme, 'colorSuccess') ||
Reflect.has(theme, 'colorWarning')
) {
preferences.theme.colorPrimary = builtinTypeColorPrimary || colorPrimary;
this.updateMainColors(preferences);
}
if (Reflect.has(theme, 'radius')) {
document.documentElement.style.setProperty('--radius', `${radius}rem`);
}
}
clearCache() {
[STORAGE_KEY, STORAGE_KEY_LOCALE, STORAGE_KEY_THEME].forEach((key) => {
this.cache?.removeItem(key);

View File

@ -0,0 +1,118 @@
import type { Preferences } from './types';
import {
updateCSSVariables as executeUpdateCSSVariables,
generatorColorVariables,
} from '@vben-core/toolkit';
import { BUILT_IN_THEME_PRESETS } from './constants';
/**
* CSS CSS
* @param preferences -
*/
function updateCSSVariables(preferences: Preferences) {
// 当修改到颜色变量时,更新 css 变量
const root = document.documentElement;
if (!root) {
return;
}
const theme = preferences?.theme ?? {};
const { builtinType, colorPrimary, mode, radius } = theme;
// html 设置 dark 类
if (Reflect.has(theme, 'mode')) {
const dark = isDarkTheme(mode);
root.classList.toggle('dark', dark);
}
// html 设置 data-theme=[builtinType]
if (Reflect.has(theme, 'builtinType')) {
const rootTheme = root.dataset.theme;
if (rootTheme !== builtinType) {
root.dataset.theme = builtinType;
}
}
// 获取当前的内置主题
const currentBuiltType = BUILT_IN_THEME_PRESETS.find(
(item) => item.type === builtinType,
);
let builtinTypeColorPrimary: string | undefined = '';
if (currentBuiltType) {
const isDark = isDarkTheme(preferences.theme.mode);
// 设置不同主题的主要颜色
const color = isDark
? currentBuiltType.darkPrimaryColor || currentBuiltType.primaryColor
: currentBuiltType.primaryColor;
builtinTypeColorPrimary = color || currentBuiltType.color;
}
// 如果内置主题颜色和自定义颜色都不存在,则不更新主题颜色
if (
builtinTypeColorPrimary ||
Reflect.has(theme, 'colorPrimary') ||
Reflect.has(theme, 'colorDestructive') ||
Reflect.has(theme, 'colorSuccess') ||
Reflect.has(theme, 'colorWarning')
) {
preferences.theme.colorPrimary = builtinTypeColorPrimary || colorPrimary;
updateMainColorVariables(preferences);
}
// 更新圆角
if (Reflect.has(theme, 'radius')) {
document.documentElement.style.setProperty('--radius', `${radius}rem`);
}
}
/**
* CSS
* @param preference - HSL CSS
*/
function updateMainColorVariables(preference: Preferences) {
if (!preference.theme) {
return;
}
const { colorDestructive, colorPrimary, colorSuccess, colorWarning } =
preference.theme;
const colorVariables = generatorColorVariables([
{ color: colorPrimary, name: 'primary' },
{ alias: 'warning', color: colorWarning, name: 'yellow' },
{ alias: 'success', color: colorSuccess, name: 'green' },
{ alias: 'destructive', color: colorDestructive, name: 'red' },
]);
if (colorPrimary) {
document.documentElement.style.setProperty(
'--primary',
colorVariables['--primary-500'],
);
}
if (colorVariables['--green-500']) {
colorVariables['--success'] = colorVariables['--green-500'];
}
if (colorVariables['--yellow-500']) {
colorVariables['--warning'] = colorVariables['--yellow-500'];
}
if (colorVariables['--red-500']) {
colorVariables['--destructive'] = colorVariables['--red-500'];
}
executeUpdateCSSVariables(colorVariables);
}
function isDarkTheme(theme: string) {
let dark = theme === 'dark';
if (theme === 'auto') {
dark = window.matchMedia('(prefers-color-scheme: dark)').matches;
}
return dark;
}
export { updateCSSVariables };

View File

@ -27,6 +27,10 @@ function usePreferences() {
return isDarkTheme(preferences.theme.mode);
});
const isMobile = computed(() => {
return appPreferences.value.isMobile;
});
const theme = computed(() => {
return isDark.value ? 'dark' : 'light';
});
@ -35,7 +39,7 @@ function usePreferences() {
* @zh_CN
*/
const layout = computed(() =>
appPreferences.value.isMobile ? 'sidebar-nav' : appPreferences.value.layout,
isMobile.value ? 'sidebar-nav' : appPreferences.value.layout,
);
/**
@ -109,6 +113,16 @@ function usePreferences() {
return appPreferences.value.authPageLayout === 'panel-center';
});
/**
* @zh_CN
* full-content模式
*/
const contentIsMaximize = computed(() => {
const headerIsHidden = preferences.header.hidden;
const sidebarIsHidden = preferences.sidebar.hidden;
return headerIsHidden && sidebarIsHidden && !isFullContent.value;
});
/**
* @zh_CN
*/
@ -138,17 +152,6 @@ function usePreferences() {
return enable && globalPreferences;
});
/**
* @zh_CN
* full-content模式
*/
const contentIsMaximize = computed(() => {
const headerIsHidden = preferences.header.hidden;
const sidebarIsHidden = preferences.sidebar.hidden;
return headerIsHidden && sidebarIsHidden && !isFullContent.value;
});
return {
authPanelCenter,
authPanelLeft,
@ -163,6 +166,7 @@ function usePreferences() {
isFullContent,
isHeaderNav,
isMixedNav,
isMobile,
isSideMixedNav,
isSideMode,
isSideNav,

View File

@ -15,7 +15,7 @@
--card-foreground: 210 40% 98%;
/* Background color for popovers such as <DropdownMenu />, <HoverCard />, <Popover /> */
--popover: 222.82deg 8.43% 16.27%;
--popover: 222.82deg 8.43% 12.27%;
--popover-foreground: 210 40% 98%;
/* Muted backgrounds such as <TabsList />, <Skeleton /> and <Switch /> */

View File

@ -36,6 +36,7 @@
},
"dependencies": {
"@iconify/vue": "^4.1.2",
"lucide-vue-next": "^0.408.0",
"vue": "^3.4.32"
}
}

View File

@ -1,5 +1,5 @@
export * from './create-icon';
export * from './material';
export * from './mdi';
export * from './lucide';
export * from './mdi';
export * from '@iconify/vue';

View File

@ -0,0 +1,46 @@
export {
ArrowDown,
ArrowLeft,
ArrowLeftToLine,
ArrowRightLeft,
ArrowRightToLine,
ArrowUp,
ArrowUpToLine,
Bell,
BookOpenText,
ChevronDown,
ChevronRight,
CircleHelp,
Copy,
CornerDownLeft,
Disc3 as IconDefault,
Ellipsis,
ExternalLink,
Eye,
EyeOff,
FoldHorizontal,
Fullscreen,
Github,
InspectionPanel,
Languages,
LoaderCircle,
LockKeyhole,
LogOut,
MailCheck,
Maximize,
Menu,
Minimize,
Minimize2,
MoonStar,
Palette,
PanelLeft,
PanelRight,
RotateCw,
Search,
SearchX,
Sun,
SunMoon,
SwatchBook,
UserRoundPen,
X,
} from 'lucide-vue-next';

View File

@ -1,88 +0,0 @@
import { createIconifyIcon } from './create-icon';
export const IconDefault = createIconifyIcon('ic:round-auto-awesome');
export const IcRoundKeyboardArrowDown = createIconifyIcon(
'ic:round-keyboard-arrow-down',
);
export const IcRoundChevronRight = createIconifyIcon('ic:round-chevron-right');
export const IcRoundMenu = createIconifyIcon('ic:round-menu');
export const IcRoundMoreHoriz = createIconifyIcon('ic:round-more-horiz');
export const IcRoundFitScreen = createIconifyIcon('ic:round-fit-screen');
export const IcTwotoneFitScreen = createIconifyIcon('ic:twotone-fit-screen');
export const IcRoundColorLens = createIconifyIcon('ic:round-color-lens');
export const IcRoundMoreVert = createIconifyIcon('ic:round-more-vert');
export const IcRoundFullscreen = createIconifyIcon('ic:round-fullscreen');
export const IcRoundFullscreenExit = createIconifyIcon(
'ic:round-fullscreen-exit',
);
export const IcRoundClose = createIconifyIcon('ic:round-close');
export const IcRoundRestartAlt = createIconifyIcon('ic:round-restart-alt');
export const IcRoundLogout = createIconifyIcon('ic:round-logout');
export const IcOutlineVisibility = createIconifyIcon('ic:outline-visibility');
export const IcOutlineVisibilityOff = createIconifyIcon(
'ic:outline-visibility-off',
);
export const IcRoundSearch = createIconifyIcon('ic:round-search');
export const IcRoundFolderCopy = createIconifyIcon('ic:round-folder-copy');
export const IcRoundSubdirectoryArrowLeft = createIconifyIcon(
'ic:round-subdirectory-arrow-left',
);
export const IcRoundArrowUpward = createIconifyIcon('ic:round-arrow-upward');
export const IcRoundArrowDownward = createIconifyIcon(
'ic:round-arrow-downward',
);
export const IcBaselineLanguage = createIconifyIcon('ic:baseline-language');
export const IcRoundSearchOff = createIconifyIcon('ic:round-search-off');
export const IcRoundNotificationsNone = createIconifyIcon(
'ic:round-notifications-none',
);
export const IcRoundMarkEmailRead = createIconifyIcon(
'ic:round-mark-email-read',
);
export const IcRoundWbSunny = createIconifyIcon('ic:round-wb-sunny');
export const IcRoundMotionPhotosAuto = createIconifyIcon(
'ic:round-motion-photos-auto',
);
export const IcRoundSettingsSuggest = createIconifyIcon(
'ic:round-settings-suggest',
);
export const IcRoundArrowBackIosNew = createIconifyIcon(
'ic:round-arrow-back-ios-new',
);
export const IcRoundMultipleStop = createIconifyIcon('ic:round-multiple-stop');
export const IcRoundTableView = createIconifyIcon('ic:round-table-view');
export const IcRoundRefresh = createIconifyIcon('ic:round-refresh');
export const IcRoundCreditScore = createIconifyIcon('ic:round-credit-score');
export const IcRoundLock = createIconifyIcon('ic:round-lock');

View File

@ -2,8 +2,6 @@ import { createIconifyIcon } from './create-icon';
export const MdiKeyboardEsc = createIconifyIcon('mdi:keyboard-esc');
export const MdiLoading = createIconifyIcon('mdi:loading');
export const MdiWechat = createIconifyIcon('mdi:wechat');
export const MdiGithub = createIconifyIcon('mdi:github');
@ -16,34 +14,6 @@ export const MdiPin = createIconifyIcon('mdi:pin');
export const MdiPinOff = createIconifyIcon('mdi:pin-off');
export const MdiFormatHorizontalAlignLeft = createIconifyIcon(
'mdi:format-horizontal-align-left',
);
export const MdiFormatHorizontalAlignRight = createIconifyIcon(
'mdi:format-horizontal-align-right',
);
export const MdiArrowExpandHorizontal = createIconifyIcon(
'mdi:arrow-expand-horizontal',
);
export const MdiMenuClose = createIconifyIcon('mdi:menu-close');
export const MdiMenuOpen = createIconifyIcon('mdi:menu-open');
export const MdiDockLeft = createIconifyIcon('mdi:dock-left');
export const MdiDockRight = createIconifyIcon('mdi:dock-right');
export const MdiDockBottom = createIconifyIcon('mdi:dock-bottom');
export const MdiDriveDocument = createIconifyIcon('mdi:drive-document');
export const MdiMoonAndStars = createIconifyIcon('mdi:moon-and-stars');
export const MdiEditBoxOutline = createIconifyIcon('mdi:edit-box-outline');
export const MdiQuestionMarkCircleOutline = createIconifyIcon(
'mdi:question-mark-circle-outline',
);

View File

@ -2,7 +2,7 @@
import type { CSSProperties } from 'vue';
import { computed, useSlots } from 'vue';
import { IcRoundMenu } from '@vben-core/icons';
import { Menu } from '@vben-core/icons';
import { VbenIconButton } from '@vben-core/shadcn-ui';
interface Props {
@ -108,7 +108,7 @@ function handleToggleMenu() {
class="my-0 ml-2 mr-1 rounded"
@click="handleToggleMenu"
>
<IcRoundMenu class="size-5" />
<Menu class="size-4" />
</VbenIconButton>
<slot></slot>
</header>

View File

@ -12,7 +12,7 @@ interface Props {
const props = withDefaults(defineProps<Props>(), {
fixed: true,
height: 30,
height: 38,
});
const style = computed((): CSSProperties => {

View File

@ -13,7 +13,7 @@ function handleCollapsed() {
class="flex-center hover:text-foreground text-foreground/60 hover:bg-accent-hover bg-accent absolute bottom-2 left-3 z-10 cursor-pointer rounded-sm p-1 transition-all duration-300"
@click.stop="handleCollapsed"
>
<MdiMenuClose v-if="collapsed" />
<MdiMenuOpen v-else />
<MdiMenuClose v-if="collapsed" class="size-4" />
<MdiMenuOpen v-else class="size-4" />
</div>
</template>

View File

@ -19,7 +19,7 @@ import {
} from 'vue';
import { useNamespace } from '@vben-core/hooks';
import { IcRoundMoreHoriz } from '@vben-core/icons';
import { Ellipsis } from '@vben-core/icons';
import { isHttpUrl } from '@vben-core/toolkit';
import { UseResizeObserverReturn, useResizeObserver } from '@vueuse/core';
@ -338,7 +338,7 @@ function removeMenuItem(item: MenuItemRegistered) {
</template>
<SubMenu is-sub-menu-more path="sub-menu-more">
<template #title>
<IcRoundMoreHoriz />
<Ellipsis class="size-4" />
</template>
<template v-for="item in getSlot.slotMore" :key="item.key">
<component :is="item" />
@ -852,9 +852,9 @@ $namespace: vben;
cursor: pointer;
background: var(--menu-submenu-hover-background-color) !important;
svg {
fill: var(--menu-submenu-hover-color);
}
// svg {
// fill: var(--menu-submenu-hover-color);
// }
}
}
</style>

View File

@ -4,10 +4,7 @@ import type { MenuItemProps } from '../interface';
import { computed } from 'vue';
import { useNamespace } from '@vben-core/hooks';
import {
IcRoundChevronRight,
IcRoundKeyboardArrowDown,
} from '@vben-core/icons';
import { ChevronDown, ChevronRight } from '@vben-core/icons';
import { VbenIcon } from '@vben-core/shadcn-ui';
import { useMenuContext } from '../hooks';
@ -67,8 +64,8 @@ const hiddenTitle = computed(() => {
const iconComp = computed(() => {
return (mode.value === 'horizontal' && !isFirstLevel.value) ||
(mode.value === 'vertical' && collapse.value)
? IcRoundChevronRight
: IcRoundKeyboardArrowDown;
? ChevronRight
: ChevronDown;
});
const iconArrowStyle = computed(() => {
@ -102,6 +99,7 @@ const iconArrowStyle = computed(() => {
v-show="showArrowIcon"
:class="[e('icon-arrow')]"
:style="iconArrowStyle"
class="size-4"
/>
</div>
</template>

View File

@ -3,7 +3,7 @@ import type { BacktopProps } from './backtop';
import { computed } from 'vue';
import { IcRoundArrowUpward } from '@vben-core/icons';
import { ArrowUpToLine } from '@vben-core/icons';
import { VbenButton } from '../button';
import { useBackTop } from './use-backtop';
@ -37,7 +37,7 @@ const { handleClick, visible } = useBackTop(props);
variant="icon"
@click="handleClick"
>
<IcRoundArrowUpward />
<ArrowUpToLine class="size-4" />
</VbenButton>
</transition>
</template>

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import type { IBreadcrumb } from './interface';
import { IcRoundKeyboardArrowDown } from '@vben-core/icons';
import { ChevronDown } from '@vben-core/icons';
import {
Breadcrumb,
BreadcrumbItem,
@ -56,7 +56,7 @@ function handleClick(path?: string) {
class="size-5"
/>
{{ item.title }}
<IcRoundKeyboardArrowDown class="size-5" />
<ChevronDown class="size-4" />
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<template

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue';
import { computed } from 'vue';
import { MdiLoading } from '@vben-core/icons';
import { LoaderCircle } from '@vben-core/icons';
import {
type ButtonVariants,
buttonVariants,
@ -40,9 +40,9 @@ const isDisabled = computed(() => {
:class="cn(buttonVariants({ variant, size }), props.class)"
:disabled="isDisabled"
>
<MdiLoading
<LoaderCircle
v-if="loading"
class="text-md mr-2 flex-shrink-0 animate-spin"
class="text-md mr-2 size-4 flex-shrink-0 animate-spin"
/>
<slot></slot>
</Primitive>

View File

@ -81,7 +81,7 @@ function handleClick(menu: IContextMenuItem) {
<component
:is="menu.icon"
v-if="menu.icon"
class="mr-1 w-6 text-lg"
class="mr-2 size-4 text-lg"
/>
{{ menu.text }}

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { IcRoundFullscreen, IcRoundFullscreenExit } from '@vben-core/icons';
import { Maximize, Minimize } from '@vben-core/icons';
import { useFullscreen } from '@vueuse/core';
@ -22,7 +22,7 @@ isFullscreen.value = !!(
</script>
<template>
<VbenIconButton @click="toggle">
<IcRoundFullscreenExit v-if="isFullscreen" class="size-6" />
<IcRoundFullscreen v-else class="size-6" />
<Minimize v-if="isFullscreen" class="size-4" />
<Maximize v-else class="size-4" />
</VbenIconButton>
</template>

View File

@ -2,12 +2,12 @@
import { type Component, computed } from 'vue';
import { Icon, IconDefault } from '@vben-core/icons';
import { isHttpUrl, isObject, isString } from '@vben-core/toolkit';
import { isFunction, isHttpUrl, isObject, isString } from '@vben-core/toolkit';
const props = defineProps<{
//
fallback?: boolean;
icon?: Component | string;
icon?: Component | Function | string;
}>();
const isRemoteIcon = computed(() => {
@ -15,7 +15,8 @@ const isRemoteIcon = computed(() => {
});
const isComponent = computed(() => {
return !isString(props.icon) && isObject(props.icon);
const { icon } = props;
return !isString(icon) && (isObject(icon) || isFunction(icon));
});
</script>

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { ref, useSlots } from 'vue';
import { IcOutlineVisibility, IcOutlineVisibilityOff } from '@vben-core/icons';
import { Eye, EyeOff } from '@vben-core/icons';
import {
type InputProps,
VbenInput,
@ -48,8 +48,8 @@ const show = ref(false);
class="hover:text-foreground text-foreground/60 absolute inset-y-0 right-0 top-3 flex cursor-pointer pr-3 text-lg leading-5"
@click="show = !show"
>
<IcOutlineVisibility v-if="show" />
<IcOutlineVisibilityOff v-else />
<Eye v-if="show" class="size-4" />
<EyeOff v-else class="size-4" />
</div>
</form>
</template>

View File

@ -42,7 +42,7 @@ function handleScroll(event: Event) {
<div
v-if="shadow"
:class="{
'opacity-100': !isAtTop,
'border-border border-t opacity-100': !isAtTop,
}"
class="scrollbar-top-shadow pointer-events-none absolute top-0 z-10 h-12 w-full opacity-0 transition-opacity duration-300 ease-in-out will-change-[opacity]"
></div>
@ -50,7 +50,7 @@ function handleScroll(event: Event) {
<div
v-if="shadow"
:class="{
'opacity-100': !isAtTop && !isAtBottom,
'border-border border-b opacity-100': !isAtTop && !isAtBottom,
}"
class="scrollbar-bottom-shadow pointer-events-none absolute bottom-0 z-10 h-12 w-full opacity-0 transition-opacity duration-300 ease-in-out will-change-[opacity]"
></div>

View File

@ -17,7 +17,7 @@ import {
SheetTrigger,
} from '@vben-core/shadcn-ui/components/ui/sheet';
import { Cross2Icon } from '@radix-icons/vue';
import { X } from 'lucide-vue-next';
interface Props {
cancelText?: string;
@ -87,12 +87,12 @@ function handlerSubmit() {
class="data-[state=open]:bg-secondary cursor-pointer rounded-full opacity-80 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none"
>
<VbenIconButton>
<Cross2Icon class="size-4" />
<X class="size-4" />
</VbenIconButton>
</SheetClose>
</SheetHeader>
<div class="h-full pb-16">
<VbenScrollbar class="h-full">
<VbenScrollbar class="h-full" shadow>
<slot></slot>
</VbenScrollbar>
</div>

View File

@ -5,7 +5,7 @@ import type { TabConfig, TabsProps } from '../../types';
import { computed, ref, watch } from 'vue';
import { IcRoundClose, MdiPin } from '@vben-core/icons';
import { MdiPin, X } from '@vben-core/icons';
import { VbenContextMenu, VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
interface Props extends TabsProps {}
@ -146,7 +146,7 @@ function scrollIntoView() {
class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%] opacity-0 transition-opacity group-hover:opacity-100"
> -->
<!-- close-icon -->
<IcRoundClose
<X
v-show="
!tab.affixTab && tabsView.length > 1 && tab.closable
"

View File

@ -3,7 +3,7 @@ import type { TabConfig, TabsProps } from '../../types';
import { computed, watch } from 'vue';
import { IcRoundClose, MdiPin } from '@vben-core/icons';
import { MdiPin, X } from '@vben-core/icons';
import { VbenContextMenu, VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
import { TabDefinition } from '@vben-core/typings';
@ -115,7 +115,7 @@ function scrollIntoView() {
class="absolute right-1.5 top-1/2 z-[3] translate-y-[-50%] overflow-hidden opacity-0 transition-opacity group-hover:opacity-100 group-[.is-active]:opacity-100"
> -->
<!-- close-icon -->
<IcRoundClose
<X
v-show="
!tab.affixTab && tabsView.length > 1 && tab.closable
"

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import type { DropdownMenuProps } from '@vben-core/shadcn-ui';
import { IcRoundKeyboardArrowDown } from '@vben-core/icons';
import { ChevronDown } from '@vben-core/icons';
import { VbenDropdownMenu } from '@vben-core/shadcn-ui';
defineProps<DropdownMenuProps>();
@ -10,9 +10,9 @@ defineProps<DropdownMenuProps>();
<template>
<VbenDropdownMenu :menus="menus" :modal="false">
<div
class="flex-center hover:bg-muted hover:text-foreground text-muted-foreground border-border h-full cursor-pointer border-l px-1.5 text-lg font-semibold"
class="flex-center hover:bg-muted hover:text-foreground text-muted-foreground border-border h-full cursor-pointer border-l px-2 text-lg font-semibold"
>
<IcRoundKeyboardArrowDown class="size-5" />
<ChevronDown class="size-4" />
</div>
</VbenDropdownMenu>
</template>

View File

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { IcRoundFitScreen, IcTwotoneFitScreen } from '@vben-core/icons';
import { Fullscreen, Minimize2 } from '@vben-core/icons';
const screen = defineModel<boolean>('screen');
@ -13,7 +13,7 @@ function toggleScreen() {
class="flex-center hover:bg-muted hover:text-foreground text-muted-foreground border-border h-full cursor-pointer border-l px-2 text-lg font-semibold"
@click="toggleScreen"
>
<IcTwotoneFitScreen v-if="screen" />
<IcRoundFitScreen v-else />
<Minimize2 v-if="screen" class="size-4" />
<Fullscreen v-else class="size-4" />
</div>
</template>

View File

@ -4,7 +4,7 @@ import type { FallbackProps } from './fallback';
import { computed, defineAsyncComponent } from 'vue';
import { useRouter } from 'vue-router';
import { IcRoundArrowBackIosNew, IcRoundRefresh } from '@vben-core/icons';
import { ArrowLeft, RotateCw } from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import { VbenButton } from '@vben-core/shadcn-ui';
@ -151,11 +151,11 @@ function refresh() {
</p>
<slot v-if="$slots.action" name="action"></slot>
<VbenButton v-else-if="showBack" size="lg" @click="back">
<IcRoundArrowBackIosNew class="mr-2" />
<ArrowLeft class="mr-2 size-4" />
{{ $t('common.backToHome') }}
</VbenButton>
<VbenButton v-else-if="showRefresh" size="lg" @click="refresh">
<IcRoundRefresh class="mr-2" />
<RotateCw class="mr-2 size-4" />
{{ $t('common.refresh') }}
</VbenButton>
</div>

View File

@ -30,7 +30,7 @@ defineOptions({ name: 'BasicLayout' });
const emit = defineEmits<{ clearPreferencesAndLogout: [] }>();
const { isDark, isHeaderNav, isMixedNav, isSideMixedNav, layout } =
const { isDark, isHeaderNav, isMixedNav, isMobile, isSideMixedNav, layout } =
usePreferences();
const headerMenuTheme = computed(() => {
@ -63,7 +63,6 @@ const logoCollapse = computed(() => {
return false;
}
const { isMobile } = preferences.app;
const { collapsed } = preferences.sidebar;
if (!collapsed && isMobile) {

View File

@ -9,17 +9,17 @@ import { computed, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import {
IcRoundClose,
IcRoundFitScreen,
IcRoundMultipleStop,
IcRoundRefresh,
IcRoundTableView,
IcTwotoneFitScreen,
MdiArrowExpandHorizontal,
MdiFormatHorizontalAlignLeft,
MdiFormatHorizontalAlignRight,
ArrowLeftToLine,
ArrowRightLeft,
ArrowRightToLine,
ExternalLink,
FoldHorizontal,
Fullscreen,
MdiPin,
MdiPinOff,
Minimize2,
RotateCw,
X,
} from '@vben-core/icons';
import { $t, useI18n } from '@vben-core/locales';
import { updatePreferences, usePreferences } from '@vben-core/preferences';
@ -131,7 +131,7 @@ function useTabs() {
handler: async () => {
await coreTabbarStore.closeTab(tab, router);
},
icon: IcRoundClose,
icon: X,
key: 'close',
text: $t('preferences.tabbar.contextMenu.close'),
},
@ -154,7 +154,7 @@ function useTabs() {
}
updateContentScreen(!contentIsMaximize.value);
},
icon: contentIsMaximize.value ? IcRoundFitScreen : IcTwotoneFitScreen,
icon: contentIsMaximize.value ? Minimize2 : Fullscreen,
key: contentIsMaximize.value ? 'restore-maximize' : 'maximize',
text: contentIsMaximize.value
? $t('preferences.tabbar.contextMenu.restoreMaximize')
@ -165,7 +165,7 @@ function useTabs() {
handler: async () => {
await coreTabbarStore.refresh(router);
},
icon: IcRoundRefresh,
icon: RotateCw,
key: 'reload',
text: $t('preferences.tabbar.contextMenu.reload'),
},
@ -178,7 +178,7 @@ function useTabs() {
const url = `${origin}${hash ? '/#' : ''}${fullPath}`;
openWindow(url, { target: '_blank' });
},
icon: IcRoundTableView,
icon: ExternalLink,
key: 'open-in-new-window',
separator: true,
text: $t('preferences.tabbar.contextMenu.openInNewWindow'),
@ -189,7 +189,7 @@ function useTabs() {
handler: async () => {
await coreTabbarStore.closeLeftTabs(tab);
},
icon: MdiFormatHorizontalAlignLeft,
icon: ArrowLeftToLine,
key: 'close-left',
text: $t('preferences.tabbar.contextMenu.closeLeft'),
},
@ -198,7 +198,7 @@ function useTabs() {
handler: async () => {
await coreTabbarStore.closeRightTabs(tab);
},
icon: MdiFormatHorizontalAlignRight,
icon: ArrowRightToLine,
key: 'close-right',
separator: true,
text: $t('preferences.tabbar.contextMenu.closeRight'),
@ -208,7 +208,7 @@ function useTabs() {
handler: async () => {
await coreTabbarStore.closeOtherTabs(tab);
},
icon: MdiArrowExpandHorizontal,
icon: FoldHorizontal,
key: 'close-other',
text: $t('preferences.tabbar.contextMenu.closeOther'),
},
@ -217,7 +217,7 @@ function useTabs() {
handler: async () => {
await coreTabbarStore.closeAllTabs(router);
},
icon: IcRoundMultipleStop,
icon: ArrowRightLeft,
key: 'close-all',
text: $t('preferences.tabbar.contextMenu.closeAll'),
},

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import type { BuiltinThemeType } from '@vben-core/typings';
import { IcRoundColorLens } from '@vben-core/icons';
import { Palette } from '@vben-core/icons';
import {
COLOR_PRESETS,
preferences,
@ -56,7 +56,7 @@ function handleUpdate(value: BuiltinThemeType) {
</div>
<VbenIconButton>
<IcRoundColorLens class="text-primary size-5" />
<Palette class="text-primary size-4" />
</VbenIconButton>
</div>
</template>

View File

@ -4,11 +4,11 @@ import type { MenuRecordRaw } from '@vben-core/typings';
import { onMounted, onUnmounted, ref, watch } from 'vue';
import {
IcRoundArrowDownward,
IcRoundArrowUpward,
IcRoundSearch,
IcRoundSubdirectoryArrowLeft,
ArrowDown,
ArrowUp,
CornerDownLeft,
MdiKeyboardEsc,
Search,
} from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import {
@ -87,8 +87,8 @@ onMounted(() => {
class="md:bg-accent group flex h-8 cursor-pointer items-center gap-3 rounded-2xl border-none bg-none px-2 py-0.5 outline-none"
@click="toggleOpen()"
>
<IcRoundSearch
class="text-muted-foreground group-hover:text-foreground size-4 group-hover:opacity-100"
<Search
class="text-muted-foreground group-hover:text-foreground size-3 group-hover:opacity-100"
/>
<span
class="text-muted-foreground group-hover:text-foreground hidden text-xs duration-300 md:block"
@ -111,13 +111,13 @@ onMounted(() => {
>
<DialogHeader>
<DialogTitle
class="border-border flex h-12 items-center gap-5 border-b px-5 font-normal"
class="border-border flex h-12 items-center gap-3 border-b px-5 font-normal"
>
<IcRoundSearch class="mt-1 size-4" />
<Search class="text-muted-foreground size-4" />
<input
v-model="keyword"
:placeholder="$t('widgets.search.searchNavigate')"
class="ring-none placeholder:text-muted-foreground w-[80%] rounded-md border border-none bg-transparent p-2 text-sm outline-none ring-0 ring-offset-transparent focus-visible:ring-transparent"
class="ring-none placeholder:text-muted-foreground w-[80%] rounded-md border border-none bg-transparent p-2 pl-0 text-sm outline-none ring-0 ring-offset-transparent focus-visible:ring-transparent"
/>
</DialogTitle>
<DialogDescription />
@ -127,16 +127,16 @@ onMounted(() => {
class="text-muted-foreground border-border hidden flex-row rounded-b-2xl border-t px-4 py-2 text-xs sm:flex sm:justify-start sm:gap-x-4"
>
<div class="flex items-center">
<IcRoundSubdirectoryArrowLeft class="mr-1" />
<CornerDownLeft class="mr-1 size-3" />
{{ $t('widgets.search.select') }}
</div>
<div class="flex items-center">
<IcRoundArrowUpward class="mr-2" />
<IcRoundArrowDownward class="mr-2" />
<ArrowUp class="mr-2 size-3" />
<ArrowDown class="mr-2 size-3" />
{{ $t('widgets.search.navigate') }}
</div>
<div class="flex items-center">
<MdiKeyboardEsc class="mr-1" />
<MdiKeyboardEsc class="mr-1 size-3" />
{{ $t('widgets.search.close') }}
</div>
</DialogFooter>

View File

@ -4,7 +4,7 @@ import type { MenuRecordRaw } from '@vben-core/typings';
import { nextTick, onMounted, ref, shallowRef, watch } from 'vue';
import { useRouter } from 'vue-router';
import { IcRoundClose, IcRoundSearchOff } from '@vben-core/icons';
import { SearchX, X } from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import { VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
import { mapTree, traverseTreeValues, uniqueByField } from '@vben-core/toolkit';
@ -221,7 +221,7 @@ onMounted(() => {
v-if="keyword && searchResults.length === 0"
class="text-muted-foreground text-center"
>
<IcRoundSearchOff class="size-12" />
<SearchX class="mx-auto size-12" />
<p class="my-10 text-xs">
{{ $t('widgets.search.noResults') }}
<span class="text-foreground text-sm font-medium">
@ -271,7 +271,7 @@ onMounted(() => {
class="flex-center dark:hover:bg-accent hover:text-primary-foreground rounded-full p-1 hover:scale-110"
@click.stop="removeItem(index)"
>
<IcRoundClose />
<X class="size-4" />
</div>
</li>
</ul>

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import type { SupportedLanguagesType } from '@vben-core/typings';
import { IcBaselineLanguage } from '@vben-core/icons';
import { Languages } from '@vben-core/icons';
import { loadLocaleMessages } from '@vben-core/locales';
import {
SUPPORT_LANGUAGES,
@ -36,7 +36,7 @@ async function handleUpdate(value: string) {
@update:model-value="handleUpdate"
>
<VbenIconButton>
<IcBaselineLanguage class="size-5" />
<Languages class="size-4" />
</VbenIconButton>
</VbenDropdownRadioMenu>
</div>

View File

@ -4,7 +4,7 @@ import type { AuthPageLayoutType } from '@vben-core/typings';
import { computed } from 'vue';
import { MdiDockBottom, MdiDockLeft, MdiDockRight } from '@vben-core/icons';
import { InspectionPanel, PanelLeft, PanelRight } from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import {
preferences,
@ -19,17 +19,17 @@ defineOptions({
const menus = computed((): VbenDropdownMenuItem[] => [
{
icon: MdiDockLeft,
icon: PanelLeft,
key: 'panel-left',
text: $t('authentication.layout.alignLeft'),
},
{
icon: MdiDockBottom,
icon: InspectionPanel,
key: 'panel-center',
text: $t('authentication.layout.center'),
},
{
icon: MdiDockRight,
icon: PanelRight,
key: 'panel-right',
text: $t('authentication.layout.alignRight'),
},
@ -53,9 +53,9 @@ function handleUpdate(value: string) {
@update:model-value="handleUpdate"
>
<VbenIconButton>
<MdiDockRight v-if="authPanelRight" class="size-5" />
<MdiDockLeft v-if="authPanelLeft" class="size-5" />
<MdiDockBottom v-if="authPanelCenter" class="size-5" />
<PanelRight v-if="authPanelRight" class="size-4" />
<PanelLeft v-if="authPanelLeft" class="size-4" />
<InspectionPanel v-if="authPanelCenter" class="size-4" />
</VbenIconButton>
</VbenDropdownRadioMenu>
</template>

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed, reactive, ref, watchEffect } from 'vue';
import { IcRoundLock } from '@vben-core/icons';
import { LockKeyhole } from '@vben-core/icons';
import { $t, useI18n } from '@vben-core/locales';
import {
VbenAvatar,
@ -92,7 +92,7 @@ function toggleUnlockForm() {
class="flex-col-center text-foreground/80 hover:text-foreground group my-4 cursor-pointer text-xl font-semibold"
@click="toggleUnlockForm"
>
<IcRoundLock
<LockKeyhole
class="size-5 transition-all duration-300 group-hover:scale-125"
/>
<span>{{ $t('widgets.lockScreen.unlock') }}</span>

View File

@ -1,10 +1,7 @@
<script lang="ts" setup>
import type { NotificationItem } from './types';
import {
IcRoundMarkEmailRead,
IcRoundNotificationsNone,
} from '@vben-core/icons';
import { Bell, MailCheck } from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import {
VbenButton,
@ -75,7 +72,7 @@ function handleClick(item: NotificationItem) {
v-if="dot"
class="bg-primary absolute right-0.5 top-0.5 h-2 w-2 rounded"
></span>
<IcRoundNotificationsNone class="size-5" />
<Bell class="size-4" />
</VbenIconButton>
</div>
</template>
@ -87,7 +84,7 @@ function handleClick(item: NotificationItem) {
:tooltip="$t('widgets.markAllAsRead')"
@click="handleMakeAll"
>
<IcRoundMarkEmailRead />
<MailCheck class="size-4" />
</VbenIconButton>
</div>
<VbenScrollbar v-if="notifications.length > 0">

View File

@ -3,7 +3,7 @@ import type { SelectOption } from '@vben-core/typings';
import { useSlots } from 'vue';
import { MdiQuestionMarkCircleOutline } from '@vben-core/icons';
import { CircleHelp } from '@vben-core/icons';
import { Input, VbenTooltip } from '@vben-core/shadcn-ui';
defineOptions({
@ -41,7 +41,7 @@ const slots = useSlots();
<VbenTooltip v-if="slots.tip" side="bottom">
<template #trigger>
<MdiQuestionMarkCircleOutline class="ml-1 cursor-help" />
<CircleHelp class="ml-1 size-3 cursor-help" />
</template>
<slot name="tip"></slot>
</VbenTooltip>

View File

@ -3,7 +3,7 @@ import type { LayoutType } from '@vben-core/typings';
import { type Component, computed } from 'vue';
import { MdiQuestionMarkCircleOutline } from '@vben-core/icons';
import { CircleHelp } from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import { VbenTooltip } from '@vben-core/shadcn-ui';
@ -84,7 +84,7 @@ function activeClass(theme: string): string[] {
{{ theme.name }}
<VbenTooltip v-if="theme.tip" side="bottom">
<template #trigger>
<MdiQuestionMarkCircleOutline class="ml-1 cursor-help" />
<CircleHelp class="ml-1 size-3 cursor-help" />
</template>
{{ theme.tip }}
</VbenTooltip>

View File

@ -3,7 +3,7 @@ import type { SelectOption } from '@vben-core/typings';
import { useSlots } from 'vue';
import { MdiQuestionMarkCircleOutline } from '@vben-core/icons';
import { CircleHelp } from '@vben-core/icons';
import {
NumberField,
NumberFieldContent,
@ -48,7 +48,7 @@ const slots = useSlots();
<VbenTooltip v-if="slots.tip" side="bottom">
<template #trigger>
<MdiQuestionMarkCircleOutline class="ml-1 cursor-help" />
<CircleHelp class="ml-1 size-3 cursor-help" />
</template>
<slot name="tip"></slot>
</VbenTooltip>

View File

@ -3,7 +3,7 @@ import type { SelectOption } from '@vben-core/typings';
import { useSlots } from 'vue';
import { MdiQuestionMarkCircleOutline } from '@vben-core/icons';
import { CircleHelp } from '@vben-core/icons';
import {
Select,
SelectContent,
@ -48,7 +48,7 @@ const slots = useSlots();
<VbenTooltip v-if="slots.tip" side="bottom">
<template #trigger>
<MdiQuestionMarkCircleOutline class="ml-1 cursor-help" />
<CircleHelp class="ml-1 size-3 cursor-help" />
</template>
<slot name="tip"></slot>
</VbenTooltip>

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import { useSlots } from 'vue';
import { MdiQuestionMarkCircleOutline } from '@vben-core/icons';
import { CircleHelp } from '@vben-core/icons';
import { Switch, VbenTooltip } from '@vben-core/shadcn-ui';
defineOptions({
@ -34,7 +34,7 @@ function handleClick() {
<VbenTooltip v-if="slots.tip" side="bottom">
<template #trigger>
<MdiQuestionMarkCircleOutline class="ml-1 cursor-help" />
<CircleHelp class="ml-1 size-3 cursor-help" />
</template>
<slot name="tip"></slot>
</VbenTooltip>

View File

@ -3,7 +3,7 @@ import type { BuiltinThemeType } from '@vben-core/typings';
import { computed, ref } from 'vue';
import { MdiEditBoxOutline } from '@vben-core/icons';
import { UserRoundPen } from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import {
BUILT_IN_THEME_PRESETS,
@ -114,7 +114,7 @@ function selectColor() {
<template v-else>
<div class="size-full px-10 py-2" @click.stop="selectColor">
<div class="flex-center relative size-5 rounded-sm">
<MdiEditBoxOutline
<UserRoundPen
class="absolute z-10 size-5 opacity-60 group-hover:opacity-100"
/>
<input

View File

@ -3,11 +3,7 @@ import type { ThemeModeType } from '@vben-core/typings';
import type { Component } from 'vue';
import {
IcRoundMotionPhotosAuto,
IcRoundWbSunny,
MdiMoonAndStars,
} from '@vben-core/icons';
import { MoonStar, Sun, SunMoon } from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import SwitchItem from '../switch-item.vue';
@ -23,15 +19,15 @@ const themeSemiDarkMenu = defineModel<boolean>('themeSemiDarkMenu', {
const THEME_PRESET: Array<{ icon: Component; name: ThemeModeType }> = [
{
icon: IcRoundWbSunny,
icon: Sun,
name: 'light',
},
{
icon: MdiMoonAndStars,
icon: MoonStar,
name: 'dark',
},
{
icon: IcRoundMotionPhotosAuto,
icon: SunMoon,
name: 'auto',
},
];

View File

@ -13,7 +13,7 @@ import type {
import { computed, ref } from 'vue';
import { IcRoundFolderCopy, IcRoundRestartAlt } from '@vben-core/icons';
import { Copy, RotateCw, SwatchBook } from '@vben-core/icons';
import { $t, loadLocaleMessages } from '@vben-core/locales';
import {
clearPreferencesCache,
@ -51,7 +51,6 @@ import {
Theme,
Widget,
} from './blocks';
import IconSetting from './icons/setting.vue';
import { useOpenPreferences } from './use-open-preferences';
const emit = defineEmits<{ clearPreferencesAndLogout: [] }>();
@ -225,9 +224,9 @@ async function handleReset() {
<template #trigger>
<VbenButton
:title="$t('preferences.title')"
class="bg-primary flex-col-center h-12 w-12 cursor-pointer rounded-l-lg rounded-r-none border-none"
class="bg-primary flex-col-center h-10 w-10 cursor-pointer rounded-l-lg rounded-r-none border-none"
>
<IconSetting class="duration-3000 fill-primary-foreground text-2xl" />
<SwatchBook class="size-5" />
</VbenButton>
</template>
<template #extra>
@ -241,7 +240,7 @@ async function handleReset() {
v-if="diffPreference"
class="bg-primary absolute right-0.5 top-0.5 h-2 w-2 rounded"
></span>
<IcRoundRestartAlt class="size-5" @click="handleReset" />
<RotateCw class="size-4" @click="handleReset" />
</VbenIconButton>
</div>
</template>
@ -408,7 +407,7 @@ async function handleReset() {
variant="default"
@click="handleCopy"
>
<IcRoundFolderCopy class="mr-2 size-3" />
<Copy class="mr-2 size-3" />
{{ $t('preferences.copyPreferences') }}
</VbenButton>
<VbenButton
@ -418,7 +417,7 @@ async function handleReset() {
variant="ghost"
@click="handleClearCache"
>
<!-- <IcRoundRestartAlt class="mr-2 size-4" /> -->
<!-- <RotateCw class="mr-2 size-4" /> -->
{{ $t('preferences.clearAndLogout') }}
</VbenButton>
</template>

View File

@ -34,7 +34,7 @@ const bindProps = computed(() => {
: {
class: 'rounded-full',
size: 'icon' as const,
style: { padding: '6px' },
style: { padding: '7px' },
variant: 'icon' as const,
};
});
@ -130,18 +130,18 @@ function toggleTheme(event: MouseEvent) {
}
&__sun {
@apply fill-foreground/80 stroke-none;
@apply fill-foreground/70 stroke-none;
transition: transform 1.6s cubic-bezier(0.25, 0, 0.2, 1);
transform-origin: center center;
&:hover > svg > & {
@apply fill-foreground/80;
@apply fill-foreground/70;
}
}
&__sun-beams {
@apply stroke-foreground/80 stroke-[2px];
@apply stroke-foreground/70 stroke-[2px];
transition:
transform 1.6s cubic-bezier(0.5, 1.5, 0.75, 1.25),

View File

@ -1,11 +1,7 @@
<script lang="ts" setup>
import type { ThemeModeType } from '@vben-core/typings';
import {
IcRoundMotionPhotosAuto,
IcRoundWbSunny,
MdiMoonAndStars,
} from '@vben-core/icons';
import { MoonStar, Sun, SunMoon } from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import {
preferences,
@ -38,17 +34,17 @@ const { isDark } = usePreferences();
const PRESETS = [
{
icon: IcRoundWbSunny,
icon: Sun,
name: 'light',
title: $t('preferences.theme.light'),
},
{
icon: MdiMoonAndStars,
icon: MoonStar,
name: 'dark',
title: $t('preferences.theme.dark'),
},
{
icon: IcRoundMotionPhotosAuto,
icon: SunMoon,
name: 'auto',
title: $t('preferences.followSystem'),
},

View File

@ -4,11 +4,7 @@ import type { AnyFunction } from '@vben-core/typings';
import type { Component } from 'vue';
import { computed, ref } from 'vue';
import {
IcRoundLock,
IcRoundLogout,
IcRoundSettingsSuggest,
} from '@vben-core/icons';
import { LockKeyhole, LogOut, SwatchBook } from '@vben-core/icons';
import { $t } from '@vben-core/locales';
import { preferences, usePreferences } from '@vben-core/preferences';
import {
@ -203,7 +199,7 @@ if (enableShortcutKey.value) {
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
@click="menu.handler"
>
<VbenIcon :icon="menu.icon" class="mr-2 size-5" />
<VbenIcon :icon="menu.icon" class="mr-2 size-4" />
{{ menu.text }}
</DropdownMenuItem>
<DropdownMenuSeparator />
@ -211,7 +207,7 @@ if (enableShortcutKey.value) {
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
@click="handleOpenPreference"
>
<IcRoundSettingsSuggest class="mr-2 size-5" />
<SwatchBook class="mr-2 size-4" />
{{ $t('preferences.title') }}
<DropdownMenuShortcut v-if="enablePreferencesShortcutKey">
{{ altView }} ,
@ -222,7 +218,7 @@ if (enableShortcutKey.value) {
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
@click="handleOpenLock"
>
<IcRoundLock class="mr-2 size-5" />
<LockKeyhole class="mr-2 size-4" />
{{ $t('widgets.lockScreen.title') }}
<DropdownMenuShortcut v-if="enableLockScreenShortcutKey">
{{ altView }} L
@ -233,7 +229,7 @@ if (enableShortcutKey.value) {
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
@click="handleLogout"
>
<IcRoundLogout class="mr-2 size-5" />
<LogOut class="mr-2 size-4" />
{{ $t('common.logout') }}
<DropdownMenuShortcut v-if="enableLogoutShortcutKey">
{{ altView }} Q

View File

@ -15,5 +15,5 @@ pnpm add @vben/icons --workspace
### 使用
```ts
import { IcRoundClose } from '@vben/icons';
import { X } from '@vben/icons';
```

13
pnpm-lock.yaml generated
View File

@ -67,8 +67,8 @@ importers:
specifier: ^8.11.0
version: 8.11.0
husky:
specifier: ^9.0.11
version: 9.0.11
specifier: ^9.1.0
version: 9.1.0
is-ci:
specifier: ^3.0.1
version: 3.0.1
@ -680,6 +680,9 @@ importers:
'@iconify/vue':
specifier: ^4.1.2
version: 4.1.2(vue@3.4.32(typescript@5.5.3))
lucide-vue-next:
specifier: ^0.408.0
version: 0.408.0(vue@3.4.32(typescript@5.5.3))
vue:
specifier: ^3.4.32
version: 3.4.32(typescript@5.5.3)
@ -5844,8 +5847,8 @@ packages:
humanize-ms@1.2.1:
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
husky@9.0.11:
resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==}
husky@9.1.0:
resolution: {integrity: sha512-8XCjbomYTGdNF2h50dio3T3zghmZ9f/ZNzr99YwSkvDdhEjJGs5qzy8tbFx+SG8yCx2wn9nMVfZxVrr/yT8gNQ==}
engines: {node: '>=18'}
hasBin: true
@ -14945,7 +14948,7 @@ snapshots:
dependencies:
ms: 2.1.3
husky@9.0.11: {}
husky@9.1.0: {}
iconv-lite@0.4.24:
dependencies: