Skip to content

Instantly share code, notes, and snippets.

@fsubal
Last active December 14, 2024 04:03
Show Gist options
  • Save fsubal/740fd408ed62f0599eed584a1ba9bfe1 to your computer and use it in GitHub Desktop.
Save fsubal/740fd408ed62f0599eed584a1ba9bfe1 to your computer and use it in GitHub Desktop.
type ClassNameValue = string | number | false | undefined | null | ClassNameValue[] | { [className: string]: boolean }
function cx(...values: ClassNameValue[]) {
const classNames: string[] = []
for (const value of values) {
if (!value) {
continue
}
if (Array.isArray(value)) {
classNames.push(cx(...value))
continue
}
if (typeof value === 'string' || typeof value === 'number') {
classNames.push(value.toString())
continue
}
for (const [key, flag] of Object.entries(value)) {
if (!flag) {
continue
}
classNames.push(key)
}
}
return Array.from(new Set(classNames), c => c.trim()).join(' ')
}
function h<K extends keyof HTMLElementTagNameMap>(
tagName: K,
attributes: Partial<HTMLElementTagNameMap[K]>,
children: (Node | null | undefined | string | number | false)[]
): HTMLElementTagNameMap[K] {
const element = document.createElement(tagName)
for (const [key, value] of Object.entries(attributes)) {
element[key] = value
}
for (const node of children) {
if (node == null) {
continue
}
if (node == false) {
continue
}
if (node instanceof Node) {
element.appendChild(node)
} else {
element.innerText = node.toString()
}
}
return element
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment