Adds first version of the slide modal

This commit is contained in:
Tessa Kelly 2019-04-04 18:30:12 -07:00
parent e088a78963
commit 98eff48478
3 changed files with 230 additions and 0 deletions

View File

@ -0,0 +1,112 @@
module Nri.Ui.SlideModal.V1 exposing (view)
import Accessibility.Styled as Html exposing (..)
import Accessibility.Styled.Role as Role
import Accessibility.Styled.Widget as Widget
import Css
import Css.Global exposing (Snippet, body, children, descendants, everything, selector)
import Html.Styled
import Html.Styled.Events exposing (onClick)
import Nri.Ui
import Nri.Ui.AssetPath exposing (Asset(..))
import Nri.Ui.Colors.Extra
import Nri.Ui.Colors.V1
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Icon.V3 as Icon
view { content, onDismiss, footerContent, width } =
Nri.Ui.styled div
"modal-backdrop-container"
(Css.backgroundColor (Nri.Ui.Colors.Extra.withAlpha 0.9 Nri.Ui.Colors.V1.navy)
:: [ Css.height (Css.vh 100)
, Css.left Css.zero
, Css.overflow Css.hidden
, Css.position Css.fixed
, Css.top Css.zero
, Css.width (Css.pct 100)
, Css.zIndex (Css.int 200)
, Css.displayFlex
, Css.alignItems Css.center
, Css.justifyContent Css.center
]
)
[ Role.dialog
, Widget.modal True
]
[ Nri.Ui.styled div
"modal-container"
[ Css.width (Css.px 600)
, Css.maxHeight <| Css.calc (Css.vh 100) Css.minus (Css.px 100)
, Css.padding4 (Css.px 35) Css.zero (Css.px 25) Css.zero
, Css.margin2 (Css.px 75) Css.auto
, Css.backgroundColor Nri.Ui.Colors.V1.white
, Css.borderRadius (Css.px 20)
, Css.property "box-shadow" "0 1px 10px 0 rgba(0, 0, 0, 0.35)"
, Css.position Css.relative -- required for closeButtonContainer
, Css.displayFlex
, Css.alignItems Css.center
, Css.flexDirection Css.column
, Css.flexWrap Css.noWrap
, Fonts.baseFont
]
[]
[ -- This global <style> node sets overflow to hidden on the body element,
-- thereby preventing the page from scrolling behind the backdrop when the modal is
-- open (and this node is present on the page).
Css.Global.global
[ Css.Global.body
[ Css.overflow Css.hidden ]
]
, viewContent content
, viewFooter footerContent
]
]
viewContent : Html msg -> Html msg
viewContent content =
Nri.Ui.styled div
"modal-content"
[ Css.overflowY Css.auto
, Css.padding2 (Css.px 30) (Css.px 45)
, Css.width (Css.pct 100)
, Css.minHeight (Css.px 150)
, Css.boxSizing Css.borderBox
]
[]
[ content ]
viewFooter : List (Html msg) -> Html msg
viewFooter footerContent =
case footerContent of
[] ->
Html.text ""
_ ->
Nri.Ui.styled div
"modal-footer"
[ 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.width (Css.pct 100)
]
[]
(List.map
(\x ->
Nri.Ui.styled div
"modal-footer-item"
[ Css.margin4 (Css.px 10) Css.zero Css.zero Css.zero
, Css.firstChild
[ Css.margin Css.zero
]
]
[]
[ x ]
)
footerContent
)

View File

@ -0,0 +1,104 @@
module Examples.SlideModal exposing (Msg, State, example, init, update)
{-|
@docs Msg, State, example, init, update
-}
import Accessibility.Styled as Html exposing (Html, div, h3, p, text)
import Assets
import Css exposing (..)
import Html.Styled.Attributes exposing (css)
import ModuleExample exposing (Category(..), ModuleExample)
import Nri.Ui.Button.V8 as Button
import Nri.Ui.SlideModal.V1 as SlideModal
{-| -}
type Msg
= DismissModal
| ShowModal
{-| -}
type alias State =
{ modal : Bool }
{-| -}
example : (Msg -> msg) -> State -> ModuleExample msg
example parentMessage state =
{ filename = "Nri.Ui.SlideModal.V1.elm"
, category = Modals
, content =
[ if state.modal then
viewModal
else
text ""
, modalLaunchButton
]
|> List.map (Html.map parentMessage)
}
{-| -}
init : State
init =
{ modal = False }
{-| -}
update : Msg -> State -> ( State, Cmd Msg )
update msg state =
case msg of
DismissModal ->
( { state | modal = False }, Cmd.none )
ShowModal ->
( { state | modal = True }, Cmd.none )
-- INTERNAL
modalLaunchButton : Html Msg
modalLaunchButton =
Button.button
{ onClick = ShowModal
, size = Button.Small
, style = Button.Secondary
, width = Button.WidthUnbounded
}
{ label = "Launch Modal"
, state = Button.Enabled
, icon = Nothing
}
viewModal : Html Msg
viewModal =
SlideModal.view
{ content = text "This is where the content goes!"
, onDismiss = Just DismissModal
, width = Nothing
, footerContent =
[ modalFooterButton "Primary" Button.Primary
]
}
modalFooterButton : String -> Button.ButtonStyle -> Html Msg
modalFooterButton label style =
Button.button
{ onClick = DismissModal
, size = Button.Large
, style = style
, width = Button.WidthExact 230
}
{ label = label
, state = Button.Enabled
, icon = Nothing
}

View File

@ -15,6 +15,7 @@ import Examples.Modal
import Examples.Page
import Examples.SegmentedControl
import Examples.Select
import Examples.SlideModal
import Examples.Table
import Examples.Tabs
import Examples.Text
@ -39,6 +40,7 @@ type alias ModuleStates =
, textInputExampleState : TextInputExample.State
, disclosureIndicatorExampleState : Examples.DisclosureIndicator.State
, modalExampleState : Examples.Modal.State
, slideModalExampleState : Examples.SlideModal.State
, tabsExampleState : Examples.Tabs.Tab
}
@ -56,6 +58,7 @@ init =
, textInputExampleState = TextInputExample.init
, disclosureIndicatorExampleState = Examples.DisclosureIndicator.init
, modalExampleState = Examples.Modal.init
, slideModalExampleState = Examples.SlideModal.init
, tabsExampleState = Examples.Tabs.First
}
@ -73,6 +76,7 @@ type Msg
| TextInputExampleMsg TextInputExample.Msg
| DisclosureIndicatorExampleMsg Examples.DisclosureIndicator.Msg
| ModalExampleMsg Examples.Modal.Msg
| SlideModalExampleMsg Examples.SlideModal.Msg
| TabsExampleMsg Examples.Tabs.Tab
| NoOp
@ -184,6 +188,15 @@ update outsideMsg moduleStates =
, Cmd.map ModalExampleMsg cmd
)
SlideModalExampleMsg msg ->
let
( slideModalExampleState, cmd ) =
Examples.SlideModal.update msg moduleStates.slideModalExampleState
in
( { moduleStates | slideModalExampleState = slideModalExampleState }
, Cmd.map SlideModalExampleMsg cmd
)
TabsExampleMsg tab ->
( { moduleStates | tabsExampleState = tab }
, Cmd.none
@ -232,6 +245,7 @@ nriThemedModules model =
, Examples.DisclosureIndicator.example DisclosureIndicatorExampleMsg model.disclosureIndicatorExampleState
, Examples.Colors.example
, Examples.Modal.example ModalExampleMsg model.modalExampleState
, Examples.SlideModal.example SlideModalExampleMsg model.slideModalExampleState
, Examples.Tabs.example TabsExampleMsg model.tabsExampleState
]