1
1
/** @jsxImportSource @compiled /react */
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
3
+ import { cssMap as cssMapLoose } from '@compiled/react' ;
2
4
import { render } from '@testing-library/react' ;
3
5
4
- import { css , cssMap , XCSSProp } from './__fixtures__/strict-api' ;
6
+ import { css , cssMap , XCSSProp , cx } from './__fixtures__/strict-api' ;
5
7
6
8
describe ( 'createStrictAPI()' , ( ) => {
7
9
describe ( 'css()' , ( ) => {
8
10
it ( 'should type error when circumventing the excess property check' , ( ) => {
9
- const styles = css ( {
11
+ const stylesOne = css ( {
10
12
color : 'var(--ds-text)' ,
11
13
accentColor : 'red' ,
12
14
// @ts -expect-error — Type 'string' is not assignable to type 'undefined'.ts(2322)
13
15
bkgrnd : 'red' ,
16
+ '&:hover' : {
17
+ color : 'var(--ds-text-hover)' ,
18
+ } ,
19
+ } ) ;
20
+ const stylesTwo = css ( {
21
+ color : 'var(--ds-text)' ,
22
+ accentColor : 'red' ,
14
23
'&:hover' : {
15
24
color : 'var(--ds-text-hover)' ,
16
25
// @ts -expect-error — Type 'string' is not assignable to type 'undefined'.ts(2322)
17
26
bkgrnd : 'red' ,
18
27
} ,
19
28
} ) ;
20
29
21
- const { getByTestId } = render ( < div css = { styles } data-testid = "div" /> ) ;
30
+ const { getByTestId } = render ( < div css = { [ stylesOne , stylesTwo ] } data-testid = "div" /> ) ;
22
31
23
32
expect ( getByTestId ( 'div' ) ) . toHaveCompiledCss ( 'color' , 'var(--ds-text)' ) ;
24
33
} ) ;
@@ -79,7 +88,7 @@ describe('createStrictAPI()', () => {
79
88
color : 'var(--ds-text)' ,
80
89
all : 'inherit' ,
81
90
'&:hover' : { color : 'var(--ds-text-hover)' } ,
82
- '&:invalid' : { color : 'orange ' } ,
91
+ '&:invalid' : { color : 'var(--ds-text) ' } ,
83
92
} ) ;
84
93
85
94
const { getByTestId } = render ( < div css = { styles } data-testid = "div" /> ) ;
@@ -146,7 +155,7 @@ describe('createStrictAPI()', () => {
146
155
accentColor : 'red' ,
147
156
all : 'inherit' ,
148
157
'&:hover' : { color : 'var(--ds-text-hover)' } ,
149
- '&:invalid' : { color : 'orange ' } ,
158
+ '&:invalid' : { color : 'var(--ds-text) ' } ,
150
159
} ,
151
160
} ) ;
152
161
@@ -271,12 +280,103 @@ describe('createStrictAPI()', () => {
271
280
} ) ;
272
281
273
282
describe ( 'XCSSProp' , ( ) => {
283
+ it ( 'should error with values not in the strict `CompiledStrictSchema`' , ( ) => {
284
+ function Button ( {
285
+ xcss,
286
+ testId,
287
+ } : {
288
+ testId : string ;
289
+ xcss : ReturnType < typeof XCSSProp < 'background' | 'color' , '&:hover' > > ;
290
+ } ) {
291
+ return < button data-testid = { testId } className = { xcss } /> ;
292
+ }
293
+ // NOTE: For some reason the "background" property is being expanded to "string" instead of
294
+ // staying narrowed as "var(--ds-surface-hover)" meaning it breaks when used with the strict
295
+ // schema loaded XCSS prop. This is a bug and unexpected.
296
+ const stylesValidRoot = cssMapLoose ( {
297
+ primary : {
298
+ color : 'var(--ds-text)' ,
299
+ '&:hover' : { color : 'var(--ds-text-hover)' , background : 'var(--ds-surface-hover)' } ,
300
+ } ,
301
+ } ) ;
302
+ const stylesInvalidRoot = cssMapLoose ( {
303
+ primary : {
304
+ color : 'red' ,
305
+ '&:hover' : { color : 'var(--ds-text-hover)' , background : 'var(--ds-surface-hover)' } ,
306
+ } ,
307
+ } ) ;
308
+ const stylesInvalid = cssMap ( {
309
+ primary : {
310
+ // @ts -expect-error -- This is not valid in the CompiledStrictSchema
311
+ color : 'red' ,
312
+ '&:hover' : { color : 'var(--ds-text-hover)' , background : 'var(--ds-surface-hover)' } ,
313
+ } ,
314
+ } ) ;
315
+
316
+ const stylesValid = cssMap ( {
317
+ primary : {
318
+ color : 'var(--ds-text)' ,
319
+ '&:hover' : { color : 'var(--ds-text-hover)' , background : 'var(--ds-surface-hover)' } ,
320
+ } ,
321
+ } ) ;
322
+
323
+ const { getByTestId } = render (
324
+ < >
325
+ < Button
326
+ testId = "button-invalid-root"
327
+ // @ts -expect-error — This conflicts with the custom API, should be a different bg color
328
+ xcss = { stylesInvalidRoot . primary }
329
+ />
330
+ < Button
331
+ testId = "button-invalid-root-cx"
332
+ // @ts -expect-error — This conflicts with the custom API, should be a different bg color
333
+ xcss = { cx ( stylesInvalidRoot . primary , stylesValid . primary ) }
334
+ />
335
+ < Button
336
+ testId = "button-valid-root"
337
+ // @ts -expect-error — For some reason the "background" property is being expanded to "string" instead of
338
+ // staying narrowed as "var(--ds-surface-hover)" meaning it breaks when used with the strict
339
+ // schema loaded XCSS prop. This is a bug and unexpected.
340
+ xcss = { stylesValidRoot . primary }
341
+ />
342
+ < Button
343
+ testId = "button-valid-root-cx"
344
+ // @ts -expect-error — For some reason the "background" property is being expanded to "string" instead of
345
+ // staying narrowed as "var(--ds-surface-hover)" meaning it breaks when used with the strict
346
+ // schema loaded XCSS prop. This is a bug and unexpected.
347
+ xcss = { cx ( stylesValidRoot . primary , stylesValid . primary ) }
348
+ />
349
+ < Button
350
+ testId = "button-invalid-strict"
351
+ // @ts -expect-error — TODO: This should conflict, but when `cssMap` conflicts, it gets a different type (this has `ApplySchema`, not the raw object), so this doesn't error? Weird…
352
+ xcss = { stylesInvalid . primary }
353
+ />
354
+ < Button
355
+ testId = "button-invalid-strict-cx"
356
+ // @ts -expect-error — TODO: This should conflict, but when `cssMap` conflicts, it gets a different type (this has `ApplySchema`, not the raw object), so this doesn't error? Weird…
357
+ xcss = { cx ( stylesInvalid . primary , stylesValid . primary ) }
358
+ />
359
+ < Button testId = "button-valid" xcss = { stylesValid . primary } />
360
+ < Button testId = "button-valid-cx" xcss = { cx ( stylesValid . primary , stylesValid . primary ) } />
361
+ < Button
362
+ testId = "button-invalid-direct"
363
+ xcss = { {
364
+ // @ts -expect-error — This is not in the `createStrictAPI` schema—this should be a css variable.
365
+ color : 'red' ,
366
+ } }
367
+ />
368
+ </ >
369
+ ) ;
370
+
371
+ expect ( getByTestId ( 'button-invalid-root' ) ) . toHaveCompiledCss ( 'color' , 'red' ) ;
372
+ } ) ;
373
+
274
374
it ( 'should allow valid values from cssMap' , ( ) => {
275
375
function Button ( { xcss } : { xcss : ReturnType < typeof XCSSProp < 'background' , never > > } ) {
276
376
return < button data-testid = "button" className = { xcss } /> ;
277
377
}
278
-
279
378
const styles = cssMap ( { bg : { background : 'var(--ds-surface)' } } ) ;
379
+
280
380
const { getByTestId } = render ( < Button xcss = { styles . bg } /> ) ;
281
381
282
382
expect ( getByTestId ( 'button' ) ) . toHaveCompiledCss ( 'background' , 'var(--ds-surface)' ) ;
@@ -302,7 +402,6 @@ describe('createStrictAPI()', () => {
302
402
function Button ( { xcss } : { xcss : ReturnType < typeof XCSSProp < 'background' , '&:hover' > > } ) {
303
403
return < button data-testid = "button" className = { xcss } /> ;
304
404
}
305
-
306
405
const styles = cssMap ( {
307
406
primary : {
308
407
background : 'var(--ds-surface)' ,
@@ -341,29 +440,53 @@ describe('createStrictAPI()', () => {
341
440
it ( 'should error with values not in the strict `CompiledAPI`' , ( ) => {
342
441
function Button ( {
343
442
xcss,
443
+ testId,
344
444
} : {
445
+ testId : string ;
345
446
xcss : ReturnType < typeof XCSSProp < 'background' | 'color' , '&:hover' > > ;
346
447
} ) {
347
- return < button data-testid = "button" className = { xcss } /> ;
448
+ return < button data-testid = { testId } className = { xcss } /> ;
348
449
}
349
450
350
- const styles = cssMap ( {
451
+ const stylesOne = cssMapLoose ( {
351
452
primary : {
352
- // @ts -expect-error -- This is not in the `createStrictAPI` schema—this should be a css variable.
453
+ color : 'red' ,
454
+ background : 'var(--ds-surface)' ,
455
+ '&:hover' : { background : 'var(--ds-surface-hover)' } ,
456
+ } ,
457
+ } ) ;
458
+ const stylesTwo = cssMap ( {
459
+ primary : {
460
+ // @ts -expect-error — This is not in the `createStrictAPI` schema—this should be a css variable.
353
461
color : 'red' ,
354
462
background : 'var(--ds-surface)' ,
355
463
'&:hover' : { background : 'var(--ds-surface-hover)' } ,
356
464
} ,
357
465
} ) ;
358
466
359
467
const { getByTestId } = render (
360
- < Button
361
- // @ts -expect-error -- Errors because `color` conflicts with the `XCSSProp` schema–`color` should be a css variable.
362
- xcss = { styles . primary }
363
- />
468
+ < >
469
+ < Button
470
+ testId = "button-1"
471
+ // @ts -expect-error — This is not in the `createStrictAPI` schema—this should be a css variable.
472
+ xcss = { stylesOne . primary }
473
+ />
474
+ < Button
475
+ testId = "button-3"
476
+ // @ts -expect-error — This is not in the `createStrictAPI` schema—this should be a css variable.
477
+ xcss = { stylesTwo . stylesTwo }
478
+ />
479
+ < Button
480
+ testId = "button-2"
481
+ xcss = { {
482
+ // @ts -expect-error — This is not in the `createStrictAPI` schema—this should be a css variable.
483
+ color : 'red' ,
484
+ } }
485
+ />
486
+ </ >
364
487
) ;
365
488
366
- expect ( getByTestId ( 'button' ) ) . toHaveCompiledCss ( 'background' , 'var(--ds-surface)' ) ;
489
+ expect ( getByTestId ( 'button-1 ' ) ) . toHaveCompiledCss ( 'background' , 'var(--ds-surface)' ) ;
367
490
} ) ;
368
491
369
492
it ( 'should error with properties not in the `XCSSProp`' , ( ) => {
@@ -380,7 +503,7 @@ describe('createStrictAPI()', () => {
380
503
381
504
const { getByTestId } = render (
382
505
< Button
383
- // @ts -expect-error -- Errors because `background` + `&:hover` are not in the `XCSSProp` schema.
506
+ // @ts -expect-error — Errors because `background` + `&:hover` are not in the `XCSSProp` schema.
384
507
xcss = { styles . primary }
385
508
/>
386
509
) ;
@@ -392,21 +515,24 @@ describe('createStrictAPI()', () => {
392
515
function Button ( { xcss } : { xcss : ReturnType < typeof XCSSProp < 'background' , '&:hover' > > } ) {
393
516
return < button data-testid = "button" className = { xcss } /> ;
394
517
}
395
-
396
- const styles = cssMap ( {
518
+ const stylesOne = cssMap ( {
397
519
primary : {
398
- // @ts -expect-error -- Fails because `foo` is not assignable to our CSSProperties whatsoever.
520
+ // @ts -expect-error — Fails because `foo` is not assignable to our CSSProperties whatsoever.
399
521
foo : 'bar' ,
400
522
background : 'var(--ds-surface)' ,
523
+ } ,
524
+ } ) ;
525
+ const stylesTwo = cssMap ( {
526
+ hover : {
401
527
'&:hover' : {
402
- // This does not fail, but would if the above was removed; this should be tested in raw `cssMap` fully .
528
+ // @ts -expect-error — Fails because `foo` is not assignable to our CSSProperties whatsoever .
403
529
foo : 'bar' ,
404
530
background : 'var(--ds-surface-hover)' ,
405
531
} ,
406
532
} ,
407
533
} ) ;
408
534
409
- const { getByTestId } = render ( < Button xcss = { styles . primary } /> ) ;
535
+ const { getByTestId } = render ( < Button xcss = { cx ( stylesOne . primary , stylesTwo . hover ) } /> ) ;
410
536
411
537
expect ( getByTestId ( 'button' ) ) . toHaveCompiledCss ( 'background' , 'var(--ds-surface)' ) ;
412
538
} ) ;
@@ -536,27 +662,84 @@ describe('createStrictAPI()', () => {
536
662
537
663
it ( 'should enforce required properties' , ( ) => {
538
664
function Button ( {
665
+ testId,
539
666
xcss,
540
667
} : {
668
+ testId : string ;
541
669
xcss : ReturnType <
542
670
typeof XCSSProp <
543
- 'background' ,
671
+ 'background' | 'color' ,
544
672
never ,
545
673
{ requiredProperties : 'background' ; requiredPseudos : never }
546
674
>
547
675
> ;
548
676
} ) {
549
- return < button data-testid = " button" className = { xcss } /> ;
677
+ return < button data-testid = { ` button- ${ testId } ` } className = { xcss } /> ;
550
678
}
551
679
680
+ const stylesValid = cssMap ( {
681
+ primary : { background : 'var(--ds-surface)' } ,
682
+ } ) ;
683
+ const stylesInvalid = cssMap ( {
684
+ primary : { color : 'var(--ds-text)' } ,
685
+ } ) ;
686
+
552
687
const { getByTestId } = render (
553
- < Button
554
- // @ts -expect-error — Type '{}' is not assignable to type 'Internal$XCSSProp<"background", never, EnforceSchema<{ background: "var(--ds-surface)" | "var(--ds-surface-sunken"; }>, object, { requiredProperties: "background"; requiredPseudos: never; }>'.ts(2322)
555
- xcss = { { } }
556
- />
688
+ < >
689
+ < Button testId = "valid" xcss = { stylesValid . primary } />
690
+ < Button
691
+ testId = "invalid"
692
+ // @ts -expect-error — This is not assignable as it's missing the required `background` property.
693
+ xcss = { stylesInvalid . primary }
694
+ />
695
+ </ >
557
696
) ;
558
697
559
- expect ( getByTestId ( 'button' ) ) . not . toHaveCompiledCss ( 'color' , 'red' ) ;
698
+ expect ( getByTestId ( 'button-valid' ) ) . toHaveCompiledCss ( 'background' , 'var(--ds-surface)' ) ;
699
+ expect ( getByTestId ( 'button-invalid' ) ) . toHaveCompiledCss ( 'color' , 'var(--ds-text)' ) ;
700
+ } ) ;
701
+
702
+ it ( 'should enforce required psuedos' , ( ) => {
703
+ function Button ( {
704
+ testId,
705
+ xcss,
706
+ } : {
707
+ testId : string ;
708
+ xcss : ReturnType <
709
+ typeof XCSSProp <
710
+ 'color' ,
711
+ '&:hover' | '&:focus' ,
712
+ { requiredProperties : never ; requiredPseudos : '&:hover' }
713
+ >
714
+ > ;
715
+ } ) {
716
+ return < button data-testid = { `button-${ testId } ` } className = { xcss } /> ;
717
+ }
718
+
719
+ const stylesValid = cssMap ( {
720
+ primary : { '&:hover' : { color : 'var(--ds-text-hover)' } } ,
721
+ } ) ;
722
+ const stylesInvalid = cssMap ( {
723
+ primary : { '&:focus' : { color : 'var(--ds-text)' } } ,
724
+ } ) ;
725
+
726
+ const { getByTestId } = render (
727
+ < >
728
+ < Button testId = "valid" xcss = { stylesValid . primary } />
729
+ < Button
730
+ testId = "invalid"
731
+ // @ts -expect-error — This is not assignable as it's missing the required `background` property.
732
+ xcss = { stylesInvalid . primary }
733
+ />
734
+ </ >
735
+ ) ;
736
+
737
+ expect ( getByTestId ( 'button-valid' ) ) . toHaveCompiledCss ( 'color' , 'var(--ds-text-hover)' , {
738
+ target : ':hover' ,
739
+ } ) ;
740
+ expect ( getByTestId ( 'button-invalid' ) ) . toHaveCompiledCss ( 'color' , 'var(--ds-text)' , {
741
+ target : ':focus' ,
742
+ } ) ;
560
743
} ) ;
561
744
} ) ;
562
745
0 commit comments