@twobirds/microcomponents 0.1.20 → 0.1.21

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/events.js ADDED
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+ export function getMcEventName(eventName) {
3
+ return '_mc' + eventName[0].toUpperCase() + eventName.substring(1);
4
+ }
5
+ export function off(domNode, eventName, handler) {
6
+ domNode.removeEventListener(getMcEventName(eventName), handler);
7
+ }
8
+ export function on(domNode, eventName, handler, once = false) {
9
+ domNode.addEventListener(getMcEventName(eventName), handler, { capture: false, once });
10
+ return handler;
11
+ }
12
+ export function one(domNode, eventName, handler) {
13
+ on(domNode, eventName, handler, true);
14
+ return handler;
15
+ }
16
+ export class BubbleController {
17
+ stopped = false;
18
+ constructor() { }
19
+ stop() {
20
+ this.stopped = true;
21
+ }
22
+ }
23
+ export function trigger(domNode, event, data = {}, bubble = 'l', controller) {
24
+ const eventName = /^_mc/.test(event) ? event : getMcEventName(event), bubbleController = controller ? controller : new BubbleController(), ev = new CustomEvent(eventName, {
25
+ detail: { data, control: bubbleController },
26
+ bubbles: false,
27
+ });
28
+ if (bubbleController.stopped)
29
+ return;
30
+ if (/l/.test(bubble)) {
31
+ domNode.dispatchEvent(ev);
32
+ ev.stopImmediatePropagation();
33
+ if (bubbleController.stopped)
34
+ return;
35
+ }
36
+ if (/[ud]/.test(bubble)) {
37
+ if (bubble.indexOf('l') === -1) {
38
+ bubble += 'l';
39
+ }
40
+ setTimeout(() => {
41
+ if (bubble.indexOf('u') > -1) {
42
+ let parentMc = domNode.parentElement?.closest('[data-mc]');
43
+ if (parentMc) {
44
+ parentMc?._mc.trigger(eventName, data, bubble, bubbleController);
45
+ }
46
+ }
47
+ if (bubble.indexOf('d') > -1) {
48
+ let childNodes = domNode._mc.children();
49
+ if (childNodes) {
50
+ childNodes.forEach((_mc) => _mc.trigger(eventName, data, bubble));
51
+ }
52
+ }
53
+ }, 0);
54
+ }
55
+ }
package/dist/events.ts ADDED
@@ -0,0 +1,158 @@
1
+ 'use strict';
2
+
3
+ import { HTMLMcElement, DC } from './MC.js';
4
+
5
+ /**
6
+ @hidden
7
+ Converts a standard event name to its microcomponent-prefixed variant.
8
+
9
+ This utility is used internally to namespace custom events (e.g., 'Click' → '_mcClick').
10
+
11
+ @param {string} eventName - The original event name (e.g., 'click', 'update').
12
+ @returns {string} The microcomponent-prefixed event name.
13
+ */
14
+ export function getMcEventName(eventName: string): string {
15
+ return '_mc' + eventName[0].toUpperCase() + eventName.substring(1);
16
+ }
17
+ /**
18
+ Removes a previously attached event handler from the DOM node. See {@link on} and {@link one}.
19
+
20
+ Uses internal microcomponent-prefixed naming for event handlers.
21
+
22
+ @param {Node} domNode - The DOM element from which to remove the listener.
23
+ @param {string} eventName - The name of the event (e.g., 'click', 'update').
24
+ @param {EventListenerOrEventListenerObject} handler - The listener function or object to detach.
25
+ */
26
+ export function off(domNode: Node, eventName: string, handler: EventListenerOrEventListenerObject) {
27
+ domNode.removeEventListener(getMcEventName(eventName), handler);
28
+ }
29
+
30
+ /**
31
+ Attaches a persistent event listener that will fire every time the specified event occurs.
32
+
33
+ @param {Node} domNode - The DOM element to attach the listener to.
34
+ @param {string} eventName - The name of the event (e.g., 'click', 'update').
35
+ @param {EventListenerOrEventListenerObject} handler - The callback function or object to invoke on each event.
36
+ @param {boolean} [once=false] - If true, remove the listener after first invocation.
37
+ @returns {EventListenerOrEventListenerObject} The attached handler reference. Useful for later deletion with {@link off}.
38
+ */
39
+ export function on(
40
+ domNode: Node,
41
+ eventName: string,
42
+ handler: EventListenerOrEventListenerObject,
43
+ once: boolean = false
44
+ ): EventListenerOrEventListenerObject {
45
+ domNode.addEventListener(getMcEventName(eventName), handler, { capture: false, once });
46
+ return handler;
47
+ }
48
+ /**
49
+ Attaches an event listener that will fire only once.
50
+
51
+ Internally calls {@link on} with the `once` flag set to true. The handler
52
+ is automatically removed after its first invocation.
53
+
54
+ @param {Node} domNode - The DOM element to attach the listener to.
55
+ @param {string} eventName - The name of the event (e.g., 'click', 'update').
56
+ @param {EventListenerOrEventListenerObject} handler - The callback function or object to invoke once.
57
+ @returns {EventListenerOrEventListenerObject} The attached one-time handler reference. Useful for later deletion with {@link off}.
58
+ */
59
+ export function one(
60
+ domNode: Node,
61
+ eventName: string,
62
+ handler: EventListenerOrEventListenerObject
63
+ ): EventListenerOrEventListenerObject {
64
+ on(domNode, eventName, handler, true);
65
+ return handler;
66
+ }
67
+
68
+ /**
69
+ @hidden
70
+ A controller object used to manage and potentially abort event bubbling.
71
+
72
+ The `trigger()` function accepts an optional instance of this class,
73
+ allowing the handler to call `.stop()` before or during dispatch to
74
+ prevent further propagation in either direction (up/down).
75
+ */
76
+ export class BubbleController {
77
+ stopped = false;
78
+ constructor() {}
79
+ /**
80
+ Signals that event bubbling should be halted.
81
+
82
+ After calling this method, subsequent `trigger()` calls will abort
83
+ before dispatching the event to any targets.
84
+ */
85
+ stop() {
86
+ this.stopped = true;
87
+ }
88
+ }
89
+
90
+ /**
91
+ Creates and dispatches a custom event on the specified DOM node.
92
+
93
+ The event is namespaced with an `_mc` prefix by default, unless already prefixed.
94
+ Supports bidirectional bubbling (up/down the DOM tree) based on the `bubble` parameter:
95
+ - 'l': local dispatch only
96
+ - 'u': bubble up towards ancestors
97
+ - 'd': bubble down to descendants
98
+
99
+ The optional `controller` allows aborting event propagation via `.stop()`.
100
+
101
+ @param {HTMLElement} domNode - The DOM element on which to trigger the event.
102
+ @param {string} event - The name of the event (will be prefixed if needed).
103
+ @param {any} [data={}] - Additional data payload attached to `event.detail.data`.
104
+ @param {string} [bubble='l'] - Bubbling direction ('l', 'u', 'd' or combinations).
105
+ @param {BubbleController} [controller] - Optional controller for managing bubbling behavior.
106
+ */
107
+ export function trigger(
108
+ domNode: HTMLElement,
109
+ event: string,
110
+ data: any = {},
111
+ bubble: string = 'l', // direction of bubbling
112
+ controller?: BubbleController
113
+ ) {
114
+ //console.warn('trigger args', ...arguments);
115
+
116
+ const eventName = /^_mc/.test(event) ? event : getMcEventName(event),
117
+ bubbleController = controller ? controller : new BubbleController(),
118
+ ev = new CustomEvent(eventName, {
119
+ detail: { data, control: bubbleController },
120
+ bubbles: false,
121
+ });
122
+
123
+ if (bubbleController.stopped) return;
124
+
125
+ if (/l/.test(bubble)) {
126
+ domNode.dispatchEvent(ev);
127
+ ev.stopImmediatePropagation();
128
+
129
+ if (bubbleController.stopped) return;
130
+ }
131
+
132
+ // bubble if up or down is indicated
133
+ if (/[ud]/.test(bubble)) {
134
+ // add missing 'l', or else no handlers are executed
135
+ if (bubble.indexOf('l') === -1) {
136
+ bubble += 'l';
137
+ }
138
+
139
+ setTimeout(() => {
140
+ // bubble up towards document.body
141
+ if (bubble.indexOf('u') > -1) {
142
+ let parentMc: HTMLMcElement | null | undefined =
143
+ domNode.parentElement?.closest('[data-mc]');
144
+ if (parentMc) {
145
+ parentMc?._mc.trigger(eventName, data, bubble, bubbleController);
146
+ }
147
+ }
148
+
149
+ // bubble down towards DOM children
150
+ if (bubble.indexOf('d') > -1) {
151
+ let childNodes: DC[] | null = (domNode as HTMLMcElement)._mc.children();
152
+ if (childNodes) {
153
+ childNodes.forEach((_mc: DC) => _mc.trigger(eventName, data, bubble)); // event multiplex - dont carry bubble controller
154
+ }
155
+ }
156
+ }, 0);
157
+ }
158
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"formValues.d.ts","sourceRoot":"","sources":["formValues.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAsB,MAAM,cAAc,CAAC;AA6L/D,wBAAgB,UAAU,CACzB,YAAY,EAAE,WAAW,EACzB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,WAAW,GAAG,UAAU,QAkB7B"}
1
+ {"version":3,"file":"formValues.d.ts","sourceRoot":"","sources":["../src/formValues.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,WAAW,EAAE,MAAM,cAAc,CAAC;AA4V/D,wBAAgB,UAAU,CACzB,YAAY,EAAE,WAAW,EACzB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,WAAW,GAAG,UAAU,QAkB7B"}
@@ -1,6 +1,5 @@
1
- 'use strict';
2
- import { copyGettersSetters } from './helpers.js';
3
1
  import { DC } from './MC.js';
2
+ import { copyGettersSetters } from './helpers.js';
4
3
  import { observe } from './observables.js';
5
4
  const getInputName = (e) => {
6
5
  return e.tagName.toLowerCase();
@@ -61,8 +60,8 @@ class SelectHandler extends InputBase {
61
60
  this.#multi = e.multiple;
62
61
  }
63
62
  get val() {
64
- const that = this, ret = [];
65
- [...that.#e.querySelectorAll('option')]
63
+ const ret = [];
64
+ [...this.#e.querySelectorAll('option')]
66
65
  .filter((o) => o.selected)
67
66
  .forEach((o) => {
68
67
  ret.push(o.value);
@@ -72,9 +71,8 @@ class SelectHandler extends InputBase {
72
71
  return ret.length ? ret[0] : '';
73
72
  }
74
73
  set val(value) {
75
- const that = this;
76
74
  value = typeof value === 'string' ? [value] : value;
77
- [...that.#e.querySelectorAll('option')].forEach((o) => {
75
+ [...this.#e.querySelectorAll('option')].forEach((o) => {
78
76
  if (value.indexOf(o.value) > -1) {
79
77
  o.selected = true;
80
78
  }
@@ -1 +1 @@
1
- var t={d:(e,r)=>{for(var n in r)t.o(r,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:r[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};function r(t){let e={};return[...Object.keys(t)].sort().forEach((n=>{var s;(s=t[n])&&s.constructor&&s.constructor===Object?e[n]=r(t[n]):e[n]=t[n]})),e}function n(t,e=!0){let s={};return[...Object.getOwnPropertyNames(t)].forEach((e=>{if(t[e]instanceof Object){const r=n(t[e],!1);s[e]={};for(const t in r)s[e+"."+t]=r[t]}else s[e]=t[e]})),e?r(s):s}function s(t,e){const r=Object.getOwnPropertyDescriptors(t);for(const[t,n]of Object.entries(r))("get"in n||"set"in n)&&Object.defineProperty(e,t,n)}t.d(e,{R:()=>S});const a=new Function("try {return this===window;}catch(e){ return false;}");function c(t){return t&&t instanceof HTMLElement}function o(t){return"_mc"+t[0].toUpperCase()+t.substring(1)}function l(t,e,r,n=!1){return t.addEventListener(o(e),r,{capture:!1,once:n}),r}class i{stopped=!1;constructor(){}stop(){this.stopped=!0}}function u(t,e,r={},n="l",s){const a=/^_mc/.test(e)?e:o(e),c=s||new i,l=new CustomEvent(a,{detail:{data:r,control:c},bubbles:!1});c.stopped||/l/.test(n)&&(t.dispatchEvent(l),l.stopImmediatePropagation(),c.stopped)||/[ud]/.test(n)&&(-1===n.indexOf("l")&&(n+="l"),setTimeout((()=>{if(n.indexOf("u")>-1){let e=t.parentElement?.closest("[data-mc]");e&&e?._mc.trigger(a,r,n,c)}if(n.indexOf("d")>-1){let e=t._mc.children();e&&e.forEach((t=>t.trigger(a,r,n)))}}),0))}class f{_target;constructor(t){var e;this._target=new WeakRef(t||{}),function(t){if(!a()||t.constructor===h)return;const e=t.target;if(e instanceof HTMLElement){let r=t;Object.getOwnPropertyNames(r.constructor.prototype).filter((t=>/^(on[A-Z]|one[A-Z])/.test(t)&&"function"==typeof r.constructor.prototype[t])).forEach((t=>{let n=/^one/.test(t),s=t.replace(/^on[e]{0,1}/,""),a=s.toLowerCase();if("on"+a in e){let n=e=>{r[t](e)};e.addEventListener(a,n)}else l(e,s,(e=>{r[t](e)}),n)}))}}(this),e=this,setTimeout((()=>{e.constructor!==h&&e.trigger("Init")}),0)}get target(){return this._target.deref()}}class h extends f{constructor(t){super(t)}static add(t,e,r={}){return function(t,e,r={}){let n=t;n._mc||(n._mc=new h(t));const s=n._mc;return e.length&&!s[e]&&(s[e]=r,t instanceof HTMLElement&&!t.getAttribute("data-mc")&&t.setAttribute("data-mc","")),n}(t,e,r)}static remove(t,e){!function(t,e){if(!e)return;const r=t?._mc||{};r&&r[e]&&delete r[e],!Object.keys(r).length&&t instanceof HTMLElement&&t.hasAttribute("data-mc")&&t.removeAttribute("data-mc")}(t,e)}off(t,e){!function(t,e,r){t.removeEventListener(o(e),r)}(this.target,t,e)}on(t,e){return l(this.target,t,e)}one(t,e){return function(t,e,r){return l(t,e,r,!0),r}(this.target,t,e)}trigger(t,e={},r="l",n){u(this.target,t,e,r,n)}ancestors(){let t=this?.target,e=[];if(!c(t))return[];for(;t=t.closest("[data-mc]");)t?._mc&&e.push(t?._mc);return e.length?e:null}closest(){let t=this.target;return c(t)&&t.closest("[data-mc]")?._mc||null}children(){let t=this?.target;return c(t)?function(t){const e=Math.random().toString().replace(".",""),r='[data-mc]:not([temp_id="'+e+'"] [data-mc] [data-mc])';t.setAttribute("temp_id",e);const n=[...t.querySelectorAll(r)].filter((t=>!!t._mc)).map((t=>t._mc));return t.removeAttribute("temp_id"),n.length?n:null}(t):null}descendants(){const t=this?.target;if(!c(t))return[];const e=[...t.querySelectorAll("[data-mc]")].filter((t=>!!t._mc)).map((t=>t._mc));return e.length?e:null}}function d(t){return null!=t&&"object"==typeof t}function p(t){let e=new Set,r=/\{[^\{\}]*\}/g;return(t.getAttributeNames?t.getAttributeNames():[]).filter((e=>t.getAttribute(e)?.match(r))).forEach((e=>{let n=new Set(t.getAttribute(e)?.match(r));n.forEach((t=>n.add(t.replace(/[\{\}]/g,""))))})),[...t.childNodes].filter((t=>3===t.nodeType&&(t.nodeValue||"").match(r))).forEach((t=>{(t.nodeValue||"").match(r).forEach((t=>{e.add(t.replace(/[\{\}]/g,""))}))})),[...e].map((t=>t.replace(/[\{\}]/g,"")))}new Set;const m=[HTMLInputElement,HTMLSelectElement,HTMLTextAreaElement];class g extends h{data={};oldDisplay="";constructor(t){super(t),p(t).forEach((t=>this.data[t]="")),v(this),this.#t()}#t(){let t=this.target,e=!1;(t.getAttributeNames?t.getAttributeNames():[]).filter((e=>t.getAttribute(e)?.match(/\{[^\{\}]*\}/g))).forEach((e=>{let r=new Set(t.getAttribute(e)?.match(/\{[^\{\}]*\}/g));var n;this.data.observe((n=t.getAttribute(e),s=>{let a=n;r.forEach((t=>{a=a.replace(t,s[t.replace(/[\{\}]/g,"")])})),t.setAttribute(e,a)}))})),[...t.childNodes].filter((t=>3===t.nodeType&&(t.nodeValue||"").match(/\{[^\{\}]*\}/g))).forEach((r=>{e=!0;let n=new Set(r.nodeValue.match(/\{[^\{\}]*\}/g));this.data.observe((e=>s=>{let a=e;n.forEach((t=>{a=a.replace(t,s[t.replace(/[\{\}]/g,"")])})),this.oldDisplay?t.style=this.oldDisplay:t.removeAttribute("style"),delete this.oldDisplay,r.nodeValue=a})(r.nodeValue)),this.oldDisplay=t.getAttribute("style")||"",e&&!m.includes(t.constructor)&&"FIELDSET"!==t.tagName&&(t.style.display="none")}))}onData(t){let e={};Object.keys(t.detail.data).forEach((r=>{this.data.hasOwnProperty(r)&&(e[r]=t.detail.data[r])})),JSON.stringify(e)!==JSON.stringify(this.data)&&Object.assign(this.data,e)}}const b={};function y(t){let e=t.constructor.name;return b[e]||function(t){const e=t.constructor,r=e.name;let s=class extends e{#e=!0;#r=[];constructor(t){super(t),this.constructor.callbacks=[],d(t)&&Object.getOwnPropertyNames(t).forEach((e=>{this[e]=t[e]}))}get callbacks(){return this.#r}set callbacks(t){this.#r=t}observe(t){return this.#r.push(t),this}bind(t){if(d(this.valueOf())){!function(t){var e;(e=t,[e].concat([...e.querySelectorAll("*")]).filter((t=>!!p(t).length)).filter((t=>"STYLE"!==t?.tagName)).reverse()).forEach((t=>{t?._mc?._placeholders||h.add(t,"_placeholders",new g(t))}))}(t);const e=[t,...t.querySelectorAll("[data-mc]")].filter((t=>!!t?._mc?._placeholders)),r=function(t){let r=n(t);e.forEach((t=>{t&&u(t,"data",r)}))};this.#r.push(r),this.notify()}else console.warn("IGNORED - cannot bind a non-Object to the dom, IS:",typeof this.valueOf(),this);return this}notify(t){let e=d(this.valueOf())&&this.valueOf()instanceof Array==0?structuredClone(Object.assign({},this)):this.valueOf();return void 0!==t&&(this.#e=t),this.#e&&this.#r.forEach((t=>{t(e)})),this}};return b[r]=s,s}(t)}const v=(t,e)=>((e?[e]:[...Object.getOwnPropertyNames(t)]).forEach((e=>{if(t.hasOwnProperty(e)&&"function"!=typeof t[e]&&!t?.[e]?.constructor?.prototype?.observe){if("_"===e[0]||void 0===t?.[e])return t;let r=t[e],a=new(y(r))(r),c=function(){let t;return()=>{clearTimeout(t),t=setTimeout((function(){!function(){a.notify()}(...arguments)}),0)}}();Object.defineProperty(t,e,{enumerable:!0,get(){if(d(a.valueOf())){let t=structuredClone(Object.assign({},a));setTimeout((function(){var e,r;e=structuredClone(Object.assign({},a)),r=t,JSON.stringify(n(e))!==JSON.stringify(n(r))&&c()}),0)}return a},set(t){if(typeof t==typeof a.valueOf())if(d(a.valueOf())&&a.valueOf()instanceof Array==0)void 0===a?.constructor?.prototype?.observe&&(a=new(y(t))(structuredClone(Object.assign({},t))),s(t,a)),Object.assign(a,t),a.notify();else{let e=a.valueOf(),r=a.callbacks;t!==e&&(a=new(y(t))(t),a.callbacks=r,c())}else console.warn("IGNORED - cannot change observable types, IS:",typeof a.valueOf(),a,"- CANNOT BECOME:",typeof t)}}),t[e]=r}})),t);class O{constructor(t){}}class E extends O{#n;constructor(t){super(t),this.#n=t}get val(){return new FormData(this.#n.form).get(this.#n.name)}set val(t){[...this.#n.form.querySelectorAll(`input[type="radio"][name="${this.#n.name}"]`)].filter((e=>e.getAttribute("value")===t)).shift().checked=!0}}class w extends O{#n;constructor(t){super(t),this.#n=t}get val(){return this.#n.checked}set val(t){this.#n.checked=t}}class A extends O{#n;constructor(t){super(t),this.#n=t}get val(){return this.#n.value}set val(t){this.#n.value=t}}class _ extends O{#n;#s=!1;constructor(t){super(t),this.#n=t,this.#s=t.multiple}get val(){const t=[];return[...this.#n.querySelectorAll("option")].filter((t=>t.selected)).forEach((e=>{t.push(e.value)})),this.#s?t:t.length?t[0]:""}set val(t){t="string"==typeof t?[t]:t,[...this.#n.querySelectorAll("option")].forEach((e=>{t.indexOf(e.value)>-1?e.selected=!0:e.selected=!1}))}}class k extends O{#n;constructor(t){super(t),this.#n=t}get val(){return this.#n.value||""}set val(t){this.#n.value=t}}const j=t=>{let e=[...(t||document).querySelectorAll("input,select,textarea")],r={};return e.forEach((t=>{const e=t.getAttribute("name");if(e){let n=!1;switch((t=>t.tagName.toLowerCase())(t)){case"input":switch(t.type){case"radio":n=new E(t);break;case"checkbox":n=new w(t);break;default:n=new A(t)}break;case"select":n=new _(t);break;case"textarea":n=new k(t);break;default:console.warn("handler missing:",e,"for",t.tagName.toLowerCase(),t)}n&&(h.add(t,e,n),Object.defineProperty(r,e,{enumerable:!0,configurable:!0,get:()=>n.val,set:t=>{n.val!==t&&(n.val=t)}}))}})),r};function S(t,e,r){let n=j(r);t[e]=Object.assign({},n),v(t,e),s(n,t[e]),[...r.querySelectorAll("input, textarea, select")].forEach((r=>{r.addEventListener("input",(r=>{t[e].notify()}))}))}var N=e.R;export{N as formValues};
1
+ var t={d:(e,r)=>{for(var n in r)t.o(r,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:r[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};function r(t){return"_mc"+t[0].toUpperCase()+t.substring(1)}function n(t,e,n,s=!1){return t.addEventListener(r(e),n,{capture:!1,once:s}),n}t.d(e,{R:()=>S});class s{stopped=!1;constructor(){}stop(){this.stopped=!0}}function a(t,e,n={},a="l",c){const o=/^_mc/.test(e)?e:r(e),l=c||new s,i=new CustomEvent(o,{detail:{data:n,control:l},bubbles:!1});l.stopped||/l/.test(a)&&(t.dispatchEvent(i),i.stopImmediatePropagation(),l.stopped)||/[ud]/.test(a)&&(-1===a.indexOf("l")&&(a+="l"),setTimeout((()=>{if(a.indexOf("u")>-1){let e=t.parentElement?.closest("[data-mc]");e&&e?._mc.trigger(o,n,a,l)}if(a.indexOf("d")>-1){let e=t._mc.children();e&&e.forEach((t=>t.trigger(o,n,a)))}}),0))}const c=new Function("try {return this===window;}catch(e){ return false;}");function o(t){return t&&t instanceof HTMLElement}class l{_target;constructor(t){var e;this._target=new WeakRef(t||{}),function(t){if(!c()||t.constructor===i)return;const e=t.target;if(e instanceof HTMLElement){let r=t;Object.getOwnPropertyNames(r.constructor.prototype).filter((t=>/^(on[A-Z]|one[A-Z])/.test(t)&&"function"==typeof r.constructor.prototype[t])).forEach((t=>{let s=/^one/.test(t),a=t.replace(/^on[e]{0,1}/,""),c=a.toLowerCase();if("on"+c in e){let n=e=>{r[t](e)};e.addEventListener(c,n)}else n(e,a,(e=>{r[t](e)}),s)}))}}(this),e=this,setTimeout((()=>{e.constructor!==i&&e.trigger("Init")}),0)}get target(){return this._target.deref()}}class i extends l{constructor(t){super(t)}static add(t,e,r={}){return function(t,e,r={}){let n=t;n._mc||(n._mc=new i(t));const s=n._mc;return e.length&&!s[e]&&(s[e]=r,t instanceof HTMLElement&&!t.getAttribute("data-mc")&&t.setAttribute("data-mc","")),n}(t,e,r)}static remove(t,e){!function(t,e){if(!e)return;const r=t?._mc||{};r&&r[e]&&delete r[e],!Object.keys(r).length&&t instanceof HTMLElement&&t.hasAttribute("data-mc")&&t.removeAttribute("data-mc")}(t,e)}off(t,e){!function(t,e,n){t.removeEventListener(r(e),n)}(this.target,t,e)}on(t,e){return n(this.target,t,e)}one(t,e){return function(t,e,r){return n(t,e,r,!0),r}(this.target,t,e)}trigger(t,e={},r="l",n){a(this.target,t,e,r,n)}ancestors(){let t=this?.target,e=[];if(!o(t))return[];for(;t=t.closest("[data-mc]");)t?._mc&&e.push(t?._mc);return e.length?e:null}closest(){let t=this.target;return o(t)&&t.closest("[data-mc]")?._mc||null}children(){let t=this?.target;return o(t)?function(t){const e=Math.random().toString().replace(".",""),r='[data-mc]:not([temp_id="'+e+'"] [data-mc] [data-mc])';t.setAttribute("temp_id",e);const n=[...t.querySelectorAll(r)].filter((t=>!!t._mc)).map((t=>t._mc));return t.removeAttribute("temp_id"),n.length?n:null}(t):null}descendants(){const t=this?.target;if(!o(t))return[];const e=[...t.querySelectorAll("[data-mc]")].filter((t=>!!t._mc)).map((t=>t._mc));return e.length?e:null}}function u(t){let e={};return[...Object.keys(t)].sort().forEach((r=>{var n;(n=t[r])&&n.constructor&&n.constructor===Object?e[r]=u(t[r]):e[r]=t[r]})),e}function f(t,e=!0){let r={};return[...Object.getOwnPropertyNames(t)].forEach((e=>{if(t[e]instanceof Object){const n=f(t[e],!1);r[e]={};for(const t in n)r[e+"."+t]=n[t]}else r[e]=t[e]})),e?u(r):r}function h(t,e){const r=Object.getOwnPropertyDescriptors(t);for(const[t,n]of Object.entries(r))("get"in n||"set"in n)&&Object.defineProperty(e,t,n)}function d(t){return null!=t&&"object"==typeof t}function p(t){let e=new Set,r=/\{[^\{\}]*\}/g;return(t.getAttributeNames?t.getAttributeNames():[]).filter((e=>t.getAttribute(e)?.match(r))).forEach((n=>{new Set(t.getAttribute(n)?.match(r)).forEach((t=>e.add(t.replace(/[\{\}]/g,""))))})),[...t.childNodes].filter((t=>3===t.nodeType&&(t.nodeValue||"").match(r))).forEach((t=>{(t?.nodeValue||"").match(r).forEach((t=>e.add(t.replace(/[\{\}]/g,""))))})),[...e]}new Set;const m=[HTMLInputElement,HTMLSelectElement,HTMLTextAreaElement];class g extends i{data={};oldDisplay="";constructor(t){super(t),p(t).forEach((t=>this.data[t]="")),v(this),this.#t()}#t(){let t=this.target,e=!1;(t.getAttributeNames?t.getAttributeNames():[]).filter((e=>t.getAttribute(e)?.match(/\{[^\{\}]*\}/g))).forEach((e=>{let r=new Set(t.getAttribute(e)?.match(/\{[^\{\}]*\}/g));var n;this.data.subscribe((n=t.getAttribute(e),s=>{let a=n;r.forEach((t=>{a=a.replace(t,s[t.replace(/[\{\}]/g,"")])})),t.setAttribute(e,a)}))})),[...t.childNodes].filter((t=>3===t.nodeType&&(t.nodeValue||"").match(/\{[^\{\}]*\}/g))).forEach((r=>{e=!0;let n=new Set(r.nodeValue.match(/\{[^\{\}]*\}/g));this.data.subscribe((e=>s=>{let a=e;n.forEach((t=>{a=a.replace(t,s[t.replace(/[\{\}]/g,"")])})),this.oldDisplay?t.style=this.oldDisplay:t.removeAttribute("style"),delete this.oldDisplay,r.nodeValue=a})(r.nodeValue)),this.oldDisplay=t.getAttribute("style")||"",e&&!m.includes(t.constructor)&&"FIELDSET"!==t.tagName&&(t.style.display="none")}))}onData(t){let e={};Object.keys(t.detail.data).forEach((r=>{this.data.hasOwnProperty(r)&&(e[r]=t.detail.data[r])})),JSON.stringify(e)!==JSON.stringify(this.data)&&Object.assign(this.data,e)}}const b={};function y(t){let e=t.constructor.name;return b[e]||function(t){const e=t.constructor,r=e.name;let n=class extends e{#e=!0;#r=[];constructor(t){super(t),this.constructor.callbacks=[],d(t)&&Object.getOwnPropertyNames(t).forEach((e=>{this[e]=t[e]}))}get callbacks(){return this.#r}set callbacks(t){this.#r=t}subscribe(t){return this.#r.push(t),this}bind(t){if(d(this.valueOf())){!function(t){var e;(e=t,[e].concat([...e.querySelectorAll("*")]).filter((t=>!!p(t).length)).filter((t=>"STYLE"!==t?.tagName)).reverse()).forEach((t=>{t?._mc?._placeholders||i.add(t,"_placeholders",new g(t))}))}(t);const e=[t,...t.querySelectorAll("[data-mc]")].filter((t=>!!t?._mc?._placeholders)),r=function(t){let r=f(t);e.forEach((t=>{t&&a(t,"data",r)}))};this.#r.push(r),this.notify()}else console.warn("IGNORED - cannot bind a non-Object to the dom, IS:",typeof this.valueOf(),this);return this}notify(t){let e=d(this.valueOf())&&this.valueOf()instanceof Array==0?structuredClone(Object.assign({},this)):this.valueOf();return void 0!==t&&(this.#e=t),this.#e&&this.#r.forEach((t=>{t(e)})),this}};return b[r]=n,n}(t)}const v=(t,e)=>((e?[e]:[...Object.getOwnPropertyNames(t)]).forEach((e=>{if(t.hasOwnProperty(e)&&"function"!=typeof t[e]&&!t?.[e]?.constructor?.prototype?.subscribe){if("_"===e[0]||void 0===t?.[e])return t;let r=t[e],n=new(y(r))(r),s=function(){let t;return()=>{clearTimeout(t),t=setTimeout((function(){!function(){n.notify()}(...arguments)}),0)}}();Object.defineProperty(t,e,{enumerable:!0,get(){if(d(n.valueOf())){let t=structuredClone(Object.assign({},n));setTimeout((function(){var e,r;e=structuredClone(Object.assign({},n)),r=t,JSON.stringify(f(e))!==JSON.stringify(f(r))&&s()}),0)}return n},set(t){if(typeof t==typeof n.valueOf())if(d(n.valueOf())&&n.valueOf()instanceof Array==0)void 0===n?.constructor?.prototype?.subscribe&&(n=new(y(t))(structuredClone(Object.assign({},t))),h(t,n)),Object.assign(n,t),n.notify();else{let e=n.valueOf(),r=n.callbacks;t!==e&&(n=new(y(t))(t),n.callbacks=r,s())}else console.warn("IGNORED - cannot change observable types, IS:",typeof n.valueOf(),n,"- CANNOT BECOME:",typeof t)}}),t[e]=r}})),t);class O{constructor(t){}}class E extends O{#n;constructor(t){super(t),this.#n=t}get val(){return new FormData(this.#n.form).get(this.#n.name)}set val(t){[...this.#n.form.querySelectorAll(`input[type="radio"][name="${this.#n.name}"]`)].filter((e=>e.getAttribute("value")===t)).shift().checked=!0}}class w extends O{#n;constructor(t){super(t),this.#n=t}get val(){return this.#n.checked}set val(t){this.#n.checked=t}}class A extends O{#n;constructor(t){super(t),this.#n=t}get val(){return this.#n.value}set val(t){this.#n.value=t}}class _ extends O{#n;#s=!1;constructor(t){super(t),this.#n=t,this.#s=t.multiple}get val(){const t=[];return[...this.#n.querySelectorAll("option")].filter((t=>t.selected)).forEach((e=>{t.push(e.value)})),this.#s?t:t.length?t[0]:""}set val(t){t="string"==typeof t?[t]:t,[...this.#n.querySelectorAll("option")].forEach((e=>{t.indexOf(e.value)>-1?e.selected=!0:e.selected=!1}))}}class k extends O{#n;constructor(t){super(t),this.#n=t}get val(){return this.#n.value||""}set val(t){this.#n.value=t}}const j=t=>{let e=[...(t||document).querySelectorAll("input,select,textarea")],r={};return e.forEach((t=>{const e=t.getAttribute("name");if(e){let n=!1;switch((t=>t.tagName.toLowerCase())(t)){case"input":switch(t.type){case"radio":n=new E(t);break;case"checkbox":n=new w(t);break;default:n=new A(t)}break;case"select":n=new _(t);break;case"textarea":n=new k(t);break;default:console.warn("handler missing:",e,"for",t.tagName.toLowerCase(),t)}n&&(i.add(t,e,n),Object.defineProperty(r,e,{enumerable:!0,configurable:!0,get:()=>n.val,set:t=>{n.val!==t&&(n.val=t)}}))}})),r};function S(t,e,r){let n=j(r);t[e]=Object.assign({},n),v(t,e),h(n,t[e]),[...r.querySelectorAll("input, textarea, select")].forEach((r=>{r.addEventListener("input",(r=>{t[e].notify()}))}))}var N=e.R;export{N as formValues};
@@ -1,31 +1,65 @@
1
- 'use strict';
2
-
3
- import { LooseObject, copyGettersSetters } from './helpers.js';
4
- import { DC, on } from './MC.js';
1
+ import { DC } from './MC.js';
2
+ import { copyGettersSetters, LooseObject } from './helpers.js';
5
3
  import { observe } from './observables.js';
6
4
 
5
+ /**
6
+ Union type for form input elements.
7
+ */
7
8
  type inputTypes = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
8
9
 
10
+ /**
11
+ Extracts the lowercase tag name of an element (e.g., 'input', 'select', 'textarea').
12
+ @param e - The HTML element to extract the tag name from.
13
+ @returns The lowercase tag name string.
14
+ */
9
15
  const getInputName = (e: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): string => {
10
16
  return e.tagName.toLowerCase();
11
17
  };
12
18
 
19
+ /**
20
+ Abstract base class for form input value handlers.
21
+ Defines the interface that all handler classes must implement.
22
+ */
13
23
  abstract class InputBase {
24
+ /**
25
+ Creates a new InputBase instance.
26
+ @param e - The HTML element being handled (input, select, or textarea).
27
+ */
14
28
  constructor(e: inputTypes) {}
15
29
 
30
+ /**
31
+ Gets the current value of the form control.
32
+ @returns The value in an appropriate type for the control.
33
+ */
16
34
  abstract get val(): any;
17
35
 
36
+ /**
37
+ Sets the value of the form control.
38
+ @param value - The new value to assign (type depends on control).
39
+ */
18
40
  abstract set val(value: any);
19
41
  }
20
42
 
43
+ /**
44
+ Handler class specifically for radio button groups.
45
+ Provides synchronized access to the selected value in a group of related radio buttons.
46
+ */
21
47
  class RadioHandler extends InputBase {
22
48
  #e: HTMLInputElement;
23
49
 
50
+ /**
51
+ Creates a new RadioHandler instance.
52
+ @param e - The first radio button element in the group (used to determine name and form scope).
53
+ */
24
54
  constructor(e: HTMLInputElement) {
25
55
  super(e);
26
56
  this.#e = e;
27
57
  }
28
58
 
59
+ /**
60
+ Gets the currently selected value of the radio button group using FormData API.
61
+ @returns The string value of the selected radio button, or undefined if none is selected.
62
+ */
29
63
  get val(): string {
30
64
  let ret = new FormData(this.#e.form as HTMLFormElement).get(this.#e.name);
31
65
 
@@ -33,6 +67,11 @@ class RadioHandler extends InputBase {
33
67
  return ret as string;
34
68
  }
35
69
 
70
+ /**
71
+ Sets the selected radio button by value.
72
+ Finds and checks the first radio input matching the specified value within the same group.
73
+ @param value - The value to match against radio inputs in this group.
74
+ */
36
75
  set val(value: string) {
37
76
  let arr = [
38
77
  ...(this.#e.form as HTMLFormElement).querySelectorAll(
@@ -45,56 +84,100 @@ class RadioHandler extends InputBase {
45
84
  }
46
85
  }
47
86
 
87
+ /**
88
+ * Handler class for checkbhox inputs.
89
+ * Provides synchronized get/set access to the checked state of a single checkbox.
90
+ */
48
91
  class CheckboxHandler extends InputBase {
49
92
  #e: HTMLInputElement;
50
93
 
94
+ /**
95
+ Creates a new CheckboxHandler instance.
96
+ @param e - The checkbox element to handle.
97
+ */
51
98
  constructor(e: HTMLInputElement) {
52
99
  super(e);
53
100
  this.#e = e;
54
101
  }
55
102
 
103
+ /**
104
+ Gets the checked state of the checkbox.
105
+ @returns True if the checkbox is checked, false otherwise.
106
+ */
56
107
  get val(): boolean {
57
108
  return this.#e.checked;
58
109
  }
59
110
 
111
+ /**
112
+ Sets the checked state of the checkbox.
113
+ @param value - The boolean value to assign as the new checked state.
114
+ */
60
115
  set val(value: boolean) {
61
116
  this.#e.checked = value;
62
117
  }
63
118
  }
64
119
 
120
+ /**
121
+ Handler class for standard single-line input fields (text, password, email, etc.).
122
+ Provides synchronized get/set access to the value of an input field.
123
+ */
65
124
  class InputHandler extends InputBase {
66
125
  #e: HTMLInputElement;
67
126
 
127
+ /**
128
+ * Creates a new InputHandler instance.
129
+ * @param e - The HTML input element to handle.
130
+ */
68
131
  constructor(e: HTMLInputElement) {
69
132
  super(e);
70
133
  this.#e = e;
71
134
  }
72
135
 
136
+ /**
137
+ * Gets the current value of the input field.
138
+ * @returns The string content of the input element.
139
+ */
73
140
  get val(): string {
74
141
  return this.#e.value;
75
142
  }
76
143
 
144
+ /**
145
+ * Sets the value of the input field.
146
+ * @param value - The new string value for the input element.
147
+ */
77
148
  set val(value: string) {
78
149
  this.#e.value = value;
79
150
  }
80
151
  }
81
152
 
153
+ /**
154
+ Handler class for select dropdown elements, supporting both single and multiple selection modes.
155
+ Provides synchronized get/set access to selected option values.
156
+ */
82
157
  class SelectHandler extends InputBase {
83
158
  #e: HTMLSelectElement;
84
159
  #multi: boolean = false;
85
160
 
161
+ /**
162
+ * Creates a new SelectHandler instance.
163
+ * @param e - The select element to handle.
164
+ */
86
165
  constructor(e: HTMLSelectElement) {
87
166
  super(e);
88
167
  this.#e = e;
89
168
  this.#multi = e.multiple;
90
169
  }
91
170
 
171
+ /**
172
+ * Gets the currently selected option value(s).
173
+ * For single selection, returns a string. For multiple selection, returns an array of strings.
174
+ * @returns A string or array of strings representing selected values.
175
+ */
92
176
  get val(): string[] | string {
93
- const that = this,
94
- ret: string[] = [];
177
+ const ret: string[] = [];
95
178
 
96
179
  // get all options
97
- [...that.#e.querySelectorAll('option')]
180
+ [...this.#e.querySelectorAll('option')]
98
181
  .filter((o) => o.selected)
99
182
  .forEach((o) => {
100
183
  ret.push(o.value);
@@ -104,13 +187,15 @@ class SelectHandler extends InputBase {
104
187
  return ret.length ? ret[0] : '';
105
188
  }
106
189
 
190
+ /**
191
+ * Sets the selected option(s) by value.
192
+ * @param value - A string or array of strings representing values to select.
193
+ */
107
194
  set val(value: string[] | string) {
108
- const that = this;
109
-
110
195
  value = typeof value === 'string' ? [value] : value;
111
196
 
112
197
  // set all options
113
- [...that.#e.querySelectorAll('option')].forEach((o) => {
198
+ [...this.#e.querySelectorAll('option')].forEach((o) => {
114
199
  if (value.indexOf(o.value) > -1) {
115
200
  o.selected = true;
116
201
  } else {
@@ -120,22 +205,47 @@ class SelectHandler extends InputBase {
120
205
  }
121
206
  }
122
207
 
208
+ /**
209
+ Handler class for textarea elements.
210
+ Provides synchronized get/set access to the multi-line text content of a textarea.
211
+ */
123
212
  class TextAreaHandler extends InputBase {
124
213
  #e: HTMLTextAreaElement;
214
+
215
+ /**
216
+ * Creates a new TextAreaHandler instance.
217
+ * @param e - The textarea element to handle.
218
+ */
125
219
  constructor(e: HTMLTextAreaElement) {
126
220
  super(e);
127
221
  this.#e = e;
128
222
  }
129
223
 
224
+ /**
225
+ * Gets the current value of the textarea (defaults to empty string if null/undefined).
226
+ * @returns The string content of the textarea element.
227
+ */
130
228
  get val(): string {
131
229
  return this.#e.value || '';
132
230
  }
133
231
 
232
+ /**
233
+ * Sets the value of the textarea.
234
+ * @param value - The new string value for the textarea element.
235
+ */
134
236
  set val(value: string) {
135
237
  this.#e.value = value;
136
238
  }
137
239
  }
138
240
 
241
+ /**
242
+ Collects all form controls within a given DOM scope and creates handler objects
243
+ that provide synchronized get/set access to their values.
244
+
245
+ @param e - Optional root DOM element or shadow root to search within; defaults to document if omitted.
246
+ @returns An object where each key is the name attribute of an input, select, or textarea,
247
+ and each value is a proxy-like accessor object with `val` getter/setter methods.
248
+ */
139
249
  const getInputHandlers = (e: HTMLElement | ShadowRoot): LooseObject => {
140
250
  let inputList = [...(e || document).querySelectorAll('input,select,textarea')],
141
251
  handlers: LooseObject = {};
@@ -189,6 +299,54 @@ const getInputHandlers = (e: HTMLElement | ShadowRoot): LooseObject => {
189
299
  return handlers;
190
300
  };
191
301
 
302
+ /**
303
+ Attaches a form-values observable to a target object property, allowing two-way binding
304
+ between the DOM form controls and the object's state.
305
+
306
+ @param targetObject - The object to which the form values will be attached as an observable.
307
+ @param propertyName - The name of the property on the target object that will hold the form data.
308
+ @param dom - The DOM element or shadow root (typically a form) whose inputs should be observed and bound.
309
+
310
+ @example
311
+ HTML
312
+ ```html
313
+ <!-- HTML Form -->
314
+ <form id="myForm">
315
+ <input type="text" name="username" value="">
316
+ <select name="role">
317
+ <option value="admin">Admin</option>
318
+ <option value="user">User</option>
319
+ </select>
320
+ <textarea name="bio"></textarea>
321
+ <input type="checkbox" name="active">
322
+ <input type="radio" name="gender" value="male"> Male
323
+ <input type="radio" name="gender" value="female"> Female
324
+ </form>
325
+ ```
326
+ Javascript
327
+ ```typescript
328
+ import { formValues } from './formValues.js';
329
+
330
+ const state = {};
331
+
332
+ // Bind the form to state.formData
333
+ formValues(state, 'formData', document.getElementById('myForm'));
334
+
335
+ // Read values from the form
336
+ console.log(state.formData.username); // string
337
+ console.log(state.formData.role); // "admin" or "user"
338
+ console.log(state.formData.bio); // string
339
+ console.log(state.formData.active); // boolean
340
+ console.log(state.formData.gender); // "male" or "female"
341
+
342
+ // Write values to the form (updates DOM automatically)
343
+ state.formData.username = 'john_doe';
344
+ state.formData.role = 'user';
345
+ state.formData.bio = 'Hello world!';
346
+ state.formData.active = true;
347
+ state.formData.gender = 'male';
348
+ ```
349
+ */
192
350
  export function formValues(
193
351
  targetObject: LooseObject,
194
352
  propertyName: string,
package/dist/helpers.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export declare function isBrowser(): boolean;
1
2
  export interface LooseObject {
2
3
  [key: string | symbol]: any;
3
4
  }
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["helpers.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC;CAC5B;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAElD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,WAAW,GAAG,WAAW,CAatD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,GAAE,OAAc,GAAG,WAAW,CAgBjF;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,GAAG,OAAO,CAEnE;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,GAAE,WAAgB,GAAG,GAAG,CAW3E;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,OAsCrE;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,UAKxC;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,QAAQ,CASvE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAU1D;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,QAO1E"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAaA,wBAAgB,SAAS,YAExB;AAKD,MAAM,WAAW,WAAW;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC;CAC5B;AAOD,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAElD;AAOD,wBAAgB,UAAU,CAAC,CAAC,EAAE,WAAW,GAAG,WAAW,CAatD;AASD,wBAAgB,aAAa,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,GAAE,OAAc,GAAG,WAAW,CAgBjF;AAQD,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,GAAG,OAAO,CAEnE;AAQD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,GAAE,WAAgB,GAAG,GAAG,CAW3E;AAUD,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,OAsCrE;AAQD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,UAKxC;AAUD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,QAAQ,CASvE;AAQD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAU1D;AAQD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,QAO1E"}
package/dist/helpers.js CHANGED
@@ -1,4 +1,6 @@
1
- 'use strict';
1
+ export function isBrowser() {
2
+ return window ? true : false;
3
+ }
2
4
  export function isNativeObject(value) {
3
5
  return value && value['constructor'] && value.constructor === Object;
4
6
  }