NoRedInk/noredink-ui/11.1.0

NOTE: the latest version is 35.9.3

Nri.Ui.Modal.V9

Changes from V8:

  • replace multipleFocusableElementView, onlyFocusableElementView, ViewFuncs, and Focusable with FocusManager
  • adds initOpen
  • enable checks against the state (e.g., is the modal open or not?)
type Model
initOpen : String -> Model

Pass the id of the element that should receive focus when the modal is closed.

isOpen : Model -> Bool
type Msg
open : String -> Msg

Pass the id of the element that should receive focus when the modal closes.

{ dismissOnEscAndOverlayClick : Bool }
-> Msg
-> Model
-> ( Model, Cmd Msg )

Include the subscription if you want the modal to dismiss on Esc.

type FocusManager msg
= MultipleFocusableElements
( { firstFocusableElement : List (Attribute msg)
, lastFocusableElement : List (Attribute msg)
, autofocusElement : Attribute msg
, closeButton : List (Attribute msg) -> Html msg
}
-> { content : List (Html msg)
, footer : List (Html msg)
}
)
| OneFocusableElement
( { onlyFocusableElement : List (Attribute msg)
, closeButton : List (Attribute msg) -> Html msg
}
-> { content : List (Html msg)
, footer : List (Html msg)
}
)

Modals should allow the user to tab forwards & backwards through the modal content. The user should never find their Focus lost behind the modal backdrop!

Use the FocusManager to tag the focusable elements in your modal, so that we know to which element to return focus when the user reaches the last focusable element.

{ visibleTitle : Bool
, title : String
, wrapMsg : Msg -> msg
, focusManager : FocusManager msg
}
-> Model
-> Html msg
{ visibleTitle : Bool
, title : String
, wrapMsg : Msg -> msg
, focusManager : FocusManager msg
}
-> Model
-> Html msg
import Html.Styled exposing (text)
import Nri.Ui.Modal.V9 as Modal


type Msg
    = ModalMsg Modal.Msg


...


viewModal : Modal.Model -> Html Msg
viewModal modalState =
    Modal.info
        { title = "Modal Title"
        , visibleTitle = False
        , wrapMsg = ModalMsg
        , focusManager =
            Modal.OneFocusableElement
                (\{ onlyFocusableElement, closeButton } ->
                    { content =
                        [ closeButton onlyFocusableElement
                        , text "Modal Content"
                        ]
                    , footer = []
                    }
                )
        }
        modalState