UNPKG

@efflore/pulse

Version:

Pulse - scheduled DOM updates, debounced with requestAnimationFrame

172 lines (160 loc) 4.48 kB
import { enqueue } from './pulse' import { isComment, safeSetAttribute } from './util' /* === Common DOM Updates === */ /** * Create a new element with the given tag name and attributes * * @param element - The parent element to append the new element to * @param tag - The tag name of the new element * @param attributes - The attributes to set on the new element * @returns {Promise<Element>} */ const ce = <E extends Element>( parent: E, tag: string, attributes: Record<string, string> = {}, text?: string ): Promise<Element> => enqueue(() => { const child = document.createElement(tag) for (const [key, value] of Object.entries(attributes)) safeSetAttribute(child, key, value) if (text) child.textContent = text parent.append(child) return child }, [parent, 'e']) /** * Remove the given element from its parent * * @param element - The element to remove * @returns {Promise<null>} */ const re = <E extends Element>( element: E ): Promise<null> => enqueue(() => { element.remove() return null }, [element, 'r']) /** * Update the text content of the given element while preserving comments * * @param element - The element whose text content to update * @param text - The new text content * @returns {Promise<E>} */ const st = <E extends Element>( element: E, text: string ): Promise<E> => enqueue(() => { Array.from(element.childNodes) .filter(node => !isComment(node)) .forEach(node => node.remove()) element.append(document.createTextNode(text)) return element }, [element, 't']) /** * Update an attribute of the given element * * @param element - The element whose attribute to update * @param attribute - The attribute to update * @param value - The new value * @returns {Promise<E>} */ const sa = <E extends Element>( element: E, attribute: string, value: string ): Promise<E> => enqueue(() => { safeSetAttribute(element, attribute, value) return element }, [element, `a:${attribute}`]) /** * Remove an attribute of the given element * * @param element - The element whose attribute to remove * @param attribute - The attribute to remove * @returns {Promise<E>} */ const ra = <E extends Element>( element: E, attribute: string ): Promise<E> => enqueue(() => { element.removeAttribute(attribute) return element }, [element, `a:${attribute}`]) /** * Toggle an attribute of the given element * * @param element - The element whose attribute to toggle * @param attribute - The attribute to toggle * @param value - The new value * @returns {Promise<E>} */ const ta = <E extends Element>( element: E, attribute: string, value: boolean ): Promise<E> => enqueue(() => { element.toggleAttribute(attribute, value) return element }, [element, `a:${attribute}`]) /** * Toggle a class of the given element * * @param element - The element whose class to toggle * @param token - The class token to toggle * @param value - The new value * @returns {Promise<E>} */ const tc = <E extends Element>( element: E, token: string, value: boolean ): Promise<E> => enqueue(() => { element.classList.toggle(token, value) return element }, [element, `c:${token}`]) /** * Update a style property of the given element * * @param element - The element whose style property to update * @param property - The style property to update * @param value - The new value * @returns {Promise<E>} */ const ss = <E extends HTMLElement | SVGElement | MathMLElement>( element: E, property: string, value: string ): Promise<E> => enqueue(() => { element.style.setProperty(property, value) return element }, [element, `s:${property}`]) /** * Remove a style property of the given element * * @param element - The element to update * @param property - The style property to remove * @returns {Promise<E>} */ const rs = <E extends HTMLElement | SVGElement | MathMLElement>( element: E, property: string ): Promise<E> => enqueue(() => { element.style.removeProperty(property) return element }, [element, `s:${property}`]) /** * Replace the inner HTML of the given element * * @param element - The element whose inner HTML to update * @param content - The new inner HTML * @returns {Promise<E>} */ const dangerouslySetInnerHTML = <E extends Element>( element: E, content: string ): Promise<E> => enqueue(() => { element.innerHTML = content return element }, [element, 'h']) export { ce, re, st, sa, ra, ta, tc, ss, rs, dangerouslySetInnerHTML }