155 lines
4.1 KiB
JavaScript
Raw Normal View History

2025-12-04 20:29:35 +01:00
/**
* @fileoverview Template Utilities for Rantii
* @author retoor <retoor@molodetz.nl>
* @description HTML template creation and manipulation helpers
* @keywords template, html, dom, element, create
*/
function createElement(tag, attributes = {}, children = []) {
const element = document.createElement(tag);
Object.entries(attributes).forEach(([key, value]) => {
if (key === 'className') {
element.className = value;
} else if (key === 'dataset') {
Object.entries(value).forEach(([dataKey, dataValue]) => {
element.dataset[dataKey] = dataValue;
});
} else if (key.startsWith('on') && typeof value === 'function') {
const eventName = key.substring(2).toLowerCase();
element.addEventListener(eventName, value);
} else if (key === 'style' && typeof value === 'object') {
Object.assign(element.style, value);
} else {
element.setAttribute(key, value);
}
});
children.forEach(child => {
if (typeof child === 'string') {
element.appendChild(document.createTextNode(child));
} else if (child instanceof Node) {
element.appendChild(child);
}
});
return element;
}
function html(strings, ...values) {
const template = document.createElement('template');
template.innerHTML = strings.reduce((result, string, i) => {
const value = values[i - 1];
if (value instanceof Node) {
return result + '<!--node-->' + string;
}
if (Array.isArray(value)) {
return result + value.map(v => v instanceof Node ? '<!--node-->' : String(v)).join('') + string;
}
return result + (value !== undefined ? String(value) : '') + string;
});
return template.content.cloneNode(true);
}
function createFragment(htmlString) {
const template = document.createElement('template');
template.innerHTML = htmlString.trim();
return template.content.cloneNode(true);
}
function clearElement(element) {
while (element.firstChild) {
element.removeChild(element.firstChild);
}
}
function replaceContent(element, newContent) {
clearElement(element);
if (typeof newContent === 'string') {
element.innerHTML = newContent;
} else if (newContent instanceof Node) {
element.appendChild(newContent);
}
}
function insertBefore(newElement, referenceElement) {
referenceElement.parentNode.insertBefore(newElement, referenceElement);
}
function insertAfter(newElement, referenceElement) {
referenceElement.parentNode.insertBefore(newElement, referenceElement.nextSibling);
}
function removeElement(element) {
if (element && element.parentNode) {
element.parentNode.removeChild(element);
}
}
function toggleClass(element, className, force) {
if (force !== undefined) {
element.classList.toggle(className, force);
} else {
element.classList.toggle(className);
}
}
function addClass(element, ...classNames) {
element.classList.add(...classNames);
}
function removeClass(element, ...classNames) {
element.classList.remove(...classNames);
}
function hasClass(element, className) {
return element.classList.contains(className);
}
function setAttributes(element, attributes) {
Object.entries(attributes).forEach(([key, value]) => {
if (value === null || value === undefined) {
element.removeAttribute(key);
} else {
element.setAttribute(key, value);
}
});
}
function getDataAttributes(element) {
return { ...element.dataset };
}
function show(element) {
element.style.display = '';
element.removeAttribute('hidden');
}
function hide(element) {
element.style.display = 'none';
}
function isVisible(element) {
return element.offsetParent !== null;
}
export {
createElement,
html,
createFragment,
clearElement,
replaceContent,
insertBefore,
insertAfter,
removeElement,
toggleClass,
addClass,
removeClass,
hasClass,
setAttributes,
getDataAttributes,
show,
hide,
isVisible
};