Created
August 8, 2024 11:04
-
-
Save StoneyEagle/5df834788300bd403d9a203b33ed8467 to your computer and use it in GitHub Desktop.
Typesafe create element
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Creates a new HTML element of the specified type and assigns the given ID to it. | |
* @param type - The type of the HTML element to create. | |
* @param id - The ID to assign to the new element. | |
* @param unique - Whether to use an existing element with the specified ID if it already exists. | |
* @returns An object with four methods: | |
* - `addClasses`: Adds the specified CSS class names to the element's class list and returns the next 3 functions. | |
* - `appendTo`: Appends the element to a parent element and returns the element. | |
* - `prependTo`: Prepends the element to a parent element and returns the element. | |
* - `get`:Returns the element. | |
*/ | |
const createElement = <K extends keyof HTMLElementTagNameMap>(type: K, id: string, unique?: boolean) =>{ | |
let el: HTMLElementTagNameMap[K]; | |
if (unique) { | |
el = (document.getElementById(id) ?? document.createElement(type)) as HTMLElementTagNameMap[K]; | |
} else { | |
el = document.createElement(type); | |
} | |
el.id = id; | |
return { | |
addClasses: (names: string[]) => addClasses(el, names), | |
appendTo: <T extends Element>(parent: T) => { | |
parent.appendChild(el); | |
return el; | |
}, | |
prependTo: <T extends Element>(parent: T) => { | |
parent.prepend(el); | |
return el; | |
}, | |
get: () => el, | |
}; | |
} | |
/** | |
* Adds the specified CSS class names to the given element's class list. | |
* | |
* @param el - The element to add the classes to. | |
* @param names - An array of CSS class names to add. | |
* @returns An object with three methods: | |
* - `appendTo`: Appends the element to a parent element and returns the element. | |
* - `prependTo`: Prepends the element to a parent element and returns the element. | |
* - `get`:Returns the element. | |
* @template T - The type of the element. | |
*/ | |
const addClasses = <T extends Element>(el: T, names: string[]) => { | |
for (const name of names.filter(Boolean)) { | |
el.classList?.add(name.trim()); | |
} | |
return { | |
appendTo: <T extends Element>(parent: T) => { | |
parent.appendChild(el); | |
return el; | |
}, | |
prependTo: <T extends Element>(parent: T) => { | |
parent.prepend(el); | |
return el; | |
}, | |
get: () => el, | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment