Skip to content

Commit f4d1603

Browse files
committed
feat: reverse shades order for dark theme to keep contrast
1 parent 67155b0 commit f4d1603

File tree

8 files changed

+62
-31
lines changed

8 files changed

+62
-31
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ plugins: [
6767
red: '#FF5555',
6868
yellow: '#F1FA8C'
6969
}
70-
}
70+
},
71+
isDark: true
7172
]
7273
})
7374
]

examples/tailwind/index.html

+14-10
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@
157157
</p>
158158
</blockquote>
159159
<figcaption class="font-medium">
160-
<div class="text-themeable-cyan-50">Author: Yiming Li</div>
160+
<div class="text-themeable-cyan-300">Author: Yiming Li</div>
161161
<div class="text-themeable-foreground">GitHub ID: upupming</div>
162162
</figcaption>
163163
</div>
@@ -168,18 +168,19 @@
168168
z-10
169169
rounded-xl
170170
shadow-lg shadow-themeable-foreground
171-
divide-y-2 divide-themeable-orange-500
171+
divide-y-2 divide-themeable-orange-300
172172
flex flex-col
173173
"
174174
>
175-
<section class="flex flex-row">
175+
<section class="flex flex-row <sm:flex-col">
176176
<h3
177177
class="
178178
flex-none
179+
<sm:w-full <sm:rounded-tr-xl
179180
w-48
180-
border-themeable-orange-500 border-t-2 border-l-2
181-
bg-themeable-orange-50
182-
text-themeable-orange-500
181+
border-themeable-orange-300 border-t-2 border-l-2
182+
bg-themeable-orange-800
183+
text-themeable-orange-300
183184
rounded-tl-xl
184185
text-lg
185186
leading-6
@@ -196,6 +197,7 @@
196197
flex-auto
197198
bg-themeable-selection
198199
rounded-tr-xl
200+
<sm:rounded-tr-none
199201
px-4
200202
py-6
201203
p-6
@@ -227,14 +229,15 @@
227229
</div>
228230
</dl>
229231
</section>
230-
<section class="flex flex-row overflow-hidden">
232+
<section class="flex flex-row overflow-hidden <sm:flex-col">
231233
<h3
232234
class="
233235
flex-none
236+
<sm:w-full <sm:rounded-none
234237
w-48
235-
bg-themeable-orange-50
236-
text-themeable-orange-500
237-
border-themeable-orange-500 border-b-2 border-l-2
238+
border-themeable-orange-300 border-l-2 border-b-2
239+
bg-themeable-orange-800
240+
text-themeable-orange-300
238241
rounded-bl-xl
239242
text-lg
240243
leading-6
@@ -252,6 +255,7 @@
252255
flex-auto
253256
bg-themeable-selection
254257
rounded-br-xl
258+
<sm:rounded-bl-xl
255259
overflow-hidden
256260
text-themeable-foreground
257261
"

examples/tailwind/tailwind.config.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ module.exports = {
1111
},
1212
darkMode: false, // or 'media' or 'class'
1313
theme: {
14-
extend: {}
14+
extend: {
15+
screens: {
16+
'<sm': { max: '639.9px' }
17+
// => @media (max-width: 639.9px) { ... }
18+
}
19+
}
1520
},
1621
variants: {
1722
extend: {

examples/windi/index.html

+14-10
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@
155155
</p>
156156
</blockquote>
157157
<figcaption class="font-medium">
158-
<div class="text-themeable-cyan-50">Author: Yiming Li</div>
158+
<div class="text-themeable-cyan-300">Author: Yiming Li</div>
159159
<div class="text-themeable-foreground">GitHub ID: upupming</div>
160160
</figcaption>
161161
</div>
@@ -166,18 +166,19 @@
166166
z-10
167167
rounded-xl
168168
shadow-lg shadow-themeable-foreground
169-
divide-y-2 divide-themeable-orange-500
169+
divide-y-2 divide-themeable-orange-300
170170
flex flex-col
171171
"
172172
>
173-
<section class="flex flex-row">
173+
<section class="flex flex-row <sm:flex-col">
174174
<h3
175175
class="
176176
flex-none
177+
<sm:w-full <sm:rounded-tr-xl
177178
w-48
178-
border-themeable-orange-500 border-t-2 border-l-2
179-
bg-themeable-orange-50
180-
text-themeable-orange-500
179+
border-themeable-orange-300 border-t-2 border-l-2
180+
bg-themeable-orange-800
181+
text-themeable-orange-300
181182
rounded-tl-xl
182183
text-lg
183184
leading-6
@@ -194,6 +195,7 @@
194195
flex-auto
195196
bg-themeable-selection
196197
rounded-tr-xl
198+
<sm:rounded-tr-none
197199
px-4
198200
py-6
199201
p-6
@@ -225,14 +227,15 @@
225227
</div>
226228
</dl>
227229
</section>
228-
<section class="flex flex-row overflow-hidden">
230+
<section class="flex flex-row overflow-hidden <sm:flex-col">
229231
<h3
230232
class="
231233
flex-none
234+
<sm:w-full <sm:rounded-none
232235
w-48
233-
bg-themeable-orange-50
234-
text-themeable-orange-500
235-
border-themeable-orange-500 border-b-2 border-l-2
236+
border-themeable-orange-300 border-l-2 border-b-2
237+
bg-themeable-orange-800
238+
text-themeable-orange-300
236239
rounded-bl-xl
237240
text-lg
238241
leading-6
@@ -250,6 +253,7 @@
250253
flex-auto
251254
bg-themeable-selection
252255
rounded-br-xl
256+
<sm:rounded-bl-xl
253257
overflow-hidden
254258
text-themeable-foreground
255259
"

examples/windi/style.css

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
}
77

88
.text-link {
9-
@apply text-themeable-orange-500
10-
hover:text-themeable-orange-600
9+
@apply text-themeable-orange-400
10+
hover:text-themeable-orange-500
1111
transition;
1212
}
1313

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
"prepare": "husky install"
1313
},
1414
"files": [
15-
"dist",
16-
"src"
15+
"/dist",
16+
"/src"
1717
],
1818
"repository": {
1919
"type": "git",

src/index.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ export type ThemePalette = {
4646
export interface Theme {
4747
name: string
4848
palette: ThemePalette
49+
/** Whether this theme is a dark theme or not,
50+
* if it is light theme, shades will get darker from 50 to 900, just like the tailwind official shades
51+
* if it is dark theme, shades will get lighter from 50 to 900
52+
* the reason why we reverse the shades for dark theme is that we want to keep contrast with background
53+
* for example, a light theme often has white background and black foreground, foreground-900 (the most dark black) will have the largest contrast with background-50 (the most light white)
54+
* when we switching to a dark theme which often has black background and white foreground, foreground-900 (the most light white) will still have the largest contrast with background-50 (the most dark black)
55+
* @default false
56+
*/
57+
isDark?: boolean
4958
}
5059

5160
export interface ThemeableOptions {
@@ -92,7 +101,8 @@ export const themeDracula = {
92101
purple: '#BD93F9',
93102
red: '#FF5555',
94103
yellow: '#F1FA8C'
95-
}
104+
},
105+
isDark: true
96106
} as const
97107
export const themeMaterial: Theme = {
98108
name: 'material',
@@ -117,9 +127,9 @@ export const builtinThemes = [themeDracula, themeMaterial] as const
117127
* Fill a `ColorShades` with auto-generated shade values and return a `ColorShadesComputed`
118128
*/
119129
export const fillColorShades = (shades: ColorShades, saturationFactor?: number,
120-
lightFactor?: number) => {
130+
lightFactor?: number, isDark?: boolean) => {
121131
const { DEFAULT } = shades
122-
const shadesComputed = color2Shades(DEFAULT, saturationFactor, lightFactor)
132+
const shadesComputed = color2Shades(DEFAULT, saturationFactor, lightFactor, isDark)
123133
return Object.assign(shadesComputed, shades)
124134
}
125135

@@ -168,7 +178,7 @@ export const themeable = createPlugin.withOptions<ThemeableOptions>(({
168178
} else {
169179
colorShades = color
170180
}
171-
const colorShadesComputed = fillColorShades(colorShades, saturationFactor, lightFactor)
181+
const colorShadesComputed = fillColorShades(colorShades, saturationFactor, lightFactor, theme.isDark)
172182
let shade: keyof ColorShades
173183
for (shade in colorShadesComputed) {
174184
const key = paletteKeyShade2CSSVariable(classPrefix, paletteKey, shade)

src/shades.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { hex2HSL, hsl2Hex } from './utils'
55
* Generate 10 shades (from 50 to 900) from one color
66
* Thanks to: https://github.com/nickgraffis/tailwind-color-generator
77
*/
8-
export const color2Shades = (color: ColorHex, saturationFactor = saturationFactorDefault, lightFactor = lightFactorDefault) => {
8+
export const color2Shades = (color: ColorHex, saturationFactor = saturationFactorDefault, lightFactor = lightFactorDefault, isDark = false) => {
99
// find the best shade index for this color, if this color is too light, it will be closer to `50`, otherwise it will be closer to `900` if too dark
1010
const [h, s, l] = hex2HSL(color)
1111

@@ -32,5 +32,12 @@ export const color2Shades = (color: ColorHex, saturationFactor = saturationFacto
3232
ans[shadeStops[i]] = hsl2Hex([h, s + saturationFactor * step, l + lightFactor * step])
3333
}
3434

35+
// reverse the shades if it is a dark theme, see the type docs of Theme['isDark']
36+
if (isDark) {
37+
for (let i = 0, j = shadeStops.length - 1; i < j; i++, j--) {
38+
[ans[shadeStops[i]], ans[shadeStops[j]]] = [ans[shadeStops[j]], ans[shadeStops[i]]]
39+
}
40+
}
41+
3542
return ans
3643
}

0 commit comments

Comments
 (0)