@twobirds/microcomponents 0.1.16 → 0.1.19
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/MC.ts +345 -346
- package/dist/elements.ts +80 -96
- package/dist/formValues.ts +165 -171
- package/dist/helpers.ts +100 -100
- package/dist/observables.ts +295 -325
- package/package.json +4 -3
- package/dist/MC.d.ts +0 -39
- package/dist/MC.d.ts.map +0 -1
- package/dist/MC.js +0 -302
- package/dist/MC.min.js +0 -345
- package/dist/elements.d.ts +0 -5
- package/dist/elements.d.ts.map +0 -1
- package/dist/elements.js +0 -67
- package/dist/elements.min.js +0 -1
- package/dist/formValues.d.ts +0 -3
- package/dist/formValues.d.ts.map +0 -1
- package/dist/formValues.js +0 -159
- package/dist/formValues.min.js +0 -1
- package/dist/helpers.d.ts +0 -14
- package/dist/helpers.d.ts.map +0 -1
- package/dist/helpers.js +0 -111
- package/dist/microcomponents.d.ts +0 -6
- package/dist/microcomponents.d.ts.map +0 -1
- package/dist/microcomponents.js +0 -6
- package/dist/microcomponents.min.js +0 -1
- package/dist/observables.d.ts +0 -11
- package/dist/observables.d.ts.map +0 -1
- package/dist/observables.js +0 -234
- package/dist/observables.min.js +0 -1
package/dist/elements.ts
CHANGED
|
@@ -3,108 +3,92 @@
|
|
|
3
3
|
import { DC, McBase } from './MC.js';
|
|
4
4
|
import { kebabToPascal } from './helpers.js';
|
|
5
5
|
|
|
6
|
-
class CeBaseClass extends HTMLElement {
|
|
7
|
-
constructor() {
|
|
8
|
-
super();
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
connectedCallback() {
|
|
12
|
-
this.dispatchEvent(new CustomEvent('_mcConnected'));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
connectedMoveCallback() {
|
|
16
|
-
this.dispatchEvent(new CustomEvent('_mcConnectedMove'));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
disconnectedCallback() {
|
|
20
|
-
this.dispatchEvent(new CustomEvent('_mcDisconnected'));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
adoptedCallback() {
|
|
24
|
-
this.dispatchEvent(new CustomEvent('_mcAdopted'));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
attributeChangedCallback(name: string, oldValue: any, newValue: any) {
|
|
28
|
-
this.dispatchEvent(
|
|
29
|
-
new CustomEvent('_mcAttributeChanged', { detail: { name, oldValue, newValue } })
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
formResetCallback() {
|
|
34
|
-
this.dispatchEvent(new CustomEvent('_mcFormReset'));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
6
|
function createNamedClass(name: string, ClassBody: { new (...args: any[]): any }) {
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function isClass(func: any) {
|
|
43
|
-
return typeof func === 'function' && /^class\s/.test(Function.prototype.toString.call(func));
|
|
7
|
+
return Object.defineProperty(ClassBody, 'name', { value: name });
|
|
44
8
|
}
|
|
45
9
|
|
|
46
10
|
export function defineCE(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
11
|
+
tagName: string,
|
|
12
|
+
DefinitionClass: { new (...args: any[]): any } | Function,
|
|
13
|
+
observedAttributes: string[] = []
|
|
50
14
|
) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
15
|
+
//console.warn('defineCE args', arguments);
|
|
16
|
+
|
|
17
|
+
if (customElements.get(tagName)) {
|
|
18
|
+
console.warn(`IGNORED: Custom element "${tagName}" is already defined!`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!tagName.includes('-')) {
|
|
23
|
+
throw new Error('createCustomElement: tagName must contain at least one hyphen ("-").');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let name = kebabToPascal(tagName);
|
|
27
|
+
|
|
28
|
+
// a class, but not a MC
|
|
29
|
+
if (!(DefinitionClass.prototype instanceof McBase)) {
|
|
30
|
+
//console.warn('pure class', tagName, DefinitionClass);
|
|
31
|
+
customElements.define(
|
|
32
|
+
tagName,
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
DefinitionClass
|
|
35
|
+
);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//console.warn('MC class', tagName, DefinitionClass);
|
|
40
|
+
// a MC
|
|
41
|
+
customElements.define(
|
|
42
|
+
tagName,
|
|
43
|
+
createNamedClass(
|
|
44
|
+
name,
|
|
45
|
+
class extends HTMLElement {
|
|
46
|
+
constructor(data?: any) {
|
|
47
|
+
super();
|
|
48
|
+
// console.log('[named class constructor]', tagName, name, this, data);
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
DC.add(this, name, new DefinitionClass(this, data));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
connectedCallback() {
|
|
54
|
+
//console.warn('onConnected', this);
|
|
55
|
+
this.dispatchEvent(new CustomEvent('_mcConnected'));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
connectedMoveCallback() {
|
|
59
|
+
//console.warn('onConnectedMove', this);
|
|
60
|
+
this.dispatchEvent(new CustomEvent('_mcConnectedMove'));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
disconnectedCallback() {
|
|
64
|
+
//console.warn('onDisconnected', this);
|
|
65
|
+
this.dispatchEvent(new CustomEvent('_mcDisconnected'));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
adoptedCallback() {
|
|
69
|
+
//console.warn('onAdopted', this);
|
|
70
|
+
this.dispatchEvent(new CustomEvent('_mcAdopted'));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
attributeChangedCallback(name: string, oldValue: any, newValue: any) {
|
|
74
|
+
//console.warn('onAttributeChanged', this);
|
|
75
|
+
this.dispatchEvent(
|
|
76
|
+
new CustomEvent('_mcAttributeChanged', { detail: { name, oldValue, newValue } })
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
formResetCallback() {
|
|
81
|
+
this.dispatchEvent(new CustomEvent('_mcFormReset'));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static get observedAttributes() {
|
|
85
|
+
return observedAttributes;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
);
|
|
106
90
|
}
|
|
107
91
|
|
|
108
92
|
export function getCE(tagName: string): CustomElementConstructor | undefined {
|
|
109
|
-
|
|
93
|
+
return customElements.get(tagName);
|
|
110
94
|
}
|
package/dist/formValues.ts
CHANGED
|
@@ -7,213 +7,207 @@ import { observe } from './observables.js';
|
|
|
7
7
|
type inputTypes = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
|
|
8
8
|
|
|
9
9
|
const getInputName = (e: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): string => {
|
|
10
|
-
|
|
10
|
+
return e.tagName.toLowerCase();
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
abstract class InputBase {
|
|
14
|
-
|
|
14
|
+
constructor(e: inputTypes) {}
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
abstract get val(): any;
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
abstract set val(value: any);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
class RadioHandler extends InputBase {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
22
|
+
#e: HTMLInputElement;
|
|
23
|
+
|
|
24
|
+
constructor(e: HTMLInputElement) {
|
|
25
|
+
super(e);
|
|
26
|
+
this.#e = e;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get val(): string {
|
|
30
|
+
let ret = new FormData(this.#e.form as HTMLFormElement).get(this.#e.name);
|
|
31
|
+
|
|
32
|
+
//console.log('radio[', this.#e.name, '] = "' + ret + '"');
|
|
33
|
+
return ret as string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
set val(value: string) {
|
|
37
|
+
let arr = [
|
|
38
|
+
...(this.#e.form as HTMLFormElement).querySelectorAll(
|
|
39
|
+
`input[type="radio"][name="${this.#e.name}"]`
|
|
40
|
+
),
|
|
41
|
+
] as HTMLInputElement[];
|
|
42
|
+
|
|
43
|
+
(arr.filter((e) => e.getAttribute('value') === value).shift() as HTMLInputElement).checked =
|
|
44
|
+
true;
|
|
45
|
+
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
class CheckboxHandler extends InputBase {
|
|
49
|
-
|
|
49
|
+
#e: HTMLInputElement;
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
constructor(e: HTMLInputElement) {
|
|
52
|
+
super(e);
|
|
53
|
+
this.#e = e;
|
|
54
|
+
}
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
get val(): boolean {
|
|
57
|
+
return this.#e.checked;
|
|
58
|
+
}
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
set val(value: boolean) {
|
|
61
|
+
this.#e.checked = value;
|
|
62
|
+
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
class InputHandler extends InputBase {
|
|
66
|
-
|
|
66
|
+
#e: HTMLInputElement;
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
constructor(e: HTMLInputElement) {
|
|
69
|
+
super(e);
|
|
70
|
+
this.#e = e;
|
|
71
|
+
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
get val(): string {
|
|
74
|
+
return this.#e.value;
|
|
75
|
+
}
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
set val(value: string) {
|
|
78
|
+
this.#e.value = value;
|
|
79
|
+
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
class SelectHandler extends InputBase {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
83
|
+
#e: HTMLSelectElement;
|
|
84
|
+
#multi: boolean = false;
|
|
85
|
+
|
|
86
|
+
constructor(e: HTMLSelectElement) {
|
|
87
|
+
super(e);
|
|
88
|
+
this.#e = e;
|
|
89
|
+
this.#multi = e.multiple;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
get val(): string[] | string {
|
|
93
|
+
const that = this,
|
|
94
|
+
ret: string[] = [];
|
|
95
|
+
|
|
96
|
+
// get all options
|
|
97
|
+
[...that.#e.querySelectorAll('option')]
|
|
98
|
+
.filter((o) => o.selected)
|
|
99
|
+
.forEach((o) => {
|
|
100
|
+
ret.push(o.value);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (this.#multi) return ret;
|
|
104
|
+
return ret.length ? ret[0] : '';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
set val(value: string[] | string) {
|
|
108
|
+
const that = this;
|
|
109
|
+
|
|
110
|
+
value = typeof value === 'string' ? [value] : value;
|
|
111
|
+
|
|
112
|
+
// set all options
|
|
113
|
+
[...that.#e.querySelectorAll('option')].forEach((o) => {
|
|
114
|
+
if (value.indexOf(o.value) > -1) {
|
|
115
|
+
o.selected = true;
|
|
116
|
+
} else {
|
|
117
|
+
o.selected = false;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
class TextAreaHandler extends InputBase {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
124
|
+
#e: HTMLTextAreaElement;
|
|
125
|
+
constructor(e: HTMLTextAreaElement) {
|
|
126
|
+
super(e);
|
|
127
|
+
this.#e = e;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
get val(): string {
|
|
131
|
+
return this.#e.value || '';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
set val(value: string) {
|
|
135
|
+
this.#e.value = value;
|
|
136
|
+
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
const getInputHandlers = (e: HTMLElement | ShadowRoot): LooseObject => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
return handlers;
|
|
140
|
+
let inputList = [...(e || document).querySelectorAll('input,select,textarea')],
|
|
141
|
+
handlers: LooseObject = {};
|
|
142
|
+
|
|
143
|
+
inputList.forEach((input) => {
|
|
144
|
+
const name: string | null = (input as inputTypes).getAttribute('name');
|
|
145
|
+
if (name) {
|
|
146
|
+
let handler: any = false;
|
|
147
|
+
switch (getInputName(input as inputTypes)) {
|
|
148
|
+
case 'input':
|
|
149
|
+
switch ((input as HTMLInputElement).type) {
|
|
150
|
+
case 'radio':
|
|
151
|
+
handler = new RadioHandler(input as HTMLInputElement);
|
|
152
|
+
break;
|
|
153
|
+
case 'checkbox':
|
|
154
|
+
handler = new CheckboxHandler(input as HTMLInputElement);
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
handler = new InputHandler(input as HTMLInputElement);
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
case 'select':
|
|
161
|
+
handler = new SelectHandler(input as HTMLSelectElement);
|
|
162
|
+
break;
|
|
163
|
+
case 'textarea':
|
|
164
|
+
handler = new TextAreaHandler(input as HTMLTextAreaElement);
|
|
165
|
+
break;
|
|
166
|
+
default:
|
|
167
|
+
console.warn('handler missing:', name, 'for', input.tagName.toLowerCase(), input);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (handler) {
|
|
172
|
+
DC.add(input as HTMLElement, name, handler);
|
|
173
|
+
Object.defineProperty(handlers, name, {
|
|
174
|
+
enumerable: true,
|
|
175
|
+
configurable: true,
|
|
176
|
+
get: (): any => {
|
|
177
|
+
return handler.val;
|
|
178
|
+
},
|
|
179
|
+
set: (value: any) => {
|
|
180
|
+
if (handler.val !== value) {
|
|
181
|
+
handler.val = value;
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
return handlers;
|
|
196
190
|
};
|
|
197
191
|
|
|
198
192
|
export function formValues(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
193
|
+
targetObject: LooseObject,
|
|
194
|
+
propertyName: string,
|
|
195
|
+
dom: HTMLElement | ShadowRoot
|
|
202
196
|
) {
|
|
203
|
-
|
|
197
|
+
let handlers = getInputHandlers(dom);
|
|
204
198
|
|
|
205
|
-
|
|
199
|
+
targetObject[propertyName] = Object.assign({}, handlers);
|
|
206
200
|
|
|
207
|
-
|
|
201
|
+
observe(targetObject, propertyName);
|
|
208
202
|
|
|
209
|
-
|
|
203
|
+
copyGettersSetters(handlers, targetObject[propertyName]);
|
|
210
204
|
|
|
211
|
-
|
|
205
|
+
//Object.seal(targetObject[propertyName]); // object structure may not be changed from now on
|
|
212
206
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
207
|
+
[...dom.querySelectorAll('input, textarea, select')].forEach((input) => {
|
|
208
|
+
input.addEventListener('input', (ev) => {
|
|
209
|
+
//console.log('input event', input, ev);
|
|
210
|
+
targetObject[propertyName].notify();
|
|
211
|
+
});
|
|
212
|
+
});
|
|
219
213
|
}
|