11// Copyright (c) Jupyter Development Team.
22// Distributed under the terms of the Modified BSD License.
33
4- import { parseColor } from '@microsoft/fast-colors' ;
54import {
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