@twobirds/microcomponents 0.1.19 → 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/README.md +12 -16
- package/dist/MC.d.ts +31 -0
- package/dist/MC.d.ts.map +1 -0
- package/dist/MC.js +249 -0
- package/dist/MC.min.js +345 -0
- package/dist/MC.ts +269 -113
- package/dist/elements.d.ts +5 -0
- package/dist/elements.d.ts.map +1 -0
- package/dist/elements.js +49 -0
- package/dist/elements.min.js +1 -0
- package/dist/elements.ts +26 -6
- package/dist/events.d.ts +11 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +55 -0
- package/dist/events.ts +158 -0
- package/dist/formValues.d.ts +3 -0
- package/dist/formValues.d.ts.map +1 -0
- package/dist/formValues.js +156 -0
- package/dist/formValues.min.js +1 -0
- package/dist/formValues.ts +168 -10
- package/dist/helpers.d.ts +15 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +113 -0
- package/dist/helpers.ts +82 -1
- package/dist/main.mjs +1 -0
- package/dist/microcomponents.d.ts +6 -0
- package/dist/microcomponents.d.ts.map +1 -0
- package/dist/microcomponents.js +6 -0
- package/dist/microcomponents.min.js +1 -0
- package/dist/observables.d.ts +11 -0
- package/dist/observables.d.ts.map +1 -0
- package/dist/observables.js +228 -0
- package/dist/observables.min.js +1 -0
- package/dist/observables.ts +132 -21
- package/package.json +7 -7
package/dist/formValues.ts
CHANGED
|
@@ -1,31 +1,65 @@
|
|
|
1
|
-
|
|
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
|
|
94
|
-
ret: string[] = [];
|
|
177
|
+
const ret: string[] = [];
|
|
95
178
|
|
|
96
179
|
// get all options
|
|
97
|
-
[...
|
|
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
|
-
[...
|
|
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,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare function isBrowser(): boolean;
|
|
2
|
+
export interface LooseObject {
|
|
3
|
+
[key: string | symbol]: any;
|
|
4
|
+
}
|
|
5
|
+
export declare function isNativeObject(value: any): boolean;
|
|
6
|
+
export declare function sortObject(o: LooseObject): LooseObject;
|
|
7
|
+
export declare function flattenObject(o: LooseObject, doSort?: boolean): LooseObject;
|
|
8
|
+
export declare function deepEqual(o1: LooseObject, o2: LooseObject): boolean;
|
|
9
|
+
export declare function nameSpace(ns: string | string[], obj?: LooseObject): any;
|
|
10
|
+
export declare function parse(what: string | object | any[], parseThis: object): any;
|
|
11
|
+
export declare function kebabToPascal(str: string): string;
|
|
12
|
+
export declare function debounce(func: Function, milliseconds: number): Function;
|
|
13
|
+
export declare function htmlToElements(html: string): HTMLElement[];
|
|
14
|
+
export declare function copyGettersSetters(source: LooseObject, target: LooseObject): void;
|
|
15
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export function isBrowser() {
|
|
2
|
+
return window ? true : false;
|
|
3
|
+
}
|
|
4
|
+
export function isNativeObject(value) {
|
|
5
|
+
return value && value['constructor'] && value.constructor === Object;
|
|
6
|
+
}
|
|
7
|
+
export function sortObject(o) {
|
|
8
|
+
let result = {}, keys = [...Object.keys(o)].sort();
|
|
9
|
+
keys.forEach((key) => {
|
|
10
|
+
if (isNativeObject(o[key])) {
|
|
11
|
+
result[key] = sortObject(o[key]);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
result[key] = o[key];
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
export function flattenObject(o, doSort = true) {
|
|
20
|
+
let result = {};
|
|
21
|
+
[...Object.getOwnPropertyNames(o)].forEach((propName) => {
|
|
22
|
+
if (o[propName] instanceof Object) {
|
|
23
|
+
const temp = flattenObject(o[propName], false);
|
|
24
|
+
result[propName] = {};
|
|
25
|
+
for (const j in temp) {
|
|
26
|
+
result[propName + '.' + j] = temp[j];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
result[propName] = o[propName];
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return doSort ? sortObject(result) : result;
|
|
34
|
+
}
|
|
35
|
+
export function deepEqual(o1, o2) {
|
|
36
|
+
return JSON.stringify(flattenObject(o1)) === JSON.stringify(flattenObject(o2));
|
|
37
|
+
}
|
|
38
|
+
export function nameSpace(ns, obj = {}) {
|
|
39
|
+
let nsa = ns.constructor === String ? ns.split('.') : ns;
|
|
40
|
+
if (!obj || !nsa[0] || !obj[nsa[0]]) {
|
|
41
|
+
console.warn('ns', nsa[0], 'not in', obj);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (obj[nsa[0]].constructor === Object && nsa.length > 1) {
|
|
45
|
+
return nameSpace(nsa.splice(1), obj[nsa[0]]);
|
|
46
|
+
}
|
|
47
|
+
return obj[nsa[0]];
|
|
48
|
+
}
|
|
49
|
+
export function parse(what, parseThis) {
|
|
50
|
+
var args = Array.from(arguments);
|
|
51
|
+
if (args.length > 2) {
|
|
52
|
+
while (args.length > 1) {
|
|
53
|
+
args[0] = parse(args[0], args[1]);
|
|
54
|
+
args.splice(1, 1);
|
|
55
|
+
}
|
|
56
|
+
return args[0];
|
|
57
|
+
}
|
|
58
|
+
if (typeof what === 'string') {
|
|
59
|
+
what.match(/\{[^\{\}]*\}/g)?.forEach(function (pPropname) {
|
|
60
|
+
var propname = pPropname.substring(1, pPropname.length - 1), value = nameSpace(propname, parseThis);
|
|
61
|
+
if (typeof value !== 'undefined') {
|
|
62
|
+
what = what.replace(pPropname, value);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else if (isNativeObject(what)) {
|
|
67
|
+
switch (what.constructor) {
|
|
68
|
+
case Object:
|
|
69
|
+
Object.keys(what).forEach(function (pKey) {
|
|
70
|
+
if (what.hasOwnProperty(pKey)) {
|
|
71
|
+
what[pKey] = parse(what[pKey], parseThis);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
break;
|
|
75
|
+
case Array:
|
|
76
|
+
what.forEach(function (pValue, pKey, original) {
|
|
77
|
+
original[pKey] = parse(what[pKey], parseThis);
|
|
78
|
+
});
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return what;
|
|
83
|
+
}
|
|
84
|
+
export function kebabToPascal(str) {
|
|
85
|
+
return str
|
|
86
|
+
.split('-')
|
|
87
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
88
|
+
.join('');
|
|
89
|
+
}
|
|
90
|
+
export function debounce(func, milliseconds) {
|
|
91
|
+
let timeout;
|
|
92
|
+
return () => {
|
|
93
|
+
clearTimeout(timeout);
|
|
94
|
+
timeout = setTimeout(function () {
|
|
95
|
+
func(...arguments);
|
|
96
|
+
}, milliseconds);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export function htmlToElements(html) {
|
|
100
|
+
let template = document.createElement('template');
|
|
101
|
+
html = html.replace(/<([A-Za-z0-9\-]*)([^>\/]*)(\/>)/gi, '<$1$2></$1>');
|
|
102
|
+
template.innerHTML = html;
|
|
103
|
+
template.content.normalize();
|
|
104
|
+
return Array.from(template.content.childNodes);
|
|
105
|
+
}
|
|
106
|
+
export function copyGettersSetters(source, target) {
|
|
107
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
108
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
109
|
+
if ('get' in descriptor || 'set' in descriptor) {
|
|
110
|
+
Object.defineProperty(target, key, descriptor);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
package/dist/helpers.ts
CHANGED
|
@@ -1,13 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether the current runtime environment is a web browser.
|
|
3
|
+
*
|
|
4
|
+
* This function works by attempting to access `this` within an anonymous function
|
|
5
|
+
* and checking if it refers to the global `window` object. It returns `true`
|
|
6
|
+
* when executed in a browser context, and `false` otherwise (e.g., Node.js).
|
|
7
|
+
*
|
|
8
|
+
* Note: While modern environments typically provide more reliable detection mechanisms,
|
|
9
|
+
* this fallback remains compatible across older runtimes where other detection techniques
|
|
10
|
+
* may be unreliable.
|
|
11
|
+
*
|
|
12
|
+
* @returns {boolean} `true` if the code is running in a browser environment, `false` otherwise.
|
|
13
|
+
*/
|
|
14
|
+
export function isBrowser() {
|
|
15
|
+
return window ? true : false;
|
|
16
|
+
}
|
|
2
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Interface for objects that can have string or symbol keys with any type of values.
|
|
20
|
+
*/
|
|
3
21
|
export interface LooseObject {
|
|
4
22
|
[key: string | symbol]: any;
|
|
5
23
|
}
|
|
6
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Checks if a value is a native JavaScript object (created via {} or new Object()).
|
|
27
|
+
* @param value - The value to check.
|
|
28
|
+
* @returns True if the value is a plain object, false otherwise.
|
|
29
|
+
*/
|
|
7
30
|
export function isNativeObject(value: any): boolean {
|
|
8
31
|
return value && value['constructor'] && value.constructor === Object;
|
|
9
32
|
}
|
|
10
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Recursively sorts all keys in an object alphabetically, preserving nested structure.
|
|
36
|
+
* @param o - The object to sort.
|
|
37
|
+
* @returns A new object with sorted keys at all levels.
|
|
38
|
+
*/
|
|
11
39
|
export function sortObject(o: LooseObject): LooseObject {
|
|
12
40
|
let result: LooseObject = {},
|
|
13
41
|
keys = [...Object.keys(o)].sort();
|
|
@@ -23,6 +51,13 @@ export function sortObject(o: LooseObject): LooseObject {
|
|
|
23
51
|
return result;
|
|
24
52
|
}
|
|
25
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Flattens a nested object into a single-level object with dot-separated keys.
|
|
56
|
+
* Optionally sorts the resulting flat keys alphabetically (default: true).
|
|
57
|
+
* @param o - The object to flatten.
|
|
58
|
+
* @param doSort - Whether to sort the resulting keys (default: true).
|
|
59
|
+
* @returns A flattened object with dot-notation keys.
|
|
60
|
+
*/
|
|
26
61
|
export function flattenObject(o: LooseObject, doSort: boolean = true): LooseObject {
|
|
27
62
|
let result: LooseObject = {};
|
|
28
63
|
|
|
@@ -41,10 +76,22 @@ export function flattenObject(o: LooseObject, doSort: boolean = true): LooseObje
|
|
|
41
76
|
return doSort ? sortObject(result) : result;
|
|
42
77
|
}
|
|
43
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Compares two objects for deep equality by flattening them and comparing their JSON representations.
|
|
81
|
+
* @param o1 - The first object to compare.
|
|
82
|
+
* @param o2 - The second object to compare.
|
|
83
|
+
* @returns True if the objects are deeply equal, false otherwise.
|
|
84
|
+
*/
|
|
44
85
|
export function deepEqual(o1: LooseObject, o2: LooseObject): boolean {
|
|
45
86
|
return JSON.stringify(flattenObject(o1)) === JSON.stringify(flattenObject(o2));
|
|
46
87
|
}
|
|
47
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Retrieves a nested value from an object using a namespace path (dot-separated).
|
|
91
|
+
* @param ns - The namespace string or array of keys representing the path.
|
|
92
|
+
* @param obj - The object to traverse.
|
|
93
|
+
* @returns The value at the specified namespace path, or undefined if not found.
|
|
94
|
+
*/
|
|
48
95
|
export function nameSpace(ns: string | string[], obj: LooseObject = {}): any {
|
|
49
96
|
let nsa = ns.constructor === String ? ns.split('.') : ns;
|
|
50
97
|
|
|
@@ -58,6 +105,14 @@ export function nameSpace(ns: string | string[], obj: LooseObject = {}): any {
|
|
|
58
105
|
return obj[nsa[0]];
|
|
59
106
|
}
|
|
60
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Parses a template string or object, replacing placeholders in the form of {key.path} with
|
|
110
|
+
* corresponding values from the provided data object using namespace resolution.
|
|
111
|
+
* Also recursively processes objects and arrays within the input.
|
|
112
|
+
* @param what - The string or object to parse (can contain {{placeholder}} expressions).
|
|
113
|
+
* @param parseThis - The object containing values for placeholder substitution.
|
|
114
|
+
* @returns The parsed result, with placeholders replaced by actual values.
|
|
115
|
+
*/
|
|
61
116
|
export function parse(what: string | object | any[], parseThis: object) {
|
|
62
117
|
var args = Array.from(arguments);
|
|
63
118
|
|
|
@@ -98,6 +153,12 @@ export function parse(what: string | object | any[], parseThis: object) {
|
|
|
98
153
|
return what;
|
|
99
154
|
}
|
|
100
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Converts a kebab-case string to PascalCase.
|
|
158
|
+
* Example: 'my-component-name' -> 'MyComponentName'
|
|
159
|
+
* @param str - The kebab-case string to convert.
|
|
160
|
+
* @returns The converted PascalCase string.
|
|
161
|
+
*/
|
|
101
162
|
export function kebabToPascal(str: string) {
|
|
102
163
|
return str
|
|
103
164
|
.split('-') // Split by hyphens
|
|
@@ -105,6 +166,14 @@ export function kebabToPascal(str: string) {
|
|
|
105
166
|
.join(''); // Join without spaces
|
|
106
167
|
}
|
|
107
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Creates a debounced version of a function that delays execution until after the specified
|
|
171
|
+
* number of milliseconds have elapsed since the last time this function was invoked.
|
|
172
|
+
* Useful for rate-limiting expensive operations like event handlers or API calls.
|
|
173
|
+
* @param func - The function to debounce.
|
|
174
|
+
* @param milliseconds - The number of milliseconds to delay execution.
|
|
175
|
+
* @returns A debounced version of the input function.
|
|
176
|
+
*/
|
|
108
177
|
export function debounce(func: Function, milliseconds: number): Function {
|
|
109
178
|
let timeout: any;
|
|
110
179
|
return () => {
|
|
@@ -116,6 +185,12 @@ export function debounce(func: Function, milliseconds: number): Function {
|
|
|
116
185
|
};
|
|
117
186
|
}
|
|
118
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Parses an HTML string and returns an array of DOM elements.
|
|
190
|
+
* Handles self-closing tags (XHTML style) by converting them to full closing tags first.
|
|
191
|
+
* @param html - The HTML string to parse.
|
|
192
|
+
* @returns An array of HTMLElement objects representing the parsed HTML nodes.
|
|
193
|
+
*/
|
|
119
194
|
export function htmlToElements(html: string): HTMLElement[] {
|
|
120
195
|
let template = document.createElement('template');
|
|
121
196
|
|
|
@@ -128,6 +203,12 @@ export function htmlToElements(html: string): HTMLElement[] {
|
|
|
128
203
|
return Array.from(template.content.childNodes) as HTMLElement[];
|
|
129
204
|
}
|
|
130
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Copies all getter and setter properties from a source object to a target object.
|
|
208
|
+
* Does not copy methods or regular data properties—only accessor properties (get/set).
|
|
209
|
+
* @param source - The source object with getters and/or setters to copy.
|
|
210
|
+
* @param target - The target object to which the accessors will be copied.
|
|
211
|
+
*/
|
|
131
212
|
export function copyGettersSetters(source: LooseObject, target: LooseObject) {
|
|
132
213
|
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
133
214
|
for (const [key, descriptor] of Object.entries(descriptors)) {
|
package/dist/main.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(t){let n={};return[...Object.keys(t)].sort().forEach((a=>{var l;(l=t[a])&&l.constructor&&l.constructor===Object?n[a]=e(t[a]):n[a]=t[a]})),n}function t(n,a=!0){let l={};return[...Object.getOwnPropertyNames(n)].forEach((e=>{if(n[e]instanceof Object){const a=t(n[e],!1);l[e]={};for(const t in a)l[e+"."+t]=a[t]}else l[e]=n[e]})),a?e(l):l}function n(e,t){const n=Object.getOwnPropertyDescriptors(e);for(const[e,a]of Object.entries(n))("get"in a||"set"in a)&&Object.defineProperty(t,e,a)}function a(e){return"_mc"+e[0].toUpperCase()+e.substring(1)}function l(e,t,n,l=!1){return e.addEventListener(a(t),n,{capture:!1,once:l}),n}class r{stopped=!1;constructor(){}stop(){this.stopped=!0}}function s(e,t,n={},l="l",s){const i=/^_mc/.test(t)?t:a(t),o=s||new r,c=new CustomEvent(i,{detail:{data:n,control:o},bubbles:!1});o.stopped||/l/.test(l)&&(e.dispatchEvent(c),c.stopImmediatePropagation(),o.stopped)||/[ud]/.test(l)&&(-1===l.indexOf("l")&&(l+="l"),setTimeout((()=>{if(l.indexOf("u")>-1){let t=e.parentElement?.closest("[data-mc]");t&&t?._mc.trigger(i,n,l,o)}if(l.indexOf("d")>-1){let t=e._mc.children();t&&t.forEach((e=>e.trigger(i,n,l)))}}),0))}const i=new Function("try {return this===window;}catch(e){ return false;}");function o(e){return e&&e instanceof HTMLElement}class c{_target;constructor(e){var t;this._target=new WeakRef(e||{}),function(e){if(!i()||e.constructor===u)return;const t=e.target;if(t instanceof HTMLElement){let n=e;Object.getOwnPropertyNames(n.constructor.prototype).filter((e=>/^(on[A-Z]|one[A-Z])/.test(e)&&"function"==typeof n.constructor.prototype[e])).forEach((e=>{let a=/^one/.test(e),r=e.replace(/^on[e]{0,1}/,""),s=r.toLowerCase();if("on"+s in t){let a=t=>{n[e](t)};t.addEventListener(s,a)}else l(t,r,(t=>{n[e](t)}),a)}))}}(this),t=this,setTimeout((()=>{t.constructor!==u&&t.trigger("Init")}),0)}get target(){return this._target.deref()}}class u extends c{constructor(e){super(e)}static add(e,t,n={}){return function(e,t,n={}){let a=e;a._mc||(a._mc=new u(e));const l=a._mc;return t.length&&!l[t]&&(l[t]=n,e instanceof HTMLElement&&!e.getAttribute("data-mc")&&e.setAttribute("data-mc","")),a}(e,t,n)}static remove(e,t){!function(e,t){if(!t)return;const n=e?._mc||{};n&&n[t]&&delete n[t],!Object.keys(n).length&&e instanceof HTMLElement&&e.hasAttribute("data-mc")&&e.removeAttribute("data-mc")}(e,t)}off(e,t){!function(e,t,n){e.removeEventListener(a(t),n)}(this.target,e,t)}on(e,t){return l(this.target,e,t)}one(e,t){return function(e,t,n){return l(e,t,n,!0),n}(this.target,e,t)}trigger(e,t={},n="l",a){s(this.target,e,t,n,a)}ancestors(){let e=this?.target,t=[];if(!o(e))return[];for(;e=e.closest("[data-mc]");)e?._mc&&t.push(e?._mc);return t.length?t:null}closest(){let e=this.target;return o(e)&&e.closest("[data-mc]")?._mc||null}children(){let e=this?.target;return o(e)?function(e){const t=Math.random().toString().replace(".",""),n='[data-mc]:not([temp_id="'+t+'"] [data-mc] [data-mc])';e.setAttribute("temp_id",t);const a=[...e.querySelectorAll(n)].filter((e=>!!e._mc)).map((e=>e._mc));return e.removeAttribute("temp_id"),a.length?a:null}(e):null}descendants(){const e=this?.target;if(!o(e))return[];const t=[...e.querySelectorAll("[data-mc]")].filter((e=>!!e._mc)).map((e=>e._mc));return t.length?t:null}}function p(e){return null!=e&&"object"==typeof e}function d(e){let t=new Set,n=/\{[^\{\}]*\}/g;return(e.getAttributeNames?e.getAttributeNames():[]).filter((t=>e.getAttribute(t)?.match(n))).forEach((a=>{new Set(e.getAttribute(a)?.match(n)).forEach((e=>t.add(e.replace(/[\{\}]/g,""))))})),[...e.childNodes].filter((e=>3===e.nodeType&&(e.nodeValue||"").match(n))).forEach((e=>{(e?.nodeValue||"").match(n).forEach((e=>t.add(e.replace(/[\{\}]/g,""))))})),[...t]}new Set;const b=[HTMLInputElement,HTMLSelectElement,HTMLTextAreaElement];class m extends u{data={};oldDisplay="";constructor(e){super(e),d(e).forEach((e=>this.data[e]="")),g(this),this.#e()}#e(){let e=this.target,t=!1;(e.getAttributeNames?e.getAttributeNames():[]).filter((t=>e.getAttribute(t)?.match(/\{[^\{\}]*\}/g))).forEach((t=>{let n=new Set(e.getAttribute(t)?.match(/\{[^\{\}]*\}/g));var a;this.data.subscribe((a=e.getAttribute(t),l=>{let r=a;n.forEach((e=>{r=r.replace(e,l[e.replace(/[\{\}]/g,"")])})),e.setAttribute(t,r)}))})),[...e.childNodes].filter((e=>3===e.nodeType&&(e.nodeValue||"").match(/\{[^\{\}]*\}/g))).forEach((n=>{t=!0;let a=new Set(n.nodeValue.match(/\{[^\{\}]*\}/g));this.data.subscribe((t=>l=>{let r=t;a.forEach((e=>{r=r.replace(e,l[e.replace(/[\{\}]/g,"")])})),this.oldDisplay?e.style=this.oldDisplay:e.removeAttribute("style"),delete this.oldDisplay,n.nodeValue=r})(n.nodeValue)),this.oldDisplay=e.getAttribute("style")||"",t&&!b.includes(e.constructor)&&"FIELDSET"!==e.tagName&&(e.style.display="none")}))}onData(e){let t={};Object.keys(e.detail.data).forEach((n=>{this.data.hasOwnProperty(n)&&(t[n]=e.detail.data[n])})),JSON.stringify(t)!==JSON.stringify(this.data)&&Object.assign(this.data,t)}}const h={};function f(e){let n=e.constructor.name;return h[n]||function(e){const n=e.constructor,a=n.name;let l=class extends n{#t=!0;#n=[];constructor(e){super(e),this.constructor.callbacks=[],p(e)&&Object.getOwnPropertyNames(e).forEach((t=>{this[t]=e[t]}))}get callbacks(){return this.#n}set callbacks(e){this.#n=e}subscribe(e){return this.#n.push(e),this}bind(e){if(p(this.valueOf())){!function(e){var t;(t=e,[t].concat([...t.querySelectorAll("*")]).filter((e=>!!d(e).length)).filter((e=>"STYLE"!==e?.tagName)).reverse()).forEach((e=>{e?._mc?._placeholders||u.add(e,"_placeholders",new m(e))}))}(e);const n=[e,...e.querySelectorAll("[data-mc]")].filter((e=>!!e?._mc?._placeholders)),a=function(e){let a=t(e);n.forEach((e=>{e&&s(e,"data",a)}))};this.#n.push(a),this.notify()}else console.warn("IGNORED - cannot bind a non-Object to the dom, IS:",typeof this.valueOf(),this);return this}notify(e){let t=p(this.valueOf())&&this.valueOf()instanceof Array==0?structuredClone(Object.assign({},this)):this.valueOf();return void 0!==e&&(this.#t=e),this.#t&&this.#n.forEach((e=>{e(t)})),this}};return h[a]=l,l}(e)}const g=(e,a)=>((a?[a]:[...Object.getOwnPropertyNames(e)]).forEach((a=>{if(e.hasOwnProperty(a)&&"function"!=typeof e[a]&&!e?.[a]?.constructor?.prototype?.subscribe){if("_"===a[0]||void 0===e?.[a])return e;let l=e[a],r=new(f(l))(l),s=function(){let e;return()=>{clearTimeout(e),e=setTimeout((function(){!function(){r.notify()}(...arguments)}),0)}}();Object.defineProperty(e,a,{enumerable:!0,get(){if(p(r.valueOf())){let e=structuredClone(Object.assign({},r));setTimeout((function(){var n,a;n=structuredClone(Object.assign({},r)),a=e,JSON.stringify(t(n))!==JSON.stringify(t(a))&&s()}),0)}return r},set(e){if(typeof e==typeof r.valueOf())if(p(r.valueOf())&&r.valueOf()instanceof Array==0)void 0===r?.constructor?.prototype?.subscribe&&(r=new(f(e))(structuredClone(Object.assign({},e))),n(e,r)),Object.assign(r,e),r.notify();else{let t=r.valueOf(),n=r.callbacks;e!==t&&(r=new(f(e))(e),r.callbacks=n,s())}else console.warn("IGNORED - cannot change observable types, IS:",typeof r.valueOf(),r,"- CANNOT BECOME:",typeof e)}}),e[a]=l}})),e);class y{constructor(e){}}class v extends y{#a;constructor(e){super(e),this.#a=e}get val(){return new FormData(this.#a.form).get(this.#a.name)}set val(e){[...this.#a.form.querySelectorAll(`input[type="radio"][name="${this.#a.name}"]`)].filter((t=>t.getAttribute("value")===e)).shift().checked=!0}}class E extends y{#a;constructor(e){super(e),this.#a=e}get val(){return this.#a.checked}set val(e){this.#a.checked=e}}class O extends y{#a;constructor(e){super(e),this.#a=e}get val(){return this.#a.value}set val(e){this.#a.value=e}}class w extends y{#a;#l=!1;constructor(e){super(e),this.#a=e,this.#l=e.multiple}get val(){const e=[];return[...this.#a.querySelectorAll("option")].filter((e=>e.selected)).forEach((t=>{e.push(t.value)})),this.#l?e:e.length?e[0]:""}set val(e){e="string"==typeof e?[e]:e,[...this.#a.querySelectorAll("option")].forEach((t=>{e.indexOf(t.value)>-1?t.selected=!0:t.selected=!1}))}}class k extends y{#a;constructor(e){super(e),this.#a=e}get val(){return this.#a.value||""}set val(e){this.#a.value=e}}!function(e,t,n=[]){if(customElements.get(e))return void console.warn(`IGNORED: Custom element "${e}" is already defined!`);if(!e.includes("-"))throw new Error('createCustomElement: tagName must contain at least one hyphen ("-").');let a=e.split("-").map((e=>e.charAt(0).toUpperCase()+e.slice(1))).join("");t.prototype instanceof c?customElements.define(e,function(e,t){return Object.defineProperty(t,"name",{value:e})}(a,class extends HTMLElement{constructor(e){super(),u.add(this,a,new t(this,e))}connectedCallback(){this.dispatchEvent(new CustomEvent("_mcConnected"))}connectedMoveCallback(){this.dispatchEvent(new CustomEvent("_mcConnectedMove"))}disconnectedCallback(){this.dispatchEvent(new CustomEvent("_mcDisconnected"))}adoptedCallback(){this.dispatchEvent(new CustomEvent("_mcAdopted"))}attributeChangedCallback(e,t,n){this.dispatchEvent(new CustomEvent("_mcAttributeChanged",{detail:{name:e,oldValue:t,newValue:n}}))}formResetCallback(){this.dispatchEvent(new CustomEvent("_mcFormReset"))}static get observedAttributes(){return n}})):customElements.define(e,t)}("test-testform",class extends u{data;constructor(e){super(e);let t=this.target.attachShadow({mode:"open"});t.innerHTML=`<style>${this.css}</style>${this.template}`,function(e,t,a){let l=(e=>{let t=[...(e||document).querySelectorAll("input,select,textarea")],n={};return t.forEach((e=>{const t=e.getAttribute("name");if(t){let a=!1;switch((e=>e.tagName.toLowerCase())(e)){case"input":switch(e.type){case"radio":a=new v(e);break;case"checkbox":a=new E(e);break;default:a=new O(e)}break;case"select":a=new w(e);break;case"textarea":a=new k(e);break;default:console.warn("handler missing:",t,"for",e.tagName.toLowerCase(),e)}a&&(u.add(e,t,a),Object.defineProperty(n,t,{enumerable:!0,configurable:!0,get:()=>a.val,set:e=>{a.val!==e&&(a.val=e)}}))}})),n})(a);e[t]=Object.assign({},l),g(e,t),n(l,e[t]),[...a.querySelectorAll("input, textarea, select")].forEach((n=>{n.addEventListener("input",(n=>{e[t].notify()}))}))}(this,"data",t),this.data.bind(t),fetch("./testform.json").then((e=>e.json())).then((e=>{this.data=e}))}get template(){return'\n <form>\n \x3c!-- sample form to start with --\x3e\n <fieldset>\n <legend>Inputs</legend>\n <label>text</label><input type="text" name="textInput" value="Hallo" /> <strong>2wB: </strong>{textInput}<br />\n <label>color</label><input type="color" name="colorInput" value="#000000" /><br />\n <label>date</label><input type="date" name="dateInput" value="" /><br />\n <label>datetime-local</label><input type="datetime-local" name="dtlInput" value="" /><br />\n <label>email</label><input type="email" name="email" value="" /><br />\n <label>file</label><input type="file" name="fileInput" value="" /><br />\n <label>hidden</label><input type="hidden" name="hiddenInput" value="hiddenVal" /><br />\n <label>month</label><input type="month" name="month" value="" /><br />\n <label>number</label><input type="number" name="number" value="" /><br />\n <label>password</label><input type="password" name="passInput" value="" /><br />\n <label>range</label><input type="range" name="rangeInput" value="" /><br />\n <label>search</label><input type="search" name="searchInput" value="" /><br />\n <label>tel</label><input type="tel" name="telInput" value="" /><br />\n <label>time</label><input type="time" name="timeInput" value="" /><br />\n <label>url</label><input type="url" name="urlInput" value="" /><br />\n <label>week</label><input type="week" name="weekInput" value="" /><br />\n </fieldset>\n\n <fieldset>\n <legend>Selects <strong>2wB: </strong> <span>"{singleSelect}"</span> <span>[{multiSelect}]</span></legend>\n\n <label>singleSelect</label>\n <select name="singleSelect">\n <option disabled selected value> -- select -- </option>\n <option value="1">Option 1</option>\n <option value="2">Option 2</option>\n <option value="3">Option 3</option>\n <option value="4">Option 4</option>\n </select><br />\n\n <label>multiSelect</label>\n <select name="multiSelect" multiple="multiple" type="select-multiple">\n <option value="1">Option 1</option>\n <option value="2" selected=true>Option 2</option>\n <option value="3">Option 3</option>\n <option value="4" selected=true>Option 4</option>\n </select>\n\n </fieldset>\n\n <fieldset>\n <legend>Radiobuttons <strong>2wB: </strong><span>"{myRadio}"</span></legend>\n\n <label>radio1</label><input type="radio" name="myRadio" value="radio1"><br />\n <label>radio2</label><input type="radio" name="myRadio" value="radio2"><br />\n <label>radio3</label><input type="radio" name="myRadio" value="radio3"><br />\n\n </fieldset>\n\n <fieldset>\n <legend>Checkboxes</legend>\n <label>cb1</label><input type="checkbox" name="cb1"><br />\n <label>cb2</label><input type="checkbox" name="cb2"><br />\n <label>cb3</label><input type="checkbox" name="cb3"><br />\n <label>cb4</label><input type="checkbox" name="cb4"><br />\n <label>cb5</label><input type="checkbox" name="cb5"><br />\n\n </fieldset>\n\n <fieldset>\n <legend>TextArea</legend>\n <label>textArea</label>\n <textarea name="textArea">abc</textarea>\n </fieldset>\n\n </form>\n '}get css(){return'\nlegend {\n display: inherit;\n margin: inherit;\n vertical-align: inherit;\n font-weight: bold;\n}\n\nlabel {\n display: inline-block;\n margin-top: 1em;\n margin-left: 5px;\n vertical-align: top;\n min-width:10em;\n text-align: right;\n}\n\nform input,\nform select,\nform textarea {\n display: inline-block;\n margin-left: 5px;\n margin-top: 1.1em;\n}\n\ninput[type="radio"],\ninput[type="checkbox"] {\n margin-top: 1.3em;\n}\n\nbody > form {\n display: block;\n}\n\nform fieldset {\n border: 1px solid #aaaaaa;\n border-radius: 3px;\n margin: 0.5em 0;\n}\n '}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"microcomponents.d.ts","sourceRoot":"","sources":["../src/microcomponents.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC"}
|