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

Can't encapsulate styles easily #140

Open
ghost opened this issue Feb 1, 2018 · 3 comments
Open

Can't encapsulate styles easily #140

ghost opened this issue Feb 1, 2018 · 3 comments

Comments

@ghost
Copy link

ghost commented Feb 1, 2018

The elm architecture pattern is normally to create child components that know nothing about their parents, and let the parents decide how their children should inter-operate. For example, say there's a parent Nav with a child Contact. Contact would have its own message types, and views to go with it. In the Nav component, you would import Contact, and create a wrapper message for it:

type NavMsg
  = Contact ContactMsg
  | ...

And you would use Html.map, Cmd.map, etc to bring that component into the Nav. We are all familiar and comfortable with this pattern of encapsulation since it's the default pattern in Elm.

Stylesheets don't work this way. Sure, the APIs are all there, leading you to believe it works this way but it just doesn't. At least, not as far as I can see. Using Element.mapAll to change style types ensures that the styles you defined will never be used because after you map the element, you can only use the parent's stylesheet in Element.layout and Element.viewport.

@lsunsi
Copy link

lsunsi commented Apr 1, 2018

I just started learning this library and to be honest I thought I was missing something. It seems counter intuitive that I have to define all styles globally and feels really reminiscent of CSS classes, much more than I would like. styled-components made me think in terms of component and as much as I really like the ambition behind style-elements, I can't seem to get my head around the style patterns.

@adam-becker Does something like this work so we can declare all styles locally and merge together on a root stylesheet?

@ghost
Copy link
Author

ghost commented Apr 1, 2018

@lsunsi that looks like it might do the trick. I wouldn't invest too heavily into this pattern though, since I believe 5.0.0 will handle styles much differently. I believe the idea is to use inline styles for everything, and creating functions for specific reusable elements.

buttonPrimary msg str =
  let style =
    [ Border.rounded 6
    , Color.background blue
    , Color.text white
    ]
  in
    button
      [ onClick msg, inlineStyle style, padding 3 ]
      ( text str )

I like this idea more, and I've converted most of my code to use this approach with an empty style sheet to satisfy the viewport function. All of the code for rendering a specific type of button is encapsulated and in one spot, while also allowing the styles to be shared and mixed however you'd like by using basic List operations.

This method also keeps the wall between Style and Layout in place, so it's still a step above a basic Html and Css approach.

@lsunsi
Copy link

lsunsi commented Apr 1, 2018

@adam-becker Yeah, that makes perfect sense to be honest. Also, this is perfectly inline with styled-components-like approach, right? Or class-less, if you will haha.

Can you think of any disadvantages on following this approach? I just started a large project and I'm still on a position to change my codebase, so I'm very inclined to.

Further, doesn't inlineStyle take a list of string tuples as parameter? :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant