mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2025-01-04 12:47:53 +03:00
Update modal to take advantage of the new button API
This commit is contained in:
parent
0c6e191a1d
commit
1fcca16f12
@ -1,10 +1,10 @@
|
||||
module Nri.Ui.Modal.V6 exposing
|
||||
( Model, init
|
||||
, Msg, update, subscriptions
|
||||
, open, close
|
||||
, info, warning, FocusableElementAttrs
|
||||
, viewContent, viewFooter
|
||||
, launchButton, closeButton
|
||||
, primaryButton, secondaryButton, dangerButton
|
||||
, closeButton
|
||||
)
|
||||
|
||||
{-| Changes from V4:
|
||||
@ -15,6 +15,7 @@ module Nri.Ui.Modal.V6 exposing
|
||||
These changes have required major API changes. Be sure to wire up subscriptions!
|
||||
|
||||
import Html.Styled exposing (..)
|
||||
import Nri.Ui.Button.V9 as Button
|
||||
import Nri.Ui.Modal.V6 as Modal
|
||||
|
||||
view : Modal.State -> Html Msg
|
||||
@ -27,7 +28,11 @@ These changes have required major API changes. Be sure to wire up subscriptions!
|
||||
div []
|
||||
[ Modal.viewContent [ text "Content goes here!" ]
|
||||
, Modal.viewFooter
|
||||
[ Modal.primaryButton DoSomething "Continue" onlyFocusableElement
|
||||
[ Button.button "Continue"
|
||||
[ Button.primary
|
||||
, Button.onClick DoSomthing
|
||||
, Button.custom onlyFocusableElement
|
||||
]
|
||||
, text "`onlyFocusableElement` will trap the focus on the 'Continue' button."
|
||||
]
|
||||
]
|
||||
@ -44,6 +49,8 @@ These changes have required major API changes. Be sure to wire up subscriptions!
|
||||
@docs Model, init
|
||||
@docs Msg, update, subscriptions
|
||||
|
||||
@docs open, close
|
||||
|
||||
|
||||
## Views
|
||||
|
||||
@ -58,10 +65,9 @@ These changes have required major API changes. Be sure to wire up subscriptions!
|
||||
@docs viewContent, viewFooter
|
||||
|
||||
|
||||
### Buttons
|
||||
## X icon
|
||||
|
||||
@docs launchButton, closeButton
|
||||
@docs primaryButton, secondaryButton, dangerButton
|
||||
@docs closeButton
|
||||
|
||||
-}
|
||||
|
||||
@ -114,49 +120,77 @@ 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
|
||||
|
||||
|
||||
{-| -}
|
||||
type alias FocusableElementAttrs msg =
|
||||
{ onlyFocusableElement : List (Root.Attribute msg)
|
||||
, firstFocusableElement : List (Root.Attribute msg)
|
||||
, lastFocusableElement : List (Root.Attribute msg)
|
||||
{ onlyFocusableElement : List (Attribute msg)
|
||||
, firstFocusableElement : List (Attribute msg)
|
||||
, lastFocusableElement : List (Attribute msg)
|
||||
}
|
||||
|
||||
|
||||
{-| -}
|
||||
info :
|
||||
{ title : { visibleTitle : Bool, title : String }
|
||||
{ visibleTitle : Bool
|
||||
, title : String
|
||||
, content : FocusableElementAttrs msg -> Html msg
|
||||
, wrapMsg : Msg -> msg
|
||||
}
|
||||
-> Model
|
||||
-> Html msg
|
||||
info config model =
|
||||
Modal.view
|
||||
{ overlayColor = toOverlayColor Colors.navy
|
||||
, wrapMsg = config.wrapMsg
|
||||
, modalAttributes = modalStyles
|
||||
, title = viewTitle Colors.navy config.title
|
||||
, content = config.content >> toUnstyled
|
||||
}
|
||||
model
|
||||
|> fromUnstyled
|
||||
view { overlayColor = Colors.navy, titleColor = Colors.navy } config model
|
||||
|
||||
|
||||
{-| -}
|
||||
warning :
|
||||
{ title : { visibleTitle : Bool, title : String }
|
||||
{ visibleTitle : Bool
|
||||
, title : String
|
||||
, content : FocusableElementAttrs msg -> Html msg
|
||||
, wrapMsg : Msg -> msg
|
||||
}
|
||||
-> Model
|
||||
-> Html msg
|
||||
warning config model =
|
||||
view { overlayColor = Colors.gray20, titleColor = Colors.red } config model
|
||||
|
||||
|
||||
view :
|
||||
{ overlayColor : Css.Color, titleColor : Css.Color }
|
||||
->
|
||||
{ visibleTitle : Bool
|
||||
, title : String
|
||||
, content : FocusableElementAttrs msg -> Html msg
|
||||
, wrapMsg : Msg -> msg
|
||||
}
|
||||
-> Model
|
||||
-> Html msg
|
||||
view { overlayColor, titleColor } config model =
|
||||
Modal.view
|
||||
{ overlayColor = toOverlayColor Colors.gray20
|
||||
{ overlayColor = toOverlayColor overlayColor
|
||||
, wrapMsg = config.wrapMsg
|
||||
, modalAttributes = modalStyles
|
||||
, title = viewTitle Colors.red config.title
|
||||
, content = config.content >> toUnstyled
|
||||
, title = viewTitle titleColor { title = config.title, visibleTitle = config.visibleTitle }
|
||||
, content =
|
||||
\{ onlyFocusableElement, firstFocusableElement, lastFocusableElement } ->
|
||||
{ onlyFocusableElement = List.map Html.Styled.Attributes.fromUnstyled onlyFocusableElement
|
||||
, firstFocusableElement = List.map Html.Styled.Attributes.fromUnstyled firstFocusableElement
|
||||
, lastFocusableElement = List.map Html.Styled.Attributes.fromUnstyled lastFocusableElement
|
||||
}
|
||||
|> config.content
|
||||
|> toUnstyled
|
||||
}
|
||||
model
|
||||
|> fromUnstyled
|
||||
@ -238,18 +272,7 @@ viewFooter =
|
||||
|
||||
|
||||
{-| -}
|
||||
launchButton : (Msg -> msg) -> List Css.Style -> String -> Html msg
|
||||
launchButton wrapMsg styles label =
|
||||
button
|
||||
(css styles
|
||||
:: List.map Html.Styled.Attributes.fromUnstyled
|
||||
(Modal.openOnClick wrapMsg (String.replace " " "-" label))
|
||||
)
|
||||
[ text label ]
|
||||
|
||||
|
||||
{-| -}
|
||||
closeButton : (Msg -> msg) -> List (Root.Attribute msg) -> Html msg
|
||||
closeButton : (Msg -> msg) -> List (Attribute msg) -> Html msg
|
||||
closeButton wrapMsg focusableElementAttrs =
|
||||
Nri.Ui.styled button
|
||||
"close-button-container"
|
||||
@ -267,155 +290,7 @@ closeButton wrapMsg focusableElementAttrs =
|
||||
]
|
||||
(Widget.label "Close modal"
|
||||
:: Html.Styled.Attributes.map wrapMsg (onClick Modal.close)
|
||||
:: List.map Html.Styled.Attributes.fromUnstyled focusableElementAttrs
|
||||
:: focusableElementAttrs
|
||||
)
|
||||
[ Nri.Ui.Svg.V1.toHtml Nri.Ui.SpriteSheet.xSvg
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
primaryButton : msg -> String -> List (Root.Attribute msg) -> Html msg
|
||||
primaryButton msg label focusableElementAttrs =
|
||||
Nri.Ui.styled button
|
||||
"modal__primary-button"
|
||||
[ buttonStyle, colorStyle PrimaryColors, sizeStyle ]
|
||||
(onClick msg :: List.map Html.Styled.Attributes.fromUnstyled focusableElementAttrs)
|
||||
[ text label ]
|
||||
|
||||
|
||||
{-| -}
|
||||
secondaryButton : msg -> String -> List (Root.Attribute msg) -> Html msg
|
||||
secondaryButton msg label focusableElementAttrs =
|
||||
Nri.Ui.styled button
|
||||
"modal__secondary-button"
|
||||
[ buttonStyle
|
||||
, colorStyle SecondaryColors
|
||||
, Css.fontSize (Css.px 20)
|
||||
, Css.marginTop (Css.px 30)
|
||||
]
|
||||
(onClick msg :: List.map Html.Styled.Attributes.fromUnstyled focusableElementAttrs)
|
||||
[ text label ]
|
||||
|
||||
|
||||
{-| -}
|
||||
dangerButton : msg -> String -> List (Root.Attribute msg) -> Html msg
|
||||
dangerButton msg label focusableElementAttrs =
|
||||
Nri.Ui.styled button
|
||||
"modal__warning-button"
|
||||
[ buttonStyle, colorStyle DangerColors, sizeStyle ]
|
||||
(onClick msg :: List.map Html.Styled.Attributes.fromUnstyled focusableElementAttrs)
|
||||
[ text label ]
|
||||
|
||||
|
||||
buttonStyle : Css.Style
|
||||
buttonStyle =
|
||||
Css.batch
|
||||
[ Css.cursor Css.pointer
|
||||
, -- Specifying the font can and should go away after bootstrap is removed from application.css
|
||||
Fonts.baseFont
|
||||
, Css.textOverflow Css.ellipsis
|
||||
, Css.overflow Css.hidden
|
||||
, Css.textDecoration Css.none
|
||||
, Css.backgroundImage Css.none
|
||||
, Css.textShadow Css.none
|
||||
, Css.property "transition" "background-color 0.2s, color 0.2s, box-shadow 0.2s, border 0.2s, border-width 0s"
|
||||
, Css.boxShadow Css.none
|
||||
, Css.border Css.zero
|
||||
, Css.marginBottom Css.zero
|
||||
, Css.hover [ Css.textDecoration Css.none ]
|
||||
, Css.display Css.inlineFlex
|
||||
, Css.alignItems Css.center
|
||||
, Css.justifyContent Css.center
|
||||
]
|
||||
|
||||
|
||||
type ColorPalette
|
||||
= PrimaryColors
|
||||
| SecondaryColors
|
||||
| DangerColors
|
||||
|
||||
|
||||
colorStyle : ColorPalette -> Css.Style
|
||||
colorStyle colorPalette =
|
||||
let
|
||||
config =
|
||||
case colorPalette of
|
||||
PrimaryColors ->
|
||||
{ background = Colors.azure
|
||||
, hover = Colors.azureDark
|
||||
, text = Colors.white
|
||||
, shadow = Colors.azureDark
|
||||
}
|
||||
|
||||
SecondaryColors ->
|
||||
{ background = Colors.white
|
||||
, hover = Colors.white
|
||||
, text = Colors.azure
|
||||
, shadow = Colors.white
|
||||
}
|
||||
|
||||
DangerColors ->
|
||||
{ background = Colors.red
|
||||
, hover = Colors.redDark
|
||||
, text = Colors.white
|
||||
, shadow = Colors.redDark
|
||||
}
|
||||
in
|
||||
Css.batch
|
||||
[ Css.color config.text
|
||||
, Css.backgroundColor config.background
|
||||
, Css.fontWeight (Css.int 700)
|
||||
, Css.textAlign Css.center
|
||||
, Css.borderStyle Css.none
|
||||
, Css.borderBottomStyle Css.solid
|
||||
, Css.borderBottomColor config.shadow
|
||||
, Css.fontStyle Css.normal
|
||||
, Css.hover
|
||||
[ Css.color config.text
|
||||
, Css.backgroundColor config.hover
|
||||
, Css.disabled [ Css.backgroundColor config.background ]
|
||||
]
|
||||
, Css.visited [ Css.color config.text ]
|
||||
]
|
||||
|
||||
|
||||
sizeStyle : Css.Style
|
||||
sizeStyle =
|
||||
let
|
||||
config =
|
||||
{ fontSize = 20
|
||||
, height = 56
|
||||
, imageHeight = 20
|
||||
, shadowHeight = 4
|
||||
, minWidth = 200
|
||||
}
|
||||
|
||||
sizingAttributes =
|
||||
let
|
||||
verticalPaddingPx =
|
||||
2
|
||||
in
|
||||
[ Css.minHeight (Css.px config.height)
|
||||
, Css.paddingTop (Css.px verticalPaddingPx)
|
||||
, Css.paddingBottom (Css.px verticalPaddingPx)
|
||||
]
|
||||
|
||||
widthAttributes =
|
||||
[ Css.paddingLeft (Css.px 16)
|
||||
, Css.paddingRight (Css.px 16)
|
||||
, Css.minWidth (Css.px 230)
|
||||
]
|
||||
|
||||
lineHeightPx =
|
||||
22
|
||||
in
|
||||
Css.batch
|
||||
[ Css.fontSize (Css.px config.fontSize)
|
||||
, Css.borderRadius (Css.px 8)
|
||||
, Css.lineHeight (Css.px lineHeightPx)
|
||||
, Css.boxSizing Css.borderBox
|
||||
, Css.borderWidth (Css.px 1)
|
||||
, Css.borderBottomWidth (Css.px config.shadowHeight)
|
||||
, Css.batch sizingAttributes
|
||||
, Css.batch widthAttributes
|
||||
]
|
||||
|
@ -12,6 +12,7 @@ import Css.Global
|
||||
import Html as Root
|
||||
import Html.Styled.Attributes exposing (css)
|
||||
import ModuleExample exposing (Category(..), ModuleExample)
|
||||
import Nri.Ui.Button.V9 as Button
|
||||
import Nri.Ui.Checkbox.V5 as Checkbox
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Modal.V6 as Modal
|
||||
@ -48,26 +49,41 @@ example parentMessage state =
|
||||
{ name = "Nri.Ui.Modal.V6"
|
||||
, category = Modals
|
||||
, content =
|
||||
[ Modal.launchButton InfoModalMsg [] "Launch Info Modal"
|
||||
, Modal.launchButton WarningModalMsg [] "Launch Warning Modal"
|
||||
[ 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
|
||||
]
|
||||
, Modal.info
|
||||
{ title = { title = "Modal.info", visibleTitle = state.visibleTitle }
|
||||
{ title = "Modal.info"
|
||||
, visibleTitle = state.visibleTitle
|
||||
, wrapMsg = InfoModalMsg
|
||||
, content =
|
||||
viewContent state
|
||||
InfoModalMsg
|
||||
(Modal.primaryButton ForceClose "Continue")
|
||||
(Modal.secondaryButton ForceClose "Close")
|
||||
Button.primary
|
||||
Button.secondary
|
||||
}
|
||||
state.infoModal
|
||||
, Modal.warning
|
||||
{ title = { title = "Modal.warning", visibleTitle = state.visibleTitle }
|
||||
{ title = "Modal.warning"
|
||||
, visibleTitle = state.visibleTitle
|
||||
, wrapMsg = WarningModalMsg
|
||||
, content =
|
||||
viewContent state
|
||||
WarningModalMsg
|
||||
(Modal.dangerButton ForceClose "Continue")
|
||||
(Modal.secondaryButton ForceClose "Close")
|
||||
Button.danger
|
||||
Button.secondary
|
||||
}
|
||||
state.warningModal
|
||||
]
|
||||
@ -78,11 +94,11 @@ example parentMessage state =
|
||||
viewContent :
|
||||
State
|
||||
-> (Modal.Msg -> Msg)
|
||||
-> (List (Root.Attribute Msg) -> Html Msg)
|
||||
-> (List (Root.Attribute Msg) -> Html Msg)
|
||||
-> Button.Attribute Msg
|
||||
-> Button.Attribute Msg
|
||||
-> Modal.FocusableElementAttrs Msg
|
||||
-> Html Msg
|
||||
viewContent state wrapMsg primaryButton secondaryButton focusableElementAttrs =
|
||||
viewContent state wrapMsg firstButtonStyle secondButtonStyle focusableElementAttrs =
|
||||
div []
|
||||
[ if state.showX then
|
||||
Modal.closeButton wrapMsg focusableElementAttrs.firstFocusableElement
|
||||
@ -92,18 +108,33 @@ viewContent state wrapMsg primaryButton secondaryButton focusableElementAttrs =
|
||||
, Modal.viewContent [ viewSettings state ]
|
||||
, if state.showContinue && state.showSecondary then
|
||||
Modal.viewFooter
|
||||
[ primaryButton []
|
||||
, secondaryButton focusableElementAttrs.lastFocusableElement
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
]
|
||||
, Button.button "Close"
|
||||
[ secondButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.custom focusableElementAttrs.lastFocusableElement
|
||||
]
|
||||
]
|
||||
|
||||
else if state.showContinue then
|
||||
Modal.viewFooter
|
||||
[ primaryButton focusableElementAttrs.lastFocusableElement
|
||||
[ Button.button "Continue"
|
||||
[ firstButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.custom focusableElementAttrs.lastFocusableElement
|
||||
]
|
||||
]
|
||||
|
||||
else if state.showSecondary then
|
||||
Modal.viewFooter
|
||||
[ secondaryButton focusableElementAttrs.lastFocusableElement
|
||||
[ Button.button "Close"
|
||||
[ secondButtonStyle
|
||||
, Button.onClick ForceClose
|
||||
, Button.custom focusableElementAttrs.lastFocusableElement
|
||||
]
|
||||
]
|
||||
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user