@@ -10,78 +10,19 @@ import semanticGrid from '@deephaven/components/src/theme/theme-dark/theme-dark-
1010import components from '@deephaven/components/src/theme/theme-dark/theme-dark-components.css?inline' ;
1111import styles from './ThemeColors.module.scss' ;
1212import { sampleSectionIdAndClasses } from './utils' ;
13-
14- // Group names are extracted from var names via a regex capture group. Most of
15- // them work pretty well, but some need to be remapped to a more appropriate
16- // group.
17- const reassignVarGroups : Record < string , string > = {
18- '--dh-color-black' : 'gray' ,
19- '--dh-color-white' : 'gray' ,
20- // Semantic
21- '--dh-color-visual-positive' : 'Visual Status' ,
22- '--dh-color-visual-negative' : 'Visual Status' ,
23- '--dh-color-visual-notice' : 'Visual Status' ,
24- '--dh-color-visual-info' : 'Visual Status' ,
25- // Editor
26- '--dh-color-editor-bg' : 'editor' ,
27- '--dh-color-editor-fg' : 'editor' ,
28- '--dh-color-editor-context-menu-bg' : 'menus' ,
29- '--dh-color-editor-context-menu-fg' : 'menus' ,
30- '--dh-color-editor-menu-selection-bg' : 'menus' ,
31- // Grid
32- '--dh-color-grid-bg' : 'grid' ,
33- '--dh-color-grid-number-positive' : 'Data Types' ,
34- '--dh-color-grid-number-negative' : 'Data Types' ,
35- '--dh-color-grid-number-zero' : 'Data Types' ,
36- '--dh-color-grid-date' : 'Data Types' ,
37- '--dh-color-grid-string-null' : 'Data Types' ,
38- } ;
39-
40- // Mappings of variable groups to rename
41- const renameGroups = {
42- editor : {
43- line : 'editor' ,
44- comment : 'code' ,
45- string : 'code' ,
46- number : 'code' ,
47- delimiter : 'code' ,
48- identifier : 'code' ,
49- keyword : 'code' ,
50- operator : 'code' ,
51- storage : 'code' ,
52- predefined : 'code' ,
53- selection : 'state' ,
54- focus : 'state' ,
55- } ,
56- chart : {
57- axis : 'Chart' ,
58- bg : 'Chart' ,
59- grid : 'Chart' ,
60- plot : 'Chart' ,
61- title : 'Chart' ,
62- active : 'Data' ,
63- trend : 'Data' ,
64- area : 'Data' ,
65- range : 'Data' ,
66- line : 'Deprecated' ,
67- } ,
68- grid : { data : 'Data Bars' , context : 'Context Menu' } ,
69- semantic : {
70- positive : 'status' ,
71- negative : 'status' ,
72- notice : 'status' ,
73- info : 'status' ,
74- well : 'wells' ,
75- } ,
76- } ;
13+ import {
14+ buildColorGroups ,
15+ contrastColor ,
16+ INVALID_COLOR_BORDER_STYLE ,
17+ } from './colorUtils' ;
7718
7819const swatchDataGroups = {
79- 'Theme Color Palette' : buildColorGroups ( palette , 1 ) ,
80- 'Semantic Colors' : buildColorGroups ( semantic , 1 , renameGroups . semantic ) ,
81- 'Chart Colors' : buildColorGroups ( chart , 2 , renameGroups . chart ) ,
82- 'Editor Colors' : buildColorGroups ( semanticEditor , 2 , renameGroups . editor ) ,
83- 'Grid Colors' : buildColorGroups ( semanticGrid , 2 , renameGroups . grid ) ,
84- 'Component Colors' : buildColorGroups ( components , 1 ) ,
20+ 'Theme Color Palette' : buildColorGroups ( 'palette' , palette , 1 ) ,
21+ 'Semantic Colors' : buildColorGroups ( ' semantic' , semantic , 1 ) ,
22+ 'Chart Colors' : buildColorGroups ( ' chart' , chart , 2 ) ,
23+ 'Editor Colors' : buildColorGroups ( 'editor' , semanticEditor , 2 ) ,
24+ 'Grid Colors' : buildColorGroups ( 'grid' , semanticGrid , 2 ) ,
25+ 'Component Colors' : buildColorGroups ( 'component' , components , 1 ) ,
8526} ;
8627
8728export function ThemeColors ( ) : JSX . Element {
@@ -110,6 +51,10 @@ export function ThemeColors(): JSX.Element {
11051 className = { styles . swatch }
11152 style = { {
11253 backgroundColor : value ,
54+ border :
55+ value === '' && name . length > 0
56+ ? INVALID_COLOR_BORDER_STYLE
57+ : undefined ,
11358 color : `var(--dh-color-${ contrastColor ( value ) } )` ,
11459 } }
11560 >
@@ -137,94 +82,3 @@ export function ThemeColors(): JSX.Element {
13782}
13883
13984export default ThemeColors ;
140-
141- /** Return black or white contrast color */
142- function contrastColor ( color : string ) : 'black' | 'white' {
143- const rgba = ColorUtils . parseRgba ( ColorUtils . asRgbOrRgbaString ( color ) ?? '' ) ;
144- if ( rgba == null || rgba . a < 0.5 ) {
145- return 'white' ;
146- }
147-
148- const { r, g, b } = rgba ;
149- const y = ( 299 * r + 587 * g + 114 * b ) / 1000 ;
150- return y >= 128 ? 'black' : 'white' ;
151- }
152-
153- /** Extract an array of { name, value } pairs for css variables in a given string */
154- function extractColorVars (
155- styleText : string
156- ) : { name : string ; value : string } [ ] {
157- const computedStyle = getComputedStyle ( document . documentElement ) ;
158- const varNames = styleText
159- . split ( / [ \n ; ] / g)
160- // Non-minified css will have leading 2 spaces in front of each css variable
161- // declaration. Minified has no prefix except for the first line which will
162- // have ':root{' prefix.
163- . map ( line => / ^ (?: \s { 2 } | : r o o t \{ ) ? ( - - d h - c o l o r - (?: [ ^ : ] + ) ) / . exec ( line ) ?. [ 1 ] )
164- . filter ( ( match ) : match is string => Boolean ( match ) ) ;
165-
166- return varNames
167- . map ( varName => {
168- const value = computedStyle . getPropertyValue ( varName ) ;
169-
170- // Chart colorway consists of multiple colors, so split into separate
171- // swatches for illustration. Note that this assumes the colors are hsl
172- // values. We'll need to make this more robust if we ever change the
173- // default themes to use non-hsl.
174- if ( varName === '--dh-color-chart-colorway' ) {
175- const colorwayColors = value
176- . split ( 'hsl' )
177- . filter ( Boolean )
178- . map ( v => `hsl${ v . trim ( ) } ` ) ;
179-
180- return colorwayColors . map ( ( varExp , i ) => ( {
181- name : `${ varName } -${ i } ` ,
182- value : varExp ,
183- } ) ) ;
184- }
185-
186- return {
187- name : varName ,
188- value,
189- } ;
190- } )
191- . flat ( ) ;
192- }
193-
194- /** Group color data based on capture group value */
195- function buildColorGroups (
196- styleText : string ,
197- captureGroupI : number ,
198- groupRemap : Record < string , string > = { }
199- ) : Record < string , { name : string ; value : string } [ ] > {
200- const swatchData = extractColorVars ( styleText ) ;
201-
202- const groupData = swatchData . reduce (
203- ( acc , { name, value } ) => {
204- const match = / ^ - - d h - c o l o r - ( [ ^ - ] + ) (?: - ( [ ^ - ] + ) ) ? / . exec ( name ) ;
205- let group =
206- reassignVarGroups [ name ] ??
207- match ?. [ captureGroupI ] ??
208- match ?. [ 1 ] ??
209- '???' ;
210-
211- group = groupRemap [ group ] ?? group ;
212-
213- if ( acc [ group ] == null ) {
214- acc [ group ] = [ ] ;
215- }
216-
217- // Add a spacer for black / white
218- if ( name === '--dh-color-black' ) {
219- acc [ group ] . push ( { name : '' , value : '' } ) ;
220- }
221-
222- acc [ group ] . push ( { name, value } ) ;
223-
224- return acc ;
225- } ,
226- { } as Record < string , { name : string ; value : string } [ ] >
227- ) ;
228-
229- return groupData ;
230- }
0 commit comments