A select component written in Elm 0.19
elm install mercurymedia/elm-smart-select
This package exposes four modules SingleSelect, SingleSelectRemote, MultiSelect, MultiSelectRemote and SmartSelect.Settings. The Single pickers can be used to pick a single element while the Multi pickers are used to select a list of elements. The pickers without a suffix select from preloaded data whereas the Remote pickers query a remote source. To keep things simple, the documentation here focuses on the SingleSelect. Note: While the basic architecture across all of the modules is similar, certain functions may expect different arguments from one module to the next. Please refer to the specific module documentation for further details and information.
There are 6 steps to configure a SmartSelect:
Settings and add it to your model providing your local Msg type and the datatype of the data to be selected.import SingleSelect
import SmartSelect.Settings exposing (defaultSettings)
type alias Product =
{ id : Int
, name : String
, price : String
}
type alias Model =
{ products : List Product
, select : SingleSelect.SmartSelect Msg Product
, selectedProduct : Maybe Product
}Msgs: one to handle updates internal to the select and one to handle receiving a selection from the select.type Msg
= HandleSelectUpdate (SingleSelect.Msg Product)
| HandleSelection ( Product, SingleSelect.Msg )init function of a particular module takes.init : ( Model, Cmd Msg )
init =
( { products = products
, select = SingleSelect.init
{ selectionMsg = HandleSelection
, internalMsg = HandleSelectUpdate
, idPrefix = "my-prefix"
}
, selectedProduct = Nothing
}
)
products : List Product
products =
[ { id = 1
, name = "product 1"
, price = "$3.00"
}
, { id = 2
, name = "product 2"
, price = "$5.00"
}
...
]SingleSelect.view.Each module exposes a .view and .viewCustom function. .view takes only the arguments it needs while providing reasonable defaults for other view related settings. .viewCustom expects all of the fields that can be customized to be provided as arguments. Please refer to the module documentation for more details.
view : Model -> Html Msg
view model =
div []
[ ...
, div
[ style "width" "500px" ]
[ SingleSelect.view
{ selected = model.selectedProduct
, options = model.products
, optionLabelFn = .name
, settings = defaultSettings
}
model.select
]
]Msgs we defined in step 2.update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
...
HandleSelectUpdate sMsg ->
let
( updatedSelect, selectCmd ) =
SingleSelect.update sMsg model.select
in
( { model | select = updatedSelect }, selectCmd )
HandleSelection ( product, sMsg ) ->
let
( updatedSelect, selectCmd ) =
SingleSelect.update sMsg model.select
in
( { model | selectedProduct = product, select = updatedSelect }, selectCmd )SingleSelect.update returns an updated smart select instance and a cmd.
subscriptions : Model -> Sub Msg
subscriptions model =
SingleSelect.subscriptions model.selectExamples can be found in the examples folder. To view the examples run npm install and npm start. Open your browser at localhost:1234.
The CSS for the date picker is now defined in a built-in way using elm-css. There are some design tokens that can be configured individually in a theme. In case you need to add additional styling, you can use the CSS-classes that are attached to all the components.
In case you'd like to use the Theme, you can pass your custom theme to the Settings. The Theme record currently looks like this:
type alias Theme =
{ fontSize :
{ base : Css.Px
, sm : Css.Px
, xs : Css.Px
, xxs : Css.Px
}
, color :
{ text :
{ primary : Css.Color
, secondary : Css.Color
, disabled : Css.Color
}
, primary :
{ main : Css.Color
, contrastText : Css.Color
, light : Css.Color
}
, error :
{ main : Css.Color
, contrastText : Css.Color
, light : Css.Color
}
, background :
{ input : Css.Color
, optionsContainer : Css.Color
}
, action : { hover : Css.Color }
, border : Css.Color
}
, size :
{ iconButton : Css.Px
, inputElement : Css.Px
}
, borderWidth : Css.Px
, borderRadius :
{ base : Css.Px
, lg : Css.Px
}
, boxShadow :
{ offsetX : Css.Px
, offsetY : Css.Px
, blurRadius : Css.Px
, spreadRadius : Css.Px
, color : Css.Color
}
, transition : { duration : Float }
}Passing a customized theme to the settings works like this:
import Css -- from elm-css
import DatePicker.Settings
exposing
( Settings
, Theme
, defaultSettings
, defaultTheme
)
-- [...]
customTheme : Theme
customTheme =
{ defaultTheme
| color =
{ text =
{ primary = Css.hex "22292f"
, secondary = Css.rgba 0 0 0 0.5
, disabled = Css.rgba 0 0 0 0.25
}
, primary =
{ main = Css.hex "3490dc"
, contrastText = Css.hex "ffffff"
, light = Css.rgba 52 144 220 0.1
}
, error =
{ main = Css.hex "c53030"
, contrastText = Css.hex "ffffff"
, light = Css.hex "feb2b2"
}
, background =
{ input = Css.hex "ffffff"
, optionsContainer = Css.hex "ffffff"
}
, action = { hover = Css.rgba 0 0 0 0.03 }
, border = Css.rgba 0 0 0 0.1
}
}
customRemoteSettings : Settings
customRemoteSettings =
let
defaults =
defaultSettings zone
in
{ defaults
| -- [...]
, theme = customTheme
}