Appearance
design 包升级指南
本文为全量升级说明(包含主题切换)
删除文件
build/config/themeConfig.tsbuild/generate/generateModifyVars.tssrc/global/theme/dark.jssrc/global/theme/index.jssrc/global/theme/updateBackground.jssrc/global/theme/updateColorWeak.jssrc/global/theme/updateGrayMode.jssrc/global/theme/util.jssrc/design/*先要排查下是否后续添加了部分样式,需要保留增量部分,可以排查 git 上的文件修改记录
新增文件
src/global/theme/adapter.jssrc/store/modules/theme.store.jstailwind.config.tsassets/styles/index.lessdesign 目录下删除的样式可以添加到该文件下
新增文件明细
src/global/theme/adapter.js
javascript
export function createAppConfigAdapter(appStore) {
return {
getDarkMode() {
return appStore.getDarkMode;
},
getHeaderBgColor() {
const setting = appStore.getHeaderSetting || {};
return setting.bgColor;
},
getMenuBgColor() {
const setting = appStore.getMenuSetting || {};
return setting.bgColor;
},
setHeaderTheme(mode) {
appStore.setProjectConfig({ headerSetting: { theme: mode } });
},
setMenuTheme(mode) {
appStore.setProjectConfig({ menuSetting: { theme: mode } });
}
};
}
src/store/modules/theme.store.js
javascript
import { defineStore } from "pinia";
import { store } from "@/store";
import { DEFAULT_PRIMARY_COLOR } from "@trinapower/design/constants";
import { ThemeManager } from "@trinapower/design/theme/runtime";
import { createAppConfigAdapter } from "@/global/theme/adapter";
import { useAppStoreWithOut } from "./app.store";
import { theme } from "@/constants/app.constant";
let manager;
export const useThemeStore = defineStore({
id: "theme",
state: () => ({
initialized: false
}),
actions: {
ensureManager() {
if (!manager) {
const appStore = useAppStoreWithOut();
const adapter = createAppConfigAdapter(appStore);
manager = new ThemeManager(adapter, {
htmlRootSelector: "#htmlRoot",
scopeAttr: "data-theme"
});
}
return manager;
},
async changePrimaryColor(color) {
const mgr = this.ensureManager();
return await mgr.changePrimaryColor(color);
},
setDarkMode(mode) {
const mgr = this.ensureManager();
mgr.setDarkMode(mode);
},
toggleGrayMode(flag) {
const mgr = this.ensureManager();
mgr.toggleGrayMode(flag);
},
toggleColorWeak(flag) {
const mgr = this.ensureManager();
mgr.toggleColorWeak(flag);
},
updateHeaderBgColor(color) {
const mgr = this.ensureManager();
if (color) {
mgr.updateHeaderBgColor(color);
} else {
mgr.updateHeaderBgColor();
}
},
updateSidebarBgColor(color) {
const mgr = this.ensureManager();
if (color) {
mgr.updateSidebarBgColor(color);
} else {
mgr.updateSidebarBgColor();
}
},
async applyInitialTheme(projCfg) {
const appStore = useAppStoreWithOut();
const darkMode = appStore.getDarkMode;
const {
colorWeak,
grayMode,
themeColor,
headerSetting: { bgColor: headerBgColor } = {},
menuSetting: { bgColor } = {}
} = projCfg || {};
const mgr = this.ensureManager();
try {
if (themeColor && themeColor !== DEFAULT_PRIMARY_COLOR) {
await mgr.changePrimaryColor(themeColor);
}
if (grayMode) mgr.toggleGrayMode(grayMode);
if (colorWeak) mgr.toggleColorWeak(colorWeak);
} catch (_) {}
mgr.setDarkMode(darkMode);
if (darkMode === theme.DARK) {
mgr.updateHeaderBgColor();
mgr.updateSidebarBgColor();
} else {
if (headerBgColor) mgr.updateHeaderBgColor(headerBgColor);
if (bgColor) mgr.updateSidebarBgColor(bgColor);
}
this.initialized = true;
}
}
});
export function useThemeStoreWithOut() {
return useThemeStore(store);
}
tailwind.config.ts
javascript
import type { Config } from 'tailwindcss'
import { createDesktopPreset } from '@trinapower/tailwind-preset-desktop'
export default {
corePlugins: {
preflight: false,
},
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
presets: [createDesktopPreset()],
} satisfies Config
修改文件
package.jsonbuild/vite/plugins/index.tsbuild/vite/plugins/theme.tssrc/components/Application/src/AppDarkModeToggle.vuesrc/global/index.jssrc/settings/project.setting.jssrc/views/layout/default/setting/components/SettingFooter.vuesrc/views/layout/default/setting/handler.jsvite.config.mtspostcss.config.jsmain.js
修改文件明细
build/vite/plugins/index.ts修改
diff
export function createVitePlugins(env: ViteEnv, isBuild: boolean) {
VITE_BUILD_COMPRESS,
VITE_BUILD_REPORT,
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE,
+ VITE_GLOB_BRAND,
} = env
...
- vitePlugins.push(configThemePlugin(isBuild))
+ vitePlugins.push(...configThemePlugin(isBuild, VITE_GLOB_BRAND))
build/vite/plugins/theme.ts替换修改
javascript
/**
* Vite plugin for website theme color switching
* https://github.com/didengren/vite-plugin-theme
*/
import type { PluginOption } from 'vite'
import { createThemePlugin } from '@trinapower/design/theme'
export function configThemePlugin(isBuild: boolean, brand: string | undefined): PluginOption[] {
return createThemePlugin({
isBuild,
brand,
enableResolveSelector: true,
reservedSelectors: [
'.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon',
'.ant-steps-item-icon > .ant-steps-icon',
'.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)',
'.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover',
'.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active',
'.ant-steps-item-icon > .ant-steps-icon',
'.ant-select-item-option-selected:not(.ant-select-item-option-disabled)',
],
darkReservedSelectors: [
'.ant-picker-cell:hover:not(.ant-picker-cell-in-view) .ant-picker-cell-inner',
'.ant-picker-cell:hover:not(.ant-picker-cell-selected):not(.ant-picker-cell-range-start):not(.ant-picker-cell-range-end):not(.ant-picker-cell-range-hover-start):not( .ant-picker-cell-range-hover-end) .ant-picker-cell-inner',
'.ant-picker-cell-in-view.ant-picker-cell-selected .ant-picker-cell-inner',
'.ant-picker-cell-in-view.ant-picker-cell-range-start .ant-picker-cell-inner',
'.ant-picker-cell-in-view.ant-picker-cell-range-end .ant-picker-cell-inner',
'.ant-picker-cell-in-view.ant-picker-cell-today .ant-picker-cell-inner'
]
}) as unknown as PluginOption[]
}
package.json最终需要根据实际修改的发布版本进行替换
diff
{
- "@trinapower/unocss-preset-desktop": "0.0.10",
- "@trinapower/unocss-public-reset": "^0.0.8",
- "unocss": "^0.56.5",
+ "cosine-fee": "0.4.2-alpha.1",
+ "tailwindcss": "^3.4.16",
+ "@trinapower/design": "0.1.3-alpha.4",
+ "@trinapower/tailwind-preset-desktop": "1.0.4",
+ "@trinapower/vite-plugin-theme": "1.0.0"
}
src/components/Application/src/AppDarkModeToggle.vue修改
diff
import { useRootSetting } from '@/hooks/setting/useRootSetting'
- import { updateHeaderBgColor, updateSidebarBgColor } from '@/global/theme/updateBackground'
- import { updateDarkTheme } from '@/global/theme/dark'
import { theme } from '@/constants/app.constant'
+ import { useThemeStore } from '@/store/modules/theme.store'
const { prefixCls } = useDesign('dark-switch')
const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting()
const isDark = computed(() => getDarkMode.value === theme.DARK)
+const themeStore = useThemeStore()
const getClass = computed(() => [
function toggleDarkMode() {
const darkMode = getDarkMode.value === theme.DARK ? theme.LIGHT : theme.DARK
setDarkMode(darkMode)
- updateDarkTheme(darkMode)
- updateHeaderBgColor()
- updateSidebarBgColor()
+ themeStore.setDarkMode(darkMode)
+ themeStore.updateHeaderBgColor()
+ themeStore.updateSidebarBgColor()
}
src/global/index.js修改
diff
import { PROJ_CFG_KEY } from '@/utils/cache/cache.constant'
import { LOCALE, currentLocale } from '@/settings/locale.setting'
import { merge } from 'lodash-es'
import projectSetting from '@/settings/project.setting'
-import { changeTheme } from './theme'
-import { updateHeaderBgColor, updateSidebarBgColor } from './theme/updateBackground'
-import { updateColorWeak } from './theme/updateColorWeak'
-import { updateGrayMode } from './theme/updateGrayMode'
-import { updateDarkTheme } from './theme/dark'
import { getCommonStoragePrefix, getStorageShortName } from '@/utils/env'
-import { primaryColor } from '../../build/config/themeConfig'
import { theme } from '@/constants/app.constant'
+import { useThemeStoreWithOut } from '@/store/modules/theme.store'
const ls = createLocalStorage()
function runTheme(appStore, projCfg) {
- const darkMode = appStore.getDarkMode
- const {
- colorWeak,
- grayMode,
- themeColor,
-
- headerSetting: { bgColor: headerBgColor } = {},
- menuSetting: { bgColor } = {},
- } = projCfg
-
- try {
- if (themeColor && themeColor !== primaryColor) {
- changeTheme(themeColor)
- }
-
- grayMode && updateGrayMode(grayMode)
- colorWeak && updateColorWeak(colorWeak)
- } catch (error) {
- console.log(error)
- }
-
- // init dark mode
- updateDarkTheme(darkMode)
- if (darkMode === theme.DARK) {
- updateHeaderBgColor()
- updateSidebarBgColor()
- } else {
- headerBgColor && updateHeaderBgColor(headerBgColor)
- bgColor && updateSidebarBgColor(bgColor)
- }
+ const themeStore = useThemeStoreWithOut()
+ themeStore.applyInitialTheme(projCfg)
}
src/settings/project.setting.js修改
diff
import {
settingButtonPosition,
} from '@/constants/app.constant'
import { SIDE_BAR_BG_COLOR_LIST, HEADER_PRESET_BG_COLOR_LIST } from './design.setting'
-import { primaryColor } from '../../build/config/themeConfig'
+import { DEFAULT_PRIMARY_COLOR } from '@trinapower/design/constants'
// ! You need to clear the browser cache after the change
const setting = {
permissionCacheType: STORAGE_TYPE.LOCAL,
// color
- themeColor: primaryColor,
+ themeColor: DEFAULT_PRIMARY_COLOR,
src/views/layout/default/setting/components/SettingFooter.vue修改
diff
import { useAppStore } from '@/store/modules/app.store'
import { usePermissionStore } from '@/store/modules/permission.store'
import { useMultipleTabStore } from '@/store/modules/multipleTab.store'
import useUserStore from '@/store/modules/user.store'
+import { useThemeStore } from '@/store/modules/theme.store'
import { useDesign } from '@/hooks/gui/useDesign'
import { useI18n } from '@/hooks/gui/useI18n'
import { useMessage } from '@/hooks/gui/useMessage'
import { useCopyToClipboard } from '@/hooks/gui/useCopyToClipboard'
-import { updateColorWeak } from '@/global/theme/updateColorWeak'
-import { updateGrayMode } from '@/global/theme/updateGrayMode'
import defaultSetting from '@/settings/project.setting'
export default defineComponent({
const tabStore = useMultipleTabStore()
const userStore = useUserStore()
const appStore = useAppStore()
+ const themeStore = useThemeStore()
function handleCopy() {
const { isSuccessRef } = useCopyToClipboard(
appStore.setProjectConfig(defaultSetting)
const { colorWeak, grayMode } = defaultSetting
// updateTheme(themeColor);
- updateColorWeak(colorWeak)
- updateGrayMode(grayMode)
+ themeStore.toggleColorWeak(colorWeak)
+ themeStore.toggleGrayMode(grayMode)
createMessage.success(t('layout.setting.resetSuccess'))
} catch (error) {
createMessage.error(error)
src/views/layout/default/setting/handler.js修改
diff
/* eslint-disable no-case-declarations */
import { HandlerEnum } from './constants'
-import { updateHeaderBgColor, updateSidebarBgColor } from '@/global/theme/updateBackground'
-import { updateColorWeak } from '@/global/theme/updateColorWeak'
-import { updateGrayMode } from '@/global/theme/updateGrayMode'
import { useAppStore } from '@/store/modules/app.store'
-import { changeTheme } from '@/global/theme'
-import { updateDarkTheme } from '@/global/theme/dark'
+import { useThemeStore } from '@/store/modules/theme.store'
import { useRootSetting } from '@/hooks/setting/useRootSetting'
export function baseHandler(event, value) {
const appStore = useAppStore()
+ const themeStore = useThemeStore()
const config = handler(event, value)
appStore.setProjectConfig(config)
if (event === HandlerEnum.CHANGE_THEME) {
- updateHeaderBgColor()
- updateSidebarBgColor()
+ themeStore.updateHeaderBgColor()
+ themeStore.updateSidebarBgColor()
}
}
export function handler(event, value) {
const appStore = useAppStore()
+ const themeStore = useThemeStore()
const { getThemeColor, getDarkMode } = useRootSetting()
switch (event) {
- changeTheme(value)
+ themeStore.changePrimaryColor(value)
- updateDarkTheme(value)
+ themeStore.setDarkMode(value)
- updateSidebarBgColor(value)
+ themeStore.updateSidebarBgColor(value)
- updateGrayMode(value)
+ themeStore.toggleGrayMode(value)
- updateColorWeak(value)
+ themeStore.toggleColorWeak(value)
- updateHeaderBgColor(value)
+ themeStore.updateHeaderBgColor(value)
vite.config.mts修改
diff
import { wrapperEnv } from './build/utils'
import { createProxy } from './build/vite/proxy'
-import { generateModifyVars } from './build/generate/generateModifyVars'
+import { generateModifyVars } from '@trinapower/design/build'
import { createVitePlugins } from './build/vite/plugins'
import { TESTING_OUTPUT_DIR, STAGING_OUTPUT_DIR, PRODUCTION_OUTPUT_DIR } from './build/constant'
export default ({ command, mode }: TrinaConfigEnv): UserConfig => {
const env = loadEnv(mode, root)
const viteEnv = wrapperEnv(env)
- const { VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY, VITE_DROP_CONSOLE } = viteEnv
+ const { VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY, VITE_DROP_CONSOLE, VITE_GLOB_BRAND } = viteEnv
optimizeDeps: {
include: ['cosine-fee/es/locale/zh_CN', 'cosine-fee/es/locale/en_US'],
+ exclude: ['@trinapower/design', '@trinapower/design/theme', '@trinapower/design/theme/runtime']
},
}
}
postcss.config.js修改
diff
module.exports = (ctx) => {
return {
plugins: {
+ 'postcss-import': {},
+ 'tailwindcss/nesting': {},
+ tailwindcss: {},
autoprefixer: {},
},
}
}
main.js修改
diff
-import '@/design/tailwind.css'
-import '@/design/index.less'
+import '@trinapower/design'
+import '@trinapower/design/cosine-fee'
+import '@/assets/styles/index.less'
import 'virtual:svg-icons-register' // Register icon sprite