1
|
|
|
import type { Falsy } from "../src/ts-swiss.types" |
2
|
|
|
import type { ClassHash } from "../src/main.types" |
3
|
|
|
|
4
|
|
|
type ClassNamesDirect<K extends string = string> = Record<K, ClassHash> |
5
|
|
|
// type ClassNamesToggle<K extends string = string> = Record<K, boolean> |
6
|
|
|
|
7
|
|
|
type ClassNamingContext<S extends string, U extends string> = { |
8
|
|
|
className?: undefined|string |
9
|
|
|
classnames: ClassNamesDirect<S> |
10
|
|
|
applied?: Record<U, ClassHash|boolean>[] |
11
|
|
|
} |
12
|
|
|
|
13
|
|
|
export { |
14
|
|
|
_doubleShape |
15
|
|
|
} |
16
|
|
|
|
17
|
|
|
function _doubleShape< |
18
|
|
|
// A extends {[K in Exclude<S, U>]?: boolean} | {[K in Exclude<S, U>]?: ClassHash}, |
19
|
|
|
A extends {[K in Exclude<S, U>]?: ClassHash | boolean}, |
20
|
|
|
S extends string, |
21
|
|
|
U extends string = never, |
22
|
|
|
>( |
23
|
|
|
ctx: ClassNamingContext<S, U>, |
24
|
|
|
withClassName: boolean, |
25
|
|
|
injection: undefined|string, |
26
|
|
|
...args: (Falsy | A)[] |
27
|
|
|
) { |
28
|
|
|
const {applied, classnames, className} = ctx |
29
|
|
|
//@ts-expect-error |
30
|
|
|
, nextApplied = !applied ? [] : applied.push(...args.filter(x => x)) as Record<U | keyof A, ClassHash|boolean>[] |
31
|
|
|
|
32
|
|
|
, host = < |
33
|
|
|
// T extends {[K in Exclude<S, U | keyof A>]?: boolean} | {[K in Exclude<S, U | keyof A>]?: ClassHash} |
34
|
|
|
T extends {[K in Exclude<S, U>]?: ClassHash | boolean}, |
35
|
|
|
>( |
36
|
|
|
withClassName: boolean, |
37
|
|
|
injection: undefined|string, |
38
|
|
|
...args: (Falsy | T)[] |
39
|
|
|
) => _doubleShape( |
40
|
|
|
{classnames, className, applied: nextApplied}, |
41
|
|
|
withClassName, |
42
|
|
|
injection, |
43
|
|
|
...args |
44
|
|
|
) |
45
|
|
|
|
46
|
|
|
for (let i = args.length; i--; ) { |
47
|
|
|
const arg = args[i] |
48
|
|
|
if (!arg) { |
49
|
|
|
delete args[i] |
50
|
|
|
continue |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
const keys = Object.keys(arg) as (keyof typeof arg)[] |
54
|
|
|
for (let i = keys.length; i--;) { |
55
|
|
|
const key = keys[i] |
56
|
|
|
, v = arg[key] |
57
|
|
|
|
58
|
|
|
switch (v) { |
59
|
|
|
case undefined: |
60
|
|
|
break |
61
|
|
|
case false: |
62
|
|
|
delete keys[i] |
63
|
|
|
break |
64
|
|
|
case true: |
65
|
|
|
//@ts-expect-error |
66
|
|
|
keys[i] = classnames?.[key as unknown as S] ?? key |
67
|
|
|
break |
68
|
|
|
default: |
69
|
|
|
if (typeof v === "string") |
70
|
|
|
//@ts-expect-error |
71
|
|
|
keys[i] = v |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
const chunk = keys.flat().join(" ") |
76
|
|
|
if (!chunk) |
77
|
|
|
delete args[i] |
78
|
|
|
else |
79
|
|
|
//@ts-expect-error |
80
|
|
|
args[i] = chunk |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
const calced = [ |
84
|
|
|
withClassName && className, |
85
|
|
|
injection, |
86
|
|
|
args.flat().join(" ") |
87
|
|
|
].filter(x => x) |
88
|
|
|
.join(" ") |
89
|
|
|
|
90
|
|
|
host["className"] = calced |
91
|
|
|
|
92
|
|
|
Object.defineProperty(host, Symbol.toPrimitive, {value: () => calced}) |
93
|
|
|
|
94
|
|
|
return host |
95
|
|
|
} |