noredink-ui/styleguide-app/Examples/Modal.elm

413 lines
16 KiB
Elm
Raw Normal View History

module Examples.Modal exposing (Msg, State, example, init, update, subscriptions)
2018-08-29 22:09:22 +03:00
{-|
@docs Msg, State, example, init, update, subscriptions
2018-08-29 22:09:22 +03:00
-}
2019-08-17 01:47:21 +03:00
import Accessibility.Styled as Html exposing (Html, div, h3, h4, p, span, text)
2018-08-29 22:09:22 +03:00
import Css exposing (..)
2019-06-11 04:24:09 +03:00
import Css.Global
import Html as Root
2018-08-29 22:09:22 +03:00
import Html.Styled.Attributes exposing (css)
import ModuleExample exposing (Category(..), ModuleExample)
import Nri.Ui.Button.V9 as Button
2019-06-11 00:28:38 +03:00
import Nri.Ui.Checkbox.V5 as Checkbox
import Nri.Ui.ClickableText.V3 as ClickableText
2018-08-29 22:09:22 +03:00
import Nri.Ui.Colors.V1 as Colors
2019-10-09 17:03:07 +03:00
import Nri.Ui.Modal.V8 as Modal
2019-08-17 01:47:21 +03:00
import Nri.Ui.Text.V4 as Text
2018-08-29 22:09:22 +03:00
{-| -}
type alias State =
{ infoModal : Modal.Model
, warningModal : Modal.Model
2019-06-11 00:28:38 +03:00
, visibleTitle : Bool
2019-06-11 00:53:38 +03:00
, showX : Bool
2019-06-11 03:12:35 +03:00
, showContinue : Bool
2019-06-11 04:32:54 +03:00
, showSecondary : Bool
2019-06-11 21:26:24 +03:00
, dismissOnEscAndOverlayClick : Bool
2019-08-17 01:51:00 +03:00
, longContent : Bool
2019-06-11 00:28:38 +03:00
}
{-| -}
init : State
init =
2019-06-12 21:12:37 +03:00
{ infoModal = Modal.init
, warningModal = Modal.init
2019-06-11 00:28:38 +03:00
, visibleTitle = True
2019-06-11 03:33:53 +03:00
, showX = True
, showContinue = True
2019-08-17 01:51:00 +03:00
, showSecondary = True
2019-06-11 21:26:24 +03:00
, dismissOnEscAndOverlayClick = True
2019-08-17 01:51:00 +03:00
, longContent = True
}
2018-08-29 22:09:22 +03:00
{-| -}
example : (Msg -> msg) -> State -> ModuleExample msg
example parentMessage state =
let
config =
if state.visibleTitle then
[]
else
[ Modal.invisibleTitle ]
in
2019-10-09 23:06:31 +03:00
{ name = "Nri.Ui.Modal.V8"
2018-08-29 22:09:22 +03:00
, category = Modals
, content =
2019-08-17 01:47:21 +03:00
[ viewSettings state
, Button.button "Launch Info Modal"
[ Button.onClick (InfoModalMsg (Modal.open "launch-info-modal"))
, Button.custom
[ Html.Styled.Attributes.id "launch-info-modal"
, css [ Css.marginRight (Css.px 16) ]
]
, Button.secondary
, Button.medium
]
, Button.button "Launch Warning Modal"
[ Button.onClick (WarningModalMsg (Modal.open "launch-warning-modal"))
, Button.custom [ Html.Styled.Attributes.id "launch-warning-modal" ]
, Button.secondary
, Button.medium
]
2019-10-23 14:46:00 +03:00
, let
params =
( state, InfoModalMsg, Button.primary )
2019-10-23 14:46:00 +03:00
in
Modal.info { title = "Modal.info", wrapMsg = InfoModalMsg }
config
(getFocusable params)
state.infoModal
2019-10-23 14:46:00 +03:00
, let
params =
( state, WarningModalMsg, Button.danger )
2019-10-23 14:46:00 +03:00
in
Modal.warning { title = "Modal.warning", wrapMsg = WarningModalMsg }
config
(getFocusable params)
state.warningModal
2018-08-29 22:09:22 +03:00
]
|> List.map (Html.map parentMessage)
}
getFocusable :
( State, Modal.Msg -> Msg, Button.Attribute Msg )
-> Modal.ViewFuncs Msg
-> Modal.Focusable Msg
getFocusable ( state, wrapMsg, firstButtonStyle ) { viewContent, closeButton } =
let
defaultOptions =
if state.visibleTitle then
[]
else
[ Modal.invisibleTitle ]
in
case ( state.showX, state.showContinue, state.showSecondary ) of
( True, True, True ) ->
Modal.multipleFocusableElementView
2019-10-23 19:10:05 +03:00
(\{ firstFocusableElement, autofocusElement, lastFocusableElement } ->
2019-10-23 18:02:52 +03:00
div []
2019-10-23 19:10:05 +03:00
[ closeButton firstFocusableElement
, viewContent
2019-10-23 18:02:52 +03:00
{ content = [ viewModalContent state.longContent ]
, footer =
[ Button.button "Continue"
[ firstButtonStyle
, Button.onClick ForceClose
, Button.large
2019-10-23 19:10:05 +03:00
, Button.custom [ autofocusElement ]
2019-10-14 19:22:16 +03:00
]
2019-10-23 18:02:52 +03:00
, ClickableText.button "Close"
[ ClickableText.onClick ForceClose
, ClickableText.large
, ClickableText.custom
(css [ Css.marginTop (Css.px 12) ]
2019-10-23 19:10:05 +03:00
:: lastFocusableElement
2019-10-23 18:02:52 +03:00
)
]
]
}
]
)
( True, False, True ) ->
Modal.multipleFocusableElementView
2019-10-23 19:10:05 +03:00
(\{ firstFocusableElement, autofocusElement, lastFocusableElement } ->
2019-10-23 18:02:52 +03:00
div []
2019-10-23 19:10:05 +03:00
[ closeButton firstFocusableElement
, viewContent
2019-10-23 18:02:52 +03:00
{ content = [ viewModalContent state.longContent ]
, footer =
[ ClickableText.button "Close"
[ ClickableText.onClick ForceClose
, ClickableText.large
, ClickableText.custom
(css [ Css.marginTop (Css.px 12) ]
2019-10-23 19:10:05 +03:00
:: autofocusElement
:: lastFocusableElement
2019-10-23 18:02:52 +03:00
)
2019-10-14 19:22:16 +03:00
]
2019-10-23 18:02:52 +03:00
]
}
]
)
( True, False, False ) ->
2019-10-23 19:10:05 +03:00
Modal.onlyFocusableElementView
(\onlyFocusableElement ->
2019-10-23 18:02:52 +03:00
div []
2019-10-23 19:10:05 +03:00
[ closeButton onlyFocusableElement
, viewContent
2019-10-23 18:02:52 +03:00
{ content = [ viewModalContent state.longContent ]
, footer = []
}
]
)
( True, True, False ) ->
Modal.multipleFocusableElementView
2019-10-23 19:10:05 +03:00
(\{ firstFocusableElement, autofocusElement, lastFocusableElement } ->
2019-10-23 18:02:52 +03:00
div []
2019-10-23 19:10:05 +03:00
[ closeButton firstFocusableElement
, viewContent
2019-10-23 18:02:52 +03:00
{ content = [ viewModalContent state.longContent ]
, footer =
[ Button.button "Continue"
[ firstButtonStyle
, Button.onClick ForceClose
2019-10-23 19:10:05 +03:00
, Button.custom (autofocusElement :: lastFocusableElement)
2019-10-23 18:02:52 +03:00
, Button.large
2019-10-14 19:22:16 +03:00
]
2019-10-23 18:02:52 +03:00
]
}
]
)
( False, True, True ) ->
Modal.multipleFocusableElementView
2019-10-23 19:10:05 +03:00
(\{ firstFocusableElement, autofocusElement, lastFocusableElement } ->
2019-10-23 18:02:52 +03:00
div []
[ viewContent
2019-10-23 18:02:52 +03:00
{ content = [ viewModalContent state.longContent ]
, footer =
[ Button.button "Continue"
[ firstButtonStyle
, Button.onClick ForceClose
2019-10-23 19:10:05 +03:00
, Button.custom (autofocusElement :: firstFocusableElement)
2019-10-23 18:02:52 +03:00
, Button.large
]
, ClickableText.button "Close"
[ ClickableText.onClick ForceClose
, ClickableText.large
, ClickableText.custom
(css [ Css.marginTop (Css.px 12) ]
2019-10-23 19:10:05 +03:00
:: lastFocusableElement
2019-10-23 18:02:52 +03:00
)
2019-10-14 19:22:16 +03:00
]
2019-10-23 18:02:52 +03:00
]
}
]
)
2019-06-11 03:45:21 +03:00
( False, False, True ) ->
2019-10-23 19:10:05 +03:00
Modal.onlyFocusableElementView
(\onlyFocusableElement ->
2019-10-23 18:02:52 +03:00
div []
[ viewContent
2019-10-23 18:02:52 +03:00
{ content = [ viewModalContent state.longContent ]
, footer =
[ ClickableText.button "Close"
[ ClickableText.onClick ForceClose
, ClickableText.large
, ClickableText.custom
(css [ Css.marginTop (Css.px 12) ]
2019-10-23 19:10:05 +03:00
:: onlyFocusableElement
2019-10-23 18:02:52 +03:00
)
2019-10-14 19:22:16 +03:00
]
2019-10-23 18:02:52 +03:00
]
}
]
)
( False, True, False ) ->
2019-10-23 19:10:05 +03:00
Modal.onlyFocusableElementView
(\onlyFocusableElement ->
2019-10-23 18:02:52 +03:00
div []
[ viewContent
2019-10-23 18:02:52 +03:00
{ content = [ viewModalContent state.longContent ]
, footer =
[ Button.button "Continue"
[ firstButtonStyle
, Button.onClick ForceClose
2019-10-23 19:10:05 +03:00
, Button.custom onlyFocusableElement
2019-10-23 18:02:52 +03:00
, Button.large
2019-10-14 19:22:16 +03:00
]
2019-10-23 18:02:52 +03:00
]
}
]
)
( False, False, False ) ->
2019-10-23 19:10:05 +03:00
Modal.onlyFocusableElementView
(\_ ->
2019-10-23 18:02:52 +03:00
div []
[ viewContent
2019-10-23 18:02:52 +03:00
{ content = [ viewModalContent state.longContent ]
, footer = []
}
]
)
2019-06-11 03:52:19 +03:00
2019-08-17 01:51:00 +03:00
viewModalContent : Bool -> Html msg
viewModalContent longContent =
2019-08-17 01:47:21 +03:00
Text.mediumBody
[ span [ css [ whiteSpace preLine ] ]
2019-08-17 01:51:00 +03:00
[ if longContent then
2019-10-11 20:24:21 +03:00
"""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.
2019-08-17 01:47:21 +03:00
2019-10-11 20:24:21 +03:00
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.
2019-08-17 01:47:21 +03:00
2019-10-11 20:24:21 +03:00
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."""
2019-08-17 01:51:00 +03:00
|> text
else
"Ice cream tootsie roll donut sweet cookie liquorice sweet donut. Sugar plum danish apple pie sesame snaps chocolate bar biscuit. Caramels macaroon jelly gummies sweet tootsie roll tiramisu apple pie. Dessert chocolate bar lemon drops dragée jelly powder cheesecake chocolate."
|> text
2019-08-17 01:47:21 +03:00
]
]
2019-06-11 03:52:19 +03:00
viewSettings : State -> Html Msg
viewSettings state =
div []
[ Checkbox.viewWithLabel
{ identifier = "visible-title"
, label = "Visible title"
, selected = Checkbox.selectedFromBool state.visibleTitle
, setterMsg = SetVisibleTitle
, disabled = False
, theme = Checkbox.Square
}
, Checkbox.viewWithLabel
{ identifier = "show-x"
, label = "Show X button"
, selected = Checkbox.selectedFromBool state.showX
, setterMsg = SetShowX
, disabled = False
, theme = Checkbox.Square
}
, Checkbox.viewWithLabel
{ identifier = "show-continue"
, label = "Show main button"
, selected = Checkbox.selectedFromBool state.showContinue
, setterMsg = SetShowContinue
, disabled = False
, theme = Checkbox.Square
}
2019-06-11 04:32:54 +03:00
, Checkbox.viewWithLabel
{ identifier = "show-secondary"
, label = "Show secondary button"
, selected = Checkbox.selectedFromBool state.showSecondary
, setterMsg = SetShowSecondary
, disabled = False
, theme = Checkbox.Square
}
2019-06-12 21:12:37 +03:00
, Checkbox.viewWithLabel
{ identifier = "dismiss-on-click"
, label = "Dismiss on ESC and on backdrop click"
, selected = Checkbox.selectedFromBool state.dismissOnEscAndOverlayClick
, setterMsg = SetDismissOnEscAndOverlayClick
, disabled = False
, theme = Checkbox.Square
}
2019-08-17 01:51:00 +03:00
, Checkbox.viewWithLabel
{ identifier = "long-content"
, label = "Display longer content"
, selected = Checkbox.selectedFromBool state.longContent
, setterMsg = SetLongContent
, disabled = False
, theme = Checkbox.Square
}
2019-06-11 03:52:19 +03:00
]
2019-06-11 03:45:21 +03:00
2018-08-29 22:09:22 +03:00
{-| -}
2019-06-11 00:28:38 +03:00
type Msg
= InfoModalMsg Modal.Msg
| WarningModalMsg Modal.Msg
2019-06-11 03:12:35 +03:00
| ForceClose
2019-06-11 00:28:38 +03:00
| SetVisibleTitle Bool
2019-06-11 00:53:38 +03:00
| SetShowX Bool
2019-06-11 03:12:35 +03:00
| SetShowContinue Bool
2019-06-11 04:32:54 +03:00
| SetShowSecondary Bool
2019-06-11 21:26:24 +03:00
| SetDismissOnEscAndOverlayClick Bool
2019-08-17 01:51:00 +03:00
| SetLongContent Bool
2018-08-29 22:09:22 +03:00
{-| -}
update : Msg -> State -> ( State, Cmd Msg )
update msg state =
2019-06-12 21:12:37 +03:00
let
updateConfig =
{ dismissOnEscAndOverlayClick = state.dismissOnEscAndOverlayClick }
in
2018-08-29 22:09:22 +03:00
case msg of
InfoModalMsg modalMsg ->
2019-06-12 21:12:37 +03:00
case Modal.update updateConfig modalMsg state.infoModal of
( newState, cmds ) ->
( { state | infoModal = newState }
, Cmd.map InfoModalMsg cmds
)
WarningModalMsg modalMsg ->
2019-06-12 21:12:37 +03:00
case Modal.update updateConfig modalMsg state.warningModal of
( newState, cmds ) ->
( { state | warningModal = newState }
, Cmd.map WarningModalMsg cmds
)
2018-08-29 22:09:22 +03:00
2019-06-11 03:12:35 +03:00
ForceClose ->
( { state
2019-06-12 21:12:37 +03:00
| infoModal = Modal.init
, warningModal = Modal.init
2019-06-11 03:12:35 +03:00
}
, Cmd.none
)
2019-06-11 00:28:38 +03:00
SetVisibleTitle value ->
( { state | visibleTitle = value }, Cmd.none )
2019-06-11 00:53:38 +03:00
SetShowX value ->
( { state | showX = value }, Cmd.none )
2019-06-11 03:12:35 +03:00
SetShowContinue value ->
( { state | showContinue = value }, Cmd.none )
2019-06-11 04:32:54 +03:00
SetShowSecondary value ->
( { state | showSecondary = value }, Cmd.none )
2019-06-11 21:26:24 +03:00
SetDismissOnEscAndOverlayClick value ->
2019-06-12 21:12:37 +03:00
( { state | dismissOnEscAndOverlayClick = value }, Cmd.none )
2019-06-11 21:26:24 +03:00
2019-08-17 01:51:00 +03:00
SetLongContent value ->
( { state | longContent = value }, Cmd.none )
2018-08-29 22:09:22 +03:00
{-| -}
subscriptions : State -> Sub Msg
subscriptions model =
Sub.batch
[ Sub.map InfoModalMsg (Modal.subscriptions model.infoModal)
, Sub.map WarningModalMsg (Modal.subscriptions model.warningModal)
]