-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathindex.ts
More file actions
72 lines (62 loc) · 1.97 KB
/
index.ts
File metadata and controls
72 lines (62 loc) · 1.97 KB
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
type DataAttribute<T> = `data-${T extends string ? T : string}`;
type DataAttributeQuery<T extends string, V, K extends string = DataAttribute<T>> = `[${K}="${V extends string
? V
: string}"]`;
interface DomObjectsOptions<T extends string> {
/**
* This attribute will be passed as [data-{attributeName}].
* Ex: [data-cy], [data-test-id] and etc.
*/
attributeName: T;
}
interface DomObjectsResult<T extends string, V extends string> {
add<V1 extends string, V2 extends string>(name: V1, selector?: V2): DomObjectsResult<T, V1>;
attr?: {
[K in DataAttribute<T>]: V;
};
query: DataAttributeQuery<T, V>;
}
enum Type {
"main",
"child",
}
type Node = {
type: Type;
name: string;
};
export const configureDomObjects = <T extends string>({ attributeName }: DomObjectsOptions<T>) => {
return <V extends string>(name: V) => {
const dataAttr = `data-${attributeName}`;
const queue: Node[] = [
{
type: Type.main,
name,
},
];
const getMethods = (currentQueue: Node[], node: Node) => ({
get attr() {
return {
[dataAttr]: node.name,
};
},
get query() {
return currentQueue.map((s) => (s.type === Type.main ? `[${dataAttr}="${s.name}"]` : s.name)).join(" ");
},
add(name: string, select: string) {
const nextNode = {
type: Type.main,
name,
};
const nextQueue = currentQueue.concat(nextNode);
if (select) {
nextQueue.push({
type: Type.child,
name: select,
});
}
return getMethods(nextQueue, nextNode);
},
});
return getMethods(queue, queue[0]) as DomObjectsResult<T, V>;
};
};