@@ -3,6 +3,10 @@ import { states } from "./colorOptions";
33import { id } from "tsafe/id" ;
44import { assert } from "tsafe/assert" ;
55import { capitalize } from "tsafe/capitalize" ;
6+ import css from "css" ;
7+ import { exclude } from "tsafe/exclude" ;
8+ import { is } from "tsafe/is" ;
9+ import { parseColorOptionName , getThemePath as getColorOptionThemePath } from "./colorOptions" ;
610
711const contexts = [ "background" , "text" , "border" , "artwork" ] as const ;
812
@@ -31,26 +35,26 @@ export function createParseColorDecisionName(params: {
3135
3236 function parseColorDecisionName ( colorDecisionName : `--${string } `) : ParsedColorDecisionName {
3337 /*
34- colorDecisionName:
35- --background-default-grey-hover
36- --background-default-grey
37- --border-action-low-orange-terre-battue
38- --background-alt-raised-grey-hover
39- --background-contrast-overlap-grey
40- */
38+ colorDecisionName:
39+ --background-default-grey-hover
40+ --background-default-grey
41+ --border-action-low-orange-terre-battue
42+ --background-alt-raised-grey-hover
43+ --background-contrast-overlap-grey
44+ */
4145
4246 const parsedColorDecisionName : ParsedColorDecisionName = { } as any ;
4347
4448 let arr = colorDecisionName . replace ( / ^ - - / , "" ) . split ( "-" ) ;
4549
4650 /*
47- arr:
48- [ "background", "default", "grey", "hover" ]
49- [ "background", "default", "grey" ]
50- [ "border", "action-low", "orange", "terre", "battue"]
51- [ "background", "alt", "raised", "grey", "hover" ]
52- [ "background", "contrast-overlap", "grey" ]
53- */
51+ arr:
52+ [ "background", "default", "grey", "hover" ]
53+ [ "background", "default", "grey" ]
54+ [ "border", "action-low", "orange", "terre", "battue"]
55+ [ "background", "alt", "raised", "grey", "hover" ]
56+ [ "background", "contrast-overlap", "grey" ]
57+ */
5458
5559 //parse context
5660 {
@@ -144,3 +148,67 @@ export function getThemePath(parsedColorDecisionName: ParsedColorDecisionName) {
144148 parsedColorDecisionName . state ?? "default"
145149 ] ;
146150}
151+
152+ export type ColorDecision = {
153+ themePath : string [ ] ;
154+ optionThemePath : string [ ] ;
155+ } ;
156+
157+ export function createParseColorDecision ( params : {
158+ /** Like [ "grey", "blueFrance", ... ]
159+ * All the the color name in camel case that we deduce from Options
160+ * it help parsing without making assumption on what is a valid Usage
161+ */
162+ colorNames : string [ ] ;
163+ /** ["--grey-1000-50-hover", "--grey-1000-50", ... ] */
164+ colorOptionNames : `--${string } `[ ] ;
165+ } ) {
166+ const { colorNames, colorOptionNames } = params ;
167+
168+ const { parseColorDecisionName } = createParseColorDecisionName ( { colorNames } ) ;
169+
170+ function parseColorDecision ( rawCssCode : string ) : ColorDecision [ ] {
171+ const parsedCss = css . parse ( rawCssCode ) ;
172+
173+ const { declarations } = ( ( ) => {
174+ const node = parsedCss . stylesheet ?. rules . find (
175+ rule => rule . type === "rule" && ( rule as any ) ?. selectors ?. [ 0 ] === ":root"
176+ ) ;
177+
178+ assert ( node !== undefined ) ;
179+
180+ const { declarations } = node as any ;
181+
182+ return { declarations } ;
183+ } ) ( ) ;
184+
185+ return declarations
186+ . map ( ( { property, value } : { property : string ; value : string } ) => {
187+ const mathArray = value . match ( / ^ v a r \( ( - - [ ^ ) ] + ) \) $ / ) ;
188+
189+ if ( mathArray === null ) {
190+ return undefined ;
191+ }
192+
193+ const colorOptionName = mathArray [ 1 ] ;
194+
195+ assert ( is < `--${string } `> ( colorOptionName ) ) ;
196+
197+ if ( ! id < string [ ] > ( colorOptionNames ) . includes ( colorOptionName ) ) {
198+ return undefined ;
199+ }
200+
201+ assert ( is < `--${string } `> ( property ) ) ;
202+
203+ return {
204+ "themePath" : getThemePath ( parseColorDecisionName ( property ) ) ,
205+ "optionThemePath" : getColorOptionThemePath (
206+ parseColorOptionName ( colorOptionName )
207+ )
208+ } ;
209+ } )
210+ . filter ( exclude ( undefined ) ) ;
211+ }
212+
213+ return { parseColorDecision } ;
214+ }
0 commit comments