Skip to content

Commit bb3a658

Browse files
authored
[Guild Week] Added generator for basic design tokens (#2265)
* Added generator for basic design tokens * Review - renaming, default parameter * Add a method for generating design tokens and loading the scheme * Cleanup
1 parent cbd63f9 commit bb3a658

File tree

3 files changed

+131
-2
lines changed

3 files changed

+131
-2
lines changed

src/style/__tests__/colors.spec.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,62 @@ describe('style/Colors', () => {
123123
expect(palette).toEqual(['#661A66', '#8F248F', '#B82EB7', '#D148D1', '#DB71DB', '#E699E6', '#F0C2F0', '#FFE5FF']);
124124
});
125125
});
126+
127+
describe('generateDesignTokens(...)', () => {
128+
it('should generate design tokens from dark color for light theme', () => {
129+
const chosenColor = '#860D86';
130+
expect(uut.isDark(chosenColor)).toEqual(true);
131+
expect(uut.generateDesignTokens(chosenColor, 'light')).toEqual({
132+
$backgroundPrimaryHeavy: chosenColor,
133+
$backgroundPrimaryLight: '#FFFAFF',
134+
$backgroundPrimaryMedium: '#FACCFA',
135+
$iconPrimary: chosenColor,
136+
$iconPrimaryLight: '#F16FF1',
137+
$outlinePrimary: chosenColor,
138+
$textPrimary: chosenColor
139+
});
140+
});
141+
142+
it('should generate design tokens from light color for light theme', () => {
143+
const chosenColor = '#E9BEE7';
144+
expect(uut.isDark(chosenColor)).toEqual(false);
145+
expect(uut.generateDesignTokens(chosenColor, 'light')).toEqual({
146+
$backgroundPrimaryHeavy: '#A4379F',
147+
$backgroundPrimaryLight: '#F6E4F5',
148+
$backgroundPrimaryMedium: '#E9BEE7',
149+
$iconPrimary: '#A4379F',
150+
$iconPrimaryLight: '#CF72CB',
151+
$outlinePrimary: '#A4379F',
152+
$textPrimary: '#A4379F'
153+
});
154+
});
155+
156+
it('should generate design tokens from dark color for dark theme', () => {
157+
const chosenColor = '#860D86';
158+
expect(uut.isDark(chosenColor)).toEqual(true);
159+
expect(uut.generateDesignTokens(chosenColor, 'dark')).toEqual({
160+
$backgroundPrimaryHeavy: '#F69DF6',
161+
$backgroundPrimaryLight: '#860D86',
162+
$backgroundPrimaryMedium: '#B512B5',
163+
$iconPrimary: '#F69DF6',
164+
$iconPrimaryLight: '#ED40ED',
165+
$outlinePrimary: '#F69DF6',
166+
$textPrimary: '#F69DF6'
167+
});
168+
});
169+
170+
it('should generate design tokens from light color for dark theme', () => {
171+
const chosenColor = '#E9BEE7';
172+
expect(uut.isDark(chosenColor)).toEqual(false);
173+
expect(uut.generateDesignTokens(chosenColor, 'dark')).toEqual({
174+
$backgroundPrimaryHeavy: chosenColor,
175+
$backgroundPrimaryLight: '#581E55',
176+
$backgroundPrimaryMedium: '#7E2B7A',
177+
$iconPrimary: chosenColor,
178+
$iconPrimaryLight: '#C24CBD',
179+
$outlinePrimary: chosenColor,
180+
$textPrimary: chosenColor
181+
});
182+
});
183+
});
126184
});

src/style/colors.ts

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ export class Colors {
4343
Object.assign(this, Scheme.getScheme());
4444
}
4545

46+
/**
47+
* Load light and dark schemes based on generated design tokens
48+
* @param color - palette color
49+
*/
50+
loadDesignTokens(color: string) {
51+
this.loadSchemes({
52+
light: this.generateLightModeTokens(color),
53+
dark: this.generateDarkModeTokens(color)
54+
});
55+
}
56+
4657
/**
4758
* Get app's current color scheme
4859
*/
@@ -173,7 +184,7 @@ export class Colors {
173184
return colorsPalette[tintLevel - 1];
174185
}
175186

176-
generateColorPalette = _.memoize(color => {
187+
private generatePalette = _.memoize((color: string): string[] => {
177188
const hsl = Color(color).hsl();
178189
const lightness = Math.round(hsl.color[2]);
179190
const lightColorsThreshold = this.shouldGenerateDarkerPalette(color) ? 5 : 0;
@@ -199,10 +210,58 @@ export class Colors {
199210

200211
const sliced = tints.slice(0, 8);
201212
const adjusted = adjustSaturation(sliced, color);
202-
const palette = adjusted || sliced;
213+
return adjusted || sliced;
214+
});
215+
216+
generateColorPalette = _.memoize((color: string): string[] => {
217+
const palette = this.generatePalette(color);
203218
return this.shouldSupportDarkMode && Scheme.getSchemeType() === 'dark' ? _.reverse(palette) : palette;
204219
});
205220

221+
generateDesignTokens(color: string, mode: 'light' | 'dark' = 'light') {
222+
return mode === 'light' ? this.generateLightModeTokens(color) : this.generateDarkModeTokens(color);
223+
}
224+
225+
private generateLightModeTokens(color: string) {
226+
const colorPalette: string[] = this.generatePalette(color);
227+
const color30 = colorPalette[2];
228+
const color50 = colorPalette[4];
229+
const color70 = colorPalette[6];
230+
const color80 = colorPalette[7];
231+
232+
const mainColor = this.isDark(color) ? color : color30;
233+
234+
return {
235+
$backgroundPrimaryHeavy: mainColor,
236+
$backgroundPrimaryLight: color80,
237+
$backgroundPrimaryMedium: color70,
238+
$iconPrimary: mainColor,
239+
$iconPrimaryLight: color50,
240+
$textPrimary: mainColor,
241+
$outlinePrimary: mainColor
242+
};
243+
}
244+
245+
private generateDarkModeTokens(color: string) {
246+
const colorPalette: string[] = _.reverse(this.generatePalette(color));
247+
const color30 = colorPalette[2];
248+
const color50 = colorPalette[4];
249+
const color70 = colorPalette[6];
250+
const color80 = colorPalette[7];
251+
252+
const mainColor = this.isDark(color) ? color30 : color;
253+
254+
return {
255+
$backgroundPrimaryHeavy: mainColor,
256+
$backgroundPrimaryLight: color80,
257+
$backgroundPrimaryMedium: color70,
258+
$iconPrimary: mainColor,
259+
$iconPrimaryLight: color50,
260+
$textPrimary: mainColor,
261+
$outlinePrimary: mainColor
262+
};
263+
}
264+
206265
private shouldGenerateDarkerPalette(color: string) {
207266
const hsl = Color(color).hsl();
208267
const hue = hsl.color[0];

typings/generatedTypes/colors.d.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,25 @@ declare class Colors {
2727
getColorName(color: string): any;
2828
getTintedColorForDynamicHex(color: string, tintKey: string | number): string;
2929
generateColorPalette: ((color: any) => string[]) & _.MemoizedFunction;
30+
generateDesignTokens(color: string, mode: 'light' | 'dark'): DesignTokens;
3031
isDark(color: string): boolean;
3132
isValidHex(string: string): boolean;
3233
getHexString(color: string): string;
3334
getHSL(color: string): tinycolor.ColorFormats.HSLA;
3435
isTransparent(color: string): boolean;
3536
areEqual(colorA: string, colorB: string): boolean;
3637
}
38+
39+
interface DesignTokens {
40+
$backgroundPrimaryHeavy: string;
41+
$backgroundPrimaryLight: string;
42+
$backgroundPrimaryMedium: string;
43+
$iconPrimary: string;
44+
$iconPrimaryLight: string;
45+
$textPrimary: string;
46+
$outlinePrimarystring: string;
47+
}
48+
3749
declare const colorObject: Colors & {
3850
grey10: string;
3951
grey20: string;

0 commit comments

Comments
 (0)