Skip to content

Commit 1b92f95

Browse files
authored
Improve recipe to link JLab theme to palette (#12)
* Tune brand color to set accent palette * Switch layout color 1 to 50% luminance to set neutral palette * Remove unused import
1 parent aebe2e1 commit 1b92f95

File tree

1 file changed

+55
-24
lines changed

1 file changed

+55
-24
lines changed

packages/components/src/utilities/theme/applyTheme.ts

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
// Copyright (c) Jupyter Development Team.
22
// Distributed under the terms of the Modified BSD License.
33

4-
import { parseColor } from '@microsoft/fast-colors';
54
import {
5+
ColorHSL,
6+
hslToRGB,
7+
parseColor,
8+
rgbToHSL
9+
} from '@microsoft/fast-colors';
10+
import {
11+
accentFillHoverDelta,
612
accentPalette,
713
baseLayerLuminance,
814
bodyFont,
@@ -65,29 +71,13 @@ interface IConverter<T> {
6571
/**
6672
* Convert the CSS variable value to design token value
6773
*/
68-
converter?: (value: string) => T | null;
74+
converter?: (value: string, isDark: boolean) => T | null;
6975
/**
7076
* Design token to update
7177
*/
7278
token: DesignToken<T>;
7379
}
7480

75-
/**
76-
* Convert a base color to a palette.
77-
*
78-
* @param value Color string
79-
* @returns The palette generated from the color
80-
*/
81-
const colorConverter = (value: string): Palette<Swatch> | null => {
82-
const parsedColor = parseColor(value);
83-
84-
return parsedColor
85-
? PaletteRGB.from(
86-
SwatchRGB.create(parsedColor.r, parsedColor.g, parsedColor.b)
87-
)
88-
: null;
89-
};
90-
9181
/**
9282
* Convert a string to an integer.
9383
*
@@ -107,12 +97,51 @@ const tokenMappings: { [key: string]: IConverter<any> } = {
10797
converter: intConverter,
10898
token: strokeWidth
10999
},
110-
'--jp-border-color1': {
111-
converter: colorConverter,
100+
'--jp-layout-color1': {
101+
converter: (value: string, isDark: boolean): Palette<Swatch> | null => {
102+
const parsedColor = parseColor(value);
103+
if (parsedColor) {
104+
const hsl = rgbToHSL(parsedColor);
105+
// Neutral luminance should be about 50%
106+
const correctedHSL = ColorHSL.fromObject({
107+
h: hsl.h,
108+
s: hsl.s,
109+
l: 0.5
110+
});
111+
const correctedRGB = hslToRGB(correctedHSL!);
112+
113+
return PaletteRGB.from(
114+
SwatchRGB.create(correctedRGB.r, correctedRGB.g, correctedRGB.b)
115+
);
116+
} else {
117+
return null;
118+
}
119+
},
112120
token: neutralPalette
113121
},
114122
'--jp-brand-color1': {
115-
converter: colorConverter,
123+
converter: (value: string, isDark: boolean): Palette<Swatch> | null => {
124+
const parsedColor = parseColor(value);
125+
if (parsedColor) {
126+
const hsl = rgbToHSL(parsedColor);
127+
// Correct luminance to get accent fill closer to brand color 1
128+
const direction = isDark ? 1 : -1;
129+
const correctedHSL = ColorHSL.fromObject({
130+
h: hsl.h,
131+
s: hsl.s,
132+
l:
133+
hsl.l +
134+
(direction * accentFillHoverDelta.getValueFor(document.body)) / 94.0
135+
});
136+
const correctedRGB = hslToRGB(correctedHSL!);
137+
138+
return PaletteRGB.from(
139+
SwatchRGB.create(correctedRGB.r, correctedRGB.g, correctedRGB.b)
140+
);
141+
} else {
142+
return null;
143+
}
144+
},
116145
token: accentPalette
117146
},
118147
'--jp-ui-font-family': {
@@ -137,10 +166,11 @@ function applyCurrentTheme() {
137166
const styles = getComputedStyle(document.body);
138167

139168
// Set mode
140-
const value = document.body.getAttribute(THEME_MODE_BODY_ATTRIBUTE);
169+
const isDark =
170+
document.body.getAttribute(THEME_MODE_BODY_ATTRIBUTE) === 'false';
141171
baseLayerLuminance.setValueFor(
142172
document.body,
143-
value === 'false' ? StandardLuminance.DarkMode : StandardLuminance.LightMode
173+
isDark ? StandardLuminance.DarkMode : StandardLuminance.LightMode
144174
);
145175

146176
for (const jpTokenName in tokenMappings) {
@@ -149,7 +179,8 @@ function applyCurrentTheme() {
149179

150180
if (document.body && value !== '') {
151181
const parsedValue = (toolkitTokenName.converter ?? ((v: string) => v))(
152-
value.trim()
182+
value.trim(),
183+
isDark
153184
);
154185
if (parsedValue !== null) {
155186
toolkitTokenName.token.setValueFor(document.body, parsedValue);

0 commit comments

Comments
 (0)