Passed
Push — main ( 675a30...a39b05 )
by Andrii
02:10
created

basic.ts ➔ _classNaming   A

Complexity

Conditions 4

Size

Total Lines 47
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 32
dl 0
loc 47
c 0
b 0
f 0
rs 9.112
cc 4
1
export type { ClassNames } from "./defs"
2
import type { ClassNamesMap, ClassNamed, GetClassKeys } from "./defs"
3
4
const {
5
  keys: $keys,
6
  defineProperty: $defineProperty,
7
  assign: $assign
8
} = Object
9
, classNameKey = "className" as const
10
11
export default classNamingBasic
12
13
/**
14
 * Makes `className` string from imported CSS
15
 * @example <div className={classNaming<string>({ClassName})} />
16
 * @example <div {...classNaming({ClassName})} />
17
 */
18
function classNamingBasic<Return, ClassKeys extends string = string>(
19
  classnames: ClassNamesMap<string extends Return ? ClassKeys : GetClassKeys<Return>>
20
): Return extends string ? string : ClassNamed
21
22
/**
23
 * Makes `className` string from imported CSS
24
 * @example <div className={classNaming<string>({ClassName})} />
25
 * @example <div {...classNaming({ClassName})} />
26
 */
27
function classNamingBasic<Return, ClassKeys extends string = string>(
28
  propagatedClassName: undefined|string,
29
  classnames: ClassNamesMap<string extends Return ? ClassKeys : GetClassKeys<Return>>
30
): Return extends string ? string : ClassNamed
31
32
function classNamingBasic(
33
  arg0: undefined|string|ClassNamesMap<string>,
34
  arg1: undefined|ClassNamesMap<string> = undefined
35
): ClassNamed {
36
  const classnames = typeof arg0 === "object" ? arg0 : arg1
37
  , className = typeof arg0 === "object" ? undefined : arg0
38
39
  return _classNaming(classnames!, className, {})
40
}
41
42
function _classNaming<T extends Partial<ClassNamed>>(
43
  classnames: ClassNamesMap<string>,
44
  className: undefined|string,
45
  destination: T
46
): T & ClassNamed {
47
  const keys = $keys(classnames)
48
  , {length} = keys
49
50
  for (let i = length; i--;) {
51
    const key = keys[i]
52
    , value = classnames[key]
53
54
    if (typeof value === "string")
55
      keys[i] = value
56
  }
57
58
  const classString = `${
59
    !className
60
    ? ""
61
    : `${className} `
62
  }${
63
    keys
64
    .join(" ")
65
  }`
66
67
  // TODO For propagation
68
  // $defineProperty(
69
  //   classnames,
70
  //   "toString",
71
  //   {
72
  //     value: undefined
73
  //   }
74
  // )
75
  // $assign(destination, {classnames})
76
77
  $assign(destination, {[classNameKey]: classString})
78
79
  $defineProperty(
80
    destination,
81
    "toString",
82
    {
83
      value: () => classString
84
    }
85
  )
86
87
  return destination as T & ClassNamed
88
}
89