Closed tesk9 closed 2 years ago
@Confidenceman02 - any other ideas besides the class
approach in https://github.com/rtfeldman/elm-css/pull/562?
@Arkham and I noticed that :
Html.Styled.Attributes.class
currently uses property
to set the "className".
If manually use Html.Styled.Attributes.attribute "class"
instead, the class is correctly included in the rendered code: https://ellie-app.com/gnJc3ttWvnga1
Should we change the class
implementation to use an attribute instead?
Worth a try! It might break other things, but at this point it seems to be down to finding these things the hard way. 😅
I started working on a PR to implement this, and found another problem when I went to add tests to Styled.elm
bug564 : Test
bug564 =
describe "Github Issue #564: https://github.com/rtfeldman/elm-css/issues/564"
[ Test.test "generated class is included when there's no custom class" <|
\_ ->
div
[ css [ color (rgb 0 0 0) ]
]
[]
|> toUnstyled
|> Query.fromHtml
|> Query.has [ Selector.class "_5dc67897" ]
, Test.test "custom class is included when there's no generated class" <|
\_ ->
div [ class "some-custom-class" ]
[]
|> toUnstyled
|> Query.fromHtml
|> Query.has [ Selector.class "some-custom-class" ]
, Test.test "custom class is included as well as generated class" <|
\_ ->
div
[ css [ color (rgb 0 0 0) ]
, class "some-custom-class"
]
[]
|> toUnstyled
|> Query.fromHtml
|> Query.has [ Selector.classes [ "_5dc67897", "some-custom-class" ] ]
]
Before I made any other changes, I expected only the test "custom class is included as well as generated class" to fail. However, "generated class is included when there's no custom class" also fails!
I believe that elm-explorations/test
only supports testing properties, not attributes.
I made a quick test module with elm/html
demonstrating the behavior:
module Example exposing (..)
import Html exposing (..)
import Html.Attributes exposing (attribute, class, property)
import Json.Encode
import Test exposing (..)
import Test.Html.Query as Query
import Test.Html.Selector as Selector
suite : Test
suite =
describe "class attribute assertions"
[ describe "Using Html.Attribute.class" <|
classAssertions <|
div [ class "some-custom-class" ] []
, describe "Using Html.Attribute.property" <|
classAssertions <|
div [ property "className" (Json.Encode.string "some-custom-class") ] []
, describe "Using Html.Attribute.attribute" <|
classAssertions <|
div [ attribute "class" "some-custom-class" ] []
]
classAssertions : Html msg -> List Test
classAssertions html =
[ test "Test.Html.Selector.class finds the class" <|
\_ ->
html
|> Query.fromHtml
|> Query.has [ Selector.class "some-custom-class" ]
, test "Test.Html.Selector.classes finds the class" <|
\_ ->
html
|> Query.fromHtml
|> Query.has [ Selector.classes [ "some-custom-class" ] ]
, test "Test.Html.Selector.exactClassName finds the class" <|
\_ ->
html
|> Query.fromHtml
|> Query.has [ Selector.exactClassName "some-custom-class" ]
]
With these tests, these are my results:
Running 9 tests. To reproduce these results, run: elm-test --fuzz 100 --seed 267504658862962
↓ Example
↓ class attribute assertions
↓ Using Html.Attribute.attribute
✗ Test.Html.Selector.class finds the class
▼ Query.fromHtml
<div class="some-custom-class">
</div>
▼ Query.has [ class "some-custom-class" ]
✗ has class "some-custom-class"
↓ Example
↓ class attribute assertions
↓ Using Html.Attribute.attribute
✗ Test.Html.Selector.classes finds the class
▼ Query.fromHtml
<div class="some-custom-class">
</div>
▼ Query.has [ classes "some-custom-class" ]
✗ has classes "some-custom-class"
↓ Example
↓ class attribute assertions
↓ Using Html.Attribute.attribute
✗ Test.Html.Selector.exactClassName finds the class
▼ Query.fromHtml
<div class="some-custom-class">
</div>
▼ Query.has [ attribute "className" "some-custom-class" ]
✗ has attribute "className" "some-custom-class"
TEST RUN FAILED
Duration: 121 ms
Passed: 6
Failed: 3
All of which is a long-winded way of saying: changing property -> attribute for class
in elm-css will mean that class assertions using elm-explorations/test will no longer work.
Previously property was being used VirtualDom.property "className" ...
I wonder what would happen if we just changed "className"
to "class"
?
Nope that doesn't work :cry:
Just throwing an idea out there.
Considering the trouble makers are svg elements, we could just give NodeNS
and KeyedNodeNS
type a different function rather than calling extractUnstyledAttribute
. Just call it extractUnstyledAttributeNS
then use the attribute property instead.
The VirtualDom has seperate types for svg's so it might make sense to handle updating classes seperately as well.
extractUnstyledAttributeNS: Dict CssTemplate Classname -> Attribute msg -> VirtualDom.Attribute msg
extractUnstyledAttributeNS styles (Attribute val isCssStyles cssTemplate) =
if isCssStyles then
case Dict.get cssTemplate styles of
Just classname ->
VirtualDom.attribute "class" classname
Nothing ->
VirtualDom.attribute "class" "_unstyled"
This way we can revert the original function to what it was and just handle the special svg case. elm-test will work for regular html elements as it used to using this fix.
Just tested and yep it works! PR good to go.
Appreciate your work! I encountered this issue today when upgrading elm-css - classnames for some custom styling / custom element behavior is missing.
Going to patch elm-test to make this work there as well. Not sure if elm-explorations projects accept PR's from non official elm peeps so will see what happens. Looks like not much has happened in that project for a while 🤷
I'd be happy to accept a PR for it on elm-explorations/test
too! 👍
@rtfeldman That's wonderful thank you! I'll give it a shot! 😄
@rtfeldman did we get a release from this?
Now it is! 17.0.5
cc @tesk9 😄
(Example available at https://ellie-app.com/gnGZhWfMXcMa1.)
When there's just
css
, the styles work as expected:And the generated class name is attached to the element:
However, when a
class
attribute is also added,The generated class name is not attached to the element:
Which results in the styles not being applied.