Merge branch 'master' into growth/premium-display

This commit is contained in:
Celso Bonutti 2022-03-10 16:09:41 -03:00
commit a521c09ee0
14 changed files with 1059 additions and 337 deletions

View File

@ -1,18 +1,24 @@
module Nri.Ui.Button.V10 exposing
( button, link
, Attribute
, icon, custom, css, nriDescription, testId, id
, onClick
, href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
, small, medium, large, modal
, exactWidth, boundedWidth, unboundedWidth, fillContainerWidth
, primary, secondary, danger, premium
, enabled, unfulfilled, disabled, error, loading, success
, icon, custom, nriDescription, testId, id
, hideIconForMobile, hideIconFor
, css, notMobileCss, mobileCss, quizEngineMobileCss
, delete
, toggleButton
)
{-|
{-| Notes for V11:
The next version of `Button` should add a `hideTextForMobile` helper.
This will require adding a selector for the text. We are not making this change in V10, as
adding a span around the text could potentially lead to regressions.
# Patch changes:
@ -20,6 +26,8 @@ module Nri.Ui.Button.V10 exposing
- uses ClickableAttributes
- adds `nriDescription`, `testId`, and `id` helpers
- adds `modal` helper, an alias for `large` size
- adds `notMobileCss`, `mobileCss`, `quizEngineMobileCss`
- adds `hideIconForMobile` and `hideIconFor`
# Changes from V9:
@ -32,7 +40,6 @@ module Nri.Ui.Button.V10 exposing
@docs button, link
@docs Attribute
@docs icon, custom, css, nriDescription, testId, id
## Behavior
@ -57,6 +64,17 @@ module Nri.Ui.Button.V10 exposing
@docs enabled, unfulfilled, disabled, error, loading, success
## Customization
@docs icon, custom, nriDescription, testId, id
### CSS
@docs hideIconForMobile, hideIconFor
@docs css, notMobileCss, mobileCss, quizEngineMobileCss
# Commonly-used buttons
@docs delete
@ -66,10 +84,12 @@ module Nri.Ui.Button.V10 exposing
import Accessibility.Styled as Html exposing (Html)
import Accessibility.Styled.Role as Role
import Accessibility.Styled.Style exposing (invisibleStyle)
import Accessibility.Styled.Widget as Widget
import ClickableAttributes exposing (ClickableAttributes)
import Css exposing (Style)
import Css.Global
import Css.Media exposing (MediaQuery)
import Html.Styled as Styled
import Html.Styled.Attributes as Attributes
import Html.Styled.Events as Events
@ -80,6 +100,7 @@ import Nri.Ui.Colors.Extra as ColorsExtra
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1
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 Svg
import Svg.Attributes
@ -171,6 +192,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
[ Css.Global.selector "[role=img]"
[ Css.display Css.none
]
]
]
]
{-| -}
css : List Style -> Attribute msg
css styles =
@ -182,6 +223,39 @@ css styles =
)
{-| Equivalent to:
Button.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:
Button.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:
Button.css
[ Css.Media.withMedia [ Nri.Ui.MediaQuery.V1.quizEngineMobile ] styles ]
-}
quizEngineMobileCss : List Style -> Attribute msg
quizEngineMobileCss styles =
css [ Css.Media.withMedia [ MediaQuery.quizEngineMobile ] styles ]
-- LINKING, CLICKING, and TRACKING BEHAVIOR

View File

@ -3,12 +3,13 @@ module Nri.Ui.ClickableSvg.V2 exposing
, Attribute
, onClick
, href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
, small, medium, large
, exactWidth, exactHeight
, exactSize, exactWidth, exactHeight
, disabled
, withBorder
, primary, secondary, danger, dangerSecondary
, custom, css, nriDescription, testId, id
, custom, nriDescription, testId, id
, css, notMobileCss, mobileCss, quizEngineMobileCss
, small, medium, large
)
{-|
@ -33,8 +34,7 @@ module Nri.Ui.ClickableSvg.V2 exposing
## Sizing
@docs small, medium, large
@docs exactWidth, exactHeight
@docs exactSize, exactWidth, exactHeight
## State
@ -47,17 +47,31 @@ module Nri.Ui.ClickableSvg.V2 exposing
@docs withBorder
@docs primary, secondary, danger, dangerSecondary
@docs custom, css, nriDescription, testId, id
@docs custom, nriDescription, testId, id
### CSS
@docs css, notMobileCss, mobileCss, quizEngineMobileCss
### DEPRECATED
In practice, we don't use these sizes. Remove them!
@docs small, medium, large
-}
import Accessibility.Styled.Widget as Widget
import ClickableAttributes exposing (ClickableAttributes)
import Css exposing (Color, Style)
import Css.Media
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Html.Attributes.V2 as ExtraAttributes
import Nri.Ui.MediaQuery.V1 as MediaQuery
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
@ -154,25 +168,47 @@ type Size
| Large
{-| This is the default.
{-| This is the default. This attribute will be removed in the next version of ClickableSvg!
-}
small : Attribute msg
small =
set (\attributes -> { attributes | size = Small })
{-| -}
{-| This attribute will be removed in the next version of ClickableSvg!
-}
medium : Attribute msg
medium =
set (\attributes -> { attributes | size = Medium })
{-| -}
{-| This attribute will be removed in the next version of ClickableSvg!
-}
large : Attribute msg
large =
set (\attributes -> { attributes | size = Large })
{-| Set the size in `px` for the element's width and height.
Equivalent to:
[ exactWidth inPx
, exactHeight inPx
]
-}
exactSize : Int -> Attribute msg
exactSize inPx =
set
(\attributes ->
{ attributes
| width = Just (toFloat inPx)
, height = Just (toFloat inPx)
}
)
{-| Define a size in `px` for the element's total width.
-}
exactWidth : Int -> Attribute msg
@ -351,6 +387,39 @@ css styles =
)
{-| Equivalent to:
ClickableSvg.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:
ClickableSvg.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:
ClickableSvg.css
[ Css.Media.withMedia [ Nri.Ui.MediaQuery.V1.quizEngineMobile ] styles ]
-}
quizEngineMobileCss : List Style -> Attribute msg
quizEngineMobileCss styles =
css [ Css.Media.withMedia [ MediaQuery.quizEngineMobile ] styles ]
-- INTERNALS

View File

@ -6,10 +6,16 @@ module Nri.Ui.ClickableText.V3 exposing
, onClick
, href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
, icon
, custom, css, nriDescription, testId, id
, custom, nriDescription, testId, id
, hideIconForMobile, hideIconFor
, hideTextForMobile, hideTextFor
, css, notMobileCss, mobileCss, quizEngineMobileCss
)
{-|
{-| Notes for V4:
- Remove the -v2- from dataDescriptor to avoid version specific
- Use dataDescriptor for clickable-text-label
# Post-release patches
@ -20,6 +26,9 @@ module Nri.Ui.ClickableText.V3 exposing
- removes bottom border
- adds `nriDescription`, `testId`, and `id` helpers
- adds `modal` helper, for use in modal footers, same as applying large and Css.marginTop (Css.px 15)
- adds `notMobileCss`, `mobileCss`, `quizEngineMobileCss`
- adds `hideIconForMobile` and `hideIconAt`
- adds `hideTextForMobile` and `hideTextAt`
# Changes from V2
@ -63,19 +72,33 @@ HTML `<a>` elements and are created here with `*Link` functions.
@docs onClick
@docs href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
## Customization
@docs icon
@docs custom, css, nriDescription, testId, id
@docs custom, nriDescription, testId, id
### CSS
@docs hideIconForMobile, hideIconFor
@docs hideTextForMobile, hideTextFor
@docs css, notMobileCss, mobileCss, quizEngineMobileCss
-}
import Accessibility.Styled.Style exposing (invisibleStyle)
import ClickableAttributes exposing (ClickableAttributes)
import Css exposing (Style)
import Css.Global
import Css.Media exposing (MediaQuery)
import Html.Styled as Html exposing (..)
import Html.Styled.Attributes as Attributes
import Nri.Ui
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1
import Nri.Ui.Html.Attributes.V2 as ExtraAttributes
import Nri.Ui.MediaQuery.V1 as MediaQuery
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
@ -162,6 +185,46 @@ 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
[ Css.Global.selector "[role=img]"
[ Css.display Css.none
]
]
]
]
{-| -}
hideTextForMobile : Attribute msg
hideTextForMobile =
hideTextFor MediaQuery.mobile
{-| -}
hideTextFor : MediaQuery -> Attribute msg
hideTextFor mediaQuery =
css
[ Css.Media.withMedia [ mediaQuery ]
[ Css.Global.descendants
[ ExtraAttributes.nriDescriptionSelector "clickable-text-label"
[ invisibleStyle
]
]
]
]
{-| -}
css : List Style -> Attribute msg
css styles =
@ -173,6 +236,39 @@ css styles =
)
{-| Equivalent to:
ClickableText.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:
ClickableText.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:
ClickableText.css
[ Css.Media.withMedia [ Nri.Ui.MediaQuery.V1.quizEngineMobile ] styles ]
-}
quizEngineMobileCss : List Style -> Attribute msg
quizEngineMobileCss styles =
css [ Css.Media.withMedia [ MediaQuery.quizEngineMobile ] styles ]
-- LINKING, CLICKING, and TRACKING BEHAVIOR
@ -309,7 +405,7 @@ viewContent config =
Css.marginRight (Css.px 4)
]
|> Svg.toHtml
, span [] [ text config.label ]
, span [ ExtraAttributes.nriDescription "clickable-text-label" ] [ text config.label ]
]
]

View File

@ -1,4 +1,4 @@
module Nri.Ui.Html.Attributes.V2 exposing (none, includeIf, targetBlank, nriDescription, testId)
module Nri.Ui.Html.Attributes.V2 exposing (none, includeIf, targetBlank, nriDescription, nriDescriptionSelector, testId)
{-|
@ -11,10 +11,12 @@ Extras for working with Html.Attributes.
This is the new version of Nri.Ui.Html.Attributes.Extra.
@docs none, includeIf, targetBlank, nriDescription, testId
@docs none, includeIf, targetBlank, nriDescription, nriDescriptionSelector, testId
-}
import Css
import Css.Global
import Html.Styled exposing (Attribute)
import Html.Styled.Attributes as Attributes
import Json.Encode as Encode
@ -75,3 +77,13 @@ testId id =
nriDescription : String -> Attribute msg
nriDescription description =
Attributes.attribute "data-nri-description" description
{-|
Note: this does not handle html escaping the description before building the query
-}
nriDescriptionSelector : String -> List Css.Style -> Css.Global.Snippet
nriDescriptionSelector description =
Css.Global.selector (String.join "" [ "[data-nri-description=\"", description, "\"]" ])

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,18 +1,45 @@
module CommonControls exposing (exampleHtml, httpError, premiumDisplay, premiumLevel, quickBrownFox, romeoAndJulietQuotation)
module CommonControls exposing
( css, mobileCss, quizEngineMobileCss, notMobileCss
, choice
, icon, iconNotCheckedByDefault, uiIcon
, content
, quickBrownFox, longPangrams, romeoAndJulietQuotation, markdown, exampleHtml, httpError
, disabledListItem, premiumLevel, premiumDisplay
)
{-|
@docs css, mobileCss, quizEngineMobileCss, notMobileCss
@docs choice
@docs icon, iconNotCheckedByDefault, uiIcon
### Content
@docs content
@docs quickBrownFox, longPangrams, romeoAndJulietQuotation, markdown, exampleHtml, httpError
-}
import Css
import Debug.Control as Control exposing (Control)
import Debug.Control.Extra as ControlExtra
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes
import Http
import Nri.Ui.Data.PremiumDisplay as PremiumDisplay exposing (PremiumDisplay)
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)
import Nri.Ui.UiIcon.V1 as UiIcon
premiumLevel : Control ( String, PremiumLevel )
premiumLevel =
Control.choice
[ ( "Free", Control.value ( "Free", Free ) )
, ( "PremiumWithWriting", Control.value ( "PremiumWithWriting", PremiumWithWriting ) )
choice "PremiumLevel"
[ ( "Free", Free )
, ( "PremiumWithWriting", PremiumWithWriting )
]
@ -61,11 +88,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 =
"""
@ -86,15 +190,146 @@ 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."
]
icon :
String
-> (Svg -> value)
-> Control (List ( String, value ))
-> Control (List ( String, value ))
icon moduleName f =
ControlExtra.optionalListItemDefaultChecked "icon"
(Control.map
(\( iconName, iconValue ) ->
( moduleName ++ ".icon " ++ iconName, f iconValue )
)
uiIcon
)
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 )
, ( "unarchive", UiIcon.unarchive )
, ( "share", UiIcon.share )
, ( "preview", UiIcon.preview )
, ( "skip", UiIcon.skip )
, ( "copyToClipboard", UiIcon.copyToClipboard )
, ( "gift", UiIcon.gift )
, ( "home", UiIcon.home )
, ( "library", UiIcon.library )
, ( "searchInCicle", UiIcon.searchInCicle )
]
|> choice "UiIcon"
choice : String -> List ( String, value ) -> Control ( String, value )
choice moduleName options =
options
|> List.map
(\( name, value ) ->
( name, Control.value ( moduleName ++ "." ++ name, value ) )
)
|> Control.choice
disabledListItem : String -> (Bool -> b) -> Control (List ( String, b )) -> Control (List ( String, b ))
disabledListItem moduleName disabled =
ControlExtra.optionalBoolListItem "disabled"
( moduleName ++ ".disabled True"
, disabled True
)
css :
{ moduleName : String, use : List Css.Style -> b }
-> Control (List ( String, b ))
-> Control (List ( String, b ))
css =
css_ "css"
( "[ Css.border3 (Css.px 4) Css.dashed Colors.red ]"
, [ Css.border3 (Css.px 4) Css.dashed Colors.red ]
)
mobileCss :
{ moduleName : String, use : List Css.Style -> b }
-> Control (List ( String, b ))
-> Control (List ( String, b ))
mobileCss =
css_ "mobileCss"
( "[ Css.border3 (Css.px 4) Css.dotted Colors.orange ]"
, [ Css.border3 (Css.px 4) Css.dotted Colors.orange ]
)
quizEngineMobileCss :
{ moduleName : String, use : List Css.Style -> b }
-> Control (List ( String, b ))
-> Control (List ( String, b ))
quizEngineMobileCss =
css_ "quizEngineMobileCss"
( "[ Css.border3 (Css.px 4) Css.solid Colors.aqua |> Css.important ]"
, [ Css.border3 (Css.px 4) Css.solid Colors.aqua |> Css.important ]
)
notMobileCss :
{ moduleName : String, use : List Css.Style -> b }
-> Control (List ( String, b ))
-> Control (List ( String, b ))
notMobileCss =
css_ "notMobileCss"
( "[ Css.backgroundColor Colors.purple ]"
, [ Css.backgroundColor Colors.purple ]
)
css_ :
String
-> ( String, List Css.Style )
->
{ moduleName : String
, use : List Css.Style -> b
}
-> Control (List ( String, b ))
-> Control (List ( String, b ))
css_ helperName ( styles, default ) { moduleName, use } =
ControlExtra.optionalListItem helperName
(Control.value
( moduleName ++ "." ++ helperName ++ " " ++ styles
, use default
)
)

View File

@ -1,12 +1,12 @@
module Debug.Control.Extra exposing
( float
, list, listItem, optionalListItem
( float, int
, list, listItem, optionalListItem, optionalListItemDefaultChecked, optionalBoolListItem
)
{-|
@docs float
@docs list, listItem, optionalListItem
@docs float, int
@docs list, listItem, optionalListItem, optionalListItemDefaultChecked, optionalBoolListItem
-}
@ -20,7 +20,19 @@ float default =
(Control.string (String.fromFloat default))
{-| -}
int : Int -> Control Int
int default =
Control.map (String.toInt >> Maybe.withDefault default)
(Control.string (String.fromInt default))
{-| Use with `listItem` and `optionalListItem`
list
|> listItem "first name" string
|> listItem "last name" string
-}
list : Control (List a)
list =
@ -37,7 +49,36 @@ listItem name accessor accumulator =
{-| -}
optionalListItem : String -> Control a -> Control (List a) -> Control (List a)
optionalListItem name accessor accumulator =
optionalListItem =
optionalListItem_ False
{-| -}
optionalListItemDefaultChecked : String -> Control a -> Control (List a) -> Control (List a)
optionalListItemDefaultChecked =
optionalListItem_ True
{-| -}
optionalListItem_ : Bool -> String -> Control a -> Control (List a) -> Control (List a)
optionalListItem_ default name accessor accumulator =
Control.field name
(Control.map (List.singleton >> List.filterMap identity) (Control.maybe False accessor))
(Control.map (List.singleton >> List.filterMap identity) (Control.maybe default accessor))
(Control.map (++) accumulator)
{-| -}
optionalBoolListItem : String -> a -> Control (List a) -> Control (List a)
optionalBoolListItem name f accumulator =
Control.field name
(Control.map
(\value ->
if value then
[ f ]
else
[]
)
(Control.bool False)
)
(Control.map (++) accumulator)

View File

@ -0,0 +1,72 @@
module Debug.Control.View exposing (codeFromList, view)
import Css exposing (..)
import Css.Media exposing (withMedia)
import Debug.Control as Control exposing (Control)
import Html.Styled exposing (..)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.MediaQuery.V1 exposing (mobile)
{-| -}
view :
{ update : Control a -> msg
, settings : Control a
, toExampleCode : a -> List { sectionName : String, code : String }
}
-> Html msg
view config =
let
value =
Control.currentValue config.settings
in
div
[ css
[ displayFlex
, Css.flexWrap Css.wrap
, Css.property "gap" "10px"
, withMedia [ mobile ] [ flexDirection column, alignItems stretch ]
]
]
[ viewSection "Settings" <|
[ fromUnstyled (Control.view config.update config.settings) ]
, viewExampleCode (config.toExampleCode value)
]
viewExampleCode : List { sectionName : String, code : String } -> Html msg
viewExampleCode values =
viewSection "Generated Code" <|
List.concatMap
(\{ sectionName, code } ->
[ details []
[ summary []
[ Heading.h4
[ Heading.css [ Css.display Css.inline ]
]
[ text sectionName ]
]
, Html.Styled.code
[ css [ whiteSpace preWrap ]
]
[ text code ]
]
]
)
values
viewSection : String -> List (Html msg) -> Html msg
viewSection name children =
section [ css [ flex (int 1) ] ]
(Heading.h3 [] [ text name ]
:: children
)
codeFromList : List ( String, a ) -> String
codeFromList list =
"\n\t[ "
++ String.join "\n\t, " (List.map Tuple.first list)
++ "\n\t] "

View File

@ -8,8 +8,11 @@ module Examples.Button exposing (Msg, State, example)
import Accessibility.Styled.Key as Key
import Category exposing (Category(..))
import CommonControls
import Css exposing (middle, verticalAlign)
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 exposing (..)
import Html.Styled.Attributes exposing (css, id)
@ -125,11 +128,9 @@ update msg state =
type alias Model =
{ label : String
, icon : Maybe Svg
, buttonType : ButtonType
, width : Button.Attribute Msg
, state : Button.Attribute Msg
{ buttonType : ButtonType
, label : String
, attributes : List ( String, Button.Attribute Msg )
}
@ -137,44 +138,54 @@ type alias Model =
initDebugControls : Control Model
initDebugControls =
Control.record Model
|> Control.field "label" (Control.string "Label")
|> Control.field "icon" (Control.maybe True iconChoice)
|> Control.field "button type"
|> Control.field "type"
(Control.choice
[ ( "button", Control.value Button )
, ( "link", Control.value Link )
]
)
|> Control.field "width"
(Control.choice
[ ( "exactWidth 120", Control.value (Button.exactWidth 120) )
, ( "exactWidth 70", Control.value (Button.exactWidth 70) )
, ( "boundedWidth 100 180", Control.value (Button.boundedWidth { min = 100, max = 180 }) )
, ( "unboundedWidth", Control.value Button.unboundedWidth )
, ( "fillContainerWidth", Control.value Button.fillContainerWidth )
]
|> Control.field "label" (Control.string "Label")
|> Control.field "attributes"
(ControlExtra.list
|> CommonControls.icon "Button" Button.icon
|> ControlExtra.optionalListItem "width"
(CommonControls.choice "Button"
[ ( "exactWidth 120", Button.exactWidth 120 )
, ( "exactWidth 70", Button.exactWidth 70 )
, ( "boundedWidth 100 180", Button.boundedWidth { min = 100, max = 180 } )
, ( "unboundedWidth", Button.unboundedWidth )
, ( "fillContainerWidth", Button.fillContainerWidth )
]
)
|> ControlExtra.optionalListItem "state (button only)"
(CommonControls.choice "Button"
[ ( "enabled", Button.enabled )
, ( "disabled", Button.disabled )
, ( "error", Button.error )
, ( "unfulfilled", Button.unfulfilled )
, ( "loading", Button.loading )
, ( "success", Button.success )
]
)
|> ControlExtra.optionalBoolListItem "hideIconForMobile"
( "Button.hideIconForMobile", Button.hideIconForMobile )
|> CommonControls.css
{ moduleName = "Button"
, use = Button.css
}
|> CommonControls.mobileCss
{ moduleName = "Button"
, use = Button.mobileCss
}
|> CommonControls.quizEngineMobileCss
{ moduleName = "Button"
, use = Button.quizEngineMobileCss
}
|> CommonControls.notMobileCss
{ moduleName = "Button"
, use = Button.notMobileCss
}
)
|> Control.field "state (button only)"
(Control.choice
[ ( "enabled", Control.value Button.enabled )
, ( "disabled", Control.value Button.disabled )
, ( "error", Control.value Button.error )
, ( "unfulfilled", Control.value Button.unfulfilled )
, ( "loading", Control.value Button.loading )
, ( "success", Control.value Button.success )
]
)
iconChoice : Control.Control Svg
iconChoice =
Control.choice
[ ( "preview", Control.value UiIcon.preview )
, ( "arrowLeft", Control.value UiIcon.arrowLeft )
, ( "performance", Control.value UiIcon.performance )
, ( "share", Control.value UiIcon.share )
, ( "download", Control.value UiIcon.download )
]
viewButtonExamples : State -> Html Msg
@ -183,8 +194,28 @@ viewButtonExamples state =
model =
Control.currentValue state.debugControlsState
in
[ Control.view SetDebugControlsState state.debugControlsState
|> fromUnstyled
[ ControlView.view
{ update = SetDebugControlsState
, settings = state.debugControlsState
, toExampleCode =
\{ label, attributes } ->
let
toCode fName =
"Button."
++ fName
++ " \""
++ label
++ "\"\n\t"
++ ControlView.codeFromList attributes
in
[ { sectionName = "Button"
, code = toCode "button"
}
, { sectionName = "Link"
, code = toCode "link"
}
]
}
, buttons model
, toggleButtons state.pressedToggleButtons
, Button.link "linkExternalWithTracking"
@ -238,19 +269,13 @@ buttons model =
exampleCell setStyle setSize =
buttonOrLink model.label
[ setSize
, setStyle
, model.width
, model.state
, Button.custom [ Html.Styled.Attributes.class "styleguide-button" ]
, Button.onClick (ShowItWorked "ButtonExample" "Button clicked!")
, case model.icon of
Just icon ->
Button.icon icon
Nothing ->
Button.custom []
]
([ setSize
, setStyle
, Button.custom [ Html.Styled.Attributes.class "styleguide-button" ]
, Button.onClick (ShowItWorked "ButtonExample" "Button clicked!")
]
++ List.map Tuple.second model.attributes
)
|> List.singleton
|> td
[ css

View File

@ -8,8 +8,11 @@ module Examples.ClickableSvg exposing (Msg, State, example)
import Accessibility.Styled.Key as Key
import Category exposing (Category(..))
import CommonControls
import Css
import Debug.Control as Control exposing (Control)
import Debug.Control.Extra as ControlExtra
import Debug.Control.View as ControlView
import EventExtras
import Example exposing (Example)
import Examples.IconExamples as IconExamples
@ -55,12 +58,30 @@ example =
]
, view =
\state ->
let
( icon, attributes ) =
applySettings state.settings
in
[ Html.fromUnstyled (Control.view SetControls state.settings)
, viewExampleTable icon attributes
[ ControlView.view
{ update = SetControls
, settings = state.settings
, toExampleCode =
\{ label, icon, attributes } ->
let
toCode fName =
"ClickableSvg."
++ fName
++ " \""
++ label
++ "\"\n\t"
++ Tuple.first icon
++ ControlView.codeFromList attributes
in
[ { sectionName = "Button"
, code = toCode "button"
}
, { sectionName = "Link"
, code = toCode "link"
}
]
}
, viewExampleTable (Control.currentValue state.settings)
, viewExample
"""
Tooltip.view
@ -103,16 +124,19 @@ Tooltip.view
}
viewExampleTable : Svg -> List (ClickableSvg.Attribute Msg) -> Html Msg
viewExampleTable icon attributes =
viewExampleTable : Settings Msg -> Html Msg
viewExampleTable { label, icon, attributes } =
let
sharedAttributes =
List.map Tuple.second attributes
viewExampleRow index ( themeName, theme ) =
Html.tr []
[ cell index [ Html.text themeName ]
, cell index [ buttonExample (theme :: attributes) ]
, cell index [ linkExample (theme :: attributes) ]
, cell index [ buttonExample (ClickableSvg.withBorder :: theme :: attributes) ]
, cell index [ linkExample (ClickableSvg.withBorder :: theme :: attributes) ]
, cell index [ buttonExample (theme :: sharedAttributes) ]
, cell index [ linkExample (theme :: sharedAttributes) ]
, cell index [ buttonExample (ClickableSvg.withBorder :: theme :: sharedAttributes) ]
, cell index [ linkExample (ClickableSvg.withBorder :: theme :: sharedAttributes) ]
]
cell index =
@ -128,15 +152,15 @@ viewExampleTable icon attributes =
]
buttonExample attributes_ =
ClickableSvg.button "Button example"
icon
ClickableSvg.button label
(Tuple.second icon)
(ClickableSvg.onClick (ShowItWorked "You clicked the back button!")
:: attributes_
)
linkExample attributes_ =
ClickableSvg.link "Link example"
icon
ClickableSvg.link label
(Tuple.second icon)
(ClickableSvg.linkSpa "some_link" :: attributes_)
in
Html.table []
@ -233,56 +257,39 @@ update msg state =
type alias Settings msg =
{ icon : Svg
, disabled : ClickableSvg.Attribute msg
, size : ClickableSvg.Attribute msg
, width : Maybe (ClickableSvg.Attribute msg)
, height : Maybe (ClickableSvg.Attribute msg)
{ label : String
, icon : ( String, Svg )
, attributes : List ( String, ClickableSvg.Attribute msg )
}
applySettings : Control (Settings msg) -> ( Svg, List (ClickableSvg.Attribute msg) )
applySettings settings =
let
{ icon, disabled, size, width, height } =
Control.currentValue settings
in
( icon, List.filterMap identity [ Just disabled, Just size, width, height ] )
initSettings : Control (Settings msg)
initSettings =
Control.record Settings
|> Control.field "icon"
(Control.choice
[ ( "arrowLeft", Control.value UiIcon.arrowLeft )
, ( "unarchive", Control.value UiIcon.unarchive )
, ( "share", Control.value UiIcon.share )
, ( "preview", Control.value UiIcon.preview )
, ( "skip", Control.value UiIcon.skip )
, ( "copyToClipboard", Control.value UiIcon.copyToClipboard )
, ( "gift", Control.value UiIcon.gift )
, ( "home", Control.value UiIcon.home )
, ( "library", Control.value UiIcon.library )
, ( "searchInCicle", Control.value UiIcon.searchInCicle )
]
|> Control.field "label" (Control.string "Back")
|> Control.field "icon" CommonControls.uiIcon
|> Control.field "attributes"
(ControlExtra.list
|> CommonControls.disabledListItem "ClickableSvg" ClickableSvg.disabled
|> ControlExtra.optionalListItem "exactSize"
(Control.map
(\v -> ( "ClickableSvg.exactSize " ++ String.fromInt v, ClickableSvg.exactSize v ))
(ControlExtra.int 36)
)
|> CommonControls.css
{ moduleName = "ClickableSvg"
, use = ClickableSvg.css
}
|> CommonControls.mobileCss
{ moduleName = "ClickableSvg"
, use = ClickableSvg.mobileCss
}
|> CommonControls.quizEngineMobileCss
{ moduleName = "ClickableSvg"
, use = ClickableSvg.quizEngineMobileCss
}
|> CommonControls.notMobileCss
{ moduleName = "ClickableSvg"
, use = ClickableSvg.notMobileCss
}
)
|> Control.field "disabled"
(Control.map ClickableSvg.disabled (Control.bool False))
|> Control.field "size"
(Control.choice
[ ( "small", Control.value ClickableSvg.small )
, ( "medium", Control.value ClickableSvg.medium )
, ( "large", Control.value ClickableSvg.large )
]
)
|> Control.field "exactWidth"
(Control.maybe False (Control.map ClickableSvg.exactWidth (controlInt 40)))
|> Control.field "exactHeight"
(Control.maybe False (Control.map ClickableSvg.exactHeight (controlInt 20)))
controlInt : Int -> Control Int
controlInt default =
Control.map (String.toInt >> Maybe.withDefault default)
(Control.string (String.fromInt default))

View File

@ -8,8 +8,11 @@ module Examples.ClickableText exposing (Msg, State, example)
import Accessibility.Styled.Key as Key
import Category exposing (Category(..))
import CommonControls
import Css exposing (middle, verticalAlign)
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 exposing (..)
import Html.Styled.Attributes exposing (css, id)
@ -20,11 +23,6 @@ import Nri.Ui.Text.V6 as Text
import Nri.Ui.UiIcon.V1 as UiIcon
{-| -}
type State
= State (Control Model)
{-| -}
example : Example State Msg
example =
@ -56,26 +54,52 @@ example =
}
{-| -}
type State
= State (Control (Settings Msg))
{-| -}
init : State
init =
Control.record Model
Control.record Settings
|> Control.field "label" (Control.string "Clickable Text")
|> Control.field "icon"
(Control.maybe True <|
Control.choice
[ ( "premiumLock", Control.value UiIcon.premiumLock )
, ( "preview", Control.value UiIcon.preview )
, ( "performance", Control.value UiIcon.performance )
, ( "edit", Control.value UiIcon.edit )
]
|> Control.field "attributes"
(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
}
|> CommonControls.mobileCss
{ moduleName = "ClickableText"
, use = ClickableText.mobileCss
}
|> CommonControls.quizEngineMobileCss
{ moduleName = "ClickableText"
, use = ClickableText.quizEngineMobileCss
}
|> CommonControls.notMobileCss
{ moduleName = "ClickableText"
, use = ClickableText.notMobileCss
}
)
|> State
type alias Settings msg =
{ label : String
, attributes : List ( String, ClickableText.Attribute msg )
}
{-| -}
type Msg
= SetState State
= SetState (Control (Settings Msg))
| ShowItWorked String String
@ -83,8 +107,8 @@ type Msg
update : Msg -> State -> ( State, Cmd Msg )
update msg state =
case msg of
SetState newState ->
( newState, Cmd.none )
SetState controls ->
( State controls, Cmd.none )
ShowItWorked group message ->
let
@ -98,36 +122,49 @@ update msg state =
-- INTERNAL
type alias Model =
{ label : String
, icon : Maybe Svg
}
viewExamples : State -> Html Msg
viewExamples (State control) =
let
model =
settings =
Control.currentValue control
clickableAttributes =
List.map Tuple.second settings.attributes
in
[ Control.view (State >> SetState) control
|> fromUnstyled
, buttons model
[ ControlView.view
{ update = SetState
, settings = control
, toExampleCode =
\{ label, attributes } ->
let
toCode fName =
"ClickableText."
++ fName
++ " \""
++ label
++ "\"\n\t"
++ ControlView.codeFromList attributes
in
[ { sectionName = "Button"
, code = toCode "button"
}
, { sectionName = "Link"
, code = toCode "link"
}
]
}
, buttons settings
, Text.smallBody
[ Text.html
[ text "Sometimes, we'll want our clickable links: "
, ClickableText.link model.label
[ ClickableText.small
, Maybe.map ClickableText.icon model.icon
|> Maybe.withDefault (ClickableText.custom [])
]
, ClickableText.link settings.label
(ClickableText.small :: clickableAttributes)
, text " and clickable buttons: "
, ClickableText.button model.label
[ ClickableText.small
, ClickableText.onClick (ShowItWorked "ClickableText" "in-line button")
, Maybe.map ClickableText.icon model.icon
|> Maybe.withDefault (ClickableText.custom [])
]
, ClickableText.button settings.label
(ClickableText.small
:: ClickableText.onClick (ShowItWorked "ClickableText" "in-line button")
:: clickableAttributes
)
, text " to show up in-line."
]
]
@ -143,8 +180,8 @@ sizes =
]
buttons : Model -> Html Msg
buttons model =
buttons : Settings Msg -> Html Msg
buttons settings =
let
sizeRow label render =
row label (List.map render sizes)
@ -153,21 +190,17 @@ buttons model =
[ sizeRow "" (\( size, sizeLabel ) -> th [] [ text sizeLabel ])
, sizeRow ".link"
(\( size, sizeLabel ) ->
ClickableText.link model.label
[ size
, Maybe.map ClickableText.icon model.icon
|> Maybe.withDefault (ClickableText.custom [])
]
ClickableText.link settings.label
(size :: List.map Tuple.second settings.attributes)
|> exampleCell
)
, sizeRow ".button"
(\( size, sizeLabel ) ->
ClickableText.button model.label
[ size
, ClickableText.onClick (ShowItWorked "ClickableText" sizeLabel)
, Maybe.map ClickableText.icon model.icon
|> Maybe.withDefault (ClickableText.custom [])
]
ClickableText.button settings.label
(size
:: ClickableText.onClick (ShowItWorked "ClickableText" sizeLabel)
:: List.map Tuple.second settings.attributes
)
|> exampleCell
)
]

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
{-| -}