perf: reorganize the icons and reduce the volume
							parent
							
								
									cb161eab89
								
							
						
					
					
						commit
						910a3553ac
					
				|  | @ -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'), | ||||
|   }, | ||||
| ]); | ||||
|  |  | |||
|  | @ -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'), | ||||
|         }, | ||||
|       }, | ||||
|  |  | |||
|  | @ -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'), | ||||
|  |  | |||
|  | @ -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", | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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 }; | ||||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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 /> */ | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ | |||
|   }, | ||||
|   "dependencies": { | ||||
|     "@iconify/vue": "^4.1.2", | ||||
|     "lucide-vue-next": "^0.408.0", | ||||
|     "vue": "^3.4.32" | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| export * from './create-icon'; | ||||
| export * from './material'; | ||||
| export * from './mdi'; | ||||
| export * from './lucide'; | ||||
| 
 | ||||
| export * from './mdi'; | ||||
| export * from '@iconify/vue'; | ||||
|  |  | |||
|  | @ -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'; | ||||
|  | @ -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'); | ||||
|  | @ -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', | ||||
| ); | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ interface Props { | |||
| 
 | ||||
| const props = withDefaults(defineProps<Props>(), { | ||||
|   fixed: true, | ||||
|   height: 30, | ||||
|   height: 38, | ||||
| }); | ||||
| 
 | ||||
| const style = computed((): CSSProperties => { | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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 }} | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
| 
 | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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 | ||||
|                     " | ||||
|  |  | |||
|  | @ -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 | ||||
|                     " | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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) { | ||||
|  |  | |||
|  | @ -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'), | ||||
|       }, | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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"> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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', | ||||
|   }, | ||||
| ]; | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
|  | @ -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), | ||||
|  |  | |||
|  | @ -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'), | ||||
|   }, | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -15,5 +15,5 @@ pnpm add @vben/icons --workspace | |||
| ### 使用 | ||||
| 
 | ||||
| ```ts | ||||
| import { IcRoundClose } from '@vben/icons'; | ||||
| import { X } from '@vben/icons'; | ||||
| ``` | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 vince
						vince