@twobirds/microcomponents 0.2.2 → 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.
Files changed (50) hide show
  1. package/README.md +45 -20
  2. package/dist/MC.min.js +1 -1
  3. package/dist/autoload.min.js +1 -1
  4. package/dist/core/MC.d.ts +288 -237
  5. package/dist/core/MC.d.ts.map +1 -1
  6. package/dist/core/MC.js +438 -182
  7. package/dist/core/elements.d.ts +58 -231
  8. package/dist/core/elements.d.ts.map +1 -1
  9. package/dist/core/elements.js +99 -214
  10. package/dist/core/index.d.ts +75 -0
  11. package/dist/core/index.d.ts.map +1 -0
  12. package/dist/core/index.js +72 -0
  13. package/dist/core/mcGuards.d.ts +7 -7
  14. package/dist/core/mcGuards.d.ts.map +1 -1
  15. package/dist/core/mcGuards.js +1 -1
  16. package/dist/elements.min.js +1 -1
  17. package/dist/formValues.min.js +1 -1
  18. package/dist/mcGuards.min.js +1 -1
  19. package/dist/microcomponents.min.js +1 -1
  20. package/dist/observables.min.js +1 -1
  21. package/dist/state/formValues.d.ts +3 -1
  22. package/dist/state/formValues.d.ts.map +1 -1
  23. package/dist/state/formValues.js +3 -1
  24. package/dist/state/index.d.ts +7 -0
  25. package/dist/state/index.d.ts.map +1 -0
  26. package/dist/state/index.js +5 -0
  27. package/dist/state/observables.d.ts +7 -59
  28. package/dist/state/observables.d.ts.map +1 -1
  29. package/dist/state/observables.js +63 -1
  30. package/dist/state/placeholders.d.ts +1 -0
  31. package/dist/state/placeholders.d.ts.map +1 -1
  32. package/dist/state/placeholders.js +1 -0
  33. package/dist/types/index.d.ts +7 -0
  34. package/dist/types/index.d.ts.map +1 -0
  35. package/dist/types/index.js +1 -0
  36. package/dist/types/mcTypes.d.ts +3 -3
  37. package/dist/types/mcTypes.js +1 -1
  38. package/dist/utils/autoload.d.ts +6 -2
  39. package/dist/utils/autoload.d.ts.map +1 -1
  40. package/dist/utils/autoload.js +7 -5
  41. package/dist/utils/events.d.ts +22 -79
  42. package/dist/utils/events.d.ts.map +1 -1
  43. package/dist/utils/events.js +63 -1
  44. package/dist/utils/helpers.d.ts +3 -2
  45. package/dist/utils/helpers.d.ts.map +1 -1
  46. package/dist/utils/helpers.js +3 -2
  47. package/dist/utils/index.d.ts +17 -0
  48. package/dist/utils/index.d.ts.map +1 -0
  49. package/dist/utils/index.js +12 -0
  50. package/package.json +9 -11
@@ -1,218 +1,46 @@
1
1
  /**
2
- * # Custom Elements
3
- * ---
4
- * Defines micro component integration with native web components and the CustomElementRegistry.
5
- * This module provides utilities for defining custom HTML elements using the native Web Components API.
6
- *
7
- * ---
8
- * The {@link defineCE} function handles registration of custom elements with the CustomElementRegistry,
9
- * automatically attaching the provided class as a DC instance ( micro component ) to the native web component created.
10
- * This class and any DC instances added to the web component later will receive all web component native events.
11
- * Only the class that defines the WC also defines its observed attributes, but all inner DCs get the changed event.
12
- * The {@link getCE} function is just a wrapper for customElements.get()
13
- *
14
- * ## Hints:
15
- * - Your micro component must extend DC, since it is a DOM element
16
- * - Method names that look like event handlers are DOM - or custom event handlers ( 'onClick()', 'oneSomething()' )
17
- * - Event handlers defined as methods will be assigned to the DOM automatically
18
- * - Micro components trigger an `init` event on themself after the constructor has run. The method `.oneInit()` catches this lifecycle event.
19
- *
20
- * ---
21
- *
22
- * @module elements
23
- *
24
- * ## Examples:
25
- *
26
- * @example define a custom component, minimum code
27
- *
28
- * javascript:
29
- * ```javascript
30
- * class MyElement extends DC {
31
- * constructor( target ){
32
- * super(target);
33
- * }
34
- * }
35
- *
36
- * defineCE( 'my-element', MyElement );
37
- * ```
38
- *
39
- * afterwards you can use ...
40
- *
41
- * html:
42
- * ```HTML
43
- * <my-element></my-element>
44
- * ```
45
- * ... in your template.
46
- *
47
- * Or you can construct it programmatically using {@link getCE}:
48
- *
49
- * javascript:
50
- * ```javascript
51
- * const MyElementClass = getCE('my-element');
52
- * const body = document.body;
53
- * body.append( new MyElementClass() );
54
- * ```
55
- *
56
- * ---
57
- * @example define a custom component with standard and/or custom event handlers
58
- *
59
- * javascript:
60
- * ```javascript
61
- * class MyElement extends DC {
62
- *
63
- * constructor( target ){
64
- * super(target);
65
- * }
66
- *
67
- * // DOM web component event handler
68
- * onConnected() {
69
- * this.innerHTML = '<p>Hi!</p>';
70
- * }
71
- *
72
- * // DOM standard event handler
73
- * onClick(){
74
- * this.trigger('something', { data: 'do something' } );
75
- * }
76
- *
77
- * // DOM custom event handler
78
- * oneSomething(ev){
79
- * // do only once! Subsequent clicks will not trigger this handler
80
- * console.log('something happens here:', ev.detail.data );
81
- * }
82
- * }
83
- * defineCE( 'my-element', MyElement );
84
- * ```
85
- *
86
- * ## Static properties
87
- *
88
- * DC classes support some static properties that configure the custom element
89
- * before any instance is constructed. These are applied automatically by `defineCE`
90
- * during element creation.
91
- *
92
- * ---
93
- * @example static tag
94
- * - replaces the default `target` element with a semantic HTML element:
95
- *
96
- * html before:
97
- * ```html
98
- * <shop-header></shop-header>
99
- * ```
100
- * javascript:
101
- * ```javascript
102
- * class ShopHeader extends DC {
103
- * static tag = 'header';
104
- * constructor(target) {
105
- * super(target);
106
- * }
107
- * }
108
- * defineCE('shop-header', ShopHeader);
109
- * ```
110
- *
111
- * html after:
112
- * ```html
113
- * <header></header>
114
- * ```
115
- *
116
- * The resulting DOM node is a `<header>` element instead of a generic template.
117
- *
118
- * ---
119
- * @example static assets
120
- * - declares companion files for auto-load and bundling by convention:
121
- *
122
- * javascript:
123
- * ```javascript
124
- * class CartContainerCheckout extends DC {
125
- * static assets = ['targetHtml', 'targetCss'];
126
- * constructor(target) {
127
- * super(target);
128
- * }
129
- * oneAssets() {
130
- * this.setupBehaviour();
131
- * }
132
- * }
133
- * defineCE('cart-container-checkout', CartContainerCheckout);
134
- * ```
135
- *
136
- * The framework resolves `targetHtml` → `checkout.target.html` and
137
- * `targetCss` → `checkout.target.css`, injects them into the element, and fires
138
- * the `_mcAssets` event so that `oneAssets()` runs.
139
- *
140
- * ---
141
- * @example static attributes
142
- * - sets HTML attributes on every instance:
143
- *
144
- * javascript:
145
- * ```javascript
146
- * class ProductCard extends DC {
147
- * static attributes = { role: 'listitem' };
148
- * constructor(target, data) {
149
- * super(target);
150
- * }
151
- * }
152
- * defineCE('product-card', ProductCard);
153
- * ```
154
- *
155
- * Every `<product-card>` element carries the attribute `role="listitem"` automatically:
156
- *
157
- * html after:
158
- * ```html
159
- * <product-card role="listitem"></product-card>
160
- * ```
161
- *
162
- * ---
163
- * @example
164
- * - All three can be combined in one class:
165
- *
166
- * javascript:
167
- * ```javascript
168
- * class ShopCatalog extends DC {
169
- * static tag = 'section';
170
- * static attributes = { role: 'list', 'aria-label': 'products' };
171
- * static assets = ['targetHtml', 'targetCss'];
172
- * constructor(target) {
173
- * super(target);
174
- * }
175
- * }
176
- * defineCE('shop-catalog', ShopCatalog);
177
- * ```
178
- *
179
- * Produces a `<section role="list" aria-label="products">` host element.
180
- *
181
- * ---
182
- * @example Creating a user defined built-in element (customized built-in element)
183
- * **Hint:**
184
- * - This is **DEPRECATED** in the standard. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#customized_built-in_elements). Use this only if you know what you are doing.
185
- * - This can be archieved in a safe way using the `static tag: 'aside';` property on your class.
186
- *
187
- * javascript:
188
- * ```javascript
189
- * class MyButton extends DC {
190
- * constructor(target) {
191
- * super(target);
192
- * }
193
- * onConnected() {
194
- * this.textContent = 'Click me!';
195
- * }
196
- * }
197
- * defineCE('my-button', MyButton, [], 'button');
198
- * ```
199
- *
200
- * afterwards you can use it in your template with the `is` attribute:
201
- *
202
- * html:
203
- * ```html
204
- * <button is="my-button"></button>
205
- * ```
206
- *
207
- *
208
- * Or you can construct it programmatically using {@link getCE}:
209
- * javascript:
210
- * ```javascript
211
- * const MyButtonClass = getCE('my-button');
212
- * const body = document.body;
213
- * body.append( new MyButtonClass() );
214
- * ```
215
- */
2
+ Custom element registration utilities — bridges DC microcomponents with the native
3
+ `CustomElementRegistry`.
4
+
5
+ This module provides:
6
+ - {@link defineCE} — wraps `customElements.define()` to register a custom element that
7
+ hosts a DC instance in its `_mc` registry. The defining class also controls observed
8
+ attributes; all inner MCs receive lifecycle events (`connected`, `disconnected`, etc.).
9
+ - {@link getCE} — typed wrapper for `customElements.get()`.
10
+ - {@link listCE} — returns every tag name registered via {@link defineCE}.
11
+
12
+ Familiarity with the [Custom Elements Web Standard](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements) is recommended.
13
+
14
+ For DC-specific documentation (static properties, event handlers, lifecycle events,
15
+ construction patterns), see the {@link DC} class in `MC.ts`.
16
+
17
+ @group Elements
18
+
19
+ @example Define custom element in registry
20
+
21
+ ```ts
22
+ class MyElement extends DC {}
23
+ defineCE('my-element', MyElement);
24
+ // Use in HTML: <my-element></my-element>
25
+ ```
26
+
27
+ @example Retrieve custom element from registry
28
+
29
+ ```ts
30
+ const MyElementClass = getCE('my-element');
31
+ if (MyElementClass) {
32
+ document.body.append(new MyElementClass());
33
+ }
34
+ ```
35
+
36
+ @example List all custom element tags registered by defineCE
37
+
38
+ ```ts
39
+ defineCE('my-element', MyElement);
40
+ defineCE('another-widget', AnotherWidget);
41
+ console.log(listCE()); // ['my-element', 'another-widget']
42
+ ```
43
+ */
216
44
  import { type McHost } from './MC.js';
217
45
  /**
218
46
  Resolves the host element type for a given `extend` tag: the matching built-in
@@ -224,12 +52,14 @@ plain `HTMLElement` otherwise.
224
52
  type Btn = TargetOf<'button'>; // HTMLButtonElement
225
53
  type Plain = TargetOf<'div'>; // HTMLElement
226
54
  ```
55
+ @group Types
227
56
  */
228
57
  export type TargetOf<E> = E extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[E] : HTMLElement;
229
58
  /**
230
59
  The type-level mirror of `kebabToPascal()` in helpers.ts: `'user-card'` →
231
60
  `'UserCard'`. Lets {@link defineCE} type the `_mc` registry entry under the
232
61
  exact key the runtime stores it at.
62
+ @group Types
233
63
  */
234
64
  export type McPascalCase<S extends string> = S extends `${infer Head}-${infer Rest}` ? `${Capitalize<Head>}${McPascalCase<Rest>}` : Capitalize<S>;
235
65
  /**
@@ -243,6 +73,7 @@ name (`N`); with the default `N = string` no entry is claimed.
243
73
  @template D - The optional construction payload accepted by `new`.
244
74
  @template E - The built-in tag being extended, if any (customized built-in elements).
245
75
  @template N - The literal PascalCase registry key; `defineCE` fills in `McPascalCase<Tag>`.
76
+ @group Types
246
77
  */
247
78
  export type McElementConstructor<T extends object = object, D = unknown, E extends keyof HTMLElementTagNameMap | undefined = undefined, N extends string = string> = new (data?: D) => McHost<TargetOf<E>, string extends N ? Record<never, never> : Record<N, T>>;
248
79
  declare global {
@@ -273,23 +104,6 @@ declare global {
273
104
  interface McElementTagNameMap {
274
105
  }
275
106
  }
276
- /**
277
- Defines a custom HTML element with optional observed attributes and micro component integration.
278
- The class provided in DefinitionClass will be added to the ._mc hash object appended to the custom element instance.
279
- Automatically assigns a "PascalCase" class name derived from the <kebab-case> tagName.
280
- If the provided definition class extends McBase (indicating a DC or MC class extension), it wraps the constructor to register
281
- the element instance with DC (DomComponent).
282
-
283
- @param tagName - The HTML tag name for the custom element (must contain at least one hyphen, enforced at compile time).
284
- @param DefinitionClass - The constructor function or class that defines the element's behavior. Its `target` parameter type follows `extend`; an optional second `data` parameter receives the payload passed on programmatic construction.
285
- @param observedAttributes - An optional array of attribute names to observe for changes.
286
- @param extend - An optional built-in HTML element tag name to extend, enabling customized built-in elements.
287
- @returns The registered custom element constructor, typed to accept the `data` payload
288
- and exposing the `_mc` entry under the PascalCase tag name — or `undefined` if the
289
- tag name was already defined. Feed it (or an equivalent `McElementConstructor`) to
290
- the global {@link McElementTagNameMap} to make `getCE()` return it typed by string.
291
-
292
- */
293
107
  export declare function defineCE<Tag extends `${string}-${string}`, T extends object, D, E extends keyof HTMLElementTagNameMap | undefined = undefined>(tagName: Tag, DefinitionClass: new (target: TargetOf<E>, data?: D) => T, observedAttributes?: string[], extend?: E): McElementConstructor<T, D, E, McPascalCase<Tag>> | undefined;
294
108
  export declare function defineCE<Tag extends `${string}-${string}`, T extends object, E extends keyof HTMLElementTagNameMap | undefined = undefined>(tagName: Tag, DefinitionClass: new (target: TargetOf<E>) => T, observedAttributes?: string[], extend?: E): McElementConstructor<T, undefined, E, McPascalCase<Tag>> | undefined;
295
109
  export declare function defineCE<Tag extends `${string}-${string}`, T extends object, D, E extends keyof HTMLElementTagNameMap | undefined = undefined>(tagName: Tag, DefinitionClass: new (target: TargetOf<E>, data: D) => T, observedAttributes?: string[], extend?: E): McElementConstructor<T, D, E, McPascalCase<Tag>> | undefined;
@@ -312,7 +126,20 @@ if (MyElementClass) {
312
126
 
313
127
  @param tagName - The HTML tag name to look up.
314
128
  @returns The constructor if defined, or undefined if not found.
129
+ @group Elements
315
130
  */
316
131
  export declare function getCE<K extends keyof McElementTagNameMap & string>(tagName: K): McElementTagNameMap[K] | undefined;
317
132
  export declare function getCE(tagName: string): CustomElementConstructor | undefined;
133
+ /**
134
+ Returns an array of all tag names registered via {@link defineCE}.
135
+
136
+ @example
137
+ ```ts
138
+ defineCE('my-element', MyElement);
139
+ defineCE('another-widget', AnotherWidget);
140
+ console.log(listCE()); // ['my-element', 'another-widget']
141
+ ```
142
+ @group Elements
143
+ */
144
+ export declare function listCE(): string[];
318
145
  //# sourceMappingURL=elements.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../../src/core/elements.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../../src/core/elements.ts"],"names":[],"mappings":"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"}
@@ -1,218 +1,46 @@
1
1
  /**
2
- * # Custom Elements
3
- * ---
4
- * Defines micro component integration with native web components and the CustomElementRegistry.
5
- * This module provides utilities for defining custom HTML elements using the native Web Components API.
6
- *
7
- * ---
8
- * The {@link defineCE} function handles registration of custom elements with the CustomElementRegistry,
9
- * automatically attaching the provided class as a DC instance ( micro component ) to the native web component created.
10
- * This class and any DC instances added to the web component later will receive all web component native events.
11
- * Only the class that defines the WC also defines its observed attributes, but all inner DCs get the changed event.
12
- * The {@link getCE} function is just a wrapper for customElements.get()
13
- *
14
- * ## Hints:
15
- * - Your micro component must extend DC, since it is a DOM element
16
- * - Method names that look like event handlers are DOM - or custom event handlers ( 'onClick()', 'oneSomething()' )
17
- * - Event handlers defined as methods will be assigned to the DOM automatically
18
- * - Micro components trigger an `init` event on themself after the constructor has run. The method `.oneInit()` catches this lifecycle event.
19
- *
20
- * ---
21
- *
22
- * @module elements
23
- *
24
- * ## Examples:
25
- *
26
- * @example define a custom component, minimum code
27
- *
28
- * javascript:
29
- * ```javascript
30
- * class MyElement extends DC {
31
- * constructor( target ){
32
- * super(target);
33
- * }
34
- * }
35
- *
36
- * defineCE( 'my-element', MyElement );
37
- * ```
38
- *
39
- * afterwards you can use ...
40
- *
41
- * html:
42
- * ```HTML
43
- * <my-element></my-element>
44
- * ```
45
- * ... in your template.
46
- *
47
- * Or you can construct it programmatically using {@link getCE}:
48
- *
49
- * javascript:
50
- * ```javascript
51
- * const MyElementClass = getCE('my-element');
52
- * const body = document.body;
53
- * body.append( new MyElementClass() );
54
- * ```
55
- *
56
- * ---
57
- * @example define a custom component with standard and/or custom event handlers
58
- *
59
- * javascript:
60
- * ```javascript
61
- * class MyElement extends DC {
62
- *
63
- * constructor( target ){
64
- * super(target);
65
- * }
66
- *
67
- * // DOM web component event handler
68
- * onConnected() {
69
- * this.innerHTML = '<p>Hi!</p>';
70
- * }
71
- *
72
- * // DOM standard event handler
73
- * onClick(){
74
- * this.trigger('something', { data: 'do something' } );
75
- * }
76
- *
77
- * // DOM custom event handler
78
- * oneSomething(ev){
79
- * // do only once! Subsequent clicks will not trigger this handler
80
- * console.log('something happens here:', ev.detail.data );
81
- * }
82
- * }
83
- * defineCE( 'my-element', MyElement );
84
- * ```
85
- *
86
- * ## Static properties
87
- *
88
- * DC classes support some static properties that configure the custom element
89
- * before any instance is constructed. These are applied automatically by `defineCE`
90
- * during element creation.
91
- *
92
- * ---
93
- * @example static tag
94
- * - replaces the default `target` element with a semantic HTML element:
95
- *
96
- * html before:
97
- * ```html
98
- * <shop-header></shop-header>
99
- * ```
100
- * javascript:
101
- * ```javascript
102
- * class ShopHeader extends DC {
103
- * static tag = 'header';
104
- * constructor(target) {
105
- * super(target);
106
- * }
107
- * }
108
- * defineCE('shop-header', ShopHeader);
109
- * ```
110
- *
111
- * html after:
112
- * ```html
113
- * <header></header>
114
- * ```
115
- *
116
- * The resulting DOM node is a `<header>` element instead of a generic template.
117
- *
118
- * ---
119
- * @example static assets
120
- * - declares companion files for auto-load and bundling by convention:
121
- *
122
- * javascript:
123
- * ```javascript
124
- * class CartContainerCheckout extends DC {
125
- * static assets = ['targetHtml', 'targetCss'];
126
- * constructor(target) {
127
- * super(target);
128
- * }
129
- * oneAssets() {
130
- * this.setupBehaviour();
131
- * }
132
- * }
133
- * defineCE('cart-container-checkout', CartContainerCheckout);
134
- * ```
135
- *
136
- * The framework resolves `targetHtml` → `checkout.target.html` and
137
- * `targetCss` → `checkout.target.css`, injects them into the element, and fires
138
- * the `_mcAssets` event so that `oneAssets()` runs.
139
- *
140
- * ---
141
- * @example static attributes
142
- * - sets HTML attributes on every instance:
143
- *
144
- * javascript:
145
- * ```javascript
146
- * class ProductCard extends DC {
147
- * static attributes = { role: 'listitem' };
148
- * constructor(target, data) {
149
- * super(target);
150
- * }
151
- * }
152
- * defineCE('product-card', ProductCard);
153
- * ```
154
- *
155
- * Every `<product-card>` element carries the attribute `role="listitem"` automatically:
156
- *
157
- * html after:
158
- * ```html
159
- * <product-card role="listitem"></product-card>
160
- * ```
161
- *
162
- * ---
163
- * @example
164
- * - All three can be combined in one class:
165
- *
166
- * javascript:
167
- * ```javascript
168
- * class ShopCatalog extends DC {
169
- * static tag = 'section';
170
- * static attributes = { role: 'list', 'aria-label': 'products' };
171
- * static assets = ['targetHtml', 'targetCss'];
172
- * constructor(target) {
173
- * super(target);
174
- * }
175
- * }
176
- * defineCE('shop-catalog', ShopCatalog);
177
- * ```
178
- *
179
- * Produces a `<section role="list" aria-label="products">` host element.
180
- *
181
- * ---
182
- * @example Creating a user defined built-in element (customized built-in element)
183
- * **Hint:**
184
- * - This is **DEPRECATED** in the standard. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#customized_built-in_elements). Use this only if you know what you are doing.
185
- * - This can be archieved in a safe way using the `static tag: 'aside';` property on your class.
186
- *
187
- * javascript:
188
- * ```javascript
189
- * class MyButton extends DC {
190
- * constructor(target) {
191
- * super(target);
192
- * }
193
- * onConnected() {
194
- * this.textContent = 'Click me!';
195
- * }
196
- * }
197
- * defineCE('my-button', MyButton, [], 'button');
198
- * ```
199
- *
200
- * afterwards you can use it in your template with the `is` attribute:
201
- *
202
- * html:
203
- * ```html
204
- * <button is="my-button"></button>
205
- * ```
206
- *
207
- *
208
- * Or you can construct it programmatically using {@link getCE}:
209
- * javascript:
210
- * ```javascript
211
- * const MyButtonClass = getCE('my-button');
212
- * const body = document.body;
213
- * body.append( new MyButtonClass() );
214
- * ```
215
- */
2
+ Custom element registration utilities — bridges DC microcomponents with the native
3
+ `CustomElementRegistry`.
4
+
5
+ This module provides:
6
+ - {@link defineCE} — wraps `customElements.define()` to register a custom element that
7
+ hosts a DC instance in its `_mc` registry. The defining class also controls observed
8
+ attributes; all inner MCs receive lifecycle events (`connected`, `disconnected`, etc.).
9
+ - {@link getCE} — typed wrapper for `customElements.get()`.
10
+ - {@link listCE} — returns every tag name registered via {@link defineCE}.
11
+
12
+ Familiarity with the [Custom Elements Web Standard](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements) is recommended.
13
+
14
+ For DC-specific documentation (static properties, event handlers, lifecycle events,
15
+ construction patterns), see the {@link DC} class in `MC.ts`.
16
+
17
+ @group Elements
18
+
19
+ @example Define custom element in registry
20
+
21
+ ```ts
22
+ class MyElement extends DC {}
23
+ defineCE('my-element', MyElement);
24
+ // Use in HTML: <my-element></my-element>
25
+ ```
26
+
27
+ @example Retrieve custom element from registry
28
+
29
+ ```ts
30
+ const MyElementClass = getCE('my-element');
31
+ if (MyElementClass) {
32
+ document.body.append(new MyElementClass());
33
+ }
34
+ ```
35
+
36
+ @example List all custom element tags registered by defineCE
37
+
38
+ ```ts
39
+ defineCE('my-element', MyElement);
40
+ defineCE('another-widget', AnotherWidget);
41
+ console.log(listCE()); // ['my-element', 'another-widget']
42
+ ```
43
+ */
216
44
  import { kebabToPascal } from '../utils/helpers.js';
217
45
  import { McBase, DC } from './MC.js';
218
46
  /**
@@ -237,6 +65,46 @@ function Base(ElementClass) {
237
65
  }
238
66
  };
239
67
  }
68
+ /**
69
+ ### Examples
70
+ ---
71
+
72
+ #### Define custom element in registry
73
+
74
+ ```ts
75
+ class MyElement extends DC {}
76
+ defineCE('my-element', MyElement);
77
+ // Use in HTML: <my-element></my-element>
78
+ ```
79
+ #### Define custom element in registry with observed attributes
80
+
81
+ ```ts
82
+ class MyElement extends DC {
83
+ onAttributeChanged(ev){
84
+ const newValue = ev.detail.data.newValue;
85
+ }
86
+ }
87
+ defineCE('my-element', MyElement, ['observed']);
88
+ // Use in HTML: <my-element observed></my-element>
89
+ // When the 'observed' attribut is changed, 'attributeChanged' is triggered, which in turn calls 'onAttributeChanged' with the data in the payload
90
+ ```
91
+
92
+ Defines a custom HTML element with optional observed attributes and micro component integration.
93
+ The class provided in DefinitionClass will be added to the ._mc hash object appended to the custom element instance.
94
+ Automatically assigns a "PascalCase" class name derived from the <kebab-case> tagName.
95
+ If the provided definition class extends McBase (indicating a DC or MC class extension), it wraps the constructor to register
96
+ the element instance with DC (DomComponent).
97
+
98
+ @param tagName - The HTML tag name for the custom element (must contain at least one hyphen, enforced at compile time).
99
+ @param DefinitionClass - The constructor function or class that defines the element's behavior. Its `target` parameter type follows `extend`; an optional second `data` parameter receives the payload passed on programmatic construction.
100
+ @param observedAttributes - An optional array of attribute names to observe for changes.
101
+ @param extend - DEPRECATED! An optional built-in HTML element tag name to extend, enabling customized built-in elements.
102
+ @returns The registered custom element constructor, typed to accept the `data` payload
103
+ and exposing the `_mc` entry under the PascalCase tag name — or `undefined` if the
104
+ tag name was already defined. Feed it (or an equivalent `McElementConstructor`) to
105
+ the global {@link McElementTagNameMap} to make `getCE()` return it typed by string.
106
+ @group Elements
107
+ */
240
108
  // Implementation signature (not directly callable)
241
109
  export function defineCE(tagName, DefinitionClass, observedAttributes = [], extend) {
242
110
  if (customElements.get(tagName)) {
@@ -285,8 +153,25 @@ export function defineCE(tagName, DefinitionClass, observedAttributes = [], exte
285
153
  }
286
154
  });
287
155
  customElements.define(tagName, McElementClass, { extends: extend });
156
+ if (!defineCE.list)
157
+ defineCE.list = [];
158
+ defineCE.list.push(tagName);
288
159
  return McElementClass;
289
160
  }
290
161
  export function getCE(tagName) {
291
162
  return customElements.get(tagName);
292
163
  }
164
+ /**
165
+ Returns an array of all tag names registered via {@link defineCE}.
166
+
167
+ @example
168
+ ```ts
169
+ defineCE('my-element', MyElement);
170
+ defineCE('another-widget', AnotherWidget);
171
+ console.log(listCE()); // ['my-element', 'another-widget']
172
+ ```
173
+ @group Elements
174
+ */
175
+ export function listCE() {
176
+ return defineCE.list ?? [];
177
+ }