Skip to content

Instantly share code, notes, and snippets.

@luizpvas
Created June 14, 2019 11:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luizpvas/197c4570b400e9cfe1fdd8dc79c1e1fa to your computer and use it in GitHub Desktop.
Save luizpvas/197c4570b400e9cfe1fdd8dc79c1e1fa to your computer and use it in GitHub Desktop.
<h1 class="text-xl mb-4">Example app for the Color picker component</h1>
<div class="p-4 border">
<div id="colorpicker" data-color="#e25712"></div>
</div>
import "phoenix_html";
import "../css/app.css";
import { Elm } from "../elm/Colorpicker.elm";
window.addEventListener("load", ev => {
let colorpicker = document.querySelector("#colorpicker");
if (colorpicker) {
Elm.Colorpicker.init({
node: colorpicker,
flags: {
color: colorpicker.getAttribute('data-color')
}
});
}
});
module Colorpicker exposing (main)
-- The Browser module has the definition we need to run an Elm application in the
-- Elm architecture.
-- Html is the module that defines the functions `div`, `span`, `button`, etc.
-- Html.Attributes exposes functions for element attributes such as `class` and `id`.
-- Html.Events exposes functions for binding elements such as `onClick` and `onInput`.
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
{-| We call `Browser.element` with a record passing our definitions of the functions.
The Elm runtime is responsible for calling each of those functions in the
appropriate moment.
-}
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
{-| Subscriptions are used to listen for external events, such as websockets
and mouse drag events. We're not using in this component, so we can just
return `Sub.none`.
-}
subscriptions model =
Sub.none
{-| Constant of possible colors users can choose from.
-}
colors : List String
colors =
[ "#4286f4", "#41f441", "#dfe212", "#e25712", "#e21212" ]
{-| Our model definition, described earlier.
-}
type alias Model =
{ selectedColor : String
}
{-| Initialization argument passed in `Elm.Colorpicker.init`.
-}
type alias Flags =
{ color : String
}
{-| The init function is called on load. We're not receiving any arguments (called flags)
right now, but we'll need them in a second.
-}
init : Flags -> ( Model, Cmd Msg )
init flags =
( { selectedColor = flags.color }, Cmd.none )
{-| List of actions users can perform in this component
-}
type Msg
= ColorSelected String
| SelectionCleared
{-| The `update` function changes the model based on the received `Msg`. To be strict about
terms, nothing is being mutated, we're just returning a changed version of the model.
-}
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
ColorSelected hash ->
( { model | selectedColor = hash }, Cmd.none )
SelectionCleared ->
( { model | selectedColor = "" }, Cmd.none )
{-| The `view` function receives the model and produces HTML. The Elm runtime is responsible
for all dom diffing and optimizations.
-}
view : Model -> Html Msg
view model =
div [ id "colorpicker" ]
[ span []
[ label [ class "font-bold" ] [ text "Choose a color" ]
, viewClearSelection model
]
, div [ class "flex items-center" ] (List.map (\hex -> viewColor (model.selectedColor == hex) hex) colors)
, input [ type_ "hidden", name "color", value model.selectedColor ] []
]
viewClearSelection : Model -> Html Msg
viewClearSelection { selectedColor } =
if selectedColor == "" then
text ""
else
span [ onClick SelectionCleared, class "text-sm ml-1 italic cursor-pointer" ] [ text "— Clear selection" ]
viewColor : Bool -> String -> Html Msg
viewColor isSelected hex =
let
className =
if isSelected then
"w-8 h-8 m-1 rounded shadow"
else
"w-6 h-6 m-1 rounded"
in
div
[ onClick (ColorSelected hex)
, class className
, style "background" hex
]
[]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment