This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.

Aui.Dropdown

Functions to present AUI buttons and groups.

Alignment

type Alignment = Left | Right

Alignment relative to the button for the dropdown container.

leftAlignment : Alignment

Left alignment of the dropdown respectively to the button

rightAlignment : Alignment

Right alignment of the dropdown respectively to the button

Types

type Config a = Config (InnerConfig a)

Configuration type to show a dropdown component.

Model

type alias Model = { open : Bool }

Model for the dropdown component.

type Msg = Toggle

Messages being sent by the dropdown component

initialModel : Model

Default model for a dropdown component

open : Model -> Model

Change a dropdown to an opened state.

close : Model -> Model

Change a dropdown to a closed state. Convenient when you handle an action from an item in the dropdown in your own update function.

Update

update : Msg -> Model -> Model

Update function for the dropdown component. This should be called from within your update function when handling Msg

Presentation

dropdown : Config a -> List (Html Msg) -> List (Html a) -> Model -> Html a

Present a dropdown given a configuration, button content, dropdown content and a model.

dropdown (baseConfig DropdownMsg |> withStyle Primary |> withAlignment Right)
    [ text "Open me"]
    [ dropdownSection (Just "Section Title")
        [ ul []
            [ li [] a [] [text "Item 1"]
            , li [] a [] [text "Item 2"]
            ]
        ]
    ]
    dropdownModel
dropdownSection : Maybe String -> List (Html a) -> Html a

Creates a section for within a dropdown container.

Utility

baseConfig : (Msg -> a) -> Config a

Create a base configuration with a Msg mapping function.

type Msg = DropdownMsg Aui.Dropdown.Msg

dropdown (baseConfig DropdownMsg) ...
withAlignment : Alignment -> Config a -> Config a

Align the container for the dropdown to the side of the dropdown button.

withStyle : Aui.Buttons.Style -> Config a -> Config a

Set the style of the dropdown button.

module Aui.Dropdown exposing (dropdown, dropdownSection, Model, initialModel, Msg, Alignment, leftAlignment, rightAlignment, baseConfig, withAlignment, withStyle, update, Config, open, close)

{-| Functions to present AUI buttons and groups.


# Alignment

@docs Alignment, leftAlignment, rightAlignment


# Types

@docs Config


# Model

@docs Model, Msg, initialModel, open, close


# Update

@docs update


# Presentation

@docs dropdown, dropdownSection


# Utility

@docs baseConfig, withAlignment, withStyle

-}

import Aui.Buttons exposing (normalStyle, baseConfig, forceAnchor, withAdditionalClass, withActive, withAction)
import Aui.Backdrop exposing (backdrop)
import Html exposing (Html, div, strong, text)
import Html.Attributes exposing (style, class)


-- {-| Style for the dropdown.
-- -}
-- type alias Style =
-- Aui.Buttons.Style


{-| Alignment relative to the button for the dropdown container.
-}
type Alignment
    = Left
    | Right


{-| Left alignment of the dropdown respectively to the button
-}
leftAlignment : Alignment
leftAlignment =
    Left


{-| Right alignment of the dropdown respectively to the button
-}
rightAlignment : Alignment
rightAlignment =
    Right


type alias InnerConfig a =
    { zIndexBackdrop : Int
    , style : Aui.Buttons.Style
    , disabled : Bool
    , msgMap : Msg -> a
    , alignment : Alignment
    }


{-| Configuration type to show a dropdown component.
-}
type Config a
    = Config (InnerConfig a)


{-| Messages being sent by the dropdown component
-}
type Msg
    = Toggle


{-| Model for the dropdown component.
-}
type alias Model =
    { open : Bool }


{-| Default model for a dropdown component
-}
initialModel : Model
initialModel =
    { open = False }


{-| Change a dropdown to a closed state. Convenient when you handle an action from an item in the dropdown in your own update function.
-}
close : Model -> Model
close model =
    { model | open = False }


{-| Change a dropdown to an opened state.
-}
open : Model -> Model
open model =
    { model | open = True }


{-| Update function for the dropdown component. This should be called from within your update function when handling `Msg`
-}
update : Msg -> Model -> Model
update msg model =
    case msg of
        Toggle ->
            { model | open = not model.open }


{-| Present a dropdown given a configuration, button content, dropdown content and a model.

    dropdown (baseConfig DropdownMsg |> withStyle Primary |> withAlignment Right)
        [ text "Open me"]
        [ dropdownSection (Just "Section Title")
            [ ul []
                [ li [] a [] [text "Item 1"]
                , li [] a [] [text "Item 2"]
                ]
            ]
        ]
        dropdownModel

-}
dropdown : Config a -> List (Html Msg) -> List (Html a) -> Model -> Html a
dropdown (Config config) buttonInner dropdownInner model =
    let
        contentDisplay =
            if model.open then
                "inline-block"
            else
                "none"

        itemsZIndex =
            config.zIndexBackdrop + 1 |> toString
    in
        div [ style [ ( "position", "relative" ), ( "display", "inline-block" ) ] ]
            [ Html.map config.msgMap (backdrop config.zIndexBackdrop Toggle model.open)
            , div [ style [ ( "z-index", itemsZIndex ), ( "position", "relative" ) ] ]
                [ Html.map config.msgMap
                    (Aui.Buttons.button
                        (Aui.Buttons.baseConfig
                            |> forceAnchor
                            |> withAdditionalClass "aui-dropdown2-trigger"
                            |> Aui.Buttons.withStyle config.style
                            |> withActive model.open
                            |> withAction Toggle
                        )
                        buttonInner
                    )
                ]
            , div
                [ style
                    [ ( "display", contentDisplay )
                    , ( "z-index", itemsZIndex )
                    , ( "position", "absolute" )
                    , ( "top", "30px" )
                    , ( if config.alignment == Left then
                            "left"
                        else
                            "right"
                      , "0"
                      )
                    ]
                , class "aui-dropdown2 aui-style-default"
                ]
                dropdownInner
            ]


{-| Creates a section for within a dropdown container.
-}
dropdownSection : Maybe String -> List (Html a) -> Html a
dropdownSection title inner =
    case title of
        Just x ->
            let
                header =
                    div [ class "aui-dropdown2-heading" ]
                        [ strong [] [ text x ] ]
            in
                div [ class "aui-dropdown2-section" ] (header :: inner)

        Nothing ->
            div [ class "aui-dropdown2-section" ] inner


{-| Create a base configuration with a Msg mapping function.

    type Msg = DropdownMsg Aui.Dropdown.Msg

    dropdown (baseConfig DropdownMsg) ...

-}
baseConfig : (Msg -> a) -> Config a
baseConfig msgMap =
    Config
        { zIndexBackdrop = 99
        , style = normalStyle
        , disabled = False
        , msgMap = msgMap
        , alignment = Left
        }


{-| Align the container for the dropdown to the side of the dropdown button.
-}
withAlignment : Alignment -> Config a -> Config a
withAlignment x (Config config) =
    Config { config | alignment = x }


{-| Set the style of the dropdown button.
-}
withStyle : Aui.Buttons.Style -> Config a -> Config a
withStyle x (Config config) =
    Config { config | style = x }