Merge remote-tracking branch 'origin/master' into dansby/heading-v3

This commit is contained in:
Tessa Kelly 2022-07-15 17:00:53 -07:00
commit 960829d335
34 changed files with 1535 additions and 2000 deletions

View File

@ -3,7 +3,7 @@
"name": "NoRedInk/noredink-ui",
"summary": "UI Widgets we use at NRI",
"license": "BSD-3-Clause",
"version": "16.4.0",
"version": "17.0.0",
"exposed-modules": [
"Nri.Ui",
"Nri.Ui.Accordion.V1",

View File

@ -5,6 +5,7 @@ module CheckboxIcons exposing
, unchecked
)
import Css
import Nri.Ui.Colors.Extra exposing (toCssString)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Svg.V1 exposing (Svg)
@ -21,11 +22,7 @@ unchecked idSuffix =
filterUrl =
"url(#" ++ filterId ++ ")"
in
Svg.svg
[ SvgAttributes.width "27px"
, SvgAttributes.height "27px"
, SvgAttributes.viewBox viewBox
]
Nri.Ui.Svg.V1.init viewBox
[ Svg.defs []
[ Svg.filter
[ SvgAttributes.x "-3.7%"
@ -79,7 +76,8 @@ unchecked idSuffix =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
|> Nri.Ui.Svg.V1.withWidth (Css.px 27)
|> Nri.Ui.Svg.V1.withHeight (Css.px 27)
checked : String -> Svg
@ -91,11 +89,7 @@ checked idSuffix =
filterUrl =
"url(#" ++ filterId ++ ")"
in
Svg.svg
[ SvgAttributes.width "27px"
, SvgAttributes.height "27px"
, SvgAttributes.viewBox viewBox
]
Nri.Ui.Svg.V1.init viewBox
[ Svg.defs []
[ Svg.filter
[ SvgAttributes.x "-3.7%"
@ -158,7 +152,8 @@ checked idSuffix =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
|> Nri.Ui.Svg.V1.withWidth (Css.px 27)
|> Nri.Ui.Svg.V1.withHeight (Css.px 27)
checkedPartially : String -> Svg
@ -170,11 +165,7 @@ checkedPartially idSuffix =
filterUrl =
"url(#" ++ filterId ++ ")"
in
Svg.svg
[ SvgAttributes.width "27px"
, SvgAttributes.height "27px"
, SvgAttributes.viewBox viewBox
]
Nri.Ui.Svg.V1.init viewBox
[ Svg.defs []
[ Svg.filter
[ SvgAttributes.x "-3.7%"
@ -236,7 +227,8 @@ checkedPartially idSuffix =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
|> Nri.Ui.Svg.V1.withWidth (Css.px 27)
|> Nri.Ui.Svg.V1.withHeight (Css.px 27)
viewBox : String
@ -270,11 +262,7 @@ lockOnInside idSuffix =
filterUrl =
"url(#" ++ filterId ++ ")"
in
Svg.svg
[ SvgAttributes.width "27px"
, SvgAttributes.height "27px"
, SvgAttributes.viewBox viewBox
]
Nri.Ui.Svg.V1.init viewBox
[ Svg.defs []
[ Svg.filter
[ SvgAttributes.x "-3.7%"
@ -357,4 +345,5 @@ lockOnInside idSuffix =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
|> Nri.Ui.Svg.V1.withWidth (Css.px 27)
|> Nri.Ui.Svg.V1.withHeight (Css.px 27)

View File

@ -21,6 +21,7 @@ import Html.Styled.Keyed
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.DisclosureIndicator.V2 as DisclosureIndicator
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Svg.V1 as Svg
{-| -}
@ -232,6 +233,7 @@ viewCaret expanded caret =
[ marginRight (px 8)
]
expanded
|> Svg.toHtml
WhiteCaret ->
DisclosureIndicator.large
@ -240,6 +242,7 @@ viewCaret expanded caret =
[ Css.Global.everything [ color Colors.white ] ]
]
expanded
|> Svg.toHtml
NoneCaret ->
text ""

File diff suppressed because one or more lines are too long

View File

@ -260,7 +260,7 @@ viewIconForLink isFirst iconStyle svg =
viewHeadingWithIcon : { config | isLast : Bool, isIconOnly : Bool } -> String -> Html msg
viewHeadingWithIcon { isIconOnly, isLast } title =
div
span
(if isIconOnly then
Style.invisible
@ -300,7 +300,7 @@ circleIconClass =
withIconCircle : Svg.Svg -> Html msg
withIconCircle icon =
styled div
styled span
[ borderRadius (pct 50)
, border3 (px 1) solid Colors.azure
, color Colors.azure

View File

@ -5,7 +5,7 @@ module Nri.Ui.Button.V10 exposing
, href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
, small, medium, large, modal
, exactWidth, boundedWidth, unboundedWidth, fillContainerWidth
, primary, secondary, danger, premium
, primary, secondary, tertiary, danger, premium
, enabled, unfulfilled, disabled, error, loading, success
, icon, custom, nriDescription, testId, id
, hideIconForMobile, hideIconFor
@ -29,6 +29,7 @@ adding a span around the text could potentially lead to regressions.
- adds `notMobileCss`, `mobileCss`, `quizEngineMobileCss`
- adds `hideIconForMobile` and `hideIconFor`
- support 'disabled' links according to [Scott O'Hara's disabled links](https://www.scottohara.me/blog/2021/05/28/disabled-links.html) article
- adds `tertiary` style
# Changes from V9:
@ -57,7 +58,7 @@ adding a span around the text could potentially lead to regressions.
## Change the color scheme
@docs primary, secondary, danger, premium
@docs primary, secondary, tertiary, danger, premium
## Change the state (buttons only)
@ -417,6 +418,15 @@ secondary =
)
{-| -}
tertiary : Attribute msg
tertiary =
set
(\attributes ->
{ attributes | style = tertiaryColors }
)
{-| -}
danger : Attribute msg
danger =
@ -834,6 +844,16 @@ secondaryColors =
}
tertiaryColors : ColorPalette
tertiaryColors =
{ background = Colors.white
, hover = Colors.frost
, text = Colors.navy
, border = Just <| Colors.gray75
, shadow = Colors.gray75
}
getColorPalette : ButtonOrLink msg -> ColorPalette
getColorPalette (ButtonOrLink config) =
case config.state of

View File

@ -20,21 +20,19 @@ A caret that indicates that a section can expand and collapse. When `isOpen` is
-}
import Css exposing (..)
import Html.Styled exposing (..)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.SpriteSheet exposing (arrowLeft)
import Nri.Ui.Svg.V1 as NriSvg
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Nri.Ui.UiIcon.V1 as UiIcon
{-| -}
medium : List Css.Style -> Bool -> Html msg
medium : List Css.Style -> Bool -> Svg
medium styles isOpen =
view { isOpen = isOpen, size = px 15, styles = styles }
{-| -}
large : List Css.Style -> Bool -> Html msg
large : List Css.Style -> Bool -> Svg
large styles isOpen =
view { isOpen = isOpen, size = px 17, styles = styles }
@ -45,32 +43,19 @@ view :
, size : Css.Px
, styles : List Css.Style
}
-> Html msg
-> Svg
view { styles, size, isOpen } =
div
[ css
([ Css.display Css.inlineBlock
, cursor pointer
, minWidth size
, minHeight size
, maxWidth size
, maxHeight size
UiIcon.arrowLeft
|> Svg.withColor Colors.azure
|> Svg.withWidth size
|> Svg.withHeight size
|> Svg.withCss
([ property "transition" "transform 0.1s"
, if isOpen then
transform (rotate (deg -90))
else
transform (rotate (deg -180))
]
++ styles
)
]
[ arrowLeft
|> NriSvg.withCss
[ Css.displayFlex
, Css.justifyContent Css.center
, Css.alignItems Css.center
, color Colors.azure
, property "transition" "transform 0.1s"
, if isOpen then
transform (rotate (deg -90))
else
transform (rotate (deg -180))
]
|> NriSvg.toHtml
]

View File

@ -78,11 +78,7 @@ spinningPencil =
{-| -}
spinningDots : Nri.Ui.Svg.V1.Svg
spinningDots =
Svg.svg
[ SvgAttributes.width "100%"
, SvgAttributes.height "100%"
, SvgAttributes.viewBox "0 0 12.54 12.54"
]
Nri.Ui.Svg.V1.init "0 0 12.54 12.54"
[ Svg.circle [ SvgAttributes.fill "#004e95", SvgAttributes.cx "6.13", SvgAttributes.cy "0.98", SvgAttributes.r "0.98" ] []
, Svg.circle [ SvgAttributes.fill "#004cc9", SvgAttributes.cx "9.95", SvgAttributes.cy "2.47", SvgAttributes.r "0.98", SvgAttributes.transform "translate(1.12 7.67) rotate(-44.43)" ] []
, Svg.circle [ SvgAttributes.fill "#146aff", SvgAttributes.cx "11.56", SvgAttributes.cy "6.24", SvgAttributes.r "0.98", SvgAttributes.transform "translate(5.09 17.67) rotate(-88.86)" ] []
@ -92,7 +88,6 @@ spinningDots =
, Svg.circle [ SvgAttributes.fill "#f5f5f5", SvgAttributes.cx "0.98", SvgAttributes.cy "6.1", SvgAttributes.r "0.98", SvgAttributes.transform "translate(-5.16 6.71) rotate(-86.57)" ] []
, Svg.circle [ SvgAttributes.fill "#fff", SvgAttributes.cx "2.69", SvgAttributes.cy "2.37", SvgAttributes.r "0.98", SvgAttributes.transform "translate(-0.9 2.35) rotate(-41)" ] []
]
|> Nri.Ui.Svg.V1.fromHtml
|> Nri.Ui.Svg.V1.withWidth (Css.px 100)
|> Nri.Ui.Svg.V1.withHeight (Css.px 100)
|> Nri.Ui.Svg.V1.withCss circlingCss

View File

@ -22,6 +22,9 @@ module Nri.Ui.Logo.V1 exposing
-}
import Css
import Nri.Ui.Colors.Extra exposing (toCssString)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Svg.V1
import Svg.Styled as Svg
import Svg.Styled.Attributes as Attributes
@ -30,18 +33,13 @@ import Svg.Styled.Attributes as Attributes
{-| -}
noredink : Nri.Ui.Svg.V1.Svg
noredink =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
, Attributes.viewBox "0 0 109 24"
]
Nri.Ui.Svg.V1.init "0 0 109 24"
[ Svg.g
[ Attributes.fill "none"
, Attributes.fillRule "evenodd"
]
[ Svg.path
[ Attributes.fill "#F3336C"
[ Attributes.fill (toCssString Colors.red)
, Attributes.d "M4.29 6.03v2.048h.065c.943-1.723 2.568-2.503 4.453-2.503 2.795 0 4.453 1.527 4.453 4.972v12.97H8.776v-12.06c0-1.755-.586-2.437-1.918-2.437-1.528 0-2.373.943-2.373 2.892v11.604H0V6.03h4.29zM22.559 20.916c1.82 0 2.404-1.788 2.404-6.143 0-4.355-.584-6.143-2.404-6.143-2.21 0-2.405 2.568-2.405 6.143 0 3.575.195 6.143 2.405 6.143zm0-15.341c5.395-.098 6.89 3.12 6.89 9.198 0 5.98-1.755 9.198-6.89 9.198-5.396.098-6.89-3.12-6.89-9.198 0-5.98 1.754-9.198 6.89-9.198z"
]
[]
@ -51,41 +49,29 @@ noredink =
]
[]
, Svg.path
[ Attributes.fill "#F3336C"
[ Attributes.fill (toCssString Colors.red)
, Attributes.d "M69.336 6.03h4.486v17.486h-4.486V6.03zm0-5.981h4.486v3.835h-4.486V.05zM76.975 6.03h4.29v2.048h.065c.944-1.723 2.568-2.503 4.453-2.503 2.795 0 4.453 1.527 4.453 4.972v12.97H85.75v-12.06c0-1.755-.585-2.437-1.917-2.437-1.527 0-2.373.943-2.373 2.892v11.604h-4.485V6.03zM97.876.31v12.253h.065l4.518-6.533h4.94l-5.037 6.89 5.785 10.596h-4.94l-3.739-7.183-1.592 2.08v5.103H93.39V.31z"
]
[]
]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
facebook : Nri.Ui.Svg.V1.Svg
facebook =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
, Attributes.viewBox "0 0 10 19"
]
Nri.Ui.Svg.V1.init "0 0 10 19"
[ Svg.path
[ Attributes.d "M10 3.1H8.2c-1.4 0-1.7.7-1.7 1.6v2.1h3.4l-.5 3.4H6.5v8.6H2.9v-8.6H0V6.9h2.9V4.4C2.9 1.6 4.7 0 7.3 0c1.3 0 2.4.1 2.7.1v3z"
]
[]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
clever : Nri.Ui.Svg.V1.Svg
clever =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
, Attributes.viewBox "0 0 87 20"
]
Nri.Ui.Svg.V1.init "0 0 87 20"
[ Svg.g
[ Attributes.fillRule "evenodd"
]
@ -95,17 +81,12 @@ clever =
[]
]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
cleverC : Nri.Ui.Svg.V1.Svg
cleverC =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.viewBox "0 0 39 44"
]
Nri.Ui.Svg.V1.init "0 0 39 44"
[ Svg.g
[ Attributes.stroke "none"
, Attributes.strokeWidth "1"
@ -119,17 +100,12 @@ cleverC =
[ Svg.path [ Attributes.d "M0,21.7580775 C0,9.74321254 8.96637318,0 21.8178825,0 C29.708078,0 34.4301716,2.63016953 38.3153078,6.45581374 L32.4575445,13.2103396 C29.2296376,10.2814579 25.9422388,8.48824593 21.7580775,8.48824593 C14.7045264,8.48824593 9.62360245,14.3460092 9.62360245,21.5188573 C9.62360245,28.8113154 14.5849163,34.7890019 21.7580775,34.7890019 C26.5399762,34.7890019 29.4688578,32.8761798 32.7565697,29.8874931 L38.614333,35.8050615 C34.3105615,40.407545 29.5286628,43.2769347 21.4590522,43.2769347 C9.1454752,43.2769347 0,33.7726293 0,21.7580775 Z" ] [] ]
]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
cleverLibrary : Nri.Ui.Svg.V1.Svg
cleverLibrary =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.viewBox "0 0 580 198"
]
Nri.Ui.Svg.V1.init "0 0 580 198"
[ Svg.g [ Attributes.stroke "none", Attributes.strokeWidth "1", Attributes.fill "none", Attributes.fillRule "evenodd" ]
[ Svg.g [ Attributes.transform "translate(0.591000, 0.620000)" ]
[ Svg.rect [ Attributes.fill "#004E95", Attributes.x "0", Attributes.y "0", Attributes.width "579", Attributes.height "197", Attributes.rx "20" ] []
@ -144,35 +120,23 @@ cleverLibrary =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
twitter : Nri.Ui.Svg.V1.Svg
twitter =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
, Attributes.viewBox "0 0 20 16"
]
Nri.Ui.Svg.V1.init "0 0 20 16"
[ Svg.path
[ Attributes.d "M17.9 4.5c0 5.3-4.1 11.4-11.6 11.4-2.3 0-4.5-.7-6.3-1.8h1c1.9 0 3.7-.6 5.1-1.7-1.8 0-3.3-1.2-3.8-2.8.3 0 .5.1.8.1.4 0 .7 0 1.1-.1C2.3 9.2.9 7.6.9 5.7c.5.2 1.1.4 1.8.4C1.6 5.4.9 4.1.9 2.7c0-.7.2-1.4.6-2 2 2.4 5 4 8.4 4.2-.2-.3-.2-.6-.2-.9 0-2.2 1.8-4 4.1-4 1.2 0 2.2.5 3 1.3.9-.2 1.8-.5 2.6-1-.3.9-.9 1.7-1.8 2.2.8-.1 1.6-.3 2.3-.6-.6.8-1.3 1.5-2 2.1v.5z"
]
[]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
googleClassroom : Nri.Ui.Svg.V1.Svg
googleClassroom =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
, Attributes.viewBox "0 0 20 20"
]
Nri.Ui.Svg.V1.init "0 0 20 20"
[ Svg.g
[ Attributes.stroke "none"
, Attributes.strokeWidth "1"
@ -196,14 +160,12 @@ googleClassroom =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
googleG : Nri.Ui.Svg.V1.Svg
googleG =
Svg.svg
[ Attributes.viewBox "0 0 43 44" ]
Nri.Ui.Svg.V1.init "0 0 43 44"
[ Svg.defs []
[ Svg.style []
[ Svg.text ".googleG-icon-clip-path-class{clip-path:url(#googleG-icon-clip-path);}" ]
@ -220,18 +182,12 @@ googleG =
, Svg.g [ Attributes.class "googleG-icon-clip-path-class" ] [ Svg.path [ Attributes.fill "#34a853", Attributes.d "M-2,35,28,12l7.9,1L46-2V46H-2Z" ] [] ]
, Svg.g [ Attributes.class "googleG-icon-clip-path-class" ] [ Svg.path [ Attributes.fill "#4285f4", Attributes.d "M46,46,15,22l-4-3L46,9Z" ] [] ]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
canvas : Nri.Ui.Svg.V1.Svg
canvas =
Svg.svg
[ Attributes.viewBox "200 250 400 115"
, Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "#E72429"
]
Nri.Ui.Svg.V1.init "200 250 400 115"
[ Svg.g []
[ Svg.g []
[ Svg.path [ Attributes.d "M220.1,306.8c0-7-5.2-12.7-12-13.5c-1.1,4.3-1.7,8.8-1.7,13.5c0,4.7,0.6,9.2,1.7,13.5 C214.9,319.5,220.1,313.7,220.1,306.8z" ] []
@ -261,34 +217,25 @@ canvas =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
|> Nri.Ui.Svg.V1.withColor (Css.hex "#E72429")
{-| -}
canvasCircle : Nri.Ui.Svg.V1.Svg
canvasCircle =
Svg.svg
[ Attributes.viewBox "0 0 200 200"
, Attributes.width "100%"
, Attributes.height "100%"
]
Nri.Ui.Svg.V1.init "0 0 200 200"
[ Svg.path
[ Attributes.fill "#D64027"
, Attributes.d "M29.2 100c0-14.9-11.2-26.9-25.5-28.4C1.5 80.6 0 89.6 0 100s1.5 19.4 3.7 28.4C18 126.9 29.2 114.2 29.2 100L29.2 100zM46.4 90.3c5 0 9 4 9 9s-4 9-9 9 -9-4-9-9S41.5 90.3 46.4 90.3zM170.8 100c0 14.9 11.2 26.9 25.5 28.4 2.2-9 3.7-18.7 3.7-28.4s-1.5-19.4-3.7-28.4C182 73.1 170.8 85.1 170.8 100L170.8 100zM151.3 90.3c5 0 9 4 9 9s-4 9-9 9c-5 0-9-4-9-9S146.3 90.3 151.3 90.3zM99.6 170.9c-15 0-27 11.2-28.5 25.4 9 2.2 18.7 3.7 28.5 3.7s19.5-1.5 28.5-3.7C126.6 182.1 114.6 170.9 99.6 170.9L99.6 170.9zM98.9 142.5c5 0 9 4 9 9 0 4.9-4 9-9 9 -5 0-9-4-9-9C89.9 146.5 93.9 142.5 98.9 142.5zM99.6 29.1c15 0 27-11.2 28.5-25.4 -9-2.2-18.7-3.7-28.5-3.7S80.1 1.5 71.2 3.7C72.7 17.9 84.6 29.1 99.6 29.1L99.6 29.1zM98.9 38.1c5 0 9 4 9 9s-4 9-9 9c-5 0-9-4-9-9S93.9 38.1 98.9 38.1zM149.8 150c-10.5 10.4-11.2 26.9-2.2 38.1 16.5-9.7 30.7-23.9 40.4-40.3C176.8 138.8 160.3 139.6 149.8 150L149.8 150zM136.3 127.6c5 0 9 4 9 9 0 4.9-4 9-9 9 -5 0-9-4-9-9C127.3 131.6 131.4 127.6 136.3 127.6zM49.4 50c10.5-10.4 11.2-26.9 2.2-38.1C35.2 21.6 21 35.8 11.2 52.2 22.5 61.2 39 60.4 49.4 50L49.4 50zM61.4 53c5 0 9 4 9 9s-4 9-9 9 -9-4-9-9S56.5 53 61.4 53zM149.8 50c10.5 10.4 27 11.2 38.2 2.2 -9.7-16.4-24-30.6-40.4-40.3C138.6 23.1 139.3 39.6 149.8 50L149.8 50zM136.3 53c5 0 9 4 9 9s-4 9-9 9c-5 0-9-4-9-9S131.4 53 136.3 53zM49.4 150c-10.5-10.4-27-11.2-38.2-2.2 9.7 16.4 24 30.6 40.4 40.3C60.7 176.1 59.9 160.4 49.4 150L49.4 150zM61.4 127.6c5 0 9 4 9 9 0 4.9-4 9-9 9s-9-4-9-9C52.4 131.6 56.5 127.6 61.4 127.6z"
]
[]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
schoology : Nri.Ui.Svg.V1.Svg
schoology =
Svg.svg
[ Attributes.viewBox "0 0 928 163"
, Attributes.width "100%"
, Attributes.height "100%"
]
Nri.Ui.Svg.V1.init "0 0 928 163"
[ Svg.g [ Attributes.fillRule "nonzero" ]
[ Svg.path
[ Attributes.d "M81.5 163C36.6 163 0 126.4 0 81.5S36.6 0 81.5 0 163 36.6 163 81.5c0 45-36.5 81.5-81.5 81.5zm0-149.4c-37.5 0-68 30.5-68 68s30.5 68 68 68 68-30.5 68-68c0-37.6-30.5-68-68-68z"
@ -305,17 +252,12 @@ schoology =
[ Svg.path [ Attributes.d "M814.9 98.5h-23v-9.2H830v43.2h-9.5v-10s1.5-1.8 0 .1c-6.9 8.1-16.8 11.7-28.9 11.7-29.7 0-40.3-22.1-40.3-42 0-23 12.2-43.7 39.1-43.7 13 0 32.1 4.6 37.4 27.1l-15.1 1.4c-.5-3.3-3.4-18.5-21.8-18.5-23.5 0-24.5 25.5-24.5 32.7 0 8.8 1.7 16.3 5.3 21.8 4.6 7.4 11.6 10.8 20.1 10.8 19.7 0 21.9-16.1 22.8-22.5l.3-2.9zM241.2 96.7c-13-3.1-29-6.7-29-23.5 0-14.8 12.5-24 31.2-24 15.4 0 31.9 7.4 34.6 26.4l-14.7 1.9c-.2-5-.5-8.9-5.8-13.1-5.3-4.1-11.5-4.8-15.6-4.8-10.7 0-16 6.3-16 11.8 0 7.7 8.7 10.1 19.4 12.7L253 86c9.6 2.2 26.9 6.4 26.9 23.3 0 13.2-11.7 25.5-33.9 25.5-9.1 0-18.5-1.9-25-6.5-2.6-1.9-10.5-8.4-12-22l15.4-2.4c-.2 3.6-.2 10.5 6 15.8 4.8 4.1 10.8 4.6 16.3 4.6 12 0 19-4.6 19-13.4 0-9.2-7-11-16.8-12.9l-7.7-1.3zM366.1 103.2c-.5 3.3-1.4 7.7-4.6 13.7-6.7 12.3-18.2 17.8-33.1 17.8-29.7 0-40.3-22.1-40.3-42 0-23 12.2-43.8 39.1-43.8 13 0 32.1 4.6 37.4 27.1l-15.1 1.4c-.5-3.3-3.4-18.5-21.8-18.5-23.5 0-24.5 25.6-24.5 32.8 0 8.7 1.7 16.3 5.3 21.8 4.6 7.4 11.7 10.8 20.1 10.8 19.7 0 21.9-16.1 22.8-22.5l14.7 1.4zM374.3 11.1h13.9v48.5C396.8 50.5 405 49 412.7 49c17.8 0 24.9 10 27.3 17.9 1.6 5.1 1.6 10.5 1.6 18.5v47h-13.9V89.7c0-10.6 0-16.8-3.3-21.8-3.4-5-8.9-6.9-14.2-6.9-8.8 0-18.2 4.8-20.9 17.3-1 4.5-1 8.8-1 14.7v39.3h-14V11.1zM494.7 134.7c-28 0-39.8-20.9-39.8-42.2 0-18 8.9-43.6 40.3-43.6 26.8 0 39.1 20.8 38.9 42.9-.1 24.6-14.7 42.9-39.4 42.9zm23.7-54.2c-3.1-15.9-13.5-20.6-22.8-20.6-18.4 0-25.7 14.2-25.7 32.8 0 17 7 31 24.7 31 22.8 0 24.5-23.7 24.7-31.9.1-5.1-.4-8.9-.9-11.3zM583.4 134.7c-28 0-39.8-20.9-39.8-42.2 0-18 8.9-43.6 40.3-43.6 26.8 0 39.1 20.8 39 42.9-.3 24.6-14.8 42.9-39.5 42.9zM607 80.5c-3.1-15.9-13.5-20.6-22.8-20.6-18.4 0-25.7 14.2-25.7 32.8 0 17 7 31 24.7 31 22.8 0 24.5-23.7 24.7-31.9.2-5.1-.3-8.9-.9-11.3zM636.7 11.2h13.2v121.1h-13.2zM703.4 134.7c-27.9 0-39.8-20.9-39.8-42.2 0-18 8.9-43.6 40.3-43.6 26.8 0 39.1 20.8 38.9 42.9-.1 24.6-14.7 42.9-39.4 42.9zm23.7-54.2c-3.1-15.9-13.6-20.6-22.8-20.6-18.4 0-25.7 14.2-25.7 32.8 0 17 7 31 24.7 31 22.8 0 24.5-23.7 24.7-31.9.1-5.1-.4-8.9-.9-11.3zM900.8 50.4h-13l-20.9 33-20.4-33h-15.1l28.9 44.4v37.5h13.1V94.8l29.5-44.4h-2.1zM927.2 58.3c0 5-4 8.9-9.1 8.9s-9.1-3.9-9.1-8.9 4.1-8.8 9.2-8.8c5-.1 9 3.8 9 8.8zm-15.9 0c0 3.9 3 7.1 6.9 7.1 3.8.1 6.7-3.1 6.7-7s-2.9-7.1-6.9-7.1c-3.8-.1-6.7 3.1-6.7 7zm5.4 4.6h-2V54c.8-.1 1.9-.3 3.4-.3 1.7 0 2.4.3 3 .7.5.4.9 1 .9 1.9 0 1.1-.8 1.8-1.8 2.1v.1c.9.3 1.3 1 1.6 2.2.3 1.3.5 1.8.6 2.2h-2.2c-.3-.3-.4-1.1-.7-2.2-.2-.9-.7-1.4-1.8-1.4h-1v3.6zm.1-5h1c1.1 0 2-.4 2-1.3 0-.8-.6-1.4-1.9-1.4-.5 0-.9.1-1.1.1v2.6z" ] []
]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
schoologyCircle : Nri.Ui.Svg.V1.Svg
schoologyCircle =
Svg.svg
[ Attributes.viewBox "0 0 163 163"
, Attributes.width "100%"
, Attributes.height "100%"
]
Nri.Ui.Svg.V1.init "0 0 163 163"
[ Svg.g []
[ Svg.path
[ Attributes.d "M81.5 163C36.6 163 0 126.4 0 81.5S36.6 0 81.5 0 163 36.6 163 81.5c0 45-36.5 81.5-81.5 81.5zm0-149.4c-37.5 0-68 30.5-68 68s30.5 68 68 68 68-30.5 68-68c0-37.6-30.5-68-68-68z"
@ -329,4 +271,3 @@ schoologyCircle =
[]
]
]
|> Nri.Ui.Svg.V1.fromHtml

View File

@ -14,79 +14,51 @@ import Svg.Styled.Attributes as Attributes
{-| -}
levelZero : Nri.Ui.Svg.V1.Svg
levelZero =
Svg.svg
[ Attributes.viewBox "0 0 400 400"
, Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
]
Nri.Ui.Svg.V1.init "0 0 400 400"
[ Svg.path [ Attributes.d "M91.6,147.8l14,28.4l2.6,5.2l5.7,0.8l31.3,4.6l-22.7,22.1l-4.1,4l1,5.7l5.4,31.2l-28-14.7l-5.1-2.7l-5.1,2.7 l-28,14.7l5.4-31.2l1-5.7l-4.2-4l-22.8-22.1l31.4-4.6l5.7-0.8l2.6-5.2L91.6,147.8 M91.5,128.1c-2,0-3.5,1.9-4.3,3.6l-19.6,39.7 l-43.8,6.4c-2.2,0.4-4.9,1.4-4.9,4c0,1.6,1.1,3.1,2.2,4.2l31.8,30.9l-7.5,43.6c-0.1,0.6-0.2,1.2-0.2,1.8c0,2.3,1.1,4.4,3.7,4.4 c1.2,0,2.4-0.4,3.5-1l39.2-20.6l39.2,20.6c1.1,0.6,2.3,1,3.5,1c2.5,0,3.6-2.1,3.6-4.4c0-0.6,0-1.2-0.1-1.8l-7.5-43.6l31.7-30.9 c1.1-1.1,2.3-2.6,2.3-4.2c0-2.6-2.8-3.7-4.9-4l-43.8-6.4l-19.6-39.7C95.1,130,93.6,128,91.5,128.1L91.5,128.1z" ] []
, Svg.path [ Attributes.d "M308.4,147.8l14,28.4l2.6,5.2l5.7,0.8l31.3,4.6l-22.7,22.1l-4.1,4l1,5.7l5.4,31.2l-28-14.7l-5.1-2.7l-5.1,2.7 l-28,14.7l5.4-31.2l1-5.7l-4.1-4l-22.7-22.1l31.4-4.6l5.7-0.8l2.6-5.2L308.4,147.8 M308.4,128.1c-2,0-3.5,1.9-4.3,3.6l-19.6,39.7 l-43.8,6.4c-2.2,0.4-4.9,1.4-4.9,4c0,1.6,1.1,3.1,2.2,4.2l31.8,30.9l-7.5,43.6c-0.1,0.6-0.2,1.2-0.2,1.8c0,2.3,1.1,4.4,3.7,4.4 c1.2,0,2.4-0.4,3.5-1l39.2-20.6l39.2,20.6c1.1,0.6,2.3,1,3.5,1c2.5,0,3.6-2.1,3.6-4.4c0-0.6,0-1.2-0.1-1.8l-7.5-43.6l31.7-30.9 c1.1-1.1,2.3-2.6,2.3-4.2c0-2.6-2.8-3.7-4.9-4l-43.8-6.4l-19.6-39.7C311.9,130,310.4,128,308.4,128.1L308.4,128.1z" ] []
, Svg.path [ Attributes.d "M200.6,264.9l14,28.4l2.6,5.2l5.7,0.8l31.3,4.6L231.6,326l-4.1,4l1,5.7l5.3,31.3l-28.1-14.8l-5.1-2.7l-5.1,2.7 L167.4,367l5.4-31.2l1-5.7l-4.1-4L146.9,304l31.4-4.6l5.7-0.8l2.6-5.2L200.6,264.9 M200.6,245.2c-2,0-3.5,1.9-4.3,3.6l-19.6,39.7 l-43.8,6.3c-2.2,0.4-4.9,1.4-4.9,4c0,1.6,1.1,3,2.2,4.2l31.8,30.9l-7.5,43.6c-0.1,0.6-0.2,1.2-0.2,1.8c0,2.3,1.1,4.4,3.7,4.4 c1.2,0,2.4-0.4,3.5-1l39.2-20.6l39.2,20.6c1.1,0.6,2.3,1,3.5,1c2.5,0,3.6-2.1,3.6-4.4c0-0.6,0-1.2-0.1-1.8l-7.5-43.6l31.7-30.9 c1.1-1.1,2.3-2.6,2.3-4.2c0-2.6-2.8-3.7-4.9-4l-43.8-6.4l-19.6-39.7C204.1,247.1,202.6,245.2,200.6,245.2L200.6,245.2z" ] []
, Svg.path [ Attributes.d "M200.1,27.1l14,28.4l2.6,5.2l5.7,0.8l31.3,4.6l-22.7,22.1l-4.1,4l1,5.7l5.4,31.2l-28-14.7l-5.1-2.7l-5.1,2.7 L167,129.1l5.4-31.2l1-5.7l-4.2-4l-22.8-22.1l31.4-4.6l5.7-0.8l2.6-5.2L200.1,27.1 M200.1,7.3c-2,0-3.5,1.9-4.3,3.6l-19.6,39.7 L132.5,57c-2.2,0.4-4.9,1.4-4.9,4c0,1.6,1.1,3.1,2.2,4.2L161.5,96l-7.5,43.6c-0.1,0.6-0.2,1.2-0.2,1.8c0,2.3,1.1,4.4,3.7,4.4 c1.2,0,2.4-0.4,3.5-1l39.2-20.6l39.2,20.6c1.1,0.6,2.3,1,3.5,1c2.5,0,3.6-2.1,3.6-4.4c0-0.6,0-1.2-0.1-1.8L238.8,96l31.7-30.9 c1.1-1.1,2.3-2.6,2.3-4.2c0-2.6-2.8-3.7-4.9-4L224,50.6l-19.6-39.7C203.6,9.3,202.2,7.3,200.1,7.3L200.1,7.3z" ] []
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
levelOne : Nri.Ui.Svg.V1.Svg
levelOne =
Svg.svg
[ Attributes.viewBox "0 0 400 400"
, Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
]
Nri.Ui.Svg.V1.init "0 0 400 400"
[ Svg.path [ Attributes.d "M91.57,147.79l14,28.39,2.56,5.18,5.72.83,31.33,4.56-22.69,22.13-4.14,4,1,5.7,5.37,31.23L96.69,235.1l-5.12-2.69-5.12,2.69L58.4,249.84l5.37-31.23,1-5.71-4.15-4L37.87,186.76l31.39-4.56,5.72-.83,2.56-5.18,14-28.39m0-19.75c-2,0-3.49,1.92-4.27,3.58L67.67,171.31l-43.79,6.37c-2.18.35-4.88,1.4-4.88,4,0,1.57,1.13,3.05,2.18,4.19l31.75,30.88-7.5,43.61a11.94,11.94,0,0,0-.17,1.75c0,2.27,1.13,4.36,3.66,4.36a7.35,7.35,0,0,0,3.49-1l39.16-20.58,39.16,20.58a7.07,7.07,0,0,0,3.49,1c2.53,0,3.58-2.09,3.58-4.36a11.83,11.83,0,0,0-.09-1.75l-7.5-43.61,31.66-30.88c1.13-1.13,2.27-2.62,2.27-4.19,0-2.62-2.79-3.66-4.88-4l-43.79-6.37L95.84,131.62C95.06,130,93.58,128,91.57,128Z" ] []
, Svg.path [ Attributes.d "M308.43,147.79l14,28.39,2.56,5.18,5.72.83,31.33,4.56-22.69,22.13-4.14,4,1,5.7,5.37,31.23L313.55,235.1l-5.12-2.69-5.12,2.69-28.05,14.74,5.37-31.23,1-5.71-4.15-4-22.73-22.11,31.39-4.56,5.72-.83,2.56-5.18,14-28.39m0-19.75c-2,0-3.49,1.92-4.27,3.58l-19.62,39.69-43.79,6.37c-2.18.35-4.88,1.4-4.88,4,0,1.57,1.13,3.05,2.18,4.19l31.75,30.88-7.5,43.61a12,12,0,0,0-.17,1.75c0,2.27,1.13,4.36,3.66,4.36a7.35,7.35,0,0,0,3.49-1l39.16-20.58,39.16,20.58a7.07,7.07,0,0,0,3.49,1c2.53,0,3.58-2.09,3.58-4.36a11.81,11.81,0,0,0-.09-1.75l-7.5-43.61,31.66-30.88c1.13-1.13,2.27-2.62,2.27-4.19,0-2.62-2.79-3.66-4.88-4l-43.79-6.37L312.7,131.62c-.79-1.66-2.27-3.58-4.27-3.58Z" ] []
, Svg.path [ Attributes.d "M270.89,65.23,239.23,96.11l7.5,43.61a11.82,11.82,0,0,1,.09,1.75c0,2.27-1,4.36-3.58,4.36a7.07,7.07,0,0,1-3.49-1L200.59,124.2l-39.16,20.58a7.35,7.35,0,0,1-3.49,1c-2.53,0-3.66-2.09-3.66-4.36a11.94,11.94,0,0,1,.17-1.75l7.5-43.61L130.2,65.23c-1-1.13-2.18-2.62-2.18-4.19,0-2.62,2.7-3.66,4.88-4l43.79-6.37L196.31,11c.79-1.66,2.27-3.58,4.27-3.58s3.49,1.92,4.27,3.58l19.62,39.69L268.27,57c2.09.35,4.88,1.4,4.88,4C273.16,62.62,272,64.1,270.89,65.23Z" ] []
, Svg.path [ Attributes.d "M200.59,264.92l14,28.39,2.56,5.18,5.72.83,31.33,4.56L231.55,326l-4.14,4,1,5.7L233.76,367,205.7,352.23l-5.12-2.69-5.12,2.69L167.41,367l5.37-31.23,1-5.71-4.15-4-22.73-22.11,31.39-4.56,5.72-.83,2.56-5.18,14-28.39m0-19.75c-2,0-3.49,1.92-4.27,3.58l-19.62,39.69L132.9,294.8c-2.18.35-4.88,1.4-4.88,4,0,1.57,1.13,3.05,2.18,4.19l31.75,30.88-7.5,43.61a12,12,0,0,0-.17,1.75c0,2.27,1.13,4.36,3.66,4.36a7.35,7.35,0,0,0,3.49-1L200.59,362l39.16,20.58a7.07,7.07,0,0,0,3.49,1c2.53,0,3.58-2.09,3.58-4.36a11.83,11.83,0,0,0-.09-1.75l-7.5-43.61L270.89,303c1.13-1.13,2.27-2.62,2.27-4.19,0-2.62-2.79-3.66-4.88-4l-43.79-6.37-19.62-39.69c-.79-1.66-2.27-3.58-4.27-3.58Z" ] []
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
levelTwo : Nri.Ui.Svg.V1.Svg
levelTwo =
Svg.svg
[ Attributes.viewBox "0 0 400 400"
, Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
]
Nri.Ui.Svg.V1.init "0 0 400 400"
[ Svg.path [ Attributes.d "M91.57,147.79l14,28.39,2.56,5.18,5.72.83,31.33,4.56-22.69,22.13-4.14,4,1,5.7,5.37,31.23L96.69,235.1l-5.12-2.69-5.12,2.69L58.4,249.84l5.37-31.23,1-5.71-4.15-4L37.87,186.76l31.39-4.56,5.72-.83,2.56-5.18,14-28.39m0-19.75c-2,0-3.49,1.92-4.27,3.58L67.67,171.31l-43.79,6.37c-2.18.35-4.88,1.4-4.88,4,0,1.57,1.13,3.05,2.18,4.19l31.75,30.88-7.5,43.61a11.94,11.94,0,0,0-.17,1.75c0,2.27,1.13,4.36,3.66,4.36a7.35,7.35,0,0,0,3.49-1l39.16-20.58,39.16,20.58a7.07,7.07,0,0,0,3.49,1c2.53,0,3.58-2.09,3.58-4.36a11.83,11.83,0,0,0-.09-1.75l-7.5-43.61,31.66-30.88c1.13-1.13,2.27-2.62,2.27-4.19,0-2.62-2.79-3.66-4.88-4l-43.79-6.37L95.84,131.62C95.06,130,93.58,128,91.57,128Z" ] []
, Svg.path [ Attributes.d "M378.73,185.87l-31.66,30.88,7.5,43.61a11.82,11.82,0,0,1,.09,1.75c0,2.27-1,4.36-3.58,4.36a7.07,7.07,0,0,1-3.49-1l-39.16-20.58-39.16,20.58a7.35,7.35,0,0,1-3.49,1c-2.53,0-3.66-2.09-3.66-4.36a11.94,11.94,0,0,1,.17-1.75l7.5-43.61L238,185.87c-1-1.13-2.18-2.62-2.18-4.19,0-2.62,2.7-3.66,4.88-4l43.79-6.37,19.62-39.69c.79-1.66,2.27-3.58,4.27-3.58s3.49,1.92,4.27,3.58l19.62,39.69,43.79,6.37c2.09.35,4.88,1.4,4.88,4C381,183.26,379.87,184.74,378.73,185.87Z" ] []
, Svg.path [ Attributes.d "M270.89,65.23,239.23,96.11l7.5,43.61a11.82,11.82,0,0,1,.09,1.75c0,2.27-1,4.36-3.58,4.36a7.07,7.07,0,0,1-3.49-1L200.59,124.2l-39.16,20.58a7.35,7.35,0,0,1-3.49,1c-2.53,0-3.66-2.09-3.66-4.36a11.94,11.94,0,0,1,.17-1.75l7.5-43.61L130.2,65.23c-1-1.13-2.18-2.62-2.18-4.19,0-2.62,2.7-3.66,4.88-4l43.79-6.37L196.31,11c.79-1.66,2.27-3.58,4.27-3.58s3.49,1.92,4.27,3.58l19.62,39.69L268.27,57c2.09.35,4.88,1.4,4.88,4C273.16,62.62,272,64.1,270.89,65.23Z" ] []
, Svg.path [ Attributes.d "M200.59,264.92l14,28.39,2.56,5.18,5.72.83,31.33,4.56L231.55,326l-4.14,4,1,5.7L233.76,367,205.7,352.23l-5.12-2.69-5.12,2.69L167.41,367l5.37-31.23,1-5.71-4.15-4-22.73-22.11,31.39-4.56,5.72-.83,2.56-5.18,14-28.39m0-19.75c-2,0-3.49,1.92-4.27,3.58l-19.62,39.69L132.9,294.8c-2.18.35-4.88,1.4-4.88,4,0,1.57,1.13,3.05,2.18,4.19l31.75,30.88-7.5,43.61a12,12,0,0,0-.17,1.75c0,2.27,1.13,4.36,3.66,4.36a7.35,7.35,0,0,0,3.49-1L200.59,362l39.16,20.58a7.07,7.07,0,0,0,3.49,1c2.53,0,3.58-2.09,3.58-4.36a11.83,11.83,0,0,0-.09-1.75l-7.5-43.61L270.89,303c1.13-1.13,2.27-2.62,2.27-4.19,0-2.62-2.79-3.66-4.88-4l-43.79-6.37-19.62-39.69c-.79-1.66-2.27-3.58-4.27-3.58Z" ] []
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
levelThree : Nri.Ui.Svg.V1.Svg
levelThree =
Svg.svg
[ Attributes.viewBox "0 0 400 400"
, Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
]
Nri.Ui.Svg.V1.init "0 0 400 400"
[ Svg.path [ Attributes.d "M91.57,147.79l14,28.39,2.56,5.18,5.72.83,31.33,4.56-22.69,22.13-4.14,4,1,5.7,5.37,31.23L96.69,235.1l-5.12-2.69-5.12,2.69L58.4,249.84l5.37-31.23,1-5.71-4.15-4L37.87,186.76l31.39-4.56,5.72-.83,2.56-5.18,14-28.39m0-19.75c-2,0-3.49,1.92-4.27,3.58L67.67,171.31l-43.79,6.37c-2.18.35-4.88,1.4-4.88,4,0,1.57,1.13,3.05,2.18,4.19l31.75,30.88-7.5,43.61a11.94,11.94,0,0,0-.17,1.75c0,2.27,1.13,4.36,3.66,4.36a7.35,7.35,0,0,0,3.49-1l39.16-20.58,39.16,20.58a7.07,7.07,0,0,0,3.49,1c2.53,0,3.58-2.09,3.58-4.36a11.83,11.83,0,0,0-.09-1.75l-7.5-43.61,31.66-30.88c1.13-1.13,2.27-2.62,2.27-4.19,0-2.62-2.79-3.66-4.88-4l-43.79-6.37L95.84,131.62C95.06,130,93.58,128,91.57,128Z" ] []
, Svg.path [ Attributes.d "M378.73,185.87l-31.66,30.88,7.5,43.61a11.82,11.82,0,0,1,.09,1.75c0,2.27-1,4.36-3.58,4.36a7.07,7.07,0,0,1-3.49-1l-39.16-20.58-39.16,20.58a7.35,7.35,0,0,1-3.49,1c-2.53,0-3.66-2.09-3.66-4.36a11.94,11.94,0,0,1,.17-1.75l7.5-43.61L238,185.87c-1-1.13-2.18-2.62-2.18-4.19,0-2.62,2.7-3.66,4.88-4l43.79-6.37,19.62-39.69c.79-1.66,2.27-3.58,4.27-3.58s3.49,1.92,4.27,3.58l19.62,39.69,43.79,6.37c2.09.35,4.88,1.4,4.88,4C381,183.26,379.87,184.74,378.73,185.87Z" ] []
, Svg.path [ Attributes.d "M270.89,65.23,239.23,96.11l7.5,43.61a11.82,11.82,0,0,1,.09,1.75c0,2.27-1,4.36-3.58,4.36a7.07,7.07,0,0,1-3.49-1L200.59,124.2l-39.16,20.58a7.35,7.35,0,0,1-3.49,1c-2.53,0-3.66-2.09-3.66-4.36a11.94,11.94,0,0,1,.17-1.75l7.5-43.61L130.2,65.23c-1-1.13-2.18-2.62-2.18-4.19,0-2.62,2.7-3.66,4.88-4l43.79-6.37L196.31,11c.79-1.66,2.27-3.58,4.27-3.58s3.49,1.92,4.27,3.58l19.62,39.69L268.27,57c2.09.35,4.88,1.4,4.88,4C273.16,62.62,272,64.1,270.89,65.23Z" ] []
, Svg.path [ Attributes.d "M270.89,303l-31.66,30.88,7.5,43.61a11.82,11.82,0,0,1,.09,1.75c0,2.27-1,4.36-3.58,4.36a7.07,7.07,0,0,1-3.49-1L200.59,362l-39.16,20.58a7.35,7.35,0,0,1-3.49,1c-2.53,0-3.66-2.09-3.66-4.36a11.94,11.94,0,0,1,.17-1.75l7.5-43.61L130.2,303c-1-1.13-2.18-2.62-2.18-4.19,0-2.62,2.7-3.66,4.88-4l43.79-6.37,19.62-39.69c.79-1.66,2.27-3.58,4.27-3.58s3.49,1.92,4.27,3.58l19.62,39.69,43.79,6.37c2.09.35,4.88,1.4,4.88,4C273.16,300.38,272,301.87,270.89,303Z" ] []
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
levelFour : Nri.Ui.Svg.V1.Svg
levelFour =
Svg.svg
[ Attributes.viewBox "0 0 400 400"
, Attributes.width "100%"
, Attributes.height "100%"
]
Nri.Ui.Svg.V1.init "0 0 400 400"
[ Svg.path
[ Attributes.fill "currentcolor"
, Attributes.d "M161.87,185.87l-31.66,30.88,7.5,43.61a11.82,11.82,0,0,1,.09,1.75c0,2.27-1,4.36-3.58,4.36a7.07,7.07,0,0,1-3.49-1L91.57,244.84,52.41,265.42a7.35,7.35,0,0,1-3.49,1c-2.53,0-3.66-2.09-3.66-4.36a11.94,11.94,0,0,1,.17-1.75l7.5-43.61L21.18,185.87c-1-1.13-2.18-2.62-2.18-4.19,0-2.62,2.7-3.66,4.88-4l43.79-6.37L87.3,131.62c.79-1.66,2.27-3.58,4.27-3.58s3.49,1.92,4.27,3.58l19.62,39.69,43.79,6.37c2.09.35,4.88,1.4,4.88,4C164.14,183.26,163,184.74,161.87,185.87Z"
@ -108,4 +80,3 @@ levelFour =
]
[]
]
|> Nri.Ui.Svg.V1.fromHtml

View File

@ -1,7 +1,7 @@
module Nri.Ui.Menu.V3 exposing
( view, button, custom, Config
, Attribute, Button, ButtonAttribute
, alignment, isDisabled, menuWidth, buttonId, menuId, menuZIndex, opensOnHover
, alignment, isDisabled, menuWidth, buttonId, menuId, menuZIndex, opensOnHover, disclosure
, Alignment(..)
, icon, wrapping, hasBorder, buttonWidth
, TitleWrapping(..)
@ -30,7 +30,7 @@ A togglable menu view and related buttons.
## Menu attributes
@docs alignment, isDisabled, menuWidth, buttonId, menuId, menuZIndex, opensOnHover
@docs alignment, isDisabled, menuWidth, buttonId, menuId, menuZIndex, opensOnHover, disclosure
@docs Alignment
@ -63,6 +63,7 @@ import Nri.Ui.Html.V3 exposing (viewJust)
import Nri.Ui.Shadows.V1 as Shadows
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.UiIcon.V1 as UiIcon
import Nri.Ui.WhenFocusLeaves.V1 as WhenFocusLeaves
{-| -}
@ -105,6 +106,7 @@ type alias MenuConfig msg =
, menuId : String
, zIndex : Int
, opensOnHover : Bool
, purpose : Purpose
}
@ -116,6 +118,11 @@ type alias ButtonConfig =
}
type Purpose
= NavMenu
| Disclosure { lastId : String }
-- Generators for ButtonAttribute
@ -201,6 +208,21 @@ opensOnHover value =
Attribute <| \config -> { config | opensOnHover = value }
{-| Makes the menu behave as a disclosure.
For more information, please read [Disclosure (Show/Hide) pattern](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/).
You will need to pass in the last focusable element in the disclosed content in order for:
- any focusable elements in the disclosed content to be keyboard accessible
- the disclosure to close appropriately when the user tabs past all of the disclosed content
-}
disclosure : { lastId : String } -> Attribute msg
disclosure exitFocusManager =
Attribute (\config -> { config | purpose = Disclosure exitFocusManager })
{-| Menu/pulldown configuration:
- `attributes`: List of (attributes)[#menu-attributes] to apply to the menu.
@ -226,6 +248,7 @@ view attributes config =
, menuId = ""
, zIndex = 1
, opensOnHover = False
, purpose = NavMenu
}
menuConfig =
@ -364,7 +387,7 @@ viewArrow { isOpen } =
[ Css.Global.svg [ display block ]
]
, property "transform-origin" "center"
, property "transition" "transform 0.1s"
, property "transition" "transform 0.4s"
, if isOpen then
transform (rotate (deg 180))
@ -415,25 +438,46 @@ viewCustom config =
div
(Attributes.id (config.buttonId ++ "__container")
:: Key.onKeyDown
[ Key.escape
(Key.escape
(config.focusAndToggle
{ isOpen = False
, focus = Just config.buttonId
}
)
, Key.tab
(config.focusAndToggle
{ isOpen = False
, focus = Nothing
}
)
, Key.tabBack
(config.focusAndToggle
{ isOpen = False
, focus = Nothing
}
)
]
:: (case config.purpose of
NavMenu ->
[ Key.tab
(config.focusAndToggle
{ isOpen = False
, focus = Nothing
}
)
, Key.tabBack
(config.focusAndToggle
{ isOpen = False
, focus = Nothing
}
)
]
Disclosure { lastId } ->
[ WhenFocusLeaves.toDecoder
{ firstId = config.buttonId
, lastId = lastId
, tabBackAction =
config.focusAndToggle
{ isOpen = False
, focus = Nothing
}
, tabForwardAction =
config.focusAndToggle
{ isOpen = False
, focus = Nothing
}
}
]
)
)
:: styleContainer
)
[ if config.isOpen then
@ -475,12 +519,18 @@ viewCustom config =
[ let
buttonAttributes =
[ Aria.disabled config.isDisabled
, Aria.hasMenuPopUp
, case config.purpose of
NavMenu ->
Aria.hasMenuPopUp
Disclosure _ ->
AttributesExtra.none
, Aria.expanded config.isOpen
, -- Whether the menu is open or closed, move to the
-- first menu item if the "down" arrow is pressed
case ( maybeFirstFocusableElementId, maybeLastFocusableElementId ) of
( Just firstFocusableElementId, Just lastFocusableElementId ) ->
-- as long as it's not a Disclosed
case ( config.purpose, maybeFirstFocusableElementId, maybeLastFocusableElementId ) of
( NavMenu, Just firstFocusableElementId, Just lastFocusableElementId ) ->
onKeyDownPreventDefault
[ Key.down
(config.focusAndToggle
@ -544,7 +594,12 @@ viewCustom config =
, div
[ classList [ ( "Content", True ), ( "ContentVisible", contentVisible ) ]
, styleContent contentVisible config
, Role.menu
, case config.purpose of
NavMenu ->
Role.menu
Disclosure _ ->
AttributesExtra.none
, Aria.labelledBy config.buttonId
, Attributes.id config.menuId
, Aria.hidden (not config.isOpen)

View File

@ -768,7 +768,6 @@ getIcon customIcon size theme =
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withLabel "Error"
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
( Nothing, Alert ) ->
@ -787,7 +786,6 @@ getIcon customIcon size theme =
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withLabel "Alert"
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
( Nothing, Tip ) ->
@ -870,7 +868,6 @@ getIcon customIcon size theme =
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withLabel "Success"
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
( Just icon_, _ ) ->
@ -878,7 +875,6 @@ getIcon customIcon size theme =
|> NriSvg.withWidth iconSize
|> NriSvg.withHeight iconSize
|> NriSvg.withCss [ marginRight, Css.flexShrink Css.zero ]
|> NriSvg.withNriDescription messageIconDescription
|> NriSvg.toHtml
( Nothing, Custom _ ) ->

View File

@ -170,6 +170,7 @@ import Css.Transitions
import Html.Styled as Root
import Html.Styled.Attributes as Attrs exposing (id)
import Html.Styled.Events exposing (onClick)
import Nri.Ui.ClickableSvg.V2 as ClickableSvg
import Nri.Ui.Colors.Extra
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.FocusTrap.V1 as FocusTrap exposing (FocusTrap)
@ -177,8 +178,7 @@ import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Html.Attributes.V2 as ExtraAttributes
import Nri.Ui.MediaQuery.V1 exposing (mobile)
import Nri.Ui.Shadows.V1 as Shadows
import Nri.Ui.SpriteSheet
import Nri.Ui.Svg.V1
import Nri.Ui.UiIcon.V1 as UiIcon
import Task
@ -721,34 +721,32 @@ closeButtonId =
{-| -}
viewCloseButton : msg -> Html msg
viewCloseButton closeModal =
button
(Aria.label "Close modal"
:: onClick closeModal
:: Attrs.css
[ -- in the upper-right corner of the modal
Css.position Css.absolute
, Css.top Css.zero
, Css.right Css.zero
ClickableSvg.button "Close modal"
UiIcon.x
[ ClickableSvg.id closeButtonId
, ClickableSvg.onClick closeModal
, -- TODO: trim down the unnecessary styles
ClickableSvg.css
[ -- in the upper-right corner of the modal
Css.position Css.absolute
, Css.top Css.zero
, Css.right Css.zero
-- make appear above lesson content
, Css.zIndex (Css.int 10)
, Css.backgroundColor (rgba 255 255 255 0.5)
, Css.borderRadius (pct 50)
-- make appear above lesson content
, Css.zIndex (Css.int 10)
, Css.backgroundColor (rgba 255 255 255 0.5)
, Css.borderRadius (pct 50)
-- make the hitspace extend all the way around x
, Css.width (Css.px 60)
, Css.height (Css.px 60)
, Css.padding (Css.px 20)
-- make the hitspace extend all the way around x
, Css.width (Css.px 60)
, Css.height (Css.px 60)
, Css.padding (Css.px 20)
-- apply button styles
, Css.borderWidth Css.zero
, Css.cursor Css.pointer
, Css.color Colors.azure
, Css.hover [ Css.color Colors.azureDark ]
, Css.Transitions.transition [ Css.Transitions.color 0.1 ]
]
:: Attrs.id closeButtonId
:: []
)
[ Nri.Ui.Svg.V1.toHtml Nri.Ui.SpriteSheet.xSvg
-- apply button styles
, Css.borderWidth Css.zero
, Css.cursor Css.pointer
, Css.color Colors.azure
, Css.hover [ Css.color Colors.azureDark ]
, Css.Transitions.transition [ Css.Transitions.color 0.1 ]
]
]

View File

@ -6,6 +6,8 @@ module Nri.Ui.Pennant.V2 exposing (premiumFlag, disabledPremiumFlag, expiredPrem
-}
import Nri.Ui.Colors.Extra exposing (toCssString)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Svg.V1 exposing (Svg)
import Svg.Styled as Svg
import Svg.Styled.Attributes as Attributes
@ -14,11 +16,7 @@ import Svg.Styled.Attributes as Attributes
{-| -}
premiumFlag : Svg
premiumFlag =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.viewBox "0 0 25 18"
]
Nri.Ui.Svg.V1.init "0 0 25 18"
[ Svg.g
[ Attributes.stroke "none"
, Attributes.strokeWidth "1"
@ -49,17 +47,12 @@ premiumFlag =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
disabledPremiumFlag : Nri.Ui.Svg.V1.Svg
disabledPremiumFlag =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.viewBox "0 0 25 18"
]
Nri.Ui.Svg.V1.init "0 0 25 18"
[ Svg.g
[ Attributes.stroke "none"
, Attributes.strokeWidth "1"
@ -90,17 +83,12 @@ disabledPremiumFlag =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
expiredPremiumFlag : Nri.Ui.Svg.V1.Svg
expiredPremiumFlag =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.viewBox "0 0 25 18"
]
Nri.Ui.Svg.V1.init "0 0 25 18"
[ Svg.g
[ Attributes.stroke "none"
, Attributes.strokeWidth "1"
@ -117,7 +105,7 @@ expiredPremiumFlag =
[ Attributes.transform "translate(0.000000, 446.000000)"
]
[ Svg.polygon
[ Attributes.fill "#F3336C"
[ Attributes.fill (toCssString Colors.red)
, Attributes.points "12.7757004 0 1.73472348e-16 0 1.73472348e-16 14.2404227 0 16.2706817 0 18 7.34267839 18 25 18 19.566978 9 25 0"
]
[]
@ -131,4 +119,3 @@ expiredPremiumFlag =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml

View File

@ -577,7 +577,7 @@ radioInputIcon config =
unselectedSvg : Svg
unselectedSvg =
Svg.svg [ SvgAttributes.viewBox "0 0 27 27" ]
Nri.Ui.Svg.V1.init "0 0 27 27"
[ Svg.defs []
[ Svg.rect [ SvgAttributes.id "unselected-path-1", SvgAttributes.x "0", SvgAttributes.y "0", SvgAttributes.width "27", SvgAttributes.height "27", SvgAttributes.rx "13.5" ] []
, Svg.filter [ SvgAttributes.id "unselected-filter-2", SvgAttributes.x "-3.7%", SvgAttributes.y "-3.7%", SvgAttributes.width "107.4%", SvgAttributes.height "107.4%", SvgAttributes.filterUnits "objectBoundingBox" ] [ Svg.feOffset [ SvgAttributes.dx "0", SvgAttributes.dy "2", SvgAttributes.in_ "SourceAlpha", SvgAttributes.result "shadowOffsetInner1" ] [], Svg.feComposite [ SvgAttributes.in_ "shadowOffsetInner1", SvgAttributes.in2 "SourceAlpha", SvgAttributes.operator "arithmetic", SvgAttributes.k2 "-1", SvgAttributes.k3 "1", SvgAttributes.result "shadowInnerInner1" ] [], Svg.feColorMatrix [ SvgAttributes.values "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0", SvgAttributes.in_ "shadowInnerInner1" ] [] ]
@ -607,13 +607,12 @@ unselectedSvg =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
|> withImageBorder Colors.gray75
selectedSvg : Svg
selectedSvg =
Svg.svg [ SvgAttributes.viewBox "0 0 27 27" ]
Nri.Ui.Svg.V1.init "0 0 27 27"
[ Svg.defs []
[ Svg.rect [ SvgAttributes.id "selected-path-1", SvgAttributes.x "0", SvgAttributes.y "0", SvgAttributes.width "27", SvgAttributes.height "27", SvgAttributes.rx "13.5" ] []
, Svg.filter
@ -652,13 +651,12 @@ selectedSvg =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
|> withImageBorder Colors.azure
lockedSvg : Svg
lockedSvg =
Svg.svg [ SvgAttributes.viewBox "0 0 30 30" ]
Nri.Ui.Svg.V1.init "0 0 30 30"
[ Svg.defs []
[ Svg.rect [ SvgAttributes.id "locked-path-1", SvgAttributes.x "0", SvgAttributes.y "0", SvgAttributes.width "30", SvgAttributes.height "30", SvgAttributes.rx "15" ] []
, Svg.filter [ SvgAttributes.id "locked-filter-2", SvgAttributes.x "-3.3%", SvgAttributes.y "-3.3%", SvgAttributes.width "106.7%", SvgAttributes.height "106.7%", SvgAttributes.filterUnits "objectBoundingBox" ] [ Svg.feOffset [ SvgAttributes.dx "0", SvgAttributes.dy "2", SvgAttributes.in_ "SourceAlpha", SvgAttributes.result "shadowOffsetInner1" ] [], Svg.feComposite [ SvgAttributes.in_ "shadowOffsetInner1", SvgAttributes.in2 "SourceAlpha", SvgAttributes.operator "arithmetic", SvgAttributes.k2 "-1", SvgAttributes.k3 "1", SvgAttributes.result "shadowInnerInner1" ] [], Svg.feColorMatrix [ SvgAttributes.values "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0", SvgAttributes.in_ "shadowInnerInner1" ] [] ]
@ -700,7 +698,6 @@ lockedSvg =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
|> withImageBorder Colors.gray75

View File

@ -1,6 +1,7 @@
module Nri.Ui.Select.V8 exposing
( view, generateId
, Choice, choices
, ChoicesGroup, groupedChoices
, value
, Attribute, defaultDisplayText
, hiddenLabel, visibleLabel
@ -24,6 +25,7 @@ module Nri.Ui.Select.V8 exposing
### Input types
@docs Choice, choices
@docs ChoicesGroup, groupedChoices
### Input content
@ -160,6 +162,26 @@ noMargin removeMargin =
Attribute <| \config -> { config | noMarginTop = removeMargin }
{-| Groupings of choices (will be added _after_ isolated choices.)
-}
type alias ChoicesGroup value =
{ label : String
, choices : List (Choice value)
}
{-| -}
groupedChoices : (value -> String) -> List (ChoicesGroup value) -> Attribute value
groupedChoices valueToString optgroups =
Attribute
(\config ->
{ config
| valueToString = Just valueToString
, optgroups = optgroups
}
)
{-| A single possible choice.
-}
type alias Choice value =
@ -195,6 +217,7 @@ type alias Config value =
{ id : Maybe String
, value : Maybe value
, choices : List (Choice value)
, optgroups : List (ChoicesGroup value)
, valueToString : Maybe (value -> String)
, defaultDisplayText : Maybe String
, error : ErrorState
@ -211,6 +234,7 @@ defaultConfig =
{ id = Nothing
, value = Nothing
, choices = []
, optgroups = []
, valueToString = Nothing
, defaultDisplayText = Nothing
, error = InputErrorAndGuidanceInternal.noError
@ -255,6 +279,7 @@ view label attributes =
config
, viewSelect
{ choices = config.choices
, optgroups = config.optgroups
, current = config.value
, id = id_
, custom = config.custom
@ -268,6 +293,7 @@ view label attributes =
viewSelect :
{ choices : List (Choice a)
, optgroups : List (ChoicesGroup a)
, current : Maybe a
, id : String
, valueToString : Maybe (a -> String)
@ -278,23 +304,25 @@ viewSelect :
-> Html a
viewSelect config =
let
stringChoices =
toChoice valueToString choice =
{ label = choice.label
, idAndValue = generateId (valueToString choice.value)
, value = choice.value
}
( optionStringChoices, groupStringChoices ) =
case config.valueToString of
Just valueToString ->
List.map
(\choice ->
{ label = choice.label
, idAndValue = generateId (valueToString choice.value)
, value = choice.value
}
)
config.choices
( List.map (toChoice valueToString) config.choices
, List.concatMap (.choices >> List.map (toChoice valueToString)) config.optgroups
)
Nothing ->
[]
( [], [] )
valueLookup =
stringChoices
optionStringChoices
++ groupStringChoices
|> List.map (\x -> ( x.idAndValue, x.value ))
|> Dict.fromList
@ -327,10 +355,23 @@ viewSelect config =
else
config.current
viewGroupedChoices group =
Html.optgroup [ Attributes.attribute "label" group.label ]
(case config.valueToString of
Just valueToString ->
List.map
(toChoice valueToString >> viewChoice currentVal)
group.choices
Nothing ->
[]
)
in
stringChoices
|> List.map (viewChoice currentVal)
|> (++) defaultOption
(defaultOption
++ List.map (viewChoice currentVal) optionStringChoices
++ List.map viewGroupedChoices config.optgroups
)
|> Nri.Ui.styled Html.select
"nri-select-menu"
[ -- border

View File

@ -1,184 +0,0 @@
module Nri.Ui.SpriteSheet exposing
( arrowLeft
, bulb
, checkmark
, exclamationMark
, xSvg
)
{-|
@docs arrowLeft
@docs bulb
@docs checkmark
@docs exclamationMark
@docs xSvg
-}
import Html.Styled exposing (..)
import Nri.Ui.Svg.V1 as NriSvg
import Svg exposing (..)
import Svg.Attributes exposing (..)
{-| -}
exclamationMark : NriSvg.Svg
exclamationMark =
Svg.svg
[ viewBox "0 0 4 12", width "100%", height "100%" ]
[ Svg.path
[ d "M3.234 10.575a1.363 1.363 0 1 1-2.726 0 1.363 1.363 0 0 1 2.726 0zm.648-8.398a1.978 1.978 0 0 1-.007.047l-.834 5.294c-.079.53-.542.926-1.085.926h-.013a1.096 1.096 0 0 1-1.085-.926L.024 2.224A1.93 1.93 0 0 1 1.93 0h.04a1.94 1.94 0 0 1 1.912 1.663v.514z"
, fill "currentcolor"
, fillRule "evenodd"
]
[]
]
|> fromUnstyled
|> NriSvg.fromHtml
{-| -}
checkmark : NriSvg.Svg
checkmark =
Svg.svg
[ x "0px"
, y "0px"
, viewBox "0 0 21.7 17.1"
, Svg.Attributes.style "enable-background:new 0 0 21.7 17.1;"
, width "100%"
, height "100%"
]
[ Svg.path
[ fill "currentcolor"
, d "M7.6,17.1c-0.5,0-1-0.2-1.4-0.6l-5.6-5.4c-0.8-0.8-0.8-2-0.1-2.8c0.8-0.8,2-0.8,2.8-0.1l4.1,4 L18.2,0.7c0.8-0.8,2-0.9,2.8-0.1s0.9,2,0.1,2.8l-12,13C8.7,16.9,8.2,17.1,7.6,17.1C7.7,17.1,7.6,17.1,7.6,17.1"
]
[]
]
|> fromUnstyled
|> NriSvg.fromHtml
{-| -}
bulb : NriSvg.Svg
bulb =
svg
[ x "0px"
, y "0px"
, viewBox "0 0 23 25"
, Svg.Attributes.style "enable-background:new 0 0 23 25;"
, width "100%"
, height "100%"
]
[ Svg.style [] [ Svg.text ".blub-st0{fill:#FEC709;} " ]
, g []
[ g [ transform "translate(-261.000000, -371.000000)" ]
[ g
[ transform "translate(259.886945, 371.000000)"
]
[ g [ transform "translate(0.859754, 0.051946)" ]
[ g [ transform "translate(0.461538, 0.000000)" ]
[ Svg.path
[ class "blub-st0"
, d "M21.6,12.5H19c-0.3,0-0.6,0.3-0.6,0.6s0.3,0.6,0.6,0.6h2.6c0.3,0,0.6-0.3,0.6-0.6 S21.9,12.5,21.6,12.5z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M18.1,9.3c0.1,0,0.2,0,0.3-0.1l2.3-1.4C20.9,7.7,21,7.3,20.8,7c-0.2-0.3-0.5-0.4-0.8-0.2 l-2.3,1.4c-0.2,0.1-0.3,0.4-0.3,0.7C17.6,9.1,17.8,9.3,18.1,9.3L18.1,9.3z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M17.1,2c-0.3-0.2-0.6-0.1-0.8,0.2l-1.5,2.2h0c-0.1,0.1-0.1,0.3-0.1,0.5c0,0.2,0.1,0.3,0.2,0.4 c0.1,0.1,0.3,0.1,0.4,0.1c0.2,0,0.3-0.1,0.4-0.3l1.5-2.2C17.4,2.6,17.4,2.2,17.1,2L17.1,2z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M6.7,5.4c0.2,0,0.4-0.1,0.5-0.3c0.1-0.2,0.1-0.4,0-0.6L5.7,2.2v0C5.6,2.1,5.4,2,5.3,1.9 C5.1,1.9,5,1.9,4.9,2C4.7,2.1,4.6,2.3,4.6,2.4c0,0.2,0,0.3,0.1,0.4l1.5,2.2C6.3,5.3,6.5,5.4,6.7,5.4L6.7,5.4z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M4,8.2L1.7,6.8C1.5,6.7,1.1,6.8,1,7C0.8,7.3,0.9,7.6,1.2,7.8l2.3,1.4c0.1,0.1,0.3,0.1,0.4,0.1 C4,9.2,4.1,9.1,4.2,9c0.1-0.1,0.1-0.3,0.1-0.5C4.2,8.4,4.1,8.2,4,8.2L4,8.2z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M20.6,17.8l-2.2-1.4c-0.3-0.2-0.6-0.1-0.8,0.2c-0.2,0.3-0.1,0.6,0.2,0.8l2.3,1.4 c0.3,0.1,0.6,0,0.7-0.2C21,18.3,20.9,18,20.6,17.8L20.6,17.8z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M3.5,16.4l-2.3,1.4h0C1.1,17.8,1,18,0.9,18.1c0,0.2,0,0.3,0.1,0.5c0.1,0.1,0.2,0.2,0.4,0.3 c0.1,0,0.3,0,0.4-0.1L4,17.4c0.3-0.2,0.3-0.5,0.2-0.8C4.1,16.4,3.7,16.3,3.5,16.4L3.5,16.4z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M3.7,13.1c0-0.3-0.3-0.6-0.6-0.6H0.6c-0.3,0-0.6,0.3-0.6,0.6s0.3,0.6,0.6,0.6h2.6 c0.1,0,0.3-0.1,0.4-0.2C3.7,13.4,3.7,13.2,3.7,13.1L3.7,13.1z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M10.7,3.9c0.3,0,0.6-0.3,0.6-0.6V0.6C11.3,0.3,11,0,10.7,0c-0.3,0-0.6,0.3-0.6,0.6v2.7 c0,0.2,0.1,0.3,0.2,0.4S10.6,3.9,10.7,3.9L10.7,3.9z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M13.4,20.2H8.9c-0.3,0-0.6,0.3-0.6,0.6c0,0.3,0.3,0.6,0.6,0.6h4.5c0.3,0,0.6-0.3,0.6-0.6 C14,20.5,13.7,20.2,13.4,20.2z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M10,23.5v0.3c0,0.4,0.3,0.7,0.6,0.7h0.9c0.4,0,0.6-0.3,0.6-0.7v-0.3c0.7,0,1.3-0.7,1.3-1.4 H8.8C8.9,22.8,9.4,23.4,10,23.5L10,23.5z"
]
[]
, Svg.path
[ class "blub-st0"
, d "M11.2,6.7c-3.1,0-5.6,2.7-5.6,6v0c0,0.8,0.1,1.5,0.4,2.3c0,0.1,0.1,0.2,0.1,0.3h0 c0.2,0.6,0.6,1.1,1,1.6l1.4,2.3h5.4l1.4-2.3c0.4-0.5,0.7-1,1-1.6c0-0.1,0.1-0.2,0.1-0.3h0c0.3-0.7,0.4-1.5,0.4-2.3 C16.8,9.4,14.3,6.7,11.2,6.7L11.2,6.7z M10.9,9c-0.6,0-1.2,0.2-1.7,0.5c-1.1,0.7-1.6,1.9-1.7,3.5v0c0,0.3-0.3,0.6-0.6,0.6 c-0.1,0-0.3-0.1-0.4-0.2c-0.1-0.1-0.2-0.3-0.2-0.4c0-2.7,1.3-4,2.3-4.6c0.7-0.4,1.4-0.6,2.2-0.7c0.3,0,0.6,0.3,0.6,0.6 C11.5,8.7,11.2,9,10.9,9L10.9,9z"
]
[]
]
]
]
]
]
]
|> fromUnstyled
|> NriSvg.fromHtml
{-| -}
arrowLeft : NriSvg.Svg
arrowLeft =
svg
[ viewBox "0 0 25 25"
, width "100%"
, height "100%"
, fill "currentcolor"
]
[ Svg.path
[ fillRule "evenodd"
, d "M19.2677026,20.7322696 C20.2443584,21.7070736 20.2443584,23.2915005 19.2677026,24.2677859 C18.7788191,24.7555583 18.139567,25 17.4999444,25 C16.8603219,25 16.2210698,24.7555583 15.7321863,24.2677859 L5.73229742,14.267897 C4.7556416,13.293093 4.7556416,11.7086662 5.73229742,10.7323808 L15.7321863,0.732491861 C16.7084718,-0.244163954 18.2914171,-0.244163954 19.2677026,0.732491861 C20.2443584,1.70729584 20.2443584,3.29172268 19.2677026,4.26800813 L11.0359422,12.5001389 L19.2677026,20.7322696 Z"
]
[]
]
|> fromUnstyled
|> NriSvg.fromHtml
xSvg : NriSvg.Svg
xSvg =
svg
[ viewBox "0 0 25 25"
, width "100%"
, height "100%"
, fill "currentcolor"
]
[ Svg.path
[ d "M1.067 6.015c-1.423-1.422-1.423-3.526 0-4.948 1.422-1.423 3.526-1.423 4.948 0l6.371 6.37 6.371-6.37c1.422-1.423 3.783-1.423 5.176 0 1.423 1.422 1.423 3.782 0 5.176l-6.37 6.37 6.37 6.372c1.423 1.422 1.423 3.526 0 4.948-1.422 1.423-3.526 1.423-4.948 0l-6.371-6.37-6.371 6.37c-1.422 1.423-3.783 1.423-5.176 0-1.423-1.422-1.423-3.782 0-5.176l6.37-6.143-6.37-6.599z"
]
[]
]
|> fromUnstyled
|> NriSvg.fromHtml

View File

@ -1,53 +1,53 @@
module Nri.Ui.Svg.V1 exposing
( Svg
, withColor, withLabel, withWidth, withHeight, withCss, withNriDescription
, fromHtml, toHtml
, toRawSvg
, withColor, withLabel, withWidth, withHeight, withCss, withCustom
, init, toHtml
)
{-|
@docs Svg
@docs withColor, withLabel, withWidth, withHeight, withCss, withNriDescription
@docs fromHtml, toHtml
@docs toRawSvg
@docs withColor, withLabel, withWidth, withHeight, withCss, withCustom
@docs init, toHtml
-}
import Accessibility.Styled.Aria as Aria
import Accessibility.Styled.Role as Role
import Css exposing (Color)
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes
import Html.Styled.Attributes
import Nri.Ui.Html.Attributes.V2 as AttributesExtra
import Svg.Styled as Svg
import Svg.Styled
import Svg.Styled.Attributes exposing (..)
{-| Opaque type describing a non-interactable Html element.
-}
type Svg
= Svg
{ icon : Html Never
{ icon : List (Svg.Styled.Svg Never)
, color : Maybe Color
, width : Maybe Css.Px
, height : Maybe Css.Px
, css : List Css.Style
, label : Maybe String
, attributes : List (Html.Attribute Never)
, viewBox : String
, attributes : List (Svg.Styled.Attribute Never)
}
{-| Tag html as being an svg.
{-| Pass through the viewbox as the first argument and the contents of the svg node as the second argument.
-}
fromHtml : Html Never -> Svg
fromHtml icon =
init : String -> List (Svg.Styled.Svg Never) -> Svg
init viewBox icon =
Svg
{ icon = icon
, color = Nothing
, height = Nothing
, width = Nothing
, css = []
, css = [ Css.flexShrink Css.zero ]
, label = Nothing
, viewBox = viewBox
, attributes = []
}
@ -58,12 +58,11 @@ withColor color (Svg record) =
Svg { record | color = Just color }
{-| Add a string aria-label property to the element.
{-| Add a title to the svg. Note that when the label is _not_ present, the icon will be entirely hidden from screenreader users.
See [Using the aria-label attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute) for
guidelines of when and how to use this attribute.
Read [Carie Fisher's "Accessible Svgs"](https://www.smashingmagazine.com/2021/05/accessible-svg-patterns-comparison/) article to learn more about accessible svgs.
Note that when the label is _not_ present, `aria-hidden` will be added. See <https://css-tricks.com/accessible-svg-icons/> for a quick summary on why.
Go through the [WCAG images tutorial](https://www.w3.org/WAI/tutorials/images/) to learn more about identifying when images are functional or decorative or something else.
-}
withLabel : String -> Svg -> Svg
@ -91,49 +90,45 @@ withCss css (Svg record) =
{-| -}
withCustom : List (Html.Attribute Never) -> Svg -> Svg
withCustom : List (Svg.Styled.Attribute Never) -> Svg -> Svg
withCustom attributes (Svg record) =
Svg { record | attributes = attributes ++ record.attributes }
Svg { record | attributes = record.attributes ++ attributes }
{-| -}
withNriDescription : String -> Svg -> Svg
withNriDescription description =
withCustom [ AttributesExtra.nriDescription description ]
{-| Render an svg.
{-| render an svg.
-}
toHtml : Svg -> Html msg
toHtml : Svg -> Svg.Styled.Svg msg
toHtml (Svg record) =
let
css =
List.filterMap identity
[ Maybe.map Css.color record.color
, Maybe.map Css.width record.width
, Maybe.map Css.height record.height
]
++ record.css
width =
Maybe.map Css.width record.width
|> Maybe.withDefault (Css.width (Css.pct 100))
attributes =
List.filterMap identity
[ if List.isEmpty css then
Nothing
height =
Maybe.map Css.height record.height
|> Maybe.withDefault (Css.height (Css.pct 100))
else
Just (Attributes.css (Css.display Css.inlineBlock :: css))
, Maybe.map Aria.label record.label
|> Maybe.withDefault (Aria.hidden True)
|> Just
, Just Role.img
]
++ record.attributes
color =
Maybe.map Css.color record.color
|> Maybe.withDefault (Css.batch [])
in
Html.map never (Html.div attributes [ record.icon ])
Svg.Styled.svg
([ viewBox record.viewBox
, fill "currentcolor"
, css (width :: height :: color :: record.css)
, Maybe.map (\_ -> AttributesExtra.none) record.label
|> Maybe.withDefault (Aria.hidden True)
, Role.img
, Html.Styled.Attributes.attribute "focusable" "false"
]
++ record.attributes
)
(case record.label of
Just label ->
Svg.Styled.title [] [ Svg.Styled.text label ]
:: record.icon
{-| Extract an svg, dropping any attributes passed through.
-}
toRawSvg : Svg -> Svg.Svg msg
toRawSvg (Svg record) =
Html.map never record.icon
Nothing ->
record.icon
)
|> Svg.Styled.map never

View File

@ -244,19 +244,7 @@ viewSwitch config =
shadowBoxId =
config.id ++ "-shadow-box"
in
Svg.svg
[ SvgAttributes.width "43"
, SvgAttributes.height "32"
, SvgAttributes.viewBox "0 0 43 32"
, SvgAttributes.css
[ Css.zIndex (Css.int 1)
, if config.isDisabled then
Css.opacity (Css.num 0.4)
else
Css.opacity (Css.num 1)
]
]
Nri.Ui.Svg.V1.init "0 0 43 32"
[ Svg.defs []
[ Svg.filter
[ SvgAttributes.id shadowFilterId
@ -366,7 +354,16 @@ viewSwitch config =
]
]
]
|> Nri.Ui.Svg.V1.fromHtml
|> Nri.Ui.Svg.V1.withWidth (Css.px 43)
|> Nri.Ui.Svg.V1.withHeight (Css.px 32)
|> Nri.Ui.Svg.V1.withCss
[ Css.zIndex (Css.int 1)
, if config.isDisabled then
Css.opacity (Css.num 0.4)
else
Css.opacity (Css.num 1)
]
stroke : Color -> Style

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,13 @@
module Nri.Ui.WhenFocusLeaves.V1 exposing (toAttribute)
module Nri.Ui.WhenFocusLeaves.V1 exposing (toAttribute, toDecoder)
{-| Listen for when the focus leaves the area, and then do an action.
@docs toAttribute
@docs toAttribute, toDecoder
-}
import Accessibility.Styled as Html
import Html.Styled.Events as Events
import Accessibility.Styled.Key as Key
import Json.Decode as Decode exposing (Decoder)
@ -17,6 +17,8 @@ what to do in reponse to tab keypresses in a part of the UI.
The ids referenced here are expected to correspond to elements in the container
we are adding the attribute to.
NOTE: When needing to listen to multiple keys toDecoder should be used instead of toAttribute.
-}
toAttribute :
{ firstId : String
@ -25,49 +27,54 @@ toAttribute :
, tabForwardAction : msg
}
-> Html.Attribute msg
toAttribute { firstId, lastId, tabBackAction, tabForwardAction } =
onTab <|
\elementId shiftKey ->
-- if the user tabs back while on the first id,
-- we execute the action
if elementId == firstId && shiftKey then
Decode.succeed
{ message = tabBackAction
, preventDefault = False
, stopPropagation = False
}
else if elementId == lastId && not shiftKey then
-- if the user tabs forward while on the last id,
-- we want to wrap around to the first id.
Decode.succeed
{ message = tabForwardAction
, preventDefault = False
, stopPropagation = False
}
else
Decode.fail "No need to intercept the key press"
toAttribute config =
Key.onKeyDown [ toDecoder config ]
onTab :
(String
-> Bool
-> Decoder { message : msg, preventDefault : Bool, stopPropagation : Bool }
)
-> Html.Attribute msg
onTab do =
Events.custom "keydown"
(Decode.andThen
(\( id, keyCode, shiftKey ) ->
if keyCode == 9 then
do id shiftKey
{-| Use this decoder to add a focus watcher to an HTML element and define
what to do in reponse to tab keypresses in a part of the UI.
The ids referenced here are expected to correspond to elements in the container
we are adding the attribute to.
NOTE: When needing to listen to multiple keys toDecoder should be used instead of toAttribute.
import Accessibility.Styled.Key as Key
Key.onKeyDown
[ Key.escape CloseModal
, toDecoder config
]
-}
toDecoder :
{ firstId : String
, lastId : String
, tabBackAction : msg
, tabForwardAction : msg
}
-> Decoder msg
toDecoder { firstId, lastId, tabBackAction, tabForwardAction } =
Decode.andThen
(\( elementId, keyCode, shiftKey ) ->
if keyCode == 9 then
-- if the user tabs back while on the first id,
-- we execute the action
if elementId == firstId && shiftKey then
Decode.succeed tabBackAction
else if elementId == lastId && not shiftKey then
-- if the user tabs forward while on the last id,
-- we want to wrap around to the first id.
Decode.succeed tabForwardAction
else
Decode.fail "No need to intercept the key press"
)
decodeKeydown
else
Decode.fail "No need to intercept the key press"
)
decodeKeydown
decodeKeydown : Decoder ( String, Int, Bool )

View File

@ -31,7 +31,6 @@ import Examples.Shadows as Shadows
import Examples.SideNav as SideNav
import Examples.SortableTable as SortableTable
import Examples.Sprite as Sprite
import Examples.Svg as Svg
import Examples.Switch as Switch
import Examples.Table as Table
import Examples.Tabs as Tabs
@ -612,25 +611,6 @@ all =
SpriteState childState ->
Just childState
_ ->
Nothing
)
, Svg.example
|> Example.wrapMsg SvgMsg
(\msg ->
case msg of
SvgMsg childMsg ->
Just childMsg
_ ->
Nothing
)
|> Example.wrapState SvgState
(\msg ->
case msg of
SvgState childState ->
Just childState
_ ->
Nothing
)
@ -839,7 +819,6 @@ type State
| SideNavState SideNav.State
| SortableTableState SortableTable.State
| SpriteState Sprite.State
| SvgState Svg.State
| SwitchState Switch.State
| TableState Table.State
| TabsState Tabs.State
@ -882,7 +861,6 @@ type Msg
| SideNavMsg SideNav.Msg
| SortableTableMsg SortableTable.Msg
| SpriteMsg Sprite.Msg
| SvgMsg Svg.Msg
| SwitchMsg Switch.Msg
| TableMsg Table.Msg
| TabsMsg Tabs.Msg

View File

@ -87,7 +87,7 @@ example =
defaultCaret : Bool -> Html msg
defaultCaret =
DisclosureIndicator.large [ Css.marginRight (Css.px 8) ]
DisclosureIndicator.large [ Css.marginRight (Css.px 8) ] >> Svg.toHtml
{-| -}
@ -104,7 +104,10 @@ view ellieLinkConfig model =
, update = UpdateControls
, settings = model.settings
, mainType = "RootHtml.Html String"
, extraImports = [ "import Nri.Ui.DisclosureIndicator.V2 as DisclosureIndicator" ]
, extraImports =
[ "import Nri.Ui.DisclosureIndicator.V2 as DisclosureIndicator"
, "import Nri.Ui.Svg.V1 as Svg"
]
, toExampleCode =
\settings ->
[ { sectionName = "Partial example"
@ -346,8 +349,8 @@ controlIcon =
Control.choice
[ ( "DisclosureIndicator"
, Control.value
( "DisclosureIndicator.large [ Css.marginRight (Css.px 8) ]"
, DisclosureIndicator.large [ Css.marginRight (Css.px 8) ]
( "DisclosureIndicator.large [ Css.marginRight (Css.px 8) ] >> Svg.toHtml"
, DisclosureIndicator.large [ Css.marginRight (Css.px 8) ] >> Svg.toHtml
)
)
, ( "none", Control.value ( "\\_ -> text \"\"", \_ -> Html.text "" ) )

View File

@ -6,9 +6,8 @@ module Examples.AssignmentIcon exposing (example, State, Msg)
-}
import Category exposing (Category(..))
import Example exposing (Example)
import Examples.IconExamples as IconExamples
import Examples.IconExamples as IconExamples exposing (Group)
import Nri.Ui.AssignmentIcon.V2 as AssignmentIcon
@ -25,13 +24,12 @@ type alias Msg =
{-| -}
example : Example State Msg
example =
{ name = "AssignmentIcon"
{ moduleName = "AssignmentIcon"
, version = 2
, categories = [ Icons ]
, keyboardSupport = []
, state = IconExamples.init
, update = IconExamples.update
, subscriptions = \_ -> Sub.none
, label = "Planning Diagnostics"
, name = "planningDiagnosticCircled"
, icon = AssignmentIcon.planningDiagnosticCircled
, renderSvgCode = \name -> "AssignmentIcon." ++ name
, preview =
IconExamples.preview
[ AssignmentIcon.planningDiagnosticCircled
@ -47,53 +45,60 @@ example =
, AssignmentIcon.standards
, AssignmentIcon.writing
]
, view =
\ellieLinkConfig settings ->
let
viewExampleSection =
IconExamples.view settings
in
[ IconExamples.viewSettings settings
, viewExampleSection "Diagnostic"
[ ( "diagnostic", AssignmentIcon.diagnostic )
, ( "planningDiagnosticCircled", AssignmentIcon.planningDiagnosticCircled )
, ( "unitDiagnosticCircled", AssignmentIcon.unitDiagnosticCircled )
]
, viewExampleSection "Practice" <|
[ ( "practice", AssignmentIcon.practice )
, ( "practiceCircled", AssignmentIcon.practiceCircled )
]
, viewExampleSection "Quiz" <|
[ ( "quiz", AssignmentIcon.quiz )
, ( "quizCircled", AssignmentIcon.quizCircled )
, ( "passageQuizCircled", AssignmentIcon.passageQuizCircled )
]
, viewExampleSection "Writing" <|
[ ( "quickWrite", AssignmentIcon.quickWrite )
, ( "guidedDraft", AssignmentIcon.guidedDraft )
, ( "peerReview", AssignmentIcon.peerReview )
, ( "selfReview", AssignmentIcon.selfReview )
]
, viewExampleSection "Writing II" <|
[ ( "quickWriteCircled", AssignmentIcon.quickWriteCircled )
, ( "guidedDraftCircled", AssignmentIcon.guidedDraftCircled )
, ( "peerReviewCircled", AssignmentIcon.peerReviewCircled )
, ( "selfReviewCircled", AssignmentIcon.selfReviewCircled )
]
, viewExampleSection "Stages" <|
[ ( "submitting", AssignmentIcon.submitting )
, ( "rating", AssignmentIcon.rating )
, ( "revising", AssignmentIcon.revising )
]
, viewExampleSection "Start" <|
[ ( "startPrimary", AssignmentIcon.startPrimary )
, ( "startSecondary", AssignmentIcon.startSecondary )
]
, viewExampleSection "Activities" <|
[ ( "assessment", AssignmentIcon.assessment )
, ( "standards", AssignmentIcon.standards )
, ( "writing", AssignmentIcon.writing )
, ( "modules", AssignmentIcon.modules )
]
]
, all = all
}
|> IconExamples.example
all : List Group
all =
[ ( "Diagnostic"
, [ ( "diagnostic", AssignmentIcon.diagnostic, [] )
, ( "planningDiagnosticCircled", AssignmentIcon.planningDiagnosticCircled, [] )
, ( "unitDiagnosticCircled", AssignmentIcon.unitDiagnosticCircled, [] )
]
)
, ( "Practice"
, [ ( "practice", AssignmentIcon.practice, [] )
, ( "practiceCircled", AssignmentIcon.practiceCircled, [] )
]
)
, ( "Quiz"
, [ ( "quiz", AssignmentIcon.quiz, [] )
, ( "quizCircled", AssignmentIcon.quizCircled, [] )
, ( "passageQuizCircled", AssignmentIcon.passageQuizCircled, [] )
]
)
, ( "Writing"
, [ ( "quickWrite", AssignmentIcon.quickWrite, [] )
, ( "guidedDraft", AssignmentIcon.guidedDraft, [] )
, ( "peerReview", AssignmentIcon.peerReview, [] )
, ( "selfReview", AssignmentIcon.selfReview, [] )
]
)
, ( "Writing II"
, [ ( "quickWriteCircled", AssignmentIcon.quickWriteCircled, [] )
, ( "guidedDraftCircled", AssignmentIcon.guidedDraftCircled, [] )
, ( "peerReviewCircled", AssignmentIcon.peerReviewCircled, [] )
, ( "selfReviewCircled", AssignmentIcon.selfReviewCircled, [] )
]
)
, ( "Stages"
, [ ( "submitting", AssignmentIcon.submitting, [] )
, ( "rating", AssignmentIcon.rating, [] )
, ( "revising", AssignmentIcon.revising, [] )
]
)
, ( "Start"
, [ ( "startPrimary", AssignmentIcon.startPrimary, [] )
, ( "startSecondary", AssignmentIcon.startSecondary, [] )
]
)
, ( "Activities"
, [ ( "assessment", AssignmentIcon.assessment, [] )
, ( "standards", AssignmentIcon.standards, [] )
, ( "writing", AssignmentIcon.writing, [] )
, ( "modules", AssignmentIcon.modules, [] )
]
)
]

View File

@ -51,6 +51,14 @@ example =
, Button.custom [ Key.tabbable False ]
, Button.icon UiIcon.link
]
, Button.link "Tertiary"
[ Button.small
, Button.fillContainerWidth
, Button.tertiary
, Button.css [ Css.marginTop (Css.px 8) ]
, Button.custom [ Key.tabbable False ]
, Button.icon UiIcon.link
]
, Button.link "Premium"
[ Button.small
, Button.fillContainerWidth
@ -248,6 +256,7 @@ buttons model =
styles =
[ ( Button.primary, "primary" )
, ( Button.secondary, "secondary" )
, ( Button.tertiary, "tertiary" )
, ( Button.danger, "danger" )
, ( Button.premium, "premium" )
]

View File

@ -15,6 +15,7 @@ import Example exposing (Example)
import Html.Styled as Html
import Html.Styled.Attributes exposing (css)
import Nri.Ui.DisclosureIndicator.V2 as DisclosureIndicator
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.Text.V6 as Text
@ -39,10 +40,10 @@ example =
, update = update
, subscriptions = \_ -> Sub.none
, preview =
[ DisclosureIndicator.medium [] False
, DisclosureIndicator.medium [] True
, DisclosureIndicator.large [] False
, DisclosureIndicator.large [] True
[ DisclosureIndicator.medium [] False |> Svg.toHtml
, DisclosureIndicator.medium [] True |> Svg.toHtml
, DisclosureIndicator.large [] False |> Svg.toHtml
, DisclosureIndicator.large [] True |> Svg.toHtml
]
, view =
\ellieLinkConfig state ->
@ -58,7 +59,7 @@ example =
, update = UpdateSettings
, settings = state.settings
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraImports = [ "import Nri.Ui.Svg.V1 as Svg" ]
, toExampleCode =
\settings ->
let
@ -70,6 +71,7 @@ example =
++ Tuple.first settings.css
++ " "
++ Tuple.first settings.isOpen
++ " |> Svg.toHtml"
in
[ { sectionName = "Large"
, code = toCode "large"
@ -83,12 +85,14 @@ example =
[ DisclosureIndicator.large
(Tuple.second attributes.css)
(Tuple.second attributes.isOpen)
|> Svg.toHtml
, Html.text "large is a 17px caret icon."
]
, Html.div [ css [ Css.displayFlex, Css.alignItems Css.center, Css.marginBottom (Css.px 8) ] ]
[ DisclosureIndicator.medium
(Tuple.second attributes.css)
(Tuple.second attributes.isOpen)
|> Svg.toHtml
, Html.text "medium is a 15px caret icon."
]
]

View File

@ -1,26 +1,61 @@
module Examples.IconExamples exposing
( preview
, Settings, init, Msg, update, viewSettings
, view, viewWithCustomStyles
( example
, Settings, Msg
, Group
, preview
)
{-|
@docs example
@docs Settings, Msg
@docs Group
@docs preview
@docs Settings, init, Msg, update, viewSettings
@docs view, viewWithCustomStyles
-}
import Category exposing (Category(..))
import Css
import Css.Global
import Example exposing (Example)
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes exposing (css)
import Html.Styled.Attributes as Attributes exposing (css)
import Html.Styled.Events as Events
import Nri.Ui.Checkbox.V5 as Checkbox
import Nri.Ui.Colors.Extra exposing (fromCssColor, toCssColor)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.Select.V8 as Select
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Nri.Ui.Text.V6 as Text
import Nri.Ui.TextInput.V7 as TextInput
import SolidColor exposing (SolidColor)
type alias Config =
{ moduleName : String
, version : Int
, label : String
, name : String
, icon : Svg
, renderSvgCode : String -> String
, preview : List (Html Never)
, all : List Group
}
example : Config -> Example Settings Msg
example config =
{ name = config.moduleName
, version = config.version
, categories = [ Icons ]
, keyboardSupport = []
, state = init config
, update = update
, subscriptions = \_ -> Sub.none
, preview = config.preview
, view = \ellieLinkConfig settings -> view settings config.all
}
{-| -}
@ -43,29 +78,84 @@ preview icons =
{-| -}
type alias Settings =
{ showIconName : Bool }
{ showIconName : Bool
, iconSelectorExpanded : Bool
, color : SolidColor
, width : Float
, height : Float
, icon : ( String, Svg )
, label : String
, showBorder : Bool
, renderSvgCode : String -> String
}
{-| -}
init : Settings
init =
{ showIconName = False }
init : Config -> Settings
init { label, name, icon, renderSvgCode } =
{ showIconName = False
, iconSelectorExpanded = False
, color = fromCssColor Colors.greenDark
, width = 100
, height = 100
, icon = ( name, icon )
, label = label
, showBorder = True
, renderSvgCode = renderSvgCode
}
{-| -}
type Msg
= ShowNames Bool
| SetIcon ( String, Svg )
| SetColor (Result String SolidColor)
| SetWidth (Maybe Float)
| SetHeight (Maybe Float)
| SetLabel String
| SetBorder Bool
{-| -}
update : Msg -> Settings -> ( Settings, Cmd msg )
update msg settings =
update msg state =
case msg of
ShowNames showIconName ->
( { settings | showIconName = showIconName }
( { state | showIconName = showIconName }
, Cmd.none
)
SetIcon svg ->
( { state | icon = svg }
, Cmd.none
)
SetColor (Ok color) ->
( { state | color = color }
, Cmd.none
)
SetColor (Err err) ->
( state, Cmd.none )
SetWidth (Just width) ->
( { state | width = width }, Cmd.none )
SetWidth Nothing ->
( state, Cmd.none )
SetHeight (Just height) ->
( { state | height = height }, Cmd.none )
SetHeight Nothing ->
( state, Cmd.none )
SetLabel label ->
( { state | label = label }, Cmd.none )
SetBorder showBorder ->
( { state | showBorder = showBorder }, Cmd.none )
{-| -}
viewSettings : Settings -> Html Msg
@ -80,20 +170,27 @@ viewSettings { showIconName } =
}
type alias Group =
( String
, List ( String, Svg.Svg, List Css.Style )
)
{-| -}
view : Settings -> String -> List ( String, Svg.Svg ) -> Html msg
view settings headerText icons =
view : Settings -> List Group -> List (Html Msg)
view settings groups =
let
defaultStyles =
[ Css.height (Css.px 25)
, Css.width (Css.px 25)
, Css.margin (Css.px 4)
, Css.color Colors.gray45
]
viewExampleSection ( group, values ) =
viewWithCustomStyles settings group values
in
viewWithCustomStyles settings
headerText
(List.map (\( name, svg ) -> ( name, svg, defaultStyles )) icons)
viewSettings settings
:: List.map viewExampleSection groups
++ [ Html.section [ css [ Css.margin2 (Css.px 30) Css.zero ] ]
[ Heading.h3 [] [ Html.text "Example Usage" ]
, viewSingularExampleSettings groups settings
, viewResults settings
]
]
{-| -}
@ -129,6 +226,18 @@ viewWithCustomStyles { showIconName } headerText icons =
viewIcon : Bool -> ( String, Svg.Svg, List Css.Style ) -> Html msg
viewIcon showIconName ( name, icon, style ) =
let
iconCss =
if List.isEmpty style then
[ Css.height (Css.px 25)
, Css.width (Css.px 25)
, Css.margin (Css.px 4)
, Css.color Colors.gray45
]
else
style
in
Html.div
[ css
[ Css.displayFlex
@ -148,7 +257,7 @@ viewIcon showIconName ( name, icon, style ) =
]
]
[ icon
|> Svg.withCss style
|> Svg.withCss iconCss
|> Svg.toHtml
, Text.smallBody
[ Text.plaintext name
@ -160,3 +269,133 @@ viewIcon showIconName ( name, icon, style ) =
[ Css.display Css.none ]
]
]
viewSingularExampleSettings : List Group -> Settings -> Html.Html Msg
viewSingularExampleSettings groups state =
let
svgGroupedChoices ( groupName, items ) =
let
toEntry ( name, icon, _ ) =
Select.Choice name ( name, icon )
in
Select.ChoicesGroup groupName (List.map toEntry items)
in
Html.div
[ Attributes.css
[ Css.displayFlex
, Css.justifyContent Css.spaceBetween
, Css.alignItems Css.center
, Css.flexWrap Css.wrap
]
]
[ TextInput.view "Title"
[ TextInput.value state.label
, TextInput.text SetLabel
]
, Select.view "Icon"
[ Select.groupedChoices Tuple.first
(List.map svgGroupedChoices groups)
, Select.value (Just state.icon)
]
|> Html.map SetIcon
, Checkbox.viewWithLabel
{ identifier = "show-border"
, label = "Show border"
, setterMsg = SetBorder
, selected = Checkbox.selectedFromBool state.showBorder
, disabled = False
, theme = Checkbox.Square
}
, Html.label []
[ Html.text "Color: "
, Html.input
[ Attributes.type_ "color"
, Attributes.value (SolidColor.toHex state.color)
, Events.onInput (SetColor << SolidColor.fromHex)
]
[]
]
, Html.label []
[ Html.text "Width: "
, Html.input
[ Attributes.type_ "range"
, Attributes.min "0"
, Attributes.max "200"
, Attributes.value (String.fromFloat state.width)
, Events.onInput (SetWidth << String.toFloat)
]
[]
]
, Html.label []
[ Html.text "Height: "
, Html.input
[ Attributes.type_ "range"
, Attributes.min "0"
, Attributes.max "200"
, Attributes.value (String.fromFloat state.height)
, Events.onInput (SetHeight << String.toFloat)
]
[]
]
]
viewResults : Settings -> Html.Html Msg
viewResults state =
let
( red, green, blue ) =
SolidColor.toRGB state.color
in
Html.div [ Attributes.css [ Css.displayFlex ] ]
[ Html.pre
[ Attributes.css
[ Css.width (Css.px 400)
, Css.marginRight (Css.px 20)
]
]
[ [ "color : Css.Color\n"
, "color =\n"
, " Css.rgb " ++ String.fromFloat red ++ " " ++ String.fromFloat green ++ " " ++ String.fromFloat blue
, "\n\n\n"
, "renderedSvg : Svg\n"
, "renderedSvg =\n"
, " " ++ state.renderSvgCode (Tuple.first state.icon) ++ "\n"
, " |> Svg.withColor color\n"
, " |> Svg.withWidth (Css.px " ++ String.fromFloat state.width ++ ")\n"
, " |> Svg.withHeight (Css.px " ++ String.fromFloat state.height ++ ")\n"
, if state.showBorder then
" |> Svg.withCss [ Css.border3 (Css.px 1) Css.solid Colors.gray20 ]\n"
else
""
, if String.isEmpty state.label then
""
else
" |> Svg.withLabel \"" ++ state.label ++ "\"\n"
, " |> Svg.toHtml\n"
]
|> String.join ""
|> Html.text
]
, Tuple.second state.icon
|> Svg.withColor (toCssColor state.color)
|> Svg.withWidth (Css.px state.width)
|> Svg.withHeight (Css.px state.height)
|> (\svg ->
if state.showBorder then
Svg.withCss [ Css.border3 (Css.px 1) Css.solid Colors.gray20 ] svg
else
svg
)
|> (\svg ->
if String.isEmpty state.label then
svg
else
Svg.withLabel state.label svg
)
|> Svg.toHtml
]

View File

@ -6,10 +6,9 @@ module Examples.Logo exposing (example, State, Msg)
-}
import Category exposing (Category(..))
import Css
import Example exposing (Example)
import Examples.IconExamples as IconExamples
import Examples.IconExamples as IconExamples exposing (Group)
import Html.Styled as Html
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Colors.V1 as Colors
@ -30,13 +29,12 @@ type alias Msg =
{-| -}
example : Example State Msg
example =
{ name = "Logo"
{ moduleName = "Logo"
, version = 1
, categories = [ Icons ]
, keyboardSupport = []
, state = IconExamples.init
, update = IconExamples.update
, subscriptions = \_ -> Sub.none
, label = "NoRedInk"
, name = "noredink"
, icon = Logo.noredink
, renderSvgCode = \name -> "Logo." ++ name
, preview =
Html.div [ css [ Css.marginBottom (Css.px 8) ] ] [ Svg.toHtml Logo.noredink ]
:: IconExamples.preview
@ -45,83 +43,87 @@ example =
, Logo.cleverC
, Logo.googleG
]
, view =
\ellieLinkConfig settings ->
let
viewExampleSection =
IconExamples.viewWithCustomStyles settings
in
[ IconExamples.viewSettings settings
, viewExampleSection "NRI"
[ ( "noredink"
, Logo.noredink
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
]
, viewExampleSection "Social Media"
[ ( "facebook", Logo.facebook, defaults )
, ( "twitter", Logo.twitter, defaults )
]
, viewExampleSection "Clever"
[ ( "clever"
, Logo.clever
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
, Css.color Colors.azure
]
)
, ( "cleverC", Logo.cleverC, defaults )
, ( "cleverLibrary"
, Logo.cleverLibrary
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
]
, viewExampleSection "Google"
[ ( "googleClassroom"
, Logo.googleClassroom
, defaults
)
, ( "googleG", Logo.googleG, defaults )
]
, viewExampleSection "LMS"
[ ( "canvas"
, Logo.canvas
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
, ( "canvasCircle"
, Logo.canvasCircle
, [ Css.height (Css.px 25)
, Css.width (Css.px 25)
, Css.margin (Css.px 4)
]
)
, ( "schoology"
, Logo.schoology
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
, ( "schoologyCircle"
, Logo.schoologyCircle
, [ Css.height (Css.px 25)
, Css.width (Css.px 25)
, Css.margin (Css.px 4)
]
)
]
]
, all = all
}
|> IconExamples.example
all : List Group
all =
[ ( "NRI"
, [ ( "noredink"
, Logo.noredink
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
]
)
, ( "Social Media"
, [ ( "facebook", Logo.facebook, defaults )
, ( "twitter", Logo.twitter, defaults )
]
)
, ( "Clever"
, [ ( "clever"
, Logo.clever
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
, Css.color Colors.azure
]
)
, ( "cleverC", Logo.cleverC, defaults )
, ( "cleverLibrary"
, Logo.cleverLibrary
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
]
)
, ( "Google"
, [ ( "googleClassroom"
, Logo.googleClassroom
, defaults
)
, ( "googleG", Logo.googleG, defaults )
]
)
, ( "LMS"
, [ ( "canvas"
, Logo.canvas
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
, ( "canvasCircle"
, Logo.canvasCircle
, [ Css.height (Css.px 25)
, Css.width (Css.px 25)
, Css.margin (Css.px 4)
]
)
, ( "schoology"
, Logo.schoology
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
, ( "schoologyCircle"
, Logo.schoologyCircle
, [ Css.height (Css.px 25)
, Css.width (Css.px 25)
, Css.margin (Css.px 4)
]
)
]
)
]
defaults : List Css.Style

View File

@ -18,11 +18,13 @@ import Debug.Control.View as ControlView
import EllieLink
import Example exposing (Example)
import KeyboardSupport exposing (Key(..))
import Nri.Ui.Button.V10 as Button
import Nri.Ui.ClickableText.V3 as ClickableText
import Nri.Ui.Colors.Extra as ColorsExtra
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Menu.V3 as Menu
import Nri.Ui.TextInput.V7 as TextInput
import Nri.Ui.UiIcon.V1 as UiIcon
import Set exposing (Set)
import Svg.Styled as Svg
@ -248,6 +250,35 @@ view ellieLinkConfig state =
button buttonAttributes [ text "Custom Menu trigger button" ]
}
)
, ( "Menu.button (with Menu.disclosure)"
, Menu.view
(menuAttributes
++ [ Menu.buttonId "with_controls__button"
, Menu.menuId "with_controls__menu"
, Menu.disclosure { lastId = "login__button" }
]
)
{ isOpen = isOpen "with_controls"
, focusAndToggle = FocusAndToggle "with_controls"
, entries =
[ Menu.entry "username-input" <|
\attrs ->
div []
[ TextInput.view "Username"
[ TextInput.id "username-input"
]
, TextInput.view "Password" []
, Button.button "Log in"
[ Button.primary
, Button.id "login__button"
, Button.fillContainerWidth
, Button.css [ Css.marginTop (Css.px 15) ]
]
]
]
, button = Menu.button defaultButtonAttributes "Log In"
}
)
]
]

View File

@ -6,10 +6,9 @@ module Examples.Pennant exposing (example, State, Msg)
-}
import Category exposing (Category(..))
import Css
import Example exposing (Example)
import Examples.IconExamples as IconExamples
import Examples.IconExamples as IconExamples exposing (Group)
import Nri.Ui.Pennant.V2 as Pennant
@ -26,36 +25,38 @@ type alias Msg =
{-| -}
example : Example State Msg
example =
{ name = "Pennant"
{ moduleName = "Pennant"
, version = 2
, categories = [ Icons ]
, keyboardSupport = []
, state = IconExamples.init
, update = IconExamples.update
, subscriptions = \_ -> Sub.none
, label = "Premium"
, name = "premiumFlag"
, icon = Pennant.premiumFlag
, renderSvgCode = \name -> "Pennant." ++ name
, preview =
IconExamples.preview
[ Pennant.premiumFlag
, Pennant.expiredPremiumFlag
, Pennant.disabledPremiumFlag
]
, view =
\ellieLinkConfig settings ->
[ IconExamples.viewSettings settings
, IconExamples.viewWithCustomStyles settings
"Premium Pennants"
[ ( "premiumFlag"
, Pennant.premiumFlag
, [ Css.width (Css.px 80) ]
)
, ( "expiredPremiumFlag"
, Pennant.expiredPremiumFlag
, [ Css.width (Css.px 80) ]
)
, ( "disabledPremiumFlag"
, Pennant.disabledPremiumFlag
, [ Css.width (Css.px 80) ]
)
]
]
, all = all
}
|> IconExamples.example
all : List Group
all =
[ ( "Premium Pennants"
, [ ( "premiumFlag"
, Pennant.premiumFlag
, [ Css.width (Css.px 80) ]
)
, ( "expiredPremiumFlag"
, Pennant.expiredPremiumFlag
, [ Css.width (Css.px 80) ]
)
, ( "disabledPremiumFlag"
, Pennant.disabledPremiumFlag
, [ Css.width (Css.px 80) ]
)
]
)
]

View File

@ -6,13 +6,10 @@ module Examples.Sprite exposing (example, State, Msg)
-}
import Category exposing (Category(..))
import Example exposing (Example)
import Examples.IconExamples as IconExamples
import Examples.IconExamples as IconExamples exposing (Group)
import Nri.Ui.Sprite.V1 as Sprite exposing (SpriteId)
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Svg.Styled exposing (svg)
import Svg.Styled.Attributes as Attributes
{-| -}
@ -28,39 +25,36 @@ type alias Msg =
{-| -}
example : Example State Msg
example =
{ name = "Sprite"
{ moduleName = "Sprite"
, version = 1
, categories = List.singleton Icons
, keyboardSupport = []
, state = IconExamples.init
, update = IconExamples.update
, subscriptions = \_ -> Sub.none
, preview = IconExamples.preview (List.map Tuple.second sprites)
, view =
\ellieLinkConfig settings ->
[ IconExamples.viewSettings settings
, IconExamples.view settings "Rich Text Formatting" sprites
]
, label = "Bold"
, name = "bold"
, icon = viewSprite Sprite.bold
, renderSvgCode = \name -> "Svg.init \"\" [ Sprite.use Sprite." ++ name ++ " ] "
, preview = IconExamples.preview (List.map (\( a, b, c ) -> b) sprites)
, all = all
}
|> IconExamples.example
sprites : List ( String, Svg )
all : List Group
all =
[ ( "Rich Text Formatting", sprites )
]
sprites : List ( String, Svg, List a )
sprites =
[ ( "bold", viewSprite Sprite.bold )
, ( "italic", viewSprite Sprite.italic )
, ( "underline", viewSprite Sprite.underline )
, ( "list", viewSprite Sprite.list )
, ( "link", viewSprite Sprite.link )
, ( "undo", viewSprite Sprite.undo )
, ( "redo", viewSprite Sprite.redo )
[ ( "bold", viewSprite Sprite.bold, [] )
, ( "italic", viewSprite Sprite.italic, [] )
, ( "underline", viewSprite Sprite.underline, [] )
, ( "list", viewSprite Sprite.list, [] )
, ( "link", viewSprite Sprite.link, [] )
, ( "undo", viewSprite Sprite.undo, [] )
, ( "redo", viewSprite Sprite.redo, [] )
]
viewSprite : SpriteId -> Svg
viewSprite id =
svg
[ Attributes.width "100%"
, Attributes.height "100%"
]
[ Sprite.use id ]
|> Svg.fromHtml
Svg.init "" [ Sprite.use id ]

View File

@ -1,198 +0,0 @@
module Examples.Svg exposing (Msg, State, example)
{-|
@docs Msg, State, example
-}
import Category exposing (Category(..))
import Css
import Example exposing (Example)
import Html.Styled as Html
import Html.Styled.Attributes as Attributes
import Html.Styled.Events as Events
import Nri.Ui.Colors.Extra exposing (fromCssColor, toCssColor)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.UiIcon.V1 as UiIcon
import SolidColor exposing (SolidColor)
{-| -}
example : Example State Msg
example =
{ name = "Svg"
, version = 1
, categories = [ Icons ]
, keyboardSupport = []
, state = init
, update = update
, subscriptions = \_ -> Sub.none
, preview = []
, view =
\ellieLinkConfig state ->
[ viewSettings state
, viewResults state
]
}
viewSettings : State -> Html.Html Msg
viewSettings state =
Html.div
[ Attributes.css
[ Css.displayFlex
, Css.justifyContent Css.spaceBetween
]
]
[ Html.label []
[ Html.text "Color: "
, Html.input
[ Attributes.type_ "color"
, Attributes.value (SolidColor.toHex state.color)
, Events.onInput (SetColor << SolidColor.fromHex)
]
[]
]
, Html.label []
[ Html.text "Width: "
, Html.input
[ Attributes.type_ "range"
, Attributes.min "0"
, Attributes.max "200"
, Attributes.value (String.fromFloat state.width)
, Events.onInput (SetWidth << String.toFloat)
]
[]
]
, Html.label []
[ Html.text "Height: "
, Html.input
[ Attributes.type_ "range"
, Attributes.min "0"
, Attributes.max "200"
, Attributes.value (String.fromFloat state.height)
, Events.onInput (SetHeight << String.toFloat)
]
[]
]
, Html.label []
[ Html.text "Aria-label: "
, Html.input
[ Attributes.value state.label
, Events.onInput SetLabel
]
[]
]
]
viewResults : State -> Html.Html Msg
viewResults state =
let
( red, green, blue ) =
SolidColor.toRGB state.color
in
Html.div [ Attributes.css [ Css.displayFlex ] ]
[ Html.pre
[ Attributes.css
[ Css.width (Css.px 400)
, Css.marginRight (Css.px 20)
]
]
[ [ "color : Css.Color\n"
, "color =\n"
, " Css.rgb " ++ String.fromFloat red ++ " " ++ String.fromFloat green ++ " " ++ String.fromFloat blue
, "\n\n\n"
, "renderedSvg : Svg\n"
, "renderedSvg =\n"
, " UiIcon.newspaper\n"
, " |> Svg.withColor color\n"
, " |> Svg.withWidth (Css.px " ++ String.fromFloat state.width ++ ")\n"
, " |> Svg.withHeight (Css.px " ++ String.fromFloat state.height ++ ")\n"
, if String.isEmpty state.label then
""
else
" |> Svg.withLabel \"" ++ state.label ++ "\"\n"
, " |> Svg.toHtml\n"
]
|> String.join ""
|> Html.text
]
, Html.div
[ Attributes.css
[ Css.backgroundColor Colors.gray92
, Css.flexGrow (Css.int 2)
]
]
[ UiIcon.newspaper
|> Svg.withColor (toCssColor state.color)
|> Svg.withWidth (Css.px state.width)
|> Svg.withHeight (Css.px state.height)
|> (\svg ->
if String.isEmpty state.label then
svg
else
Svg.withLabel state.label svg
)
|> Svg.toHtml
]
]
{-| -}
type alias State =
{ color : SolidColor
, width : Float
, height : Float
, label : String
}
{-| -}
init : State
init =
{ color = fromCssColor Colors.azure
, width = 30
, height = 30
, label = "Newspaper"
}
{-| -}
type Msg
= SetColor (Result String SolidColor)
| SetWidth (Maybe Float)
| SetHeight (Maybe Float)
| SetLabel String
{-| -}
update : Msg -> State -> ( State, Cmd Msg )
update msg state =
case msg of
SetColor (Ok color) ->
( { state | color = color }
, Cmd.none
)
SetColor (Err err) ->
( state, Cmd.none )
SetWidth (Just width) ->
( { state | width = width }, Cmd.none )
SetWidth Nothing ->
( state, Cmd.none )
SetHeight (Just height) ->
( { state | height = height }, Cmd.none )
SetHeight Nothing ->
( state, Cmd.none )
SetLabel label ->
( { state | label = label }, Cmd.none )

View File

@ -6,9 +6,8 @@ module Examples.UiIcon exposing (example, State, Msg)
-}
import Category exposing (Category(..))
import Example exposing (Example)
import Examples.IconExamples as IconExamples
import Examples.IconExamples as IconExamples exposing (Group)
import Nri.Ui.UiIcon.V1 as UiIcon
@ -25,13 +24,12 @@ type alias Msg =
{-| -}
example : Example State Msg
example =
{ name = "UiIcon"
{ moduleName = "UiIcon"
, version = 1
, categories = List.singleton Icons
, keyboardSupport = []
, state = IconExamples.init
, update = IconExamples.update
, subscriptions = \_ -> Sub.none
, label = "Mastered"
, name = "starFilled"
, icon = UiIcon.starFilled
, renderSvgCode = \name -> "UiIcon." ++ name
, preview =
IconExamples.preview
[ UiIcon.seeMore
@ -47,160 +45,199 @@ example =
, UiIcon.checkmark
, UiIcon.equals
]
, view =
\ellieLinkConfig settings ->
let
viewExampleSection =
IconExamples.view settings
in
[ IconExamples.viewSettings settings
, viewExampleSection "Interface"
[ ( "seeMore", UiIcon.seeMore )
, ( "openClose", UiIcon.openClose )
, ( "download", UiIcon.download )
, ( "sort", UiIcon.sort )
, ( "gear", UiIcon.gear )
]
, viewExampleSection "Archive & Unarchive"
[ ( "archive", UiIcon.archive )
, ( "unarchive", UiIcon.unarchive )
]
, viewExampleSection "Media in Circles"
[ ( "playInCircle", UiIcon.playInCircle )
, ( "pauseInCircle", UiIcon.pauseInCircle )
, ( "stopInCircle", UiIcon.stopInCircle )
]
, viewExampleSection "Media"
[ ( "play", UiIcon.play )
, ( "skip", UiIcon.skip )
]
, viewExampleSection "Actions"
[ ( "share", UiIcon.share )
, ( "preview", UiIcon.preview )
, ( "activity", UiIcon.activity )
, ( "copyToClipboard", UiIcon.copyToClipboard )
, ( "gift", UiIcon.gift )
, ( "openInNewTab", UiIcon.openInNewTab )
, ( "sync", UiIcon.sync )
]
, viewExampleSection "Guidance"
[ ( "footsteps", UiIcon.footsteps )
, ( "help", UiIcon.help )
, ( "checklist", UiIcon.checklist )
, ( "checklistComplete", UiIcon.checklistComplete )
]
, viewExampleSection "Bulbs"
[ ( "sparkleBulb", UiIcon.sparkleBulb )
, ( "baldBulb", UiIcon.baldBulb )
]
, viewExampleSection "Science & Measurement"
[ ( "compass", UiIcon.compass )
, ( "speedometer", UiIcon.speedometer )
, ( "performance", UiIcon.performance )
, ( "microscope", UiIcon.microscope )
, ( "scale", UiIcon.scale )
]
, viewExampleSection "Humans & Class"
[ ( "person", UiIcon.person )
, ( "couple", UiIcon.couple )
, ( "class", UiIcon.class )
, ( "leaderboard", UiIcon.leaderboard )
]
, viewExampleSection "Time"
[ ( "emptyCalendar", UiIcon.emptyCalendar )
, ( "calendar", UiIcon.calendar )
, ( "clock", UiIcon.clock )
]
, viewExampleSection "Texts"
[ ( "missingDocument", UiIcon.missingDocument )
, ( "document", UiIcon.document )
, ( "documents", UiIcon.documents )
, ( "newspaper", UiIcon.newspaper )
, ( "openBook", UiIcon.openBook )
, ( "openBooks", UiIcon.openBooks )
]
, viewExampleSection "Communication"
[ ( "speechBalloon", UiIcon.speechBalloon )
, ( "mail", UiIcon.mail )
]
, viewExampleSection "Writing Utensils"
[ ( "edit", UiIcon.edit )
, ( "pen", UiIcon.pen )
, ( "highlighter", UiIcon.highlighter )
]
, viewExampleSection "Arrows"
[ ( "arrowTop", UiIcon.arrowTop )
, ( "arrowRight", UiIcon.arrowRight )
, ( "arrowDown", UiIcon.arrowDown )
, ( "arrowLeft", UiIcon.arrowLeft )
, ( "arrowPointingRight", UiIcon.arrowPointingRight )
, ( "arrowPointingRightThick", UiIcon.arrowPointingRightThick )
, ( "sortArrow", UiIcon.sortArrow )
, ( "sortArrowDown", UiIcon.sortArrowDown )
]
, viewExampleSection "Checks"
[ ( "checkmark", UiIcon.checkmark )
, ( "checkmarkInCircle", UiIcon.checkmarkInCircle )
, ( "checkmarkInCircleInverse", UiIcon.checkmarkInCircleInverse )
, ( "emptyCircle", UiIcon.emptyCircle )
]
, viewExampleSection "Xs"
[ ( "x", UiIcon.x )
, ( "xInCircle", UiIcon.xInCircle )
]
, viewExampleSection "Bangs"
[ ( "attention", UiIcon.attention )
, ( "exclamation", UiIcon.exclamation )
]
, viewExampleSection "Math"
[ ( "equals", UiIcon.equals )
, ( "plus", UiIcon.plus )
, ( "null", UiIcon.null )
]
, viewExampleSection "Notifs"
[ ( "flag", UiIcon.flag )
, ( "star", UiIcon.star )
, ( "starFilled", UiIcon.starFilled )
, ( "starOutline", UiIcon.starOutline )
]
, viewExampleSection "Badges & Celebration"
[ ( "badge", UiIcon.badge )
, ( "tada", UiIcon.tada )
]
, viewExampleSection "Lock & Key"
[ ( "key", UiIcon.key )
, ( "lock", UiIcon.lock )
, ( "premiumLock", UiIcon.premiumLock )
]
, viewExampleSection "Tips & Tricks"
[ ( "hat", UiIcon.hat )
, ( "keychain", UiIcon.keychain )
]
, viewExampleSection "Growth"
[ ( "sprout", UiIcon.sprout )
, ( "sapling", UiIcon.sapling )
, ( "tree", UiIcon.tree )
]
, viewExampleSection "Rich Text Formatting"
[ ( "bold", UiIcon.bold )
, ( "italic", UiIcon.italic )
, ( "underline", UiIcon.underline )
, ( "list", UiIcon.list )
, ( "link", UiIcon.link )
, ( "undo", UiIcon.undo )
, ( "redo", UiIcon.redo )
]
, viewExampleSection "Punctuation"
[ ( "openQuotationMark", UiIcon.openQuotationMark )
, ( "closeQuotationMark", UiIcon.closeQuotationMark )
]
, viewExampleSection "Navigation"
[ ( "home", UiIcon.home )
, ( "library", UiIcon.library )
]
, viewExampleSection "Search"
[ ( "search", UiIcon.search )
, ( "searchInCircle", UiIcon.searchInCicle )
]
]
, all = all
}
|> IconExamples.example
all : List Group
all =
[ ( "Interface"
, [ ( "seeMore", UiIcon.seeMore, [] )
, ( "openClose", UiIcon.openClose, [] )
, ( "download", UiIcon.download, [] )
, ( "sort", UiIcon.sort, [] )
, ( "gear", UiIcon.gear, [] )
]
)
, ( "Archive & Unarchive"
, [ ( "archive", UiIcon.archive, [] )
, ( "unarchive", UiIcon.unarchive, [] )
]
)
, ( "Media in Circles"
, [ ( "playInCircle", UiIcon.playInCircle, [] )
, ( "pauseInCircle", UiIcon.pauseInCircle, [] )
, ( "stopInCircle", UiIcon.stopInCircle, [] )
]
)
, ( "Media"
, [ ( "play", UiIcon.play, [] )
, ( "skip", UiIcon.skip, [] )
]
)
, ( "Actions"
, [ ( "share", UiIcon.share, [] )
, ( "preview", UiIcon.preview, [] )
, ( "activity", UiIcon.activity, [] )
, ( "copyToClipboard", UiIcon.copyToClipboard, [] )
, ( "gift", UiIcon.gift, [] )
, ( "openInNewTab", UiIcon.openInNewTab, [] )
, ( "sync", UiIcon.sync, [] )
]
)
, ( "Guidance"
, [ ( "footsteps", UiIcon.footsteps, [] )
, ( "help", UiIcon.help, [] )
, ( "checklist", UiIcon.checklist, [] )
, ( "checklistComplete", UiIcon.checklistComplete, [] )
]
)
, ( "Bulbs"
, [ ( "sparkleBulb", UiIcon.sparkleBulb, [] )
, ( "baldBulb", UiIcon.baldBulb, [] )
]
)
, ( "Science & Measurement"
, [ ( "compass", UiIcon.compass, [] )
, ( "speedometer", UiIcon.speedometer, [] )
, ( "performance", UiIcon.performance, [] )
, ( "microscope", UiIcon.microscope, [] )
, ( "scale", UiIcon.scale, [] )
]
)
, ( "Humans & Class"
, [ ( "person", UiIcon.person, [] )
, ( "couple", UiIcon.couple, [] )
, ( "class", UiIcon.class, [] )
, ( "leaderboard", UiIcon.leaderboard, [] )
, ( "graduateCap", UiIcon.graduateCap, [] )
]
)
, ( "Time"
, [ ( "emptyCalendar", UiIcon.emptyCalendar, [] )
, ( "calendar", UiIcon.calendar, [] )
, ( "clock", UiIcon.clock, [] )
]
)
, ( "Texts"
, [ ( "missingDocument", UiIcon.missingDocument, [] )
, ( "document", UiIcon.document, [] )
, ( "documents", UiIcon.documents, [] )
, ( "newspaper", UiIcon.newspaper, [] )
, ( "openBook", UiIcon.openBook, [] )
, ( "openBooks", UiIcon.openBooks, [] )
]
)
, ( "Communication"
, [ ( "speechBalloon", UiIcon.speechBalloon, [] )
, ( "mail", UiIcon.mail, [] )
]
)
, ( "Writing Utensils"
, [ ( "edit", UiIcon.edit, [] )
, ( "pen", UiIcon.pen, [] )
, ( "highlighter", UiIcon.highlighter, [] )
]
)
, ( "Arrows"
, [ ( "arrowTop", UiIcon.arrowTop, [] )
, ( "arrowRight", UiIcon.arrowRight, [] )
, ( "arrowDown", UiIcon.arrowDown, [] )
, ( "arrowLeft", UiIcon.arrowLeft, [] )
, ( "arrowPointingRight", UiIcon.arrowPointingRight, [] )
, ( "arrowPointingRightThick", UiIcon.arrowPointingRightThick, [] )
, ( "sortArrow", UiIcon.sortArrow, [] )
, ( "sortArrowDown", UiIcon.sortArrowDown, [] )
]
)
, ( "Checks"
, [ ( "checkmark", UiIcon.checkmark, [] )
, ( "checkmarkInCircle", UiIcon.checkmarkInCircle, [] )
, ( "checkmarkInCircleInverse", UiIcon.checkmarkInCircleInverse, [] )
, ( "emptyCircle", UiIcon.emptyCircle, [] )
]
)
, ( "Xs"
, [ ( "x", UiIcon.x, [] )
, ( "xInCircle", UiIcon.xInCircle, [] )
]
)
, ( "Bangs"
, [ ( "attention", UiIcon.attention, [] )
, ( "exclamation", UiIcon.exclamation, [] )
]
)
, ( "Math"
, [ ( "equals", UiIcon.equals, [] )
, ( "plus", UiIcon.plus, [] )
, ( "null", UiIcon.null, [] )
]
)
, ( "Notifs"
, [ ( "flag", UiIcon.flag, [] )
, ( "star", UiIcon.star, [] )
, ( "starFilled", UiIcon.starFilled, [] )
, ( "starOutline", UiIcon.starOutline, [] )
]
)
, ( "Badges & Celebration"
, [ ( "badge", UiIcon.badge, [] )
, ( "tada", UiIcon.tada, [] )
]
)
, ( "Lock & Key"
, [ ( "key", UiIcon.key, [] )
, ( "lock", UiIcon.lock, [] )
, ( "premiumLock", UiIcon.premiumLock, [] )
]
)
, ( "Tips & Tricks"
, [ ( "hat", UiIcon.hat, [] )
, ( "keychain", UiIcon.keychain, [] )
]
)
, ( "Growth"
, [ ( "sprout", UiIcon.sprout, [] )
, ( "sapling", UiIcon.sapling, [] )
, ( "tree", UiIcon.tree, [] )
]
)
, ( "Rich Text Formatting"
, [ ( "bold", UiIcon.bold, [] )
, ( "italic", UiIcon.italic, [] )
, ( "underline", UiIcon.underline, [] )
, ( "list", UiIcon.list, [] )
, ( "link", UiIcon.link, [] )
, ( "undo", UiIcon.undo, [] )
, ( "redo", UiIcon.redo, [] )
]
)
, ( "Punctuation"
, [ ( "openQuotationMark", UiIcon.openQuotationMark, [] )
, ( "closeQuotationMark", UiIcon.closeQuotationMark, [] )
]
)
, ( "Navigation"
, [ ( "home", UiIcon.home, [] )
, ( "library", UiIcon.library, [] )
]
)
, ( "Search"
, [ ( "search", UiIcon.search, [] )
, ( "searchInCircle", UiIcon.searchInCicle, [] )
]
)
, ( "School Category"
, [ ( "school", UiIcon.school, [] )
, ( "highSchool", UiIcon.highSchool, [] )
, ( "company", UiIcon.company, [] )
, ( "homeSchool", UiIcon.homeSchool, [] )
]
)
, ( "Location"
, [ ( "flagUs", UiIcon.flagUs, [] )
, ( "globe", UiIcon.globe, [] )
]
)
]

View File

@ -2,6 +2,7 @@ module Spec.Nri.Ui.Menu exposing (spec)
import Html.Attributes as Attributes
import Html.Styled as HtmlStyled
import Json.Encode as Encode
import Nri.Ui.ClickableText.V3 as ClickableText
import Nri.Ui.Menu.V3 as Menu
import ProgramTest exposing (ProgramTest, ensureViewHas, ensureViewHasNot)
@ -32,6 +33,44 @@ spec =
|> clickMenuButton
|> ensureViewHasNot (menuContentSelector menuContent)
|> ProgramTest.done
, test "Close on tab key" <|
\() ->
program []
-- Menu opens on mouse click and closes on tab key
|> clickMenuButton
|> ensureViewHas (menuContentSelector menuContent)
|> pressTabKey { targetId = Nothing }
|> ensureViewHasNot (menuContentSelector menuContent)
|> ProgramTest.done
, test "Close on esc key" <|
\() ->
program []
-- Menu opens on mouse click and closes on tab key
|> clickMenuButton
|> ensureViewHas (menuContentSelector menuContent)
|> pressEscKey { targetId = Nothing }
|> ensureViewHasNot (menuContentSelector menuContent)
|> ProgramTest.done
, describe "disclosure" <|
[ test "Close on esc key" <|
\() ->
program [ Menu.disclosure { lastId = "last-button" } ]
-- Menu opens on mouse click and closes on esc key
|> clickMenuButton
|> ensureViewHas (menuContentSelector menuContent)
|> pressEscKey { targetId = Nothing }
|> ensureViewHasNot (menuContentSelector menuContent)
|> ProgramTest.done
, test "Closes after tab on lastId" <|
\() ->
program [ Menu.disclosure { lastId = "last-button" } ]
|> clickMenuButton
|> ensureViewHas (menuContentSelector menuContent)
-- NOTE: unable to simulate pressTabKey with other targetId since those decoders will fail
|> pressTabKey { targetId = Just "last-button" }
|> ensureViewHasNot (menuContentSelector menuContent)
|> ProgramTest.done
]
]
@ -58,6 +97,9 @@ program attributes =
[ Menu.entry "hello-button" <|
\attrs ->
ClickableText.button menuContent [ ClickableText.custom attrs ]
, Menu.entry "last-button" <|
\attrs ->
ClickableText.button menuContent [ ClickableText.custom attrs ]
]
, focusAndToggle = \{ isOpen } -> isOpen
}
@ -122,3 +164,38 @@ clickMenuButton =
]
)
Event.click
pressKey : { targetId : Maybe String, keyCode : Int, shiftKey : Bool } -> ProgramTest model msg effect -> ProgramTest model msg effect
pressKey { targetId, keyCode, shiftKey } =
ProgramTest.simulateDomEvent
(Query.find
[ Selector.class "Container"
]
)
(Event.custom
"keydown"
(Encode.object
[ ( "keyCode", Encode.int keyCode )
, ( "shiftKey", Encode.bool shiftKey )
, ( "target"
, Encode.object
(List.filterMap identity <|
[ targetId
|> Maybe.map (\id -> ( "id", Encode.string id ))
]
)
)
]
)
)
pressTabKey : { targetId : Maybe String } -> ProgramTest model msg effect -> ProgramTest model msg effect
pressTabKey { targetId } =
pressKey { targetId = targetId, keyCode = 9, shiftKey = False }
pressEscKey : { targetId : Maybe String } -> ProgramTest model msg effect -> ProgramTest model msg effect
pressEscKey { targetId } =
pressKey { targetId = targetId, keyCode = 27, shiftKey = False }