mdgriffith / style-elements

Create styles that don't mysteriously break!
http://package.elm-lang.org/packages/mdgriffith/style-elements/latest
BSD 3-Clause "New" or "Revised" License
445 stars 49 forks source link

Style-elements doesn't play nice with Font Awesome icons in SVG+JS mode #147

Closed Steve-OH closed 6 years ago

Steve-OH commented 6 years ago

The big picture of what I'm trying to do

I'm trying to use Font Awesome icons in the "new and improved" SVG+JS mode, rather than the old-fashioned CSS mode.

What I did

I could not get the code to work from within Ellie, so here it is:

(Main.elm)

module Main exposing (..)

import Color
import Element exposing (..)
import Element.Events exposing (onClick)
import Element.Attributes exposing (..)
import Html exposing (..)
import Html.Attributes as HA
import Style exposing (..)
import Style.Border as Border
import Style.Color as Color
import Style.Font as Font

type Styles
    = None
    | Page
    | Button

iCheckTrue : Element style variation msg
iCheckTrue =
    Html.span [ HA.class "far fa-check-square" ] []
        |> Element.html

iCheckFalse : Element style variation msg
iCheckFalse =
    Html.span [ HA.class "far fa-square" ] []
        |> Element.html

embed : Bool -> Element style variation msg
embed flag =
    if flag then
        iCheckTrue
    else
        iCheckFalse

stylesheet : StyleSheet Styles variation
stylesheet =
    Style.styleSheet
        [ style None []
        , style Page
            [ Color.text Color.darkCharcoal
            , Color.background Color.white
            , Font.typeface
                [ Font.font "helvetica"
                , Font.font "arial"
                , Font.font "sans-serif"
                ]
            , Font.size 16
            , Font.lineHeight 1.3
            ]
        , style Button
            [ Border.rounded 5
            , Border.all 1
            , Border.solid
            , Color.border Color.blue
            , Color.background Color.lightBlue
            ]
        ]

main =
    Html.program
        { init =
            ( { state = False
              }
            , Cmd.none
            )
        , update = update
        , view = view
        , subscriptions = \_ -> Sub.none
        }

type Msg
    = Toggle

update msg model =
    case msg of
        Toggle ->
            ( { model | state = not model.state }, Cmd.none )

view model =
    Element.layout stylesheet <|
        el None [ center, width (px 150) ] <|
            column Page
                [ spacing 20, padding 20 ]
                [ (embed model.state)
                , Element.button Button [ onClick Toggle ] (Element.text "Toggle")
                ]

(index.html)

<!DOCTYPE html>
<html lang="en-us">
  <head>
<!--<link href="https://use.fontawesome.com/releases/v5.0.7/css/all.css" rel="stylesheet">-->
    <script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
  </head>
  <body>
    <div id="main"></div>
  </body>
</html>

To see the problem, click the button.

What I Expected To Happen

When the button is clicked, the displayed icon should switch between "checked" and "unchecked" forms.

What Actually Happened

Style elements raises an Uncaught TypeError, because it is apparently trying to set the className property on an SVG element, which doesn't have a settable className property.

The workaround is to go back to old-fashioned CSS mode (see the commented-out line in the HTML), which works fine.

Versions

aaronkor commented 6 years ago

@Steve-OH have you tried using HA.classList instead of HA.class?

Here is my generic implementation for showing fa icons:

fa : String -> Element style variation msg
fa faClasses =
    Element.html <|
        Html.i
            [ Html.Attributes.classList <|
                List.map (\s -> ( s, True )) <|
                    String.split " " faClasses
            ]
            []

and use it by:

fa "far fa-check-square"
Steve-OH commented 6 years ago

@aaronkor

Thanks for the idea; I'll give it a try when I get a chance.

I just discovered the other day that this issue is present in plain ol' Elm as well, so it's not specific to style-elements. Therefore, I'm going to close this one and open one on Elm.