UNPKG

deleight

Version:

A library with 9 modules for writing more expressive web applications with traditional HTML, CSS and JavaScript.

310 lines (309 loc) 9.7 kB
/** * A few important functions for expressively and efficiently * working with elements on a web page. * * The functions here include: * * 5. {@link listener} an {@link apply} component (function) used to declaratively * attach listeners to specified elements within a tree. * * 6. {@link setter} an {@link apply} component (function) used to declaratively * set the values of element properties within a tree. * * 7. {@link assigner} an {@link apply} component (function) used to declaratively * set element sub-properties within a tree. * * 8. {@link attrSetter} an {@link apply} component (function) used to declaratively * set the values of element attributes within a tree. * * 9. Many more including {@link addTo}, {@link attr}, {@link prop} and * {@link selectorSetter}... * * The functions are used to build components which can be used with {@link apply}, * {@link process} or {@link Dom}. * * Pending tests. Please report bugs. * * @module */ import { IKey } from "../../types.js"; export interface IComponent { (elements: Element | Iterable<Element>, matcher?: IKey | Attr, ...args: any[]): any; } /** * Creates a function to be called with listener functions to return `apply * * @example * import { listener } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * * document.body.innerHTML = ` * <div>I am a div</div> * <p>I am a paragraph</p> * <section>I am a section <button>Btn1</button></section> * <article>I am an article <button>Btn2</button></article> * `; * * const componentFactory = listener('click', { once: true }) * * const btns = []; * const component = componentFactory(e => btns.push(e.target.textContent)); * * const subComponents = { button: component } * apply({ section: subComponents, article: subComponents }); * * @param event * @param options * @returns */ export declare function listener(event: keyof HTMLElementEventMap, options?: AddEventListenerOptions): (listener: EventListener) => (elements: Element | Iterable<Element>) => void; /** * Sets a property on 1 or more elements. * * @example * import { setter } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * * document.body.innerHTML = ` * <div>I am a div</div> * <p>I am a paragraph</p> * <section>I am a section <button>Btn1</button></section> * <article>I am an article <button>Btn2</button></article> * `; * * const val = setter('propKey'); * apply({ section: { button: val(20) }, article: { button: val(33) } }); * * @param key * @returns */ export declare function setter(key: IKey): (value: any) => (elements: Element | Iterable<Element>) => void; /** * Returns a component for setting multiple element properties or * nested properties (such as properties within Element.style. * * Pending tests. Please report bugs. * * @example * import { setters } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * * document.body.innerHTML = ` * <div>I am a div</div> * <p>I am a paragraph</p> * <section>I am a section <button>Btn1</button></section> * <article>I am an article <button>Btn2</button></article> * `; * * apply({ * section: { button: setters({ a: 1, b: 2 }) }, * article: { button: setters({ a: 5, b: 6 }) } * }); * * @param value * @returns */ export declare function setters(value: object): (elements: Element | Iterable<Element>) => void; /** * Alias (older name) for {@link setters} */ export declare const assigner: typeof setters; /** * Returns a component for setting single element attributes. * * Pending tests. Please report bugs. * * @example * import { attrSetter } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * * document.body.innerHTML = ` * <div>I am a div</div> * <p>I am a paragraph</p> * <section>I am a section <button>Btn1</button></section> * <article>I am an article <button>Btn2</button></article> * `; * * const val = attrSetter('attr') * apply({ section: { button: val(20) }, article: { button: val(33) } }); * * @param name * @returns */ export declare function attrSetter(name: string): (value: any) => (elements: Element | Iterable<Element>) => void; /** * Returns a component for setting multiple element attributes. * * Pending tests. Please report bugs. * * @example * import { attrsSetter } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * * document.body.innerHTML = ` * <div>I am a div</div> * <p>I am a paragraph</p> * <section>I am a section <button>Btn1</button></section> * <article>I am an article <button>Btn2</button></article> * `; * * apply({ * section: { button: attrsSetter({ a: '1', b: '2' }) }, * article: { button: attrsSetter({ a: '5', b: '6' }) } * }); * * @param values * @returns */ export declare function attrsSetter<T extends object>(values: T): (elements: Element | Iterable<Element>) => void; /** * Returns a component that sets the selected members as properties on the element using the keys * associated with the `selectorAttr`. * * @example * import { listener } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * * document.body.innerHTML = ` * <div>I am a div</div> * <p m-ember="about">I am a paragraph</p> * <section>I am a section <button m-ember="b1">Btn1</button></section> * <article>I am an article <button m-ember="b2">Btn2</button></article> * `; * * const comp = selectorSetter() * comp(body); * document.body.about; * document.body.b1; * document.body.b2; * * @param selectorAttr * @returns */ export declare function selectorSetter(selectorAttr?: string): (element: Element) => void; /** * Sets the selected members as properties on the element using the keys * associated with the `selectorAttr`. * * @example * import { selectMembers } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * * document.body.innerHTML = ` * <div>I am a div</div> * <p>I am a paragraph</p> * <section>I am a section <button m-ember="b1">Btn1</button></section> * <article>I am an article <button m-ember="b2">Btn2</button></article> * `; * * selectMembers(); * document.body.b1; * document.body.b2; * * * @param selectorAttr * @returns */ export declare function selectMembers<T extends object>(element?: Element, selectorAttr?: string): Element & T; /** * Components for setting up reactivity */ /** * A component that adds the element (or a value derived from it) * to an object used with primitives from the object/shared module. * * The optional wrapper is a function or key used to derive another * value from the element. If a function, it takes the element, * optional matcher and optional extra args as arg * and returns the derived value. If a key, fetches the element's * property with the key. * * @example * import { addTo } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * * document.body.innerHTML = ` * <div>I am a div</div> * <p>I am a paragraph</p> * <section>I am a section <button>Btn1</button></section> * <article>I am an article <button>Btn2</button></article> * `; * * const obj = { }; // a reactive object * apply({ * section: { button: addTo(obj, text) }, * article: { button: addTo(obj, text) } * }); * * @param object * @param key * @param wrapper * @returns */ export declare function addTo<T extends object, U = any>(object: T, key: IKey, wrapper?: IKey | ((element: Element, matcher?: IKey | Attr, ...args: any[]) => U)): (elements: Element | Iterable<Element>) => void; /** * Alias (older name) for {@link addTo} */ export declare const bind: typeof addTo; /** * A wrapper used with {@link addTo} to make the binding set attributes * instead of properties on the bound element. * * @example * import { addTo, attr } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * import { sets } from 'deleight/object/shared' * * document.body.innerHTML = ` * <div>I am a div</div> * <p>I am a paragraph</p> * <section>I am a section <button>Btn1</button></section> * <article>I am an article <button>Btn2</button></article> * `; * * const obj = { }; // a reactive object * * apply({ * section: { button: addTo(obj, 'a', attr) }, * article: { button: addTo(obj, 'color', 'styles') } * }); * * sets(obj, 'yellow'); * // document.querySelector('button').getAttribute('a'); // yellow * // document.body.lastElementChild.lastElementChild.style.color; // yellow * * sets(obj, 'green'); * // document.querySelector('button').getAttribute('a'); // green * // document.body.lastElementChild.lastElementChild.style.color; // green * * @param element */ export declare function attr(element: Element): Element; /** * Returns a component that applies all the specified components * to the matched element(s): * * @example * import { listener } from 'deleight/dom/components' * import { apply } from 'deleight/dom/apply' * * document.body.innerHTML = ` * <div>I am a div</div> * <p>I am a paragraph</p> * <section>I am a section <button>Btn1</button></section> * <article>I am an article <button>Btn2</button></article> * `; * * const a = setter('a'); * const b = setter('b'); * apply({ section: { button: all(a(2), b(3)) }, article: { button: all(a(62), b(53)) } }); * * @param components * @returns */ export declare function all(...components: IComponent[]): (elements: Element | Iterable<Element>, matcher?: IKey | Attr, ...args: any[]) => void; /** * Just an alias for the longish 'textContent' string. * */ export declare const text = "textContent";