export function $(selector, context = document) {
return context.querySelector(selector);
}
export function $$(selector, context = document) {
return Array.from(context.querySelectorAll(selector));
}
export function createElement(tag, attributes = {}, children = []) {
const element = document.createElement(tag);
for (const [key, value] of Object.entries(attributes)) {
if (key === 'className') {
element.className = value;
} else if (key === 'style' && typeof value === 'object') {
Object.assign(element.style, value);
} else if (key.startsWith('on') && typeof value === 'function') {
const eventName = key.slice(2).toLowerCase();
element.addEventListener(eventName, value);
} else if (key === 'data' && typeof value === 'object') {
for (const [dataKey, dataValue] of Object.entries(value)) {
element.dataset[dataKey] = dataValue;
}
} else {
element.setAttribute(key, value);
}
}
for (const child of children) {
if (typeof child === 'string') {
element.appendChild(document.createTextNode(child));
} else if (child instanceof Node) {
element.appendChild(child);
}
}
return element;
}
export function html(strings, ...values) {
const template = document.createElement('template');
template.innerHTML = strings.reduce((acc, str, i) => {
const value = values[i] ?? '';
const escaped = typeof value === 'string'
? value.replace(/[&<>"']/g, (c) => ({
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
})[c])
: value;
return acc + str + escaped;
}, '');
return template.content;
}
export function addClass(element, ...classNames) {
element.classList.add(...classNames);
return element;
}
export function removeClass(element, ...classNames) {
element.classList.remove(...classNames);
return element;
}
export function toggleClass(element, className, force) {
element.classList.toggle(className, force);
return element;
}
export function hasClass(element, className) {
return element.classList.contains(className);
}
export function setAttributes(element, attributes) {
for (const [key, value] of Object.entries(attributes)) {
if (value === null || value === undefined) {
element.removeAttribute(key);
} else {
element.setAttribute(key, value);
}
}
return element;
}
export function empty(element) {
while (element.firstChild) {
element.removeChild(element.firstChild);
}
return element;
}
export function remove(element) {
element.parentNode?.removeChild(element);
return element;
}
export function insertAfter(newElement, referenceElement) {
referenceElement.parentNode.insertBefore(
newElement,
referenceElement.nextSibling
);
return newElement;
}
export function wrap(element, wrapper) {
element.parentNode.insertBefore(wrapper, element);
wrapper.appendChild(element);
return wrapper;
}