Commit 5b8eb4a49a097a47caf491c44df427522ab58daa
1 parent
f05cc6d3
feat: dark mode
Showing
100 changed files
with
720 additions
and
803 deletions
Too many changes to show.
To preserve performance only 100 of 109 files are displayed.
CHANGELOG.zh_CN.md
build/config/themeConfig.ts
@@ -2,11 +2,7 @@ import { generate } from '@ant-design/colors'; | @@ -2,11 +2,7 @@ import { generate } from '@ant-design/colors'; | ||
2 | 2 | ||
3 | export const primaryColor = '#0960bd'; | 3 | export const primaryColor = '#0960bd'; |
4 | 4 | ||
5 | -export const borderColorBase = '#d9d9d9'; | ||
6 | - | ||
7 | -export const themeMode = 'light'; | ||
8 | - | ||
9 | -export type ThemeMode = 'dark' | 'light'; | 5 | +export const darkMode = 'light'; |
10 | 6 | ||
11 | type Fn = (...arg: any) => any; | 7 | type Fn = (...arg: any) => any; |
12 | 8 | ||
@@ -17,18 +13,17 @@ export interface GenerateColorsParams { | @@ -17,18 +13,17 @@ export interface GenerateColorsParams { | ||
17 | color?: string; | 13 | color?: string; |
18 | } | 14 | } |
19 | 15 | ||
20 | -export function generateAntColors(color: string, mode: ThemeMode) { | 16 | +export function generateAntColors(color: string) { |
21 | return generate(color, { | 17 | return generate(color, { |
22 | - theme: mode == 'dark' ? 'dark' : 'default', | 18 | + theme: 'default', |
23 | }); | 19 | }); |
24 | } | 20 | } |
25 | 21 | ||
26 | -export function getThemeColors(color?: string, theme?: ThemeMode) { | 22 | +export function getThemeColors(color?: string) { |
27 | const tc = color || primaryColor; | 23 | const tc = color || primaryColor; |
28 | - const tm = theme || themeMode; | ||
29 | - const colors = generateAntColors(tc, tm); | 24 | + const colors = generateAntColors(tc); |
30 | const primary = colors[5]; | 25 | const primary = colors[5]; |
31 | - const modeColors = generateAntColors(primary, tm === 'dark' ? 'light' : 'dark'); | 26 | + const modeColors = generateAntColors(primary); |
32 | 27 | ||
33 | return [...colors, ...modeColors]; | 28 | return [...colors, ...modeColors]; |
34 | } | 29 | } |
@@ -71,36 +66,3 @@ export function generateColors({ | @@ -71,36 +66,3 @@ export function generateColors({ | ||
71 | .filter((item) => item !== '#000000'); | 66 | .filter((item) => item !== '#000000'); |
72 | return [...lightens, ...darkens, ...alphaColors, ...tinycolorDarkens, ...tinycolorLightens]; | 67 | return [...lightens, ...darkens, ...alphaColors, ...tinycolorDarkens, ...tinycolorLightens]; |
73 | } | 68 | } |
74 | - | ||
75 | -/** | ||
76 | - * less global variable | ||
77 | - */ | ||
78 | -export function generateModifyVars() { | ||
79 | - const palettes = generateAntColors(primaryColor, themeMode); | ||
80 | - const primary = palettes[5]; | ||
81 | - | ||
82 | - const primaryColorObj: Record<string, string> = {}; | ||
83 | - | ||
84 | - for (let index = 0; index < 10; index++) { | ||
85 | - primaryColorObj[`primary-${index + 1}`] = palettes[index]; | ||
86 | - } | ||
87 | - | ||
88 | - return { | ||
89 | - 'primary-color': primary, | ||
90 | - ...primaryColorObj, | ||
91 | - 'info-color': primary, | ||
92 | - 'processing-color': primary, | ||
93 | - 'success-color': '#55D187', // Success color | ||
94 | - 'error-color': '#ED6F6F', // False color | ||
95 | - 'warning-color': '#EFBD47', // Warning color | ||
96 | - 'disabled-color': 'rgba(0, 0, 0, 0.25)', // Failure color | ||
97 | - 'heading-color': 'rgba(0, 0, 0, 0.85)', // Title color | ||
98 | - 'text-color': 'rgba(0, 0, 0, 0.85)', // Main text color | ||
99 | - 'text-color-secondary': 'rgba(0, 0, 0, 0.45)', // Subtext color | ||
100 | - 'font-size-base': '14px', // Main font size | ||
101 | - 'box-shadow-base': '0 2px 8px rgba(0, 0, 0, 0.15)', // Floating shadow | ||
102 | - 'border-color-base': borderColorBase, // Border color, | ||
103 | - 'border-radius-base': '2px', // Component/float fillet | ||
104 | - 'link-color': primary, // Link color | ||
105 | - }; | ||
106 | -} |
build/generate/generateModifyVars.ts
0 → 100644
1 | +import { generateAntColors, primaryColor } from '../config/themeConfig'; | ||
2 | +import { getThemeVariables } from 'ant-design-vue/dist/theme'; | ||
3 | +import { resolve } from 'path'; | ||
4 | + | ||
5 | +/** | ||
6 | + * less global variable | ||
7 | + */ | ||
8 | +export function generateModifyVars(dark = false) { | ||
9 | + const palettes = generateAntColors(primaryColor); | ||
10 | + const primary = palettes[5]; | ||
11 | + | ||
12 | + const primaryColorObj: Record<string, string> = {}; | ||
13 | + | ||
14 | + for (let index = 0; index < 10; index++) { | ||
15 | + primaryColorObj[`primary-${index + 1}`] = palettes[index]; | ||
16 | + } | ||
17 | + | ||
18 | + const modifyVars = getThemeVariables({ dark }); | ||
19 | + return { | ||
20 | + ...modifyVars, | ||
21 | + // Used for global import to avoid the need to import each style file separately | ||
22 | + // reference: Avoid repeated references | ||
23 | + hack: `${modifyVars.hack} @import (reference) "${resolve('src/design/config.less')}";`, | ||
24 | + 'primary-color': primary, | ||
25 | + ...primaryColorObj, | ||
26 | + 'info-color': primary, | ||
27 | + 'processing-color': primary, | ||
28 | + 'success-color': '#55D187', // Success color | ||
29 | + 'error-color': '#ED6F6F', // False color | ||
30 | + 'warning-color': '#EFBD47', // Warning color | ||
31 | + 'font-size-base': '14px', // Main font size | ||
32 | + 'border-radius-base': '2px', // Component/float fillet | ||
33 | + 'link-color': primary, // Link color | ||
34 | + }; | ||
35 | +} |
build/vite/plugin/index.ts
@@ -62,7 +62,7 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) { | @@ -62,7 +62,7 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) { | ||
62 | vitePlugins.push(configVisualizerConfig()); | 62 | vitePlugins.push(configVisualizerConfig()); |
63 | 63 | ||
64 | //vite-plugin-theme | 64 | //vite-plugin-theme |
65 | - vitePlugins.push(configThemePlugin()); | 65 | + vitePlugins.push(configThemePlugin(isBuild)); |
66 | 66 | ||
67 | // The following plugins only work in the production environment | 67 | // The following plugins only work in the production environment |
68 | if (isBuild) { | 68 | if (isBuild) { |
build/vite/plugin/theme.ts
@@ -2,18 +2,50 @@ | @@ -2,18 +2,50 @@ | ||
2 | * Vite plugin for website theme color switching | 2 | * Vite plugin for website theme color switching |
3 | * https://github.com/anncwb/vite-plugin-theme | 3 | * https://github.com/anncwb/vite-plugin-theme |
4 | */ | 4 | */ |
5 | -import { viteThemePlugin, mixLighten, mixDarken, tinycolor } from 'vite-plugin-theme'; | 5 | +import type { Plugin } from 'vite'; |
6 | +import { | ||
7 | + viteThemePlugin, | ||
8 | + antdDarkThemePlugin, | ||
9 | + mixLighten, | ||
10 | + mixDarken, | ||
11 | + tinycolor, | ||
12 | +} from 'vite-plugin-theme'; | ||
6 | import { getThemeColors, generateColors } from '../../config/themeConfig'; | 13 | import { getThemeColors, generateColors } from '../../config/themeConfig'; |
14 | +import { generateModifyVars } from '../../generate/generateModifyVars'; | ||
7 | 15 | ||
8 | -export function configThemePlugin() { | 16 | +export function configThemePlugin(isBuild: boolean): Plugin[] { |
9 | const colors = generateColors({ | 17 | const colors = generateColors({ |
10 | mixDarken, | 18 | mixDarken, |
11 | mixLighten, | 19 | mixLighten, |
12 | tinycolor, | 20 | tinycolor, |
13 | }); | 21 | }); |
14 | 22 | ||
15 | - const plugin = viteThemePlugin({ | ||
16 | - colorVariables: [...getThemeColors(), ...colors], | ||
17 | - }); | ||
18 | - return plugin; | 23 | + const plugin = [ |
24 | + viteThemePlugin({ | ||
25 | + resolveSelector: (s) => `[data-theme] ${s}`, | ||
26 | + colorVariables: [...getThemeColors(), ...colors], | ||
27 | + }), | ||
28 | + antdDarkThemePlugin({ | ||
29 | + filter: (id) => { | ||
30 | + if (isBuild) { | ||
31 | + return !id.endsWith('antd.less'); | ||
32 | + } | ||
33 | + return true; | ||
34 | + }, | ||
35 | + // extractCss: false, | ||
36 | + darkModifyVars: { | ||
37 | + ...generateModifyVars(true), | ||
38 | + 'text-color': '#c9d1d9', | ||
39 | + 'text-color-base': '#c9d1d9', | ||
40 | + 'component-background': '#151515', | ||
41 | + // black: '#0e1117', | ||
42 | + // #8b949e | ||
43 | + 'text-color-secondary': '#8b949e', | ||
44 | + 'border-color-base': '#30363d', | ||
45 | + 'item-active-bg': '#111b26', | ||
46 | + }, | ||
47 | + }), | ||
48 | + ]; | ||
49 | + | ||
50 | + return (plugin as unknown) as Plugin[]; | ||
19 | } | 51 | } |
index.html
1 | <!DOCTYPE html> | 1 | <!DOCTYPE html> |
2 | -<html lang="en"> | 2 | +<html lang="en" id="htmlRoot"> |
3 | <head> | 3 | <head> |
4 | <meta charset="UTF-8" /> | 4 | <meta charset="UTF-8" /> |
5 | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> | 5 | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> |
@@ -13,8 +13,24 @@ | @@ -13,8 +13,24 @@ | ||
13 | <link rel="icon" href="/favicon.ico" /> | 13 | <link rel="icon" href="/favicon.ico" /> |
14 | </head> | 14 | </head> |
15 | <body> | 15 | <body> |
16 | + <script> | ||
17 | + (() => { | ||
18 | + var htmlRoot = document.getElementById('htmlRoot'); | ||
19 | + const theme = window.localStorage.getItem('__APP__DARK__MODE__'); | ||
20 | + if (!htmlRoot || !theme) return; | ||
21 | + htmlRoot.setAttribute('data-theme', theme); | ||
22 | + })(); | ||
23 | + </script> | ||
16 | <div id="app"> | 24 | <div id="app"> |
17 | <style> | 25 | <style> |
26 | + html[data-theme='dark'] .app-loading { | ||
27 | + background: #2c344a; | ||
28 | + } | ||
29 | + | ||
30 | + html[data-theme='dark'] .app-loading .app-loading-title { | ||
31 | + color: rgba(255, 255, 255, 0.85); | ||
32 | + } | ||
33 | + | ||
18 | .app-loading { | 34 | .app-loading { |
19 | display: flex; | 35 | display: flex; |
20 | width: 100%; | 36 | width: 100%; |
package.json
@@ -35,7 +35,6 @@ | @@ -35,7 +35,6 @@ | ||
35 | "@vueuse/core": "^4.7.0", | 35 | "@vueuse/core": "^4.7.0", |
36 | "@zxcvbn-ts/core": "^0.3.0", | 36 | "@zxcvbn-ts/core": "^0.3.0", |
37 | "ant-design-vue": "^2.1.2", | 37 | "ant-design-vue": "^2.1.2", |
38 | - "apexcharts": "^3.26.0", | ||
39 | "axios": "^0.21.1", | 38 | "axios": "^0.21.1", |
40 | "cropperjs": "^1.5.11", | 39 | "cropperjs": "^1.5.11", |
41 | "crypto-js": "^4.0.0", | 40 | "crypto-js": "^4.0.0", |
@@ -51,7 +50,7 @@ | @@ -51,7 +50,7 @@ | ||
51 | "vditor": "^3.8.4", | 50 | "vditor": "^3.8.4", |
52 | "vue": "3.0.11", | 51 | "vue": "3.0.11", |
53 | "vue-i18n": "^9.0.0", | 52 | "vue-i18n": "^9.0.0", |
54 | - "vue-router": "^4.0.5", | 53 | + "vue-router": "^4.0.6", |
55 | "vue-types": "^3.0.2", | 54 | "vue-types": "^3.0.2", |
56 | "vuex": "^4.0.0", | 55 | "vuex": "^4.0.0", |
57 | "vuex-module-decorators": "^1.0.1", | 56 | "vuex-module-decorators": "^1.0.1", |
@@ -110,12 +109,12 @@ | @@ -110,12 +109,12 @@ | ||
110 | "vite-plugin-compression": "^0.2.4", | 109 | "vite-plugin-compression": "^0.2.4", |
111 | "vite-plugin-html": "^2.0.6", | 110 | "vite-plugin-html": "^2.0.6", |
112 | "vite-plugin-imagemin": "^0.3.0", | 111 | "vite-plugin-imagemin": "^0.3.0", |
113 | - "vite-plugin-mock": "^2.4.2", | 112 | + "vite-plugin-mock": "^2.5.0", |
114 | "vite-plugin-purge-icons": "^0.7.0", | 113 | "vite-plugin-purge-icons": "^0.7.0", |
115 | "vite-plugin-pwa": "^0.6.5", | 114 | "vite-plugin-pwa": "^0.6.5", |
116 | "vite-plugin-style-import": "^0.9.2", | 115 | "vite-plugin-style-import": "^0.9.2", |
117 | "vite-plugin-svg-icons": "^0.4.1", | 116 | "vite-plugin-svg-icons": "^0.4.1", |
118 | - "vite-plugin-theme": "^0.5.0", | 117 | + "vite-plugin-theme": "^0.6.0", |
119 | "vite-plugin-windicss": "0.12.5", | 118 | "vite-plugin-windicss": "0.12.5", |
120 | "vue-eslint-parser": "^7.6.0" | 119 | "vue-eslint-parser": "^7.6.0" |
121 | }, | 120 | }, |
src/assets/icons/moon.svg
0 → 100644
1 | +<?xml version="1.0" encoding="iso-8859-1"?> | ||
2 | +<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||
3 | + viewBox="0 0 499.712 499.712" style="enable-background: new 0 0 499.712 499.712;" xml:space="preserve"> | ||
4 | +<path style="fill: #FFD93B;" d="M146.88,375.528c126.272,0,228.624-102.368,228.624-228.64c0-55.952-20.16-107.136-53.52-146.88 | ||
5 | + C425.056,33.096,499.696,129.64,499.696,243.704c0,141.392-114.608,256-256,256c-114.064,0-210.608-74.64-243.696-177.712 | ||
6 | + C39.744,355.368,90.944,375.528,146.88,375.528z"/> | ||
7 | +<path style="fill: #F4C534;" d="M401.92,42.776c34.24,43.504,54.816,98.272,54.816,157.952c0,141.392-114.608,256-256,256 | ||
8 | + c-59.68,0-114.448-20.576-157.952-54.816c46.848,59.472,119.344,97.792,200.928,97.792c141.392,0,256-114.608,256-256 | ||
9 | + C499.712,162.12,461.392,89.64,401.92,42.776z"/> | ||
10 | +<g> | ||
11 | + <polygon style="fill: #FFD83B;" points="128.128,99.944 154.496,153.4 213.472,161.96 170.8,203.56 180.864,262.296 | ||
12 | + 128.128,234.568 75.376,262.296 85.44,203.56 42.768,161.96 101.744,153.4"/> | ||
13 | + <polygon style="fill: #FFD83B;" points="276.864,82.84 290.528,110.552 321.104,114.984 298.976,136.552 304.208,166.984 | ||
14 | + 276.864,152.616 249.52,166.984 254.752,136.552 232.624,114.984 263.2,110.552"/> | ||
15 | +</g> | ||
16 | +</svg> |
src/assets/icons/sun.svg
0 → 100644
1 | +<?xml version="1.0" encoding="iso-8859-1"?> | ||
2 | +<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||
3 | + viewBox="0 0 60 60" style="enable-background: new 0 0 60 60;" xml:space="preserve"> | ||
4 | +<g> | ||
5 | + <path style="fill: #F0C419;" d="M30,0c-0.552,0-1,0.448-1,1v6c0,0.552,0.448,1,1,1s1-0.448,1-1V1C31,0.448,30.552,0,30,0z"/> | ||
6 | + <path style="fill: #F0C419;" d="M30,52c-0.552,0-1,0.448-1,1v6c0,0.552,0.448,1,1,1s1-0.448,1-1v-6C31,52.448,30.552,52,30,52z"/> | ||
7 | + <path style="fill: #F0C419;" d="M59,29h-6c-0.552,0-1,0.448-1,1s0.448,1,1,1h6c0.552,0,1-0.448,1-1S59.552,29,59,29z"/> | ||
8 | + <path style="fill: #F0C419;" d="M8,30c0-0.552-0.448-1-1-1H1c-0.552,0-1,0.448-1,1s0.448,1,1,1h6C7.552,31,8,30.552,8,30z"/> | ||
9 | + <path style="fill: #F0C419;" d="M46.264,14.736c0.256,0,0.512-0.098,0.707-0.293l5.736-5.736c0.391-0.391,0.391-1.023,0-1.414 | ||
10 | + s-1.023-0.391-1.414,0l-5.736,5.736c-0.391,0.391-0.391,1.023,0,1.414C45.752,14.639,46.008,14.736,46.264,14.736z"/> | ||
11 | + <path style="fill: #F0C419;" d="M13.029,45.557l-5.736,5.736c-0.391,0.391-0.391,1.023,0,1.414C7.488,52.902,7.744,53,8,53 | ||
12 | + s0.512-0.098,0.707-0.293l5.736-5.736c0.391-0.391,0.391-1.023,0-1.414S13.42,45.166,13.029,45.557z"/> | ||
13 | + <path style="fill: #F0C419;" d="M46.971,45.557c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l5.736,5.736 | ||
14 | + C51.488,52.902,51.744,53,52,53s0.512-0.098,0.707-0.293c0.391-0.391,0.391-1.023,0-1.414L46.971,45.557z"/> | ||
15 | + <path style="fill: #F0C419;" d="M8.707,7.293c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l5.736,5.736 | ||
16 | + c0.195,0.195,0.451,0.293,0.707,0.293s0.512-0.098,0.707-0.293c0.391-0.391,0.391-1.023,0-1.414L8.707,7.293z"/> | ||
17 | + <path style="fill: #F0C419;" d="M50.251,21.404c0.162,0.381,0.532,0.61,0.921,0.61c0.13,0,0.263-0.026,0.39-0.08l2.762-1.172 | ||
18 | + c0.508-0.216,0.746-0.803,0.53-1.311s-0.804-0.746-1.311-0.53l-2.762,1.172C50.272,20.309,50.035,20.896,50.251,21.404z"/> | ||
19 | + <path style="fill: #F0C419;" d="M9.749,38.596c-0.216-0.508-0.803-0.746-1.311-0.53l-2.762,1.172 | ||
20 | + c-0.508,0.216-0.746,0.803-0.53,1.311c0.162,0.381,0.532,0.61,0.921,0.61c0.13,0,0.263-0.026,0.39-0.08l2.762-1.172 | ||
21 | + C9.728,39.691,9.965,39.104,9.749,38.596z"/> | ||
22 | + <path style="fill: #F0C419;" d="M54.481,38.813L51.7,37.688c-0.511-0.207-1.095,0.041-1.302,0.553 | ||
23 | + c-0.207,0.512,0.041,1.095,0.553,1.302l2.782,1.124c0.123,0.049,0.25,0.073,0.374,0.073c0.396,0,0.771-0.236,0.928-0.626 | ||
24 | + C55.241,39.603,54.994,39.02,54.481,38.813z"/> | ||
25 | + <path style="fill: #F0C419;" d="M5.519,21.188L8.3,22.312c0.123,0.049,0.25,0.073,0.374,0.073c0.396,0,0.771-0.236,0.928-0.626 | ||
26 | + c0.207-0.512-0.041-1.095-0.553-1.302l-2.782-1.124c-0.513-0.207-1.095,0.04-1.302,0.553C4.759,20.397,5.006,20.98,5.519,21.188z" | ||
27 | + /> | ||
28 | + <path style="fill: #F0C419;" d="M39.907,50.781c-0.216-0.508-0.803-0.745-1.311-0.53c-0.508,0.216-0.746,0.803-0.53,1.311 | ||
29 | + l1.172,2.762c0.162,0.381,0.532,0.61,0.921,0.61c0.13,0,0.263-0.026,0.39-0.08c0.508-0.216,0.746-0.803,0.53-1.311L39.907,50.781z" | ||
30 | + /> | ||
31 | + <path style="fill: #F0C419;" d="M21.014,9.829c0.13,0,0.263-0.026,0.39-0.08c0.508-0.216,0.746-0.803,0.53-1.311l-1.172-2.762 | ||
32 | + c-0.215-0.509-0.802-0.747-1.311-0.53c-0.508,0.216-0.746,0.803-0.53,1.311l1.172,2.762C20.254,9.6,20.625,9.829,21.014,9.829z"/> | ||
33 | + <path style="fill: #F0C419;" d="M21.759,50.398c-0.511-0.205-1.095,0.04-1.302,0.553l-1.124,2.782 | ||
34 | + c-0.207,0.512,0.041,1.095,0.553,1.302c0.123,0.049,0.25,0.073,0.374,0.073c0.396,0,0.771-0.236,0.928-0.626l1.124-2.782 | ||
35 | + C22.519,51.188,22.271,50.605,21.759,50.398z"/> | ||
36 | + <path style="fill: #F0C419;" d="M38.615,9.675c0.396,0,0.771-0.236,0.928-0.626l1.124-2.782c0.207-0.512-0.041-1.095-0.553-1.302 | ||
37 | + c-0.511-0.207-1.095,0.041-1.302,0.553L37.688,8.3c-0.207,0.512,0.041,1.095,0.553,1.302C38.364,9.651,38.491,9.675,38.615,9.675z" | ||
38 | + /> | ||
39 | +</g> | ||
40 | +<circle style="fill: #F0C419;" cx="30" cy="30" r="20"/> | ||
41 | +<circle style="fill: #EDE21B;" cx="30" cy="30" r="15"/> | ||
42 | +</svg> |
src/assets/svg/login-bg-dark.svg
0 → 100644
1 | +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="6395" height="1080" viewBox="0 0 6395 1080"> | ||
2 | + <defs> | ||
3 | + <clipPath id="clip-path"> | ||
4 | + <rect id="Rectangle_73" data-name="Rectangle 73" width="6395" height="1079" transform="translate(-5391)" fill="#fff"/> | ||
5 | + </clipPath> | ||
6 | + <linearGradient id="linear-gradient" x1="0.631" y1="0.5" x2="0.958" y2="0.488" gradientUnits="objectBoundingBox"> | ||
7 | + <stop offset="0" stop-color="#2e364a"/> | ||
8 | + <stop offset="1" stop-color="#2c344a"/> | ||
9 | + </linearGradient> | ||
10 | + </defs> | ||
11 | + <g id="Web_1920_1" data-name="Web 1920 – 1" clip-path="url(#clip-Web_1920_1)"> | ||
12 | + <g id="Mask_Group_1" data-name="Mask Group 1" transform="translate(5391)" clip-path="url(#clip-path)"> | ||
13 | + <g id="Group_118" data-name="Group 118" transform="translate(-419.333 -1.126)"> | ||
14 | + <path id="Path_142" data-name="Path 142" d="M6271.734-6.176s-222.478,187.809-55.349,583.254c44.957,106.375,81.514,205.964,84.521,277,8.164,192.764-156.046,268.564-156.046,268.564l-653.53-26.8L5475.065-21.625Z" transform="translate(-4876.383)" fill="#2d3750"/> | ||
15 | + <path id="Union_6" data-name="Union 6" d="M-2631.1,1081.8v-1.6H-8230.9V.022h5599.8V0h759.7s-187.845,197.448-91.626,488.844c49.167,148.9,96.309,256.289,104.683,362.118,7.979,100.852-57.98,201.711-168.644,254.286-65.858,31.29-144.552,42.382-223.028,42.383C-2441.2,1147.632-2631.1,1081.8-2631.1,1081.8Z" transform="translate(3259.524 0.803)" fill="url(#linear-gradient)"/> | ||
16 | + </g> | ||
17 | + </g> | ||
18 | + </g> | ||
19 | +</svg> |
src/assets/svg/login-bg.svg
@@ -4,8 +4,8 @@ | @@ -4,8 +4,8 @@ | ||
4 | <rect id="Rectangle_73" data-name="Rectangle 73" width="6395" height="1079" transform="translate(-5391)" fill="#fff"/> | 4 | <rect id="Rectangle_73" data-name="Rectangle 73" width="6395" height="1079" transform="translate(-5391)" fill="#fff"/> |
5 | </clipPath> | 5 | </clipPath> |
6 | <linearGradient id="linear-gradient" x1="0.747" y1="0.222" x2="0.973" y2="0.807" gradientUnits="objectBoundingBox"> | 6 | <linearGradient id="linear-gradient" x1="0.747" y1="0.222" x2="0.973" y2="0.807" gradientUnits="objectBoundingBox"> |
7 | - <stop offset="0" stop-color="#2b51b4"/> | ||
8 | - <stop offset="1" stop-color="#1c3faa"/> | 7 | + <stop offset="0" stop-color="#2c41b4"/> |
8 | + <stop offset="1" stop-color="#1b4fab"/> | ||
9 | </linearGradient> | 9 | </linearGradient> |
10 | </defs> | 10 | </defs> |
11 | <g id="Mask_Group_1" data-name="Mask Group 1" transform="translate(5391)" clip-path="url(#clip-path)"> | 11 | <g id="Mask_Group_1" data-name="Mask Group 1" transform="translate(5391)" clip-path="url(#clip-path)"> |
src/components/Application/index.ts
@@ -2,6 +2,7 @@ import AppLogo from './src/AppLogo.vue'; | @@ -2,6 +2,7 @@ import AppLogo from './src/AppLogo.vue'; | ||
2 | import AppProvider from './src/AppProvider.vue'; | 2 | import AppProvider from './src/AppProvider.vue'; |
3 | import AppSearch from './src/search/AppSearch.vue'; | 3 | import AppSearch from './src/search/AppSearch.vue'; |
4 | import AppLocalePicker from './src/AppLocalePicker.vue'; | 4 | import AppLocalePicker from './src/AppLocalePicker.vue'; |
5 | +import AppDarkModeToggle from './src/AppDarkModeToggle.vue'; | ||
5 | 6 | ||
6 | export { useAppProviderContext } from './src/useAppContext'; | 7 | export { useAppProviderContext } from './src/useAppContext'; |
7 | -export { AppLogo, AppProvider, AppSearch, AppLocalePicker }; | 8 | +export { AppLogo, AppProvider, AppSearch, AppLocalePicker, AppDarkModeToggle }; |
src/components/Application/src/AppDarkModeToggle.vue
0 → 100644
1 | +<template> | ||
2 | + <div | ||
3 | + v-if="getShowDarkModeToggle" | ||
4 | + :class="[ | ||
5 | + prefixCls, | ||
6 | + `${prefixCls}--${size}`, | ||
7 | + { | ||
8 | + [`${prefixCls}--dark`]: isDark, | ||
9 | + }, | ||
10 | + ]" | ||
11 | + @click="toggleDarkMode" | ||
12 | + > | ||
13 | + <div :class="`${prefixCls}-inner`"> </div> | ||
14 | + <SvgIcon size="14" name="sun" /> | ||
15 | + <SvgIcon size="14" name="moon" /> | ||
16 | + </div> | ||
17 | +</template> | ||
18 | +<script lang="ts"> | ||
19 | + import { defineComponent, computed } from 'vue'; | ||
20 | + | ||
21 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
22 | + | ||
23 | + import { SvgIcon } from '/@/components/Icon'; | ||
24 | + import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | ||
25 | + import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground'; | ||
26 | + import { updateDarkTheme } from '/@/logics/theme/dark'; | ||
27 | + | ||
28 | + import { ThemeEnum } from '/@/enums/appEnum'; | ||
29 | + | ||
30 | + export default defineComponent({ | ||
31 | + name: 'DarkModeToggle', | ||
32 | + components: { SvgIcon }, | ||
33 | + props: { | ||
34 | + size: { | ||
35 | + type: String, | ||
36 | + default: 'default', | ||
37 | + validate: (val) => ['default', 'large'].includes(val), | ||
38 | + }, | ||
39 | + }, | ||
40 | + setup() { | ||
41 | + const { prefixCls } = useDesign('dark-mode-toggle'); | ||
42 | + const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting(); | ||
43 | + const isDark = computed(() => getDarkMode.value === ThemeEnum.DARK); | ||
44 | + function toggleDarkMode() { | ||
45 | + const darkMode = getDarkMode.value === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK; | ||
46 | + setDarkMode(darkMode); | ||
47 | + updateDarkTheme(darkMode); | ||
48 | + updateHeaderBgColor(); | ||
49 | + updateSidebarBgColor(); | ||
50 | + } | ||
51 | + | ||
52 | + return { | ||
53 | + isDark, | ||
54 | + prefixCls, | ||
55 | + toggleDarkMode, | ||
56 | + getShowDarkModeToggle, | ||
57 | + }; | ||
58 | + }, | ||
59 | + }); | ||
60 | +</script> | ||
61 | +<style lang="less" scoped> | ||
62 | + @prefix-cls: ~'@{namespace}-dark-mode-toggle'; | ||
63 | + | ||
64 | + html[data-theme='dark'] { | ||
65 | + .@{prefix-cls} { | ||
66 | + border: 1px solid rgb(196, 188, 188); | ||
67 | + } | ||
68 | + } | ||
69 | + | ||
70 | + .@{prefix-cls} { | ||
71 | + position: relative; | ||
72 | + display: flex; | ||
73 | + width: 50px; | ||
74 | + height: 26px; | ||
75 | + padding: 0 6px; | ||
76 | + margin-left: auto; | ||
77 | + cursor: pointer; | ||
78 | + background-color: #151515; | ||
79 | + border-radius: 30px; | ||
80 | + justify-content: space-between; | ||
81 | + align-items: center; | ||
82 | + | ||
83 | + &-inner { | ||
84 | + position: absolute; | ||
85 | + z-index: 1; | ||
86 | + width: 18px; | ||
87 | + height: 18px; | ||
88 | + background-color: #fff; | ||
89 | + border-radius: 50%; | ||
90 | + transition: transform 0.5s, background-color 0.5s; | ||
91 | + will-change: transform; | ||
92 | + } | ||
93 | + | ||
94 | + &--dark { | ||
95 | + .@{prefix-cls}-inner { | ||
96 | + transform: translateX(calc(100% + 2px)); | ||
97 | + } | ||
98 | + } | ||
99 | + | ||
100 | + &--large { | ||
101 | + width: 72px; | ||
102 | + height: 34px; | ||
103 | + padding: 0 10px; | ||
104 | + | ||
105 | + .@{prefix-cls}-inner { | ||
106 | + width: 26px; | ||
107 | + height: 26px; | ||
108 | + } | ||
109 | + } | ||
110 | + } | ||
111 | +</style> |
src/components/Application/src/search/AppSearchFooter.vue
@@ -42,9 +42,9 @@ | @@ -42,9 +42,9 @@ | ||
42 | padding: 0 16px; | 42 | padding: 0 16px; |
43 | font-size: 12px; | 43 | font-size: 12px; |
44 | color: #666; | 44 | color: #666; |
45 | - background: rgb(255 255 255); | 45 | + background: @component-background; |
46 | + border-top: 1px solid @border-color-base; | ||
46 | border-radius: 0 0 16px 16px; | 47 | border-radius: 0 0 16px 16px; |
47 | - box-shadow: 0 -1px 0 0 #e0e3e8, 0 -3px 6px 0 rgba(69, 98, 155, 0.12); | ||
48 | align-items: center; | 48 | align-items: center; |
49 | flex-shrink: 0; | 49 | flex-shrink: 0; |
50 | 50 |
src/components/Application/src/search/AppSearchModal.vue
@@ -190,12 +190,10 @@ | @@ -190,12 +190,10 @@ | ||
190 | &-content { | 190 | &-content { |
191 | position: relative; | 191 | position: relative; |
192 | width: 632px; | 192 | width: 632px; |
193 | - // padding: 14px; | ||
194 | margin: 0 auto auto auto; | 193 | margin: 0 auto auto auto; |
195 | - background: #f5f6f7; | 194 | + background: @component-background; |
196 | border-radius: 16px; | 195 | border-radius: 16px; |
197 | box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); | 196 | box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); |
198 | - // box-shadow: inset 1px 1px 0 0 hsla(0, 0%, 100%, 0.5), 0 3px 8px 0 #555a64; | ||
199 | flex-direction: column; | 197 | flex-direction: column; |
200 | } | 198 | } |
201 | 199 | ||
@@ -253,8 +251,7 @@ | @@ -253,8 +251,7 @@ | ||
253 | font-size: 14px; | 251 | font-size: 14px; |
254 | color: @text-color-base; | 252 | color: @text-color-base; |
255 | cursor: pointer; | 253 | cursor: pointer; |
256 | - // background: @primary-color; | ||
257 | - background: #fff; | 254 | + background: @component-background; |
258 | border-radius: 4px; | 255 | border-radius: 4px; |
259 | box-shadow: 0 1px 3px 0 #d4d9e1; | 256 | box-shadow: 0 1px 3px 0 #d4d9e1; |
260 | align-items: center; | 257 | align-items: center; |
src/components/Container/src/collapse/CollapseContainer.vue
@@ -101,7 +101,7 @@ | @@ -101,7 +101,7 @@ | ||
101 | @prefix-cls: ~'@{namespace}-collapse-container'; | 101 | @prefix-cls: ~'@{namespace}-collapse-container'; |
102 | 102 | ||
103 | .@{prefix-cls} { | 103 | .@{prefix-cls} { |
104 | - background: #fff; | 104 | + background: @component-background; |
105 | border-radius: 2px; | 105 | border-radius: 2px; |
106 | transition: all 0.3s ease-in-out; | 106 | transition: all 0.3s ease-in-out; |
107 | 107 |
src/components/ContextMenu/src/index.less
@@ -22,7 +22,7 @@ | @@ -22,7 +22,7 @@ | ||
22 | 22 | ||
23 | &:not(.ant-menu-item-disabled):hover { | 23 | &:not(.ant-menu-item-disabled):hover { |
24 | color: @text-color-base; | 24 | color: @text-color-base; |
25 | - background: #eee; | 25 | + background: @item-hover-bg; |
26 | } | 26 | } |
27 | } | 27 | } |
28 | } | 28 | } |
@@ -36,7 +36,7 @@ | @@ -36,7 +36,7 @@ | ||
36 | width: 156px; | 36 | width: 156px; |
37 | margin: 0; | 37 | margin: 0; |
38 | list-style: none; | 38 | list-style: none; |
39 | - background-color: #fff; | 39 | + background-color: @component-background; |
40 | border: 1px solid rgba(0, 0, 0, 0.08); | 40 | border: 1px solid rgba(0, 0, 0, 0.08); |
41 | border-radius: 0.25rem; | 41 | border-radius: 0.25rem; |
42 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.1), | 42 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.1), |
src/components/Drawer/src/BasicDrawer.vue
@@ -221,7 +221,7 @@ | @@ -221,7 +221,7 @@ | ||
221 | .ant-drawer-body { | 221 | .ant-drawer-body { |
222 | height: calc(100% - @header-height); | 222 | height: calc(100% - @header-height); |
223 | padding: 0; | 223 | padding: 0; |
224 | - background-color: #fff; | 224 | + background-color: @component-background; |
225 | 225 | ||
226 | .scrollbar__wrap { | 226 | .scrollbar__wrap { |
227 | padding: 16px !important; | 227 | padding: 16px !important; |
src/components/Drawer/src/components/DrawerFooter.vue
@@ -74,7 +74,7 @@ | @@ -74,7 +74,7 @@ | ||
74 | width: 100%; | 74 | width: 100%; |
75 | padding: 0 12px 0 20px; | 75 | padding: 0 12px 0 20px; |
76 | text-align: right; | 76 | text-align: right; |
77 | - background: #fff; | 77 | + background: @component-background; |
78 | border-top: 1px solid @border-color-base; | 78 | border-top: 1px solid @border-color-base; |
79 | 79 | ||
80 | > * { | 80 | > * { |
src/components/Form/src/components/FormItem.vue
@@ -258,7 +258,7 @@ | @@ -258,7 +258,7 @@ | ||
258 | const { label, helpMessage, helpComponentProps, subLabel } = props.schema; | 258 | const { label, helpMessage, helpComponentProps, subLabel } = props.schema; |
259 | const renderLabel = subLabel ? ( | 259 | const renderLabel = subLabel ? ( |
260 | <span> | 260 | <span> |
261 | - {label} <span style="color:#00000073">{subLabel}</span> | 261 | + {label} <span class="text-secondary">{subLabel}</span> |
262 | </span> | 262 | </span> |
263 | ) : ( | 263 | ) : ( |
264 | label | 264 | label |
src/components/Loading/src/index.vue
1 | <template> | 1 | <template> |
2 | - <section class="full-loading" :class="{ absolute }" v-show="loading" :style="getStyle"> | 2 | + <section class="full-loading" :class="{ absolute }" v-show="loading"> |
3 | <Spin v-bind="$attrs" :tip="tip" :size="size" :spinning="loading" /> | 3 | <Spin v-bind="$attrs" :tip="tip" :size="size" :spinning="loading" /> |
4 | </section> | 4 | </section> |
5 | </template> | 5 | </template> |
6 | <script lang="ts"> | 6 | <script lang="ts"> |
7 | - import { computed, CSSProperties, PropType } from 'vue'; | 7 | + import { PropType } from 'vue'; |
8 | 8 | ||
9 | import { defineComponent } from 'vue'; | 9 | import { defineComponent } from 'vue'; |
10 | import { Spin } from 'ant-design-vue'; | 10 | import { Spin } from 'ant-design-vue'; |
11 | 11 | ||
12 | import { SizeEnum } from '/@/enums/sizeEnum'; | 12 | import { SizeEnum } from '/@/enums/sizeEnum'; |
13 | - import { ThemeEnum } from '/@/enums/appEnum'; | ||
14 | 13 | ||
15 | export default defineComponent({ | 14 | export default defineComponent({ |
16 | name: 'Loading', | 15 | name: 'Loading', |
@@ -38,25 +37,6 @@ | @@ -38,25 +37,6 @@ | ||
38 | background: { | 37 | background: { |
39 | type: String as PropType<string>, | 38 | type: String as PropType<string>, |
40 | }, | 39 | }, |
41 | - theme: { | ||
42 | - type: String as PropType<'dark' | 'light'>, | ||
43 | - default: 'light', | ||
44 | - }, | ||
45 | - }, | ||
46 | - setup(props) { | ||
47 | - const getStyle = computed( | ||
48 | - (): CSSProperties => { | ||
49 | - const { background, theme } = props; | ||
50 | - const bgColor = background | ||
51 | - ? background | ||
52 | - : theme === ThemeEnum.DARK | ||
53 | - ? 'rgba(0, 0, 0, 0.2)' | ||
54 | - : 'rgba(240, 242, 245, 0.4)'; | ||
55 | - return { background: bgColor }; | ||
56 | - } | ||
57 | - ); | ||
58 | - | ||
59 | - return { getStyle }; | ||
60 | }, | 40 | }, |
61 | }); | 41 | }); |
62 | </script> | 42 | </script> |
@@ -71,6 +51,7 @@ | @@ -71,6 +51,7 @@ | ||
71 | height: 100%; | 51 | height: 100%; |
72 | justify-content: center; | 52 | justify-content: center; |
73 | align-items: center; | 53 | align-items: center; |
54 | + background: rgba(240, 242, 245, 0.4); | ||
74 | 55 | ||
75 | &.absolute { | 56 | &.absolute { |
76 | position: absolute; | 57 | position: absolute; |
@@ -79,4 +60,10 @@ | @@ -79,4 +60,10 @@ | ||
79 | z-index: 300; | 60 | z-index: 300; |
80 | } | 61 | } |
81 | } | 62 | } |
63 | + | ||
64 | + html[data-theme='dark'] { | ||
65 | + .full-loading { | ||
66 | + background: @modal-mask-bg; | ||
67 | + } | ||
68 | + } | ||
82 | </style> | 69 | </style> |
src/components/Markdown/src/index.vue
@@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
10 | onUnmounted, | 10 | onUnmounted, |
11 | nextTick, | 11 | nextTick, |
12 | computed, | 12 | computed, |
13 | - watchEffect, | 13 | + watch, |
14 | } from 'vue'; | 14 | } from 'vue'; |
15 | import Vditor from 'vditor'; | 15 | import Vditor from 'vditor'; |
16 | import 'vditor/dist/index.css'; | 16 | import 'vditor/dist/index.css'; |
@@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
18 | import { propTypes } from '/@/utils/propTypes'; | 18 | import { propTypes } from '/@/utils/propTypes'; |
19 | import { useLocale } from '/@/locales/useLocale'; | 19 | import { useLocale } from '/@/locales/useLocale'; |
20 | import { useModalContext } from '../../Modal'; | 20 | import { useModalContext } from '../../Modal'; |
21 | + import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | ||
21 | 22 | ||
22 | type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined; | 23 | type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined; |
23 | export default defineComponent({ | 24 | export default defineComponent({ |
@@ -35,8 +36,24 @@ | @@ -35,8 +36,24 @@ | ||
35 | const modalFn = useModalContext(); | 36 | const modalFn = useModalContext(); |
36 | 37 | ||
37 | const { getLocale } = useLocale(); | 38 | const { getLocale } = useLocale(); |
39 | + const { getDarkMode } = useRootSetting(); | ||
38 | 40 | ||
39 | - watchEffect(() => {}); | 41 | + watch( |
42 | + [() => getDarkMode.value, () => initedRef.value], | ||
43 | + ([val]) => { | ||
44 | + const vditor = unref(vditorRef); | ||
45 | + | ||
46 | + if (!vditor) { | ||
47 | + return; | ||
48 | + } | ||
49 | + const theme = val === 'dark' ? 'dark' : undefined; | ||
50 | + vditor.setTheme(theme as 'dark'); | ||
51 | + }, | ||
52 | + { | ||
53 | + immediate: true, | ||
54 | + flush: 'post', | ||
55 | + } | ||
56 | + ); | ||
40 | 57 | ||
41 | const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => { | 58 | const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => { |
42 | let lang: Lang; | 59 | let lang: Lang; |
@@ -60,6 +77,7 @@ | @@ -60,6 +77,7 @@ | ||
60 | if (!wrapEl) return; | 77 | if (!wrapEl) return; |
61 | const bindValue = { ...attrs, ...props }; | 78 | const bindValue = { ...attrs, ...props }; |
62 | vditorRef.value = new Vditor(wrapEl, { | 79 | vditorRef.value = new Vditor(wrapEl, { |
80 | + theme: 'classic', | ||
63 | lang: unref(getCurrentLang), | 81 | lang: unref(getCurrentLang), |
64 | mode: 'sv', | 82 | mode: 'sv', |
65 | preview: { | 83 | preview: { |
src/components/Page/src/PageFooter.vue
@@ -38,8 +38,8 @@ | @@ -38,8 +38,8 @@ | ||
38 | align-items: center; | 38 | align-items: center; |
39 | padding: 0 24px; | 39 | padding: 0 24px; |
40 | line-height: 44px; | 40 | line-height: 44px; |
41 | - background: #fff; | ||
42 | - border-top: 1px solid #f0f0f0; | 41 | + background: @component-background; |
42 | + border-top: 1px solid @border-color-base; | ||
43 | box-shadow: 0 -6px 16px -8px rgba(0, 0, 0, 0.08), 0 -9px 28px 0 rgba(0, 0, 0, 0.05), | 43 | box-shadow: 0 -6px 16px -8px rgba(0, 0, 0, 0.08), 0 -9px 28px 0 rgba(0, 0, 0, 0.05), |
44 | 0 -12px 48px 16px rgba(0, 0, 0, 0.03); | 44 | 0 -12px 48px 16px rgba(0, 0, 0, 0.03); |
45 | transition: width 0.2s; | 45 | transition: width 0.2s; |
src/components/Page/src/PageWrapper.vue
@@ -17,11 +17,7 @@ | @@ -17,11 +17,7 @@ | ||
17 | <slot :name="item" v-bind="data"></slot> | 17 | <slot :name="item" v-bind="data"></slot> |
18 | </template> | 18 | </template> |
19 | </PageHeader> | 19 | </PageHeader> |
20 | - <div | ||
21 | - class="overflow-hidden" | ||
22 | - :class="[`${prefixCls}-content`, contentClass]" | ||
23 | - :style="getContentStyle" | ||
24 | - > | 20 | + <div class="overflow-hidden" :class="getContentClass" :style="getContentStyle"> |
25 | <slot></slot> | 21 | <slot></slot> |
26 | </div> | 22 | </div> |
27 | <PageFooter v-if="getShowFooter" ref="footerRef"> | 23 | <PageFooter v-if="getShowFooter" ref="footerRef"> |
@@ -87,14 +83,12 @@ | @@ -87,14 +83,12 @@ | ||
87 | 83 | ||
88 | const getContentStyle = computed( | 84 | const getContentStyle = computed( |
89 | (): CSSProperties => { | 85 | (): CSSProperties => { |
90 | - const { contentBackground, contentFullHeight, contentStyle, fixedHeight } = props; | ||
91 | - const bg = contentBackground ? { backgroundColor: '#fff' } : {}; | 86 | + const { contentFullHeight, contentStyle, fixedHeight } = props; |
92 | if (!contentFullHeight) { | 87 | if (!contentFullHeight) { |
93 | - return { ...bg, ...contentStyle }; | 88 | + return { ...contentStyle }; |
94 | } | 89 | } |
95 | const height = `${unref(pageHeight)}px`; | 90 | const height = `${unref(pageHeight)}px`; |
96 | return { | 91 | return { |
97 | - ...bg, | ||
98 | ...contentStyle, | 92 | ...contentStyle, |
99 | minHeight: height, | 93 | minHeight: height, |
100 | ...(fixedHeight ? { height } : {}), | 94 | ...(fixedHeight ? { height } : {}), |
@@ -103,6 +97,17 @@ | @@ -103,6 +97,17 @@ | ||
103 | } | 97 | } |
104 | ); | 98 | ); |
105 | 99 | ||
100 | + const getContentClass = computed(() => { | ||
101 | + const { contentBackground, contentClass } = props; | ||
102 | + return [ | ||
103 | + `${prefixCls}-content`, | ||
104 | + contentClass, | ||
105 | + { | ||
106 | + [`${prefixCls}-content-bg`]: contentBackground, | ||
107 | + }, | ||
108 | + ]; | ||
109 | + }); | ||
110 | + | ||
106 | watch( | 111 | watch( |
107 | () => [contentHeight?.value, getShowFooter.value], | 112 | () => [contentHeight?.value, getShowFooter.value], |
108 | () => { | 113 | () => { |
@@ -170,6 +175,7 @@ | @@ -170,6 +175,7 @@ | ||
170 | getShowFooter, | 175 | getShowFooter, |
171 | pageHeight, | 176 | pageHeight, |
172 | omit, | 177 | omit, |
178 | + getContentClass, | ||
173 | }; | 179 | }; |
174 | }, | 180 | }, |
175 | }); | 181 | }); |
@@ -190,6 +196,10 @@ | @@ -190,6 +196,10 @@ | ||
190 | } | 196 | } |
191 | } | 197 | } |
192 | 198 | ||
199 | + &-content-bg { | ||
200 | + background: @component-background; | ||
201 | + } | ||
202 | + | ||
193 | &--dense { | 203 | &--dense { |
194 | .@{prefix-cls}-content { | 204 | .@{prefix-cls}-content { |
195 | margin: 0; | 205 | margin: 0; |
src/components/SimpleMenu/src/index.less
@@ -11,9 +11,9 @@ | @@ -11,9 +11,9 @@ | ||
11 | 11 | ||
12 | &-dark&-vertical .@{simple-prefix-cls}__children, | 12 | &-dark&-vertical .@{simple-prefix-cls}__children, |
13 | &-dark&-popup .@{simple-prefix-cls}__children { | 13 | &-dark&-popup .@{simple-prefix-cls}__children { |
14 | - background-color: @sider-dark-lighten-1-bg-color; | 14 | + background-color: @sider-dark-lighten-bg-color; |
15 | > .@{prefix-cls}-submenu-title { | 15 | > .@{prefix-cls}-submenu-title { |
16 | - background-color: @sider-dark-lighten-1-bg-color; | 16 | + background-color: @sider-dark-lighten-bg-color; |
17 | } | 17 | } |
18 | } | 18 | } |
19 | 19 |
src/components/Table/src/BasicTable.vue
@@ -298,6 +298,26 @@ | @@ -298,6 +298,26 @@ | ||
298 | 298 | ||
299 | @prefix-cls: ~'@{namespace}-basic-table'; | 299 | @prefix-cls: ~'@{namespace}-basic-table'; |
300 | 300 | ||
301 | + html[data-theme='light'] { | ||
302 | + .@{prefix-cls} { | ||
303 | + &-row__striped { | ||
304 | + td { | ||
305 | + background: #fafafa; | ||
306 | + } | ||
307 | + } | ||
308 | + } | ||
309 | + } | ||
310 | + | ||
311 | + html[data-theme='dark'] { | ||
312 | + .@{prefix-cls} { | ||
313 | + &-row__striped { | ||
314 | + td { | ||
315 | + background: rgb(255 255 255 / 4%); | ||
316 | + } | ||
317 | + } | ||
318 | + } | ||
319 | + } | ||
320 | + | ||
301 | .@{prefix-cls} { | 321 | .@{prefix-cls} { |
302 | &-form-container { | 322 | &-form-container { |
303 | padding: 16px; | 323 | padding: 16px; |
@@ -305,17 +325,11 @@ | @@ -305,17 +325,11 @@ | ||
305 | .ant-form { | 325 | .ant-form { |
306 | padding: 12px 10px 6px 10px; | 326 | padding: 12px 10px 6px 10px; |
307 | margin-bottom: 16px; | 327 | margin-bottom: 16px; |
308 | - background: #fff; | 328 | + background: @component-background; |
309 | border-radius: 4px; | 329 | border-radius: 4px; |
310 | } | 330 | } |
311 | } | 331 | } |
312 | 332 | ||
313 | - &-row__striped { | ||
314 | - td { | ||
315 | - background: #fafafa; | ||
316 | - } | ||
317 | - } | ||
318 | - | ||
319 | &--inset { | 333 | &--inset { |
320 | .ant-table-wrapper { | 334 | .ant-table-wrapper { |
321 | padding: 0; | 335 | padding: 0; |
@@ -328,7 +342,7 @@ | @@ -328,7 +342,7 @@ | ||
328 | 342 | ||
329 | .ant-table-wrapper { | 343 | .ant-table-wrapper { |
330 | padding: 6px; | 344 | padding: 6px; |
331 | - background: #fff; | 345 | + background: @component-background; |
332 | border-radius: 2px; | 346 | border-radius: 2px; |
333 | 347 | ||
334 | .ant-table-title { | 348 | .ant-table-title { |
@@ -340,7 +354,6 @@ | @@ -340,7 +354,6 @@ | ||
340 | } | 354 | } |
341 | } | 355 | } |
342 | 356 | ||
343 | - // | ||
344 | .ant-table { | 357 | .ant-table { |
345 | width: 100%; | 358 | width: 100%; |
346 | overflow-x: hidden; | 359 | overflow-x: hidden; |
src/components/Tree/src/index.vue
@@ -324,7 +324,7 @@ | @@ -324,7 +324,7 @@ | ||
324 | const showTitle = title || toolbar || search || slots.headerTitle; | 324 | const showTitle = title || toolbar || search || slots.headerTitle; |
325 | const scrollStyle: CSSProperties = { height: 'calc(100% - 38px)' }; | 325 | const scrollStyle: CSSProperties = { height: 'calc(100% - 38px)' }; |
326 | return ( | 326 | return ( |
327 | - <div class={[prefixCls, 'h-full bg-white', attrs.class]}> | 327 | + <div class={[prefixCls, 'h-full', attrs.class]}> |
328 | {showTitle && ( | 328 | {showTitle && ( |
329 | <TreeHeader | 329 | <TreeHeader |
330 | checkable={checkable} | 330 | checkable={checkable} |
@@ -361,6 +361,8 @@ | @@ -361,6 +361,8 @@ | ||
361 | @prefix-cls: ~'@{namespace}-basic-tree'; | 361 | @prefix-cls: ~'@{namespace}-basic-tree'; |
362 | 362 | ||
363 | .@{prefix-cls} { | 363 | .@{prefix-cls} { |
364 | + background: @component-background; | ||
365 | + | ||
364 | .ant-tree-node-content-wrapper { | 366 | .ant-tree-node-content-wrapper { |
365 | position: relative; | 367 | position: relative; |
366 | 368 |
src/components/Upload/src/FileList.less
1 | .file-table { | 1 | .file-table { |
2 | width: 100%; | 2 | width: 100%; |
3 | border-collapse: collapse; | 3 | border-collapse: collapse; |
4 | - // border: 1px solid @border-color-light; | ||
5 | 4 | ||
6 | .center { | 5 | .center { |
7 | text-align: center; | 6 | text-align: center; |
@@ -21,12 +20,12 @@ | @@ -21,12 +20,12 @@ | ||
21 | } | 20 | } |
22 | 21 | ||
23 | thead { | 22 | thead { |
24 | - background-color: @background-color-dark; | 23 | + background-color: @background-color-light; |
25 | } | 24 | } |
26 | 25 | ||
27 | table, | 26 | table, |
28 | td, | 27 | td, |
29 | th { | 28 | th { |
30 | - border: 1px solid @border-color-light; | 29 | + border: 1px solid @border-color-base; |
31 | } | 30 | } |
32 | } | 31 | } |
src/design/ant/btn.less
@@ -61,9 +61,9 @@ | @@ -61,9 +61,9 @@ | ||
61 | &.ant-btn-link.is-disabled { | 61 | &.ant-btn-link.is-disabled { |
62 | color: rgba(0, 0, 0, 0.25) !important; | 62 | color: rgba(0, 0, 0, 0.25) !important; |
63 | text-shadow: none; | 63 | text-shadow: none; |
64 | - cursor: not-allowed; | ||
65 | - background-color: transparent; | ||
66 | - border-color: transparent; | 64 | + cursor: not-allowed !important; |
65 | + background-color: transparent !important; | ||
66 | + border-color: transparent !important; | ||
67 | box-shadow: none; | 67 | box-shadow: none; |
68 | } | 68 | } |
69 | 69 | ||
@@ -187,7 +187,7 @@ | @@ -187,7 +187,7 @@ | ||
187 | 187 | ||
188 | &-ghost { | 188 | &-ghost { |
189 | color: @button-ghost-color; | 189 | color: @button-ghost-color; |
190 | - background-color: @white; | 190 | + background-color: transparent; |
191 | border-color: @button-ghost-color; | 191 | border-color: @button-ghost-color; |
192 | border-width: 1px; | 192 | border-width: 1px; |
193 | 193 | ||
@@ -205,4 +205,14 @@ | @@ -205,4 +205,14 @@ | ||
205 | border-color: fade(@button-ghost-color, 40%); | 205 | border-color: fade(@button-ghost-color, 40%); |
206 | } | 206 | } |
207 | } | 207 | } |
208 | + | ||
209 | + &-ghost.ant-btn-link:not([disabled='disabled']) { | ||
210 | + color: @button-ghost-color; | ||
211 | + | ||
212 | + &:hover, | ||
213 | + &:focus { | ||
214 | + color: @button-ghost-hover-color; | ||
215 | + border-color: transparent; | ||
216 | + } | ||
217 | + } | ||
208 | } | 218 | } |
src/design/ant/pagination.less
1 | +html[data-theme='dark'] { | ||
2 | + .ant-pagination { | ||
3 | + &.mini { | ||
4 | + .ant-pagination-prev, | ||
5 | + .ant-pagination-next, | ||
6 | + .ant-pagination-item { | ||
7 | + background: rgb(255 255 255 / 4%) !important; | ||
8 | + | ||
9 | + a { | ||
10 | + color: #8b949e !important; | ||
11 | + } | ||
12 | + } | ||
13 | + | ||
14 | + .ant-select-arrow { | ||
15 | + color: @text-color-secondary !important; | ||
16 | + } | ||
17 | + | ||
18 | + .ant-pagination-item-active { | ||
19 | + background: @primary-color !important; | ||
20 | + border: none; | ||
21 | + border-radius: none !important; | ||
22 | + | ||
23 | + a { | ||
24 | + color: @white !important; | ||
25 | + } | ||
26 | + } | ||
27 | + } | ||
28 | + } | ||
29 | +} | ||
30 | + | ||
1 | .ant-pagination { | 31 | .ant-pagination { |
2 | &.mini { | 32 | &.mini { |
3 | .ant-pagination-prev, | 33 | .ant-pagination-prev, |
src/design/color.less
1 | -:root { | 1 | +html { |
2 | // header | 2 | // header |
3 | --header-bg-color: #394664; | 3 | --header-bg-color: #394664; |
4 | --header-bg-hover-color: #273352; | 4 | --header-bg-hover-color: #273352; |
@@ -7,16 +7,13 @@ | @@ -7,16 +7,13 @@ | ||
7 | // sider | 7 | // sider |
8 | --sider-dark-bg-color: #273352; | 8 | --sider-dark-bg-color: #273352; |
9 | --sider-dark-darken-bg-color: #273352; | 9 | --sider-dark-darken-bg-color: #273352; |
10 | - --sider-dark-lighten-1-bg-color: #273352; | ||
11 | - --sider-dark-lighten-2-bg-color: #273352; | 10 | + --sider-dark-lighten-bg-color: #273352; |
12 | } | 11 | } |
13 | 12 | ||
14 | @white: #fff; | 13 | @white: #fff; |
15 | 14 | ||
16 | @content-bg: #f4f7f9; | 15 | @content-bg: #f4f7f9; |
17 | -// @content-bg: #f0f2f5; | ||
18 | 16 | ||
19 | -@basic-mask-color: fade(@white, 30%); | ||
20 | // :export { | 17 | // :export { |
21 | // name: "less"; | 18 | // name: "less"; |
22 | // mainColor: @mainColor; | 19 | // mainColor: @mainColor; |
@@ -35,10 +32,7 @@ | @@ -35,10 +32,7 @@ | ||
35 | @border-color-shallow-dark: #cececd; | 32 | @border-color-shallow-dark: #cececd; |
36 | 33 | ||
37 | // Light-dark | 34 | // Light-dark |
38 | -@border-color-light: #ebeef5; | ||
39 | - | ||
40 | -// Light-light | ||
41 | -@border-color-shallow-light: #f2f6fc; | 35 | +@border-color-light: @border-color-base; |
42 | 36 | ||
43 | // ================================= | 37 | // ================================= |
44 | // ==============message============== | 38 | // ==============message============== |
@@ -54,17 +48,6 @@ | @@ -54,17 +48,6 @@ | ||
54 | @danger-background-color: #fef0f0; | 48 | @danger-background-color: #fef0f0; |
55 | 49 | ||
56 | // ================================= | 50 | // ================================= |
57 | -// ==============bg color============ | ||
58 | -// ================================= | ||
59 | - | ||
60 | -// dark | ||
61 | -@background-color-dark: #f4f7f9; | ||
62 | -// light | ||
63 | -@background-color-light: #f5f7fa; | ||
64 | -// layout content background | ||
65 | -@layout-content-bg-color: #f1f1f6; | ||
66 | - | ||
67 | -// ================================= | ||
68 | // ==============Header============= | 51 | // ==============Header============= |
69 | // ================================= | 52 | // ================================= |
70 | 53 | ||
@@ -83,14 +66,11 @@ | @@ -83,14 +66,11 @@ | ||
83 | // let -menu | 66 | // let -menu |
84 | @sider-dark-bg-color: var(--sider-dark-bg-color); | 67 | @sider-dark-bg-color: var(--sider-dark-bg-color); |
85 | @sider-dark-darken-bg-color: var(--sider-dark-darken-bg-color); | 68 | @sider-dark-darken-bg-color: var(--sider-dark-darken-bg-color); |
86 | -@sider-dark-lighten-1-bg-color: var(--sider-dark-lighten-1-bg-color); | ||
87 | -@sider-dark-lighten-2-bg-color: var(--sider-dark-lighten-2-bg-color); | 69 | +@sider-dark-lighten-bg-color: var(--sider-dark-lighten-bg-color); |
88 | 70 | ||
89 | // trigger | 71 | // trigger |
90 | @trigger-dark-hover-bg-color: rgba(255, 255, 255, 0.2); | 72 | @trigger-dark-hover-bg-color: rgba(255, 255, 255, 0.2); |
91 | @trigger-dark-bg-color: rgba(255, 255, 255, 0.1); | 73 | @trigger-dark-bg-color: rgba(255, 255, 255, 0.1); |
92 | -@trigger-light-bg-color: @white; | ||
93 | -@trigger-light-hover-bg-color: rgba(255, 255, 255, 0.7); | ||
94 | 74 | ||
95 | // ================================= | 75 | // ================================= |
96 | // ==============tree============ | 76 | // ==============tree============ |
@@ -119,9 +99,6 @@ | @@ -119,9 +99,6 @@ | ||
119 | // Auxiliary information color-dark | 99 | // Auxiliary information color-dark |
120 | @text-color-help-dark: #909399; | 100 | @text-color-help-dark: #909399; |
121 | 101 | ||
122 | -// Auxiliary information color-light color | ||
123 | -@text-color-help-light: #c0c4cc; | ||
124 | - | ||
125 | // ================================= | 102 | // ================================= |
126 | // ==============breadcrumb========= | 103 | // ==============breadcrumb========= |
127 | // ================================= | 104 | // ================================= |
src/design/index.less
@@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
2 | @import 'var/index.less'; | 2 | @import 'var/index.less'; |
3 | @import 'public.less'; | 3 | @import 'public.less'; |
4 | @import 'ant/index.less'; | 4 | @import 'ant/index.less'; |
5 | +@import './theme.less'; | ||
5 | 6 | ||
6 | input:-webkit-autofill { | 7 | input:-webkit-autofill { |
7 | -webkit-box-shadow: 0 0 0 1000px white inset !important; | 8 | -webkit-box-shadow: 0 0 0 1000px white inset !important; |
src/design/theme.less
0 → 100644
1 | +.bg-white { | ||
2 | + background: @component-background !important; | ||
3 | +} | ||
4 | + | ||
5 | +html[data-theme='light'] { | ||
6 | + .text-secondary { | ||
7 | + color: rgba(0, 0, 0, 0.45); | ||
8 | + } | ||
9 | +} | ||
10 | + | ||
11 | +html[data-theme='dark'] { | ||
12 | + .text-secondary { | ||
13 | + color: #8b949e; | ||
14 | + } | ||
15 | + | ||
16 | + .ant-card-grid-hoverable:hover { | ||
17 | + box-shadow: 0 3px 6px -4px rgb(0 0 0 / 48%), 0 6px 16px 0 rgb(0 0 0 / 32%), | ||
18 | + 0 9px 28px 8px rgb(0 0 0 / 20%); | ||
19 | + } | ||
20 | + | ||
21 | + .ant-alert-message, | ||
22 | + .ant-alert-with-description .ant-alert-message, | ||
23 | + .ant-alert-description { | ||
24 | + color: rgba(0, 0, 0, 0.85); | ||
25 | + } | ||
26 | + | ||
27 | + .ant-checkbox-checked .ant-checkbox-inner::after { | ||
28 | + border-top: 0; | ||
29 | + border-left: 0; | ||
30 | + } | ||
31 | +} |
src/directives/loading.ts
@@ -5,14 +5,12 @@ const loadingDirective: Directive = { | @@ -5,14 +5,12 @@ const loadingDirective: Directive = { | ||
5 | mounted(el, binding) { | 5 | mounted(el, binding) { |
6 | const tip = el.getAttribute('loading-tip'); | 6 | const tip = el.getAttribute('loading-tip'); |
7 | const background = el.getAttribute('loading-background'); | 7 | const background = el.getAttribute('loading-background'); |
8 | - const theme = el.getAttribute('loading-theme'); | ||
9 | const size = el.getAttribute('loading-size'); | 8 | const size = el.getAttribute('loading-size'); |
10 | const fullscreen = !!binding.modifiers.fullscreen; | 9 | const fullscreen = !!binding.modifiers.fullscreen; |
11 | const instance = createLoading( | 10 | const instance = createLoading( |
12 | { | 11 | { |
13 | tip, | 12 | tip, |
14 | background, | 13 | background, |
15 | - theme, | ||
16 | size: size || 'large', | 14 | size: size || 'large', |
17 | loading: !!binding.value, | 15 | loading: !!binding.value, |
18 | absolute: !fullscreen, | 16 | absolute: !fullscreen, |
src/enums/appEnum.ts
@@ -8,17 +8,9 @@ export enum ContentEnum { | @@ -8,17 +8,9 @@ export enum ContentEnum { | ||
8 | FIXED = 'fixed', | 8 | FIXED = 'fixed', |
9 | } | 9 | } |
10 | 10 | ||
11 | -// app current theme | ||
12 | -export enum ThemeModeEnum { | ||
13 | - LIGHT = 'light-mode', | ||
14 | - DARK = 'dark-mode', | ||
15 | - SEMI_DARK = 'semi-dark-mode', | ||
16 | -} | ||
17 | - | ||
18 | // menu theme enum | 11 | // menu theme enum |
19 | export enum ThemeEnum { | 12 | export enum ThemeEnum { |
20 | DARK = 'dark', | 13 | DARK = 'dark', |
21 | - | ||
22 | LIGHT = 'light', | 14 | LIGHT = 'light', |
23 | } | 15 | } |
24 | 16 |
src/enums/cacheEnum.ts
@@ -15,6 +15,8 @@ export const PROJ_CFG_KEY = 'PROJ__CFG__KEY__'; | @@ -15,6 +15,8 @@ export const PROJ_CFG_KEY = 'PROJ__CFG__KEY__'; | ||
15 | // lock info | 15 | // lock info |
16 | export const LOCK_INFO_KEY = 'LOCK__INFO__KEY__'; | 16 | export const LOCK_INFO_KEY = 'LOCK__INFO__KEY__'; |
17 | 17 | ||
18 | +export const APP_DARK_MODE_KEY_ = '__APP__DARK__MODE__'; | ||
19 | + | ||
18 | // base global local key | 20 | // base global local key |
19 | export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY__'; | 21 | export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY__'; |
20 | 22 |
src/hooks/setting/useRootSetting.ts
@@ -4,6 +4,7 @@ import { computed, unref } from 'vue'; | @@ -4,6 +4,7 @@ import { computed, unref } from 'vue'; | ||
4 | 4 | ||
5 | import { appStore } from '/@/store/modules/app'; | 5 | import { appStore } from '/@/store/modules/app'; |
6 | import { ContentEnum } from '/@/enums/appEnum'; | 6 | import { ContentEnum } from '/@/enums/appEnum'; |
7 | +import { ThemeEnum } from '../../enums/appEnum'; | ||
7 | 8 | ||
8 | type RootSetting = Omit< | 9 | type RootSetting = Omit< |
9 | ProjectConfig, | 10 | ProjectConfig, |
@@ -48,6 +49,10 @@ const getGrayMode = computed(() => unref(getRootSetting).grayMode); | @@ -48,6 +49,10 @@ const getGrayMode = computed(() => unref(getRootSetting).grayMode); | ||
48 | 49 | ||
49 | const getLockTime = computed(() => unref(getRootSetting).lockTime); | 50 | const getLockTime = computed(() => unref(getRootSetting).lockTime); |
50 | 51 | ||
52 | +const getShowDarkModeToggle = computed(() => unref(getRootSetting).showDarkModeToggle); | ||
53 | + | ||
54 | +const getDarkMode = computed(() => appStore.getDarkMode); | ||
55 | + | ||
51 | const getLayoutContentMode = computed(() => | 56 | const getLayoutContentMode = computed(() => |
52 | unref(getRootSetting).contentMode === ContentEnum.FULL ? ContentEnum.FULL : ContentEnum.FIXED | 57 | unref(getRootSetting).contentMode === ContentEnum.FULL ? ContentEnum.FULL : ContentEnum.FIXED |
53 | ); | 58 | ); |
@@ -56,6 +61,10 @@ function setRootSetting(setting: Partial<RootSetting>) { | @@ -56,6 +61,10 @@ function setRootSetting(setting: Partial<RootSetting>) { | ||
56 | appStore.commitProjectConfigState(setting); | 61 | appStore.commitProjectConfigState(setting); |
57 | } | 62 | } |
58 | 63 | ||
64 | +function setDarkMode(mode: ThemeEnum) { | ||
65 | + appStore.commitDarkMode(mode); | ||
66 | +} | ||
67 | + | ||
59 | export function useRootSetting() { | 68 | export function useRootSetting() { |
60 | return { | 69 | return { |
61 | setRootSetting, | 70 | setRootSetting, |
@@ -80,5 +89,8 @@ export function useRootSetting() { | @@ -80,5 +89,8 @@ export function useRootSetting() { | ||
80 | getContentMode, | 89 | getContentMode, |
81 | getLockTime, | 90 | getLockTime, |
82 | getThemeColor, | 91 | getThemeColor, |
92 | + getDarkMode, | ||
93 | + setDarkMode, | ||
94 | + getShowDarkModeToggle, | ||
83 | }; | 95 | }; |
84 | } | 96 | } |
src/hooks/web/useApexCharts.ts deleted
100644 → 0
1 | -import { useTimeoutFn } from '/@/hooks/core/useTimeout'; | ||
2 | -import { unref, Ref, nextTick } from 'vue'; | ||
3 | -import { tryOnUnmounted } from '@vueuse/core'; | ||
4 | - | ||
5 | -interface CallBackFn { | ||
6 | - (instance: Nullable<ApexCharts>): void; | ||
7 | -} | ||
8 | - | ||
9 | -export function useApexCharts(elRef: Ref<HTMLDivElement>) { | ||
10 | - let chartInstance: Nullable<ApexCharts> = null; | ||
11 | - | ||
12 | - function setOptions(options: any, callback?: CallBackFn) { | ||
13 | - nextTick(() => { | ||
14 | - useTimeoutFn(async () => { | ||
15 | - const el = unref(elRef); | ||
16 | - | ||
17 | - if (!el || !unref(el)) return; | ||
18 | - const ApexCharts = await (await import('apexcharts')).default; | ||
19 | - chartInstance = new ApexCharts(el, options); | ||
20 | - | ||
21 | - chartInstance && chartInstance.render(); | ||
22 | - | ||
23 | - // The callback method is added to setOptions to return the chartInstance to facilitate the re-operation of the chart, such as calling the updateOptions method to update the chart | ||
24 | - callback && callback(chartInstance); | ||
25 | - }, 30); | ||
26 | - }); | ||
27 | - } | ||
28 | - | ||
29 | - // Call the updateOptions method of ApexCharts to update the chart | ||
30 | - function updateOptions( | ||
31 | - chartInstance: Nullable<ApexCharts>, | ||
32 | - options: any, | ||
33 | - redraw = false, | ||
34 | - animate = true, | ||
35 | - updateSyncedCharts = true, | ||
36 | - callback: CallBackFn | ||
37 | - ) { | ||
38 | - nextTick(() => { | ||
39 | - useTimeoutFn(() => { | ||
40 | - chartInstance && chartInstance.updateOptions(options, redraw, animate, updateSyncedCharts); | ||
41 | - | ||
42 | - callback && callback(chartInstance); | ||
43 | - }, 30); | ||
44 | - }); | ||
45 | - } | ||
46 | - | ||
47 | - tryOnUnmounted(() => { | ||
48 | - if (!chartInstance) return; | ||
49 | - chartInstance?.destroy?.(); | ||
50 | - chartInstance = null; | ||
51 | - }); | ||
52 | - | ||
53 | - return { | ||
54 | - setOptions, | ||
55 | - updateOptions, | ||
56 | - }; | ||
57 | -} |
src/hooks/web/useECharts.ts
1 | import { useTimeoutFn } from '/@/hooks/core/useTimeout'; | 1 | import { useTimeoutFn } from '/@/hooks/core/useTimeout'; |
2 | import { tryOnUnmounted } from '@vueuse/core'; | 2 | import { tryOnUnmounted } from '@vueuse/core'; |
3 | -import { unref, Ref, nextTick } from 'vue'; | 3 | +import { unref, Ref, nextTick, watch, computed, ref } from 'vue'; |
4 | import type { EChartsOption } from 'echarts'; | 4 | import type { EChartsOption } from 'echarts'; |
5 | import { useDebounce } from '/@/hooks/core/useDebounce'; | 5 | import { useDebounce } from '/@/hooks/core/useDebounce'; |
6 | import { useEventListener } from '/@/hooks/event/useEventListener'; | 6 | import { useEventListener } from '/@/hooks/event/useEventListener'; |
7 | import { useBreakpoint } from '/@/hooks/event/useBreakpoint'; | 7 | import { useBreakpoint } from '/@/hooks/event/useBreakpoint'; |
8 | 8 | ||
9 | import echarts from '/@/plugins/echarts'; | 9 | import echarts from '/@/plugins/echarts'; |
10 | +import { useRootSetting } from '../setting/useRootSetting'; | ||
10 | 11 | ||
11 | export function useECharts( | 12 | export function useECharts( |
12 | elRef: Ref<HTMLDivElement>, | 13 | elRef: Ref<HTMLDivElement>, |
13 | theme: 'light' | 'dark' | 'default' = 'light' | 14 | theme: 'light' | 'dark' | 'default' = 'light' |
14 | ) { | 15 | ) { |
16 | + const { getDarkMode } = useRootSetting(); | ||
15 | let chartInstance: echarts.ECharts | null = null; | 17 | let chartInstance: echarts.ECharts | null = null; |
16 | let resizeFn: Fn = resize; | 18 | let resizeFn: Fn = resize; |
19 | + const cacheOptions = ref<EChartsOption>({}); | ||
17 | let removeResizeFn: Fn = () => {}; | 20 | let removeResizeFn: Fn = () => {}; |
18 | 21 | ||
19 | const [debounceResize] = useDebounce(resize, 200); | 22 | const [debounceResize] = useDebounce(resize, 200); |
20 | resizeFn = debounceResize; | 23 | resizeFn = debounceResize; |
21 | 24 | ||
22 | - function initCharts() { | 25 | + const getOptions = computed( |
26 | + (): EChartsOption => { | ||
27 | + if (getDarkMode.value !== 'dark') { | ||
28 | + return cacheOptions.value; | ||
29 | + } | ||
30 | + return { | ||
31 | + backgroundColor: '#151515', | ||
32 | + ...cacheOptions.value, | ||
33 | + }; | ||
34 | + } | ||
35 | + ); | ||
36 | + | ||
37 | + function initCharts(t = theme) { | ||
23 | const el = unref(elRef); | 38 | const el = unref(elRef); |
24 | if (!el || !unref(el)) { | 39 | if (!el || !unref(el)) { |
25 | return; | 40 | return; |
26 | } | 41 | } |
27 | 42 | ||
28 | - chartInstance = echarts.init(el, theme); | 43 | + chartInstance = echarts.init(el, t); |
29 | const { removeEvent } = useEventListener({ | 44 | const { removeEvent } = useEventListener({ |
30 | el: window, | 45 | el: window, |
31 | name: 'resize', | 46 | name: 'resize', |
@@ -41,22 +56,23 @@ export function useECharts( | @@ -41,22 +56,23 @@ export function useECharts( | ||
41 | } | 56 | } |
42 | 57 | ||
43 | function setOptions(options: EChartsOption, clear = true) { | 58 | function setOptions(options: EChartsOption, clear = true) { |
59 | + cacheOptions.value = options; | ||
44 | if (unref(elRef)?.offsetHeight === 0) { | 60 | if (unref(elRef)?.offsetHeight === 0) { |
45 | useTimeoutFn(() => { | 61 | useTimeoutFn(() => { |
46 | - setOptions(options); | 62 | + setOptions(unref(getOptions)); |
47 | }, 30); | 63 | }, 30); |
48 | return; | 64 | return; |
49 | } | 65 | } |
50 | nextTick(() => { | 66 | nextTick(() => { |
51 | useTimeoutFn(() => { | 67 | useTimeoutFn(() => { |
52 | if (!chartInstance) { | 68 | if (!chartInstance) { |
53 | - initCharts(); | 69 | + initCharts(getDarkMode.value); |
54 | 70 | ||
55 | if (!chartInstance) return; | 71 | if (!chartInstance) return; |
56 | } | 72 | } |
57 | clear && chartInstance?.clear(); | 73 | clear && chartInstance?.clear(); |
58 | 74 | ||
59 | - chartInstance?.setOption(options); | 75 | + chartInstance?.setOption(unref(getOptions)); |
60 | }, 30); | 76 | }, 30); |
61 | }); | 77 | }); |
62 | } | 78 | } |
@@ -65,6 +81,17 @@ export function useECharts( | @@ -65,6 +81,17 @@ export function useECharts( | ||
65 | chartInstance?.resize(); | 81 | chartInstance?.resize(); |
66 | } | 82 | } |
67 | 83 | ||
84 | + watch( | ||
85 | + () => getDarkMode.value, | ||
86 | + (theme) => { | ||
87 | + if (chartInstance) { | ||
88 | + chartInstance.dispose(); | ||
89 | + initCharts(theme); | ||
90 | + setOptions(cacheOptions.value); | ||
91 | + } | ||
92 | + } | ||
93 | + ); | ||
94 | + | ||
68 | tryOnUnmounted(() => { | 95 | tryOnUnmounted(() => { |
69 | if (!chartInstance) return; | 96 | if (!chartInstance) return; |
70 | removeResizeFn(); | 97 | removeResizeFn(); |
src/layouts/default/header/MultipleHeader.vue
@@ -112,7 +112,6 @@ | @@ -112,7 +112,6 @@ | ||
112 | @prefix-cls: ~'@{namespace}-layout-multiple-header'; | 112 | @prefix-cls: ~'@{namespace}-layout-multiple-header'; |
113 | 113 | ||
114 | .@{prefix-cls} { | 114 | .@{prefix-cls} { |
115 | - // margin-left: 1px; | ||
116 | transition: width 0.2s; | 115 | transition: width 0.2s; |
117 | flex: 0 0 auto; | 116 | flex: 0 0 auto; |
118 | 117 |
src/layouts/default/header/components/lock/LockModal.vue
src/layouts/default/header/components/user-dropdown/index.vue
@@ -131,10 +131,6 @@ | @@ -131,10 +131,6 @@ | ||
131 | cursor: pointer; | 131 | cursor: pointer; |
132 | align-items: center; | 132 | align-items: center; |
133 | 133 | ||
134 | - &:hover { | ||
135 | - background: @header-light-bg-hover-color; | ||
136 | - } | ||
137 | - | ||
138 | img { | 134 | img { |
139 | width: 24px; | 135 | width: 24px; |
140 | height: 24px; | 136 | height: 24px; |
src/layouts/default/header/index.less
@@ -131,7 +131,7 @@ | @@ -131,7 +131,7 @@ | ||
131 | } | 131 | } |
132 | 132 | ||
133 | &--light { | 133 | &--light { |
134 | - background: @white; | 134 | + background: @white !important; |
135 | border-bottom: 1px solid @header-light-bottom-border-color; | 135 | border-bottom: 1px solid @header-light-bottom-border-color; |
136 | border-left: 1px solid @header-light-bottom-border-color; | 136 | border-left: 1px solid @header-light-bottom-border-color; |
137 | 137 | ||
@@ -165,8 +165,9 @@ | @@ -165,8 +165,9 @@ | ||
165 | } | 165 | } |
166 | 166 | ||
167 | &--dark { | 167 | &--dark { |
168 | - background: @header-dark-bg-color; | ||
169 | - | 168 | + background: @header-dark-bg-color !important; |
169 | + border-bottom: 1px solid @border-color-base; | ||
170 | + border-left: 1px solid @border-color-base; | ||
170 | .@{header-prefix-cls}-logo { | 171 | .@{header-prefix-cls}-logo { |
171 | &:hover { | 172 | &:hover { |
172 | background: @header-dark-bg-hover-color; | 173 | background: @header-dark-bg-hover-color; |
src/layouts/default/setting/SettingDrawer.tsx
@@ -3,13 +3,15 @@ import { BasicDrawer } from '/@/components/Drawer/index'; | @@ -3,13 +3,15 @@ import { BasicDrawer } from '/@/components/Drawer/index'; | ||
3 | import { Divider } from 'ant-design-vue'; | 3 | import { Divider } from 'ant-design-vue'; |
4 | import { | 4 | import { |
5 | TypePicker, | 5 | TypePicker, |
6 | - ThemePicker, | 6 | + ThemeColorPicker, |
7 | SettingFooter, | 7 | SettingFooter, |
8 | SwitchItem, | 8 | SwitchItem, |
9 | SelectItem, | 9 | SelectItem, |
10 | InputNumberItem, | 10 | InputNumberItem, |
11 | } from './components'; | 11 | } from './components'; |
12 | 12 | ||
13 | +import { AppDarkModeToggle } from '/@/components/Application'; | ||
14 | + | ||
13 | import { MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum'; | 15 | import { MenuTypeEnum, TriggerEnum } from '/@/enums/menuEnum'; |
14 | 16 | ||
15 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | 17 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
@@ -52,6 +54,7 @@ export default defineComponent({ | @@ -52,6 +54,7 @@ export default defineComponent({ | ||
52 | getColorWeak, | 54 | getColorWeak, |
53 | getGrayMode, | 55 | getGrayMode, |
54 | getLockTime, | 56 | getLockTime, |
57 | + getShowDarkModeToggle, | ||
55 | getThemeColor, | 58 | getThemeColor, |
56 | } = useRootSetting(); | 59 | } = useRootSetting(); |
57 | 60 | ||
@@ -116,7 +119,7 @@ export default defineComponent({ | @@ -116,7 +119,7 @@ export default defineComponent({ | ||
116 | 119 | ||
117 | function renderHeaderTheme() { | 120 | function renderHeaderTheme() { |
118 | return ( | 121 | return ( |
119 | - <ThemePicker | 122 | + <ThemeColorPicker |
120 | colorList={HEADER_PRESET_BG_COLOR_LIST} | 123 | colorList={HEADER_PRESET_BG_COLOR_LIST} |
121 | def={unref(getHeaderBgColor)} | 124 | def={unref(getHeaderBgColor)} |
122 | event={HandlerEnum.HEADER_THEME} | 125 | event={HandlerEnum.HEADER_THEME} |
@@ -126,7 +129,7 @@ export default defineComponent({ | @@ -126,7 +129,7 @@ export default defineComponent({ | ||
126 | 129 | ||
127 | function renderSiderTheme() { | 130 | function renderSiderTheme() { |
128 | return ( | 131 | return ( |
129 | - <ThemePicker | 132 | + <ThemeColorPicker |
130 | colorList={SIDE_BAR_BG_COLOR_LIST} | 133 | colorList={SIDE_BAR_BG_COLOR_LIST} |
131 | def={unref(getMenuBgColor)} | 134 | def={unref(getMenuBgColor)} |
132 | event={HandlerEnum.MENU_THEME} | 135 | event={HandlerEnum.MENU_THEME} |
@@ -136,7 +139,7 @@ export default defineComponent({ | @@ -136,7 +139,7 @@ export default defineComponent({ | ||
136 | 139 | ||
137 | function renderMainTheme() { | 140 | function renderMainTheme() { |
138 | return ( | 141 | return ( |
139 | - <ThemePicker | 142 | + <ThemeColorPicker |
140 | colorList={APP_PRESET_COLOR_LIST} | 143 | colorList={APP_PRESET_COLOR_LIST} |
141 | def={unref(getThemeColor)} | 144 | def={unref(getThemeColor)} |
142 | event={HandlerEnum.CHANGE_THEME_COLOR} | 145 | event={HandlerEnum.CHANGE_THEME_COLOR} |
@@ -404,6 +407,8 @@ export default defineComponent({ | @@ -404,6 +407,8 @@ export default defineComponent({ | ||
404 | width={330} | 407 | width={330} |
405 | wrapClassName="setting-drawer" | 408 | wrapClassName="setting-drawer" |
406 | > | 409 | > |
410 | + {unref(getShowDarkModeToggle) && <Divider>{() => t('layout.setting.darkMode')}</Divider>} | ||
411 | + {unref(getShowDarkModeToggle) && <AppDarkModeToggle class="mx-auto" size="large" />} | ||
407 | <Divider>{() => t('layout.setting.navMode')}</Divider> | 412 | <Divider>{() => t('layout.setting.navMode')}</Divider> |
408 | {renderSidebar()} | 413 | {renderSidebar()} |
409 | <Divider>{() => t('layout.setting.sysTheme')}</Divider> | 414 | <Divider>{() => t('layout.setting.sysTheme')}</Divider> |
src/layouts/default/setting/components/ThemePicker.vue renamed to src/layouts/default/setting/components/ThemeColorPicker.vue
@@ -26,7 +26,7 @@ | @@ -26,7 +26,7 @@ | ||
26 | import { HandlerEnum } from '../enum'; | 26 | import { HandlerEnum } from '../enum'; |
27 | 27 | ||
28 | export default defineComponent({ | 28 | export default defineComponent({ |
29 | - name: 'ThemePicker', | 29 | + name: 'ThemeColorPicker', |
30 | components: { CheckOutlined }, | 30 | components: { CheckOutlined }, |
31 | props: { | 31 | props: { |
32 | colorList: { | 32 | colorList: { |
src/layouts/default/setting/components/TypePicker.vue
@@ -74,7 +74,8 @@ | @@ -74,7 +74,8 @@ | ||
74 | content: ''; | 74 | content: ''; |
75 | } | 75 | } |
76 | 76 | ||
77 | - &--sidebar { | 77 | + &--sidebar, |
78 | + &--light { | ||
78 | &::before { | 79 | &::before { |
79 | top: 0; | 80 | top: 0; |
80 | left: 0; | 81 | left: 0; |
@@ -124,6 +125,10 @@ | @@ -124,6 +125,10 @@ | ||
124 | } | 125 | } |
125 | } | 126 | } |
126 | 127 | ||
128 | + &--dark { | ||
129 | + background-color: #273352; | ||
130 | + } | ||
131 | + | ||
127 | &--mix-sidebar { | 132 | &--mix-sidebar { |
128 | &::before { | 133 | &::before { |
129 | top: 0; | 134 | top: 0; |
@@ -152,17 +157,6 @@ | @@ -152,17 +157,6 @@ | ||
152 | } | 157 | } |
153 | } | 158 | } |
154 | 159 | ||
155 | - // &::after { | ||
156 | - // position: absolute; | ||
157 | - // top: 50%; | ||
158 | - // left: 50%; | ||
159 | - // width: 0; | ||
160 | - // height: 0; | ||
161 | - // content: ''; | ||
162 | - // opacity: 0; | ||
163 | - // transition: all 0.3s; | ||
164 | - // } | ||
165 | - | ||
166 | &:hover, | 160 | &:hover, |
167 | &--active { | 161 | &--active { |
168 | padding: 12px; | 162 | padding: 12px; |
src/layouts/default/setting/components/index.ts
1 | import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; | 1 | import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; |
2 | 2 | ||
3 | export const TypePicker = createAsyncComponent(() => import('./TypePicker.vue')); | 3 | export const TypePicker = createAsyncComponent(() => import('./TypePicker.vue')); |
4 | -export const ThemePicker = createAsyncComponent(() => import('./ThemePicker.vue')); | 4 | +export const ThemeColorPicker = createAsyncComponent(() => import('./ThemeColorPicker.vue')); |
5 | export const SettingFooter = createAsyncComponent(() => import('./SettingFooter.vue')); | 5 | export const SettingFooter = createAsyncComponent(() => import('./SettingFooter.vue')); |
6 | export const SwitchItem = createAsyncComponent(() => import('./SwitchItem.vue')); | 6 | export const SwitchItem = createAsyncComponent(() => import('./SwitchItem.vue')); |
7 | export const SelectItem = createAsyncComponent(() => import('./SelectItem.vue')); | 7 | export const SelectItem = createAsyncComponent(() => import('./SelectItem.vue')); |
src/layouts/default/setting/enum.ts
@@ -14,6 +14,7 @@ const { t } = useI18n(); | @@ -14,6 +14,7 @@ const { t } = useI18n(); | ||
14 | export enum HandlerEnum { | 14 | export enum HandlerEnum { |
15 | CHANGE_LAYOUT, | 15 | CHANGE_LAYOUT, |
16 | CHANGE_THEME_COLOR, | 16 | CHANGE_THEME_COLOR, |
17 | + CHANGE_THEME, | ||
17 | // menu | 18 | // menu |
18 | MENU_HAS_DRAG, | 19 | MENU_HAS_DRAG, |
19 | MENU_ACCORDION, | 20 | MENU_ACCORDION, |
src/layouts/default/setting/handler.ts
@@ -6,15 +6,20 @@ import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; | @@ -6,15 +6,20 @@ import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; | ||
6 | import { appStore } from '/@/store/modules/app'; | 6 | import { appStore } from '/@/store/modules/app'; |
7 | import { ProjectConfig } from '/#/config'; | 7 | import { ProjectConfig } from '/#/config'; |
8 | import { changeTheme } from '/@/logics/theme'; | 8 | import { changeTheme } from '/@/logics/theme'; |
9 | +import { updateDarkTheme } from '/@/logics/theme/dark'; | ||
9 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; | 10 | import { useRootSetting } from '/@/hooks/setting/useRootSetting'; |
10 | 11 | ||
11 | export function baseHandler(event: HandlerEnum, value: any) { | 12 | export function baseHandler(event: HandlerEnum, value: any) { |
12 | const config = handler(event, value); | 13 | const config = handler(event, value); |
13 | appStore.commitProjectConfigState(config); | 14 | appStore.commitProjectConfigState(config); |
15 | + if (event === HandlerEnum.CHANGE_THEME) { | ||
16 | + updateHeaderBgColor(); | ||
17 | + updateSidebarBgColor(); | ||
18 | + } | ||
14 | } | 19 | } |
15 | 20 | ||
16 | export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConfig> { | 21 | export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConfig> { |
17 | - const { getThemeColor } = useRootSetting(); | 22 | + const { getThemeColor, getDarkMode } = useRootSetting(); |
18 | switch (event) { | 23 | switch (event) { |
19 | case HandlerEnum.CHANGE_LAYOUT: | 24 | case HandlerEnum.CHANGE_LAYOUT: |
20 | const { mode, type, split } = value; | 25 | const { mode, type, split } = value; |
@@ -36,8 +41,17 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf | @@ -36,8 +41,17 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf | ||
36 | return {}; | 41 | return {}; |
37 | } | 42 | } |
38 | changeTheme(value); | 43 | changeTheme(value); |
44 | + | ||
39 | return { themeColor: value }; | 45 | return { themeColor: value }; |
40 | 46 | ||
47 | + case HandlerEnum.CHANGE_THEME: | ||
48 | + if (getDarkMode.value === value) { | ||
49 | + return {}; | ||
50 | + } | ||
51 | + updateDarkTheme(value); | ||
52 | + | ||
53 | + return { darkMode: value }; | ||
54 | + | ||
41 | case HandlerEnum.MENU_HAS_DRAG: | 55 | case HandlerEnum.MENU_HAS_DRAG: |
42 | return { menuSetting: { canDrag: value } }; | 56 | return { menuSetting: { canDrag: value } }; |
43 | 57 |
src/layouts/default/sider/MixSider.vue
src/layouts/default/tabs/index.less
1 | @prefix-cls: ~'@{namespace}-multiple-tabs'; | 1 | @prefix-cls: ~'@{namespace}-multiple-tabs'; |
2 | 2 | ||
3 | +html[data-theme='dark'] { | ||
4 | + .@{prefix-cls} { | ||
5 | + .ant-tabs-tab { | ||
6 | + border-bottom: 1px solid @border-color-base; | ||
7 | + } | ||
8 | + } | ||
9 | +} | ||
10 | + | ||
3 | .@{prefix-cls} { | 11 | .@{prefix-cls} { |
4 | z-index: 10; | 12 | z-index: 10; |
5 | height: @multiple-height + 2; | 13 | height: @multiple-height + 2; |
6 | line-height: @multiple-height + 2; | 14 | line-height: @multiple-height + 2; |
7 | - background: @white; | 15 | + background: @component-background; |
16 | + border-bottom: 1px solid @border-color-base; | ||
8 | box-shadow: 0 1px 2px 0 rgba(29, 35, 41, 0.05); | 17 | box-shadow: 0 1px 2px 0 rgba(29, 35, 41, 0.05); |
9 | 18 | ||
10 | .ant-tabs-small { | 19 | .ant-tabs-small { |
@@ -15,7 +24,7 @@ | @@ -15,7 +24,7 @@ | ||
15 | .ant-tabs-card-bar { | 24 | .ant-tabs-card-bar { |
16 | height: @multiple-height; | 25 | height: @multiple-height; |
17 | margin: 0; | 26 | margin: 0; |
18 | - background: @white; | 27 | + background: @component-background; |
19 | border: 0; | 28 | border: 0; |
20 | box-shadow: none; | 29 | box-shadow: none; |
21 | 30 | ||
@@ -28,35 +37,14 @@ | @@ -28,35 +37,14 @@ | ||
28 | height: calc(@multiple-height - 2px); | 37 | height: calc(@multiple-height - 2px); |
29 | padding-right: 12px; | 38 | padding-right: 12px; |
30 | line-height: calc(@multiple-height - 2px); | 39 | line-height: calc(@multiple-height - 2px); |
31 | - color: @text-color-call-out; | ||
32 | - background: @white; | ||
33 | - border-bottom: 1px solid @header-light-bottom-border-color; | 40 | + color: @text-color-base; |
41 | + background: @component-background; | ||
34 | transition: none; | 42 | transition: none; |
35 | 43 | ||
36 | - // &:not(.ant-tabs-tab-active)::before { | ||
37 | - // position: absolute; | ||
38 | - // top: -1px; | ||
39 | - // left: 50%; | ||
40 | - // width: 100%; | ||
41 | - // height: 2px; | ||
42 | - // background-color: @primary-color; | ||
43 | - // content: ''; | ||
44 | - // opacity: 0; | ||
45 | - // transform: translate(-50%, 0) scaleX(0); | ||
46 | - // transform-origin: center; | ||
47 | - // transition: none; | ||
48 | - // } | ||
49 | - | ||
50 | &:hover { | 44 | &:hover { |
51 | .ant-tabs-close-x { | 45 | .ant-tabs-close-x { |
52 | opacity: 1; | 46 | opacity: 1; |
53 | } | 47 | } |
54 | - | ||
55 | - // &:not(.ant-tabs-tab-active)::before { | ||
56 | - // opacity: 1; | ||
57 | - // transform: translate(-50%, 0) scaleX(1); | ||
58 | - // transition: all 0.3s ease-in-out; | ||
59 | - // } | ||
60 | } | 48 | } |
61 | 49 | ||
62 | .ant-tabs-close-x { | 50 | .ant-tabs-close-x { |
@@ -85,26 +73,20 @@ | @@ -85,26 +73,20 @@ | ||
85 | } | 73 | } |
86 | } | 74 | } |
87 | 75 | ||
76 | + .ant-tabs-tab:not(.ant-tabs-tab-active) { | ||
77 | + &:hover { | ||
78 | + color: @primary-color; | ||
79 | + } | ||
80 | + } | ||
81 | + | ||
88 | .ant-tabs-tab-active { | 82 | .ant-tabs-tab-active { |
89 | position: relative; | 83 | position: relative; |
90 | - padding-left: 26px; | 84 | + padding-left: 18px; |
91 | color: @white; | 85 | color: @white; |
92 | - background: fade(@primary-color, 100%); | 86 | + background: @primary-color; |
93 | border: 0; | 87 | border: 0; |
94 | transition: none; | 88 | transition: none; |
95 | 89 | ||
96 | - &::before { | ||
97 | - position: absolute; | ||
98 | - top: calc(50% - 3px); | ||
99 | - left: 8px; | ||
100 | - width: 6px; | ||
101 | - height: 6px; | ||
102 | - background: #fff; | ||
103 | - border-radius: 50%; | ||
104 | - content: ''; | ||
105 | - transition: none; | ||
106 | - } | ||
107 | - | ||
108 | .ant-tabs-close-x { | 90 | .ant-tabs-close-x { |
109 | opacity: 1; | 91 | opacity: 1; |
110 | } | 92 | } |
@@ -158,10 +140,10 @@ | @@ -158,10 +140,10 @@ | ||
158 | width: 36px; | 140 | width: 36px; |
159 | height: @multiple-height; | 141 | height: @multiple-height; |
160 | line-height: @multiple-height; | 142 | line-height: @multiple-height; |
161 | - color: #666; | 143 | + color: @text-color-secondary; |
162 | text-align: center; | 144 | text-align: center; |
163 | cursor: pointer; | 145 | cursor: pointer; |
164 | - border-left: 1px solid #eee; | 146 | + border-left: 1px solid @border-color-base; |
165 | 147 | ||
166 | &:hover { | 148 | &:hover { |
167 | color: @text-color-base; | 149 | color: @text-color-base; |
src/locales/lang/en/common.ts
src/locales/lang/en/layout/setting.ts
@@ -30,6 +30,7 @@ export default { | @@ -30,6 +30,7 @@ export default { | ||
30 | 30 | ||
31 | drawerTitle: 'Configuration', | 31 | drawerTitle: 'Configuration', |
32 | 32 | ||
33 | + darkMode: 'Dark mode', | ||
33 | navMode: 'Navigation mode', | 34 | navMode: 'Navigation mode', |
34 | interfaceFunction: 'Interface function', | 35 | interfaceFunction: 'Interface function', |
35 | interfaceDisplay: 'Interface display', | 36 | interfaceDisplay: 'Interface display', |
src/locales/lang/en/routes/demo/charts.ts
src/locales/lang/zh_CN/common.ts
src/locales/lang/zh_CN/layout/setting.ts
@@ -29,6 +29,7 @@ export default { | @@ -29,6 +29,7 @@ export default { | ||
29 | 29 | ||
30 | drawerTitle: '项目配置', | 30 | drawerTitle: '项目配置', |
31 | 31 | ||
32 | + darkMode: '主题', | ||
32 | navMode: '导航栏模式', | 33 | navMode: '导航栏模式', |
33 | interfaceFunction: '界面功能', | 34 | interfaceFunction: '界面功能', |
34 | interfaceDisplay: '界面显示', | 35 | interfaceDisplay: '界面显示', |
src/locales/lang/zh_CN/routes/demo/charts.ts
src/logics/initAppConfig.ts
@@ -9,6 +9,7 @@ import projectSetting from '/@/settings/projectSetting'; | @@ -9,6 +9,7 @@ import projectSetting from '/@/settings/projectSetting'; | ||
9 | import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground'; | 9 | import { updateHeaderBgColor, updateSidebarBgColor } from '/@/logics/theme/updateBackground'; |
10 | import { updateColorWeak } from '/@/logics/theme/updateColorWeak'; | 10 | import { updateColorWeak } from '/@/logics/theme/updateColorWeak'; |
11 | import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; | 11 | import { updateGrayMode } from '/@/logics/theme/updateGrayMode'; |
12 | +import { updateDarkTheme } from '/@/logics/theme/dark'; | ||
12 | import { changeTheme } from '/@/logics/theme'; | 13 | import { changeTheme } from '/@/logics/theme'; |
13 | 14 | ||
14 | import { appStore } from '/@/store/modules/app'; | 15 | import { appStore } from '/@/store/modules/app'; |
@@ -19,30 +20,43 @@ import { getCommonStoragePrefix, getStorageShortName } from '/@/utils/env'; | @@ -19,30 +20,43 @@ import { getCommonStoragePrefix, getStorageShortName } from '/@/utils/env'; | ||
19 | import { primaryColor } from '../../build/config/themeConfig'; | 20 | import { primaryColor } from '../../build/config/themeConfig'; |
20 | import { Persistent } from '/@/utils/cache/persistent'; | 21 | import { Persistent } from '/@/utils/cache/persistent'; |
21 | import { deepMerge } from '/@/utils'; | 22 | import { deepMerge } from '/@/utils'; |
23 | +import { ThemeEnum } from '../enums/appEnum'; | ||
22 | 24 | ||
23 | // Initial project configuration | 25 | // Initial project configuration |
24 | export function initAppConfigStore() { | 26 | export function initAppConfigStore() { |
25 | let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig; | 27 | let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig; |
26 | projCfg = deepMerge(projectSetting, projCfg || {}); | 28 | projCfg = deepMerge(projectSetting, projCfg || {}); |
29 | + const darkMode = appStore.getDarkMode; | ||
30 | + const { | ||
31 | + colorWeak, | ||
32 | + grayMode, | ||
33 | + themeColor, | ||
34 | + | ||
35 | + headerSetting: { bgColor: headerBgColor } = {}, | ||
36 | + menuSetting: { bgColor } = {}, | ||
37 | + } = projCfg; | ||
27 | try { | 38 | try { |
28 | - const { | ||
29 | - colorWeak, | ||
30 | - grayMode, | ||
31 | - themeColor, | ||
32 | - headerSetting: { bgColor: headerBgColor } = {}, | ||
33 | - menuSetting: { bgColor } = {}, | ||
34 | - } = projCfg; | ||
35 | if (themeColor && themeColor !== primaryColor) { | 39 | if (themeColor && themeColor !== primaryColor) { |
36 | changeTheme(themeColor); | 40 | changeTheme(themeColor); |
37 | } | 41 | } |
38 | - headerBgColor && updateHeaderBgColor(headerBgColor); | ||
39 | - bgColor && updateSidebarBgColor(bgColor); | 42 | + |
40 | grayMode && updateGrayMode(grayMode); | 43 | grayMode && updateGrayMode(grayMode); |
41 | colorWeak && updateColorWeak(colorWeak); | 44 | colorWeak && updateColorWeak(colorWeak); |
42 | } catch (error) { | 45 | } catch (error) { |
43 | console.log(error); | 46 | console.log(error); |
44 | } | 47 | } |
45 | appStore.commitProjectConfigState(projCfg); | 48 | appStore.commitProjectConfigState(projCfg); |
49 | + | ||
50 | + // init dark mode | ||
51 | + updateDarkTheme(darkMode); | ||
52 | + if (darkMode === ThemeEnum.DARK) { | ||
53 | + updateHeaderBgColor(); | ||
54 | + updateSidebarBgColor(); | ||
55 | + } else { | ||
56 | + headerBgColor && updateHeaderBgColor(headerBgColor); | ||
57 | + bgColor && updateSidebarBgColor(bgColor); | ||
58 | + } | ||
59 | + // init store | ||
46 | localeStore.initLocale(); | 60 | localeStore.initLocale(); |
47 | 61 | ||
48 | setTimeout(() => { | 62 | setTimeout(() => { |
src/logics/theme/dark.ts
0 → 100644
1 | +import { darkCssIsReady, loadDarkThemeCss } from 'vite-plugin-theme/es/client'; | ||
2 | + | ||
3 | +export async function updateDarkTheme(mode: string | null = 'light') { | ||
4 | + const htmlRoot = document.getElementById('htmlRoot'); | ||
5 | + if (mode === 'dark') { | ||
6 | + if (import.meta.env.PROD && !darkCssIsReady) { | ||
7 | + await loadDarkThemeCss(); | ||
8 | + } | ||
9 | + htmlRoot?.setAttribute('data-theme', 'dark'); | ||
10 | + } else { | ||
11 | + htmlRoot?.setAttribute('data-theme', 'light'); | ||
12 | + } | ||
13 | +} |
src/logics/theme/index.ts
1 | -import { getThemeColors, ThemeMode, generateColors } from '../../../build/config/themeConfig'; | 1 | +import { getThemeColors, generateColors } from '../../../build/config/themeConfig'; |
2 | 2 | ||
3 | import { replaceStyleVariables } from 'vite-plugin-theme/es/client'; | 3 | import { replaceStyleVariables } from 'vite-plugin-theme/es/client'; |
4 | import { mixLighten, mixDarken, tinycolor } from 'vite-plugin-theme/es/colorUtils'; | 4 | import { mixLighten, mixDarken, tinycolor } from 'vite-plugin-theme/es/colorUtils'; |
5 | 5 | ||
6 | -export async function changeTheme(color: string, theme?: ThemeMode) { | 6 | +export async function changeTheme(color: string) { |
7 | const colors = generateColors({ | 7 | const colors = generateColors({ |
8 | mixDarken, | 8 | mixDarken, |
9 | mixLighten, | 9 | mixLighten, |
@@ -12,6 +12,6 @@ export async function changeTheme(color: string, theme?: ThemeMode) { | @@ -12,6 +12,6 @@ export async function changeTheme(color: string, theme?: ThemeMode) { | ||
12 | }); | 12 | }); |
13 | 13 | ||
14 | return await replaceStyleVariables({ | 14 | return await replaceStyleVariables({ |
15 | - colorVariables: [...getThemeColors(color, theme), ...colors], | 15 | + colorVariables: [...getThemeColors(color), ...colors], |
16 | }); | 16 | }); |
17 | } | 17 | } |
src/logics/theme/updateBackground.ts
1 | -import { isHexColor, colorIsDark, lighten, darken } from '/@/utils/color'; | 1 | +import { colorIsDark, lighten, darken } from '/@/utils/color'; |
2 | import { appStore } from '/@/store/modules/app'; | 2 | import { appStore } from '/@/store/modules/app'; |
3 | import { ThemeEnum } from '/@/enums/appEnum'; | 3 | import { ThemeEnum } from '/@/enums/appEnum'; |
4 | import { setCssVar } from './util'; | 4 | import { setCssVar } from './util'; |
@@ -9,29 +9,35 @@ const HEADER_MENU_ACTIVE_BG_COLOR_VAR = '--header-active-menu-bg-color'; | @@ -9,29 +9,35 @@ const HEADER_MENU_ACTIVE_BG_COLOR_VAR = '--header-active-menu-bg-color'; | ||
9 | 9 | ||
10 | const SIDER_DARK_BG_COLOR = '--sider-dark-bg-color'; | 10 | const SIDER_DARK_BG_COLOR = '--sider-dark-bg-color'; |
11 | const SIDER_DARK_DARKEN_BG_COLOR = '--sider-dark-darken-bg-color'; | 11 | const SIDER_DARK_DARKEN_BG_COLOR = '--sider-dark-darken-bg-color'; |
12 | -const SIDER_LIGHTEN_1_BG_COLOR = '--sider-dark-lighten-1-bg-color'; | ||
13 | -const SIDER_LIGHTEN_2_BG_COLOR = '--sider-dark-lighten-2-bg-color'; | 12 | +const SIDER_LIGHTEN_BG_COLOR = '--sider-dark-lighten-bg-color'; |
14 | 13 | ||
15 | /** | 14 | /** |
16 | * Change the background color of the top header | 15 | * Change the background color of the top header |
17 | * @param color | 16 | * @param color |
18 | */ | 17 | */ |
19 | -export function updateHeaderBgColor(color: string) { | ||
20 | - if (!isHexColor(color)) return; | 18 | +export function updateHeaderBgColor(color?: string) { |
19 | + const darkMode = appStore.getDarkMode === ThemeEnum.DARK; | ||
20 | + if (!color) { | ||
21 | + if (darkMode) { | ||
22 | + color = '#151515'; | ||
23 | + } else { | ||
24 | + color = appStore.getProjectConfig.headerSetting.bgColor; | ||
25 | + } | ||
26 | + } | ||
21 | // bg color | 27 | // bg color |
22 | setCssVar(HEADER_BG_COLOR_VAR, color); | 28 | setCssVar(HEADER_BG_COLOR_VAR, color); |
23 | 29 | ||
24 | // hover color | 30 | // hover color |
25 | - const hoverColor = lighten(color, 6); | 31 | + const hoverColor = lighten(color!, 6); |
26 | setCssVar(HEADER_BG_HOVER_COLOR_VAR, hoverColor); | 32 | setCssVar(HEADER_BG_HOVER_COLOR_VAR, hoverColor); |
27 | setCssVar(HEADER_MENU_ACTIVE_BG_COLOR_VAR, hoverColor); | 33 | setCssVar(HEADER_MENU_ACTIVE_BG_COLOR_VAR, hoverColor); |
28 | 34 | ||
29 | // Determine the depth of the color value and automatically switch the theme | 35 | // Determine the depth of the color value and automatically switch the theme |
30 | - const isDark = colorIsDark(color); | 36 | + const isDark = colorIsDark(color!); |
31 | 37 | ||
32 | appStore.commitProjectConfigState({ | 38 | appStore.commitProjectConfigState({ |
33 | headerSetting: { | 39 | headerSetting: { |
34 | - theme: isDark ? ThemeEnum.DARK : ThemeEnum.LIGHT, | 40 | + theme: isDark || darkMode ? ThemeEnum.DARK : ThemeEnum.LIGHT, |
35 | }, | 41 | }, |
36 | }); | 42 | }); |
37 | } | 43 | } |
@@ -40,21 +46,27 @@ export function updateHeaderBgColor(color: string) { | @@ -40,21 +46,27 @@ export function updateHeaderBgColor(color: string) { | ||
40 | * Change the background color of the left menu | 46 | * Change the background color of the left menu |
41 | * @param color bg color | 47 | * @param color bg color |
42 | */ | 48 | */ |
43 | -export function updateSidebarBgColor(color: string) { | ||
44 | - if (!isHexColor(color)) return; | ||
45 | - | 49 | +export function updateSidebarBgColor(color?: string) { |
50 | + // if (!isHexColor(color)) return; | ||
51 | + const darkMode = appStore.getDarkMode === ThemeEnum.DARK; | ||
52 | + if (!color) { | ||
53 | + if (darkMode) { | ||
54 | + color = '#212121'; | ||
55 | + } else { | ||
56 | + color = appStore.getProjectConfig.menuSetting.bgColor; | ||
57 | + } | ||
58 | + } | ||
46 | setCssVar(SIDER_DARK_BG_COLOR, color); | 59 | setCssVar(SIDER_DARK_BG_COLOR, color); |
47 | - setCssVar(SIDER_DARK_DARKEN_BG_COLOR, darken(color, 6)); | ||
48 | - setCssVar(SIDER_LIGHTEN_1_BG_COLOR, lighten(color, 5)); | ||
49 | - setCssVar(SIDER_LIGHTEN_2_BG_COLOR, lighten(color, 8)); | 60 | + setCssVar(SIDER_DARK_DARKEN_BG_COLOR, darken(color!, 6)); |
61 | + setCssVar(SIDER_LIGHTEN_BG_COLOR, lighten(color!, 5)); | ||
50 | 62 | ||
51 | // only #ffffff is light | 63 | // only #ffffff is light |
52 | // Only when the background color is #fff, the theme of the menu will be changed to light | 64 | // Only when the background color is #fff, the theme of the menu will be changed to light |
53 | - const isLight = ['#fff', '#ffffff'].includes(color.toLowerCase()); | 65 | + const isLight = ['#fff', '#ffffff'].includes(color!.toLowerCase()); |
54 | 66 | ||
55 | appStore.commitProjectConfigState({ | 67 | appStore.commitProjectConfigState({ |
56 | menuSetting: { | 68 | menuSetting: { |
57 | - theme: isLight ? ThemeEnum.LIGHT : ThemeEnum.DARK, | 69 | + theme: isLight && !darkMode ? ThemeEnum.LIGHT : ThemeEnum.DARK, |
58 | }, | 70 | }, |
59 | }); | 71 | }); |
60 | } | 72 | } |
src/router/menus/modules/demo/charts.ts
@@ -22,11 +22,6 @@ const menu: MenuModule = { | @@ -22,11 +22,6 @@ const menu: MenuModule = { | ||
22 | name: t('routes.demo.charts.googleMap'), | 22 | name: t('routes.demo.charts.googleMap'), |
23 | }, | 23 | }, |
24 | { | 24 | { |
25 | - path: 'apexChart', | ||
26 | - name: t('routes.demo.charts.apexChart'), | ||
27 | - }, | ||
28 | - | ||
29 | - { | ||
30 | path: 'echarts', | 25 | path: 'echarts', |
31 | name: 'Echarts', | 26 | name: 'Echarts', |
32 | children: [ | 27 | children: [ |
src/router/routes/modules/demo/charts.ts
@@ -39,14 +39,6 @@ const charts: AppRouteModule = { | @@ -39,14 +39,6 @@ const charts: AppRouteModule = { | ||
39 | }, | 39 | }, |
40 | 40 | ||
41 | { | 41 | { |
42 | - path: 'apexChart', | ||
43 | - name: 'ApexChart', | ||
44 | - meta: { | ||
45 | - title: t('routes.demo.charts.apexChart'), | ||
46 | - }, | ||
47 | - component: () => import('/@/views/demo/charts/apex/index.vue'), | ||
48 | - }, | ||
49 | - { | ||
50 | path: 'echarts', | 42 | path: 'echarts', |
51 | name: 'Echarts', | 43 | name: 'Echarts', |
52 | component: getParentLayout('Echarts'), | 44 | component: getParentLayout('Echarts'), |
src/settings/designSetting.ts
1 | +import { ThemeEnum } from '../enums/appEnum'; | ||
1 | export default { | 2 | export default { |
2 | prefixCls: 'vben', | 3 | prefixCls: 'vben', |
3 | }; | 4 | }; |
4 | 5 | ||
6 | +export const darkMode = ThemeEnum.LIGHT; | ||
7 | + | ||
5 | // app theme preset color | 8 | // app theme preset color |
6 | export const APP_PRESET_COLOR_LIST: string[] = [ | 9 | export const APP_PRESET_COLOR_LIST: string[] = [ |
7 | '#0960bd', | 10 | '#0960bd', |
@@ -18,6 +21,7 @@ export const APP_PRESET_COLOR_LIST: string[] = [ | @@ -18,6 +21,7 @@ export const APP_PRESET_COLOR_LIST: string[] = [ | ||
18 | // header preset color | 21 | // header preset color |
19 | export const HEADER_PRESET_BG_COLOR_LIST: string[] = [ | 22 | export const HEADER_PRESET_BG_COLOR_LIST: string[] = [ |
20 | '#ffffff', | 23 | '#ffffff', |
24 | + '#151515', | ||
21 | '#009688', | 25 | '#009688', |
22 | '#5172DC', | 26 | '#5172DC', |
23 | '#018ffb', | 27 | '#018ffb', |
@@ -32,6 +36,7 @@ export const HEADER_PRESET_BG_COLOR_LIST: string[] = [ | @@ -32,6 +36,7 @@ export const HEADER_PRESET_BG_COLOR_LIST: string[] = [ | ||
32 | // sider preset color | 36 | // sider preset color |
33 | export const SIDE_BAR_BG_COLOR_LIST: string[] = [ | 37 | export const SIDE_BAR_BG_COLOR_LIST: string[] = [ |
34 | '#001529', | 38 | '#001529', |
39 | + '#212121', | ||
35 | '#273352', | 40 | '#273352', |
36 | '#ffffff', | 41 | '#ffffff', |
37 | '#191b24', | 42 | '#191b24', |
src/settings/projectSetting.ts
@@ -9,13 +9,16 @@ import { | @@ -9,13 +9,16 @@ import { | ||
9 | SettingButtonPositionEnum, | 9 | SettingButtonPositionEnum, |
10 | } from '/@/enums/appEnum'; | 10 | } from '/@/enums/appEnum'; |
11 | import { SIDE_BAR_BG_COLOR_LIST, HEADER_PRESET_BG_COLOR_LIST } from './designSetting'; | 11 | import { SIDE_BAR_BG_COLOR_LIST, HEADER_PRESET_BG_COLOR_LIST } from './designSetting'; |
12 | -import { primaryColor, themeMode } from '../../build/config/themeConfig'; | 12 | +import { primaryColor } from '../../build/config/themeConfig'; |
13 | 13 | ||
14 | // ! You need to clear the browser cache after the change | 14 | // ! You need to clear the browser cache after the change |
15 | const setting: ProjectConfig = { | 15 | const setting: ProjectConfig = { |
16 | // Whether to show the configuration button | 16 | // Whether to show the configuration button |
17 | showSettingButton: true, | 17 | showSettingButton: true, |
18 | 18 | ||
19 | + // Whether to show the theme switch button | ||
20 | + showDarkModeToggle: true, | ||
21 | + | ||
19 | // `Settings` button position | 22 | // `Settings` button position |
20 | settingButtonPosition: SettingButtonPositionEnum.AUTO, | 23 | settingButtonPosition: SettingButtonPositionEnum.AUTO, |
21 | 24 | ||
@@ -28,9 +31,6 @@ const setting: ProjectConfig = { | @@ -28,9 +31,6 @@ const setting: ProjectConfig = { | ||
28 | // color | 31 | // color |
29 | themeColor: primaryColor, | 32 | themeColor: primaryColor, |
30 | 33 | ||
31 | - // TODO dark theme | ||
32 | - themeMode: themeMode, | ||
33 | - | ||
34 | // Website gray mode, open for possible mourning dates | 34 | // Website gray mode, open for possible mourning dates |
35 | grayMode: false, | 35 | grayMode: false, |
36 | 36 |
src/store/modules/app.ts
@@ -4,13 +4,16 @@ import type { BeforeMiniState } from '../types'; | @@ -4,13 +4,16 @@ import type { BeforeMiniState } from '../types'; | ||
4 | import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators'; | 4 | import { VuexModule, getModule, Module, Mutation, Action } from 'vuex-module-decorators'; |
5 | import store from '/@/store'; | 5 | import store from '/@/store'; |
6 | 6 | ||
7 | -import { PROJ_CFG_KEY } from '/@/enums/cacheEnum'; | 7 | +import { PROJ_CFG_KEY, APP_DARK_MODE_KEY_ } from '/@/enums/cacheEnum'; |
8 | 8 | ||
9 | import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; | 9 | import { hotModuleUnregisterModule } from '/@/utils/helper/vuexHelper'; |
10 | import { Persistent } from '/@/utils/cache/persistent'; | 10 | import { Persistent } from '/@/utils/cache/persistent'; |
11 | import { deepMerge } from '/@/utils'; | 11 | import { deepMerge } from '/@/utils'; |
12 | 12 | ||
13 | import { resetRouter } from '/@/router'; | 13 | import { resetRouter } from '/@/router'; |
14 | +import { ThemeEnum } from '../../enums/appEnum'; | ||
15 | + | ||
16 | +import { darkMode } from '/@/settings/designSetting'; | ||
14 | 17 | ||
15 | export interface LockInfo { | 18 | export interface LockInfo { |
16 | pwd: string | undefined; | 19 | pwd: string | undefined; |
@@ -22,6 +25,8 @@ const NAME = 'app'; | @@ -22,6 +25,8 @@ const NAME = 'app'; | ||
22 | hotModuleUnregisterModule(NAME); | 25 | hotModuleUnregisterModule(NAME); |
23 | @Module({ dynamic: true, namespaced: true, store, name: NAME }) | 26 | @Module({ dynamic: true, namespaced: true, store, name: NAME }) |
24 | export default class App extends VuexModule { | 27 | export default class App extends VuexModule { |
28 | + private darkMode; | ||
29 | + | ||
25 | // Page loading status | 30 | // Page loading status |
26 | private pageLoadingState = false; | 31 | private pageLoadingState = false; |
27 | 32 | ||
@@ -38,6 +43,10 @@ export default class App extends VuexModule { | @@ -38,6 +43,10 @@ export default class App extends VuexModule { | ||
38 | return this.pageLoadingState; | 43 | return this.pageLoadingState; |
39 | } | 44 | } |
40 | 45 | ||
46 | + get getDarkMode() { | ||
47 | + return this.darkMode || localStorage.getItem(APP_DARK_MODE_KEY_) || darkMode; | ||
48 | + } | ||
49 | + | ||
41 | get getBeforeMiniState() { | 50 | get getBeforeMiniState() { |
42 | return this.beforeMiniState; | 51 | return this.beforeMiniState; |
43 | } | 52 | } |
@@ -56,6 +65,12 @@ export default class App extends VuexModule { | @@ -56,6 +65,12 @@ export default class App extends VuexModule { | ||
56 | } | 65 | } |
57 | 66 | ||
58 | @Mutation | 67 | @Mutation |
68 | + commitDarkMode(mode: ThemeEnum): void { | ||
69 | + this.darkMode = mode; | ||
70 | + localStorage.setItem(APP_DARK_MODE_KEY_, mode); | ||
71 | + } | ||
72 | + | ||
73 | + @Mutation | ||
59 | commitBeforeMiniState(state: BeforeMiniState): void { | 74 | commitBeforeMiniState(state: BeforeMiniState): void { |
60 | this.beforeMiniState = state; | 75 | this.beforeMiniState = state; |
61 | } | 76 | } |
src/views/dashboard/analysis/components/VisitRadar.vue
src/views/dashboard/workbench/components/SaleRadar.vue
src/views/demo/charts/SaleRadar.vue
src/views/demo/charts/apex/Area.vue deleted
100644 → 0
1 | -<template> | ||
2 | - <div ref="chartRef" :style="{ width: '100%' }"></div> | ||
3 | -</template> | ||
4 | -<script lang="ts"> | ||
5 | - import { defineComponent, ref, Ref, onMounted } from 'vue'; | ||
6 | - | ||
7 | - import { useApexCharts } from '/@/hooks/web/useApexCharts'; | ||
8 | - | ||
9 | - export default defineComponent({ | ||
10 | - setup() { | ||
11 | - const chartRef = ref<HTMLDivElement | null>(null); | ||
12 | - const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); | ||
13 | - | ||
14 | - onMounted(() => { | ||
15 | - setOptions({ | ||
16 | - series: [ | ||
17 | - { | ||
18 | - name: 'series1', | ||
19 | - data: [31, 40, 28, 51, 42, 109, 100], | ||
20 | - }, | ||
21 | - { | ||
22 | - name: 'series2', | ||
23 | - data: [11, 32, 45, 32, 34, 52, 41], | ||
24 | - }, | ||
25 | - ], | ||
26 | - chart: { | ||
27 | - height: 350, | ||
28 | - type: 'area', | ||
29 | - }, | ||
30 | - dataLabels: { | ||
31 | - enabled: false, | ||
32 | - }, | ||
33 | - stroke: { | ||
34 | - curve: 'smooth', | ||
35 | - }, | ||
36 | - xaxis: { | ||
37 | - type: 'datetime', | ||
38 | - categories: [ | ||
39 | - '2018-09-19T00:00:00.000Z', | ||
40 | - '2018-09-19T01:30:00.000Z', | ||
41 | - '2018-09-19T02:30:00.000Z', | ||
42 | - '2018-09-19T03:30:00.000Z', | ||
43 | - '2018-09-19T04:30:00.000Z', | ||
44 | - '2018-09-19T05:30:00.000Z', | ||
45 | - '2018-09-19T06:30:00.000Z', | ||
46 | - ], | ||
47 | - }, | ||
48 | - tooltip: { | ||
49 | - x: { | ||
50 | - format: 'dd/MM/yy HH:mm', | ||
51 | - }, | ||
52 | - }, | ||
53 | - }); | ||
54 | - }); | ||
55 | - return { chartRef }; | ||
56 | - }, | ||
57 | - }); | ||
58 | -</script> |
src/views/demo/charts/apex/Bar.vue deleted
100644 → 0
1 | -<template> | ||
2 | - <div ref="chartRef" :style="{ width: '100%' }"></div> | ||
3 | -</template> | ||
4 | -<script lang="ts"> | ||
5 | - import { defineComponent, ref, Ref, onMounted } from 'vue'; | ||
6 | - | ||
7 | - import { useApexCharts } from '/@/hooks/web/useApexCharts'; | ||
8 | - | ||
9 | - export default defineComponent({ | ||
10 | - setup() { | ||
11 | - const chartRef = ref<HTMLDivElement | null>(null); | ||
12 | - const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); | ||
13 | - | ||
14 | - onMounted(() => { | ||
15 | - setOptions({ | ||
16 | - series: [ | ||
17 | - { | ||
18 | - data: [400, 430, 448, 470, 540, 580, 690, 1100, 1200, 1380], | ||
19 | - }, | ||
20 | - ], | ||
21 | - chart: { | ||
22 | - type: 'bar', | ||
23 | - height: 350, | ||
24 | - }, | ||
25 | - plotOptions: { | ||
26 | - bar: { | ||
27 | - horizontal: true, | ||
28 | - }, | ||
29 | - }, | ||
30 | - dataLabels: { | ||
31 | - enabled: false, | ||
32 | - }, | ||
33 | - xaxis: { | ||
34 | - categories: [ | ||
35 | - 'South Korea', | ||
36 | - 'Canada', | ||
37 | - 'United Kingdom', | ||
38 | - 'Netherlands', | ||
39 | - 'Italy', | ||
40 | - 'France', | ||
41 | - 'Japan', | ||
42 | - 'United States', | ||
43 | - 'China', | ||
44 | - 'Germany', | ||
45 | - ], | ||
46 | - }, | ||
47 | - }); | ||
48 | - }); | ||
49 | - return { chartRef }; | ||
50 | - }, | ||
51 | - }); | ||
52 | -</script> |
src/views/demo/charts/apex/Line.vue deleted
100644 → 0
1 | -<template> | ||
2 | - <div ref="chartRef" :style="{ width: '100%' }"></div> | ||
3 | -</template> | ||
4 | -<script lang="ts"> | ||
5 | - import { defineComponent, ref, Ref, onMounted } from 'vue'; | ||
6 | - | ||
7 | - import { useApexCharts } from '/@/hooks/web/useApexCharts'; | ||
8 | - | ||
9 | - export default defineComponent({ | ||
10 | - setup() { | ||
11 | - const chartRef = ref<HTMLDivElement | null>(null); | ||
12 | - const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); | ||
13 | - | ||
14 | - onMounted(() => { | ||
15 | - setOptions({ | ||
16 | - series: [ | ||
17 | - { | ||
18 | - name: 'Desktops', | ||
19 | - data: [10, 41, 35, 51, 49, 62, 69, 91, 148], | ||
20 | - }, | ||
21 | - ], | ||
22 | - chart: { | ||
23 | - height: 350, | ||
24 | - type: 'line', | ||
25 | - zoom: { | ||
26 | - enabled: false, | ||
27 | - }, | ||
28 | - }, | ||
29 | - dataLabels: { | ||
30 | - enabled: false, | ||
31 | - }, | ||
32 | - stroke: { | ||
33 | - curve: 'straight', | ||
34 | - }, | ||
35 | - title: { | ||
36 | - text: 'Product Trends by Month', | ||
37 | - align: 'left', | ||
38 | - }, | ||
39 | - grid: { | ||
40 | - row: { | ||
41 | - colors: ['#f3f3f3', 'transparent'], // takes an array which will be repeated on columns | ||
42 | - opacity: 0.5, | ||
43 | - }, | ||
44 | - }, | ||
45 | - xaxis: { | ||
46 | - categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'], | ||
47 | - }, | ||
48 | - }); | ||
49 | - }); | ||
50 | - return { chartRef }; | ||
51 | - }, | ||
52 | - }); | ||
53 | -</script> |
src/views/demo/charts/apex/Mixed.vue deleted
100644 → 0
1 | -<template> | ||
2 | - <div ref="chartRef" :style="{ width: '100%' }"></div> | ||
3 | -</template> | ||
4 | -<script lang="ts"> | ||
5 | - import { defineComponent, ref, Ref, onMounted } from 'vue'; | ||
6 | - | ||
7 | - import { useApexCharts } from '/@/hooks/web/useApexCharts'; | ||
8 | - | ||
9 | - export default defineComponent({ | ||
10 | - setup() { | ||
11 | - const chartRef = ref<HTMLDivElement | null>(null); | ||
12 | - const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); | ||
13 | - | ||
14 | - onMounted(() => { | ||
15 | - setOptions({ | ||
16 | - series: [ | ||
17 | - { | ||
18 | - name: 'Income', | ||
19 | - type: 'column', | ||
20 | - data: [1.4, 2, 2.5, 1.5, 2.5, 2.8, 3.8, 4.6], | ||
21 | - }, | ||
22 | - { | ||
23 | - name: 'Cashflow', | ||
24 | - type: 'column', | ||
25 | - data: [1.1, 3, 3.1, 4, 4.1, 4.9, 6.5, 8.5], | ||
26 | - }, | ||
27 | - { | ||
28 | - name: 'Revenue', | ||
29 | - type: 'line', | ||
30 | - data: [20, 29, 37, 36, 44, 45, 50, 58], | ||
31 | - }, | ||
32 | - ], | ||
33 | - chart: { | ||
34 | - height: 350, | ||
35 | - type: 'line', | ||
36 | - stacked: false, | ||
37 | - }, | ||
38 | - dataLabels: { | ||
39 | - enabled: false, | ||
40 | - }, | ||
41 | - stroke: { | ||
42 | - width: [1, 1, 4], | ||
43 | - }, | ||
44 | - title: { | ||
45 | - text: 'XYZ - Stock Analysis (2009 - 2016)', | ||
46 | - align: 'left', | ||
47 | - offsetX: 110, | ||
48 | - }, | ||
49 | - xaxis: { | ||
50 | - categories: [2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016], | ||
51 | - }, | ||
52 | - yaxis: [ | ||
53 | - { | ||
54 | - axisTicks: { | ||
55 | - show: true, | ||
56 | - }, | ||
57 | - axisBorder: { | ||
58 | - show: true, | ||
59 | - color: '#008FFB', | ||
60 | - }, | ||
61 | - labels: { | ||
62 | - style: { | ||
63 | - colors: '#008FFB', | ||
64 | - }, | ||
65 | - }, | ||
66 | - title: { | ||
67 | - text: 'Income (thousand crores)', | ||
68 | - style: { | ||
69 | - color: '#008FFB', | ||
70 | - }, | ||
71 | - }, | ||
72 | - tooltip: { | ||
73 | - enabled: true, | ||
74 | - }, | ||
75 | - }, | ||
76 | - { | ||
77 | - seriesName: 'Income', | ||
78 | - opposite: true, | ||
79 | - axisTicks: { | ||
80 | - show: true, | ||
81 | - }, | ||
82 | - axisBorder: { | ||
83 | - show: true, | ||
84 | - color: '#00E396', | ||
85 | - }, | ||
86 | - labels: { | ||
87 | - style: { | ||
88 | - colors: '#00E396', | ||
89 | - }, | ||
90 | - }, | ||
91 | - title: { | ||
92 | - text: 'Operating Cashflow (thousand crores)', | ||
93 | - style: { | ||
94 | - color: '#00E396', | ||
95 | - }, | ||
96 | - }, | ||
97 | - }, | ||
98 | - { | ||
99 | - seriesName: 'Revenue', | ||
100 | - opposite: true, | ||
101 | - axisTicks: { | ||
102 | - show: true, | ||
103 | - }, | ||
104 | - axisBorder: { | ||
105 | - show: true, | ||
106 | - color: '#FEB019', | ||
107 | - }, | ||
108 | - labels: { | ||
109 | - style: { | ||
110 | - colors: '#FEB019', | ||
111 | - }, | ||
112 | - }, | ||
113 | - title: { | ||
114 | - text: 'Revenue (thousand crores)', | ||
115 | - style: { | ||
116 | - color: '#FEB019', | ||
117 | - }, | ||
118 | - }, | ||
119 | - }, | ||
120 | - ], | ||
121 | - tooltip: { | ||
122 | - fixed: { | ||
123 | - enabled: true, | ||
124 | - position: 'topLeft', // topRight, topLeft, bottomRight, bottomLeft | ||
125 | - offsetY: 30, | ||
126 | - offsetX: 60, | ||
127 | - }, | ||
128 | - }, | ||
129 | - legend: { | ||
130 | - horizontalAlign: 'left', | ||
131 | - offsetX: 40, | ||
132 | - }, | ||
133 | - }); | ||
134 | - }); | ||
135 | - return { chartRef }; | ||
136 | - }, | ||
137 | - }); | ||
138 | -</script> |
src/views/demo/charts/apex/SaleRadar.vue deleted
100644 → 0
1 | -<template> | ||
2 | - <div ref="chartRef" :style="{ width: '100%' }"></div> | ||
3 | -</template> | ||
4 | -<script lang="ts"> | ||
5 | - import { defineComponent, Ref, ref, onMounted } from 'vue'; | ||
6 | - | ||
7 | - import { useApexCharts } from '/@/hooks/web/useApexCharts'; | ||
8 | - | ||
9 | - export default defineComponent({ | ||
10 | - setup() { | ||
11 | - const chartRef = ref<HTMLDivElement | null>(null); | ||
12 | - const { setOptions } = useApexCharts(chartRef as Ref<HTMLDivElement>); | ||
13 | - onMounted(() => { | ||
14 | - setOptions({ | ||
15 | - series: [ | ||
16 | - { name: 'Visits', data: [90, 50, 86, 40, 100, 20] }, | ||
17 | - { name: 'Sales', data: [70, 75, 70, 76, 20, 85] }, | ||
18 | - ], | ||
19 | - chart: { | ||
20 | - height: 350, | ||
21 | - type: 'radar', | ||
22 | - toolbar: { | ||
23 | - show: false, | ||
24 | - }, | ||
25 | - }, | ||
26 | - yaxis: { | ||
27 | - show: false, | ||
28 | - }, | ||
29 | - | ||
30 | - title: { | ||
31 | - show: false, | ||
32 | - }, | ||
33 | - markers: { | ||
34 | - // size: 0, | ||
35 | - }, | ||
36 | - xaxis: { | ||
37 | - categories: ['2016', '2017', '2018', '2019', '2020', '2021'], | ||
38 | - }, | ||
39 | - stroke: { | ||
40 | - width: 0, | ||
41 | - }, | ||
42 | - colors: ['#9f8ed7', '#1edec5'], | ||
43 | - | ||
44 | - fill: { | ||
45 | - type: 'gradient', | ||
46 | - gradient: { | ||
47 | - shade: 'dark', | ||
48 | - gradientToColors: ['#8e9ad6', '#1fcadb'], | ||
49 | - shadeIntensity: 1, | ||
50 | - type: 'horizontal', | ||
51 | - opacityFrom: 1, | ||
52 | - opacityTo: 1, | ||
53 | - stops: [0, 100, 100, 100], | ||
54 | - }, | ||
55 | - }, | ||
56 | - }); | ||
57 | - }); | ||
58 | - return { chartRef }; | ||
59 | - }, | ||
60 | - }); | ||
61 | -</script> |
src/views/demo/charts/apex/index.vue deleted
100644 → 0
1 | -<template> | ||
2 | - <div class="apex-demo p-4"> | ||
3 | - <div class="demo-box"> | ||
4 | - <Line /> | ||
5 | - </div> | ||
6 | - <div class="demo-box"> | ||
7 | - <Bar /> | ||
8 | - </div> | ||
9 | - <div class="demo-box"> | ||
10 | - <Area /> | ||
11 | - </div> | ||
12 | - <div class="demo-box"> | ||
13 | - <Mixed /> | ||
14 | - </div> | ||
15 | - <div class="demo-box"> | ||
16 | - <SaleRadar /> | ||
17 | - </div> | ||
18 | - </div> | ||
19 | -</template> | ||
20 | -<script> | ||
21 | - import { defineComponent } from 'vue'; | ||
22 | - | ||
23 | - import Line from './Line.vue'; | ||
24 | - import Bar from './Bar.vue'; | ||
25 | - import Area from './Area.vue'; | ||
26 | - import Mixed from './Mixed.vue'; | ||
27 | - import SaleRadar from './SaleRadar.vue'; | ||
28 | - export default defineComponent({ | ||
29 | - components: { Line, Bar, Area, Mixed, SaleRadar }, | ||
30 | - setup() {}, | ||
31 | - }); | ||
32 | -</script> | ||
33 | -<style lang="less" scoped> | ||
34 | - .apex-demo { | ||
35 | - display: flex; | ||
36 | - flex-wrap: wrap; | ||
37 | - justify-content: space-between; | ||
38 | - | ||
39 | - .demo-box { | ||
40 | - width: 49%; | ||
41 | - margin-bottom: 20px; | ||
42 | - background: #fff; | ||
43 | - border-radius: 10px; | ||
44 | - } | ||
45 | - } | ||
46 | -</style> |
src/views/demo/comp/lazy/Transition.vue
@@ -29,7 +29,7 @@ | @@ -29,7 +29,7 @@ | ||
29 | height: 2000px; | 29 | height: 2000px; |
30 | margin: 20px auto; | 30 | margin: 20px auto; |
31 | text-align: center; | 31 | text-align: center; |
32 | - background: #fff; | 32 | + background: @component-background; |
33 | justify-content: center; | 33 | justify-content: center; |
34 | flex-direction: column; | 34 | flex-direction: column; |
35 | align-items: center; | 35 | align-items: center; |
src/views/demo/comp/lazy/index.vue
@@ -33,7 +33,7 @@ | @@ -33,7 +33,7 @@ | ||
33 | height: 2000px; | 33 | height: 2000px; |
34 | margin: 20px auto; | 34 | margin: 20px auto; |
35 | text-align: center; | 35 | text-align: center; |
36 | - background: #fff; | 36 | + background: @component-background; |
37 | justify-content: center; | 37 | justify-content: center; |
38 | flex-direction: column; | 38 | flex-direction: column; |
39 | align-items: center; | 39 | align-items: center; |
src/views/demo/comp/scroll/Action.vue
src/views/demo/comp/scroll/VirtualScroll.vue
@@ -50,7 +50,7 @@ | @@ -50,7 +50,7 @@ | ||
50 | &-wrap { | 50 | &-wrap { |
51 | display: flex; | 51 | display: flex; |
52 | margin: 0 30%; | 52 | margin: 0 30%; |
53 | - background: #fff; | 53 | + background: @component-background; |
54 | justify-content: center; | 54 | justify-content: center; |
55 | } | 55 | } |
56 | 56 | ||
@@ -58,7 +58,7 @@ | @@ -58,7 +58,7 @@ | ||
58 | height: 40px; | 58 | height: 40px; |
59 | padding: 0 20px; | 59 | padding: 0 20px; |
60 | line-height: 40px; | 60 | line-height: 40px; |
61 | - border-bottom: 1px solid #ddd; | 61 | + border-bottom: 1px solid @border-color-base; |
62 | } | 62 | } |
63 | } | 63 | } |
64 | </style> | 64 | </style> |
src/views/demo/comp/scroll/index.vue
src/views/demo/comp/strength-meter/index.vue
@@ -26,7 +26,7 @@ | @@ -26,7 +26,7 @@ | ||
26 | <style lang="less" scoped> | 26 | <style lang="less" scoped> |
27 | .demo-wrap { | 27 | .demo-wrap { |
28 | width: 50%; | 28 | width: 50%; |
29 | - background: #fff; | 29 | + background: @component-background; |
30 | border-radius: 10px; | 30 | border-radius: 10px; |
31 | } | 31 | } |
32 | </style> | 32 | </style> |
src/views/demo/feat/tab-params/index.vue
@@ -3,17 +3,18 @@ | @@ -3,17 +3,18 @@ | ||
3 | Current Param : {{ params }} | 3 | Current Param : {{ params }} |
4 | <br /> | 4 | <br /> |
5 | Keep Alive | 5 | Keep Alive |
6 | - <input /> | 6 | + <Input /> |
7 | </PageWrapper> | 7 | </PageWrapper> |
8 | </template> | 8 | </template> |
9 | <script lang="ts"> | 9 | <script lang="ts"> |
10 | import { computed, defineComponent, unref } from 'vue'; | 10 | import { computed, defineComponent, unref } from 'vue'; |
11 | import { useRouter } from 'vue-router'; | 11 | import { useRouter } from 'vue-router'; |
12 | import { PageWrapper } from '/@/components/Page'; | 12 | import { PageWrapper } from '/@/components/Page'; |
13 | + import { Input } from 'ant-design-vue'; | ||
13 | 14 | ||
14 | export default defineComponent({ | 15 | export default defineComponent({ |
15 | name: 'TestTab', | 16 | name: 'TestTab', |
16 | - components: { PageWrapper }, | 17 | + components: { PageWrapper, Input }, |
17 | setup() { | 18 | setup() { |
18 | const { currentRoute } = useRouter(); | 19 | const { currentRoute } = useRouter(); |
19 | return { | 20 | return { |
src/views/demo/level/Menu111.vue
@@ -2,10 +2,11 @@ | @@ -2,10 +2,11 @@ | ||
2 | <div class="p-5"> | 2 | <div class="p-5"> |
3 | 多层级缓存-页面1-1-1 | 3 | 多层级缓存-页面1-1-1 |
4 | <br /> | 4 | <br /> |
5 | - <input /> | 5 | + <Input /> |
6 | </div> | 6 | </div> |
7 | </template> | 7 | </template> |
8 | <script lang="ts"> | 8 | <script lang="ts"> |
9 | import { defineComponent } from 'vue'; | 9 | import { defineComponent } from 'vue'; |
10 | - export default defineComponent({ name: 'Menu111Demo' }); | 10 | + import { Input } from 'ant-design-vue'; |
11 | + export default defineComponent({ name: 'Menu111Demo', components: { Input } }); | ||
11 | </script> | 12 | </script> |
src/views/demo/level/Menu12.vue
@@ -2,10 +2,11 @@ | @@ -2,10 +2,11 @@ | ||
2 | <div class="p-5"> | 2 | <div class="p-5"> |
3 | 多层级缓存-页面1-2 | 3 | 多层级缓存-页面1-2 |
4 | <br /> | 4 | <br /> |
5 | - <input /> | 5 | + <Input /> |
6 | </div> | 6 | </div> |
7 | </template> | 7 | </template> |
8 | <script lang="ts"> | 8 | <script lang="ts"> |
9 | import { defineComponent } from 'vue'; | 9 | import { defineComponent } from 'vue'; |
10 | - export default defineComponent({ name: 'Menu12Demo' }); | 10 | + import { Input } from 'ant-design-vue'; |
11 | + export default defineComponent({ name: 'Menu12Demo', components: { Input } }); | ||
11 | </script> | 12 | </script> |
src/views/demo/level/Menu2.vue
@@ -2,12 +2,14 @@ | @@ -2,12 +2,14 @@ | ||
2 | <div class="p-5"> | 2 | <div class="p-5"> |
3 | 多层级缓存-页面2 | 3 | 多层级缓存-页面2 |
4 | <br /> | 4 | <br /> |
5 | - <input /> | 5 | + <Input /> |
6 | </div> | 6 | </div> |
7 | </template> | 7 | </template> |
8 | <script lang="ts"> | 8 | <script lang="ts"> |
9 | import { defineComponent } from 'vue'; | 9 | import { defineComponent } from 'vue'; |
10 | + import { Input } from 'ant-design-vue'; | ||
10 | export default defineComponent({ | 11 | export default defineComponent({ |
11 | name: 'Menu2Demo', | 12 | name: 'Menu2Demo', |
13 | + components: { Input }, | ||
12 | }); | 14 | }); |
13 | </script> | 15 | </script> |
src/views/demo/page/account/center/Application.vue
@@ -64,7 +64,6 @@ | @@ -64,7 +64,6 @@ | ||
64 | margin-bottom: 5px; | 64 | margin-bottom: 5px; |
65 | font-size: 16px; | 65 | font-size: 16px; |
66 | font-weight: 500; | 66 | font-weight: 500; |
67 | - color: rgba(0, 0, 0, 0.85); | ||
68 | 67 | ||
69 | .icon { | 68 | .icon { |
70 | margin-top: -5px; | 69 | margin-top: -5px; |
@@ -75,19 +74,18 @@ | @@ -75,19 +74,18 @@ | ||
75 | &-num { | 74 | &-num { |
76 | margin-left: 24px; | 75 | margin-left: 24px; |
77 | line-height: 36px; | 76 | line-height: 36px; |
78 | - color: #7d7a7a; | 77 | + color: @text-color-secondary; |
79 | 78 | ||
80 | span { | 79 | span { |
81 | margin-left: 5px; | 80 | margin-left: 5px; |
82 | font-size: 18px; | 81 | font-size: 18px; |
83 | - color: #000; | ||
84 | } | 82 | } |
85 | } | 83 | } |
86 | 84 | ||
87 | &-download { | 85 | &-download { |
88 | float: right; | 86 | float: right; |
89 | font-size: 20px !important; | 87 | font-size: 20px !important; |
90 | - color: #1890ff; | 88 | + color: @primary-color; |
91 | } | 89 | } |
92 | } | 90 | } |
93 | } | 91 | } |
src/views/demo/page/account/center/index.vue
@@ -102,7 +102,7 @@ | @@ -102,7 +102,7 @@ | ||
102 | &-top { | 102 | &-top { |
103 | padding: 10px; | 103 | padding: 10px; |
104 | margin: 16px 16px 12px 16px; | 104 | margin: 16px 16px 12px 16px; |
105 | - background: #fff; | 105 | + background: @component-background; |
106 | border-radius: 3px; | 106 | border-radius: 3px; |
107 | 107 | ||
108 | &__avatar { | 108 | &__avatar { |
@@ -144,7 +144,7 @@ | @@ -144,7 +144,7 @@ | ||
144 | &-bottom { | 144 | &-bottom { |
145 | padding: 10px; | 145 | padding: 10px; |
146 | margin: 0 16px 16px 16px; | 146 | margin: 0 16px 16px 16px; |
147 | - background: #fff; | 147 | + background: @component-background; |
148 | border-radius: 3px; | 148 | border-radius: 3px; |
149 | } | 149 | } |
150 | } | 150 | } |
src/views/demo/page/account/setting/index.vue
@@ -48,14 +48,14 @@ | @@ -48,14 +48,14 @@ | ||
48 | <style lang="less"> | 48 | <style lang="less"> |
49 | .account-setting { | 49 | .account-setting { |
50 | margin: 12px; | 50 | margin: 12px; |
51 | - background: #fff; | 51 | + background: @component-background; |
52 | 52 | ||
53 | .base-title { | 53 | .base-title { |
54 | padding-left: 0; | 54 | padding-left: 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | .ant-tabs-tab-active { | 57 | .ant-tabs-tab-active { |
58 | - background-color: #e6f7ff; | 58 | + background-color: @item-active-bg; |
59 | } | 59 | } |
60 | } | 60 | } |
61 | </style> | 61 | </style> |
src/views/demo/page/desc/basic/index.vue
src/views/demo/page/form/basic/index.vue
src/views/demo/page/form/step/Step1.vue
@@ -78,18 +78,18 @@ | @@ -78,18 +78,18 @@ | ||
78 | margin: 0 0 12px; | 78 | margin: 0 0 12px; |
79 | font-size: 16px; | 79 | font-size: 16px; |
80 | line-height: 32px; | 80 | line-height: 32px; |
81 | - color: rgba(0, 0, 0, 0.45); | 81 | + color: @text-color; |
82 | } | 82 | } |
83 | 83 | ||
84 | h4 { | 84 | h4 { |
85 | margin: 0 0 4px; | 85 | margin: 0 0 4px; |
86 | font-size: 14px; | 86 | font-size: 14px; |
87 | line-height: 22px; | 87 | line-height: 22px; |
88 | - color: rgba(0, 0, 0, 0.45); | 88 | + color: @text-color; |
89 | } | 89 | } |
90 | 90 | ||
91 | p { | 91 | p { |
92 | - color: rgba(0, 0, 0, 0.45); | 92 | + color: @text-color; |
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 |
src/views/demo/page/form/step/Step3.vue
src/views/demo/page/form/step/index.vue
@@ -85,7 +85,7 @@ | @@ -85,7 +85,7 @@ | ||
85 | <style lang="less" scoped> | 85 | <style lang="less" scoped> |
86 | .step-form-content { | 86 | .step-form-content { |
87 | padding: 24px; | 87 | padding: 24px; |
88 | - background: #fff; | 88 | + background: @component-background; |
89 | } | 89 | } |
90 | 90 | ||
91 | .step-form-form { | 91 | .step-form-form { |
src/views/demo/page/list/basic/index.vue
@@ -86,25 +86,25 @@ | @@ -86,25 +86,25 @@ | ||
86 | &__top { | 86 | &__top { |
87 | padding: 24px; | 87 | padding: 24px; |
88 | text-align: center; | 88 | text-align: center; |
89 | - background: #fff; | 89 | + background: @component-background; |
90 | 90 | ||
91 | &-col { | 91 | &-col { |
92 | &:not(:last-child) { | 92 | &:not(:last-child) { |
93 | - border-right: 1px dashed rgba(206, 206, 206, 0.4); | 93 | + border-right: 1px dashed @border-color-base; |
94 | } | 94 | } |
95 | 95 | ||
96 | div { | 96 | div { |
97 | margin-bottom: 12px; | 97 | margin-bottom: 12px; |
98 | font-size: 14px; | 98 | font-size: 14px; |
99 | line-height: 22px; | 99 | line-height: 22px; |
100 | - color: rgba(0, 0, 0, 0.45); | 100 | + color: @text-color; |
101 | } | 101 | } |
102 | 102 | ||
103 | p { | 103 | p { |
104 | margin: 0; | 104 | margin: 0; |
105 | font-size: 24px; | 105 | font-size: 24px; |
106 | line-height: 32px; | 106 | line-height: 32px; |
107 | - color: rgba(0, 0, 0, 0.85); | 107 | + color: @text-color; |
108 | } | 108 | } |
109 | } | 109 | } |
110 | } | 110 | } |
@@ -112,7 +112,7 @@ | @@ -112,7 +112,7 @@ | ||
112 | &__content { | 112 | &__content { |
113 | padding: 24px; | 113 | padding: 24px; |
114 | margin-top: 12px; | 114 | margin-top: 12px; |
115 | - background: #fff; | 115 | + background: @component-background; |
116 | 116 | ||
117 | .list { | 117 | .list { |
118 | position: relative; | 118 | position: relative; |
@@ -127,7 +127,7 @@ | @@ -127,7 +127,7 @@ | ||
127 | top: 20px; | 127 | top: 20px; |
128 | right: 15px; | 128 | right: 15px; |
129 | font-weight: normal; | 129 | font-weight: normal; |
130 | - color: #1890ff; | 130 | + color: @primary-color; |
131 | cursor: pointer; | 131 | cursor: pointer; |
132 | } | 132 | } |
133 | 133 |
src/views/demo/page/list/card/index.vue
@@ -84,7 +84,7 @@ | @@ -84,7 +84,7 @@ | ||
84 | margin-bottom: 5px; | 84 | margin-bottom: 5px; |
85 | font-size: 16px; | 85 | font-size: 16px; |
86 | font-weight: 500; | 86 | font-weight: 500; |
87 | - color: rgba(0, 0, 0, 0.85); | 87 | + color: @text-color; |
88 | 88 | ||
89 | .icon { | 89 | .icon { |
90 | margin-top: -5px; | 90 | margin-top: -5px; |
@@ -97,7 +97,7 @@ | @@ -97,7 +97,7 @@ | ||
97 | padding-top: 10px; | 97 | padding-top: 10px; |
98 | padding-left: 30px; | 98 | padding-left: 30px; |
99 | font-size: 14px; | 99 | font-size: 14px; |
100 | - color: rgba(0, 0, 0, 0.5); | 100 | + color: @text-color-secondary; |
101 | } | 101 | } |
102 | } | 102 | } |
103 | } | 103 | } |
src/views/demo/page/list/search/index.vue
@@ -91,7 +91,7 @@ | @@ -91,7 +91,7 @@ | ||
91 | 91 | ||
92 | &__container { | 92 | &__container { |
93 | padding: 12px; | 93 | padding: 12px; |
94 | - background: #fff; | 94 | + background: @component-background; |
95 | } | 95 | } |
96 | 96 | ||
97 | &__title { | 97 | &__title { |
@@ -100,7 +100,7 @@ | @@ -100,7 +100,7 @@ | ||
100 | } | 100 | } |
101 | 101 | ||
102 | &__content { | 102 | &__content { |
103 | - color: rgba(0, 0, 0, 0.65); | 103 | + color: @text-color-secondary; |
104 | } | 104 | } |
105 | 105 | ||
106 | &__action { | 106 | &__action { |
@@ -109,7 +109,7 @@ | @@ -109,7 +109,7 @@ | ||
109 | &-item { | 109 | &-item { |
110 | display: inline-block; | 110 | display: inline-block; |
111 | padding: 0 16px; | 111 | padding: 0 16px; |
112 | - color: rgba(0, 0, 0, 0.45); | 112 | + color: @text-color-secondary; |
113 | 113 | ||
114 | &:nth-child(1) { | 114 | &:nth-child(1) { |
115 | padding-left: 0; | 115 | padding-left: 0; |
@@ -117,7 +117,7 @@ | @@ -117,7 +117,7 @@ | ||
117 | 117 | ||
118 | &:nth-child(1), | 118 | &:nth-child(1), |
119 | &:nth-child(2) { | 119 | &:nth-child(2) { |
120 | - border-right: 1px solid rgba(206, 206, 206, 0.4); | 120 | + border-right: 1px solid @border-color-base; |
121 | } | 121 | } |
122 | } | 122 | } |
123 | 123 |
src/views/demo/page/result/fail/index.vue
@@ -34,17 +34,16 @@ | @@ -34,17 +34,16 @@ | ||
34 | <style lang="less" scoped> | 34 | <style lang="less" scoped> |
35 | .result-error { | 35 | .result-error { |
36 | padding: 48px 32px; | 36 | padding: 48px 32px; |
37 | - background: #fff; | 37 | + background: @component-background; |
38 | 38 | ||
39 | &__content { | 39 | &__content { |
40 | padding: 24px 40px; | 40 | padding: 24px 40px; |
41 | - background: #fafafa; | 41 | + background: @background-color-light; |
42 | 42 | ||
43 | &-title { | 43 | &-title { |
44 | margin-bottom: 16px; | 44 | margin-bottom: 16px; |
45 | font-size: 16px; | 45 | font-size: 16px; |
46 | font-weight: 500; | 46 | font-weight: 500; |
47 | - color: rgba(0, 0, 0, 0.85); | ||
48 | } | 47 | } |
49 | 48 | ||
50 | &-icon { | 49 | &-icon { |
src/views/demo/page/result/success/index.vue
@@ -48,11 +48,11 @@ | @@ -48,11 +48,11 @@ | ||
48 | <style lang="less" scoped> | 48 | <style lang="less" scoped> |
49 | .result-success { | 49 | .result-success { |
50 | padding: 48px 32px; | 50 | padding: 48px 32px; |
51 | - background: #fff; | 51 | + background: @component-background; |
52 | 52 | ||
53 | &__content { | 53 | &__content { |
54 | padding: 24px 40px; | 54 | padding: 24px 40px; |
55 | - background: #fafafa; | 55 | + background: @background-color-light; |
56 | } | 56 | } |
57 | } | 57 | } |
58 | </style> | 58 | </style> |
src/views/demo/permission/back/Btn.vue
src/views/demo/permission/back/index.vue