Merge pull request #293 from NoRedInk/tessa/icon-work

Accessible Modal
This commit is contained in:
Tessa 2019-06-18 09:20:34 -07:00 committed by GitHub
commit aece305611
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 624 additions and 208 deletions

View File

@ -41,6 +41,7 @@
"Nri.Ui.Modal.V2",
"Nri.Ui.Modal.V3",
"Nri.Ui.Modal.V4",
"Nri.Ui.Modal.V5",
"Nri.Ui.Outline.V2",
"Nri.Ui.Page.V2",
"Nri.Ui.Page.V3",
@ -73,15 +74,17 @@
"elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": {
"avh4/elm-color": "1.0.0 <= v < 2.0.0",
"elm/browser": "1.0.1 <= v < 2.0.0",
"elm/core": "1.0.0 <= v < 2.0.0",
"elm/html": "1.0.0 <= v < 2.0.0",
"elm/json": "1.0.0 <= v < 2.0.0",
"elm/regex": "1.0.0 <= v < 2.0.0",
"elm/svg": "1.0.1 <= v < 2.0.0",
"lukewestby/accessible-html-with-css-temp-19": "1.0.0 <= v < 2.0.0",
"tesk9/accessible-html-with-css": "2.1.1 <= v < 3.0.0",
"pablohirafuji/elm-markdown": "2.0.5 <= v < 3.0.0",
"rtfeldman/elm-css": "16.0.0 <= v < 17.0.0",
"tesk9/accessible-html": "4.0.0 <= v < 5.0.0",
"tesk9/modal": "5.0.1 <= v < 6.0.0",
"wernerdegroot/listzipper": "3.1.1 <= v < 4.0.0"
},
"test-dependencies": {

View File

@ -73,7 +73,6 @@ import Nri.Ui.AssetPath as AssetPath exposing (Asset)
import Nri.Ui.Colors.Extra as ColorsExtra
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1
import Nri.Ui.Icon.V4 as Icon exposing (IconType)
import Nri.Ui.Svg.V1 as NriSvg exposing (Svg)
import Svg
import Svg.Attributes

View File

@ -209,7 +209,6 @@ viewEnabledLabel model labelView icon =
, css
[ positioning
, textStyle
, outline none
, cursor pointer
]
]

421
src/Nri/Ui/Modal/V5.elm Normal file
View File

@ -0,0 +1,421 @@
module Nri.Ui.Modal.V5 exposing
( Model, init
, Msg, update, subscriptions
, info, warning, FocusableElementAttrs
, viewContent, viewFooter
, launchButton, closeButton
, primaryButton, secondaryButton, dangerButton
)
{-| Changes from V4:
- Remove dependence on Assets
- Adds keyboard support (escape key to exit, tabs contained within the modal)
These changes have required major API changes. Be sure to wire up subscriptions!
import Html.Styled exposing (..)
import Nri.Ui.Modal.V5 as Modal
view : Modal.State -> Html Msg
view state =
Modal.info
{ title = { title = "Modal Header", visibleTitle = True }
, wrapMsg = ModalMsg
, content =
\{ onlyFocusableElement } ->
div []
[ Modal.viewContent [ text "Content goes here!" ]
, Modal.viewFooter
[ Modal.primaryButton DoSomething "Continue" onlyFocusableElement
, text "`onlyFocusableElement` will trap the focus on the 'Continue' button."
]
]
}
state
subscriptions : Modal.State -> Sub Msg
subscriptions state =
Modal.subscriptions state
## State and updates
@docs Model, init
@docs Msg, update, subscriptions
## Views
### Modals
@docs info, warning, FocusableElementAttrs
### View containers
@docs viewContent, viewFooter
### Buttons
@docs launchButton, closeButton
@docs primaryButton, secondaryButton, dangerButton
-}
import Accessibility.Modal as Modal
import Accessibility.Style
import Accessibility.Styled as Html exposing (..)
import Accessibility.Styled.Style
import Accessibility.Styled.Widget as Widget
import Color
import Css
import Css.Global
import Html as Root
import Html.Attributes exposing (style)
import Html.Styled.Attributes exposing (css)
import Html.Styled.Events exposing (onClick)
import Nri.Ui
import Nri.Ui.Colors.Extra
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.SpriteSheet
import Nri.Ui.Svg.V1
{-| -}
type alias Model =
Modal.Model
{-| -}
init : Model
init =
Modal.init
{-| -}
type alias Msg =
Modal.Msg
{-| Include the subscription if you want the modal to dismiss on `Esc`.
-}
subscriptions : Model -> Sub Msg
subscriptions =
Modal.subscriptions
{-| -}
update : { dismissOnEscAndOverlayClick : Bool } -> Msg -> Model -> ( Model, Cmd Msg )
update config msg model =
Modal.update config msg model
{-| -}
type alias FocusableElementAttrs msg =
{ onlyFocusableElement : List (Root.Attribute msg)
, firstFocusableElement : List (Root.Attribute msg)
, lastFocusableElement : List (Root.Attribute msg)
}
{-| -}
info :
{ title : { 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
{-| -}
warning :
{ title : { visibleTitle : Bool, title : String }
, content : FocusableElementAttrs msg -> Html msg
, wrapMsg : Msg -> msg
}
-> Model
-> Html msg
warning config model =
Modal.view
{ overlayColor = toOverlayColor Colors.gray20
, wrapMsg = config.wrapMsg
, modalAttributes = modalStyles
, title = viewTitle Colors.red config.title
, content = config.content >> toUnstyled
}
model
|> fromUnstyled
toOverlayColor : Css.Color -> String
toOverlayColor color =
toCssString (Nri.Ui.Colors.Extra.withAlpha 0.9 color)
modalStyles : List (Root.Attribute Never)
modalStyles =
[ style "width" "600px"
, style "max-height" "calc(100vh - 100px)"
, style "padding" "40px 0 40px 0"
, style "margin" "75px auto"
, style "background-color" (toCssString Colors.white)
, style "border-radius" "20px"
, style "box-shadow" "0 1px 10px 0 rgba(0, 0, 0, 0.35)"
, style "position" "relative" -- required for closeButtonContainer
]
{-| -}
viewTitle : Css.Color -> { visibleTitle : Bool, title : String } -> ( String, List (Root.Attribute Never) )
viewTitle color { visibleTitle, title } =
( title
, if visibleTitle then
[ style "font-weight" "700"
, style "line-height" "27px"
, style "margin" "0 49px"
, style "font-size" "20px"
, style "text-align" "center"
, style "color" (toCssString color)
]
else
Accessibility.Style.invisible
)
toCssString : Css.Color -> String
toCssString =
Color.toCssString << Nri.Ui.Colors.Extra.toCoreColor
{-| -}
viewContent : List (Html msg) -> Html msg
viewContent =
Nri.Ui.styled div
"modal-content"
[ Css.overflowY Css.auto
, Css.padding2 (Css.px 30) (Css.px 40)
, Css.width (Css.pct 100)
, Css.minHeight (Css.px 150)
, Css.boxSizing Css.borderBox
]
[]
{-| -}
viewFooter : List (Html msg) -> Html msg
viewFooter =
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)
]
[]
--BUTTONS
{-| -}
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 wrapMsg focusableElementAttrs =
Nri.Ui.styled button
"close-button-container"
[ Css.position Css.absolute
, Css.top Css.zero
, Css.right Css.zero
, Css.padding (Css.px 25)
, Css.borderWidth Css.zero
, Css.width (Css.px 75)
, Css.backgroundColor Css.transparent
, Css.cursor Css.pointer
, Css.color Colors.azure
, Css.hover [ Css.color Colors.azureDark ]
, Css.property "transition" "color 0.1s"
]
(Widget.label "Close modal"
:: Html.Styled.Attributes.map wrapMsg (onClick Modal.close)
:: List.map Html.Styled.Attributes.fromUnstyled 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
]

View File

@ -1,232 +1,224 @@
module Examples.Modal exposing (Msg, State, example, init, update)
module Examples.Modal exposing (Msg, State, example, init, update, subscriptions)
{-|
@docs Msg, State, example, init, update
@docs Msg, State, example, init, update, subscriptions
-}
import Accessibility.Styled as Html exposing (Html, div, h3, p, text)
import Assets
import Accessibility.Styled as Html exposing (Html, div, h3, h4, p, text)
import Css exposing (..)
import Css.Global
import Html as Root
import Html.Styled.Attributes exposing (css)
import ModuleExample exposing (Category(..), ModuleExample)
import Nri.Ui.Button.V5 as Button
import Nri.Ui.Checkbox.V5 as Checkbox
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Modal.V4 as Modal
{-| -}
type Msg
= DismissModal
| ShowModal ModalType
import Nri.Ui.Modal.V5 as Modal
{-| -}
type alias State =
{ modal : Maybe ModalType }
{-| -}
example : (Msg -> msg) -> State -> ModuleExample msg
example parentMessage state =
{ name = "Nri.Ui.Modal.V3"
, category = Modals
, content =
[ case state.modal of
Just modal ->
viewModal modal
Nothing ->
text ""
, viewButtons
]
|> List.map (Html.map parentMessage)
{ infoModal : Modal.Model
, warningModal : Modal.Model
, visibleTitle : Bool
, showX : Bool
, showContinue : Bool
, showSecondary : Bool
, dismissOnEscAndOverlayClick : Bool
}
{-| -}
init : State
init =
{ modal = Nothing }
{ infoModal = Modal.init
, warningModal = Modal.init
, visibleTitle = True
, showX = True
, showContinue = True
, showSecondary = False
, dismissOnEscAndOverlayClick = True
}
{-| -}
example : (Msg -> msg) -> State -> ModuleExample msg
example parentMessage state =
{ name = "Nri.Ui.Modal.V5"
, category = Modals
, content =
[ Modal.launchButton InfoModalMsg [] "Launch Info Modal"
, Modal.launchButton WarningModalMsg [] "Launch Warning Modal"
, Modal.info
{ title = { title = "Modal.info", visibleTitle = state.visibleTitle }
, wrapMsg = InfoModalMsg
, content =
viewContent state
InfoModalMsg
(Modal.primaryButton ForceClose "Continue")
(Modal.secondaryButton ForceClose "Close")
}
state.infoModal
, Modal.warning
{ title = { title = "Modal.warning", visibleTitle = state.visibleTitle }
, wrapMsg = WarningModalMsg
, content =
viewContent state
WarningModalMsg
(Modal.dangerButton ForceClose "Continue")
(Modal.secondaryButton ForceClose "Close")
}
state.warningModal
]
|> List.map (Html.map parentMessage)
}
viewContent :
State
-> (Modal.Msg -> Msg)
-> (List (Root.Attribute Msg) -> Html Msg)
-> (List (Root.Attribute Msg) -> Html Msg)
-> Modal.FocusableElementAttrs Msg
-> Html Msg
viewContent state wrapMsg primaryButton secondaryButton focusableElementAttrs =
div []
[ if state.showX then
Modal.closeButton wrapMsg focusableElementAttrs.firstFocusableElement
else
text ""
, Modal.viewContent [ viewSettings state ]
, if state.showContinue && state.showSecondary then
Modal.viewFooter
[ primaryButton []
, secondaryButton focusableElementAttrs.lastFocusableElement
]
else if state.showContinue then
Modal.viewFooter
[ primaryButton focusableElementAttrs.lastFocusableElement
]
else if state.showSecondary then
Modal.viewFooter
[ secondaryButton focusableElementAttrs.lastFocusableElement
]
else
text ""
]
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
}
, Checkbox.viewWithLabel
{ identifier = "show-secondary"
, label = "Show secondary button"
, selected = Checkbox.selectedFromBool state.showSecondary
, setterMsg = SetShowSecondary
, disabled = False
, theme = Checkbox.Square
}
, 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
}
]
{-| -}
type Msg
= InfoModalMsg Modal.Msg
| WarningModalMsg Modal.Msg
| ForceClose
| SetVisibleTitle Bool
| SetShowX Bool
| SetShowContinue Bool
| SetShowSecondary Bool
| SetDismissOnEscAndOverlayClick Bool
{-| -}
update : Msg -> State -> ( State, Cmd Msg )
update msg state =
let
updateConfig =
{ dismissOnEscAndOverlayClick = state.dismissOnEscAndOverlayClick }
in
case msg of
DismissModal ->
( { state | modal = Nothing }, Cmd.none )
InfoModalMsg modalMsg ->
case Modal.update updateConfig modalMsg state.infoModal of
( newState, cmds ) ->
( { state | infoModal = newState }
, Cmd.map InfoModalMsg cmds
)
ShowModal modalType ->
( { state | modal = Just modalType }, Cmd.none )
WarningModalMsg modalMsg ->
case Modal.update updateConfig modalMsg state.warningModal of
( newState, cmds ) ->
( { state | warningModal = newState }
, Cmd.map WarningModalMsg cmds
)
ForceClose ->
( { state
| infoModal = Modal.init
, warningModal = Modal.init
}
, Cmd.none
)
SetVisibleTitle value ->
( { state | visibleTitle = value }, Cmd.none )
SetShowX value ->
( { state | showX = value }, Cmd.none )
SetShowContinue value ->
( { state | showContinue = value }, Cmd.none )
SetShowSecondary value ->
( { state | showSecondary = value }, Cmd.none )
SetDismissOnEscAndOverlayClick value ->
( { state | dismissOnEscAndOverlayClick = value }, Cmd.none )
-- INTERNAL
type ModalType
= InfoModal
| WarningModal
| NoButtonModal
| NoDismissModal
| OnlyXDismissModal
| NoHeading
| ScrolledContentModal
viewButtons : Html Msg
viewButtons =
[ ( "Info Modal", "Modal.info", InfoModal )
, ( "Warning Modal", "Modal.warning", WarningModal )
, ( "No Button Modal", "Modal.info { ... footerContent = [] ... }", NoButtonModal )
, ( "No Dismiss Modal", "Modal.info { ... onDismiss = NotDismissible ... }", NoDismissModal )
, ( "Only X-Dismiss Modal", "Modal.info { ... onDismiss = WithOnlyX ... }", OnlyXDismissModal )
, ( "No Heading", "Modal.info { ... visibleTitle = False ... }", NoHeading )
, ( "Scrolled Content"
, "Modal.info { content = Html.text 'so much stuff' }"
, ScrolledContentModal
)
]
|> List.map modalLaunchButton
|> div []
modalLaunchButton : ( String, String, ModalType ) -> Html Msg
modalLaunchButton ( label, details, modalType ) =
div []
[ h3 [] [ text label ]
, p [] [ text details ]
, Button.button
{ onClick = ShowModal modalType
, size = Button.Small
, style = Button.Secondary
, width = Button.WidthUnbounded
}
{ label = label
, state = Button.Enabled
, icon = Nothing
}
{-| -}
subscriptions : State -> Sub Msg
subscriptions model =
Sub.batch
[ Sub.map InfoModalMsg (Modal.subscriptions model.infoModal)
, Sub.map WarningModalMsg (Modal.subscriptions model.warningModal)
]
viewModal : ModalType -> Html Msg
viewModal modal =
case modal of
InfoModal ->
Modal.info Assets.assets
{ title = "Info Modal"
, visibleTitle = True
, content = text "This is where the content goes!"
, onDismiss = Modal.WithBackgroundOrX DismissModal
, width = Nothing
, footerContent =
[ modalFooterButton "Primary" Button.Primary
, modalFooterButton "Cancel" Button.Borderless
]
}
WarningModal ->
Modal.warning Assets.assets
{ title = "Warning Modal"
, visibleTitle = True
, content = text "This is where the content goes!"
, onDismiss = Modal.WithBackgroundOrX DismissModal
, width = Nothing
, footerContent =
[ modalFooterButton "Primary" Button.Danger
, modalFooterButton "Cancel" Button.Borderless
]
}
NoButtonModal ->
Modal.info Assets.assets
{ title = "No Buttons"
, visibleTitle = True
, content = text "This is where the content goes!"
, onDismiss = Modal.WithBackgroundOrX DismissModal
, width = Nothing
, footerContent = []
}
NoDismissModal ->
Modal.info Assets.assets
{ title = "No Dismiss"
, visibleTitle = True
, content = text "This is where the content goes!"
, onDismiss = Modal.NotDismissible
, width = Nothing
, footerContent =
[ modalFooterButton "Primary" Button.Primary
, modalFooterButton "Cancel" Button.Borderless
]
}
OnlyXDismissModal ->
Modal.info Assets.assets
{ title = "Only X-Dismiss"
, visibleTitle = True
, content = text "This is where the content goes!"
, onDismiss = Modal.WithOnlyX DismissModal
, width = Nothing
, footerContent =
[ modalFooterButton "Primary" Button.Primary
, modalFooterButton "Cancel" Button.Borderless
]
}
NoHeading ->
Modal.info Assets.assets
{ title = "Hidden title"
, onDismiss = Modal.WithBackgroundOrX DismissModal
, visibleTitle = False
, footerContent = []
, width = Nothing
, content =
div
[ css
[ width (pct 100)
, height (px 200)
, backgroundColor Colors.gray75
, border3 (px 1) dashed Colors.gray20
]
]
[ text "Imagine an image" ]
}
ScrolledContentModal ->
Modal.info Assets.assets
{ title = "Scrolled Content"
, onDismiss = Modal.WithBackgroundOrX DismissModal
, visibleTitle = True
, footerContent = [ modalFooterButton "Primary" Button.Primary ]
, width = Nothing
, content =
div []
[ text "\nIt was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.\n\n\nIt was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.\n\nIt was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.\n "
, div
[ css
[ width (pct 100)
, height (px 200)
, backgroundColor Colors.gray75
, border3 (px 1) dashed Colors.gray20
]
]
[ text "Imagine an image" ]
]
}
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

@ -233,7 +233,8 @@ update outsideMsg moduleStates =
subscriptions : ModuleStates -> Sub Msg
subscriptions moduleStates =
Sub.batch
[]
[ Sub.map ModalExampleMsg (Examples.Modal.subscriptions moduleStates.modalExampleState)
]
{-| A container with a visually-apparent size for demonstrating how style guide components

View File

@ -18,10 +18,11 @@
"elm/svg": "1.0.1",
"elm/url": "1.0.0",
"elm-community/string-extra": "4.0.1",
"lukewestby/accessible-html-with-css-temp-19": "1.0.0",
"tesk9/accessible-html-with-css": "2.1.1",
"pablohirafuji/elm-markdown": "2.0.5",
"rtfeldman/elm-css": "16.0.0",
"tesk9/accessible-html": "4.0.0",
"tesk9/modal": "5.0.1",
"wernerdegroot/listzipper": "3.2.0"
},
"indirect": {
@ -35,4 +36,4 @@
"direct": {},
"indirect": {}
}
}
}