@@ -6,17 +6,29 @@ import type {
66
77type CSSPropertiesKeys = keyof CSSProperties ;
88
9+ type DefineRulesResolver <
10+ Out = CSSPropertiesWithVars | undefined ,
11+ Arg = unknown
12+ > = {
13+ bivarianceHack ( arg : Arg ) : Out ;
14+ } [ "bivarianceHack" ] ;
15+
916type DefineRulesCssProperties = {
10- [ Property in CSSPropertiesKeys ] ?:
11- | ReadonlyArray < CSSProperties [ Property ] >
12- | Record < string , CSSProperties [ Property ] | CSSPropertiesWithVars >
13- | true
14- | false ;
17+ [ Property in CSSPropertiesKeys ] ?: DefineRulesCssPropertiesValue <
18+ CSSProperties [ Property ]
19+ > ;
1520} ;
21+ type DefineRulesCssPropertiesValue < Value > =
22+ | ReadonlyArray < Value >
23+ | Record < string , Value | CSSPropertiesWithVars >
24+ | DefineRulesResolver < Value >
25+ | true
26+ | false ;
27+
1628type DefineRulesCustomProperties = Partial <
1729 Record <
1830 Exclude < NonNullableString , CSSPropertiesKeys > ,
19- Record < string , CSSPropertiesWithVars >
31+ Record < string , CSSPropertiesWithVars > | DefineRulesResolver
2032 >
2133> ;
2234export type DefineRulesProperties =
@@ -31,7 +43,8 @@ type ShortcutValue<
3143 | keyof Properties
3244 | Exclude < keyof Shortcuts , ShortcutsKey >
3345 | ReadonlyArray < keyof Properties | Exclude < keyof Shortcuts , ShortcutsKey > >
34- | DefineRulesCssInput < Properties , Shortcuts > ;
46+ | DefineRulesCssInput < Properties , Shortcuts >
47+ | DefineRulesResolver < DefineRulesCssInput < Properties , Shortcuts > > ;
3548
3649export type DefineRulesShortcuts <
3750 Properties extends DefineRulesProperties ,
@@ -59,15 +72,17 @@ type PropertiesInput<Properties extends DefineRulesProperties> = {
5972type ResolvePropertiesValue < Key , Value > =
6073 Value extends ReadonlyArray < infer Item >
6174 ? Item
62- : true extends Value
63- ? Key extends CSSPropertiesKeys
64- ? CSSProperties [ Key ]
65- : never
66- : false extends Value
67- ? never
68- : Value extends Record < infer StyleObjectKey , unknown >
69- ? StyleObjectKey
70- : never ;
75+ : Value extends ( arg : infer Arg ) => unknown
76+ ? Arg
77+ : true extends Value
78+ ? Key extends CSSPropertiesKeys
79+ ? CSSProperties [ Key ]
80+ : never
81+ : false extends Value
82+ ? never
83+ : Value extends Record < infer StyleObjectKey , unknown >
84+ ? StyleObjectKey
85+ : never ;
7186
7287type ShortcutsInput <
7388 Properties extends Record < string , unknown > ,
@@ -86,9 +101,11 @@ type ResolveShortcutValue<
86101 Value
87102> = Value extends readonly unknown [ ]
88103 ? ResolveShortcutArrayRef < Properties , Shortcuts , Value >
89- : Value extends Record < string , unknown >
90- ? boolean
91- : ResolveShortcutRef < Properties , Shortcuts , Value > ;
104+ : Value extends ( arg : infer Arg ) => unknown
105+ ? Arg
106+ : Value extends Record < string , unknown >
107+ ? boolean
108+ : ResolveShortcutRef < Properties , Shortcuts , Value > ;
92109
93110type ResolveShortcutArrayRef <
94111 Properties extends Record < string , unknown > ,
@@ -295,6 +312,68 @@ if (import.meta.vitest) {
295312 backgroundOpacity : "quarter"
296313 } ) ;
297314 } ) ;
315+
316+ it ( "Function values return CSS properties" , ( ) => {
317+ const { rules, _props } = resolveDefineRules ( {
318+ properties : {
319+ color ( arg : "primary" | "secondary" ) {
320+ if ( arg === "primary" ) {
321+ return { color : "blue" } as const ;
322+ } else {
323+ return { color : "gray" } as const ;
324+ }
325+ }
326+ }
327+ } ) ;
328+ assertType < {
329+ properties ?: {
330+ color : ( arg : "primary" | "secondary" ) =>
331+ | {
332+ color : string ;
333+ }
334+ | undefined ;
335+ } ;
336+ } > ( rules ) ;
337+
338+ assertType < typeof _props > ( {
339+ color : "primary"
340+ } ) ;
341+ } ) ;
342+
343+ it ( "Function values return Style objects" , ( ) => {
344+ const { rules, _props } = resolveDefineRules ( {
345+ properties : {
346+ color ( arg : "primary" | "secondary" ) {
347+ if ( arg === "primary" ) {
348+ return "blue" ;
349+ } else {
350+ return "gray" ;
351+ }
352+ } ,
353+ otherColor ( arg : "primary" | "secondary" ) {
354+ if ( arg === "primary" ) {
355+ return { color : "red" } as const ;
356+ } else {
357+ return { color : "green" } as const ;
358+ }
359+ }
360+ }
361+ } ) ;
362+ assertType < {
363+ properties ?: {
364+ color : ( arg : "primary" | "secondary" ) => "blue" | "gray" ;
365+ otherColor : ( arg : "primary" | "secondary" ) =>
366+ | {
367+ color : string ;
368+ }
369+ | undefined ;
370+ } ;
371+ } > ( rules ) ;
372+
373+ assertType < typeof _props > ( {
374+ color : "primary"
375+ } ) ;
376+ } ) ;
298377 } ) ;
299378
300379 describe . concurrent ( "DefineRulesShortcuts Type" , ( ) => {
@@ -462,6 +541,49 @@ if (import.meta.vitest) {
462541 } ) ;
463542 assertType < typeof _props > ( [ "inline" ] ) ;
464543 } ) ;
544+
545+ it ( "Function shortcut" , ( ) => {
546+ const { rules, _props } = resolveDefineRules ( {
547+ properties : {
548+ display : [ "none" , "inline" , "block" ] ,
549+ paddingLeft : [ 0 , 4 , 8 ] ,
550+ paddingRight : [ 0 , 4 , 8 ]
551+ } ,
552+ shortcuts : {
553+ px : [ "paddingLeft" , "paddingRight" ] ,
554+ center ( arg : "none" | "inline" | "block" ) {
555+ return {
556+ display : arg ,
557+ px : 4
558+ } ;
559+ }
560+ }
561+ } ) ;
562+ assertType < {
563+ properties ?: {
564+ display : readonly [ "none" , "inline" , "block" ] ;
565+ paddingLeft : readonly [ 0 , 4 , 8 ] ;
566+ paddingRight : readonly [ 0 , 4 , 8 ] ;
567+ } ;
568+ shortcuts ?: {
569+ px : readonly [ "paddingLeft" , "paddingRight" ] ;
570+ center : ( arg : "none" | "inline" | "block" ) =>
571+ | {
572+ display : "none" | "inline" | "block" ;
573+ px : number ;
574+ }
575+ | undefined ;
576+ } ;
577+ } > ( rules ) ;
578+
579+ assertType < typeof _props > ( {
580+ center : "inline"
581+ } ) ;
582+ assertType < typeof _props > ( {
583+ // @ts -expect-error: invalid value
584+ center : "flex"
585+ } ) ;
586+ } ) ;
465587 } ) ;
466588
467589 describe . concurrent ( "Invalid Type Cases" , ( ) => {
0 commit comments