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

Special CSS className handling #22

Closed
raquo opened this issue Jun 10, 2018 · 1 comment
Closed

Special CSS className handling #22

raquo opened this issue Jun 10, 2018 · 1 comment
Milestone

Comments

@raquo
Copy link
Owner

raquo commented Jun 10, 2018

In #20 @pishen raised the issue with CSS class name handling being inconvenient in Laminar. I didn't quite appreciate the full extent of the problem initially, but now I think it really should be addressed.

Laminar treats className like any other attribute, but unlike other attributes it's a composite value – a list of values to be precise

Consider this component:

object TextInput {

  def apply(mods: Mod[Input]*): Input = {
    input(
      typ("text"),
      cls("TextInput"),
      mods
    )
  }
}

There is no easy way to add a css class to a single instance of that component without polluting either this component's API or the call site.

The solution I propose is for each ReactiveElement to keep track of css class names that various modifiers want to keep on it in a Map[String, Boolean].

Then the modifier classes("TextInput") would add a ("TextInput" -> true) to that map, and this CSS class will stay with this element unless someone adds a classes.remove("TextInput") modifier that would set ("TextInput" -> false). classes.set("TextInput") would behave like cls("TextInput") does today, clearing the map and setting its own value.

We'd also need something like classes.toggle and/or classes.map which could be used reactively with Observable[Boolean] or Observable[Map[String, Boolean]].


Unfortunately it would be undesirably easy to override class names with the existing cls and className modifiers which we get from Scala DOM Types. Maybe we should extract those into a separate trait in Scala DOM Types so that consuming libraries like Laminar can choose to implement a different way to deal with CSS classes.

@fdietze
Copy link

fdietze commented Jun 11, 2018

The same is implemented in Outwatch: outwatch/outwatch#118

@raquo raquo added this to the v0.4 milestone Jun 15, 2018
@raquo raquo closed this as completed in 277b884 Sep 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants