/**
 * 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";
