1- import type { Falsy , ToggleMap , ClassValue , ClassNamer , ClassNamed } from "./defs"
1+ import type { Falsy , ToggleMap , ClassValue , ClassNamer , ClassNamed , ClassNamesMap } from "./defs"
22import { emptize , stringifyClassNamed , truthyKeys } from "./utils"
33
4+ emptize ( classNamer )
5+
6+ //TODO no `className` - no first `true`
47interface tClassNaming < ClassKeys extends string > {
58 /**
69 * @example classes(true) === props.className
@@ -17,7 +20,7 @@ interface tClassNaming<ClassKeys extends string> {
1720 : ToggleMap < ClassKeys >
1821 ) | ClassKeys | Falsy ,
1922 ...expressions : ( ClassKeys | Falsy ) [ ]
20- ) : ClassNamed
23+ ) : ClassNamed & { classNames ?: ClassNamesMap < ClassKeys > }
2124}
2225
2326export default classNamingCtx
@@ -27,20 +30,44 @@ export default classNamingCtx
2730 * @example const classes = classNamingCtx({className, classNames})
2831 * @example const classes = classNamingCtx({classNames})
2932 */
30- function classNamingCtx < ClassKeys extends string > ( ctx : ClassNamer < ClassKeys > ) : tClassNaming < ClassKeys > {
31- emptize ( ctx . classNames )
33+ function classNamingCtx < ClassKeys extends string /*, withClassNames extends boolean = false*/ > (
34+ { classNames, className} : ClassNamer < ClassKeys > ,
35+ options ?: ClassNamerOptions //<withClassNames>
36+ ) : tClassNaming < ClassKeys > {
37+ emptize ( classNames )
3238
33- return classNamer . bind ( ctx ) as tClassNaming < ClassKeys >
39+ return classNamer . bind ( { classNames , className , ... options } ) as tClassNaming < ClassKeys >
3440}
3541
42+ // type get<T, K> = K extends keyof T ? T[K] : never
43+
44+ type ClassNamerOptions <
45+ // withClassNames extends undefined|boolean = undefined|boolean
46+ > = Partial < {
47+ withClassNames : boolean //withClassNames
48+ // withSelf: boolean
49+ } >
50+
3651function classNamer < ClassKeys extends string > (
37- this : ClassNamer < ClassKeys > ,
52+ this : ClassNamer < ClassKeys > & ClassNamerOptions ,
3853 arg0 : true | ToggleMap < ClassKeys > | ClassKeys ,
3954 arg1 ?: ToggleMap < ClassKeys > | ClassKeys ,
4055 ...args : ( ClassKeys | Falsy ) [ ]
41- ) : ClassNamed {
42- const { className, classNames} = this
43- const withPropagation = arg0 === true
56+ ) : ClassNamed
57+ & Partial < Pick < typeof this , "classNames" > >
58+ // & (
59+ // [Extract<get<typeof this, "withClassNames">, true>] extends [never]
60+ // ? EmptyObject
61+ // : Pick<typeof this, "classNames">
62+ // )
63+ {
64+ const {
65+ className : _propagated ,
66+ classNames,
67+ withClassNames,
68+ // withSelf
69+ } = this
70+ , withPropagation = arg0 === true
4471 , allowed : ClassKeys [ ] = truthyKeys ( arg0 === true ? false : arg0 )
4572 //@ts -expect-error
4673 . concat ( truthyKeys ( arg1 ) )
@@ -51,6 +78,8 @@ function classNamer<ClassKeys extends string>(
5178 Boolean
5279 )
5380
81+ emptize ( classNames )
82+
5483 for ( let i = allowed . length ; i -- ; ) {
5584 const key = allowed [ i ]
5685 , hash : ClassValue = classNames [ key ]
@@ -61,20 +90,28 @@ function classNamer<ClassKeys extends string>(
6190 }
6291
6392 const allowedString = allowed . join ( " " )
64- , propagated = withPropagation && className || ""
65- , $return = {
66- className : `${
67- propagated
68- } ${
69- propagated && allowedString
70- ? " "
71- : ""
72- } ${
73- allowedString
74- } `
75- }
76-
77- stringifyClassNamed ( $return )
93+ , propagated = withPropagation && _propagated || ""
94+
95+ //TODO Consider undefined|empty|never for type error
96+ , className = `${
97+ propagated
98+ } ${
99+ propagated && allowedString
100+ ? " "
101+ : ""
102+ } ${
103+ allowedString
104+ } `
105+
78106
79- return $return
107+ if ( ! withClassNames ) {
108+ return stringifyClassNamed ( {
109+ className
110+ } )
111+ } else {
112+ return stringifyClassNamed ( {
113+ className,
114+ classNames
115+ } )
116+ }
80117}
0 commit comments