frandibar / elm-bootstrap / Bootstrap.Modal

Modals are streamlined, but flexible dialog prompts. They support a number of use cases from user notifications to completely custom content and feature a handful of helpful subcomponents, sizes, and more.

type alias Model =
    { modalVisibility : Modal.Visibility }

init : ( Model, Cmd Msg )
init =
    ( { modalVisibility = Modal.hidden }, Cmd.none )

type Msg
    = CloseModal
    | ShowModal

update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
    case msg of
        CloseModal ->
            ( { model | modalVisibility = Modal.hidden }
            , Cmd.none
            )

        ShowModal ->
            ( { model | modalVisibility = Modal.shown }
            , Cmd.none
            )

view : Model -> Html msg
view model =
    Grid.container []
        [ Button.button
            [ Button.attrs [ onClick ShowModal ] ]
            [ text "Show modal" ]
        , Modal.config CloseModal
            |> Modal.small
            |> Modal.h5 [] [ text "Modal header" ]
            |> Modal.body []
                [ Grid.containerFluid []
                    [ Grid.row []
                        [ Grid.col
                            [ Col.xs6 ]
                            [ text "Col 1" ]
                        , Grid.col
                            [ Col.xs6 ]
                            [ text "Col 2" ]
                        ]
                    ]
                ]
            |> Modal.footer []
                [ Button.button
                    [ Button.outlinePrimary
                    , Button.attrs [ onClick CloseModal ]
                    ]
                    [ text "Close" ]
                ]
            |> Modal.view model.modalVisibility
        ]

NOTE: Don't try to open several modals at the same time. It probably won't end well.

Modal

view : Visibility -> Config msg -> Html.Styled.Html msg

Create a modal for your application

config : msg -> Config msg

Create an initial modal config. You can enrich the config by using the header, body, footer and option related functions.


type Config msg

Opaque type representing the view config for a model. Use the config function to create an initial config.

State

hidden : Visibility

The modal should be hidden

shown : Visibility

The modal should be made visible.


type Visibility

Visibility state for the modal

Modal options

small : Config msg -> Config msg

Option to make a modal smaller than the default

large : Config msg -> Config msg

Option to make a modal larger than the default

centered : Basics.Bool -> Config msg -> Config msg

If you don't like the modal vertically centered, override with False here!

hideOnBackdropClick : Basics.Bool -> Config msg -> Config msg

Option to trigger close message when the user clicks on the modal backdrop. Default True.

scrollableBody : Basics.Bool -> Config msg -> Config msg

Use this function to make the Modal body scrollable.

attrs : List (Html.Styled.Attribute msg) -> Config msg -> Config msg

Use this function to add any Html.Attribute options you wish to the Modal

Header

header : List (Html.Styled.Attribute msg) -> List (Html.Styled.Html msg) -> Config msg -> Config msg

Create a header for a modal, typically for titles, but you can be imaginative

h1 : List (Html.Styled.Attribute msg) -> List (Html.Styled.Html msg) -> Config msg -> Config msg

Creates a modal header with a h1 title child element

h2 : List (Html.Styled.Attribute msg) -> List (Html.Styled.Html msg) -> Config msg -> Config msg

Creates a modal header with a h2 title child element

h3 : List (Html.Styled.Attribute msg) -> List (Html.Styled.Html msg) -> Config msg -> Config msg

Creates a modal header with a h3 title child element

h4 : List (Html.Styled.Attribute msg) -> List (Html.Styled.Html msg) -> Config msg -> Config msg

Creates a modal header with a h4 title child element

h5 : List (Html.Styled.Attribute msg) -> List (Html.Styled.Html msg) -> Config msg -> Config msg

Creates a modal header with a h5 title child element

h6 : List (Html.Styled.Attribute msg) -> List (Html.Styled.Html msg) -> Config msg -> Config msg

Creates a modal header with a h6 title child element


type Header msg

Opaque type representing a modal header

Body

body : List (Html.Styled.Attribute msg) -> List (Html.Styled.Html msg) -> Config msg -> Config msg

Create a body for a modal, you would typically always create a body for a modal


type Body msg

Opaque type representing a modal body

Footer

footer : List (Html.Styled.Attribute msg) -> List (Html.Styled.Html msg) -> Config msg -> Config msg

Create a footer for a modal. Normally used for action buttons, but you might be creative


type Footer msg

Opaque type representing a modal body

Animated Modals

When you want your modal to support an animation when displayed and closed. There is a few more things you must wire-up and keep in mind.

withAnimation : (Visibility -> msg) -> Config msg -> Config msg

Configure the modal to support fade-in/out animations. You'll need to provide a message to handle animation.

subscriptions : Visibility -> (Visibility -> msg) -> Platform.Sub.Sub msg

Subscription for handling animations

hiddenAnimated : Visibility

When using animations use this state for handling custom close buttons etc.

Button.button
    [ Button.outlinePrimary
    , Button.attrs [ onClick <| CloseModalAnimated Modal.hiddenAnimated ]
    ]
    [ text "Close" ]

Example

type Msg
    = ShowModal
      -- Note the extra msg constructor needed
    | AnimateModal Modal.Visibility
    | CloseModal

update : Msg -> State -> State
update msg state =
    case msg of
        CloseModal ->
            { state | modalVisibility = Modal.hidden }

        ShowModal ->
            { state | modalVisibility = Modal.shown }

        -- You need to handle the extra animation message
        AnimateModal visibility ->
            { state | modalVisibility = visibility }

-- Animations for modal doesn't work without a subscription.
-- DON“T forget this !
subscriptions : Model -> Sub msg
subscriptions model =
    Sub.batch
        [ Modal.subscriptions model.modalVisibility AnimateModal ]

view : Model -> Html msg
view model =
    Grid.container []
        [ Button.button
            [ Button.attrs [ onClick ShowModal ] ]
            [ text "Show modal" ]
        , Modal.config CloseModal
            |> Modal.h5 [] [ text "Modal header" ]
            |> Modal.body [] [ text "Modal body" ]
            |> Modal.footer []
                [ Button.button
                    [ Button.outlinePrimary
                    , Button.attrs [ onClick <| AnimateModal Modal.hiddenAnimated ]
                    ]
                    [ text "Close" ]
                ]
            |> Modal.view model.modalVisibility
        ]