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

Support style attribute #1345

Closed
bcardarella opened this issue May 4, 2024 · 12 comments
Closed

Support style attribute #1345

bcardarella opened this issue May 4, 2024 · 12 comments
Assignees
Milestone

Comments

@bcardarella
Copy link
Collaborator

bcardarella commented May 4, 2024

I think we should pull the trigger on this as a blocker for v0.3

My changes to the UtilityStyles gave people the ability to write class names that are effectively syntax parity with the actual modifiers. This is looking odd now as it appears to be rules written as class names.

I'd like to move this format for the UtilityStyles over to a style attribute:

<Text style={[
"font(.title)",
~S(foobar(a: "SomeString"))
]}>Hello, world!</Text>

I'm going to make the changes in the Elixir code. The above template should output as:

<Text style="font(.title); foobar(a: &quot;SomeString&quot;);">Hello, world!</Text>

The HTML entities should be decoded first then the string is split on ; instead of whitespace.

The stylesheet will be identical. The key value will be the pre-decoded version and the value will be post-decoded so the above would result in the following stylesheet:

%{
  "font(.title)" => [{:font, [], [{:., [], [nil, :title]}]],
  "foobar(a: &quot;SomeString&quot;)" => [{:foobar, [], [a: "SomeString"]}]
}

This would require the client to collect class names from both class and style attr. Similar to HTML the modifiers from style have a higher precdence than the ones from class.

As an example, the folllowing HTML:

<style>
.blue {
  color: blue
}
</style>

<div class="blue" style="color: red">Hello, world!</div>

this will result in a red color as style will be applied after the styles from class. However modifier application precedence is done we should ensure that this behavior is similar.

Edge cases

Any trailing ; should be collapsed:

styles = "a; b; c;"
assert parse_styles(styles) == ["a", "b", "c"]

styles = "a;b;c"
assert parse_styles(styles) == ["a", "b", "c"]

styles = "a;b;c;;;;;;;;;;"
assert parse_styles(styles) == ["a", "b", "c"]
@bcardarella
Copy link
Collaborator Author

@BrooklinJazz take note ☝️ this affects the tutorial if you're using this style of class name. You will be able to just change class to style though to quickly fix once this is available

@bcardarella
Copy link
Collaborator Author

As far as implementation goes for the Elixir side, I will likely remove the changes I made to the UtilityStyle module and rely on the existing rules parser.

What I'm not sure about is if we should add support for ; within the rules parser or not. I can easily just split and treat each individually when compiling the template. While adding ; to the parser does align it more closely to CSS I question what we benefit from that other than just ceremonial.

@bcardarella
Copy link
Collaborator Author

bcardarella commented May 4, 2024

As far as why "style" over "modifiers"

  1. "style" is more concise
  2. "style" can be platform agnostic, so we can use a similar approach in WinUI3 or Jetpack without having to worry about platform-relevant attribute names
  3. it aligns with our naming for our stylesheets

@bcardarella
Copy link
Collaborator Author

The other benefit is I believe this will put people on the better path towards wanting a styling framework in the future. Supporting inline-styles along with the escape hatch of supporting class names for styling with multiple modifiers is familiar for those coming from web and I think this will result in less WTFs.

@BrooklinJazz
Copy link
Contributor

BrooklinJazz commented May 4, 2024

As far as implementation goes for the Elixir side, I will likely remove the changes I made to the UtilityStyle module and rely on the existing rules parser.

What I'm not sure about is if we should add support for ; within the rules parser or not. I can easily just split and treat each individually when compiling the template. While adding ; to the parser does align it more closely to CSS I question what we benefit from that other than just ceremonial.

What about supporting .?

.modifier()
.otherModifier()

That way writing modifiers is nearly 1-1. It probably won't be as easy as a split on colon but should be do-able.

It could also mean we can solve the whitespace problem. It'd be nice to be able to do stuff like this:

.modifier(param: 10, param: 10)

@bcardarella
Copy link
Collaborator Author

bcardarella commented May 4, 2024

I've debated that, it more of less turns it into a pure parser at that point. My only reason, as you surmised, for not doing so is that splitting between the rules requires more than a simple split and you have to start tokenizing the string to find where the outer-most .s are for splitting

@bcardarella
Copy link
Collaborator Author

Part 1/2 liveview-native/live_view_native#179

@NduatiK
Copy link
Contributor

NduatiK commented May 8, 2024

Why do we bother with HTML encoding? (Why is " turned into &quot;?)

@bcardarella
Copy link
Collaborator Author

@NduatiK on native devices we're using html parsers and they don't like seeing " even when escaped

@bcardarella
Copy link
Collaborator Author

FWIW I am not a fan of having to use &quot; but I don't have another solution at the moment

@NduatiK
Copy link
Contributor

NduatiK commented May 8, 2024

That's a good point, I forgot about the HTML bits

@bcardarella
Copy link
Collaborator Author

This is complete

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

4 participants