-
Notifications
You must be signed in to change notification settings - Fork 20
Description
Context:
What we have now is pretty good, thanks to Laminar's influence. But I feel now that it is wrong, and we can do better. This should also open doors to better support web components and stuff.
Basically, I believe we need only two types: tags and attributes.
Tags should be similar to our existing encoding. Something like this:
class Tag[F[_], E](name: String):
def apply[M](modifiers: M)(using shapeless magic): Resource[F, E]
Then, for attributes, we should have something like this:
class Attribute[F[_], A]:
def :=[E, V](value: V)(using Setter[F, E, A, V]): Modifier[F, E, Setter]
def <--[E, V](value: Signal[F, V])(using Setter[F, E, A, V]): Modifier[F, E, SignalSetter]
def -->[E, Ev](listener: Pipe[F, Ev, Nothing])(using Emits[F, E, Ev]): Modifier[F, E, Listener]
What is Setter[F, E, A, V]
? It is evidence, that you are allowed to set a value of type V
to an attribute A
on an element E
. It will also provide the implementation for how to do this, since it depends.
Similarly, Emits[F, E, Ev]
is evidence that element E
emits events of type Ev
.
This enables some interesting things:
- Attributes
A
can be used only with the specific elementE
that actually support them. - In fact, an attribute
A
may have a different implementation or even a different type depending on the elementE
it is modifying. - Anyone can implement custom tags (e.g. in a web component library) that support certain attributes, simply by implementing these typeclasses.
If this works and type inference is ergonomic, then this should be a completely source-compatible change, hidden from users.