armanbilge/calico

Allow Elm-like dsl with an implicit topic in scope

hejfelix opened this issue · 2 comments

Specifying the pipe for events is very powerful, but probably not necessary in the majority of cases.

button("-", onClick.as(Event.Decrement) --> outgoing.publish)

Where outgoing is a Topic[F, Event]. It would be nice if we could allow to skip that part to simply write:

button("-", onClick.as(Event.Decrement))

When we have an implicit Topic[F, Event] in scope. I realize this could become messy, so it could be provided as an opt-in or alternative syntax for the DSL

Firstly, if you are looking for an Elm-like experience, I strongly recommend you look at Tyrian :)

https://github.com/PurpleKingdomGames/tyrian


Otherwise, this sort of feature feels out-of-scope for Calico. However, I would be very supportive of a external library/framework that builds on Calico and offers this (and other Elm-like facilities).

To support this, all you need to do is put a custom Modifier[F, Node[F], EventProp[F, E]] into scope.

trait Modifier[F[_], E, A]:
outer =>
def modify(a: A, e: E): Resource[F, Unit]
inline final def contramap[B](inline f: B => A): Modifier[F, E, B] =
(b: B, e: E) => outer.modify(f(b), e)

Something like this:

given [F[_], N, E](
  using sink: Topic[F, E]
): Modifier[F, N <: fs2.dom.Node[F], EventProp[F, E]] with
  def modify(prop: EventProp[F, E], node: N): Resource[F, Unit] =
    forPipeEventProp.modify(prop --> sink.publish, node)

Yeah I agree this might sit on the next level of abstraction or in the user's own code.