This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.
Customizable, stylable dropdown menu with full keyboard support
version 1.0.0
license BSD3
native-modules False
elm-version 0.18.0 <= v < 0.19.0
Tag 1.0.0
Committed At 2017-09-05 10:30:21 UTC
elm-lang/html 2.0.0 <= v < 3.0.0 2.0.0
elm-lang/core 5.1.1 <= v < 6.0.0 5.1.1
elm-community/list-extra 6.1.0 <= v < 7.0.0 6.1.0



This package is a work in progress, and is published with the goal to facilitate discussion.

While the package is perfectly usable, there is an unresolved issue related to transitions and internal scrolling, and the examples and the docs are incomplete.


This is the dropdown menu we use in production at Stax.

  • Full keyboard support: alphanumberic blind search, Esc, Enter, Space, Up, Down, Page Up, Page Down, Home, End
  • Fully stylable, default CSS class names are provided and can be overridden
  • Internal scrolling with max-height and overflow-y: scroll
  • Optional Clear button
  • Placeholder

You can see the dropdown menu in action here.

The package works really well for our specific use case, but looks a bit jerky when it comes to dropdowns that both have a menu opening/closing transition and allow the menu to vertically scroll.

The issue

The update function needs to control the menu vertical scrolling, and calculating the correct scrolling position requires knowing the DOM geometry of the menu and its children; normally this can be done via DOM traversal (as done in elm-selecize).

However, using a menu opening/closing transition will (depending on the specific transition chosen) cause the geometry to change over time, usually without triggering any DOM event that could be used to get updated geometry information.

The ideal solution would allow an accurate and smooth scrolling during any arbitrary transition or animation, but an ideal solution might not be practical.


import DropdownMenu
import Html

type Msg
    = FruitDropdownMsg DropdownMenu.Msg

type alias Fruit =
    { id : String
    , name : String

type alias Model =
    { fruits : List Fruit
    , maybeFruitDropdown : Maybe DropdownMenu.OpenState
    , maybeSelectedFruit : Maybe Fruit

fruitDropdownConfig =
    { hasClearButton = False
    , itemToHtml = \isSelected isHighlighted fruit -> Html.text
    , itemToId = .id
    , itemToLabel = .name
    , modelToItems = .fruitList
    , modelToMaybeOpenState = .maybeFruitDropdown
    , modelToMaybeSelection = .maybeSelectedFruit
    , msgWrapper = FruitDropdownMsg
    , placeholder = Html.text "Select your favourite fruit"

update msg model =
    case msg of
        FruitDropdownMsg nestedMsg ->
                { closeAllDropdowns = \model -> { model | maybeFruitDropdown = Nothing }
                , openOnlyThisDropdown = \openState model -> ( { model | maybeFruitDropdown = Just openState }, Cmd.none )
                , setCurrentSelection = \maybeFruit model -> ( { model | maybeSelectedFruit = maybeFruit }, Cmd.none )

view model =
    DropdownMenu.viewEnabled DropdownMenu.defaultCommonFeatures fruitDropdownConfig model