Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helper to set multiple keys (props / attrs / event props) at the same time #146

Open
raquo opened this issue Dec 18, 2023 · 1 comment
Open
Labels
ergonomics need to find time https://falseknees.com/297.html

Comments

@raquo
Copy link
Owner

raquo commented Dec 18, 2023

Sometimes people want an easier way to set multiple props from the same signal, like this:

      svg.line(
          svg.x1 <-- signal.map(_.x1),
          svg.y1 <-- signal.map(_.y1),
          svg.x2 <-- signal.map(_.x2),
          svg.y2 <-- signal.map(_.y2),
      )

Currently the easiest way to abstract over this is something like:

def coordsFromRect(signal: Signal[Rect]) = List(
  svg.x1 <-- signal.map(_.x1),
  svg.y1 <-- signal.map(_.y1),
  svg.x2 <-- signal.map(_.x2),
  svg.y2 <-- signal.map(_.y2)
)
svg.line(
  coordsFromRect(signal)
)

But that only helps if you need to do this a lot for the same data type / props.


We could potentially have some convenience methods for this, for example something like this:

svg.line(
  multiKey(svg.x1, svg.y1, svg.x2, svg.y2) <-- signal.map(v => (v.x1, v.y1, v.x2, v.y2))
)

I feel like I've seen a multi-setter like this somewhere (Laminext perhaps?) but can't find it right now.

One complication is that such an API should support mixing different kinds of keys (attrs, props, style props). Style props accept V | String, not just V, unlike other types of props, so would need special handling.

Ideally we would design an API that keeps a localized "map" of keys and values (e.g. (svg.x1 -> v.x1, ...), instead of splitting them into two separate "parallel arrays" like in the syntax above, because that way it's too easy to accidentally send the value to the wrong prop.

At the same time, such a map-based API would need to prevent the changes in the list of properties to keep things simple and avoid dealing with issues similar to #89. So, we could do something like:

svg.line(
  multiKey(signal)(
    svg.x1 <-- _.x1,
    svg.y1 <-- _.y1,
    svg.x2 <-- _.x2,
    svg.y2 <-- _.y2
  )
)

And we would need N variations of that method for different arities. But at least it easily takes care of style props.

Not sure I like this exact syntax, but it does work technically, and I do want some arrows in it to indicate reactive bindings.

Lastly, I guess another approach is some kind of derivation, but I think I'd rather not have such magic in the core library, and I from my understanding, it wouldn't actually work very well in this case as the DOM props are relatively loosely typed.

@raquo raquo added need to find time https://falseknees.com/297.html ergonomics labels Dec 18, 2023
@raquo
Copy link
Owner Author

raquo commented Aug 22, 2024

Consider similar syntax for writing to multiple observers, e.g.

multiObserve(chosenFileSignal)(
  _._1 --> CompilePage.knownFileName,
  _._2 --> CompilePage.fileContents
)

Unlike other Observer.combine / contraObserve options, this does not need type ascriptions, which is nice.

Discussion on discord

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ergonomics need to find time https://falseknees.com/297.html
Projects
None yet
Development

No branches or pull requests

1 participant