Merge branch 'master' into ink-james--premium-checkbox

This commit is contained in:
James Gary 2018-09-07 15:32:58 -07:00
commit 743f270fec
4 changed files with 296 additions and 37 deletions

View File

@ -1,5 +1,5 @@
{ {
"version": "5.15.0", "version": "5.16.0",
"summary": "UI Widgets we use at NRI", "summary": "UI Widgets we use at NRI",
"repository": "https://github.com/NoRedInk/noredink-ui.git", "repository": "https://github.com/NoRedInk/noredink-ui.git",
"license": "BSD3", "license": "BSD3",
@ -30,6 +30,7 @@
"Nri.Ui.InputStyles", "Nri.Ui.InputStyles",
"Nri.Ui.Modal.V1", "Nri.Ui.Modal.V1",
"Nri.Ui.Modal.V2", "Nri.Ui.Modal.V2",
"Nri.Ui.Modal.V3",
"Nri.Ui.Outline.V1", "Nri.Ui.Outline.V1",
"Nri.Ui.Page.V1", "Nri.Ui.Page.V1",
"Nri.Ui.Palette.V1", "Nri.Ui.Palette.V1",

245
src/Nri/Ui/Modal/V3.elm Normal file
View File

@ -0,0 +1,245 @@
module Nri.Ui.Modal.V3
exposing
( Model
, info
, warning
)
{-| Changes from V2:
- Add assets for close button
@docs Model
@docs info
@docs warning
-}
import Accessibility.Styled as Html exposing (..)
import Accessibility.Styled.Role as Role
import Accessibility.Styled.Widget as Widget
import Css
import Css.Foreign 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
{-|
- `onDismiss`: If `Nothing`, the modal will not be dismissable
- `visibleTitle`: If `False`, the title will still be used for screen readers
- `content`: This will be placed in a `width:100%` div in the main area of the modal
- `footerContent`: The optional items here will be stacked below the main content area and center-aligned.
Commonly you will either give a list of Nri.Ui.Buttons,
or an empty list.
-}
type alias Model msg =
{ title : String
, visibleTitle : Bool
, content : Html msg
, footerContent : List (Html msg)
, onDismiss : Maybe msg
, width : Maybe Int
}
type alias Assets r =
{ r | icons_xBlue_svg : Asset }
type ModalType
= Info
| Warning
{-| -}
info : Assets r -> Model msg -> Html msg
info assets =
view assets Info
{-| -}
warning : Assets r -> Model msg -> Html msg
warning assets =
view assets Warning
view : Assets r -> ModalType -> Model msg -> Html msg
view assets modalType { title, visibleTitle, content, onDismiss, footerContent, width } =
Nri.Ui.styled div
"modal-backdrop-container"
((case modalType of
Info ->
Css.backgroundColor (Nri.Ui.Colors.Extra.withAlpha 0.9 Nri.Ui.Colors.V1.navy)
Warning ->
Css.backgroundColor (Nri.Ui.Colors.Extra.withAlpha 0.9 Nri.Ui.Colors.V1.gray20)
)
:: [ 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.label title
, Widget.modal True
]
[ Nri.Ui.styled Html.Styled.div
"modal-click-catcher"
[ Css.bottom Css.zero
, Css.left Css.zero
, Css.position Css.absolute
, Css.right Css.zero
, Css.top Css.zero
]
(case onDismiss of
Nothing ->
[]
Just msg ->
[ onClick msg ]
)
[]
, 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.Foreign.global
[ Css.Foreign.body
[ Css.overflow Css.hidden ]
]
, case onDismiss of
Just msg ->
closeButton assets msg
Nothing ->
text ""
, if visibleTitle then
viewHeader modalType title
else
text ""
, viewContent modalType content
, viewFooter footerContent
]
]
closeButton : Assets r -> msg -> Html msg
closeButton assets msg =
Nri.Ui.styled div
"close-button-container"
[ Css.position Css.absolute
, Css.top Css.zero
, Css.right Css.zero
, Css.padding (Css.px 25)
]
[]
[ Icon.button
{ alt = "Close"
, msg = msg
, icon = Icon.close assets
, disabled = False
, size = Icon.Medium
}
]
viewHeader : ModalType -> String -> Html msg
viewHeader modalType title =
Nri.Ui.styled Html.h3
"modal-header"
((case modalType of
Info ->
Css.color Nri.Ui.Colors.V1.navy
Warning ->
Css.color Nri.Ui.Colors.V1.red
)
:: [ Css.fontWeight (Css.int 700)
, Css.lineHeight (Css.px 27)
, Css.margin2 Css.zero (Css.px 65)
, Css.fontSize (Css.px 20)
, Fonts.baseFont
]
)
[]
[ Html.text title
]
viewContent : ModalType -> Html msg -> Html msg
viewContent modalType content =
Nri.Ui.styled div
"modal-content"
[ Css.overflowY Css.scroll
, 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

@ -82,32 +82,15 @@ custom { header, view, width } =
{-| Displays a table of data without a header row {-| Displays a table of data without a header row
-} -}
viewWithoutHeader : List (Column data msg) -> List data -> Html msg viewWithoutHeader : List (Column data msg) -> List data -> Html msg
viewWithoutHeader columns data = viewWithoutHeader columns =
table [] <| tableWithoutHeader [] columns (viewRow columns)
List.map (viewRow columns) data
{-| Displays a table of data based on the provided column definitions {-| Displays a table of data based on the provided column definitions
-} -}
view : List (Column data msg) -> List data -> Html msg view : List (Column data msg) -> List data -> Html msg
view columns data = view columns =
tableWithHeader [] columns <| tableWithHeader [] columns (viewRow columns)
List.map (viewRow columns) data
viewHeaders : List (Column data msg) -> Html msg
viewHeaders columns =
tr
[ css headersStyles ]
(List.map viewRowHeader columns)
viewRowHeader : Column data msg -> Html msg
viewRowHeader (Column header _ width) =
th
[ css (width :: headerStyles)
]
[ header ]
viewRow : List (Column data msg) -> data -> Html msg viewRow : List (Column data msg) -> data -> Html msg
@ -135,16 +118,14 @@ data is on its way and what it will look like when it arrives.
-} -}
viewLoading : List (Column data msg) -> Html msg viewLoading : List (Column data msg) -> Html msg
viewLoading columns = viewLoading columns =
tableWithHeader loadingTableStyles columns <| tableWithHeader loadingTableStyles columns (viewLoadingRow columns) (List.range 0 8)
List.map (viewLoadingRow columns) (List.range 0 8)
{-| Display the loading table without a header row {-| Display the loading table without a header row
-} -}
viewLoadingWithoutHeader : List (Column data msg) -> Html msg viewLoadingWithoutHeader : List (Column data msg) -> Html msg
viewLoadingWithoutHeader columns = viewLoadingWithoutHeader columns =
table loadingTableStyles <| tableWithoutHeader loadingTableStyles columns (viewLoadingRow columns) (List.range 0 8)
List.map (viewLoadingRow columns) (List.range 0 8)
viewLoadingRow : List (Column data msg) -> Int -> Html msg viewLoadingRow : List (Column data msg) -> Int -> Html msg
@ -173,14 +154,45 @@ stylesLoadingColumn rowIndex colIndex width =
-- HELP -- HELP
tableWithoutHeader : List Style -> List (Column data msg) -> (a -> Html msg) -> List a -> Html msg
tableWithoutHeader styles columns toRow data =
table styles
[ tableBody toRow data
]
tableWithHeader : List Style -> List (Column data msg) -> (a -> Html msg) -> List a -> Html msg
tableWithHeader styles columns toRow data =
table styles
[ tableHeader columns
, tableBody toRow data
]
table : List Style -> List (Html msg) -> Html msg table : List Style -> List (Html msg) -> Html msg
table styles = table styles =
Html.table [ css (styles ++ tableStyles) ] Html.table [ css (styles ++ tableStyles) ]
tableWithHeader : List Style -> List (Column data msg) -> List (Html msg) -> Html msg tableHeader : List (Column data msg) -> Html msg
tableWithHeader styles columns rows = tableHeader columns =
table styles (viewHeaders columns :: rows) thead []
[ tr [ css headersStyles ]
(List.map tableRowHeader columns)
]
tableRowHeader : Column data msg -> Html msg
tableRowHeader (Column header _ width) =
th
[ css (width :: headerStyles)
]
[ header ]
tableBody : (a -> Html msg) -> List a -> Html msg
tableBody toRow items =
tbody [] (List.map toRow items)

View File

@ -7,13 +7,14 @@ module Examples.Modal exposing (Msg, State, example, init, update)
-} -}
import Accessibility.Styled as Html exposing (Html, div, h3, p, text) import Accessibility.Styled as Html exposing (Html, div, h3, p, text)
import Assets
import Css exposing (..) import Css exposing (..)
import Html.Styled import Html.Styled
import Html.Styled.Attributes exposing (css) import Html.Styled.Attributes exposing (css)
import ModuleExample exposing (Category(..), ModuleExample) import ModuleExample exposing (Category(..), ModuleExample)
import Nri.Ui.Button.V3 as Button import Nri.Ui.Button.V3 as Button
import Nri.Ui.Colors.V1 as Colors import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Modal.V2 as Modal import Nri.Ui.Modal.V3 as Modal
{-| -} {-| -}
@ -30,7 +31,7 @@ type alias State =
{-| -} {-| -}
example : (Msg -> msg) -> State -> ModuleExample msg example : (Msg -> msg) -> State -> ModuleExample msg
example parentMessage state = example parentMessage state =
{ filename = "Nri.Ui.Modal.V2.elm" { filename = "Nri.Ui.Modal.V3.elm"
, category = Modals , category = Modals
, content = , content =
[ case state.modal of [ case state.modal of
@ -114,7 +115,7 @@ viewModal : ModalType -> Html Msg
viewModal modal = viewModal modal =
case modal of case modal of
InfoModal -> InfoModal ->
Modal.info Modal.info Assets.assets
{ title = "Info Modal" { title = "Info Modal"
, visibleTitle = True , visibleTitle = True
, content = text "This is where the content goes!" , content = text "This is where the content goes!"
@ -127,7 +128,7 @@ viewModal modal =
} }
WarningModal -> WarningModal ->
Modal.warning Modal.warning Assets.assets
{ title = "Warning Modal" { title = "Warning Modal"
, visibleTitle = True , visibleTitle = True
, content = text "This is where the content goes!" , content = text "This is where the content goes!"
@ -140,7 +141,7 @@ viewModal modal =
} }
NoButtonModal -> NoButtonModal ->
Modal.info Modal.info Assets.assets
{ title = "No Buttons" { title = "No Buttons"
, visibleTitle = True , visibleTitle = True
, content = text "This is where the content goes!" , content = text "This is where the content goes!"
@ -150,7 +151,7 @@ viewModal modal =
} }
NoDismissModal -> NoDismissModal ->
Modal.info Modal.info Assets.assets
{ title = "No Dismiss" { title = "No Dismiss"
, visibleTitle = True , visibleTitle = True
, content = text "This is where the content goes!" , content = text "This is where the content goes!"
@ -163,7 +164,7 @@ viewModal modal =
} }
NoHeading -> NoHeading ->
Modal.info Modal.info Assets.assets
{ title = "Hidden title" { title = "Hidden title"
, onDismiss = Just DismissModal , onDismiss = Just DismissModal
, visibleTitle = False , visibleTitle = False
@ -182,7 +183,7 @@ viewModal modal =
} }
ScrolledContentModal -> ScrolledContentModal ->
Modal.info Modal.info Assets.assets
{ title = "Scrolled Content" { title = "Scrolled Content"
, onDismiss = Just DismissModal , onDismiss = Just DismissModal
, visibleTitle = True , visibleTitle = True