Skip to content

Commit a53db24

Browse files
committed
Improve live theme palette previews
1 parent 78f8b16 commit a53db24

3 files changed

Lines changed: 172 additions & 23 deletions

File tree

components/ThemeSwitch.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useGlobal } from '@/lib/global'
44
import { getQueryParam } from '@/lib/utils'
55
import { THEMES } from '@/themes/theme'
66
import { useRouter } from 'next/router'
7-
import { useEffect, useRef, useState } from 'react'
7+
import { useCallback, useEffect, useRef, useState } from 'react'
88
import { Draggable } from './Draggable'
99
import { Moon, Sun } from './HeroIcons'
1010
import LazyImage from './LazyImage'
@@ -148,6 +148,19 @@ function ThemeConsole ({ meta, onClose }) {
148148
return value
149149
}
150150

151+
const getConsoleAlias = useCallback(item => {
152+
const prefix = `${String(meta.id).toUpperCase()}_COLOR_`
153+
if (item.key.startsWith(prefix)) {
154+
return item.key.slice(prefix.length).toLowerCase().replace(/_/g, '-')
155+
}
156+
return String(item.cssVar || '').replace(/^--/, '').replace(`${meta.id}-`, '')
157+
}, [meta.id])
158+
159+
const writePreviewColor = useCallback((root, item, value) => {
160+
root.style.setProperty(item.cssVar, value)
161+
root.style.setProperty(`--${meta.id}-console-${getConsoleAlias(item)}`, value)
162+
}, [getConsoleAlias, meta.id])
163+
151164
const getExportValue = item => {
152165
const value = values[item.key] ?? item.defaultValue
153166
if (item.key === 'FUWARI_THEME_COLOR_HUE') return hexToHue(value)
@@ -170,10 +183,11 @@ function ThemeConsole ({ meta, onClose }) {
170183
declaredPalette.forEach(item => {
171184
nextValues[item.key] =
172185
styles.getPropertyValue(item.cssVar).trim() || item.defaultValue
186+
writePreviewColor(root, item, nextValues[item.key])
173187
})
174188
setPalette(declaredPalette)
175189
setValues(nextValues)
176-
}, [meta.id, meta.rootId, declaredPalette])
190+
}, [meta.id, meta.rootId, declaredPalette, writePreviewColor])
177191

178192
useEffect(() => () => window.clearTimeout(noticeTimerRef.current), [])
179193

@@ -189,7 +203,7 @@ function ThemeConsole ({ meta, onClose }) {
189203
const previewValue = getPreviewValue(item, value)
190204
setValues(prev => ({ ...prev, [item.key]: previewValue }))
191205
const root = getRoot()
192-
root.style.setProperty(item.cssVar, previewValue)
206+
writePreviewColor(root, item, previewValue)
193207
if (meta.id === 'fuwari' && item.cssVar === '--fuwari-primary') {
194208
root.style.setProperty('--fuwari-primary-soft', `color-mix(in oklab, ${previewValue} 14%, transparent)`)
195209
root.style.setProperty('--fuwari-gradient', `linear-gradient(135deg, ${previewValue} 0%, color-mix(in oklab, ${previewValue} 70%, #ffffff) 100%)`)

lib/themeConsoleStyle.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,111 @@ export function themeConsoleStyle(themeId, config, options = {}) {
2121
#${rootId} {
2222
${vars}
2323
--${themeId}-console-primary: var(${getThemeColorCssVar(themeId, 'PRIMARY')});
24+
--${themeId}-console-primary-hover: var(${getThemeColorCssVar(themeId, 'PRIMARY_HOVER')}, var(--${themeId}-console-primary));
2425
--${themeId}-console-bg: var(${getThemeColorCssVar(themeId, 'BG')});
2526
--${themeId}-console-card: var(${getThemeColorCssVar(themeId, 'CARD')});
2627
--${themeId}-console-text: var(${getThemeColorCssVar(themeId, 'TEXT')});
2728
--${themeId}-console-text-secondary: var(${getThemeColorCssVar(themeId, 'TEXT_SECONDARY')});
2829
--${themeId}-console-border: var(${getThemeColorCssVar(themeId, 'BORDER')});
30+
--${themeId}-console-dark: var(${getThemeColorCssVar(themeId, 'BG_DARK')});
2931
}
3032
3133
.dark #${rootId} {
3234
--${themeId}-console-primary: var(${getThemeColorCssVar(themeId, 'PRIMARY_DARK')});
35+
--${themeId}-console-primary-hover: var(${getThemeColorCssVar(themeId, 'PRIMARY_HOVER_DARK')}, var(--${themeId}-console-primary));
3336
--${themeId}-console-bg: var(${getThemeColorCssVar(themeId, 'BG_DARK')});
3437
--${themeId}-console-card: var(${getThemeColorCssVar(themeId, 'CARD_DARK')});
3538
--${themeId}-console-text: var(${getThemeColorCssVar(themeId, 'TEXT_DARK')});
3639
--${themeId}-console-text-secondary: var(${getThemeColorCssVar(themeId, 'TEXT_SECONDARY_DARK')});
3740
--${themeId}-console-border: var(${getThemeColorCssVar(themeId, 'BORDER_DARK')});
41+
--${themeId}-console-dark: var(${getThemeColorCssVar(themeId, 'BG_DARK')});
42+
}
43+
44+
#${rootId} {
45+
background-color: var(--${themeId}-console-bg);
46+
color: var(--${themeId}-console-text);
47+
}
48+
49+
#${rootId} [class~="bg-primary"],
50+
#${rootId} [class~="bg-blue-500"],
51+
#${rootId} [class~="bg-blue-600"],
52+
#${rootId} [class~="bg-indigo-500"],
53+
#${rootId} [class~="bg-indigo-600"],
54+
#${rootId} [class~="bg-red-500"],
55+
#${rootId} [class~="bg-red-600"],
56+
#${rootId} [class~="bg-green-500"],
57+
#${rootId} [class~="bg-green-600"] {
58+
background-color: var(--${themeId}-console-primary) !important;
59+
}
60+
61+
#${rootId} [class~="hover:bg-primary"]:hover,
62+
#${rootId} [class~="hover:bg-blue-dark"]:hover,
63+
#${rootId} [class*="hover:bg-blue-"]:hover,
64+
#${rootId} [class*="hover:bg-indigo-"]:hover,
65+
#${rootId} [class*="hover:bg-red-"]:hover,
66+
#${rootId} [class*="hover:bg-green-"]:hover {
67+
background-color: var(--${themeId}-console-primary-hover) !important;
68+
}
69+
70+
#${rootId} [class~="text-primary"],
71+
#${rootId} [class~="text-blue-500"],
72+
#${rootId} [class~="text-blue-600"],
73+
#${rootId} [class~="text-indigo-500"],
74+
#${rootId} [class~="text-indigo-600"],
75+
#${rootId} [class~="text-red-500"],
76+
#${rootId} [class~="text-red-600"],
77+
#${rootId} [class~="text-green-500"],
78+
#${rootId} [class~="text-green-600"],
79+
#${rootId} [class~="hover:text-primary"]:hover,
80+
#${rootId} [class*="hover:text-blue-"]:hover,
81+
#${rootId} [class*="hover:text-indigo-"]:hover,
82+
#${rootId} [class*="hover:text-red-"]:hover,
83+
#${rootId} [class*="hover:text-green-"]:hover,
84+
#${rootId} .group:hover [class~="group-hover:text-primary"] {
85+
color: var(--${themeId}-console-primary) !important;
86+
}
87+
88+
#${rootId} [class~="text-body-color"],
89+
#${rootId} [class~="text-body-secondary"],
90+
#${rootId} [class~="text-gray-500"],
91+
#${rootId} [class~="text-gray-600"],
92+
#${rootId} [class~="text-gray-400"] {
93+
color: var(--${themeId}-console-text-secondary) !important;
94+
}
95+
96+
#${rootId} [class~="bg-white"],
97+
#${rootId} [class~="bg-gray-50"],
98+
#${rootId} [class~="bg-gray-1"],
99+
#${rootId} [class~="dark:bg-dark-2"]:is(.dark *) {
100+
background-color: var(--${themeId}-console-card) !important;
101+
}
102+
103+
#${rootId} [class~="bg-dark"],
104+
#${rootId} [class~="dark:bg-dark"]:is(.dark *) {
105+
background-color: var(--${themeId}-console-dark) !important;
106+
}
107+
108+
#${rootId} [class~="border-primary"],
109+
#${rootId} [class*="border-blue-"],
110+
#${rootId} [class*="border-indigo-"],
111+
#${rootId} [class*="border-red-"],
112+
#${rootId} [class*="border-green-"],
113+
#${rootId} [class~="focus:border-primary"]:focus {
114+
border-color: var(--${themeId}-console-primary) !important;
115+
}
116+
117+
#${rootId} [class~="border"],
118+
#${rootId} [class*="border-gray-"] {
119+
border-color: var(--${themeId}-console-border);
120+
}
121+
122+
#${rootId} input:focus,
123+
#${rootId} textarea:focus,
124+
#${rootId} select:focus,
125+
#${rootId} [class~="ring-primary"],
126+
#${rootId} [class~="focus:ring-primary"]:focus {
127+
--tw-ring-color: var(--${themeId}-console-primary) !important;
128+
border-color: var(--${themeId}-console-primary) !important;
38129
}
39130
`
40131
}

themes/starter/style.js

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable react/no-unknown-property */
2-
import CONFIG from './config'
2+
import CONFIG, { starterConfig } from './config'
33
import { themeConsoleStyle } from '@/lib/themeConsoleStyle'
44

55
/**
@@ -8,8 +8,61 @@ import { themeConsoleStyle } from '@/lib/themeConsoleStyle'
88
* @returns
99
*/
1010
const Style = () => {
11+
const primary = starterConfig('STARTER_COLOR_PRIMARY', CONFIG.STARTER_COLOR_PRIMARY, CONFIG)
12+
const primaryHover = starterConfig('STARTER_COLOR_PRIMARY_HOVER', CONFIG.STARTER_COLOR_PRIMARY_HOVER, CONFIG)
13+
const dark = starterConfig('STARTER_COLOR_DARK', CONFIG.STARTER_COLOR_DARK, CONFIG)
14+
const textMuted = starterConfig('STARTER_COLOR_TEXT_MUTED', CONFIG.STARTER_COLOR_TEXT_MUTED, CONFIG)
15+
1116
return <style jsx global>{`
1217
18+
#theme-starter {
19+
--starter-color-primary: ${primary};
20+
--starter-color-primary-hover: ${primaryHover};
21+
--starter-color-dark: ${dark};
22+
--starter-color-text-muted: ${textMuted};
23+
}
24+
25+
#theme-starter [class~="bg-primary"] {
26+
background-color: var(--starter-color-primary) !important;
27+
}
28+
29+
#theme-starter [class~="text-primary"],
30+
#theme-starter [class~="hover:text-primary"]:hover,
31+
#theme-starter .group:hover [class~="group-hover:text-primary"] {
32+
color: var(--starter-color-primary) !important;
33+
}
34+
35+
#theme-starter [class~="border-primary"],
36+
#theme-starter [class~="focus:border-primary"]:focus {
37+
border-color: var(--starter-color-primary) !important;
38+
}
39+
40+
#theme-starter [class~="ring-primary"],
41+
#theme-starter [class~="focus:ring-primary"]:focus {
42+
--tw-ring-color: var(--starter-color-primary) !important;
43+
}
44+
45+
#theme-starter [class~="hover:bg-primary"]:hover,
46+
#theme-starter [class~="hover:bg-blue-dark"]:hover,
47+
#theme-starter [class~="hover:border-blue-dark"]:hover {
48+
background-color: var(--starter-color-primary-hover) !important;
49+
border-color: var(--starter-color-primary-hover) !important;
50+
}
51+
52+
#theme-starter [class~="bg-dark"],
53+
.dark #theme-starter [class~="dark:bg-dark"] {
54+
background-color: var(--starter-color-dark) !important;
55+
}
56+
57+
#theme-starter [class~="hover:bg-dark"]:hover {
58+
background-color: var(--starter-color-dark) !important;
59+
}
60+
61+
#theme-starter .text-body-color,
62+
#theme-starter [class~="text-body-color"] {
63+
color: var(--starter-color-text-muted) !important;
64+
}
65+
1366
#theme-starter .sticky{
1467
position: fixed;
1568
z-index: 20;
@@ -22,7 +75,7 @@ const Style = () => {
2275
}
2376
2477
:is(.dark #theme-starter .sticky){
25-
background-color: rgb(17 25 40 / 0.8);
78+
background-color: color-mix(in srgb, var(--starter-color-dark) 80%, transparent);
2679
}
2780
2881
#theme-starter .sticky {
@@ -52,8 +105,7 @@ const Style = () => {
52105
}
53106
54107
#theme-starter .sticky #navbarCollapse li > a:hover{
55-
--tw-text-opacity: 1;
56-
color: rgb(55 88 249 / var(--tw-text-opacity));
108+
color: var(--starter-color-primary);
57109
opacity: 1;
58110
}
59111
@@ -68,8 +120,7 @@ const Style = () => {
68120
}
69121
70122
:is(.dark #theme-starter .sticky #navbarCollapse li > a:hover){
71-
--tw-text-opacity: 1;
72-
color: rgb(55 88 249 / var(--tw-text-opacity));
123+
color: var(--starter-color-primary);
73124
}
74125
75126
:is(.dark #theme-starter .sticky #navbarCollapse li > button){
@@ -82,8 +133,7 @@ const Style = () => {
82133
}
83134
84135
#theme-starter .sticky #navbarCollapse li .ud-menu-scroll.active{
85-
--tw-text-opacity: 1;
86-
color: rgb(55 88 249 / var(--tw-text-opacity));
136+
color: var(--starter-color-primary);
87137
opacity: 1;
88138
}
89139
@@ -93,8 +143,7 @@ const Style = () => {
93143
}
94144
95145
#theme-starter .sticky .loginBtn:hover{
96-
--tw-text-opacity: 1;
97-
color: rgb(55 88 249 / var(--tw-text-opacity));
146+
color: var(--starter-color-primary);
98147
opacity: 1;
99148
}
100149
@@ -104,20 +153,17 @@ const Style = () => {
104153
}
105154
106155
:is(.dark #theme-starter .sticky .loginBtn:hover){
107-
--tw-text-opacity: 1;
108-
color: rgb(55 88 249 / var(--tw-text-opacity));
156+
color: var(--starter-color-primary);
109157
}
110158
111159
#theme-starter .sticky .signUpBtn{
112-
--tw-bg-opacity: 1;
113-
background-color: rgb(55 88 249 / var(--tw-bg-opacity));
160+
background-color: var(--starter-color-primary);
114161
--tw-text-opacity: 1;
115162
color: rgb(255 255 255 / var(--tw-text-opacity));
116163
}
117164
118165
#theme-starter .sticky .signUpBtn:hover{
119-
--tw-bg-opacity: 1;
120-
background-color: rgb(27 68 200 / var(--tw-bg-opacity));
166+
background-color: var(--starter-color-primary-hover);
121167
--tw-text-opacity: 1;
122168
color: rgb(255 255 255 / var(--tw-text-opacity));
123169
}
@@ -149,8 +195,7 @@ const Style = () => {
149195
}
150196
151197
.text-body-color{
152-
--tw-text-opacity: 1;
153-
color: rgb(99 115 129 / var(--tw-text-opacity));
198+
color: var(--starter-color-text-muted);
154199
}
155200
156201
.text-body-secondary{
@@ -184,8 +229,7 @@ const Style = () => {
184229
185230
.common-carousel .swiper-button-next:hover,
186231
.common-carousel .swiper-button-prev:hover{
187-
--tw-bg-opacity: 1;
188-
background-color: rgb(55 88 249 / var(--tw-bg-opacity));
232+
background-color: var(--starter-color-primary);
189233
--tw-text-opacity: 1;
190234
color: rgb(255 255 255 / var(--tw-text-opacity));
191235
--tw-shadow: 0 0 #0000;

0 commit comments

Comments
 (0)