-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmod.ts
94 lines (91 loc) · 2.65 KB
/
mod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
* @module
*/
/**
* A type for a given HTMLElement that filters the available attributes to
* values of type string, number, or boolean.
*
* @example Usage
* ```ts
* type InputAttributes = Attributes<'input'>
* ```
*/
export type Attributes<T extends keyof HTMLElementTagNameMap> = Partial<
{
[
U in keyof HTMLElementTagNameMap[T] as HTMLElementTagNameMap[T][U] extends string | number | boolean | null ? U
: never
]: HTMLElementTagNameMap[T][U]
}
>
/**
* A type specifying the structure of the function that can be passed to the
* createTag element.
*
* @example Usage
* ```ts
* type InputFunc = Func<'input'>
* ```
*/
export type Func<T extends keyof HTMLElementTagNameMap> = (tag: HTMLElementTagNameMap[T]) => unknown
/**
* A function that creates a HTMLElement with the correct typings.
*
* @param type A string containing the name of the HTML element to be created.
* @param attributes An object containing the key-value pairs of attributes to
* be assigned to the HTML element. Only string, number, and boolean values are
* valid.
* @param func An optional function that passes the created HTML element as a
* parameter before resolving the function.
* @returns A HTML element based off what was specified in type.
*
* @example Usage
* ```ts
* createTag('button', { textContent: 'Click Me!' }, buttonTag =>
* buttonTag.addEventListener('click', function (_event) {
* console.log(this.outerHTML)
* })).click()
* ```
*/
export function createTag<T extends keyof HTMLElementTagNameMap>(
type: T,
attributes: Attributes<T>,
func?: Func<T>,
): HTMLElementTagNameMap[T]
/**
* A function that creates a HTMLElement with the correct typings.
*
* @param type A string containing the name of the HTML element to be created.
* @param func An optional function that passes the created HTML element as a
* parameter before resolving the function.
* @returns A HTML element based off what was specified in type.
*
* @example Usage
* ```ts
* createTag('button', buttonTag =>
* buttonTag.addEventListener('click', function (_event) {
* console.log("I've been clicked!")
* }))
* ```
*/
export function createTag<T extends keyof HTMLElementTagNameMap>(type: T, func?: Func<T>): HTMLElementTagNameMap[T]
export function createTag<T extends keyof HTMLElementTagNameMap>(
arg1: T,
arg2?: Attributes<T> | Func<T>,
arg3?: Func<T>,
): HTMLElementTagNameMap[T] {
const tag = document.createElement(arg1)
if (typeof arg2 === 'function') {
arg2(tag)
} else if (arg2) {
for (const [key, value] of Object.entries(arg2)) {
if (value != null) {
tag[key as 'id'] = value as string
}
}
if (arg3) {
arg3(tag)
}
}
return tag
}