Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d7ca354

Browse files
feat: implement theme toggling and enhance Button styles with new color variables
1 parent 428fdfc commit d7ca354

File tree

8 files changed

+144
-132
lines changed

8 files changed

+144
-132
lines changed

‎apps/playground/src/App.vue‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
<template>
2-
<RouterView></RouterView>
2+
<button @click="toggleTheme" class="fixed top-2 right-2">toggle {{ appearance }}</button>
3+
<a-theme :appearance="appearance">
4+
<RouterView />
5+
</a-theme>
36
</template>
7+
<script setup lang="ts">
8+
import { ref } from 'vue'
9+
10+
const appearance = ref('light')
11+
12+
const toggleTheme = () => {
13+
appearance.value = appearance.value === 'light' ? 'dark' : 'light'
14+
}
15+
</script>

‎packages/ui/src/components/button/Button.vue‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { buttonProps, buttonEmits, ButtonSlots } from './meta'
1414
import { getCssVarColor } from '@/utils/colorAlgorithm'
1515
import { useThemeInject } from '../theme/hook'
1616
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined'
17+
import { defaultColor } from '../theme/meta'
1718
1819
const props = defineProps(buttonProps)
1920
@@ -28,7 +29,7 @@ const color = computed(() => {
2829
}
2930
3031
if (props.danger) {
31-
return theme.dangerColor
32+
return 'red'
3233
}
3334
3435
return theme.primaryColor
@@ -46,7 +47,12 @@ const rootClass = computed(() => {
4647
}
4748
})
4849
const cssVars = computed(() => {
49-
return getCssVarColor(color.value)
50+
return color.value.toLowerCase() !== defaultColor.toLowerCase()
51+
? getCssVarColor(color.value, {
52+
appearance: theme.appearance,
53+
backgroundColor: theme.backgroundColor,
54+
})
55+
: {}
5056
})
5157
5258
const handleClick = (event: MouseEvent) => {

‎packages/ui/src/components/button/style/index.css‎

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,40 @@
1111
}
1212

1313
&:where(.ant-btn-solid:not(:disabled)) {
14-
@apply border-none bg-[var(--accent-color)] text-[var(--accent-color-content)];
15-
@apply hover:bg-[var(--accent-color-hover)] active:bg-[var(--accent-color-active)];
14+
@apply bg-accent text-accent-content border-none;
15+
@apply hover:bg-accent-hover active:bg-accent-active;
1616
}
1717
&:where(.ant-btn-outlined:not(:disabled)),
1818
&:where(.ant-btn-dashed:not(:disabled)) {
19-
@apply border-[var(--accent-color)] bg-transparent text-[var(--accent-color)];
20-
@apply hover:text-[var(--accent-color-hover)] active:border-[var(--accent-color-active)] active:text-[var(--accent-color-active)];
21-
@apply border-[var(--accent-color-active)] hover:border-[var(--accent-color-hover)];
19+
@apply border-accenttext-accent bg-transparent;
20+
@apply hover:text-accent-hover active:border-accent-active active:text-accent-active;
21+
@apply border-accent-active hover:border-accent-hover;
2222
}
2323
&:where(.ant-btn-text:not(.ant-btn-custom-color):not(:disabled)) {
24-
@apply border-none bg-transparent text-[var(--neutral-color)];
25-
@apply hover:bg-[var(--neutral-disabled-bg)];
24+
@apply text-neutral border-none bg-transparent;
25+
@apply hover:bg-neutral-disabled-bg;
2626
}
2727
&:where(.ant-btn-text.ant-btn-custom-color:not(:disabled)) {
28-
@apply border-none bg-transparent text-[var(--accent-color)];
29-
@apply hover:bg-[var(--accent-color-1)] hover:text-[var(--accent-color-hover)];
28+
@apply text-accent border-none bg-transparent;
29+
@apply hover:bg-accent-1 hover:text-accent-hover;
3030
}
3131

3232
&:where(.ant-btn-link:not(:disabled)) {
33-
@apply border-none bg-transparent text-[var(--accent-color)] hover:text-[var(--accent-color-hover)];
33+
@apply text-accent border-none bg-transparent;
34+
@apply hover:text-accent-hover;
3435
}
3536
&:where(.ant-btn-dashed) {
3637
@apply border-dashed;
3738
}
3839
&:where(.ant-btn-filled:not(:disabled)) {
39-
@apply border-none bg-[var(--accent-color-1)] text-[var(--accent-color)] hover:text-[var(--accent-color-hover)];
40-
@apply hover:bg-[var(--accent-color-2)] active:bg-[var(--accent-color-3)] active:text-[var(--accent-color-active)];
40+
@apply text-accent bg-accent-1 border-none;
41+
@apply hover:bg-accent-2 active:bg-accent-3 active:text-accent-active;
42+
@apply hover:text-accent-hover;
4143
}
4244

4345
&:where(.ant-btn-disabled) {
4446
@apply cursor-not-allowed;
45-
@apply border-[var(--neutral-border)] bg-[var(--neutral-disabled-bg)] text-[var(--neutral-disabled)];
47+
@apply text-neutral-disabled bg-neutral-disabled-bg border-neutral-border;
4648
}
4749
&:where(.ant-btn-disabled.ant-btn-text),
4850
&:where(.ant-btn-disabled.ant-btn-link) {

‎packages/ui/src/components/theme/Theme.vue‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,30 @@
55
<script setup lang="ts">
66
import { themeProps } from './meta'
77
import { useThemeProvide } from './hook'
8+
import { getCssVarColor } from '@/utils/colorAlgorithm'
9+
import { watchEffect } from 'vue'
810
911
const props = defineProps(themeProps)
1012
1113
useThemeProvide(props)
14+
15+
const style = document.createElement('style')
16+
watchEffect(() => {
17+
const cssVars = getCssVarColor(props.primaryColor, {
18+
appearance: props.appearance,
19+
backgroundColor: props.backgroundColor,
20+
})
21+
document.documentElement.classList.remove('light-theme', 'dark-theme')
22+
document.documentElement.classList.add(`${props.appearance}-theme`)
23+
style.textContent = `:root.${props.appearance}-theme {
24+
${Object.entries(cssVars)
25+
.map(([key, value]) => `${key}: ${value};`)
26+
.join('\n')}
27+
}`
28+
document.head.appendChild(style)
29+
30+
return () => {
31+
document.head.removeChild(style)
32+
}
33+
})
1234
</script>
Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
1-
import { inject, InjectionKey, provide, Reactive } from 'vue'
1+
import { inject, InjectionKey, provide } from 'vue'
2+
import { ThemeProps } from './meta'
23

3-
type ThemeType = Reactive<{
4-
appearance: 'light' | 'dark'
5-
primaryColor: string
6-
dangerColor: string
7-
}>
8-
9-
const ThemeSymbol: InjectionKey<ThemeType> = Symbol('theme')
4+
const ThemeSymbol: InjectionKey<ThemeProps> = Symbol('theme')
105

116
export const useThemeInject = () => {
127
return inject(ThemeSymbol, {
138
appearance: 'light',
149
primaryColor: '#1677ff',
1510
dangerColor: '#ff4d4f',
16-
})
11+
darkBackgroundColor: '#141414',
12+
} as ThemeProps)
1713
}
1814

19-
export const useThemeProvide = (theme: ThemeType) => {
15+
export const useThemeProvide = (theme: ThemeProps) => {
2016
provide(ThemeSymbol, theme)
2117
}

‎packages/ui/src/components/theme/meta.ts‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { PropType, ExtractPublicPropTypes } from 'vue'
22

3+
export const defaultColor = '#1677FF'
34
// Theme Props
45
export const themeProps = {
56
/**
@@ -16,15 +17,15 @@ export const themeProps = {
1617
*/
1718
primaryColor: {
1819
type: String,
19-
default: '#1677FF',
20+
default: defaultColor,
2021
},
2122
/**
22-
* Specifies the danger color of the component
23-
* @default '#ff4d4f'
23+
* Specifies the background color of the component, only used in dark mode
24+
* @default '#141414'
2425
*/
25-
dangerColor: {
26+
backgroundColor: {
2627
type: String,
27-
default: '#ff4d4f',
28+
default: '#141414',
2829
},
2930
} as const
3031

‎packages/ui/src/style/base.css‎

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,33 @@
11
@theme static {
2-
--color-base-100: #ffffff;
3-
--color-base-200: #f7f7f7;
4-
--color-base-300: #ededed;
5-
--color-base-content: #222222;
6-
--color-primary: #151415;
7-
--color-primary-content: #ffffff;
8-
--color-secondary: #0d58fc;
9-
--color-secondary-content: #ffffff;
10-
--color-accent: #0289ff;
2+
--color-accent-1: #e6f4ff;
3+
--color-accent-2: #bae0ff;
4+
--color-accent-3: #91caff;
5+
--color-accent-4: #69b1ff;
6+
--color-accent-5: #4096ff;
7+
--color-accent-6: #1677ff;
8+
--color-accent-7: #0958d9;
9+
--color-accent-8: #003eb3;
10+
--color-accent-9: #002c8c;
11+
--color-accent-10: #001d66;
12+
--color-accent: #1677ff;
13+
--color-accent-hover: #4096ff;
14+
--color-accent-active: #0958d9;
1115
--color-accent-content: #ffffff;
12-
--color-neutral: #666666;
13-
--color-neutral-content: #ffffff;
14-
--color-info: #0d58fc;
15-
--color-info-content: #ffffff;
16-
--color-success: #00c573;
17-
--color-success-content: #ffffff;
18-
--color-warning: #ff9900;
19-
--color-warning-content: #ffffff;
20-
--color-error: #ff3333;
21-
--color-error-content: #ffffff;
2216

23-
--neutral-color: #000000e0;
24-
--neutral-secondary: #000000a6;
25-
--neutral-disabled: #00000040;
26-
--neutral-border: #d9d9d9;
27-
--neutral-separator: #0505050f;
28-
--neutral-bg: #f5f5f5;
17+
--color-neutral: #000000e0;
18+
--color-neutral-secondary: #000000a6;
19+
--color-neutral-disabled: #00000040;
20+
--color-neutral-disabled-bg: #0000000a;
21+
--color-neutral-border: #d9d9d9;
22+
--color-neutral-separator: #0505050f;
23+
--color-neutral-bg: #f5f5f5;
24+
25+
--color-error: #ff4d4f;
26+
--color-warning: #faad14;
27+
--color-success: #52c41a;
28+
--color-info: #1677ff;
29+
}
30+
31+
.dark-theme {
32+
background-color: #141414;
2933
}
Lines changed: 45 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,41 @@
11
import { TinyColor } from '@ctrl/tinycolor'
22
import { generate, presetPalettes, presetDarkPalettes } from '@ant-design/colors'
33

4-
export const getAlphaColor = (baseColor: string, alpha: number) =>
5-
new TinyColor(baseColor).setAlpha(alpha).toRgbString()
6-
7-
export const getSolidColor = (baseColor: string, brightness: number) => {
8-
const instance = new TinyColor(baseColor)
9-
return instance.darken(brightness).toHexString()
10-
}
11-
12-
export const getTintColor = (baseColor: string, tintNumber: number) => {
13-
return new TinyColor(baseColor).tint(tintNumber).toString()
14-
}
15-
16-
export const getShadeColor = (baseColor: string, shadeNumber: number) => {
17-
return new TinyColor(baseColor).shade(shadeNumber).toString()
18-
}
19-
204
export const getLightNeutralColor = () => {
215
return {
22-
'--neutral-color': '#000000e0',
23-
'--neutral-secondary': '#000000a6',
24-
'--neutral-disabled': '#00000040',
25-
'--neutral-disabled-bg': '#0000000a',
26-
'--neutral-border': '#d9d9d9',
27-
'--neutral-separator': '#0505050f',
28-
'--neutral-bg': '#f5f5f5',
6+
'--color-neutral': '#000000e0',
7+
'--color-neutral-secondary': '#000000a6',
8+
'--color-neutral-disabled': '#00000040',
9+
'--color-neutral-disabled-bg': '#0000000a',
10+
'--color-neutral-border': '#d9d9d9',
11+
'--color-neutral-separator': '#0505050f',
12+
'--color-neutral-bg': '#f5f5f5',
2913
}
3014
}
3115

3216
export const getDarkNeutralColor = () => {
3317
return {
34-
'--neutral-color': '#FFFFFFD9',
35-
'--neutral-secondary': '#FFFFFFA6',
36-
'--neutral-disabled': '#FFFFFF40',
37-
'--neutral-disabled-bg': 'rgba(255, 255, 255, 0.08)',
38-
'--neutral-border': '#424242',
39-
'--neutral-separator': '#FDFDFD1F',
40-
'--neutral-bg': '#000000',
18+
'--color-neutral': '#FFFFFFD9',
19+
'--color-neutral-secondary': '#FFFFFFA6',
20+
'--color-neutral-disabled': '#FFFFFF40',
21+
'--color-neutral-disabled-bg': 'rgba(255, 255, 255, 0.08)',
22+
'--color-neutral-border': '#424242',
23+
'--color-neutral-separator': '#FDFDFD1F',
24+
'--color-neutral-bg': '#000000',
4125
}
4226
}
4327

28+
const cacheColors = new Map<string, Record<string, string>>()
29+
4430
export const getCssVarColor = (
4531
baseColor: string,
46-
opts?: { appearance: 'light' | 'dark'; backgroundColor: string },
32+
opts: { appearance: 'light' | 'dark'; backgroundColor: string },
4733
) => {
48-
const { appearance = 'light', backgroundColor = '#141414' } = opts || {}
34+
const { appearance = 'light', backgroundColor = '#141414' } = opts
35+
const cacheKey = `${baseColor}-${appearance}-${backgroundColor}`
36+
if (cacheColors.has(cacheKey)) {
37+
return cacheColors.get(cacheKey)
38+
}
4939
const color = new TinyColor(baseColor)
5040
const preset = appearance === 'dark' ? presetDarkPalettes : presetPalettes
5141
const colors =
@@ -55,50 +45,29 @@ export const getCssVarColor = (
5545
appearance === 'dark' ? { theme: appearance, backgroundColor } : undefined,
5646
)
5747
const accentColor = colors[5]
58-
return {
59-
'--accent-color-1': colors[0],
60-
'--accent-color-2': colors[1],
61-
'--accent-color-3': colors[2],
62-
'--accent-color-4': colors[3],
63-
'--accent-color-5': colors[4],
64-
'--accent-color-6': colors[5],
65-
'--accent-color-7': colors[6],
66-
'--accent-color-8': colors[7],
67-
'--accent-color-9': colors[8],
68-
'--accent-color-10': colors[9],
69-
'--accent-color': accentColor,
70-
'--accent-color-hover': colors[4],
71-
'--accent-color-active': colors[5],
72-
'--accent-color-content': '#ffffff',
73-
...(appearance==='dark' ? getDarkNeutralColor() : getLightNeutralColor()),
74-
'--bg-color': baseColor,
75-
'--bg-color-hover': getTintColor(baseColor,10),
76-
'--bg-color-active': getTintColor(baseColor,20),
77-
'--bg-color-content': '#ffffff',
48+
constcssVars= {
49+
'--color-accent-1': colors[0],
50+
'--color-accent-2': colors[1],
51+
'--color-accent-3': colors[2],
52+
'--color-accent-4': colors[3],
53+
'--color-accent-5': colors[4],
54+
'--color-accent-6': colors[5],
55+
'--color-accent-7': colors[6],
56+
'--color-accent-8': colors[7],
57+
'--color-accent-9': colors[8],
58+
'--color-accent-10': colors[9],
59+
'--color-accent': accentColor,
60+
'--color-accent-hover': colors[4],
61+
'--color-accent-active': colors[6],
62+
'--color-accent-content': '#ffffff',
63+
64+
'--color-error': preset.red[4],
65+
'--color-warning': preset.yellow[4],
66+
'--color-success': preset.green[4],
67+
'--color-info': preset.blue[4],
7868

79-
'--border-color': baseColor,
80-
'--border-color-hover': getTintColor(baseColor, 10),
81-
'--border-color-active': getTintColor(baseColor, 20),
82-
'--border-color-tint-10': getTintColor(baseColor, 10),
83-
'--border-color-tint-20': getTintColor(baseColor, 20),
84-
'--border-color-tint-30': getTintColor(baseColor, 30),
85-
'--border-color-tint-40': getTintColor(baseColor, 40),
86-
'--border-color-tint-50': getTintColor(baseColor, 50),
87-
'--border-color-tint-60': getTintColor(baseColor, 60),
88-
'--border-color-tint-70': getTintColor(baseColor, 70),
89-
'--border-color-tint-80': getTintColor(baseColor, 80),
90-
'--border-color-tint-90': getTintColor(baseColor, 90),
91-
'--bg-color-tint-10': getTintColor(baseColor, 10),
92-
'--bg-color-tint-20': getTintColor(baseColor, 20),
93-
'--bg-color-tint-30': getTintColor(baseColor, 30),
94-
'--bg-color-tint-40': getTintColor(baseColor, 40),
95-
'--bg-color-tint-50': getTintColor(baseColor, 50),
96-
'--bg-color-tint-60': getTintColor(baseColor, 60),
97-
'--bg-color-tint-70': getTintColor(baseColor, 70),
98-
'--bg-color-tint-80': getTintColor(baseColor, 80),
99-
'--bg-color-tint-90': getTintColor(baseColor, 90),
100-
'--text-color': baseColor,
101-
'--text-color-hover': getTintColor(baseColor, 10),
102-
'--text-color-active': getTintColor(baseColor, 20),
69+
...(appearance === 'dark' ? getDarkNeutralColor() : getLightNeutralColor()),
10370
}
71+
cacheColors.set(cacheKey, cssVars)
72+
return cssVars
10473
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /