diff --git a/readme.md b/readme.md
index bad654f..15b4957 100644
--- a/readme.md
+++ b/readme.md
@@ -2,6 +2,23 @@
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
+
+
+
+```
+
## Concept
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 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
-when the controller is removed again. This promise has an additional property
-`"signal"` which returns an `AbortSignal`. This means the promise can be passed
-directly as the third argument to `addEventListener` function calls.
+to the element when the controller is removed again. This promise has an
+additional property `"signal"` which returns an `AbortSignal`. This means the
+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
object similar to a `DomTokenList` for easier management of the controller list.
The `controller` attribute is a space-separated list of controller names as
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.