Add more examples to readme
This commit is contained in:
parent
bfb9b560ca
commit
ff0f7a96a7
1 changed files with 70 additions and 3 deletions
73
readme.md
73
readme.md
|
@ -2,6 +2,23 @@
|
||||||
|
|
||||||
A prototype for an alternative to custom elements.
|
A prototype for an alternative to custom elements.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// example.js
|
||||||
|
import controllers from "controller-registry"
|
||||||
|
|
||||||
|
controllers.define("clickable", (element, detached) => {
|
||||||
|
element.addEventListener("click", () => {
|
||||||
|
alert("The element has been clicked!")
|
||||||
|
}, detached)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script type="module" src="example.js"></script>
|
||||||
|
|
||||||
|
<button controller="clickable">Try clicking this button</button>
|
||||||
|
```
|
||||||
|
|
||||||
## Concept
|
## Concept
|
||||||
|
|
||||||
Similar to a custom element, a controller defines custom behaviours for HTML
|
Similar to a custom element, a controller defines custom behaviours for HTML
|
||||||
|
@ -26,13 +43,63 @@ Controllers can be registered under any name as either a callback which gets
|
||||||
called when the controller is added to an element or a constructor which gets
|
called when the controller is added to an element or a constructor which gets
|
||||||
called with `new` and passed a revokable proxy to the element.
|
called with `new` and passed a revokable proxy to the element.
|
||||||
|
|
||||||
|
```js
|
||||||
|
controllers.define("showcase", class ShowcaseController {
|
||||||
|
constructor(element, detached) {
|
||||||
|
this.method(element)
|
||||||
|
// detached promise is passed here too for convenience,
|
||||||
|
// but the `detached` method is the preferred place
|
||||||
|
// to put cleanup code.
|
||||||
|
}
|
||||||
|
|
||||||
|
method(element) {
|
||||||
|
console.log("Calling method on:", element)
|
||||||
|
}
|
||||||
|
|
||||||
|
detached(element) {
|
||||||
|
// Cleanup if necessary
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that only class controllers are given a revocable proxy: this is because
|
||||||
|
their stateful nature and suitability for more complex handling makes them more
|
||||||
|
likely candidates to retain references to the target past their detachment.
|
||||||
|
|
||||||
|
For complex function controllers, this can easily be done manually using
|
||||||
|
`Proxy.revocable(element, {})`.
|
||||||
|
|
||||||
|
This behaviour might change in the future.
|
||||||
|
|
||||||
If the controller is a function, the second argument is a promise that resolves
|
If the controller is a function, the second argument is a promise that resolves
|
||||||
when the controller is removed again. This promise has an additional property
|
to the element when the controller is removed again. This promise has an
|
||||||
`"signal"` which returns an `AbortSignal`. This means the promise can be passed
|
additional property `"signal"` which returns an `AbortSignal`. This means the
|
||||||
directly as the third argument to `addEventListener` function calls.
|
promise can be passed directly as the third argument to `addEventListener`
|
||||||
|
function calls.
|
||||||
|
|
||||||
|
```js
|
||||||
|
controllers.define("showcase", async (element, detached) => {
|
||||||
|
console.log("Attached to element:", element)
|
||||||
|
console.log("Detached promise:", detached)
|
||||||
|
console.log("Detached signal:", detached.signal)
|
||||||
|
element === await detached
|
||||||
|
console.log("Detached from element:", element)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
The registry also exposes a `list` function which, given an element, returns an
|
The registry also exposes a `list` function which, given an element, returns an
|
||||||
object similar to a `DomTokenList` for easier management of the controller list.
|
object similar to a `DomTokenList` for easier management of the controller list.
|
||||||
|
|
||||||
The `controller` attribute is a space-separated list of controller names as
|
The `controller` attribute is a space-separated list of controller names as
|
||||||
registered in the registry.
|
registered in the registry.
|
||||||
|
|
||||||
|
## Interactions between controllers
|
||||||
|
|
||||||
|
There is no direct way for controllers to interact with each other, as they
|
||||||
|
should be mostly independent.
|
||||||
|
|
||||||
|
When signalling is needed, events are the way to go; when data needs to be
|
||||||
|
shared, the element's `dataset` or a more semantic attribute should be used.
|
||||||
|
|
||||||
|
For anything even more complex, a custom element or a higher level component
|
||||||
|
framework might be the better solution.
|
||||||
|
|
Loading…
Reference in a new issue