module Main exposing (..) {-| Inspired by an animation I saw once and a talk by Evan Czaplicki Styling of the checkbox is adapted from -} import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (onClick) type Model = None | One String | Two String String main : Program Never Model Msg main = Html.beginnerProgram { model = One "Quality" , view = view , update = update } view : Model -> Html Msg view model = div [ class "container" ] [ addCssStyles , h1 [] [ text "Choose wisely" ] , ul [] [ viewCheckbox "Quality" model , viewCheckbox "Fast" model , viewCheckbox "Cheap" model ] ] viewCheckbox : String -> Model -> Html Msg viewCheckbox which model = let id_ = "switch-" ++ which in li [ style [] ] [ input [ type_ "checkbox" , id id_ , checked <| isChecked which model , onClick <| Toggle which ] [] , label [ for id_ ] [ text which ] ] isChecked : String -> Model -> Bool isChecked which model = case model of None -> False One a -> a == which Two a b -> which == a || which == b type Msg = Toggle String update : Msg -> Model -> Model update msg model = case msg of Toggle str -> case model of None -> One str One a -> if a /= str then Two a str else None Two a b -> if str == a then One b else if str == b then One a else Two b str addCssStyles : Html msg addCssStyles = Html.node "style" [] [ text css ] css : String css = """/* injected css */ html { height: 100%; margin: 0; } body { height: 100%; margin: 0; display: flex; align-items: center; } .container { font-family: sans-serif; font-size: 8vmin; height: 8em; margin: auto; } h1 { font-size: 120%; margin-bottom: .5em; } ul { list-style-type: none; padding-left: 1em; margin-top: 0; } li { margin: .5em 0; } input[type="checkbox"] { display: none; } input[type="checkbox"] + label { display: block; position: relative; padding-left: 1.6em; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } input[type="checkbox"] + label:before { content: ''; display: block; width: 1em; height: 1em; border: .1em solid #000; position: absolute; left: 0; top: 0; opacity: .6; -webkit-transition: all .12s, border-color .08s; transition: all .12s, border-color .08s; } input[type="checkbox"]:checked + label:before { width: .5em; top: -.3em; left: .4em; border-radius: 0; border-width: .15em; opacity: 1; border-color: #199045; border-top-color: transparent; border-left-color: transparent; -webkit-transform: rotate(35deg); transform: rotate(35deg); border-radius: .1em; } """