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

View File

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

View File

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

View File

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

View File

@ -4,12 +4,7 @@ import type { Preferences } from './types';
import { markRaw, reactive, readonly, watch } from 'vue'; import { markRaw, reactive, readonly, watch } from 'vue';
import { import { StorageManager, merge } from '@vben-core/toolkit';
StorageManager,
generatorColorVariables,
merge,
updateCSSVariables,
} from '@vben-core/toolkit';
import { import {
breakpointsTailwind, breakpointsTailwind,
@ -18,7 +13,7 @@ import {
} from '@vueuse/core'; } from '@vueuse/core';
import { defaultPreferences } from './config'; import { defaultPreferences } from './config';
import { BUILT_IN_THEME_PRESETS } from './constants'; import { updateCSSVariables } from './update-css-variables';
const STORAGE_KEY = 'preferences'; const STORAGE_KEY = 'preferences';
const STORAGE_KEY_LOCALE = `${STORAGE_KEY}-locale`; const STORAGE_KEY_LOCALE = `${STORAGE_KEY}-locale`;
@ -48,11 +43,10 @@ class PreferenceManager {
}); });
constructor() { constructor() {
this.cache = new StorageManager(); this.cache = new StorageManager();
// this.flattenedState = reactive(flattenObject(this.state));
this.savePreferences = useDebounceFn( this.savePreferences = useDebounceFn(
(preference: Preferences) => this._savePreferences(preference), (preference: Preferences) => this._savePreferences(preference),
100, 200,
); );
} }
@ -76,7 +70,7 @@ class PreferenceManager {
const themeUpdates = updates.theme || {}; const themeUpdates = updates.theme || {};
const appUpdates = updates.app || {}; const appUpdates = updates.app || {};
if (themeUpdates && Object.keys(themeUpdates).length > 0) { if (themeUpdates && Object.keys(themeUpdates).length > 0) {
this.updateTheme(this.state); updateCSSVariables(this.state);
} }
if ( if (
@ -130,7 +124,7 @@ class PreferenceManager {
this.updatePreferences({ this.updatePreferences({
theme: { mode: isDark ? 'dark' : 'light' }, 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() { clearCache() {
[STORAGE_KEY, STORAGE_KEY_LOCALE, STORAGE_KEY_THEME].forEach((key) => { [STORAGE_KEY, STORAGE_KEY_LOCALE, STORAGE_KEY_THEME].forEach((key) => {
this.cache?.removeItem(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); return isDarkTheme(preferences.theme.mode);
}); });
const isMobile = computed(() => {
return appPreferences.value.isMobile;
});
const theme = computed(() => { const theme = computed(() => {
return isDark.value ? 'dark' : 'light'; return isDark.value ? 'dark' : 'light';
}); });
@ -35,7 +39,7 @@ function usePreferences() {
* @zh_CN * @zh_CN
*/ */
const layout = computed(() => 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'; 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 * @zh_CN
*/ */
@ -138,17 +152,6 @@ function usePreferences() {
return enable && globalPreferences; 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 { return {
authPanelCenter, authPanelCenter,
authPanelLeft, authPanelLeft,
@ -163,6 +166,7 @@ function usePreferences() {
isFullContent, isFullContent,
isHeaderNav, isHeaderNav,
isMixedNav, isMixedNav,
isMobile,
isSideMixedNav, isSideMixedNav,
isSideMode, isSideMode,
isSideNav, isSideNav,

View File

@ -15,7 +15,7 @@
--card-foreground: 210 40% 98%; --card-foreground: 210 40% 98%;
/* Background color for popovers such as <DropdownMenu />, <HoverCard />, <Popover /> */ /* 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%; --popover-foreground: 210 40% 98%;
/* Muted backgrounds such as <TabsList />, <Skeleton /> and <Switch /> */ /* Muted backgrounds such as <TabsList />, <Skeleton /> and <Switch /> */

View File

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

View File

@ -1,5 +1,5 @@
export * from './create-icon'; export * from './create-icon';
export * from './material'; export * from './lucide';
export * from './mdi';
export * from './mdi';
export * from '@iconify/vue'; 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 MdiKeyboardEsc = createIconifyIcon('mdi:keyboard-esc');
export const MdiLoading = createIconifyIcon('mdi:loading');
export const MdiWechat = createIconifyIcon('mdi:wechat'); export const MdiWechat = createIconifyIcon('mdi:wechat');
export const MdiGithub = createIconifyIcon('mdi:github'); 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 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 MdiMenuClose = createIconifyIcon('mdi:menu-close');
export const MdiMenuOpen = createIconifyIcon('mdi:menu-open'); 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 type { CSSProperties } from 'vue';
import { computed, useSlots } 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'; import { VbenIconButton } from '@vben-core/shadcn-ui';
interface Props { interface Props {
@ -108,7 +108,7 @@ function handleToggleMenu() {
class="my-0 ml-2 mr-1 rounded" class="my-0 ml-2 mr-1 rounded"
@click="handleToggleMenu" @click="handleToggleMenu"
> >
<IcRoundMenu class="size-5" /> <Menu class="size-4" />
</VbenIconButton> </VbenIconButton>
<slot></slot> <slot></slot>
</header> </header>

View File

@ -12,7 +12,7 @@ interface Props {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
fixed: true, fixed: true,
height: 30, height: 38,
}); });
const style = computed((): CSSProperties => { 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" 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" @click.stop="handleCollapsed"
> >
<MdiMenuClose v-if="collapsed" /> <MdiMenuClose v-if="collapsed" class="size-4" />
<MdiMenuOpen v-else /> <MdiMenuOpen v-else class="size-4" />
</div> </div>
</template> </template>

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
import type { HTMLAttributes } from 'vue'; import type { HTMLAttributes } from 'vue';
import { computed } from 'vue'; import { computed } from 'vue';
import { MdiLoading } from '@vben-core/icons'; import { LoaderCircle } from '@vben-core/icons';
import { import {
type ButtonVariants, type ButtonVariants,
buttonVariants, buttonVariants,
@ -40,9 +40,9 @@ const isDisabled = computed(() => {
:class="cn(buttonVariants({ variant, size }), props.class)" :class="cn(buttonVariants({ variant, size }), props.class)"
:disabled="isDisabled" :disabled="isDisabled"
> >
<MdiLoading <LoaderCircle
v-if="loading" 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> <slot></slot>
</Primitive> </Primitive>

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, useSlots } from 'vue'; import { ref, useSlots } from 'vue';
import { IcOutlineVisibility, IcOutlineVisibilityOff } from '@vben-core/icons'; import { Eye, EyeOff } from '@vben-core/icons';
import { import {
type InputProps, type InputProps,
VbenInput, 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" 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" @click="show = !show"
> >
<IcOutlineVisibility v-if="show" /> <Eye v-if="show" class="size-4" />
<IcOutlineVisibilityOff v-else /> <EyeOff v-else class="size-4" />
</div> </div>
</form> </form>
</template> </template>

View File

@ -42,7 +42,7 @@ function handleScroll(event: Event) {
<div <div
v-if="shadow" v-if="shadow"
:class="{ :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]" 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> ></div>
@ -50,7 +50,7 @@ function handleScroll(event: Event) {
<div <div
v-if="shadow" v-if="shadow"
:class="{ :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]" 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> ></div>

View File

@ -17,7 +17,7 @@ import {
SheetTrigger, SheetTrigger,
} from '@vben-core/shadcn-ui/components/ui/sheet'; } from '@vben-core/shadcn-ui/components/ui/sheet';
import { Cross2Icon } from '@radix-icons/vue'; import { X } from 'lucide-vue-next';
interface Props { interface Props {
cancelText?: string; 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" 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> <VbenIconButton>
<Cross2Icon class="size-4" /> <X class="size-4" />
</VbenIconButton> </VbenIconButton>
</SheetClose> </SheetClose>
</SheetHeader> </SheetHeader>
<div class="h-full pb-16"> <div class="h-full pb-16">
<VbenScrollbar class="h-full"> <VbenScrollbar class="h-full" shadow>
<slot></slot> <slot></slot>
</VbenScrollbar> </VbenScrollbar>
</div> </div>

View File

@ -5,7 +5,7 @@ import type { TabConfig, TabsProps } from '../../types';
import { computed, ref, watch } from 'vue'; 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'; import { VbenContextMenu, VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
interface Props extends TabsProps {} 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" 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 --> <!-- close-icon -->
<IcRoundClose <X
v-show=" v-show="
!tab.affixTab && tabsView.length > 1 && tab.closable !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 { 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 { VbenContextMenu, VbenIcon, VbenScrollbar } from '@vben-core/shadcn-ui';
import { TabDefinition } from '@vben-core/typings'; 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" 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 --> <!-- close-icon -->
<IcRoundClose <X
v-show=" v-show="
!tab.affixTab && tabsView.length > 1 && tab.closable !tab.affixTab && tabsView.length > 1 && tab.closable
" "

View File

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { DropdownMenuProps } from '@vben-core/shadcn-ui'; 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'; import { VbenDropdownMenu } from '@vben-core/shadcn-ui';
defineProps<DropdownMenuProps>(); defineProps<DropdownMenuProps>();
@ -10,9 +10,9 @@ defineProps<DropdownMenuProps>();
<template> <template>
<VbenDropdownMenu :menus="menus" :modal="false"> <VbenDropdownMenu :menus="menus" :modal="false">
<div <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> </div>
</VbenDropdownMenu> </VbenDropdownMenu>
</template> </template>

View File

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { IcRoundFitScreen, IcTwotoneFitScreen } from '@vben-core/icons'; import { Fullscreen, Minimize2 } from '@vben-core/icons';
const screen = defineModel<boolean>('screen'); 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" 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" @click="toggleScreen"
> >
<IcTwotoneFitScreen v-if="screen" /> <Minimize2 v-if="screen" class="size-4" />
<IcRoundFitScreen v-else /> <Fullscreen v-else class="size-4" />
</div> </div>
</template> </template>

View File

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

View File

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

View File

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

View File

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

View File

@ -4,11 +4,11 @@ import type { MenuRecordRaw } from '@vben-core/typings';
import { onMounted, onUnmounted, ref, watch } from 'vue'; import { onMounted, onUnmounted, ref, watch } from 'vue';
import { import {
IcRoundArrowDownward, ArrowDown,
IcRoundArrowUpward, ArrowUp,
IcRoundSearch, CornerDownLeft,
IcRoundSubdirectoryArrowLeft,
MdiKeyboardEsc, MdiKeyboardEsc,
Search,
} from '@vben-core/icons'; } from '@vben-core/icons';
import { $t } from '@vben-core/locales'; import { $t } from '@vben-core/locales';
import { 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" 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()" @click="toggleOpen()"
> >
<IcRoundSearch <Search
class="text-muted-foreground group-hover:text-foreground size-4 group-hover:opacity-100" class="text-muted-foreground group-hover:text-foreground size-3 group-hover:opacity-100"
/> />
<span <span
class="text-muted-foreground group-hover:text-foreground hidden text-xs duration-300 md:block" class="text-muted-foreground group-hover:text-foreground hidden text-xs duration-300 md:block"
@ -111,13 +111,13 @@ onMounted(() => {
> >
<DialogHeader> <DialogHeader>
<DialogTitle <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 <input
v-model="keyword" v-model="keyword"
:placeholder="$t('widgets.search.searchNavigate')" :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> </DialogTitle>
<DialogDescription /> <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" 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"> <div class="flex items-center">
<IcRoundSubdirectoryArrowLeft class="mr-1" /> <CornerDownLeft class="mr-1 size-3" />
{{ $t('widgets.search.select') }} {{ $t('widgets.search.select') }}
</div> </div>
<div class="flex items-center"> <div class="flex items-center">
<IcRoundArrowUpward class="mr-2" /> <ArrowUp class="mr-2 size-3" />
<IcRoundArrowDownward class="mr-2" /> <ArrowDown class="mr-2 size-3" />
{{ $t('widgets.search.navigate') }} {{ $t('widgets.search.navigate') }}
</div> </div>
<div class="flex items-center"> <div class="flex items-center">
<MdiKeyboardEsc class="mr-1" /> <MdiKeyboardEsc class="mr-1 size-3" />
{{ $t('widgets.search.close') }} {{ $t('widgets.search.close') }}
</div> </div>
</DialogFooter> </DialogFooter>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,5 +15,5 @@ pnpm add @vben/icons --workspace
### 使用 ### 使用
```ts ```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 specifier: ^8.11.0
version: 8.11.0 version: 8.11.0
husky: husky:
specifier: ^9.0.11 specifier: ^9.1.0
version: 9.0.11 version: 9.1.0
is-ci: is-ci:
specifier: ^3.0.1 specifier: ^3.0.1
version: 3.0.1 version: 3.0.1
@ -680,6 +680,9 @@ importers:
'@iconify/vue': '@iconify/vue':
specifier: ^4.1.2 specifier: ^4.1.2
version: 4.1.2(vue@3.4.32(typescript@5.5.3)) 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: vue:
specifier: ^3.4.32 specifier: ^3.4.32
version: 3.4.32(typescript@5.5.3) version: 3.4.32(typescript@5.5.3)
@ -5844,8 +5847,8 @@ packages:
humanize-ms@1.2.1: humanize-ms@1.2.1:
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
husky@9.0.11: husky@9.1.0:
resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} resolution: {integrity: sha512-8XCjbomYTGdNF2h50dio3T3zghmZ9f/ZNzr99YwSkvDdhEjJGs5qzy8tbFx+SG8yCx2wn9nMVfZxVrr/yT8gNQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
@ -14945,7 +14948,7 @@ snapshots:
dependencies: dependencies:
ms: 2.1.3 ms: 2.1.3
husky@9.0.11: {} husky@9.1.0: {}
iconv-lite@0.4.24: iconv-lite@0.4.24:
dependencies: dependencies: