mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-16 11:22:02 +08:00
【同步】前端项目源码
【修复】工作流兼容问题
This commit is contained in:
71
frontend/packages/vue/naive-ui/src/theme/bak/baota/index.tsx
Normal file
71
frontend/packages/vue/naive-ui/src/theme/bak/baota/index.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import type { ThemeTemplate, PresetConfig } from '../../types'
|
||||
import './style.css'
|
||||
|
||||
// 预设参数配置,用于预设视图组件的相关参数
|
||||
const presets: PresetConfig = {
|
||||
Modal: {
|
||||
preset: 'card',
|
||||
},
|
||||
}
|
||||
|
||||
// 宝塔亮色主题
|
||||
const baotaLight: ThemeTemplate = {
|
||||
name: 'baotaLight',
|
||||
type: 'light',
|
||||
title: '宝塔亮色主题',
|
||||
themeOverrides: {
|
||||
Layout: {
|
||||
color: '#f9fafb',
|
||||
},
|
||||
common: {
|
||||
primaryColor: '#20a53a',
|
||||
fontSize: '12px',
|
||||
fontWeight: '400',
|
||||
},
|
||||
Dialog: {
|
||||
titleTextColor: '#333',
|
||||
titleFontSize: '14px',
|
||||
titleFontWeight: '400',
|
||||
titlePadding: '12px 16px',
|
||||
iconSize: '0px',
|
||||
padding: '0px',
|
||||
fontSize: '12px',
|
||||
closeMargin: '10px 12px',
|
||||
border: '1px solid #d9d9d9',
|
||||
},
|
||||
Card: {
|
||||
titleFontSizeMedium: '14px',
|
||||
titleFontWeightMedium: '400',
|
||||
titlePaddingMedium: '12px 16px',
|
||||
border: '1px solid #d9d9d9',
|
||||
padding: '0px',
|
||||
actionColor: '#20a53a',
|
||||
},
|
||||
|
||||
Button: {
|
||||
fontSizeSmall: '12px',
|
||||
fontSizeMedium: '12px',
|
||||
paddingMedium: '8px 16px',
|
||||
heightMedium: '32px',
|
||||
},
|
||||
DataTable: {
|
||||
thPaddingMedium: '8px',
|
||||
fontSizeMedium: '12px',
|
||||
thFontWeight: '400',
|
||||
},
|
||||
Table: {
|
||||
thPaddingMedium: '8px',
|
||||
fontSizeMedium: '12px',
|
||||
thFontWeight: '400',
|
||||
},
|
||||
Tabs: {
|
||||
navBgColor: '#fff',
|
||||
navActiveBgColor: '#eaf8ed',
|
||||
barColor: '#20a53a',
|
||||
tabFontWeightActive: '400',
|
||||
},
|
||||
},
|
||||
presetsOverrides: presets,
|
||||
}
|
||||
|
||||
export { baotaLight }
|
||||
51
frontend/packages/vue/naive-ui/src/theme/bak/baota/style.css
Normal file
51
frontend/packages/vue/naive-ui/src/theme/bak/baota/style.css
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 变量配置 */
|
||||
:root[class='baotaLight'] {
|
||||
--n-dialog-title-padding: 0 10px 0 18px; /* 对话框标题内边距 */
|
||||
--n-dialog-title-height: 40px; /* 对话框标题高度 */
|
||||
--n-dialog-content-padding: 20px 12px; /* 对话框内容内边距 */
|
||||
--n-dialog-action-bg: #f0f0f0; /* 对话框标题背景色 */
|
||||
--n-dialog-action-padding: 8px 16px; /* 对话框操作按钮内边距 */
|
||||
--bt-card-bg-color: #fff; /* tab卡片背景色 */
|
||||
--bt-card-bg-color-active: #eaf8ed; /* tab卡片背景色-激活 */
|
||||
}
|
||||
|
||||
:root[class='baotaDark'] {
|
||||
--n-dialog-title-color: #eee; /* 对话框标题文字颜色 */
|
||||
--n-dialog-action-bg: #333; /* 对话框标题背景色 */
|
||||
--n-dialog-border: 1px solid #333; /* 对话框标题下边框 */
|
||||
--bt-card-bg-color: #18181c; /* tab卡片背景色 */
|
||||
--bt-card-bg-color-active: #1e2720; /* tab卡片背景色-激活 */
|
||||
}
|
||||
|
||||
/* ------------------------------对话框--------------------------------- */
|
||||
|
||||
/* 对话框/模态框标题 */
|
||||
.n-dialog .n-dialog__title,
|
||||
.n-modal .n-card-header {
|
||||
padding: var(--n-dialog-title-padding) !important;
|
||||
background-color: var(--n-dialog-action-bg);
|
||||
color: var(--n-dialog-title-color);
|
||||
border-bottom: var(--n-dialog-border);
|
||||
height: var(--n-dialog-title-height);
|
||||
border-top-right-radius: var(--n-border-radius);
|
||||
border-top-left-radius: var(--n-border-radius);
|
||||
}
|
||||
|
||||
/* 对话框/模态框内容 */
|
||||
.n-dialog .n-dialog__content,
|
||||
.n-modal .n-card__content {
|
||||
margin: 0;
|
||||
padding: var(--n-dialog-content-padding);
|
||||
}
|
||||
|
||||
/* 对话框操作按钮 */
|
||||
.n-dialog .n-dialog__action,
|
||||
.n-modal .n-card__footer {
|
||||
border-top: var(--n-dialog-border);
|
||||
padding: var(--n-dialog-action-padding);
|
||||
background-color: var(--n-dialog-action-bg);
|
||||
border-bottom-left-radius: var(--n-border-radius);
|
||||
border-bottom-right-radius: var(--n-border-radius);
|
||||
}
|
||||
|
||||
/* 对话框-END */
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { ThemeTemplate, PresetConfig } from '../../types'
|
||||
import './style.css'
|
||||
|
||||
// 预设变量,用于继承预设主题
|
||||
const presets: PresetConfig = {
|
||||
Modal: {
|
||||
preset: 'card',
|
||||
},
|
||||
}
|
||||
|
||||
// 暗色主题
|
||||
const goldDark: ThemeTemplate = {
|
||||
name: 'darkGold',
|
||||
type: 'dark',
|
||||
title: '暗金主题',
|
||||
themeOverrides: {},
|
||||
presetsOverrides: presets, // 预设变量
|
||||
}
|
||||
|
||||
export { goldDark }
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Dark Theme */
|
||||
:root[class='darkGold'] {
|
||||
/* Empty light theme styles */
|
||||
}
|
||||
229
frontend/packages/vue/naive-ui/src/theme/index.tsx
Normal file
229
frontend/packages/vue/naive-ui/src/theme/index.tsx
Normal file
@@ -0,0 +1,229 @@
|
||||
import { computed, ref, effectScope, onScopeDispose, watch } from 'vue'
|
||||
import { useDark, useLocalStorage } from '@vueuse/core'
|
||||
import { darkTheme, lightTheme, useThemeVars } from 'naive-ui'
|
||||
import themes from './model'
|
||||
|
||||
import type { ThemeName, ThemeItemProps, ThemeTemplate } from './types'
|
||||
|
||||
// 驼峰命名转中划线命名的缓存
|
||||
const camelToKebabCache = new Map<string, string>()
|
||||
|
||||
/**
|
||||
* @description 驼峰命名转中划线命名
|
||||
* @param {string} str 输入的驼峰字符串
|
||||
* @returns {string} 转换后的中划线字符串
|
||||
*/
|
||||
const camelToKebabCase = (str: string): string => {
|
||||
if (camelToKebabCache.has(str)) {
|
||||
return camelToKebabCache.get(str)!
|
||||
}
|
||||
// 修改正则表达式,支持在字母与数字之间添加中划线
|
||||
const result = str
|
||||
.replace(/([a-z])([A-Z0-9])/g, '$1-$2')
|
||||
.replace(/([0-9])([a-zA-Z])/g, '$1-$2')
|
||||
.toLowerCase()
|
||||
camelToKebabCache.set(str, result)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 主题组合函数
|
||||
* @param {ThemeName} name 初始主题名称
|
||||
* @returns 主题状态和方法
|
||||
*/
|
||||
export const useTheme = (name?: ThemeName) => {
|
||||
// 主题状态
|
||||
const themeActive = useLocalStorage<ThemeName>('theme-active', name || 'defaultLight') // 主题名称
|
||||
|
||||
// 主题激活状态 Ref
|
||||
const themeActiveOverrides = ref<ThemeTemplate | null>(null)
|
||||
|
||||
// 是否暗黑
|
||||
const isDark = useDark()
|
||||
|
||||
// 主题
|
||||
const theme = computed(() => {
|
||||
return isDark.value ? darkTheme : lightTheme
|
||||
})
|
||||
|
||||
// 主题继承修改
|
||||
const themeOverrides = computed(() => {
|
||||
// 如果没有激活的主题,则返回空对象
|
||||
if (!themeActiveOverrides.value) return {}
|
||||
return themeActiveOverrides.value.themeOverrides || {}
|
||||
})
|
||||
|
||||
// 预设配置
|
||||
const presetsOverrides = computed(() => {
|
||||
// 如果没有激活的主题,则返回空对象
|
||||
console.log('presetsOverrides', themeActiveOverrides.value)
|
||||
if (!themeActiveOverrides.value) return {}
|
||||
return themeActiveOverrides.value.presetsOverrides || {}
|
||||
})
|
||||
|
||||
/**
|
||||
* @description 切换暗黑模式
|
||||
* @param {boolean} hasAnimation 是否有动画
|
||||
*/
|
||||
const cutDarkMode = (hasAnimation: boolean = false, e?: MouseEvent) => {
|
||||
// 检查当前主题是否存在暗黑模式
|
||||
isDark.value = !isDark.value
|
||||
|
||||
if (hasAnimation) {
|
||||
// 如果有动画,则执行切换暗黑模式动画
|
||||
cutDarkModeAnimation(e ? { clientX: e.clientX, clientY: e.clientY } : undefined)
|
||||
} else {
|
||||
themeActive.value = isDark.value ? 'defaultDark' : 'defaultLight'
|
||||
}
|
||||
// 更新主题名称
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 切换暗色模式动画
|
||||
*/
|
||||
const cutDarkModeAnimation = (event?: { clientY: number; clientX: number }) => {
|
||||
const root = document.documentElement
|
||||
// 先移除现有动画类
|
||||
root.classList.remove('animate-to-light', 'animate-to-dark')
|
||||
|
||||
// 添加相应的动画类
|
||||
root.classList.add(isDark.value ? 'animate-to-light' : 'animate-to-dark')
|
||||
|
||||
// 切换主题
|
||||
themeActive.value = isDark.value ? 'defaultDark' : 'defaultLight'
|
||||
setTimeout(() => {
|
||||
// 先移除现有动画类
|
||||
root.classList.remove('animate-to-light', 'animate-to-dark')
|
||||
}, 500)
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 动态加载CSS内容
|
||||
* @param {string} cssContent CSS内容
|
||||
* @param {string} id 样式标签ID
|
||||
*/
|
||||
const loadDynamicCss = (cssContent: string, id: string) => {
|
||||
// 检查是否已存在相同ID的样式标签
|
||||
let styleElement = document.getElementById(id) as HTMLStyleElement
|
||||
|
||||
if (!styleElement) {
|
||||
// 如果不存在,创建新的style标签
|
||||
styleElement = document.createElement('style')
|
||||
styleElement.id = id
|
||||
document.head.appendChild(styleElement)
|
||||
}
|
||||
|
||||
// 更新样式内容
|
||||
styleElement.textContent = cssContent
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 加载主题样式
|
||||
* @param {string} themeName 主题名称
|
||||
*/
|
||||
const loadThemeStyles = async (themeName: string) => {
|
||||
// 根据主题名称加载对应的样式文件
|
||||
try {
|
||||
// 从主题配置中获取样式路径
|
||||
const themeItem = themes[themeName]
|
||||
if (!themeItem) return
|
||||
// 加载主题样式
|
||||
const themeConfig = await themeItem.import()
|
||||
const themeStyles = await themeItem.styleContent() // 获取主题样式内容
|
||||
// 加载新样式
|
||||
if (themeStyles || themeStyles) {
|
||||
loadDynamicCss(themeStyles as string, 'theme-style')
|
||||
}
|
||||
// 更新激活的主题
|
||||
themeActiveOverrides.value = themeConfig
|
||||
} catch (error) {
|
||||
console.error(`加载主题失败 ${themeName}:`, error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取主题列表
|
||||
* @returns {ThemeItemProps[]} 主题列表
|
||||
*/
|
||||
const getThemeList = () => {
|
||||
const themeList: ThemeItemProps[] = []
|
||||
for (const key in themes) {
|
||||
themeList.push(themes[key])
|
||||
}
|
||||
return themeList
|
||||
}
|
||||
|
||||
const scope = effectScope()
|
||||
scope.run(() => {
|
||||
watch(
|
||||
themeActive,
|
||||
(newVal) => {
|
||||
// 移除之前的主题类名
|
||||
if (themeActive.value) document.documentElement.classList.remove(themeActive.value)
|
||||
// 添加新的主题类名
|
||||
document.documentElement.classList.add(newVal)
|
||||
// 更新主题名称
|
||||
themeActive.value = newVal
|
||||
// 加载主题样式
|
||||
loadThemeStyles(newVal)
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
onScopeDispose(() => {
|
||||
scope.stop()
|
||||
})
|
||||
})
|
||||
|
||||
return {
|
||||
// 状态
|
||||
theme,
|
||||
themeOverrides,
|
||||
presetsOverrides,
|
||||
isDark,
|
||||
themeActive,
|
||||
// 方法
|
||||
getThemeList, // 获取主题列表
|
||||
cutDarkModeAnimation, // 切换暗黑模式动画
|
||||
cutDarkMode, // 切换暗黑模式
|
||||
loadThemeStyles, // 加载主题样式
|
||||
loadDynamicCss, // 动态加载CSS内容
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 主题样式提取
|
||||
* @param {string[]} options 主题变量
|
||||
* @param options
|
||||
*/
|
||||
/**
|
||||
* @description 主题样式提取
|
||||
* @param {string[]} options 主题变量
|
||||
* @returns {string} 生成的样式字符串
|
||||
*/
|
||||
export const useThemeCssVar = (options: string[]) => {
|
||||
const vars = useThemeVars()
|
||||
const stylesRef = ref('')
|
||||
const scope = effectScope()
|
||||
scope.run(() => {
|
||||
watch(
|
||||
vars,
|
||||
(newVal) => {
|
||||
// 使用数组收集样式,最后统一拼接
|
||||
const styles: string[] = []
|
||||
for (const key of options) {
|
||||
if (key in newVal) {
|
||||
const kebabKey = camelToKebabCase(key)
|
||||
styles.push(`--n-${kebabKey}: ${newVal[key as keyof typeof vars.value]};`)
|
||||
}
|
||||
}
|
||||
// 拼接样式字符串
|
||||
stylesRef.value = styles.join('\n')
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
onScopeDispose(() => {
|
||||
scope.stop()
|
||||
})
|
||||
})
|
||||
return stylesRef
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import type { ThemeTemplate, PresetConfig } from '../../types'
|
||||
import './style.css'
|
||||
|
||||
// 预设变量,用于继承预设主题
|
||||
const presets: PresetConfig = {
|
||||
Modal: {
|
||||
preset: 'card',
|
||||
},
|
||||
}
|
||||
|
||||
// 默认亮色主题
|
||||
const defaultLight: ThemeTemplate = {
|
||||
name: 'defaultLight', // 主题标识
|
||||
type: 'light', // 主题类型,可选值为 light、dark,用于继承预设主题
|
||||
title: '默认亮色主题', // 主题名称
|
||||
themeOverrides: {
|
||||
common: {
|
||||
borderRadius: '0.6rem', // 圆角
|
||||
},
|
||||
}, // 主题变量
|
||||
presetsOverrides: presets, // 预设变量
|
||||
}
|
||||
|
||||
// 默认暗色主题
|
||||
const defaultDark: ThemeTemplate = {
|
||||
name: 'defaultDark',
|
||||
type: 'dark',
|
||||
title: '默认暗色主题',
|
||||
themeOverrides: {
|
||||
common: {
|
||||
// baseColor: '#F1F1F1', // 基础色
|
||||
primaryColor: '#4caf50', // 主色
|
||||
primaryColorHover: '#20a53a', // 主色悬停
|
||||
primaryColorPressed: '#157f3a', // 主色按下
|
||||
primaryColorSuppl: '#4caf50', // 主色补充
|
||||
borderRadius: '0.6rem', // 圆角
|
||||
},
|
||||
|
||||
Popover: {
|
||||
// color: '#ffffff', // 弹出层背景色
|
||||
},
|
||||
Button: {
|
||||
textColorPrimary: '#ffffff', // 主按钮文本色
|
||||
textColorHoverPrimary: '#ffffff', // 主按钮文本色悬停
|
||||
textColorPressedPrimary: '#ffffff', // 主按钮文本色按下
|
||||
textColorFocusPrimary: '#ffffff', // 主按钮文本色聚焦
|
||||
},
|
||||
Radio: {
|
||||
buttonTextColorActive: '#ffffff', // 单选框文本色
|
||||
},
|
||||
},
|
||||
presetsOverrides: presets, // 预设变量
|
||||
}
|
||||
|
||||
export { defaultLight, defaultDark }
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Light Theme */
|
||||
:root[class='defaultLight'] {
|
||||
/* Empty light theme styles */
|
||||
--background-color: #121212;
|
||||
--text-color: #f1f1f1;
|
||||
--bt-popover-color: #ffffff;
|
||||
}
|
||||
|
||||
/* Dark Theme */
|
||||
:root[class='defaultDark'] {
|
||||
/* Empty dark theme styles */
|
||||
--bg-color: #121212;
|
||||
--bt-popover-color: #48484e;
|
||||
}
|
||||
|
||||
/* 创建动画 */
|
||||
@keyframes fadeToLight {
|
||||
from {
|
||||
opacity: 0.8;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeToDark {
|
||||
from {
|
||||
opacity: 0.8;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* 应用动画 */
|
||||
:root {
|
||||
--background-color: #ffffff;
|
||||
--text-color: #333333;
|
||||
}
|
||||
|
||||
:root.animate-to-light {
|
||||
animation: fadeToLight 0.5s ease forwards;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:root.animate-to-dark {
|
||||
animation: fadeToDark 0.5s ease forwards;
|
||||
overflow: hidden;
|
||||
}
|
||||
42
frontend/packages/vue/naive-ui/src/theme/model/index.tsx
Normal file
42
frontend/packages/vue/naive-ui/src/theme/model/index.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
// 导出主题表,需要自己定义
|
||||
|
||||
import type { ThemeJsonProps } from '../types'
|
||||
|
||||
const cssModules = import.meta.glob('../model/*/*.css', {
|
||||
eager: false,
|
||||
import: 'default',
|
||||
// as: 'url', // 使用 url 加载器,将 CSS 文件作为独立的资源加载
|
||||
})
|
||||
|
||||
const themes: ThemeJsonProps = {
|
||||
defaultLight: {
|
||||
name: 'defaultLight', // 主题标识
|
||||
type: 'light', // 主题类型,可选值为 light、dark,用于继承预设主题
|
||||
title: '默认亮色主题', // 主题名称
|
||||
import: async () => (await import('./default/index')).defaultLight, // 主题导入函数,用于动态导入主题文件
|
||||
styleContent: async () => (await cssModules['./default/style.css']()) as string, // 主题样式导入函数,用于动态导入主题样式文件
|
||||
},
|
||||
defaultDark: {
|
||||
name: 'defaultDark',
|
||||
type: 'dark',
|
||||
title: '默认暗色主题',
|
||||
import: async () => (await import('./default/index')).defaultDark,
|
||||
styleContent: async () => (await cssModules['./default/style.css']()) as string, // 主题样式导入函数,用于动态导入主题样式文件
|
||||
},
|
||||
// baotaLight: {
|
||||
// name: 'baotaLight',
|
||||
// type: 'light',
|
||||
// title: '宝塔主题',
|
||||
// import: async () => (await import('./baota/index')).baotaLight,
|
||||
// styleContent: async () => (await cssModules['./baota/style.css']()) as string, // 主题样式导入函数,用于动态导入主题样式文件
|
||||
// },
|
||||
// darkGold: {
|
||||
// name: 'darkGold',
|
||||
// type: 'dark',
|
||||
// title: '暗金主题',
|
||||
// import: async () => (await import('./dark-gold/index')).goldDark,
|
||||
// styleContent: async () => (await cssModules['./dark-gold/style.css']()) as string, // 主题样式导入函数,用于动态导入主题样式文件
|
||||
// },
|
||||
}
|
||||
|
||||
export default themes
|
||||
52
frontend/packages/vue/naive-ui/src/theme/model/ssl/index.tsx
Normal file
52
frontend/packages/vue/naive-ui/src/theme/model/ssl/index.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import type { ThemeTemplate, PresetConfig } from '../../types'
|
||||
import './style.css'
|
||||
|
||||
// 预设变量,用于继承预设主题
|
||||
const presets: PresetConfig = {
|
||||
Modal: {
|
||||
preset: 'card',
|
||||
},
|
||||
}
|
||||
|
||||
// 默认亮色主题
|
||||
const blueLight: ThemeTemplate = {
|
||||
name: 'blueLight', // 主题标识
|
||||
type: 'light', // 主题类型,可选值为 light、dark,用于继承预设主题
|
||||
title: '蓝色主题', // 主题名称
|
||||
themeOverrides: {
|
||||
common: {},
|
||||
}, // 主题变量
|
||||
presetsOverrides: presets, // 预设变量
|
||||
}
|
||||
|
||||
// 默认暗色主题
|
||||
const blueDark: ThemeTemplate = {
|
||||
name: 'blueDark',
|
||||
type: 'dark',
|
||||
title: '蓝色主题',
|
||||
themeOverrides: {
|
||||
common: {
|
||||
// baseColor: '#F1F1F1', // 基础色
|
||||
primaryColor: '#4caf50', // 主色
|
||||
primaryColorHover: '#20a53a', // 主色悬停
|
||||
primaryColorPressed: '#157f3a', // 主色按下
|
||||
primaryColorSuppl: '#4caf50', // 主色补充
|
||||
},
|
||||
|
||||
Popover: {
|
||||
// color: '#ffffff', // 弹出层背景色
|
||||
},
|
||||
Button: {
|
||||
textColorPrimary: '#ffffff', // 主按钮文本色
|
||||
textColorHoverPrimary: '#ffffff', // 主按钮文本色悬停
|
||||
textColorPressedPrimary: '#ffffff', // 主按钮文本色按下
|
||||
textColorFocusPrimary: '#ffffff', // 主按钮文本色聚焦
|
||||
},
|
||||
Radio: {
|
||||
buttonTextColorActive: '#ffffff', // 单选框文本色
|
||||
},
|
||||
},
|
||||
presetsOverrides: presets, // 预设变量
|
||||
}
|
||||
|
||||
export { blueLight, blueDark }
|
||||
69
frontend/packages/vue/naive-ui/src/theme/model/ssl/style.css
Normal file
69
frontend/packages/vue/naive-ui/src/theme/model/ssl/style.css
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Light Theme */
|
||||
:root[class='defaultLight'] {
|
||||
/* Empty light theme styles */
|
||||
--background-color: #121212;
|
||||
--text-color: #f1f1f1;
|
||||
--bt-popover-color: #ffffff;
|
||||
}
|
||||
|
||||
/* Dark Theme */
|
||||
:root[class='defaultDark'] {
|
||||
/* Empty dark theme styles */
|
||||
--bg-color: #121212;
|
||||
--bt-popover-color: #48484e;
|
||||
}
|
||||
|
||||
/* 创建动画 */
|
||||
@keyframes fadeToLight {
|
||||
from {
|
||||
opacity: 0.8;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeToDark {
|
||||
from {
|
||||
opacity: 0.8;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* 应用动画 */
|
||||
:root {
|
||||
--background-color: #ffffff;
|
||||
--text-color: #333333;
|
||||
}
|
||||
|
||||
:root.animate-to-light {
|
||||
animation: fadeToLight 0.5s ease forwards;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:root.animate-to-dark {
|
||||
animation: fadeToDark 0.5s ease forwards;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.text-info {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: #ff9800;
|
||||
}
|
||||
|
||||
.text-error {
|
||||
color: #f44336;
|
||||
}
|
||||
36
frontend/packages/vue/naive-ui/src/theme/types.d.ts
vendored
Normal file
36
frontend/packages/vue/naive-ui/src/theme/types.d.ts
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { GlobalThemeOverrides, ModalProps, FormProps, FormItemProps, TableProps } from 'naive-ui'
|
||||
|
||||
export interface ThemeTemplate {
|
||||
name: string
|
||||
type: 'light' | 'dark'
|
||||
title: string
|
||||
themeOverrides: GlobalThemeOverrides
|
||||
presetsOverrides: PresetConfig
|
||||
}
|
||||
|
||||
export interface ThemeTemplateType {
|
||||
[key: string]: ThemeTemplate
|
||||
}
|
||||
|
||||
// 主题名称
|
||||
export type ThemeName = string
|
||||
|
||||
// 预设配置
|
||||
export interface PresetConfig {
|
||||
Modal?: ModalProps
|
||||
Form?: FormProps
|
||||
FormItem?: FormItemProps
|
||||
Table?: TableProps
|
||||
}
|
||||
|
||||
export interface ThemeItemProps {
|
||||
name: string // 主题标识
|
||||
type: 'light' | 'dark' // 主题类型,可选值为 light、dark,用于继承预设主题
|
||||
title: string // 主题名称
|
||||
import: () => Promise<ThemeTemplate> // 主题导入函数,用于动态导入主题文件
|
||||
styleContent: () => Promise<string> // 主题样式内容,用于动态生成主题样式
|
||||
}
|
||||
|
||||
export interface ThemeJsonProps {
|
||||
[key: string]: ThemeItemProps // 主题表,key为主题标识,value为主题配置
|
||||
}
|
||||
Reference in New Issue
Block a user