mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-12-11 14:36:38 +03:00
Merge pull request #380 from NoRedInk/lab/modal-without-bottom-buttons
Lab/modal without bottom buttons
This commit is contained in:
commit
a76904e9d4
1
elm.json
1
elm.json
@ -53,6 +53,7 @@
|
||||
"Nri.Ui.Modal.V5",
|
||||
"Nri.Ui.Modal.V6",
|
||||
"Nri.Ui.Modal.V7",
|
||||
"Nri.Ui.Modal.V8",
|
||||
"Nri.Ui.Outline.V2",
|
||||
"Nri.Ui.Page.V2",
|
||||
"Nri.Ui.Page.V3",
|
||||
|
453
src/Nri/Ui/Modal/V8.elm
Normal file
453
src/Nri/Ui/Modal/V8.elm
Normal file
@ -0,0 +1,453 @@
|
||||
module Nri.Ui.Modal.V8 exposing
|
||||
( Model, init
|
||||
, Msg, update, subscriptions
|
||||
, open, close
|
||||
, info, warning
|
||||
, ViewFuncs
|
||||
, Focusable
|
||||
, multipleFocusableElementView, onlyFocusableElementView
|
||||
)
|
||||
|
||||
{-| Changes from V7:
|
||||
|
||||
- More customizable attributes
|
||||
- Rather than accepting any number of attributes, Modal provides one callback that returns a focusable
|
||||
- viewFooter has been merged into viewContent
|
||||
- viewContent and closeButton are now callbacks that are pre-configured with settings
|
||||
(previously you passed config through)
|
||||
|
||||
```
|
||||
import Html.Styled exposing (..)
|
||||
import Nri.Ui.Button.V9 as Button
|
||||
import Nri.Ui.Modal.V8 as Modal
|
||||
|
||||
type Msg
|
||||
= ModalMsg Modal.Msg
|
||||
| DoSomething
|
||||
|
||||
view : Modal.Model -> Html Msg
|
||||
view state =
|
||||
Modal.info
|
||||
{ title = "Modal Header"
|
||||
, wrapMsg = ModalMsg
|
||||
, visibleTitle = True
|
||||
}
|
||||
(\{viewContent, closeButton} ->
|
||||
Modal.onlyFocusableElementView
|
||||
(\{ onlyFocusableElement } ->
|
||||
div []
|
||||
[ viewContent {
|
||||
, content = [ text "Content goes here!" ]
|
||||
, footer =
|
||||
[ Button.button "Continue"
|
||||
[ Button.primary
|
||||
, Button.onClick DoSomething
|
||||
, Button.custom onlyFocusableElement
|
||||
]
|
||||
, text "`onlyFocusableElement` will trap the focus on the 'Continue' button."
|
||||
]
|
||||
}
|
||||
visibleTitle
|
||||
]
|
||||
)
|
||||
)
|
||||
state
|
||||
|
||||
subscriptions : Modal.Model -> Sub Msg
|
||||
subscriptions state =
|
||||
Modal.subscriptions state
|
||||
|
||||
view init
|
||||
--> text "" -- a closed modal
|
||||
```
|
||||
|
||||
|
||||
## State and updates
|
||||
|
||||
@docs Model, init
|
||||
@docs Msg, update, subscriptions
|
||||
|
||||
@docs open, close
|
||||
|
||||
|
||||
## Views
|
||||
|
||||
|
||||
### Modals
|
||||
|
||||
@docs info, warning
|
||||
@docs ViewFuncs
|
||||
|
||||
|
||||
### Focusable
|
||||
|
||||
@docs Focusable
|
||||
@docs multipleFocusableElementView, onlyFocusableElementView
|
||||
|
||||
-}
|
||||
|
||||
import Accessibility.Modal.Copy as Modal
|
||||
import Accessibility.Styled as Html exposing (..)
|
||||
import Accessibility.Styled.Widget as Widget
|
||||
import Color.Transparent as Transparent
|
||||
import Css
|
||||
import Css.Transitions
|
||||
import Html.Styled.Attributes as Attributes exposing (css)
|
||||
import Html.Styled.Events exposing (onClick)
|
||||
import Nri.Ui.Colors.Extra
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.SpriteSheet
|
||||
import Nri.Ui.Svg.V1
|
||||
|
||||
|
||||
{-| -}
|
||||
type alias Model =
|
||||
Modal.Model
|
||||
|
||||
|
||||
type alias Config msg =
|
||||
{ visibleTitle : Bool
|
||||
, title : String
|
||||
, wrapMsg : Msg -> msg
|
||||
}
|
||||
|
||||
|
||||
{-| -}
|
||||
init : Model
|
||||
init =
|
||||
Modal.init
|
||||
|
||||
|
||||
{-| -}
|
||||
type alias Msg =
|
||||
Modal.Msg
|
||||
|
||||
|
||||
{-| Include the subscription if you want the modal to dismiss on `Esc`.
|
||||
-}
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions =
|
||||
Modal.subscriptions
|
||||
|
||||
|
||||
{-| -}
|
||||
update : { dismissOnEscAndOverlayClick : Bool } -> Msg -> Model -> ( Model, Cmd Msg )
|
||||
update config msg model =
|
||||
Modal.update config msg model
|
||||
|
||||
|
||||
{-| -}
|
||||
close : Msg
|
||||
close =
|
||||
Modal.close
|
||||
|
||||
|
||||
{-| Pass the id of the element that focus should return to when the modal closes.
|
||||
-}
|
||||
open : String -> Msg
|
||||
open =
|
||||
Modal.open
|
||||
|
||||
|
||||
{-| -}
|
||||
info :
|
||||
Config msg
|
||||
-> (ViewFuncs msg -> Focusable msg)
|
||||
-> Model
|
||||
-> Html msg
|
||||
info config getFocusable model =
|
||||
view Info config getFocusable model
|
||||
|
||||
|
||||
{-| -}
|
||||
warning :
|
||||
Config msg
|
||||
-> (ViewFuncs msg -> Focusable msg)
|
||||
-> Model
|
||||
-> Html msg
|
||||
warning config getFocusable model =
|
||||
view Warning config getFocusable model
|
||||
|
||||
|
||||
type Theme
|
||||
= Info
|
||||
| Warning
|
||||
|
||||
|
||||
themeToOverlayColor : Theme -> Css.Color
|
||||
themeToOverlayColor theme =
|
||||
case theme of
|
||||
Info ->
|
||||
Colors.navy
|
||||
|
||||
Warning ->
|
||||
Colors.gray20
|
||||
|
||||
|
||||
themeToTitleColor : Theme -> Css.Color
|
||||
themeToTitleColor theme =
|
||||
case theme of
|
||||
Info ->
|
||||
Colors.navy
|
||||
|
||||
Warning ->
|
||||
Colors.red
|
||||
|
||||
|
||||
{-| -}
|
||||
type Focusable msg
|
||||
= Focusable (Modal.Attribute msg) (List (Modal.Attribute msg))
|
||||
|
||||
|
||||
{-| -}
|
||||
multipleFocusableElementView :
|
||||
({ firstFocusableElement : List (Html.Attribute msg)
|
||||
, lastFocusableElement : List (Html.Attribute msg)
|
||||
, autofocusElement : Html.Attribute msg
|
||||
}
|
||||
-> Html msg
|
||||
)
|
||||
-> Focusable msg
|
||||
multipleFocusableElementView f =
|
||||
Focusable (Modal.multipleFocusableElementView (\attributes -> f attributes)) []
|
||||
|
||||
|
||||
{-| -}
|
||||
onlyFocusableElementView : (List (Html.Attribute msg) -> Html msg) -> Focusable msg
|
||||
onlyFocusableElementView f =
|
||||
Focusable (Modal.onlyFocusableElementView (\attributes -> f attributes)) [ Modal.autofocusOnLastElement ]
|
||||
|
||||
|
||||
{-| -}
|
||||
type alias ViewFuncs msg =
|
||||
{ viewContent : { content : List (Html msg), footer : List (Html msg) } -> Html msg
|
||||
, closeButton : List (Html.Attribute msg) -> Html msg
|
||||
}
|
||||
|
||||
|
||||
view :
|
||||
Theme
|
||||
-> Config msg
|
||||
-> (ViewFuncs msg -> Focusable msg)
|
||||
-> Model
|
||||
-> Html msg
|
||||
view theme config getFocusable model =
|
||||
let
|
||||
viewFuncs : ViewFuncs msg
|
||||
viewFuncs =
|
||||
{ viewContent = viewContent config.visibleTitle
|
||||
, closeButton = closeButton config.wrapMsg
|
||||
}
|
||||
|
||||
focusables =
|
||||
case getFocusable viewFuncs of
|
||||
Focusable fst rst ->
|
||||
fst :: rst
|
||||
in
|
||||
Modal.view
|
||||
config.wrapMsg
|
||||
config.title
|
||||
([ Modal.overlayColor (Nri.Ui.Colors.Extra.withAlpha 0.9 (themeToOverlayColor theme))
|
||||
, Modal.custom
|
||||
[ Css.width (Css.px 600)
|
||||
, Css.margin2 (Css.px 50) Css.auto
|
||||
, Css.borderRadius (Css.px 20)
|
||||
, Css.boxShadow5 Css.zero (Css.px 1) (Css.px 10) Css.zero (Css.rgba 0 0 0 0.35)
|
||||
, Css.backgroundColor Colors.white
|
||||
]
|
||||
, if config.visibleTitle then
|
||||
Modal.titleStyles
|
||||
[ Fonts.baseFont
|
||||
, Css.fontWeight (Css.int 700)
|
||||
, Css.paddingTop (Css.px 40)
|
||||
, Css.paddingBottom (Css.px 20)
|
||||
, Css.margin Css.zero
|
||||
, Css.fontSize (Css.px 20)
|
||||
, Css.textAlign Css.center
|
||||
, Css.color (themeToTitleColor theme)
|
||||
]
|
||||
|
||||
else
|
||||
Modal.titleStyles
|
||||
[ -- https://snook.ca/archives/html_and_css/hiding-content-for-accessibility
|
||||
Css.property "clip" "rect(1px, 1px, 1px, 1px)"
|
||||
, Css.position Css.absolute
|
||||
, Css.height (Css.px 1)
|
||||
, Css.width (Css.px 1)
|
||||
, Css.overflow Css.hidden
|
||||
, Css.margin (Css.px -1)
|
||||
, Css.padding Css.zero
|
||||
, Css.border Css.zero
|
||||
]
|
||||
]
|
||||
++ focusables
|
||||
)
|
||||
model
|
||||
|> List.singleton
|
||||
|> div [ css [ Css.position Css.relative, Css.zIndex (Css.int 1) ] ]
|
||||
|
||||
|
||||
{-| -}
|
||||
viewContent : Bool -> { content : List (Html msg), footer : List (Html msg) } -> Html msg
|
||||
viewContent visibleTitle { content, footer } =
|
||||
div []
|
||||
[ viewInnerContent content visibleTitle (not (List.isEmpty footer))
|
||||
, viewFooter footer
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
viewInnerContent : List (Html msg) -> Bool -> Bool -> Html msg
|
||||
viewInnerContent children visibleTitle visibleFooter =
|
||||
let
|
||||
titleHeight =
|
||||
if visibleTitle then
|
||||
45
|
||||
|
||||
else
|
||||
0
|
||||
|
||||
footerHeight =
|
||||
if visibleFooter then
|
||||
180
|
||||
|
||||
else
|
||||
0
|
||||
|
||||
modalTitleStyles =
|
||||
if visibleTitle then
|
||||
[]
|
||||
|
||||
else
|
||||
[ Css.borderTopLeftRadius (Css.px 20)
|
||||
, Css.borderTopRightRadius (Css.px 20)
|
||||
, Css.overflowY Css.hidden
|
||||
]
|
||||
|
||||
modalFooterStyles =
|
||||
if visibleFooter then
|
||||
[]
|
||||
|
||||
else
|
||||
[ Css.borderBottomLeftRadius (Css.px 20)
|
||||
, Css.borderBottomRightRadius (Css.px 20)
|
||||
, Css.overflowY Css.hidden
|
||||
]
|
||||
in
|
||||
div
|
||||
[ css (modalTitleStyles ++ modalFooterStyles)
|
||||
]
|
||||
[ div
|
||||
[ css
|
||||
[ Css.overflowY Css.auto
|
||||
, Css.minHeight (Css.px 150)
|
||||
, Css.maxHeight
|
||||
(Css.calc (Css.vh 100)
|
||||
Css.minus
|
||||
(Css.px (footerHeight + titleHeight + 145))
|
||||
)
|
||||
, Css.width (Css.pct 100)
|
||||
, Css.boxSizing Css.borderBox
|
||||
, Css.paddingLeft (Css.px 40)
|
||||
, Css.paddingRight (Css.px 40)
|
||||
, if visibleTitle then
|
||||
Css.paddingTop Css.zero
|
||||
|
||||
else
|
||||
Css.paddingTop (Css.px 40)
|
||||
, if visibleFooter then
|
||||
Css.paddingBottom Css.zero
|
||||
|
||||
else
|
||||
Css.paddingBottom (Css.px 40)
|
||||
, if visibleFooter then
|
||||
shadow (Transparent.customOpacity 0.15) (Css.px 16)
|
||||
|
||||
else
|
||||
shadow (Transparent.customOpacity 0.4) (Css.px 30)
|
||||
]
|
||||
]
|
||||
children
|
||||
]
|
||||
|
||||
|
||||
shadow : Transparent.Opacity -> Css.Px -> Css.Style
|
||||
shadow opacity bottomShadowHeight =
|
||||
let
|
||||
to =
|
||||
Transparent.fromRGBA { red = 0, green = 0, blue = 0, alpha = opacity }
|
||||
|> Transparent.toRGBAString
|
||||
in
|
||||
Css.batch
|
||||
[ -- Shadows for indicating that the content is scrollable
|
||||
[ "/* TOP shadow */"
|
||||
, "top linear-gradient(to top, rgb(255, 255, 255), rgb(255, 255, 255)) local,"
|
||||
, "top linear-gradient(to top, rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.15)) scroll,"
|
||||
, ""
|
||||
, "/* BOTTOM shadow */"
|
||||
, "bottom linear-gradient(to bottom, rgb(255, 255, 255), rgb(255, 255, 255)) local,"
|
||||
, "bottom linear-gradient(to bottom, rgba(255, 255, 255, 0), " ++ to ++ ") scroll"
|
||||
]
|
||||
|> String.join "\n"
|
||||
|> Css.property "background"
|
||||
, Css.backgroundSize2 (Css.pct 100) bottomShadowHeight
|
||||
, Css.backgroundRepeat Css.noRepeat
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
viewFooter : List (Html msg) -> Html msg
|
||||
viewFooter children =
|
||||
if List.isEmpty children then
|
||||
Html.text ""
|
||||
|
||||
else
|
||||
div
|
||||
[ css
|
||||
[ Css.alignItems Css.center
|
||||
, Css.displayFlex
|
||||
, Css.flexDirection Css.column
|
||||
, Css.flexGrow (Css.int 2)
|
||||
, Css.flexWrap Css.noWrap
|
||||
, Css.margin4 (Css.px 20) Css.zero Css.zero Css.zero
|
||||
, Css.paddingBottom (Css.px 40)
|
||||
, Css.width (Css.pct 100)
|
||||
]
|
||||
]
|
||||
children
|
||||
|
||||
|
||||
|
||||
--BUTTONS
|
||||
|
||||
|
||||
{-| -}
|
||||
closeButton : (Msg -> msg) -> List (Html.Attribute msg) -> Html msg
|
||||
closeButton wrapMsg focusableElementAttrs =
|
||||
button
|
||||
(Widget.label "Close modal"
|
||||
:: Attributes.map wrapMsg (onClick Modal.close)
|
||||
:: css
|
||||
[ -- in the upper-right corner of the modal
|
||||
Css.position Css.absolute
|
||||
, Css.top Css.zero
|
||||
, Css.right Css.zero
|
||||
|
||||
-- make the hitspace extend all the way to the corner
|
||||
, Css.width (Css.px 40)
|
||||
, Css.height (Css.px 40)
|
||||
, Css.padding4 (Css.px 20) (Css.px 20) (Css.px 2) Css.zero
|
||||
|
||||
-- apply button styles
|
||||
, Css.borderWidth Css.zero
|
||||
, Css.backgroundColor Css.transparent
|
||||
, Css.cursor Css.pointer
|
||||
, Css.color Colors.azure
|
||||
, Css.hover [ Css.color Colors.azureDark ]
|
||||
, Css.Transitions.transition [ Css.Transitions.color 0.1 ]
|
||||
]
|
||||
:: focusableElementAttrs
|
||||
)
|
||||
[ Nri.Ui.Svg.V1.toHtml Nri.Ui.SpriteSheet.xSvg
|
||||
]
|
@ -16,7 +16,7 @@ import Nri.Ui.Button.V9 as Button
|
||||
import Nri.Ui.Checkbox.V5 as Checkbox
|
||||
import Nri.Ui.ClickableText.V3 as ClickableText
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Modal.V7 as Modal
|
||||
import Nri.Ui.Modal.V8 as Modal
|
||||
import Nri.Ui.Text.V4 as Text
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ init =
|
||||
{-| -}
|
||||
example : (Msg -> msg) -> State -> ModuleExample msg
|
||||
example parentMessage state =
|
||||
{ name = "Nri.Ui.Modal.V7"
|
||||
{ name = "Nri.Ui.Modal.V8"
|
||||
, category = Modals
|
||||
, content =
|
||||
[ viewSettings state
|
||||
@ -69,181 +69,185 @@ example parentMessage state =
|
||||
, Button.secondary
|
||||
, Button.medium
|
||||
]
|
||||
, Modal.info
|
||||
{ title = "Modal.info"
|
||||
, visibleTitle = state.visibleTitle
|
||||
, wrapMsg = InfoModalMsg
|
||||
}
|
||||
(viewContent state InfoModalMsg Button.primary)
|
||||
, let
|
||||
params =
|
||||
( state, InfoModalMsg, Button.primary )
|
||||
in
|
||||
Modal.info { title = "Modal.info", wrapMsg = InfoModalMsg, visibleTitle = state.visibleTitle }
|
||||
(getFocusable params)
|
||||
state.infoModal
|
||||
, Modal.warning
|
||||
{ title = "Modal.warning"
|
||||
, visibleTitle = state.visibleTitle
|
||||
, wrapMsg = WarningModalMsg
|
||||
}
|
||||
(viewContent state WarningModalMsg Button.danger)
|
||||
, let
|
||||
params =
|
||||
( state, WarningModalMsg, Button.danger )
|
||||
in
|
||||
Modal.warning { title = "Modal.warning", wrapMsg = WarningModalMsg, visibleTitle = state.visibleTitle }
|
||||
(getFocusable params)
|
||||
state.warningModal
|
||||
]
|
||||
|> List.map (Html.map parentMessage)
|
||||
}
|
||||
|
||||
|
||||
viewContent :
|
||||
State
|
||||
-> (Modal.Msg -> Msg)
|
||||
-> Button.Attribute Msg
|
||||
-> List (Modal.Attribute Msg)
|
||||
viewContent state wrapMsg firstButtonStyle =
|
||||
getFocusable :
|
||||
( State, Modal.Msg -> Msg, Button.Attribute Msg )
|
||||
-> Modal.ViewFuncs Msg
|
||||
-> Modal.Focusable Msg
|
||||
getFocusable ( state, wrapMsg, firstButtonStyle ) { viewContent, closeButton } =
|
||||
case ( state.showX, state.showContinue, state.showSecondary ) of
|
||||
( True, True, True ) ->
|
||||
[ Modal.multipleFocusableElementView
|
||||
(\focusableElementAttrs ->
|
||||
Modal.multipleFocusableElementView
|
||||
(\{ firstFocusableElement, autofocusElement, lastFocusableElement } ->
|
||||
div []
|
||||
[ Modal.closeButton wrapMsg focusableElementAttrs.firstFocusableElement
|
||||
, Modal.viewContent [ viewModalContent state.longContent ]
|
||||
, Modal.viewFooter
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.large
|
||||
, Button.custom [ focusableElementAttrs.autofocusElement ]
|
||||
[ closeButton firstFocusableElement
|
||||
, viewContent
|
||||
{ content = [ viewModalContent state.longContent ]
|
||||
, footer =
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.large
|
||||
, Button.custom [ autofocusElement ]
|
||||
]
|
||||
, ClickableText.button "Close"
|
||||
[ ClickableText.onClick ForceClose
|
||||
, ClickableText.large
|
||||
, ClickableText.custom
|
||||
(css [ Css.marginTop (Css.px 12) ]
|
||||
:: lastFocusableElement
|
||||
)
|
||||
]
|
||||
]
|
||||
, ClickableText.button "Close"
|
||||
[ ClickableText.onClick ForceClose
|
||||
, ClickableText.large
|
||||
, ClickableText.custom
|
||||
(css [ Css.marginTop (Css.px 20) ]
|
||||
:: focusableElementAttrs.lastFocusableElement
|
||||
)
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
( True, False, True ) ->
|
||||
[ Modal.multipleFocusableElementView
|
||||
(\focusableElementAttrs ->
|
||||
Modal.multipleFocusableElementView
|
||||
(\{ firstFocusableElement, autofocusElement, lastFocusableElement } ->
|
||||
div []
|
||||
[ Modal.closeButton wrapMsg focusableElementAttrs.firstFocusableElement
|
||||
, Modal.viewContent [ viewModalContent state.longContent ]
|
||||
, Modal.viewFooter
|
||||
[ ClickableText.button "Close"
|
||||
[ ClickableText.onClick ForceClose
|
||||
, ClickableText.large
|
||||
, ClickableText.custom
|
||||
(css [ Css.marginTop (Css.px 20) ]
|
||||
:: focusableElementAttrs.lastFocusableElement
|
||||
)
|
||||
[ closeButton firstFocusableElement
|
||||
, viewContent
|
||||
{ content = [ viewModalContent state.longContent ]
|
||||
, footer =
|
||||
[ ClickableText.button "Close"
|
||||
[ ClickableText.onClick ForceClose
|
||||
, ClickableText.large
|
||||
, ClickableText.custom
|
||||
(css [ Css.marginTop (Css.px 12) ]
|
||||
:: autofocusElement
|
||||
:: lastFocusableElement
|
||||
)
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
( True, False, False ) ->
|
||||
[ Modal.multipleFocusableElementView
|
||||
(\focusableElementAttrs ->
|
||||
Modal.onlyFocusableElementView
|
||||
(\onlyFocusableElement ->
|
||||
div []
|
||||
[ Modal.closeButton wrapMsg focusableElementAttrs.firstFocusableElement
|
||||
, Modal.viewContent [ viewModalContent state.longContent ]
|
||||
[ closeButton onlyFocusableElement
|
||||
, viewContent
|
||||
{ content = [ viewModalContent state.longContent ]
|
||||
, footer = []
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
( True, True, False ) ->
|
||||
[ Modal.autofocusOnLastElement
|
||||
, Modal.multipleFocusableElementView
|
||||
(\focusableElementAttrs ->
|
||||
Modal.multipleFocusableElementView
|
||||
(\{ firstFocusableElement, autofocusElement, lastFocusableElement } ->
|
||||
div []
|
||||
[ Modal.closeButton wrapMsg focusableElementAttrs.firstFocusableElement
|
||||
, Modal.viewContent [ viewModalContent state.longContent ]
|
||||
, Modal.viewFooter
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.custom focusableElementAttrs.lastFocusableElement
|
||||
, Button.large
|
||||
[ closeButton firstFocusableElement
|
||||
, viewContent
|
||||
{ content = [ viewModalContent state.longContent ]
|
||||
, footer =
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.custom (autofocusElement :: lastFocusableElement)
|
||||
, Button.large
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
( False, True, True ) ->
|
||||
[ Modal.multipleFocusableElementView
|
||||
(\focusableElementAttrs ->
|
||||
Modal.multipleFocusableElementView
|
||||
(\{ firstFocusableElement, autofocusElement, lastFocusableElement } ->
|
||||
div []
|
||||
[ Modal.viewContent [ viewModalContent state.longContent ]
|
||||
, Modal.viewFooter
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.custom focusableElementAttrs.firstFocusableElement
|
||||
, Button.large
|
||||
[ viewContent
|
||||
{ content = [ viewModalContent state.longContent ]
|
||||
, footer =
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.custom (autofocusElement :: firstFocusableElement)
|
||||
, Button.large
|
||||
]
|
||||
, ClickableText.button "Close"
|
||||
[ ClickableText.onClick ForceClose
|
||||
, ClickableText.large
|
||||
, ClickableText.custom
|
||||
(css [ Css.marginTop (Css.px 12) ]
|
||||
:: lastFocusableElement
|
||||
)
|
||||
]
|
||||
]
|
||||
, ClickableText.button "Close"
|
||||
[ ClickableText.onClick ForceClose
|
||||
, ClickableText.large
|
||||
, ClickableText.custom
|
||||
(css [ Css.marginTop (Css.px 20) ]
|
||||
:: focusableElementAttrs.lastFocusableElement
|
||||
)
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
( False, False, True ) ->
|
||||
[ Modal.autofocusOnLastElement
|
||||
, Modal.multipleFocusableElementView
|
||||
(\focusableElementAttrs ->
|
||||
Modal.onlyFocusableElementView
|
||||
(\onlyFocusableElement ->
|
||||
div []
|
||||
[ Modal.viewContent [ viewModalContent state.longContent ]
|
||||
, Modal.viewFooter
|
||||
[ ClickableText.button "Close"
|
||||
[ ClickableText.onClick ForceClose
|
||||
, ClickableText.large
|
||||
, ClickableText.custom
|
||||
(css
|
||||
[ Css.marginTop
|
||||
(Css.px 20)
|
||||
]
|
||||
:: focusableElementAttrs.lastFocusableElement
|
||||
)
|
||||
[ viewContent
|
||||
{ content = [ viewModalContent state.longContent ]
|
||||
, footer =
|
||||
[ ClickableText.button "Close"
|
||||
[ ClickableText.onClick ForceClose
|
||||
, ClickableText.large
|
||||
, ClickableText.custom
|
||||
(css [ Css.marginTop (Css.px 12) ]
|
||||
:: onlyFocusableElement
|
||||
)
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
( False, True, False ) ->
|
||||
[ Modal.autofocusOnLastElement
|
||||
, Modal.multipleFocusableElementView
|
||||
(\focusableElementAttrs ->
|
||||
Modal.onlyFocusableElementView
|
||||
(\onlyFocusableElement ->
|
||||
div []
|
||||
[ Modal.viewContent [ viewModalContent state.longContent ]
|
||||
, Modal.viewFooter
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.custom [ focusableElementAttrs.autofocusElement ]
|
||||
, Button.large
|
||||
[ viewContent
|
||||
{ content = [ viewModalContent state.longContent ]
|
||||
, footer =
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.custom onlyFocusableElement
|
||||
, Button.large
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
( False, False, False ) ->
|
||||
[ Modal.multipleFocusableElementView
|
||||
(\focusableElementAttrs ->
|
||||
Modal.onlyFocusableElementView
|
||||
(\_ ->
|
||||
div []
|
||||
[ Modal.viewContent [ viewModalContent state.longContent ]
|
||||
[ viewContent
|
||||
{ content = [ viewModalContent state.longContent ]
|
||||
, footer = []
|
||||
}
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
viewModalContent : Bool -> Html msg
|
||||
@ -251,13 +255,11 @@ viewModalContent longContent =
|
||||
Text.mediumBody
|
||||
[ span [ css [ whiteSpace preLine ] ]
|
||||
[ if longContent then
|
||||
"""
|
||||
Soufflé pastry chocolate cake danish muffin. Candy wafer pastry ice cream cheesecake toffee cookie cake carrot cake. Macaroon pie jujubes gummies cookie pie. Gummi bears brownie pastry carrot cake cotton candy. Jelly-o sweet roll biscuit cake soufflé lemon drops tiramisu marshmallow macaroon. Chocolate jelly halvah marzipan macaroon cupcake sweet cheesecake carrot cake.
|
||||
"""Soufflé pastry chocolate cake danish muffin. Candy wafer pastry ice cream cheesecake toffee cookie cake carrot cake. Macaroon pie jujubes gummies cookie pie. Gummi bears brownie pastry carrot cake cotton candy. Jelly-o sweet roll biscuit cake soufflé lemon drops tiramisu marshmallow macaroon. Chocolate jelly halvah marzipan macaroon cupcake sweet cheesecake carrot cake.
|
||||
|
||||
Sesame snaps pastry muffin cookie. Powder powder sweet roll toffee cake icing. Chocolate cake sweet roll gingerbread icing chupa chups sweet roll sesame snaps. Chocolate croissant chupa chups jelly beans toffee. Jujubes sweet wafer marshmallow halvah jelly. Liquorice sesame snaps sweet.
|
||||
Sesame snaps pastry muffin cookie. Powder powder sweet roll toffee cake icing. Chocolate cake sweet roll gingerbread icing chupa chups sweet roll sesame snaps. Chocolate croissant chupa chups jelly beans toffee. Jujubes sweet wafer marshmallow halvah jelly. Liquorice sesame snaps sweet.
|
||||
|
||||
Tootsie roll icing jelly danish ice cream tiramisu sweet roll. Fruitcake ice cream dragée. Bear claw sugar plum sweet jelly beans bonbon dragée tart. Gingerbread chocolate sweet. Apple pie danish toffee sugar plum jelly beans donut. Chocolate cake croissant caramels chocolate bar. Jelly beans caramels toffee chocolate cake liquorice. Toffee pie sugar plum cookie toffee muffin. Marzipan marshmallow marzipan liquorice tiramisu.
|
||||
"""
|
||||
Tootsie roll icing jelly danish ice cream tiramisu sweet roll. Fruitcake ice cream dragée. Bear claw sugar plum sweet jelly beans bonbon dragée tart. Gingerbread chocolate sweet. Apple pie danish toffee sugar plum jelly beans donut. Chocolate cake croissant caramels chocolate bar. Jelly beans caramels toffee chocolate cake liquorice. Toffee pie sugar plum cookie toffee muffin. Marzipan marshmallow marzipan liquorice tiramisu."""
|
||||
|> text
|
||||
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user