@@ -16,7 +16,7 @@ import values = require('lodash/values');
16
16
const VAR_PREFIX = 'grist' ;
17
17
18
18
class CustomProp {
19
- constructor ( public name : string , public value ?: string , public fallback ?: string | CustomProp ) {
19
+ constructor ( public name : string , public value ?: string | CustomProp , public fallback ?: string | CustomProp ) {
20
20
21
21
}
22
22
@@ -78,6 +78,89 @@ export const colors = {
78
78
79
79
} ;
80
80
81
+ /**
82
+ * Example of new "design tokens" that are a mix of current `colors`, `vars` and `theme` props.
83
+ *
84
+ * The css variables defined here take precedence over the ones in `colors` and `vars`, but are
85
+ * overriden by variables re-declared in a theme or a custom css file.
86
+ *
87
+ * The idea is we would not need `colors` and `vars` anymore.
88
+ *
89
+ * 1) List the `colors` above but rename them to have more abstracted names, ie "lightGreen" becomes "primaryLight".
90
+ * Grays are an exception here as I assume they will always be targetted as such, but we could name them differently
91
+ * if we want to stick to non-visual names here, like "shadeXX", "neutralXX". Or "secondaryXX", renaming the current
92
+ * "secondary" color to "tertiary" or "accent"? I just followed original naming for now.
93
+ *
94
+ * 2) Whenever possible, design tokens target other design tokens instead of copying color codes, ie "primaryBg"
95
+ * directly targets "primaryLight" instead of being "#16B378". Here I use getters to define tokens that target other
96
+ * tokens to prevent having to define multiple temporary vars.
97
+ *
98
+ * 3) Follow the `vars` object idea and add more semantic/global tokens to the list.
99
+ * What I have in mind is to move most of `vars` props here, and some of the pretty-much global things listed in `theme`
100
+ * (like text colors or panel global things). The endgoal would be to list all colors and tokens globally used in
101
+ * Grist here. I guess it might not make sense to list here a few really specific components (for example, code view).
102
+ *
103
+ * 4) Either have component-specific variables listed in `theme` below consume these designTokens, *or* remove
104
+ * them and make it so that components directly consume the designTokens in their own code.
105
+ *
106
+ * Colors listed here default to Grist light theme colors.
107
+ * Contrary to `colors` and `vars`, all tokens here are meant to be overridable by a theme,
108
+ * allowing a theme to only override what it wants instead of having to redefine everything.
109
+ */
110
+ export const designTokens = {
111
+ /* first list hard-coded colors, then other colors consuming them and other non-color tokens */
112
+ white : new CustomProp ( 'color-white' , '#FFFFFF' ) ,
113
+ greyLight : new CustomProp ( 'color-grey-light' , '#F7F7F7' ) ,
114
+ greyMediumOpaque : new CustomProp ( 'color-grey-medium-opaque' , '#E8E8E8' ) ,
115
+ greyMedium : new CustomProp ( 'color-grey-medium' , 'rgba(217,217,217,0.6)' ) ,
116
+ greyDark : new CustomProp ( 'color-grey-dark' , '#D9D9D9' ) ,
117
+ slate : new CustomProp ( 'color-slate' , '#929299' ) ,
118
+ darkText : new CustomProp ( 'color-dark-text' , '#494949' ) ,
119
+ dark : new CustomProp ( 'color-dark' , '#262633' ) ,
120
+ black : new CustomProp ( 'color-black' , '#000000' ) ,
121
+
122
+ primaryLighter : new CustomProp ( 'color-primary-lighter' , '#b1ffe2' ) ,
123
+ primaryLight : new CustomProp ( 'color-primary-light' , '#16B378' ) ,
124
+ primaryDark : new CustomProp ( 'color-primary-dark' , '#009058' ) ,
125
+ primaryDarker : new CustomProp ( 'color-primary-darker' , '#007548' ) ,
126
+
127
+ secondaryLighter : new CustomProp ( 'color-secondary-lighter' , '#87b2f9' ) ,
128
+ secondaryLight : new CustomProp ( 'color-secondary-light' , '#3B82F6' ) ,
129
+
130
+ error : new CustomProp ( 'color-error' , '#D0021B' ) ,
131
+ warningLight : new CustomProp ( 'color-warning-light' , '#F9AE41' ) ,
132
+ warningDark : new CustomProp ( 'color-warning-dark' , '#dd962c' ) ,
133
+
134
+ cursorInactive : new CustomProp ( 'color-cursor-inactive' , '#A2E1C9' ) ,
135
+ selection : new CustomProp ( 'color-selection' , 'rgba(22,179,120,0.15)' ) ,
136
+ selectionOpaque : new CustomProp ( 'color-selection-opaque' , '#DCF4EB' ) ,
137
+ selectionDarkerOpaque : new CustomProp ( 'color-selection-darker-opaque' , '#d6eee5' ) ,
138
+ hover : new CustomProp ( 'color-hover' , '#bfbfbf' ) ,
139
+ backdrop : new CustomProp ( 'color-backdrop' , 'rgba(38,38,51,0.9)' ) ,
140
+
141
+ get warningBg ( ) { return new CustomProp ( 'color-warning-bg' , this . warningDark ) ; } ,
142
+
143
+ get primaryBg ( ) { return new CustomProp ( 'primary-bg' , this . primaryLight ) ; } ,
144
+ get primaryBgHover ( ) { return new CustomProp ( 'primary-bg-hover' , this . primaryDark ) ; } ,
145
+ get primaryFg ( ) { return new CustomProp ( 'primary-fg' , this . white ) ; } ,
146
+
147
+ get controlBg ( ) { return new CustomProp ( 'control-bg' , this . white ) ; } ,
148
+ get controlFg ( ) { return new CustomProp ( 'control-fg' , this . primaryLight ) ; } ,
149
+ get controlFgHover ( ) { return new CustomProp ( 'primary-fg-hover' , this . primaryDark ) ; } ,
150
+ get controlBorderColor ( ) { return new CustomProp ( 'control-border-color' , this . primaryLight ) ; } ,
151
+ controlBorderRadius : new CustomProp ( 'border-radius' , '4px' ) ,
152
+
153
+ get cursor ( ) { return new CustomProp ( 'color-cursor' , this . primaryLight ) ; } ,
154
+
155
+ get mainBg ( ) { return new CustomProp ( 'main-bg' , this . white ) ; } ,
156
+ get text ( ) { return new CustomProp ( 'text' , this . dark ) ; } ,
157
+ get textLight ( ) { return new CustomProp ( 'text-light' , this . slate ) ; } ,
158
+
159
+ get panelBg ( ) { return new CustomProp ( 'panel-bg' , this . greyLight ) ; } ,
160
+ get panelFg ( ) { return new CustomProp ( 'panel-fg' , this . dark ) ; } ,
161
+ get panelBorder ( ) { return new CustomProp ( 'panel-border' , this . greyMedium ) ; } ,
162
+ } ;
163
+
81
164
export const vars = {
82
165
/* Fonts */
83
166
fontFamily : new CustomProp ( 'font-family' , `-apple-system,BlinkMacSystemFont,Segoe UI,Liberation Sans,
@@ -923,6 +1006,7 @@ export const theme = {
923
1006
924
1007
const cssColors = values ( colors ) . map ( v => v . decl ( ) ) . join ( '\n' ) ;
925
1008
const cssVars = values ( vars ) . map ( v => v . decl ( ) ) . join ( '\n' ) ;
1009
+ const cssTokens = values ( designTokens ) . map ( v => v . decl ( ) ) . join ( '\n' ) ;
926
1010
927
1011
// We set box-sizing globally to match bootstrap's setting of border-box, since we are integrating
928
1012
// into an app which already has it set, and it's impossible to make things look consistently with
@@ -1065,6 +1149,11 @@ export function attachCssRootVars(productFlavor: ProductFlavor, varsOnly: boolea
1065
1149
${ cssRootVars }
1066
1150
}
1067
1151
${ ! varsOnly && cssReset }
1152
+ }
1153
+ @layer grist-tokens {
1154
+ :root {
1155
+ ${ cssTokens }
1156
+ }
1068
1157
}` ;
1069
1158
document . documentElement . classList . add ( cssRoot . className ) ;
1070
1159
document . body . classList . add ( cssBody . className ) ;
0 commit comments