@zero-dependency/dom 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/html.d.ts CHANGED
@@ -4,11 +4,20 @@ type Attributes<T extends keyof HTMLElementTagNameMap> = Partial<{
4
4
  } & Omit<HTMLElementTagNameMap[T], 'style'>>;
5
5
  type Children = (string | Node | HTMLElement)[];
6
6
  /**
7
- * Create an element
8
- * @param tag The tag name of the element to create
9
- * @param attributes The attributes or children to set on the element
10
- * @param children The children to append to the element
11
- * @returns The created element
7
+ * Creates a new HTML element of the specified type and with the given attributes and children nodes.
8
+ *
9
+ * @param {T} tag
10
+ * The type of HTML element to create.
11
+ *
12
+ * @param {Attributes<T> | Children | HTMLElement} [attributes]
13
+ * The attributes or children nodes to add to the element.
14
+ *
15
+ * @param {...Children} children
16
+ * The children nodes to add to the element.
17
+ *
18
+ * @return {HTMLElementTagNameMap[T]}
19
+ * The newly created HTML element of the specified type.
20
+ *
12
21
  * @example
13
22
  * el('div', { id: 'foo' }, 'Hello world')
14
23
  * el('div', 'Hello world')
@@ -17,23 +26,22 @@ type Children = (string | Node | HTMLElement)[];
17
26
  * el('div', el('span', 'Hello'), el('span', 'world'))
18
27
  * el('div', el('span', 'Hello world'), 'world')
19
28
  */
20
- export declare function el<T extends keyof HTMLElementTagNameMap>(tag: T, attributes?: Attributes<T> | Children, ...children: Children): HTMLElementTagNameMap[T];
29
+ export declare function el<T extends keyof HTMLElementTagNameMap>(tag: T, attributes?: Attributes<T> | Children | HTMLElement, ...children: Children): HTMLElementTagNameMap[T];
21
30
  /**
22
- * Create a text node
23
- * @param text The string to create a text node from
31
+ * Creates a new Text node with the provided text.
32
+ *
33
+ * @param {string} text
34
+ * The text to create the Text node with.
35
+ *
36
+ * @return {Text}
37
+ * A new Text node with the provided text.
24
38
  */
25
39
  export declare function text(text: string): Text;
26
40
  /**
27
- * A non-breaking space
41
+ * Returns a Text object containing a non-breaking space character.
42
+ *
43
+ * @return {Text}
44
+ * A Text object containing a non-breaking space character.
28
45
  */
29
46
  export declare function nbsp(): Text;
30
- type WindowEvent<T extends string> = T extends keyof WindowEventMap ? WindowEventMap[T] : Event;
31
- /**
32
- * Add an event listener to an element
33
- * @param el The element to add the event listener to
34
- * @param type The event type to listen for
35
- * @param callback The callback to call when the event is fired
36
- * @param options The options to pass to `addEventListener`
37
- */
38
- export declare function addEvent<T extends string>(el: HTMLElement, type: T, callback: (event: WindowEvent<T>) => void, options?: boolean | AddEventListenerOptions): () => void;
39
47
  export {};
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function l(r,e,...t){const n=document.createElement(r);return typeof e=="string"?n.append(c(e)):Array.isArray(e)?n.append(...e):(Object.assign(n,e),Object.assign(n.style,e?.style)),t.length&&n.append(...t),n}function c(r){return document.createTextNode(r)}function u(){return c(" ")}function d(r,e,t,n){return r.addEventListener(e,t,n),()=>r.removeEventListener(e,t,n)}class p{#e={};constructor(){const{history:e,location:t}=window,{pushState:n,replaceState:s}=e;e.pushState=(...o)=>{n.apply(e,o),this.#e?.pushState(t,o[0])},e.replaceState=(...o)=>{s.apply(e,o),this.#e?.replaceState(t,o[0])},window.addEventListener("popstate",o=>{this.#e?.popState(t,o)})}on(e,t){return this.#e[e]=t,()=>this.off(e)}off(e){delete this.#e[e]}}function i(r,e,t){const n=new MutationObserver((s,o)=>{for(const a of s)e(a,o)});return n.observe(r,{childList:!0,subtree:!0,...t}),()=>n.disconnect()}function f(r,e=document.documentElement){return new Promise(t=>{i(e,(n,s)=>{const o=e.querySelector(r);o&&(s.disconnect(),t(o))})})}exports.LocationObserver=p;exports.addEvent=d;exports.el=l;exports.nbsp=u;exports.observeElement=i;exports.text=c;exports.waitElement=f;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function u(t,e,...o){const n=document.createElement(t);return typeof e=="string"?n.append(s(e)):Array.isArray(e)?o.unshift(...e):(Object.assign(n,e),Object.assign(n.style,e?.style)),o.length&&n.append(...o),n}function s(t){return document.createTextNode(t)}function a(){return s(" ")}function p(t){const{history:e,location:o}=window,{pushState:n,replaceState:r}=e;e.pushState=(...c)=>{n.apply(e,c),t.onPush(o,c[0])},e.replaceState=(...c)=>{r.apply(e,c),t.onReplace(o,c[0])}}function i(t,e,o){const n=new MutationObserver((r,c)=>{for(const l of r)e(l,c)});return n.observe(t,{childList:!0,subtree:!0,...o}),()=>n.disconnect()}function f(t,e=document.body){return new Promise(o=>{i(e,(n,r)=>{const c=e.querySelector(t);c&&(r.disconnect(),o(c))})})}exports.el=u;exports.locationObserver=p;exports.nbsp=a;exports.observeElement=i;exports.text=s;exports.waitElement=f;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/html.ts","../src/location-observer.ts","../src/mutation-observer.ts"],"sourcesContent":["import * as CSS from 'csstype'\n\n// prettier-ignore\ntype Attributes<T extends keyof HTMLElementTagNameMap> = Partial<{\n style: CSS.Properties\n} & Omit<HTMLElementTagNameMap[T], 'style'>>\n\ntype Children = (string | Node | HTMLElement)[]\n\n/**\n * Create an element\n * @param tag The tag name of the element to create\n * @param attributes The attributes or children to set on the element\n * @param children The children to append to the element\n * @returns The created element\n * @example\n * el('div', { id: 'foo' }, 'Hello world')\n * el('div', 'Hello world')\n * el('div', [el('span', 'Hello'), el('span', 'world')])\n * el('div', el('span', 'Hello world'))\n * el('div', el('span', 'Hello'), el('span', 'world'))\n * el('div', el('span', 'Hello world'), 'world')\n */\nexport function el<T extends keyof HTMLElementTagNameMap>(\n tag: T,\n attributes?: Attributes<T> | Children,\n ...children: Children\n): HTMLElementTagNameMap[T] {\n const el = document.createElement(tag)\n\n if (typeof attributes === 'string') {\n el.append(text(attributes))\n } else if (Array.isArray(attributes)) {\n el.append(...attributes)\n } else {\n Object.assign(el, attributes)\n Object.assign(el.style, attributes?.style)\n }\n\n if (children.length) {\n el.append(...children)\n }\n\n return el\n}\n\n/**\n * Create a text node\n * @param text The string to create a text node from\n */\nexport function text(text: string): Text {\n return document.createTextNode(text)\n}\n\n/**\n * A non-breaking space\n */\nexport function nbsp(): Text {\n return text('\\u00a0')\n}\n\ntype WindowEvent<T extends string> = T extends keyof WindowEventMap\n ? WindowEventMap[T]\n : Event\n\n/**\n * Add an event listener to an element\n * @param el The element to add the event listener to\n * @param type The event type to listen for\n * @param callback The callback to call when the event is fired\n * @param options The options to pass to `addEventListener`\n */\nexport function addEvent<T extends string>(\n el: HTMLElement,\n type: T,\n callback: (event: WindowEvent<T>) => void,\n options?: boolean | AddEventListenerOptions\n): () => void\nexport function addEvent(\n el: HTMLElement,\n type: string,\n cb: (event: Event) => void,\n options?: boolean | AddEventListenerOptions\n): () => void {\n el.addEventListener(type, cb, options)\n return () => el.removeEventListener(type, cb, options)\n}\n","type LocationCallback<T = any> = (location: Location, args: T) => void\n\ntype Events<T> = {\n pushState: LocationCallback<T>\n replaceState: LocationCallback<T>\n popState: LocationCallback<\n Omit<PopStateEvent, 'state'> & { readonly state: T }\n >\n}\n\n/**\n * Observe changes to the location\n * @example\n * const observer = new LocationObserver<{ id: string }>()\n * observer.on('pushState', (location, state) => {\n * console.log(state.id)\n * })\n */\nexport class LocationObserver<T> {\n #events = {} as Record<keyof Events<T>, LocationCallback<any>>\n\n constructor() {\n const { history, location } = window\n const { pushState, replaceState } = history\n\n history.pushState = (...args) => {\n pushState.apply(history, args)\n this.#events?.pushState(location, args[0])\n }\n\n history.replaceState = (...args) => {\n replaceState.apply(history, args)\n this.#events?.replaceState(location, args[0])\n }\n\n window.addEventListener('popstate', (event) => {\n this.#events?.popState(location, event)\n })\n }\n\n on<E extends keyof Events<T>>(event: E, listener: Events<T>[E]): () => void {\n this.#events[event] = listener\n return () => this.off(event)\n }\n\n off<E extends keyof Events<T>>(event: E): void {\n delete this.#events[event]\n }\n}\n","type Disconnect = () => void\n\n/**\n * Observe mutations on an element\n * @param el The element to observe\n * @param callback The callback to call when a mutation occurs\n * @param options The options to pass to the `MutationObserver`\n * @returns A function to disconnect the observer\n */\nexport function observeElement<T extends Element = Element>(\n el: T,\n callback: (mutation: MutationRecord, observer: MutationObserver) => void,\n options?: MutationObserverInit\n): Disconnect {\n const observe = new MutationObserver((mutations, observer) => {\n for (const mutation of mutations) {\n callback(mutation, observer)\n }\n })\n\n observe.observe(el, {\n childList: true,\n subtree: true,\n ...options\n })\n\n return () => observe.disconnect()\n}\n\n/**\n * Wait for an element to appear in the DOM\n * @param selector The selector to wait for\n * @param target The element to search in\n * @returns A promise that resolves when the element is found\n */\nexport function waitElement<T extends Element = Element>(\n selector: string,\n target = document.documentElement\n): Promise<T> {\n return new Promise((resolve) => {\n observeElement(target, (_, observer) => {\n const el = target.querySelector<T>(selector)\n if (el) {\n observer.disconnect()\n resolve(el)\n }\n })\n })\n}\n"],"names":["el","tag","attributes","children","text","nbsp","addEvent","type","cb","options","LocationObserver","#events","history","location","pushState","replaceState","args","event","listener","observeElement","callback","observe","mutations","observer","mutation","waitElement","selector","target","resolve","_"],"mappings":"gFAuBgB,SAAAA,EACdC,EACAC,KACGC,EACuB,CACpBH,MAAAA,EAAK,SAAS,cAAcC,CAAG,EAEjC,OAAA,OAAOC,GAAe,SACxBF,EAAG,OAAOI,EAAKF,CAAU,CAAC,EACjB,MAAM,QAAQA,CAAU,EACjCF,EAAG,OAAO,GAAGE,CAAU,GAEhB,OAAA,OAAOF,EAAIE,CAAU,EAC5B,OAAO,OAAOF,EAAG,MAAOE,GAAY,KAAK,GAGvCC,EAAS,QACXH,EAAG,OAAO,GAAGG,CAAQ,EAGhBH,CACT,CAMO,SAASI,EAAKA,EAAoB,CAChC,OAAA,SAAS,eAAeA,CAAI,CACrC,CAKO,SAASC,GAAa,CAC3B,OAAOD,EAAK,GAAQ,CACtB,CAmBO,SAASE,EACdN,EACAO,EACAC,EACAC,EACY,CACZT,OAAAA,EAAG,iBAAiBO,EAAMC,EAAIC,CAAO,EAC9B,IAAMT,EAAG,oBAAoBO,EAAMC,EAAIC,CAAO,CACvD,CCpEO,MAAMC,CAAoB,CAC/BC,GAAU,CAAA,EAEV,aAAc,CACN,KAAA,CAAE,QAAAC,EAAS,SAAAC,CAAa,EAAA,OACxB,CAAE,UAAAC,EAAW,aAAAC,CAAiB,EAAAH,EAE5BA,EAAA,UAAY,IAAII,IAAS,CACrBF,EAAA,MAAMF,EAASI,CAAI,EAC7B,KAAKL,IAAS,UAAUE,EAAUG,EAAK,CAAC,CAAC,CAAA,EAGnCJ,EAAA,aAAe,IAAII,IAAS,CACrBD,EAAA,MAAMH,EAASI,CAAI,EAChC,KAAKL,IAAS,aAAaE,EAAUG,EAAK,CAAC,CAAC,CAAA,EAGvC,OAAA,iBAAiB,WAAaC,GAAU,CACxC,KAAAN,IAAS,SAASE,EAAUI,CAAK,CAAA,CACvC,CACH,CAEA,GAA8BA,EAAUC,EAAoC,CACrE,YAAAP,GAAQM,CAAK,EAAIC,EACf,IAAM,KAAK,IAAID,CAAK,CAC7B,CAEA,IAA+BA,EAAgB,CACtC,OAAA,KAAKN,GAAQM,CAAK,CAC3B,CACF,CCvCgB,SAAAE,EACdnB,EACAoB,EACAX,EACY,CACZ,MAAMY,EAAU,IAAI,iBAAiB,CAACC,EAAWC,IAAa,CAC5D,UAAWC,KAAYF,EACrBF,EAASI,EAAUD,CAAQ,CAC7B,CACD,EAED,OAAAF,EAAQ,QAAQrB,EAAI,CAClB,UAAW,GACX,QAAS,GACT,GAAGS,CAAA,CACJ,EAEM,IAAMY,EAAQ,YACvB,CAQO,SAASI,EACdC,EACAC,EAAS,SAAS,gBACN,CACL,OAAA,IAAI,QAASC,GAAY,CACfT,EAAAQ,EAAQ,CAACE,EAAGN,IAAa,CAChC,MAAAvB,EAAK2B,EAAO,cAAiBD,CAAQ,EACvC1B,IACFuB,EAAS,WAAW,EACpBK,EAAQ5B,CAAE,EACZ,CACD,CAAA,CACF,CACH"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/html.ts","../src/location-observer.ts","../src/mutation-observer.ts"],"sourcesContent":["import * as CSS from 'csstype'\n\n// prettier-ignore\ntype Attributes<T extends keyof HTMLElementTagNameMap> = Partial<{\n style: CSS.Properties\n} & Omit<HTMLElementTagNameMap[T], 'style'>>\n\ntype Children = (string | Node | HTMLElement)[]\n\n/**\n * Creates a new HTML element of the specified type and with the given attributes and children nodes.\n *\n * @param {T} tag\n * The type of HTML element to create.\n *\n * @param {Attributes<T> | Children | HTMLElement} [attributes]\n * The attributes or children nodes to add to the element.\n *\n * @param {...Children} children\n * The children nodes to add to the element.\n *\n * @return {HTMLElementTagNameMap[T]}\n * The newly created HTML element of the specified type.\n *\n * @example\n * el('div', { id: 'foo' }, 'Hello world')\n * el('div', 'Hello world')\n * el('div', [el('span', 'Hello'), el('span', 'world')])\n * el('div', el('span', 'Hello world'))\n * el('div', el('span', 'Hello'), el('span', 'world'))\n * el('div', el('span', 'Hello world'), 'world')\n */\nexport function el<T extends keyof HTMLElementTagNameMap>(\n tag: T,\n attributes?: Attributes<T> | Children | HTMLElement,\n ...children: Children\n): HTMLElementTagNameMap[T] {\n const el = document.createElement(tag)\n\n if (typeof attributes === 'string') {\n el.append(text(attributes))\n } else if (Array.isArray(attributes)) {\n children.unshift(...attributes)\n } else {\n Object.assign(el, attributes)\n Object.assign(el.style, attributes?.style)\n }\n\n if (children.length) {\n el.append(...children)\n }\n\n return el\n}\n\n/**\n * Creates a new Text node with the provided text.\n *\n * @param {string} text\n * The text to create the Text node with.\n *\n * @return {Text}\n * A new Text node with the provided text.\n */\nexport function text(text: string): Text {\n return document.createTextNode(text)\n}\n\n/**\n * Returns a Text object containing a non-breaking space character.\n *\n * @return {Text}\n * A Text object containing a non-breaking space character.\n */\nexport function nbsp(): Text {\n return text('\\u00a0')\n}\n","type LocationCallback<T = any> = (location: Location, args: T) => void\n\ntype Events<T> = {\n onPush: LocationCallback<T>\n onReplace: LocationCallback<T>\n}\n\n/**\n * Observes changes to the browser's location and history, and invokes\n * the specified callbacks when the user navigates to a new page or updates the\n * current page's state.\n *\n * @param {Events<T>} events\n * An object that contains optional callback functions for push and replace actions.\n *\n * @example\n * locationObserver<{ id: string }>({\n * onPush: (location, args) => {},\n * onReplace: (location, args) => {}\n * })\n */\nexport function locationObserver<T>(events: Events<T>): void {\n const { history, location } = window\n const { pushState, replaceState } = history\n\n history.pushState = (...args) => {\n pushState.apply(history, args)\n events.onPush(location, args[0])\n }\n\n history.replaceState = (...args) => {\n replaceState.apply(history, args)\n events.onReplace(location, args[0])\n }\n}\n","type Disconnect = () => void\n\n/**\n * Observes changes to an element and invokes a callback function for each mutation.\n *\n * @param {T extends Element} el\n * The element to observe.\n *\n * @param {(mutation: MutationRecord, observer: MutationObserver) => void} callback\n * The function to call when a mutation occurs.\n *\n * @param {MutationObserverInit} [options]\n * Optional configuration options for the MutationObserver.\n *\n * @returns {Disconnect}\n * A function that disconnects the observer.\n *\n * @example\n * const disconnect = observeElement(document.body, (mutation, observer) => {\n * console.log(mutation)\n * })\n */\nexport function observeElement<T extends Element = Element>(\n el: T,\n callback: (mutation: MutationRecord, observer: MutationObserver) => void,\n options?: MutationObserverInit\n): Disconnect {\n const observe = new MutationObserver((mutations, observer) => {\n for (const mutation of mutations) {\n callback(mutation, observer)\n }\n })\n\n observe.observe(el, {\n childList: true,\n subtree: true,\n ...options\n })\n\n return () => observe.disconnect()\n}\n\n/**\n * Returns a Promise that resolves with the first element matching the given selector\n * in the specified target, or rejects if no matches are found.\n *\n * @param {string} selector\n * The CSS selector to match.\n *\n * @param {Element} [target=document.documentElement]\n * The element to search in.\n *\n * @returns {Promise<T>}\n * A Promise that resolves with the first matching element.\n *\n * @example\n * const el = await waitElement('.foo')\n */\nexport function waitElement<T extends Element = Element>(\n selector: string,\n target: Element = document.body\n): Promise<T> {\n return new Promise((resolve) => {\n observeElement(target, (_, observer) => {\n const el = target.querySelector<T>(selector)\n if (el) {\n observer.disconnect()\n resolve(el)\n }\n })\n })\n}\n"],"names":["el","tag","attributes","children","text","nbsp","locationObserver","events","history","location","pushState","replaceState","args","observeElement","callback","options","observe","mutations","observer","mutation","waitElement","selector","target","resolve","_"],"mappings":"gFAgCgB,SAAAA,EACdC,EACAC,KACGC,EACuB,CACpBH,MAAAA,EAAK,SAAS,cAAcC,CAAG,EAEjC,OAAA,OAAOC,GAAe,SACxBF,EAAG,OAAOI,EAAKF,CAAU,CAAC,EACjB,MAAM,QAAQA,CAAU,EACxBC,EAAA,QAAQ,GAAGD,CAAU,GAEvB,OAAA,OAAOF,EAAIE,CAAU,EAC5B,OAAO,OAAOF,EAAG,MAAOE,GAAY,KAAK,GAGvCC,EAAS,QACXH,EAAG,OAAO,GAAGG,CAAQ,EAGhBH,CACT,CAWO,SAASI,EAAKA,EAAoB,CAChC,OAAA,SAAS,eAAeA,CAAI,CACrC,CAQO,SAASC,GAAa,CAC3B,OAAOD,EAAK,GAAQ,CACtB,CCvDO,SAASE,EAAoBC,EAAyB,CACrD,KAAA,CAAE,QAAAC,EAAS,SAAAC,CAAa,EAAA,OACxB,CAAE,UAAAC,EAAW,aAAAC,CAAiB,EAAAH,EAE5BA,EAAA,UAAY,IAAII,IAAS,CACrBF,EAAA,MAAMF,EAASI,CAAI,EAC7BL,EAAO,OAAOE,EAAUG,EAAK,CAAC,CAAC,CAAA,EAGzBJ,EAAA,aAAe,IAAII,IAAS,CACrBD,EAAA,MAAMH,EAASI,CAAI,EAChCL,EAAO,UAAUE,EAAUG,EAAK,CAAC,CAAC,CAAA,CAEtC,CCZgB,SAAAC,EACdb,EACAc,EACAC,EACY,CACZ,MAAMC,EAAU,IAAI,iBAAiB,CAACC,EAAWC,IAAa,CAC5D,UAAWC,KAAYF,EACrBH,EAASK,EAAUD,CAAQ,CAC7B,CACD,EAED,OAAAF,EAAQ,QAAQhB,EAAI,CAClB,UAAW,GACX,QAAS,GACT,GAAGe,CAAA,CACJ,EAEM,IAAMC,EAAQ,YACvB,CAkBO,SAASI,EACdC,EACAC,EAAkB,SAAS,KACf,CACL,OAAA,IAAI,QAASC,GAAY,CACfV,EAAAS,EAAQ,CAACE,EAAGN,IAAa,CAChC,MAAAlB,EAAKsB,EAAO,cAAiBD,CAAQ,EACvCrB,IACFkB,EAAS,WAAW,EACpBK,EAAQvB,CAAE,EACZ,CACD,CAAA,CACF,CACH"}
package/dist/index.js CHANGED
@@ -1,61 +1,46 @@
1
- function u(r, e, ...t) {
2
- const n = document.createElement(r);
3
- return typeof e == "string" ? n.append(c(e)) : Array.isArray(e) ? n.append(...e) : (Object.assign(n, e), Object.assign(n.style, e?.style)), t.length && n.append(...t), n;
1
+ function l(t, e, ...o) {
2
+ const n = document.createElement(t);
3
+ return typeof e == "string" ? n.append(s(e)) : Array.isArray(e) ? o.unshift(...e) : (Object.assign(n, e), Object.assign(n.style, e?.style)), o.length && n.append(...o), n;
4
4
  }
5
- function c(r) {
6
- return document.createTextNode(r);
5
+ function s(t) {
6
+ return document.createTextNode(t);
7
7
  }
8
8
  function p() {
9
- return c(" ");
9
+ return s(" ");
10
10
  }
11
- function l(r, e, t, n) {
12
- return r.addEventListener(e, t, n), () => r.removeEventListener(e, t, n);
11
+ function a(t) {
12
+ const { history: e, location: o } = window, { pushState: n, replaceState: r } = e;
13
+ e.pushState = (...c) => {
14
+ n.apply(e, c), t.onPush(o, c[0]);
15
+ }, e.replaceState = (...c) => {
16
+ r.apply(e, c), t.onReplace(o, c[0]);
17
+ };
13
18
  }
14
- class d {
15
- #e = {};
16
- constructor() {
17
- const { history: e, location: t } = window, { pushState: n, replaceState: s } = e;
18
- e.pushState = (...o) => {
19
- n.apply(e, o), this.#e?.pushState(t, o[0]);
20
- }, e.replaceState = (...o) => {
21
- s.apply(e, o), this.#e?.replaceState(t, o[0]);
22
- }, window.addEventListener("popstate", (o) => {
23
- this.#e?.popState(t, o);
24
- });
25
- }
26
- on(e, t) {
27
- return this.#e[e] = t, () => this.off(e);
28
- }
29
- off(e) {
30
- delete this.#e[e];
31
- }
32
- }
33
- function a(r, e, t) {
34
- const n = new MutationObserver((s, o) => {
35
- for (const i of s)
36
- e(i, o);
19
+ function u(t, e, o) {
20
+ const n = new MutationObserver((r, c) => {
21
+ for (const i of r)
22
+ e(i, c);
37
23
  });
38
- return n.observe(r, {
24
+ return n.observe(t, {
39
25
  childList: !0,
40
26
  subtree: !0,
41
- ...t
27
+ ...o
42
28
  }), () => n.disconnect();
43
29
  }
44
- function f(r, e = document.documentElement) {
45
- return new Promise((t) => {
46
- a(e, (n, s) => {
47
- const o = e.querySelector(r);
48
- o && (s.disconnect(), t(o));
30
+ function f(t, e = document.body) {
31
+ return new Promise((o) => {
32
+ u(e, (n, r) => {
33
+ const c = e.querySelector(t);
34
+ c && (r.disconnect(), o(c));
49
35
  });
50
36
  });
51
37
  }
52
38
  export {
53
- d as LocationObserver,
54
- l as addEvent,
55
- u as el,
39
+ l as el,
40
+ a as locationObserver,
56
41
  p as nbsp,
57
- a as observeElement,
58
- c as text,
42
+ u as observeElement,
43
+ s as text,
59
44
  f as waitElement
60
45
  };
61
46
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/html.ts","../src/location-observer.ts","../src/mutation-observer.ts"],"sourcesContent":["import * as CSS from 'csstype'\n\n// prettier-ignore\ntype Attributes<T extends keyof HTMLElementTagNameMap> = Partial<{\n style: CSS.Properties\n} & Omit<HTMLElementTagNameMap[T], 'style'>>\n\ntype Children = (string | Node | HTMLElement)[]\n\n/**\n * Create an element\n * @param tag The tag name of the element to create\n * @param attributes The attributes or children to set on the element\n * @param children The children to append to the element\n * @returns The created element\n * @example\n * el('div', { id: 'foo' }, 'Hello world')\n * el('div', 'Hello world')\n * el('div', [el('span', 'Hello'), el('span', 'world')])\n * el('div', el('span', 'Hello world'))\n * el('div', el('span', 'Hello'), el('span', 'world'))\n * el('div', el('span', 'Hello world'), 'world')\n */\nexport function el<T extends keyof HTMLElementTagNameMap>(\n tag: T,\n attributes?: Attributes<T> | Children,\n ...children: Children\n): HTMLElementTagNameMap[T] {\n const el = document.createElement(tag)\n\n if (typeof attributes === 'string') {\n el.append(text(attributes))\n } else if (Array.isArray(attributes)) {\n el.append(...attributes)\n } else {\n Object.assign(el, attributes)\n Object.assign(el.style, attributes?.style)\n }\n\n if (children.length) {\n el.append(...children)\n }\n\n return el\n}\n\n/**\n * Create a text node\n * @param text The string to create a text node from\n */\nexport function text(text: string): Text {\n return document.createTextNode(text)\n}\n\n/**\n * A non-breaking space\n */\nexport function nbsp(): Text {\n return text('\\u00a0')\n}\n\ntype WindowEvent<T extends string> = T extends keyof WindowEventMap\n ? WindowEventMap[T]\n : Event\n\n/**\n * Add an event listener to an element\n * @param el The element to add the event listener to\n * @param type The event type to listen for\n * @param callback The callback to call when the event is fired\n * @param options The options to pass to `addEventListener`\n */\nexport function addEvent<T extends string>(\n el: HTMLElement,\n type: T,\n callback: (event: WindowEvent<T>) => void,\n options?: boolean | AddEventListenerOptions\n): () => void\nexport function addEvent(\n el: HTMLElement,\n type: string,\n cb: (event: Event) => void,\n options?: boolean | AddEventListenerOptions\n): () => void {\n el.addEventListener(type, cb, options)\n return () => el.removeEventListener(type, cb, options)\n}\n","type LocationCallback<T = any> = (location: Location, args: T) => void\n\ntype Events<T> = {\n pushState: LocationCallback<T>\n replaceState: LocationCallback<T>\n popState: LocationCallback<\n Omit<PopStateEvent, 'state'> & { readonly state: T }\n >\n}\n\n/**\n * Observe changes to the location\n * @example\n * const observer = new LocationObserver<{ id: string }>()\n * observer.on('pushState', (location, state) => {\n * console.log(state.id)\n * })\n */\nexport class LocationObserver<T> {\n #events = {} as Record<keyof Events<T>, LocationCallback<any>>\n\n constructor() {\n const { history, location } = window\n const { pushState, replaceState } = history\n\n history.pushState = (...args) => {\n pushState.apply(history, args)\n this.#events?.pushState(location, args[0])\n }\n\n history.replaceState = (...args) => {\n replaceState.apply(history, args)\n this.#events?.replaceState(location, args[0])\n }\n\n window.addEventListener('popstate', (event) => {\n this.#events?.popState(location, event)\n })\n }\n\n on<E extends keyof Events<T>>(event: E, listener: Events<T>[E]): () => void {\n this.#events[event] = listener\n return () => this.off(event)\n }\n\n off<E extends keyof Events<T>>(event: E): void {\n delete this.#events[event]\n }\n}\n","type Disconnect = () => void\n\n/**\n * Observe mutations on an element\n * @param el The element to observe\n * @param callback The callback to call when a mutation occurs\n * @param options The options to pass to the `MutationObserver`\n * @returns A function to disconnect the observer\n */\nexport function observeElement<T extends Element = Element>(\n el: T,\n callback: (mutation: MutationRecord, observer: MutationObserver) => void,\n options?: MutationObserverInit\n): Disconnect {\n const observe = new MutationObserver((mutations, observer) => {\n for (const mutation of mutations) {\n callback(mutation, observer)\n }\n })\n\n observe.observe(el, {\n childList: true,\n subtree: true,\n ...options\n })\n\n return () => observe.disconnect()\n}\n\n/**\n * Wait for an element to appear in the DOM\n * @param selector The selector to wait for\n * @param target The element to search in\n * @returns A promise that resolves when the element is found\n */\nexport function waitElement<T extends Element = Element>(\n selector: string,\n target = document.documentElement\n): Promise<T> {\n return new Promise((resolve) => {\n observeElement(target, (_, observer) => {\n const el = target.querySelector<T>(selector)\n if (el) {\n observer.disconnect()\n resolve(el)\n }\n })\n })\n}\n"],"names":["el","tag","attributes","children","text","nbsp","addEvent","type","cb","options","LocationObserver","#events","history","location","pushState","replaceState","args","event","listener","observeElement","callback","observe","mutations","observer","mutation","waitElement","selector","target","resolve","_"],"mappings":"AAuBgB,SAAAA,EACdC,GACAC,MACGC,GACuB;AACpBH,QAAAA,IAAK,SAAS,cAAcC,CAAG;AAEjC,SAAA,OAAOC,KAAe,WACxBF,EAAG,OAAOI,EAAKF,CAAU,CAAC,IACjB,MAAM,QAAQA,CAAU,IACjCF,EAAG,OAAO,GAAGE,CAAU,KAEhB,OAAA,OAAOF,GAAIE,CAAU,GAC5B,OAAO,OAAOF,EAAG,OAAOE,GAAY,KAAK,IAGvCC,EAAS,UACXH,EAAG,OAAO,GAAGG,CAAQ,GAGhBH;AACT;AAMO,SAASI,EAAKA,GAAoB;AAChC,SAAA,SAAS,eAAeA,CAAI;AACrC;AAKO,SAASC,IAAa;AAC3B,SAAOD,EAAK,GAAQ;AACtB;AAmBO,SAASE,EACdN,GACAO,GACAC,GACAC,GACY;AACZT,SAAAA,EAAG,iBAAiBO,GAAMC,GAAIC,CAAO,GAC9B,MAAMT,EAAG,oBAAoBO,GAAMC,GAAIC,CAAO;AACvD;ACpEO,MAAMC,EAAoB;AAAA,EAC/BC,KAAU,CAAA;AAAA,EAEV,cAAc;AACN,UAAA,EAAE,SAAAC,GAAS,UAAAC,EAAa,IAAA,QACxB,EAAE,WAAAC,GAAW,cAAAC,EAAiB,IAAAH;AAE5B,IAAAA,EAAA,YAAY,IAAII,MAAS;AACrB,MAAAF,EAAA,MAAMF,GAASI,CAAI,GAC7B,KAAKL,IAAS,UAAUE,GAAUG,EAAK,CAAC,CAAC;AAAA,IAAA,GAGnCJ,EAAA,eAAe,IAAII,MAAS;AACrB,MAAAD,EAAA,MAAMH,GAASI,CAAI,GAChC,KAAKL,IAAS,aAAaE,GAAUG,EAAK,CAAC,CAAC;AAAA,IAAA,GAGvC,OAAA,iBAAiB,YAAY,CAACC,MAAU;AACxC,WAAAN,IAAS,SAASE,GAAUI,CAAK;AAAA,IAAA,CACvC;AAAA,EACH;AAAA,EAEA,GAA8BA,GAAUC,GAAoC;AACrE,gBAAAP,GAAQM,CAAK,IAAIC,GACf,MAAM,KAAK,IAAID,CAAK;AAAA,EAC7B;AAAA,EAEA,IAA+BA,GAAgB;AACtC,WAAA,KAAKN,GAAQM,CAAK;AAAA,EAC3B;AACF;ACvCgB,SAAAE,EACdnB,GACAoB,GACAX,GACY;AACZ,QAAMY,IAAU,IAAI,iBAAiB,CAACC,GAAWC,MAAa;AAC5D,eAAWC,KAAYF;AACrB,MAAAF,EAASI,GAAUD,CAAQ;AAAA,EAC7B,CACD;AAED,SAAAF,EAAQ,QAAQrB,GAAI;AAAA,IAClB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,GAAGS;AAAA,EAAA,CACJ,GAEM,MAAMY,EAAQ;AACvB;AAQO,SAASI,EACdC,GACAC,IAAS,SAAS,iBACN;AACL,SAAA,IAAI,QAAQ,CAACC,MAAY;AACf,IAAAT,EAAAQ,GAAQ,CAACE,GAAGN,MAAa;AAChC,YAAAvB,IAAK2B,EAAO,cAAiBD,CAAQ;AAC3C,MAAI1B,MACFuB,EAAS,WAAW,GACpBK,EAAQ5B,CAAE;AAAA,IACZ,CACD;AAAA,EAAA,CACF;AACH;"}
1
+ {"version":3,"file":"index.js","sources":["../src/html.ts","../src/location-observer.ts","../src/mutation-observer.ts"],"sourcesContent":["import * as CSS from 'csstype'\n\n// prettier-ignore\ntype Attributes<T extends keyof HTMLElementTagNameMap> = Partial<{\n style: CSS.Properties\n} & Omit<HTMLElementTagNameMap[T], 'style'>>\n\ntype Children = (string | Node | HTMLElement)[]\n\n/**\n * Creates a new HTML element of the specified type and with the given attributes and children nodes.\n *\n * @param {T} tag\n * The type of HTML element to create.\n *\n * @param {Attributes<T> | Children | HTMLElement} [attributes]\n * The attributes or children nodes to add to the element.\n *\n * @param {...Children} children\n * The children nodes to add to the element.\n *\n * @return {HTMLElementTagNameMap[T]}\n * The newly created HTML element of the specified type.\n *\n * @example\n * el('div', { id: 'foo' }, 'Hello world')\n * el('div', 'Hello world')\n * el('div', [el('span', 'Hello'), el('span', 'world')])\n * el('div', el('span', 'Hello world'))\n * el('div', el('span', 'Hello'), el('span', 'world'))\n * el('div', el('span', 'Hello world'), 'world')\n */\nexport function el<T extends keyof HTMLElementTagNameMap>(\n tag: T,\n attributes?: Attributes<T> | Children | HTMLElement,\n ...children: Children\n): HTMLElementTagNameMap[T] {\n const el = document.createElement(tag)\n\n if (typeof attributes === 'string') {\n el.append(text(attributes))\n } else if (Array.isArray(attributes)) {\n children.unshift(...attributes)\n } else {\n Object.assign(el, attributes)\n Object.assign(el.style, attributes?.style)\n }\n\n if (children.length) {\n el.append(...children)\n }\n\n return el\n}\n\n/**\n * Creates a new Text node with the provided text.\n *\n * @param {string} text\n * The text to create the Text node with.\n *\n * @return {Text}\n * A new Text node with the provided text.\n */\nexport function text(text: string): Text {\n return document.createTextNode(text)\n}\n\n/**\n * Returns a Text object containing a non-breaking space character.\n *\n * @return {Text}\n * A Text object containing a non-breaking space character.\n */\nexport function nbsp(): Text {\n return text('\\u00a0')\n}\n","type LocationCallback<T = any> = (location: Location, args: T) => void\n\ntype Events<T> = {\n onPush: LocationCallback<T>\n onReplace: LocationCallback<T>\n}\n\n/**\n * Observes changes to the browser's location and history, and invokes\n * the specified callbacks when the user navigates to a new page or updates the\n * current page's state.\n *\n * @param {Events<T>} events\n * An object that contains optional callback functions for push and replace actions.\n *\n * @example\n * locationObserver<{ id: string }>({\n * onPush: (location, args) => {},\n * onReplace: (location, args) => {}\n * })\n */\nexport function locationObserver<T>(events: Events<T>): void {\n const { history, location } = window\n const { pushState, replaceState } = history\n\n history.pushState = (...args) => {\n pushState.apply(history, args)\n events.onPush(location, args[0])\n }\n\n history.replaceState = (...args) => {\n replaceState.apply(history, args)\n events.onReplace(location, args[0])\n }\n}\n","type Disconnect = () => void\n\n/**\n * Observes changes to an element and invokes a callback function for each mutation.\n *\n * @param {T extends Element} el\n * The element to observe.\n *\n * @param {(mutation: MutationRecord, observer: MutationObserver) => void} callback\n * The function to call when a mutation occurs.\n *\n * @param {MutationObserverInit} [options]\n * Optional configuration options for the MutationObserver.\n *\n * @returns {Disconnect}\n * A function that disconnects the observer.\n *\n * @example\n * const disconnect = observeElement(document.body, (mutation, observer) => {\n * console.log(mutation)\n * })\n */\nexport function observeElement<T extends Element = Element>(\n el: T,\n callback: (mutation: MutationRecord, observer: MutationObserver) => void,\n options?: MutationObserverInit\n): Disconnect {\n const observe = new MutationObserver((mutations, observer) => {\n for (const mutation of mutations) {\n callback(mutation, observer)\n }\n })\n\n observe.observe(el, {\n childList: true,\n subtree: true,\n ...options\n })\n\n return () => observe.disconnect()\n}\n\n/**\n * Returns a Promise that resolves with the first element matching the given selector\n * in the specified target, or rejects if no matches are found.\n *\n * @param {string} selector\n * The CSS selector to match.\n *\n * @param {Element} [target=document.documentElement]\n * The element to search in.\n *\n * @returns {Promise<T>}\n * A Promise that resolves with the first matching element.\n *\n * @example\n * const el = await waitElement('.foo')\n */\nexport function waitElement<T extends Element = Element>(\n selector: string,\n target: Element = document.body\n): Promise<T> {\n return new Promise((resolve) => {\n observeElement(target, (_, observer) => {\n const el = target.querySelector<T>(selector)\n if (el) {\n observer.disconnect()\n resolve(el)\n }\n })\n })\n}\n"],"names":["el","tag","attributes","children","text","nbsp","locationObserver","events","history","location","pushState","replaceState","args","observeElement","callback","options","observe","mutations","observer","mutation","waitElement","selector","target","resolve","_"],"mappings":"AAgCgB,SAAAA,EACdC,GACAC,MACGC,GACuB;AACpBH,QAAAA,IAAK,SAAS,cAAcC,CAAG;AAEjC,SAAA,OAAOC,KAAe,WACxBF,EAAG,OAAOI,EAAKF,CAAU,CAAC,IACjB,MAAM,QAAQA,CAAU,IACxBC,EAAA,QAAQ,GAAGD,CAAU,KAEvB,OAAA,OAAOF,GAAIE,CAAU,GAC5B,OAAO,OAAOF,EAAG,OAAOE,GAAY,KAAK,IAGvCC,EAAS,UACXH,EAAG,OAAO,GAAGG,CAAQ,GAGhBH;AACT;AAWO,SAASI,EAAKA,GAAoB;AAChC,SAAA,SAAS,eAAeA,CAAI;AACrC;AAQO,SAASC,IAAa;AAC3B,SAAOD,EAAK,GAAQ;AACtB;ACvDO,SAASE,EAAoBC,GAAyB;AACrD,QAAA,EAAE,SAAAC,GAAS,UAAAC,EAAa,IAAA,QACxB,EAAE,WAAAC,GAAW,cAAAC,EAAiB,IAAAH;AAE5B,EAAAA,EAAA,YAAY,IAAII,MAAS;AACrB,IAAAF,EAAA,MAAMF,GAASI,CAAI,GAC7BL,EAAO,OAAOE,GAAUG,EAAK,CAAC,CAAC;AAAA,EAAA,GAGzBJ,EAAA,eAAe,IAAII,MAAS;AACrB,IAAAD,EAAA,MAAMH,GAASI,CAAI,GAChCL,EAAO,UAAUE,GAAUG,EAAK,CAAC,CAAC;AAAA,EAAA;AAEtC;ACZgB,SAAAC,EACdb,GACAc,GACAC,GACY;AACZ,QAAMC,IAAU,IAAI,iBAAiB,CAACC,GAAWC,MAAa;AAC5D,eAAWC,KAAYF;AACrB,MAAAH,EAASK,GAAUD,CAAQ;AAAA,EAC7B,CACD;AAED,SAAAF,EAAQ,QAAQhB,GAAI;AAAA,IAClB,WAAW;AAAA,IACX,SAAS;AAAA,IACT,GAAGe;AAAA,EAAA,CACJ,GAEM,MAAMC,EAAQ;AACvB;AAkBO,SAASI,EACdC,GACAC,IAAkB,SAAS,MACf;AACL,SAAA,IAAI,QAAQ,CAACC,MAAY;AACf,IAAAV,EAAAS,GAAQ,CAACE,GAAGN,MAAa;AAChC,YAAAlB,IAAKsB,EAAO,cAAiBD,CAAQ;AAC3C,MAAIrB,MACFkB,EAAS,WAAW,GACpBK,EAAQvB,CAAE;AAAA,IACZ,CACD;AAAA,EAAA,CACF;AACH;"}
@@ -1,23 +1,21 @@
1
1
  type LocationCallback<T = any> = (location: Location, args: T) => void;
2
2
  type Events<T> = {
3
- pushState: LocationCallback<T>;
4
- replaceState: LocationCallback<T>;
5
- popState: LocationCallback<Omit<PopStateEvent, 'state'> & {
6
- readonly state: T;
7
- }>;
3
+ onPush: LocationCallback<T>;
4
+ onReplace: LocationCallback<T>;
8
5
  };
9
6
  /**
10
- * Observe changes to the location
7
+ * Observes changes to the browser's location and history, and invokes
8
+ * the specified callbacks when the user navigates to a new page or updates the
9
+ * current page's state.
10
+ *
11
+ * @param {Events<T>} events
12
+ * An object that contains optional callback functions for push and replace actions.
13
+ *
11
14
  * @example
12
- * const observer = new LocationObserver<{ id: string }>()
13
- * observer.on('pushState', (location, state) => {
14
- * console.log(state.id)
15
+ * locationObserver<{ id: string }>({
16
+ * onPush: (location, args) => {},
17
+ * onReplace: (location, args) => {}
15
18
  * })
16
19
  */
17
- export declare class LocationObserver<T> {
18
- #private;
19
- constructor();
20
- on<E extends keyof Events<T>>(event: E, listener: Events<T>[E]): () => void;
21
- off<E extends keyof Events<T>>(event: E): void;
22
- }
20
+ export declare function locationObserver<T>(events: Events<T>): void;
23
21
  export {};
@@ -1,17 +1,40 @@
1
1
  type Disconnect = () => void;
2
2
  /**
3
- * Observe mutations on an element
4
- * @param el The element to observe
5
- * @param callback The callback to call when a mutation occurs
6
- * @param options The options to pass to the `MutationObserver`
7
- * @returns A function to disconnect the observer
3
+ * Observes changes to an element and invokes a callback function for each mutation.
4
+ *
5
+ * @param {T extends Element} el
6
+ * The element to observe.
7
+ *
8
+ * @param {(mutation: MutationRecord, observer: MutationObserver) => void} callback
9
+ * The function to call when a mutation occurs.
10
+ *
11
+ * @param {MutationObserverInit} [options]
12
+ * Optional configuration options for the MutationObserver.
13
+ *
14
+ * @returns {Disconnect}
15
+ * A function that disconnects the observer.
16
+ *
17
+ * @example
18
+ * const disconnect = observeElement(document.body, (mutation, observer) => {
19
+ * console.log(mutation)
20
+ * })
8
21
  */
9
22
  export declare function observeElement<T extends Element = Element>(el: T, callback: (mutation: MutationRecord, observer: MutationObserver) => void, options?: MutationObserverInit): Disconnect;
10
23
  /**
11
- * Wait for an element to appear in the DOM
12
- * @param selector The selector to wait for
13
- * @param target The element to search in
14
- * @returns A promise that resolves when the element is found
24
+ * Returns a Promise that resolves with the first element matching the given selector
25
+ * in the specified target, or rejects if no matches are found.
26
+ *
27
+ * @param {string} selector
28
+ * The CSS selector to match.
29
+ *
30
+ * @param {Element} [target=document.documentElement]
31
+ * The element to search in.
32
+ *
33
+ * @returns {Promise<T>}
34
+ * A Promise that resolves with the first matching element.
35
+ *
36
+ * @example
37
+ * const el = await waitElement('.foo')
15
38
  */
16
- export declare function waitElement<T extends Element = Element>(selector: string, target?: HTMLElement): Promise<T>;
39
+ export declare function waitElement<T extends Element = Element>(selector: string, target?: Element): Promise<T>;
17
40
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zero-dependency/dom",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "DOM utils",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",