@twobirds/microcomponents 0.2.1 → 0.2.3
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/README.md +45 -20
- package/dist/MC.min.js +1 -1
- package/dist/autoload.min.js +1 -1
- package/dist/core/MC.d.ts +289 -238
- package/dist/core/MC.d.ts.map +1 -1
- package/dist/core/MC.js +445 -184
- package/dist/core/elements.d.ts +58 -231
- package/dist/core/elements.d.ts.map +1 -1
- package/dist/core/elements.js +99 -214
- package/dist/core/index.d.ts +75 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +72 -0
- package/dist/core/mcGuards.d.ts +7 -7
- package/dist/core/mcGuards.d.ts.map +1 -1
- package/dist/core/mcGuards.js +1 -1
- package/dist/elements.min.js +1 -1
- package/dist/formValues.min.js +1 -1
- package/dist/mcGuards.min.js +1 -1
- package/dist/microcomponents.min.js +1 -1
- package/dist/observables.min.js +1 -1
- package/dist/state/formValues.d.ts +113 -66
- package/dist/state/formValues.d.ts.map +1 -1
- package/dist/state/formValues.js +134 -68
- package/dist/state/index.d.ts +7 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +5 -0
- package/dist/state/observables.d.ts +66 -133
- package/dist/state/observables.d.ts.map +1 -1
- package/dist/state/observables.js +185 -83
- package/dist/state/placeholders.d.ts +1 -0
- package/dist/state/placeholders.d.ts.map +1 -1
- package/dist/state/placeholders.js +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/mcTypes.d.ts +3 -3
- package/dist/types/mcTypes.js +1 -1
- package/dist/utils/autoload.d.ts +6 -2
- package/dist/utils/autoload.d.ts.map +1 -1
- package/dist/utils/autoload.js +7 -5
- package/dist/utils/events.d.ts +22 -79
- package/dist/utils/events.d.ts.map +1 -1
- package/dist/utils/events.js +63 -1
- package/dist/utils/helpers.d.ts +10 -9
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/helpers.js +26 -14
- package/dist/utils/index.d.ts +17 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +12 -0
- package/package.json +13 -15
|
@@ -1,70 +1,117 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
2
|
+
Two-way binding between DOM form controls (`input`, `select`, `textarea`) and an observable
|
|
3
|
+
object property. Reads reflect live DOM values; writes update the controls synchronously.
|
|
4
|
+
Most likely you will only need the the first variant mentioned in the examples below.
|
|
5
|
+
|
|
6
|
+
@module Form Values
|
|
7
|
+
|
|
8
|
+
@example Plugin — chainable instance method on DC components
|
|
9
|
+
```ts
|
|
10
|
+
import { DC, defineCE, formValuePlugin } from '@twobirds/microcomponents';
|
|
11
|
+
|
|
12
|
+
formValuePlugin(DC);
|
|
13
|
+
|
|
14
|
+
class CheckoutForm extends DC {
|
|
15
|
+
static assets = ['targetHtml'];
|
|
16
|
+
|
|
17
|
+
oneAssets() {
|
|
18
|
+
this
|
|
19
|
+
.formValues(this.target, 'formData')
|
|
20
|
+
.subscribe('formData', (data) => console.log(data))
|
|
21
|
+
.bind('formData', this.target);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
defineCE('checkout-form', CheckoutForm);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
@example Standalone function — bind a plain object to a form in the DOM
|
|
29
|
+
```ts
|
|
30
|
+
import { formValues } from '@twobirds/microcomponents/formValues';
|
|
31
|
+
|
|
32
|
+
const state = {};
|
|
33
|
+
formValues(state, 'formData', document.getElementById('myForm'));
|
|
34
|
+
console.log(state.formData.username); // reads <input name="username"> value
|
|
35
|
+
state.formData.role = 'admin'; // writes back to the <select> control
|
|
36
|
+
```
|
|
37
|
+
*/
|
|
33
38
|
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
39
|
+
@hidden
|
|
40
|
+
|
|
41
|
+
Attaches a form-values observable to a target object property, enabling two-way binding
|
|
42
|
+
between DOM form controls and the object's state.
|
|
43
|
+
|
|
44
|
+
Scans the given DOM subtree for `input`, `select`, and `textarea` elements with a `name`
|
|
45
|
+
attribute and creates live getters/setters on the resulting observable. Input events trigger
|
|
46
|
+
automatic notifications so subscribers react to user changes.
|
|
47
|
+
|
|
48
|
+
@param targetObject - The object that will receive the form-data property.
|
|
49
|
+
@param propertyName - The property name under which the bound form data is stored.
|
|
50
|
+
@param dom - HTMLElement or ShadowRoot containing the form controls.
|
|
51
|
+
|
|
52
|
+
@example Bind a plain object to an HTML form element
|
|
53
|
+
```ts
|
|
54
|
+
import { formValues } from '@twobirds/microcomponents/formValues';
|
|
55
|
+
|
|
56
|
+
const state = {};
|
|
57
|
+
formValues(state, 'formData', document.getElementById('myForm'));
|
|
58
|
+
console.log(state.formData.username); // reads <input name="username"> value
|
|
59
|
+
state.formData.role = 'admin'; // writes back to the <select> control
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
@example Subscribe to form changes inside a component
|
|
63
|
+
```ts
|
|
64
|
+
import { DC, defineCE, formValues } from '@twobirds/microcomponents';
|
|
65
|
+
|
|
66
|
+
class MyForm extends DC {
|
|
67
|
+
static assets = ['targetHtml'];
|
|
68
|
+
|
|
69
|
+
oneAssets() {
|
|
70
|
+
formValues(this, 'formData', this.target);
|
|
71
|
+
this.formData.subscribe((data) => console.log('form changed:', data));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
defineCE('my-form', MyForm);
|
|
76
|
+
```
|
|
77
|
+
*/
|
|
69
78
|
export declare function formValues<T extends object>(targetObject: T, propertyName: keyof T & string, dom: HTMLElement | ShadowRoot): void;
|
|
79
|
+
/**
|
|
80
|
+
Attaches a convenience method `formValues()` to the prototype of a microcomponent class so that
|
|
81
|
+
form controls can be bound directly on the instance without importing the standalone function.
|
|
82
|
+
|
|
83
|
+
This plugin also pulls in all observable methods from {@link observePlugin} — `notify()`,
|
|
84
|
+
`subscribe()`, and `bind()` — so you can chain them fluently after binding form data.
|
|
85
|
+
|
|
86
|
+
Call it once at module level before defining any component classes. The plugin is idempotent —
|
|
87
|
+
subsequent calls are no-ops.
|
|
88
|
+
|
|
89
|
+
@param Class - A constructor function whose prototype chain includes {@link Core.McBase}.
|
|
90
|
+
|
|
91
|
+
@example
|
|
92
|
+
```ts
|
|
93
|
+
import { DC, defineCE, formValuePlugin } from '@twobirds/microcomponents';
|
|
94
|
+
|
|
95
|
+
formValuePlugin(DC);
|
|
96
|
+
|
|
97
|
+
class CheckoutForm extends DC {
|
|
98
|
+
static assets = ['targetHtml'];
|
|
99
|
+
|
|
100
|
+
oneAssets() {
|
|
101
|
+
this
|
|
102
|
+
.formValues(this.target, 'formData')
|
|
103
|
+
.subscribe('formData', (data) => console.log(data))
|
|
104
|
+
.bind('formData', this.target);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
defineCE('checkout-form', CheckoutForm);
|
|
109
|
+
```
|
|
110
|
+
*/
|
|
111
|
+
export declare function formValuePlugin(Class: any): void;
|
|
112
|
+
declare module '../core/MC' {
|
|
113
|
+
interface McBase<TTarget extends object = object> {
|
|
114
|
+
formValues(target: object, propName: string): this;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
70
117
|
//# sourceMappingURL=formValues.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formValues.d.ts","sourceRoot":"","sources":["../../src/state/formValues.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"formValues.d.ts","sourceRoot":"","sources":["../../src/state/formValues.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCE;AA8SF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCE;AACF,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAC1C,YAAY,EAAE,CAAC,EACf,YAAY,EAAE,MAAM,CAAC,GAAG,MAAM,EAC9B,GAAG,EAAE,WAAW,GAAG,UAAU,QAuB7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BE;AACF,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,QA2BzC;AAED,OAAO,QAAQ,YAAY,CAAC;IAC3B,UAAiB,MAAM,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM;QACtD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACnD;CACD"}
|
package/dist/state/formValues.js
CHANGED
|
@@ -1,38 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
2
|
+
Two-way binding between DOM form controls (`input`, `select`, `textarea`) and an observable
|
|
3
|
+
object property. Reads reflect live DOM values; writes update the controls synchronously.
|
|
4
|
+
Most likely you will only need the the first variant mentioned in the examples below.
|
|
5
|
+
|
|
6
|
+
@module Form Values
|
|
7
|
+
|
|
8
|
+
@example Plugin — chainable instance method on DC components
|
|
9
|
+
```ts
|
|
10
|
+
import { DC, defineCE, formValuePlugin } from '@twobirds/microcomponents';
|
|
11
|
+
|
|
12
|
+
formValuePlugin(DC);
|
|
13
|
+
|
|
14
|
+
class CheckoutForm extends DC {
|
|
15
|
+
static assets = ['targetHtml'];
|
|
16
|
+
|
|
17
|
+
oneAssets() {
|
|
18
|
+
this
|
|
19
|
+
.formValues(this.target, 'formData')
|
|
20
|
+
.subscribe('formData', (data) => console.log(data))
|
|
21
|
+
.bind('formData', this.target);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
defineCE('checkout-form', CheckoutForm);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
@example Standalone function — bind a plain object to a form in the DOM
|
|
29
|
+
```ts
|
|
30
|
+
import { formValues } from '@twobirds/microcomponents/formValues';
|
|
31
|
+
|
|
32
|
+
const state = {};
|
|
33
|
+
formValues(state, 'formData', document.getElementById('myForm'));
|
|
34
|
+
console.log(state.formData.username); // reads <input name="username"> value
|
|
35
|
+
state.formData.role = 'admin'; // writes back to the <select> control
|
|
36
|
+
```
|
|
37
|
+
*/
|
|
33
38
|
import { DC } from '../core/MC.js';
|
|
34
39
|
import { copyGettersSetters, isBrowser } from '../utils/helpers.js';
|
|
35
|
-
import { observe } from './observables.js';
|
|
40
|
+
import { observe, observePlugin } from './observables.js';
|
|
41
|
+
observePlugin(DC);
|
|
36
42
|
/**
|
|
37
43
|
Extracts the lowercase tag name of an element (e.g., 'input', 'select', 'textarea').
|
|
38
44
|
@param inputElement - The HTML element to extract the tag name from.
|
|
@@ -177,7 +183,7 @@ class SelectHandler extends InputBase {
|
|
|
177
183
|
.forEach((o) => {
|
|
178
184
|
ret.push(o.value);
|
|
179
185
|
});
|
|
180
|
-
return this.#multi ? ret
|
|
186
|
+
return this.#multi ? ret : ret[0];
|
|
181
187
|
}
|
|
182
188
|
/**
|
|
183
189
|
* Sets the selected option(s) by value.
|
|
@@ -279,41 +285,45 @@ const getInputHandlers = (e) => {
|
|
|
279
285
|
return handlers;
|
|
280
286
|
};
|
|
281
287
|
/**
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
288
|
+
@hidden
|
|
289
|
+
|
|
290
|
+
Attaches a form-values observable to a target object property, enabling two-way binding
|
|
291
|
+
between DOM form controls and the object's state.
|
|
292
|
+
|
|
293
|
+
Scans the given DOM subtree for `input`, `select`, and `textarea` elements with a `name`
|
|
294
|
+
attribute and creates live getters/setters on the resulting observable. Input events trigger
|
|
295
|
+
automatic notifications so subscribers react to user changes.
|
|
296
|
+
|
|
297
|
+
@param targetObject - The object that will receive the form-data property.
|
|
298
|
+
@param propertyName - The property name under which the bound form data is stored.
|
|
299
|
+
@param dom - HTMLElement or ShadowRoot containing the form controls.
|
|
300
|
+
|
|
301
|
+
@example Bind a plain object to an HTML form element
|
|
302
|
+
```ts
|
|
303
|
+
import { formValues } from '@twobirds/microcomponents/formValues';
|
|
304
|
+
|
|
305
|
+
const state = {};
|
|
306
|
+
formValues(state, 'formData', document.getElementById('myForm'));
|
|
307
|
+
console.log(state.formData.username); // reads <input name="username"> value
|
|
308
|
+
state.formData.role = 'admin'; // writes back to the <select> control
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
@example Subscribe to form changes inside a component
|
|
312
|
+
```ts
|
|
313
|
+
import { DC, defineCE, formValues } from '@twobirds/microcomponents';
|
|
314
|
+
|
|
315
|
+
class MyForm extends DC {
|
|
316
|
+
static assets = ['targetHtml'];
|
|
317
|
+
|
|
318
|
+
oneAssets() {
|
|
319
|
+
formValues(this, 'formData', this.target);
|
|
320
|
+
this.formData.subscribe((data) => console.log('form changed:', data));
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
defineCE('my-form', MyForm);
|
|
325
|
+
```
|
|
326
|
+
*/
|
|
317
327
|
export function formValues(targetObject, propertyName, dom) {
|
|
318
328
|
/* v8 ignore next */
|
|
319
329
|
if (!isBrowser())
|
|
@@ -332,3 +342,59 @@ export function formValues(targetObject, propertyName, dom) {
|
|
|
332
342
|
});
|
|
333
343
|
});
|
|
334
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
Attaches a convenience method `formValues()` to the prototype of a microcomponent class so that
|
|
347
|
+
form controls can be bound directly on the instance without importing the standalone function.
|
|
348
|
+
|
|
349
|
+
This plugin also pulls in all observable methods from {@link observePlugin} — `notify()`,
|
|
350
|
+
`subscribe()`, and `bind()` — so you can chain them fluently after binding form data.
|
|
351
|
+
|
|
352
|
+
Call it once at module level before defining any component classes. The plugin is idempotent —
|
|
353
|
+
subsequent calls are no-ops.
|
|
354
|
+
|
|
355
|
+
@param Class - A constructor function whose prototype chain includes {@link Core.McBase}.
|
|
356
|
+
|
|
357
|
+
@example
|
|
358
|
+
```ts
|
|
359
|
+
import { DC, defineCE, formValuePlugin } from '@twobirds/microcomponents';
|
|
360
|
+
|
|
361
|
+
formValuePlugin(DC);
|
|
362
|
+
|
|
363
|
+
class CheckoutForm extends DC {
|
|
364
|
+
static assets = ['targetHtml'];
|
|
365
|
+
|
|
366
|
+
oneAssets() {
|
|
367
|
+
this
|
|
368
|
+
.formValues(this.target, 'formData')
|
|
369
|
+
.subscribe('formData', (data) => console.log(data))
|
|
370
|
+
.bind('formData', this.target);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
defineCE('checkout-form', CheckoutForm);
|
|
375
|
+
```
|
|
376
|
+
*/
|
|
377
|
+
export function formValuePlugin(Class) {
|
|
378
|
+
const McBaseProto = Object.getPrototypeOf(Class.prototype);
|
|
379
|
+
if (!Object.hasOwn(McBaseProto, 'formValues')) {
|
|
380
|
+
Object.assign(McBaseProto, {
|
|
381
|
+
/**
|
|
382
|
+
* Bind all named form controls inside a DOM subtree to an observable property on this instance.
|
|
383
|
+
* Ensures the property becomes observable and stays in sync with input changes.
|
|
384
|
+
* @param target - HTMLElement or ShadowRoot containing the form controls.
|
|
385
|
+
* @param propName - The name of the property that will hold the bound form data.
|
|
386
|
+
* @returns This instance for chaining.
|
|
387
|
+
|
|
388
|
+
@example
|
|
389
|
+
```ts
|
|
390
|
+
this.formValues(this.target, 'formData');
|
|
391
|
+
// now this.formData.username reflects <input name="username"> live
|
|
392
|
+
```
|
|
393
|
+
*/
|
|
394
|
+
formValues: function (target, propName) {
|
|
395
|
+
formValues(this, propName, target);
|
|
396
|
+
return this; // chainable
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@module State
|
|
3
|
+
*/
|
|
4
|
+
export { observe, observePlugin, isAlreadyObserved } from './observables.js';
|
|
5
|
+
export type { Observable, Callback, Observed, ObservedKey, Unobserved } from './observables.js';
|
|
6
|
+
export { formValues, formValuePlugin } from './formValues.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.ts"],"names":[],"mappings":"AAAA;;EAEE;AACF,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAChG,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|