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

422 lines
17 KiB
Elm
Raw Normal View History

2020-03-31 22:43:32 +03:00
module Examples.Modal exposing (Msg, State, example)
2018-08-29 22:09:22 +03:00
{-|
2020-03-31 22:43:32 +03:00
@docs Msg, State, example
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)
2020-06-19 23:41:28 +03:00
import AtomicDesignType exposing (AtomicDesignType(..))
import Category exposing (Category(..))
2018-08-29 22:09:22 +03:00
import Css exposing (..)
2019-06-11 04:24:09 +03:00
import Css.Global
2020-03-31 23:20:03 +03:00
import Example exposing (Example)
import Html as Root
import Html.Styled.Attributes as Attributes
import KeyboardSupport exposing (Direction(..), Key(..))
2020-01-29 04:10:20 +03:00
import Nri.Ui.Button.V10 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
import Nri.Ui.Modal.V10 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 =
2020-07-03 01:09:07 +03:00
{ state : Modal.Model
, content : Content
, settings : Settings
}
{-| -}
init : State
init =
{ state = Modal.init
, content = Info
, settings = initModalSettings
}
type Content
= Info
| Warning
type alias Settings =
{ 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
, customStyling : Bool
2019-06-11 00:28:38 +03:00
}
2020-07-03 01:09:07 +03:00
initModalSettings : Settings
initModalSettings =
{ 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
, customStyling = False
}
2018-08-29 22:09:22 +03:00
{-| -}
2020-03-31 23:20:03 +03:00
example : Example State Msg
2020-03-31 22:43:32 +03:00
example =
2020-08-19 00:00:44 +03:00
{ name = "Nri.Ui.Modal.V10"
2020-03-31 22:43:32 +03:00
, categories = [ Modals ]
2020-06-20 00:16:10 +03:00
, atomicDesignType = Organism
, keyboardSupport = []
2020-03-31 22:43:32 +03:00
, state = init
, update = update
2020-03-31 22:48:26 +03:00
, subscriptions = subscriptions
2020-03-31 22:43:32 +03:00
, view =
\state ->
let
titleAttrs =
if state.settings.visibleTitle then
[]
else
[ Modal.hideTitle ]
stylingAttrs =
if state.settings.customStyling then
[ Modal.css
[ Css.borderRadius Css.zero
, Css.width (Css.px 800)
]
]
else
[]
attrs =
titleAttrs ++ stylingAttrs
in
2020-07-03 01:09:07 +03:00
[ viewSettings state.settings
2020-03-31 22:43:32 +03:00
, Button.button "Launch Info Modal"
2020-07-03 01:33:51 +03:00
[ Button.onClick (OpenModal Info "launch-info-modal")
2020-03-31 22:43:32 +03:00
, Button.custom [ Attributes.id "launch-info-modal" ]
, Button.css [ Css.marginRight (Css.px 16) ]
, Button.secondary
, Button.medium
]
, Button.button "Launch Warning Modal"
2020-07-03 01:33:51 +03:00
[ Button.onClick (OpenModal Warning "launch-warning-modal")
2020-03-31 22:43:32 +03:00
, Button.custom [ Attributes.id "launch-warning-modal" ]
, Button.secondary
, Button.medium
]
2020-07-03 01:09:07 +03:00
, case state.content of
Info ->
Modal.info
{ title = "Modal.info"
, wrapMsg = ModalMsg
, focusManager = makeFocusManager Button.primary state.settings
}
attrs
2020-07-03 01:09:07 +03:00
state.state
Warning ->
Modal.warning
{ title = "Modal.warning"
, wrapMsg = ModalMsg
, focusManager = makeFocusManager Button.danger state.settings
}
attrs
2020-07-03 01:09:07 +03:00
state.state
]
2018-08-29 22:09:22 +03:00
}
2020-07-03 01:09:07 +03:00
makeFocusManager : Button.Attribute Msg -> Settings -> Modal.FocusManager Msg
makeFocusManager firstButtonStyle settings =
case ( settings.showX, settings.showContinue, settings.showSecondary ) of
( True, True, True ) ->
2020-07-03 01:09:07 +03:00
Modal.MultipleFocusableElements <|
\modalOptions ->
{ content =
[ modalOptions.closeButton modalOptions.firstFocusableElement
, viewModalContent settings.longContent
2019-10-23 18:02:52 +03:00
]
2020-07-03 01:09:07 +03:00
, footer =
[ Button.button "Continue"
[ firstButtonStyle
, Button.onClick ForceClose
, Button.large
, Button.custom [ modalOptions.autofocusElement ]
]
, ClickableText.button "Close"
[ ClickableText.onClick ForceClose
, ClickableText.large
, ClickableText.custom modalOptions.lastFocusableElement
, ClickableText.css [ Css.marginTop (Css.px 12) ]
]
]
}
( True, False, True ) ->
2020-07-03 01:09:07 +03:00
Modal.MultipleFocusableElements <|
\modalOptions ->
{ content =
[ modalOptions.closeButton modalOptions.firstFocusableElement
, viewModalContent settings.longContent
2019-10-23 18:02:52 +03:00
]
2020-07-03 01:09:07 +03:00
, footer =
[ ClickableText.button "Close"
[ ClickableText.onClick ForceClose
, ClickableText.large
, ClickableText.custom (modalOptions.autofocusElement :: modalOptions.lastFocusableElement)
, ClickableText.css [ Css.marginTop (Css.px 12) ]
]
]
}
( True, False, False ) ->
2020-07-03 01:09:07 +03:00
Modal.OneFocusableElement
(\{ onlyFocusableElement, closeButton } ->
{ content =
2019-10-23 19:10:05 +03:00
[ closeButton onlyFocusableElement
2020-07-03 01:09:07 +03:00
, viewModalContent settings.longContent
2019-10-23 18:02:52 +03:00
]
2020-07-03 01:09:07 +03:00
, footer = []
}
2019-10-23 18:02:52 +03:00
)
( True, True, False ) ->
2020-07-03 01:09:07 +03:00
Modal.MultipleFocusableElements <|
\modalOptions ->
{ content =
[ modalOptions.closeButton modalOptions.firstFocusableElement
, viewModalContent settings.longContent
2019-10-23 18:02:52 +03:00
]
2020-07-03 01:09:07 +03:00
, footer =
[ Button.button "Continue"
[ firstButtonStyle
, Button.onClick ForceClose
, Button.custom (modalOptions.autofocusElement :: modalOptions.lastFocusableElement)
, Button.large
]
]
}
( False, True, True ) ->
2020-07-03 01:09:07 +03:00
Modal.MultipleFocusableElements <|
\modalOptions ->
{ content = [ viewModalContent settings.longContent ]
, footer =
[ Button.button "Continue"
[ firstButtonStyle
, Button.onClick ForceClose
, Button.custom (modalOptions.autofocusElement :: modalOptions.firstFocusableElement)
, Button.large
]
, ClickableText.button "Close"
[ ClickableText.onClick ForceClose
, ClickableText.large
, ClickableText.custom modalOptions.lastFocusableElement
, ClickableText.css [ Css.marginTop (Css.px 12) ]
]
2019-10-23 18:02:52 +03:00
]
2020-07-03 01:09:07 +03:00
}
2019-06-11 03:45:21 +03:00
( False, False, True ) ->
2020-07-03 01:09:07 +03:00
Modal.OneFocusableElement
(\{ onlyFocusableElement } ->
2020-07-03 01:09:07 +03:00
{ content = [ viewModalContent settings.longContent ]
, footer =
[ ClickableText.button "Close"
[ ClickableText.onClick ForceClose
, ClickableText.large
, ClickableText.custom onlyFocusableElement
, ClickableText.css [ Css.marginTop (Css.px 12) ]
]
2019-10-23 18:02:52 +03:00
]
2020-07-03 01:09:07 +03:00
}
2019-10-23 18:02:52 +03:00
)
( False, True, False ) ->
2020-07-03 01:09:07 +03:00
Modal.OneFocusableElement
(\{ onlyFocusableElement } ->
2020-07-03 01:09:07 +03:00
{ content = [ viewModalContent settings.longContent ]
, footer =
[ Button.button "Continue"
[ firstButtonStyle
, Button.onClick ForceClose
, Button.custom onlyFocusableElement
, Button.large
]
2019-10-23 18:02:52 +03:00
]
2020-07-03 01:09:07 +03:00
}
2019-10-23 18:02:52 +03:00
)
( False, False, False ) ->
2020-07-03 01:09:07 +03:00
Modal.OneFocusableElement
2019-10-23 19:10:05 +03:00
(\_ ->
2020-07-03 01:09:07 +03:00
{ content = [ viewModalContent settings.longContent ]
, footer = []
}
2019-10-23 18:02:52 +03:00
)
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 [ Attributes.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-11-12 18:50:04 +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.
Brownie ice cream halvah danish candy ice cream sweet roll jujubes chocolate cake. Chocolate bar sesame snaps bear claw gummies. Dragée cookie brownie cake sugar plum chocolate cake fruitcake toffee. Tiramisu tiramisu cookie cake. Lemon drops pie toffee icing powder biscuit cotton candy gummies. Caramels lemon drops cupcake. Lemon drops toffee macaroon liquorice chocolate bar candy bonbon. Cupcake biscuit cupcake chupa chups candy. Chocolate cake sweet toffee bonbon danish biscuit pudding. Tootsie roll brownie jelly tootsie roll. Jujubes jujubes marshmallow gummi bears bear claw sugar plum. Cupcake bonbon soufflé carrot cake powder fruitcake sugar plum brownie.
Danish sesame snaps tiramisu chocolate cake powder cotton candy powder. Liquorice cupcake macaroon sweet soufflé jujubes. Jelly-o oat cake caramels sweet roll. Sweet roll sugar plum gummies cheesecake sesame snaps. Gummies pastry tootsie roll marzipan lollipop muffin sweet cake. Wafer carrot cake halvah bear claw jelly beans apple pie cookie halvah. Brownie sugar plum macaroon halvah croissant pastry. Marzipan muffin carrot cake chocolate jelly beans dragée jelly beans dragée tiramisu. Sweet roll powder apple pie icing halvah marshmallow pastry. Pastry marzipan chocolate cake jelly beans sugar plum carrot cake lollipop croissant. Cotton candy chocolate croissant gummies muffin. Dragée jelly beans oat cake pastry muffin pie. Donut marzipan dessert wafer gingerbread tiramisu macaroon. Cotton candy macaroon gummies oat cake cake gingerbread cotton candy sweet roll pie."""
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
]
]
2020-07-03 01:09:07 +03:00
viewSettings : Settings -> Html Msg
viewSettings settings =
2019-06-11 03:52:19 +03:00
div []
[ Checkbox.viewWithLabel
{ identifier = "visible-title"
, label = "Visible title"
2020-07-03 01:09:07 +03:00
, selected = Checkbox.selectedFromBool settings.visibleTitle
2019-06-11 03:52:19 +03:00
, setterMsg = SetVisibleTitle
, disabled = False
, theme = Checkbox.Square
}
, Checkbox.viewWithLabel
{ identifier = "show-x"
, label = "Show X button"
2020-07-03 01:09:07 +03:00
, selected = Checkbox.selectedFromBool settings.showX
2019-06-11 03:52:19 +03:00
, setterMsg = SetShowX
, disabled = False
, theme = Checkbox.Square
}
, Checkbox.viewWithLabel
{ identifier = "show-continue"
, label = "Show main button"
2020-07-03 01:09:07 +03:00
, selected = Checkbox.selectedFromBool settings.showContinue
2019-06-11 03:52:19 +03:00
, setterMsg = SetShowContinue
, disabled = False
, theme = Checkbox.Square
}
2019-06-11 04:32:54 +03:00
, Checkbox.viewWithLabel
{ identifier = "show-secondary"
, label = "Show secondary button"
2020-07-03 01:09:07 +03:00
, selected = Checkbox.selectedFromBool settings.showSecondary
2019-06-11 04:32:54 +03:00
, 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"
2020-07-03 01:09:07 +03:00
, selected = Checkbox.selectedFromBool settings.dismissOnEscAndOverlayClick
2019-06-12 21:12:37 +03:00
, setterMsg = SetDismissOnEscAndOverlayClick
, disabled = False
, theme = Checkbox.Square
}
2019-08-17 01:51:00 +03:00
, Checkbox.viewWithLabel
{ identifier = "long-content"
, label = "Display longer content"
2020-07-03 01:09:07 +03:00
, selected = Checkbox.selectedFromBool settings.longContent
2019-08-17 01:51:00 +03:00
, setterMsg = SetLongContent
, disabled = False
, theme = Checkbox.Square
}
, Checkbox.viewWithLabel
{ identifier = "custom-styles"
, label = "Custom Styling"
, selected = Checkbox.selectedFromBool settings.customStyling
, setterMsg = SetCustomStyling
, 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
2020-07-03 01:33:51 +03:00
= OpenModal Content String
| ModalMsg 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
| SetCustomStyling 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
2020-07-03 01:09:07 +03:00
settings =
state.settings
2019-06-12 21:12:37 +03:00
updateConfig =
2020-07-03 01:09:07 +03:00
{ dismissOnEscAndOverlayClick = settings.dismissOnEscAndOverlayClick }
2019-06-12 21:12:37 +03:00
in
2018-08-29 22:09:22 +03:00
case msg of
2020-07-03 01:33:51 +03:00
OpenModal content returnFocusTo ->
update (ModalMsg (Modal.open returnFocusTo)) { state | content = content }
2020-07-03 01:09:07 +03:00
ModalMsg modalMsg ->
case Modal.update updateConfig modalMsg state.state of
( newState, cmds ) ->
2020-07-03 01:09:07 +03:00
( { state | state = newState }
, Cmd.map ModalMsg cmds
)
2018-08-29 22:09:22 +03:00
2019-06-11 03:12:35 +03:00
ForceClose ->
2020-07-03 01:09:07 +03:00
( { state | state = Modal.init }
2019-06-11 03:12:35 +03:00
, Cmd.none
)
2019-06-11 00:28:38 +03:00
SetVisibleTitle value ->
2020-07-03 01:09:07 +03:00
( { state | settings = { settings | visibleTitle = value } }, Cmd.none )
2019-06-11 00:28:38 +03:00
2019-06-11 00:53:38 +03:00
SetShowX value ->
2020-07-03 01:09:07 +03:00
( { state | settings = { settings | showX = value } }, Cmd.none )
2019-06-11 00:53:38 +03:00
2019-06-11 03:12:35 +03:00
SetShowContinue value ->
2020-07-03 01:09:07 +03:00
( { state | settings = { settings | showContinue = value } }, Cmd.none )
2019-06-11 03:12:35 +03:00
2019-06-11 04:32:54 +03:00
SetShowSecondary value ->
2020-07-03 01:09:07 +03:00
( { state | settings = { settings | showSecondary = value } }, Cmd.none )
2019-06-11 04:32:54 +03:00
2019-06-11 21:26:24 +03:00
SetDismissOnEscAndOverlayClick value ->
2020-07-03 01:09:07 +03:00
( { state | settings = { settings | dismissOnEscAndOverlayClick = value } }, Cmd.none )
2019-06-11 21:26:24 +03:00
2019-08-17 01:51:00 +03:00
SetLongContent value ->
2020-07-03 01:09:07 +03:00
( { state | settings = { settings | longContent = value } }, Cmd.none )
2019-08-17 01:51:00 +03:00
SetCustomStyling value ->
( { state | settings = { settings | customStyling = value } }, Cmd.none )
2018-08-29 22:09:22 +03:00
{-| -}
subscriptions : State -> Sub Msg
subscriptions model =
2020-07-03 01:09:07 +03:00
Sub.map ModalMsg (Modal.subscriptions model.state)