Merge pull request #852 from NoRedInk/tessa/media-support-3

Tessa/media support 3
This commit is contained in:
Brian J. Cardiff 2022-03-10 15:27:58 -03:00 committed by GitHub
commit dce31c6a14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 328 additions and 163 deletions

View File

@ -225,7 +225,7 @@ css styles =
{-| Equivalent to:
ClickableText.css
Button.css
[ Css.Media.withMedia [ Nri.Ui.MediaQuery.V1.notMobile ] styles ]
-}
@ -236,7 +236,7 @@ notMobileCss styles =
{-| Equivalent to:
ClickableText.css
Button.css
[ Css.Media.withMedia [ Nri.Ui.MediaQuery.V1.mobile ] styles ]
-}
@ -247,7 +247,7 @@ mobileCss styles =
{-| Equivalent to:
ClickableText.css
Button.css
[ Css.Media.withMedia [ Nri.Ui.MediaQuery.V1.quizEngineMobile ] styles ]
-}

View File

@ -1,7 +1,9 @@
module Nri.Ui.Message.V3 exposing
( somethingWentWrong
, view, Attribute
, icon, custom, css, testId, id
, icon, custom, testId, id
, hideIconForMobile, hideIconFor
, css, notMobileCss, mobileCss, quizEngineMobileCss
, tiny, large, banner
, plaintext, markdown, html, httpError
, tip, error, alert, success, customTheme
@ -9,20 +11,27 @@ module Nri.Ui.Message.V3 exposing
, onDismiss
)
{-| Changes from V2:
{-| Patch changes:
- adds `notMobileCss`, `mobileCss`, `quizEngineMobileCss`
- adds `hideIconForMobile` and `hideIconFor`
Changes from V2:
- adds helpers: `custom`,`css`,`icon`,`testId`,`id`
Patch changes:
- add `httpError`
# View
@docs somethingWentWrong
@docs view, Attribute
@docs icon, custom, css, testId, id
@docs icon, custom, testId, id
# CSS
@docs hideIconForMobile, hideIconFor
@docs css, notMobileCss, mobileCss, quizEngineMobileCss
## Size
@ -53,10 +62,11 @@ Patch changes:
import Accessibility.Styled as Html exposing (..)
import Accessibility.Styled.Role as Role
import Accessibility.Styled.Style exposing (invisibleStyle)
import Accessibility.Styled.Widget as Widget
import Css exposing (..)
import Css.Global
import Css.Media
import Css.Media exposing (MediaQuery)
import Html.Styled.Attributes as Attributes
import Html.Styled.Events exposing (onClick)
import Http
@ -66,6 +76,7 @@ import Nri.Ui.ClickableSvg.V2 as ClickableSvg
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Html.Attributes.V2 as ExtraAttributes
import Nri.Ui.MediaQuery.V1 as MediaQuery
import Nri.Ui.Svg.V1 as NriSvg exposing (Svg)
import Nri.Ui.UiIcon.V1 as UiIcon
@ -133,7 +144,12 @@ view attributes_ =
++ role
++ attributes.customAttributes
)
[ Nri.Ui.styled div "Nri-Ui-Message--icon" [ alignSelf flexStart ] [] [ icon_ ]
[ Nri.Ui.styled div
"Nri-Ui-Message--icon"
[ alignSelf flexStart ]
[]
[ icon_
]
, div [] attributes.content
, case attributes.onDismiss of
Nothing ->
@ -507,6 +523,26 @@ id id_ =
custom [ Attributes.id id_ ]
{-| -}
hideIconForMobile : Attribute msg
hideIconForMobile =
hideIconFor MediaQuery.mobile
{-| -}
hideIconFor : MediaQuery -> Attribute msg
hideIconFor mediaQuery =
css
[ Css.Media.withMedia [ mediaQuery ]
[ Css.Global.descendants
[ ExtraAttributes.nriDescriptionSelector messageIconDescription
[ invisibleStyle
]
]
]
]
{-| -}
css : List Style -> Attribute msg
css styles =
@ -517,6 +553,39 @@ css styles =
}
{-| Equivalent to:
Message.css
[ Css.Media.withMedia [ Nri.Ui.MediaQuery.V1.notMobile ] styles ]
-}
notMobileCss : List Style -> Attribute msg
notMobileCss styles =
css [ Css.Media.withMedia [ MediaQuery.notMobile ] styles ]
{-| Equivalent to:
Message.css
[ Css.Media.withMedia [ Nri.Ui.MediaQuery.V1.mobile ] styles ]
-}
mobileCss : List Style -> Attribute msg
mobileCss styles =
css [ Css.Media.withMedia [ MediaQuery.mobile ] styles ]
{-| Equivalent to:
Message.css
[ Css.Media.withMedia [ Nri.Ui.MediaQuery.V1.quizEngineMobile ] styles ]
-}
quizEngineMobileCss : List Style -> Attribute msg
quizEngineMobileCss styles =
css [ Css.Media.withMedia [ MediaQuery.quizEngineMobile ] styles ]
{-| Adds a dismiss ("X" icon) to a message which will produce the given `msg` when clicked.
-}
onDismiss : msg -> Attribute msg
@ -699,6 +768,7 @@ getIcon customIcon size theme =
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withLabel "Error"
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
( Nothing, Alert ) ->
@ -717,6 +787,7 @@ getIcon customIcon size theme =
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withLabel "Alert"
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
( Nothing, Tip ) ->
@ -728,6 +799,7 @@ getIcon customIcon size theme =
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withLabel "Tip"
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
Large ->
@ -737,6 +809,7 @@ getIcon customIcon size theme =
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withLabel "Tip"
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
Banner ->
@ -757,6 +830,7 @@ getIcon customIcon size theme =
, width (px 35)
]
]
, ExtraAttributes.nriDescription messageIconDescription
]
[ UiIcon.bulb
|> NriSvg.withColor Colors.mustard
@ -778,6 +852,7 @@ getIcon customIcon size theme =
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withLabel "Success"
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
( Just icon_, _ ) ->
@ -785,12 +860,18 @@ getIcon customIcon size theme =
|> NriSvg.withWidth iconSize
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
( Nothing, Custom _ ) ->
Html.text ""
messageIconDescription : String
messageIconDescription =
"Nri-Ui-Message-icon"
-- Role

View File

@ -1,6 +1,6 @@
module Nri.Ui.Svg.V1 exposing
( Svg
, withColor, withLabel, withWidth, withHeight, withCss
, withColor, withLabel, withWidth, withHeight, withCss, withNriDescription
, fromHtml, toHtml
, toRawSvg
)
@ -8,7 +8,7 @@ module Nri.Ui.Svg.V1 exposing
{-|
@docs Svg
@docs withColor, withLabel, withWidth, withHeight, withCss
@docs withColor, withLabel, withWidth, withHeight, withCss, withNriDescription
@docs fromHtml, toHtml
@docs toRawSvg
@ -19,6 +19,7 @@ import Accessibility.Styled.Widget as Widget
import Css exposing (Color)
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes
import Nri.Ui.Html.Attributes.V2 as AttributesExtra
import Svg.Styled as Svg
@ -32,6 +33,7 @@ type Svg
, height : Maybe Css.Px
, css : List Css.Style
, label : Maybe String
, attributes : List (Html.Attribute Never)
}
@ -46,6 +48,7 @@ fromHtml icon =
, width = Nothing
, css = []
, label = Nothing
, attributes = []
}
@ -87,6 +90,18 @@ withCss css (Svg record) =
Svg { record | css = css }
{-| -}
withCustom : List (Html.Attribute Never) -> Svg -> Svg
withCustom attributes (Svg record) =
Svg { record | attributes = attributes ++ record.attributes }
{-| -}
withNriDescription : String -> Svg -> Svg
withNriDescription description =
withCustom [ AttributesExtra.nriDescription description ]
{-| Render an svg.
-}
toHtml : Svg -> Html msg
@ -112,8 +127,9 @@ toHtml (Svg record) =
|> Just
, Just Role.img
]
++ record.attributes
in
Html.div attributes [ Html.map never record.icon ]
Html.map never (Html.div attributes [ record.icon ])
{-| Extract an svg, dropping any attributes passed through.

View File

@ -1,15 +1,23 @@
module CommonControls exposing
( css, mobileCss, quizEngineMobileCss, notMobileCss
, choice
, icon, uiIcon
, disabledListItem, exampleHtml, httpError, premiumLevel, quickBrownFox, romeoAndJulietQuotation
, icon, iconNotCheckedByDefault, uiIcon
, content
, quickBrownFox, longPangrams, romeoAndJulietQuotation, markdown, exampleHtml, httpError
, disabledListItem, premiumLevel
)
{-|
@docs css, mobileCss, quizEngineMobileCss, notMobileCss
@docs choice
@docs icon, uiIcon
@docs icon, iconNotCheckedByDefault, uiIcon
### Content
@docs content
@docs quickBrownFox, longPangrams, romeoAndJulietQuotation, markdown, exampleHtml, httpError
-}
@ -19,6 +27,7 @@ import Debug.Control.Extra as ControlExtra
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes
import Http
import Nri.Ui.ClickableText.V3 as ClickableText
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Data.PremiumLevel exposing (PremiumLevel(..))
import Nri.Ui.Svg.V1 exposing (Svg)
@ -69,11 +78,88 @@ httpError =
]
content :
{ moduleName : String
, plaintext : String -> attribute
, markdown : String -> attribute
, html : List (Html msg) -> attribute
, httpError : Maybe (Http.Error -> attribute)
}
-> Control ( String, attribute )
content ({ moduleName } as config) =
Control.choice
([ ( "plain text (short)"
, Control.string quickBrownFox
|> Control.map
(\str ->
( moduleName ++ ".plaintext \"" ++ str ++ "\""
, config.plaintext str
)
)
)
, ( "plain text (long, no newlines)"
, Control.string longPangrams
|> Control.map
(\str ->
( moduleName ++ ".plaintext \"" ++ str ++ "\""
, config.plaintext str
)
)
)
, ( "plain text (long, with newlines)"
, Control.stringTextarea romeoAndJulietQuotation
|> Control.map
(\str ->
( moduleName ++ ".plaintext\n\t\t\"\"\"" ++ str ++ "\t\t\"\"\""
, config.plaintext str
)
)
)
, ( "markdown"
, Control.string markdown
|> Control.map
(\str ->
( moduleName ++ ".markdown \"" ++ str ++ "\""
, config.markdown str
)
)
)
, ( "HTML"
, Control.value
( moduleName ++ ".html [ ... ]"
, config.html exampleHtml
)
)
]
++ (case config.httpError of
Just httpError_ ->
[ ( "httpError"
, Control.map
(\error ->
( moduleName ++ ".httpError error"
, httpError_ error
)
)
httpError
)
]
Nothing ->
[]
)
)
quickBrownFox : String
quickBrownFox =
"The quick brown fox jumps over the lazy dog."
longPangrams : String
longPangrams =
"Waltz, bad nymph, for quick jigs vex. Glib jocks quiz nymph to vex dwarf. Sphinx of black quartz, judge my vow. How vexingly quick daft zebras jump!"
romeoAndJulietQuotation : String
romeoAndJulietQuotation =
"""
@ -94,16 +180,21 @@ romeoAndJulietQuotation =
"""
markdown : String
markdown =
"_Katie's dad suggests:_ Don't tip too much, or your waitress will **fall over**!"
exampleHtml : List (Html msg)
exampleHtml =
[ Html.text "This is a "
, Html.strong [] [ Html.text "bolded phrase" ]
, Html.text ". "
, Html.a
[ Attributes.href "http://www.noredink.com"
, Attributes.target "_blank"
, ClickableText.link quickBrownFox
[ ClickableText.small
, ClickableText.icon UiIcon.starFilled
, ClickableText.href "http://www.noredink.com"
]
[ Html.text quickBrownFox ]
, Html.text " When I stepped out, into the bright sunlight from the darkness of the movie house, I had only two things on my mind: Paul Newman, and a ride home."
]
@ -123,6 +214,21 @@ icon moduleName f =
)
iconNotCheckedByDefault :
String
-> (Svg -> value)
-> Control (List ( String, value ))
-> Control (List ( String, value ))
iconNotCheckedByDefault moduleName f =
ControlExtra.optionalListItem "icon"
(Control.map
(\( iconName, iconValue ) ->
( moduleName ++ ".icon " ++ iconName, f iconValue )
)
uiIcon
)
uiIcon : Control ( String, Svg )
uiIcon =
[ ( "arrowLeft", UiIcon.arrowLeft )

View File

@ -40,12 +40,19 @@ viewExampleCode values =
viewSection "Generated Code" <|
List.concatMap
(\{ sectionName, code } ->
[ Heading.h4 [] [ text sectionName ]
[ details []
[ summary []
[ Heading.h4
[ Heading.css [ Css.display Css.inline ]
]
[ text sectionName ]
]
, Html.Styled.code
[ css [ whiteSpace preWrap ]
]
[ text code ]
]
]
)
values

View File

@ -168,9 +168,7 @@ initDebugControls =
]
)
|> ControlExtra.optionalBoolListItem "hideIconForMobile"
(\_ ->
( "Button.hideIconForMobile", Button.hideIconForMobile )
)
|> CommonControls.css
{ moduleName = "Button"
, use = Button.css

View File

@ -68,13 +68,9 @@ init =
(ControlExtra.list
|> CommonControls.icon "ClickableText" ClickableText.icon
|> ControlExtra.optionalBoolListItem "hideIconForMobile"
(\_ ->
( "ClickableText.hideIconForMobile", ClickableText.hideIconForMobile )
)
|> ControlExtra.optionalBoolListItem "hideTextForMobile"
(\_ ->
( "ClickableText.hideTextForMobile", ClickableText.hideTextForMobile )
)
|> CommonControls.css
{ moduleName = "ClickableText"
, use = ClickableText.css

View File

@ -6,21 +6,19 @@ import CommonControls
import Css exposing (..)
import Debug.Control as Control exposing (Control)
import Debug.Control.Extra as ControlExtra
import Debug.Control.View as ControlView
import Example exposing (Example)
import Html.Styled.Attributes as Attributes exposing (css, href)
import KeyboardSupport exposing (Direction(..), Key(..))
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Message.V3 as Message
import Nri.Ui.Pennant.V2 as Pennant
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.UiIcon.V1 as UiIcon
import ViewHelpers exposing (viewExamples)
type alias State =
{ show : Bool
, control : Control (List (Message.Attribute Msg))
, control : Control (List ( String, Message.Attribute Msg ))
}
@ -30,132 +28,82 @@ init =
, control =
ControlExtra.list
|> ControlExtra.optionalListItem "theme" controlTheme
|> ControlExtra.listItem "content" controlContent
|> ControlExtra.listItem "content"
(CommonControls.content
{ moduleName = "Message"
, plaintext = Message.plaintext
, markdown = Message.markdown
, html = Message.html
, httpError = Just Message.httpError
}
)
|> ControlExtra.optionalListItem "role" controlRole
|> ControlExtra.optionalListItem "dismissable" controlDismissable
|> ControlExtra.optionalListItem "css" controlCss
|> ControlExtra.optionalListItem "icon" controlIcon
|> ControlExtra.optionalBoolListItem "dismissable"
( "Message.onDismiss Dismiss", Message.onDismiss Dismiss )
|> CommonControls.iconNotCheckedByDefault "Message" Message.icon
|> ControlExtra.optionalBoolListItem "hideIconForMobile"
( "Message.hideIconForMobile", Message.hideIconForMobile )
|> CommonControls.css
{ moduleName = "Message"
, use = Message.css
}
|> CommonControls.mobileCss
{ moduleName = "Message"
, use = Message.mobileCss
}
|> CommonControls.quizEngineMobileCss
{ moduleName = "Message"
, use = Message.quizEngineMobileCss
}
|> CommonControls.notMobileCss
{ moduleName = "Message"
, use = Message.notMobileCss
}
}
controlTheme : Control (Message.Attribute msg)
controlTheme : Control ( String, Message.Attribute msg )
controlTheme =
Control.choice
[ ( "tip", Control.value Message.tip )
, ( "error", Control.value Message.error )
, ( "alert", Control.value Message.alert )
, ( "success", Control.value Message.success )
[ ( "tip", Control.value ( "Message.tip", Message.tip ) )
, ( "error", Control.value ( "Message.error", Message.error ) )
, ( "alert", Control.value ( "Message.alert", Message.alert ) )
, ( "success", Control.value ( "Message.success", Message.success ) )
, ( "customTheme", controlCustomTheme )
]
controlCustomTheme : Control (Message.Attribute msg)
controlCustomTheme : Control ( String, Message.Attribute msg )
controlCustomTheme =
Control.record (\a b -> Message.customTheme { color = a, backgroundColor = b })
Control.record
(\( aStr, a ) ( bStr, b ) ->
( "Message.customTheme { color = " ++ aStr ++ ", backgroundColor = " ++ bStr ++ " }"
, Message.customTheme { color = a, backgroundColor = b }
)
)
|> Control.field "color"
(Control.choice
[ ( "aquaDark", Control.value Colors.aquaDark )
(CommonControls.choice "Colors"
[ ( "aquaDark", Colors.aquaDark )
]
)
|> Control.field "backgroundColor"
(Control.choice
[ ( "gray92", Control.value Colors.gray92 )
(CommonControls.choice "Colors"
[ ( "gray92", Colors.gray92 )
]
)
controlIcon : Control (Message.Attribute msg)
controlIcon =
Control.choice
[ ( "premiumFlag", Control.value (Message.icon Pennant.premiumFlag) )
, ( "lock", Control.value (Message.icon UiIcon.lock) )
, ( "clock", Control.value (Message.icon UiIcon.clock) )
]
controlContent : Control (Message.Attribute msg)
controlContent =
Control.choice
[ ( "plain text (short)"
, Control.string "Comic books do count as literature."
|> Control.map Message.plaintext
)
, ( "plain text (long)"
, Control.stringTextarea "Share this link with students as an easy shortcut to join Jeffy's Favorite Class (no class code needed). The link works for students new to NoRedInk and those with existing accounts. Students only need to use this link once to join."
|> Control.map Message.plaintext
)
, ( "markdown"
, Control.string "_Katie's dad suggests:_ Don't tip too much, or your waitress will **fall over**!"
|> Control.map Message.markdown
)
, ( "HTML (short)"
, Control.value
(Message.html
[ code [] [ text "git status" ]
, text " "
, Html.em [] [ text "tries again" ]
]
)
)
, ( "HTML (long)"
, Control.value
(Message.html
[ text "Click "
, a [ href "http://www.noredink.com", Attributes.target "_blank" ]
[ text "here, yes, HERE, right here on this very long success message. "
, text "Wow, how successful! You're the biggest success I've ever seen! "
, text "You should feel great about yourself! Give yourself a very big round of applause! "
, styled div
[ display inlineBlock
, width (px 20)
]
[]
[ Svg.toHtml UiIcon.gear ]
]
, text " to check out NoRedInk."
]
)
)
, ( "httpError"
, Control.map Message.httpError CommonControls.httpError
)
]
controlRole : Control (Message.Attribute msg)
controlRole : Control ( String, Message.Attribute msg )
controlRole =
Control.choice
[ ( "alertRole", Control.value Message.alertRole )
, ( "alertDialogRole", Control.value Message.alertDialogRole )
]
controlDismissable : Control (Message.Attribute Msg)
controlDismissable =
Control.value (Message.onDismiss Dismiss)
controlCss : Control (Message.Attribute Msg)
controlCss =
Control.choice
[ ( "css [ border3 (px 1) dashed red ]"
, Control.value
(Message.css [ Css.border3 (Css.px 1) Css.dashed Colors.red ])
)
, ( "css [ border3 (px 2) solid purple, borderRadius4 (px 8) (px 8) zero zero ]"
, Control.value
(Message.css
[ Css.border3 (Css.px 2) Css.solid Colors.purple
, Css.borderRadius4 (Css.px 8) (Css.px 8) Css.zero Css.zero
]
)
)
CommonControls.choice "Message"
[ ( "alertRole", Message.alertRole )
, ( "alertDialogRole", Message.alertDialogRole )
]
type Msg
= Dismiss
| UpdateControl (Control (List (Message.Attribute Msg)))
| UpdateControl (Control (List ( String, Message.Attribute Msg )))
update : Msg -> State -> ( State, Cmd Msg )
@ -186,7 +134,7 @@ example =
\state ->
let
attributes =
Control.currentValue state.control
List.map Tuple.second (Control.currentValue state.control)
orDismiss view =
if state.show then
@ -195,13 +143,35 @@ example =
else
text "Nice! The messages were dismissed. 👍"
in
[ Heading.h3 [ Heading.css [ Css.marginBottom (Css.px 20) ] ]
[ text "Message.view" ]
, Control.view UpdateControl state.control
|> Html.fromUnstyled
[ ControlView.view
{ update = UpdateControl
, settings = state.control
, toExampleCode =
\settings ->
let
toCode maybeSize =
"Message.view\n\t[ "
++ (maybeSize
:: List.map (Tuple.first >> Just) settings
|> List.filterMap identity
|> String.join "\n\t, "
)
++ "\n\t]"
in
[ { sectionName = "Tiny"
, code = toCode Nothing
}
, { sectionName = "Large"
, code = toCode (Just "Message.large")
}
, { sectionName = "Banner"
, code = toCode (Just "Message.banner")
}
]
}
, orDismiss <|
viewExamples
[ ( "tiny", Message.view (Message.tiny :: attributes) )
[ ( "tiny", Message.view attributes )
, ( "large", Message.view (Message.large :: attributes) )
, ( "banner", Message.view (Message.banner :: attributes) )
]

View File

@ -111,23 +111,14 @@ init =
controlContent : Control (Text.Attribute msg)
controlContent =
Control.choice
[ ( "HTML"
, Control.value (Text.html exampleHtml)
)
, ( "plain text (short)"
, Control.string quickBrownFox
|> Control.map Text.plaintext
)
, ( "plain text (long)"
, Control.stringTextarea romeoAndJulietQuotation
|> Control.map Text.plaintext
)
, ( "markdown"
, Control.string romeoAndJulietQuotation
|> Control.map Text.markdown
)
]
CommonControls.content
{ moduleName = "Text"
, plaintext = Text.plaintext
, markdown = Text.markdown
, html = Text.html
, httpError = Nothing
}
|> Control.map Tuple.second
{-| -}