@twobirds/microcomponents 0.0.34 → 0.0.39
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 +40 -27
- package/assets/documentation/{MicroComponents.md → MC.md} +17 -17
- package/assets/documentation/comparision.md +0 -0
- package/assets/documentation/elements.md +276 -0
- package/assets/documentation/magic.md +10 -68
- package/assets/my-tag.css +6 -2
- package/dist/MC.d.ts +3 -4
- package/dist/MC.d.ts.map +1 -1
- package/dist/MC.min.js +89 -66
- package/dist/MC.ts +213 -178
- package/dist/autoloader.ts +1 -1
- package/dist/{customElements.d.ts → elements.d.ts} +1 -1
- package/dist/elements.d.ts.map +1 -0
- package/dist/elements.min.js +1 -0
- package/dist/{customElements.ts → elements.ts} +23 -14
- package/dist/helpers.d.ts +6 -4
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.ts +95 -128
- package/dist/microcomponents.d.ts +3 -3
- package/dist/microcomponents.d.ts.map +1 -1
- package/dist/microcomponents.min.js +1 -1
- package/dist/microcomponents.ts +3 -3
- package/dist/{customObservables.d.ts → observables.d.ts} +3 -3
- package/dist/observables.d.ts.map +1 -0
- package/dist/observables.min.js +1 -0
- package/dist/observables.ts +353 -0
- package/dist/{customSelectors.d.ts → selectors.d.ts} +1 -1
- package/dist/selectors.d.ts.map +1 -0
- package/dist/selectors.min.js +1 -0
- package/dist/test.ts +135 -156
- package/klemmstein.png +0 -0
- package/package.json +52 -52
- package/public/MC.js +90 -67
- package/public/MC.js.map +1 -1
- package/public/MC.min.js +89 -66
- package/public/assets/search.js +1 -1
- package/public/autoloader.js +1 -1
- package/public/autoloader.js.map +1 -1
- package/public/classes/{DC.html → MC.DC.html} +60 -59
- package/public/classes/{MC.html → MC.MC.html} +41 -35
- package/public/classes/{McBase.html → MC.McBase.html} +28 -20
- package/public/classes/{McEvent.html → MC.McEvent.html} +48 -42
- package/public/documentation/{MicroComponents.md → MC.md} +17 -17
- package/public/documentation/comparision.md +0 -0
- package/public/documentation/elements.md +276 -0
- package/public/documentation/magic.md +10 -68
- package/public/{customElements.js → elements.js} +9 -10
- package/public/elements.js.map +1 -0
- package/public/elements.min.js +1 -0
- package/public/functions/{addListener.html → MC.addListener.html} +18 -12
- package/public/functions/{removeListener.html → MC.removeListener.html} +18 -12
- package/public/functions/elements.defineCE.html +78 -0
- package/public/functions/elements.getCE.html +63 -0
- package/public/functions/formValues.formValues.html +68 -0
- package/public/functions/observables.observe.html +65 -0
- package/public/functions/selectors._d.html +69 -0
- package/public/functions/selectors._t.html +69 -0
- package/public/helpers.js +66 -89
- package/public/helpers.js.map +1 -1
- package/public/index.html +48 -33
- package/public/interfaces/{HTMLMcElement.html → MC.HTMLMcElement.html} +601 -595
- package/public/interfaces/selectors.DSelector.html +1013 -0
- package/public/interfaces/selectors.TSelector.html +712 -0
- package/public/microcomponents.js +3 -3
- package/public/microcomponents.js.map +1 -1
- package/public/microcomponents.min.js +1 -1
- package/public/modules/MC.html +78 -0
- package/public/modules/elements.html +62 -0
- package/public/modules/formValues.html +60 -0
- package/public/modules/observables.html +65 -0
- package/public/modules/selectors.html +76 -0
- package/public/modules.html +11 -23
- package/public/my-tag.css +6 -2
- package/public/observables.js +259 -0
- package/public/observables.js.map +1 -0
- package/public/observables.min.js +1 -0
- package/public/{customSelectors.js → selectors.js} +1 -1
- package/public/selectors.js.map +1 -0
- package/public/selectors.min.js +1 -0
- package/public/src/MC.ts +413 -0
- package/public/src/McEvent.ts +96 -0
- package/public/src/autoloader.ts +98 -0
- package/{src/customElements.ts → public/src/elements.ts} +23 -14
- package/public/src/formValues.ts +275 -0
- package/public/src/helpers.ts +140 -0
- package/public/src/microcomponents.ts +8 -0
- package/public/src/observables.ts +353 -0
- package/public/src/test.ts +190 -0
- package/public/test.js +93 -118
- package/public/test.js.map +1 -1
- package/public/types/observables.Observable.html +91 -0
- package/public/types/selectors.selection.html +58 -0
- package/public/types/selectors.singleSelector.html +58 -0
- package/src/MC.ts +213 -178
- package/src/autoloader.ts +1 -1
- package/src/elements.ts +76 -0
- package/src/helpers.ts +95 -128
- package/src/microcomponents.ts +3 -3
- package/src/observables.ts +353 -0
- package/src/selectors.ts +1634 -0
- package/src/test.ts +135 -156
- package/typedoc.json +1 -1
- package/webpack.config.js +9 -9
- package/dist/customElements.d.ts.map +0 -1
- package/dist/customElements.min.js +0 -1
- package/dist/customObservables.d.ts.map +0 -1
- package/dist/customObservables.min.js +0 -1
- package/dist/customObservables.ts +0 -348
- package/dist/customSelectors.d.ts.map +0 -1
- package/dist/customSelectors.min.js +0 -1
- package/public/customElements.js.map +0 -1
- package/public/customElements.min.js +0 -1
- package/public/customObservables.js +0 -256
- package/public/customObservables.js.map +0 -1
- package/public/customObservables.min.js +0 -1
- package/public/customSelectors.js.map +0 -1
- package/public/customSelectors.min.js +0 -1
- package/src/customObservables.ts +0 -348
- /package/dist/{customSelectors.ts → selectors.ts} +0 -0
- /package/{src/customSelectors.ts → public/src/selectors.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,43 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+

|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## MICRO COMPONENTS
|
|
4
4
|
|
|
5
5
|
**This code aims at improving Javascript modularity and encapsulation**.
|
|
6
6
|
|
|
7
7
|
Using micro components enforces **DRY, KISS and SOLID** principles in Javascript programming.
|
|
8
8
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
**WIP**. Should be done soon. In [manual testing](http://twobirds.gitlab.io/microcomponents/test.html), also working a lot on the documentation.
|
|
12
|
-
|
|
13
|
-
## Skippable Disclaimer
|
|
14
|
-
I decided to extract this functionality from the [twoBirds framework](https://www.npmjs.com/package/twobirds-core), because it is a useful tool in itself and it is framework agnostic. It relies solely on the standard DOM and native javascript or typescript.
|
|
15
|
-
|
|
16
|
-
Later this will be backported into twoBirds as a dependency, and twoBirds will become completely modularized on the base of MCs.
|
|
9
|
+
## Think **Building Blocks**
|
|
17
10
|
|
|
18
|
-
|
|
11
|
+
When coding with this system, you create classes that extend either the **[MC](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/MC.md?ref_type=heads#mc-class-extends-mcbase)** or **[DC](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/MC.md?ref_type=heads#dc-class-extends-mcbase)** superclasses provided here. These classes provide the structure you need to build your wonderland.
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
**This is a low-level OOP approach to Javascript programming.**
|
|
13
|
+
In an almost literal sense they work like childrens building blocks, where a chest full of unassuming parts lets you compose whatever functionality lies in your imagination.
|
|
23
14
|
|
|
24
|
-
|
|
15
|
+
This systems **modular** approach gives you full control over your software, without the need to rely on other frameworks. On the other hand, its **minimalistic** stance enables you to use the resulting functionality in any other framework, and makes the **learning curve neglectable**.
|
|
25
16
|
|
|
26
|
-
|
|
17
|
+
## Status
|
|
27
18
|
|
|
28
|
-
|
|
19
|
+
**WIP**. Should be done soon. In [manual testing](http://twobirds.gitlab.io/microcomponents/test.html), also working a lot on the documentation.
|
|
29
20
|
|
|
30
|
-
|
|
21
|
+
## General
|
|
31
22
|
|
|
32
|
-
|
|
23
|
+
- **This is a low-level OOP approach to Javascript programming.** It aims at proving that strict OOP is a valid alternative to other frameworks functional approaches.
|
|
24
|
+
- You can use it in vanilla JS or Typescript coding environments.
|
|
33
25
|
|
|
34
26
|
This repository exports 5 independent functionalities:
|
|
35
27
|
|
|
36
|
-
1. **[Micro Components](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/
|
|
37
|
-
2. **
|
|
38
|
-
3. **
|
|
39
|
-
4.
|
|
40
|
-
5. (
|
|
28
|
+
1. **[Micro Components](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/MC.md?ref_type=heads)** contains the **MC** and **DC** classes you can use as super classes.
|
|
29
|
+
2. **[Elements](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/elements.md?ref_type=heads)** lets you define and use your own native web components. Uses (1).
|
|
30
|
+
3. (wip) **Observables** add **observability** and **run time type safety** to object properties. Also they provide **1-way binding** to placeholders in your template HTML.
|
|
31
|
+
4. (wip) **FormValues** gives you **2-way binding** between a HTML form and an observable object. Uses (3).
|
|
32
|
+
5. (wip) **Selectors** provide chainable jQuery like selectors for both the DOM and micro components.
|
|
41
33
|
|
|
42
34
|
Also there is a bundle file that contains all of the above.
|
|
43
35
|
|
|
@@ -45,7 +37,7 @@ Check the [typedoc API reference](https://twobirds.gitlab.io/microcomponents/mod
|
|
|
45
37
|
|
|
46
38
|
To see what can be done, go to [additional concepts](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/magic.md?ref_type=heads) which shows what it already has been used for.
|
|
47
39
|
|
|
48
|
-
## Simple Usage
|
|
40
|
+
## Simple Usage Example
|
|
49
41
|
|
|
50
42
|
**Micro Components** can be added to to a DOM element like this:
|
|
51
43
|
|
|
@@ -90,9 +82,30 @@ after:
|
|
|
90
82
|
```HTML
|
|
91
83
|
<div _mc></div>
|
|
92
84
|
```
|
|
93
|
-
_mc indicates that this HTML element contains at least one micro component
|
|
85
|
+
The `_mc` **attribute** indicates that this **HTML element contains at least one micro component**. This is needed for the selectors.
|
|
86
|
+
|
|
87
|
+
The `_mc` **attribute** and **property** are the only interference with the DOM, so any other system should be happy to work with this.
|
|
88
|
+
|
|
89
|
+
## Disclaimer
|
|
90
|
+
I decided to extract this functionality from the [twoBirds framework](https://www.npmjs.com/package/twobirds-core), because it is a useful tool in itself and it is framework agnostic. It relies solely on the standard DOM and native javascript or typescript.
|
|
91
|
+
|
|
92
|
+
Later this will be backported into twoBirds as a dependency, and twoBirds will become completely modularized on the base of MCs.
|
|
93
|
+
|
|
94
|
+
**This is a massive undertaking.** MCs are just the foundation of what I do. I am about to dump [20+ years of javascript programming](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/magic.md?ref_type=heads#things-i-already-did-with-this-in-my-own-framework-twobirds-or-in-apps-that-i-developed-with-it) into open source libraries, so feel free to [fund this](https://www.gofundme.com/f/nachhaltige-programmierung). The better this is funded, the faster it will be done. Given enough resources, I will start a crowdfunded company that will develop a new open source ecosystem for javascript/typescript programming. By **"Open Source"** I mean **really free and open**, as **you get all my inner source code with it**. Once you understand the Micro Component principle, you are back in command of your software, no matter what MC functionality you import in your system.
|
|
95
|
+
|
|
96
|
+
Since **Micro Components** are encapsuled, off-shoring and near-shoring is no problem, and reusability is guaranteed. Your external coders do not need to access your code repository or your toolchain. They only need to understand MCs.
|
|
97
|
+
|
|
98
|
+
## Distinct differences to other frameworks
|
|
99
|
+
|
|
100
|
+
There are a few potentially unique aspects of this micro components system that might differentiate it from other frameworks:
|
|
101
|
+
|
|
102
|
+
- **Pure OOP Approach**: The system explicitly positions itself as a strict object-oriented alternative to the functional approaches that dominate many modern frameworks.
|
|
103
|
+
- **Minimal Interference**: The system has minimal DOM interference (only adding _mc attribute and property). This makes it unusually compatible with other frameworks or libraries.
|
|
104
|
+
- **Hierarchical Component Traversal**: The built-in parent/child/ancestor/descendant traversal methods provide a clean way to navigate component relationships.
|
|
105
|
+
- **Direct DOM Integration**: Unlike virtual DOM-based frameworks, this approach works directly with the actual DOM while still providing component encapsulation.
|
|
106
|
+
- **Outsourcing Potential**: Your external coders do not need to access your code repository or your toolchain.
|
|
94
107
|
|
|
95
|
-
The
|
|
108
|
+
The strongest argument might be for developers who prefer OOP, want minimal framework lock-in, and need a lightweight solution that works well with existing code or other libraries.
|
|
96
109
|
|
|
97
110
|
## Contact
|
|
98
111
|
Feel free to contact me for any questions or inquiries:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Micro Components
|
|
1
|
+
# Micro Components <span style="float:right; height:1em;"><img height="24px" src="./MicroComponents.svg" /></span>
|
|
2
2
|
|
|
3
3
|
This system allows you to to define **Micro Components** and attach them to DOM elements or other Micro Components.
|
|
4
4
|
|
|
@@ -6,15 +6,12 @@ The module exports 2 classes:
|
|
|
6
6
|
- **MC**: Micro Component ( not DOM related, works on the server also )
|
|
7
7
|
- **DC**: Dom Component ( extends MC and adds DOM related methods, client only )
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
In general when coding with this system, you create classes that extend either the **DC** or **MC** class provided here.
|
|
12
|
-
|
|
13
|
-
**If your functionality needs to access the DOM**, e.g. to find other DC instances, **your class extends DC**.
|
|
9
|
+
# Usage
|
|
14
10
|
|
|
15
|
-
**
|
|
11
|
+
- **If your functionality needs to access the DOM**, e.g. to find other DC instances, **your class extends DC**.
|
|
12
|
+
- **Otherwise** - and always on the server - **your class extends MC**.
|
|
16
13
|
|
|
17
|
-
In any case, your class instances will contain a property **"_mc"** where you can put in other MCs.
|
|
14
|
+
In any case, your class instances will contain a property **"_mc"** where you can (but don't have to) put in other MCs.
|
|
18
15
|
|
|
19
16
|
Also your class instances will have a readonly **"target"** property that is back reference to the instance they are contained in.
|
|
20
17
|
|
|
@@ -27,25 +24,28 @@ As an application programmer you should understand **MC** and **DC** methods and
|
|
|
27
24
|
- **DC** use observables and formValues to provide 1-way and 2-way binding to the DOM.
|
|
28
25
|
- **DC** have selectors to find other DCs in the DOM.
|
|
29
26
|
|
|
30
|
-
#
|
|
27
|
+
# Rules
|
|
31
28
|
|
|
32
29
|
- **Your own application code MUST NOT overwrite the properties and methods in the classes below.**
|
|
33
30
|
- If you do it anyway, you do it on your own risk.
|
|
34
31
|
|
|
35
32
|
# Not Exported
|
|
36
33
|
|
|
37
|
-
## McBase
|
|
34
|
+
## **McBase** Superclass
|
|
38
35
|
|
|
39
36
|
**Instance Properties**
|
|
40
37
|
- `.target`: readonly, a getter returning the DOM element or parent MC instance your instance resides in
|
|
41
38
|
|
|
42
39
|
**Constructor:**
|
|
43
40
|
- calls `init()`: triggers the 'init' lifecycle event, also recursively into the inner '._mc' structure.
|
|
44
|
-
- calls `autoAttachListeners()`: methods in your
|
|
41
|
+
- calls `autoAttachListeners()`: methods in your class code that start with "on[A-Z]" or "one[A-Z]" and describe native DOM events (e.g. "onClick") will be added to the DOM Element as listeners.
|
|
42
|
+
|
|
43
|
+
- **Instance Methods:**
|
|
44
|
+
- `.trigger( eventName, data )`: runs callback methods.
|
|
45
45
|
|
|
46
46
|
# Exported:
|
|
47
47
|
|
|
48
|
-
## MC
|
|
48
|
+
## **MC** Class, extends McBase
|
|
49
49
|
|
|
50
50
|
**Instance Properties**
|
|
51
51
|
- `.target`: (inherited from McBase)
|
|
@@ -54,7 +54,7 @@ As an application programmer you should understand **MC** and **DC** methods and
|
|
|
54
54
|
- **Instance Methods:**
|
|
55
55
|
- `.trigger( eventName, data )`: (inherited from McBase)
|
|
56
56
|
|
|
57
|
-
## DC
|
|
57
|
+
## **DC** Class, extends McBase
|
|
58
58
|
|
|
59
59
|
- **Static Methods:**
|
|
60
60
|
- `DC.add( DomElement, key, mc)`: Add a DC to an HTMLElement.
|
|
@@ -72,7 +72,7 @@ As an application programmer you should understand **MC** and **DC** methods and
|
|
|
72
72
|
- `.descendants(search?)`: Get descendant DCs.
|
|
73
73
|
- `.trigger( eventName, data, bubble )`: trigger an event on "this", handles directional bubbling in the DOM.
|
|
74
74
|
|
|
75
|
-
#
|
|
75
|
+
# Examples
|
|
76
76
|
|
|
77
77
|
## Typical Workflow
|
|
78
78
|
|
|
@@ -105,12 +105,12 @@ MyPublicClass = class extends DC{
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
// attach a DC
|
|
108
|
-
DC.add( myElement, 'myDcComponent', new
|
|
108
|
+
DC.add( myElement, 'myDcComponent', new MyPublicClass( myElement ) );
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
#### **Hint**
|
|
112
|
-
- After you added a micro component using this function, the **HTMLElement will contain a property `_mc`** which contains the
|
|
113
|
-
- Also the **HTMLElement then has an attribute '_mc'**
|
|
112
|
+
- After you added a micro component using this function, the **HTMLElement will contain a property `_mc`** which contains the MC instances visible in the DOM.
|
|
113
|
+
- Also the **HTMLElement then has an attribute '_mc'** to indicate that at least one micro component is attached to this dom element.
|
|
114
114
|
|
|
115
115
|
### Remove a top level Micro Component from a DOM element
|
|
116
116
|
|
|
File without changes
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# Custom Elements <span style="float:right; height:1em;"><img height="24px" src="https://gitlab.com/twoBirds/microcomponents/-/raw/main/MicroComponents.svg" /></span>
|
|
2
|
+
|
|
3
|
+
Custom Elements provides two funktions:
|
|
4
|
+
- **defineCE()** lets you define a custom tag and add functionality to it. Internally it uses [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define).
|
|
5
|
+
- **getCE()** retrieves a custom element constructor from the web component registry via [CustomElementRegistry.get()](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/get).
|
|
6
|
+
|
|
7
|
+
# Prerequisites
|
|
8
|
+
|
|
9
|
+
You should at least know Micro Components **[DC](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/MicroComponents.md?ref_type=heads#dc-class-extends-mcbase)** superclass usage, since your own class code extends from it and uses its static functions. It is recommended that you have read and understood the **[Micro Component documentation](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/MicroComponents.md?ref_type=heads)**, since custom elements is just an extension that internally uses micro components.
|
|
10
|
+
|
|
11
|
+
# Usage
|
|
12
|
+
|
|
13
|
+
## Create a Custom Element
|
|
14
|
+
|
|
15
|
+
Before:
|
|
16
|
+
|
|
17
|
+
```html
|
|
18
|
+
<body></body>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
defineCE(
|
|
23
|
+
// equivalent to and internally using customElementRegistry.define()
|
|
24
|
+
"my-tag",
|
|
25
|
+
class MyTag extends DC {
|
|
26
|
+
|
|
27
|
+
constructor(target, data = {} ) {
|
|
28
|
+
super(target);
|
|
29
|
+
this.data = data;
|
|
30
|
+
target.innerHTML = "Hello World";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
let MyTag = getCE("my-tag"),
|
|
36
|
+
data = { a: 1 },
|
|
37
|
+
myTag = new MyTag( data );
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
HINT:
|
|
41
|
+
At this point the web component is not yet attached to the DOM.
|
|
42
|
+
But you can perform any operation on it, e.g. calling methods on its inner micro components.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
document.body.append( myTag );
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
After:
|
|
49
|
+
```html
|
|
50
|
+
<body>
|
|
51
|
+
<my-tag _mc>Hello World</my-tag>
|
|
52
|
+
</body>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### **Hints**
|
|
56
|
+
- Your code extends the **[DC](https://gitlab.com/twoBirds/microcomponents/-/blob/main/assets/documentation/MicroComponents.md?ref_type=heads#dc-class-extends-mcbase)** superclass. This superclass provides methods to traverse the DOM and select other micro components contained in HTML elements.
|
|
57
|
+
- it is essential to understand that your web component code is only one of the numerous micro components that can reside inside `<my-tag>`
|
|
58
|
+
- After you created a custom element, the custom element will contain a **property `<my-tag>._mc`** which contains your class instance.
|
|
59
|
+
- Also the custom element then has an **attribute '_mc'** which will indicate that at least one micro component is attached to it.
|
|
60
|
+
- Note that you can hand over data natively via parameters, when handling custom elements in above way.
|
|
61
|
+
- The native way of usage, simply adding the tag to the template, is still possible. You have to use attributes then to hand in data.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
## Web Component Lifecycle Events
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
defineCE(
|
|
68
|
+
"my-tag",
|
|
69
|
+
class MyTag extends DC {
|
|
70
|
+
|
|
71
|
+
constructor(target) {
|
|
72
|
+
super(target);
|
|
73
|
+
target.setAttribute('my-attribute', 'change me');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/*
|
|
77
|
+
web component specific event handlers
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
onConnected(ev) {
|
|
81
|
+
console.info("MyTag .onConnected() handler", ev);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
onAttributeChanged(ev) {
|
|
85
|
+
console.info("MyTag .onAttributeChanged() handler", ev);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
onAdopted(ev) {
|
|
89
|
+
console.info("MyTag .onAdopted() handler", ev);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
onDisconnected(ev) {
|
|
93
|
+
console.info("MyTag .onDisconnected() handler", ev);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
['my-attribute'] // DOM node attributes to observe
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
let MyTag = getCE("my-tag"),
|
|
100
|
+
myTag = new MyTag();
|
|
101
|
+
|
|
102
|
+
document.body.append( myTag );
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
You can use your Web Component constructor to add other modules to the `<my-tag>` DOM node:
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
|
|
109
|
+
class OtherModule extends DC {
|
|
110
|
+
|
|
111
|
+
constructor(target) {
|
|
112
|
+
super(target);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
onConnected(ev) {
|
|
116
|
+
console.info("[OtherModule] .onConnected() handler", ev);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
defineCE(
|
|
121
|
+
"my-tag",
|
|
122
|
+
class MyTag extends DC {
|
|
123
|
+
|
|
124
|
+
constructor(target) {
|
|
125
|
+
super(target);
|
|
126
|
+
DC.add( target, 'otherModule', new OtherModule(target) );
|
|
127
|
+
// equivalent:
|
|
128
|
+
// target._mc.otherModule = new OtherModule(target);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
onConnected(ev) {
|
|
132
|
+
console.info("[MyTag] .onConnected() handler", ev);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
let MyTag = getCE("my-tag");
|
|
139
|
+
|
|
140
|
+
document.body.append( new MyTag() );
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### **Hints**
|
|
144
|
+
- You can add as many other micro components to the DOM node as you like.
|
|
145
|
+
- The native web component lifecycle events will be triggered on **all** micro components.
|
|
146
|
+
- The event parameter handed over is an internal event instance, that contains the original native event in its `data` property.
|
|
147
|
+
|
|
148
|
+
## Native Event Handlers
|
|
149
|
+
|
|
150
|
+
Native event handlers will be auto-attached, when the method name follows one of these two schemes:
|
|
151
|
+
|
|
152
|
+
- **on[A-Z]...**: e.g. **onClick(){ ... }** will be called when the native event is triggered
|
|
153
|
+
- **one[A-Z]...**: e.g. **oneClick(){ ... }** will be called **once** only when the native event is triggered. Subsequent events will be ignored.
|
|
154
|
+
|
|
155
|
+
```javascript
|
|
156
|
+
defineCE(
|
|
157
|
+
"my-tag",
|
|
158
|
+
class MyTag extends DC {
|
|
159
|
+
|
|
160
|
+
constructor(target) {
|
|
161
|
+
super(target);
|
|
162
|
+
target.innerHTML = "Click Me";
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
native event handlers
|
|
167
|
+
*/
|
|
168
|
+
onClick(ev) {
|
|
169
|
+
console.info("MyTag .onClick() handler", ev);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
let MyTag = getCE("my-tag");
|
|
175
|
+
|
|
176
|
+
document.body.append( new MyTag() );
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### **Hints**
|
|
180
|
+
- The native web component lifecycle events will be triggered on **all** micro components contained in the custom element, provided the MC contains a matching named handler.
|
|
181
|
+
- The event parameter handed over is an internal event instance, that contains the original native event in its .data property.
|
|
182
|
+
|
|
183
|
+
## Lifecycle Event Handlers
|
|
184
|
+
|
|
185
|
+
Currently there is only one lifecycle event handler: the **oneInit(){ ... }** method you provide with your class.
|
|
186
|
+
|
|
187
|
+
This method is triggered asynchronous via a timeout after you made a new instance of your class.
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
defineCE(
|
|
191
|
+
"my-tag",
|
|
192
|
+
class MyTag extends DC {
|
|
193
|
+
|
|
194
|
+
constructor(target) {
|
|
195
|
+
super(target);
|
|
196
|
+
target.innerHTML = "Hello World";
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/*
|
|
200
|
+
lifecycle event handlers
|
|
201
|
+
*/
|
|
202
|
+
oneInit(ev) {
|
|
203
|
+
console.info("MyTag .onInit() handler", ev);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
let MyTag = getCE("my-tag");
|
|
209
|
+
|
|
210
|
+
document.body.append( new MyTag() );
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### **Hints**
|
|
214
|
+
- The native web component lifecycle events will be triggered on **all** micro components contained in the custom element, provided the specific micro component contains a matching named handler.
|
|
215
|
+
- The event parameter handed over is an internal event instance that contains no data.
|
|
216
|
+
|
|
217
|
+
## Custom Events
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
defineCE(
|
|
221
|
+
"my-tag",
|
|
222
|
+
class MyTag extends DC {
|
|
223
|
+
|
|
224
|
+
constructor(target) {
|
|
225
|
+
super(target);
|
|
226
|
+
target.innerHTML = "Hello World";
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/*
|
|
230
|
+
custom event handlers
|
|
231
|
+
*/
|
|
232
|
+
onSpecialEvent(ev) {
|
|
233
|
+
console.log('MyTag .onSpecialEvent() handler', ev);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
let MyTag = getCE("my-tag");
|
|
239
|
+
|
|
240
|
+
document.body.append( new MyTag() );
|
|
241
|
+
|
|
242
|
+
document
|
|
243
|
+
.querySelector( 'my-tag' )
|
|
244
|
+
?._mc
|
|
245
|
+
.MyTag
|
|
246
|
+
.trigger('specialEvent');
|
|
247
|
+
|
|
248
|
+
/*
|
|
249
|
+
Alternatives:
|
|
250
|
+
*/
|
|
251
|
+
|
|
252
|
+
document
|
|
253
|
+
.querySelector( 'my-tag' )
|
|
254
|
+
?._mc
|
|
255
|
+
.trigger('specialEvent'); // ...on all micro components contained in <my-tag>
|
|
256
|
+
|
|
257
|
+
/*
|
|
258
|
+
traversing the DOM:
|
|
259
|
+
<my-tag>
|
|
260
|
+
<my-inner-tag />
|
|
261
|
+
</my-tag>
|
|
262
|
+
*/
|
|
263
|
+
|
|
264
|
+
// <my-tag> method:
|
|
265
|
+
onSpecialEvent(ev){
|
|
266
|
+
console.log( ev.data );
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// <my-inner-tag> method:
|
|
270
|
+
sendSpecialEvent(){
|
|
271
|
+
this.trigger( 'specialEvent', "Hello World", 'u' ); // 'u' = bubble up.
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### **Hints**
|
|
276
|
+
- The event parameter handed over is an internal event instance, that contains the payload in its .data property.
|
|
@@ -1,63 +1,12 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
**Micro Components** can literally be anything you can put into an object as a property.
|
|
4
|
-
|
|
5
|
-
Here are some examples of what **Micro Components** can really archieve.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## The MC() class can be used as a selector of its own, even if you dont attach a micro component yourself
|
|
9
|
-
|
|
10
|
-
Since MC is a class you instanciate with a target element as your selection root element, and you can do this:
|
|
11
|
-
|
|
12
|
-
```javascript
|
|
13
|
-
const myElement = document.getElementById('myDiv');
|
|
14
|
-
|
|
15
|
-
// find the nearst MC parent elements to this HTMLElement
|
|
16
|
-
const myParent = ( new MC( myElement ) ).parent();
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Since MC() is a class, you can extend your own micro components with it and have the selectors nicely available
|
|
20
|
-
|
|
21
|
-
Here is some typical usage:
|
|
22
|
-
|
|
23
|
-
```javascript
|
|
24
|
-
class MyMicroComponent extends MC {
|
|
25
|
-
|
|
26
|
-
constructor( target ){
|
|
27
|
-
super(target);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
showParents(){
|
|
31
|
-
console.log( this.parents() ); // Logs all anchestor micro components
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
let myDiv = document.querySelector('div');
|
|
36
|
-
|
|
37
|
-
MC.add( myDiv, 'my_micro_component', new MyMicroComponent( myDiv ) );
|
|
38
|
-
|
|
39
|
-
// TADA!
|
|
40
|
-
myDiv
|
|
41
|
-
._mc
|
|
42
|
-
.my_micro_component
|
|
43
|
-
.showParents();
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
As you can see, without any effort you have a **second structural layer that hovers over the DOM**.
|
|
47
|
-
|
|
48
|
-
The browser knows nothing of this, except that there may be _mc properties on some HTMLElements.
|
|
49
|
-
|
|
50
|
-
It doesnt get more standard compliant than that.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
## Things I already did with this, in my own framework twoBirds, or in apps that I developed with it:
|
|
1
|
+
# Things I already did with this...
|
|
54
2
|
|
|
55
3
|
- `encapsulated and modular 3D rendering` in an HTMLElement viewport.
|
|
56
|
-
- `Data Driven Workflow` with micro components using
|
|
4
|
+
- `Data Driven Workflow` with micro components using observables.
|
|
57
5
|
- `DOM handling` in general, lots of `UI functionality`
|
|
58
|
-
- `2 way Data Binding` between forms and observable objects representing the form data
|
|
59
6
|
- `1 way Data Binding` from data observables to the DOM
|
|
60
|
-
- `
|
|
7
|
+
- `2 way Data Binding` between forms and observables representing the form data
|
|
8
|
+
- `progressive enhancement` / `graceful degradation` on standard websites
|
|
9
|
+
- `Loose Coupling` via custom event objects
|
|
61
10
|
- `Rule Engines`
|
|
62
11
|
- `Complex Runtime Templating` without JSX or virtual DOM
|
|
63
12
|
- `Single Page Applications`
|
|
@@ -65,23 +14,16 @@ It doesnt get more standard compliant than that.
|
|
|
65
14
|
- `Electron Apps`
|
|
66
15
|
- `Progressive Web Apps`
|
|
67
16
|
- `Complex Native Web Components`, that comprised of a set of modular `UI` and `business logic` micro components
|
|
68
|
-
|
|
17
|
+
|
|
18
|
+
- `server side` structure in general.
|
|
69
19
|
|
|
70
20
|
|
|
71
21
|
Funny stuff:
|
|
72
22
|
|
|
73
|
-
- `Vending Machine
|
|
74
|
-
-
|
|
75
|
-
- `UI for ocean going container ships`
|
|
23
|
+
- `Vending Machine Frontend` ( selling lottery tickets )
|
|
24
|
+
- `UI for ocean going container ships` ( a wave impact stress simulator frontend )
|
|
76
25
|
|
|
77
26
|
|
|
78
27
|
Not from me, but somehow based on my ideas:
|
|
79
28
|
|
|
80
|
-
- `SpaceX` uses web components as an interface in their `Dragon Capsule`. I
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
This list is far from complete, I used this as a core principle for 20 years. All of the above is modular, so you can use it together.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
**Whatever functionality you can do with Javascript, you can encapsule it in a micro component and reuse in any framework that allows for DOM access**.
|
|
29
|
+
- `SpaceX` uses web components as an interface in their `Dragon Capsule`. I regard myself to be a co-inventor of web components, since I announced my idea on ajaxian.com in 2007. Much later, [User defined built in elements](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#customized_built-in_elements) were a copy of what I already had back then. So in a way, this already goes to space.
|
package/assets/my-tag.css
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
my-tag {
|
|
1
|
+
my-tag > button {
|
|
2
2
|
border: 2px solid gray;
|
|
3
3
|
margin: 3px;
|
|
4
4
|
padding: 2px 5px;
|
|
5
5
|
display: inline-block;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
my-tag
|
|
8
|
+
my-tag.clicked > button {
|
|
9
|
+
border-color: blue;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
my-tag > button:hover {
|
|
9
13
|
border-color: red;
|
|
10
14
|
}
|
package/dist/MC.d.ts
CHANGED
|
@@ -5,12 +5,12 @@ export interface HTMLMcElement extends HTMLElement {
|
|
|
5
5
|
}
|
|
6
6
|
declare function addListener(domNode: Node, eventName: string, handler: EventListenerOrEventListenerObject | null, capture?: boolean, once?: boolean): void;
|
|
7
7
|
declare function removeListener(domNode: Node, eventName: string, handler: EventListenerOrEventListenerObject | null): void;
|
|
8
|
-
declare function trigger(target:
|
|
8
|
+
declare function trigger(target: HTMLElement, ev: McEvent | string, data?: any, bubble?: string): void;
|
|
9
9
|
declare class McBase {
|
|
10
10
|
#private;
|
|
11
11
|
constructor(target?: {
|
|
12
12
|
[key: string]: any;
|
|
13
|
-
});
|
|
13
|
+
}, debug?: boolean);
|
|
14
14
|
get target(): any;
|
|
15
15
|
}
|
|
16
16
|
declare class MC extends McBase {
|
|
@@ -25,8 +25,7 @@ declare class DC extends McBase {
|
|
|
25
25
|
_mc: {
|
|
26
26
|
[key: string]: any;
|
|
27
27
|
};
|
|
28
|
-
constructor(target: HTMLElement);
|
|
29
|
-
static debug: boolean;
|
|
28
|
+
constructor(target: HTMLElement, debug?: boolean);
|
|
30
29
|
static add: Function;
|
|
31
30
|
static remove: Function;
|
|
32
31
|
static trigger: Function;
|
package/dist/MC.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MC.d.ts","sourceRoot":"","sources":["../src/MC.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"MC.d.ts","sourceRoot":"","sources":["../src/MC.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAevC,MAAM,WAAW,aAAc,SAAQ,WAAW;IACjD,GAAG,EAAE,WAAW,CAAC;CACjB;AA8CD,iBAAS,WAAW,CACnB,OAAO,EAAE,IAAI,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kCAAkC,GAAG,IAAI,EAClD,OAAO,GAAE,OAAe,EACxB,IAAI,GAAE,OAAe,QAarB;AAED,iBAAS,cAAc,CACtB,OAAO,EAAE,IAAI,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kCAAkC,GAAG,IAAI,QAGlD;AAmDD,iBAAS,OAAO,CACf,MAAM,EAAE,WAAW,EACnB,EAAE,EAAE,OAAO,GAAG,MAAM,EACpB,IAAI,GAAE,GAAQ,EACd,MAAM,GAAE,MAAY,QAwBpB;AAiGD,cAAM,MAAM;;gBAGC,MAAM,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,KAAK,GAAE,OAAe;IAWnE,IAAI,MAAM,IAAI,GAAG,CAEhB;CACD;AAED,cAAM,EAAG,SAAQ,MAAM;IACtB,GAAG,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAM;gBAErB,MAAM,CAAC,EAAE,GAAG;IAIxB,MAAM,CAAC,OAAO,iBAAW;IAEzB,OAAO,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,IAAI,GAAE,GAAQ,EAAE,MAAM,GAAE,MAAY;CAmElE;AAED,cAAM,EAAG,SAAQ,MAAM;IACtB,GAAG,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAM;gBAErB,MAAM,EAAE,WAAW,EAAE,KAAK,GAAE,OAAe;IAIvD,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAO;IAC3B,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAU;IACjC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAW;IAEnC,OAAO,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,IAAI,GAAE,GAAQ,EAAE,MAAM,CAAC,EAAE,MAAM;IAI7D,MAAM,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;IAMlC,SAAS,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;IAMrC,QAAQ,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;IAYpC,WAAW,CAAC,MAAM,GAAE,MAAW,GAAG,GAAG,EAAE;CAMvC;AAED,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC"}
|