Merge remote-tracking branch 'origin/master' into tessa/remove-old-components

This commit is contained in:
Tessa Kelly 2020-05-01 10:35:55 -07:00
commit f7cf19a07e
19 changed files with 968 additions and 274 deletions

View File

@ -0,0 +1,89 @@
module MessageV1 exposing (..)
{-| NOTE: requires elm-refactor alpha-220-g24db2f5 or later.
-}
import Nri.Ui.Message.V1 as Message
--
-- Nri.Ui.Alert.V4
--
upgrade_Nri_Ui_Alert_V4_error content =
Message.tiny Message.Error (Message.Markdown content)
upgrade_Nri_Ui_Alert_V4_warning content =
Message.tiny Message.Alert (Message.Markdown content)
upgrade_Nri_Ui_Alert_V4_tip content =
Message.tiny Message.Tip (Message.Markdown content)
upgrade_Nri_Ui_Alert_V4_success content =
Message.tiny Message.Success (Message.Markdown content)
upgrade_Nri_Ui_Alert_V4_somethingWentWrong errorMessageForEngineers =
Message.somethingWentWrong errorMessageForEngineers
--
-- Nri.Ui.BannerAlert.V6
--
upgrade_Nri_Ui_BannerAlert_V6_alert content maybeOnDismiss =
Message.banner Message.Alert
(Message.Html content)
(List.filterMap identity
[ Maybe.map Message.onDismiss maybeOnDismiss
]
)
upgrade_Nri_Ui_BannerAlert_V6_error content maybeOnDismiss =
Message.banner Message.Error
(Message.Html content)
(List.filterMap identity
[ Maybe.map Message.onDismiss maybeOnDismiss
]
)
upgrade_Nri_Ui_BannerAlert_V6_neutral content maybeOnDismiss =
Message.banner Message.Tip
(Message.Html content)
(List.filterMap identity
[ Maybe.map Message.onDismiss maybeOnDismiss
]
)
upgrade_Nri_Ui_BannerAlert_V6_success content maybeOnDismiss =
Message.banner Message.Success
(Message.Html content)
(List.filterMap identity
[ Maybe.map Message.onDismiss maybeOnDismiss
]
)
upgrade_Nri_Ui_BannerAlert_V6_custom config =
Message.banner
(Message.Custom
{ color = config.color
, backgroundColor = config.backgroundColor
, icon = config.icon
}
)
(Message.Html config.content)
(List.filterMap identity
[ Maybe.map Message.onDismiss config.dismiss
]
)

View File

@ -3,7 +3,7 @@
"name": "NoRedInk/noredink-ui",
"summary": "UI Widgets we use at NRI",
"license": "BSD-3-Clause",
"version": "8.2.0",
"version": "8.3.1",
"exposed-modules": [
"Nri.Ui",
"Nri.Ui.Accordion.V1",
@ -36,6 +36,7 @@
"Nri.Ui.Loading.V1",
"Nri.Ui.Logo.V1",
"Nri.Ui.MasteryIcon.V1",
"Nri.Ui.Message.V1",
"Nri.Ui.Modal.V2",
"Nri.Ui.Modal.V3",
"Nri.Ui.Modal.V8",

View File

@ -8,12 +8,7 @@ src/Nri/Ui/Page/V3.elm,Nri.Ui.Text,2
src/Nri/Ui/SlideModal/V2.elm,Nri.Ui.Button,8
src/Nri/Ui/SlideModal/V2.elm,Nri.Ui.Icon,3
src/Nri/Ui/SlideModal/V2.elm,Nri.Ui.Text,2
src/Nri/Ui/Alert/V4.elm,Nri.Ui.Icon,3
src/Nri/Ui/TextInput/V6.elm,Nri.Ui.InputStyles,2
src/Nri/Ui/SortableTable/V1.elm,Nri.Ui.Table,4
src/Nri/Ui/Checkbox/V3.elm,Nri.Ui.Html,3
src/Nri/Ui/Checkbox/V5.elm,Nri.Ui.Html,3
src/Nri/Ui/TextArea/V4.elm,Nri.Ui.InputStyles,2
src/Nri/Ui/Button/V8.elm,Html,DEPRECATED
src/Nri/Ui/Button/V5.elm,Nri.Ui.Icon,3
src/Nri/Ui/SegmentedControl/V6.elm,Nri.Ui.Icon,3

1 filename name version
8 src/Nri/Ui/SlideModal/V2.elm Nri.Ui.Button 8
9 src/Nri/Ui/SlideModal/V2.elm Nri.Ui.Icon 3
10 src/Nri/Ui/SlideModal/V2.elm Nri.Ui.Text 2
src/Nri/Ui/Alert/V4.elm Nri.Ui.Icon 3
src/Nri/Ui/TextInput/V6.elm Nri.Ui.InputStyles 2
11 src/Nri/Ui/SortableTable/V1.elm Nri.Ui.Table 4
src/Nri/Ui/Checkbox/V3.elm Nri.Ui.Html 3
src/Nri/Ui/Checkbox/V5.elm Nri.Ui.Html 3
src/Nri/Ui/TextArea/V4.elm Nri.Ui.InputStyles 2
12 src/Nri/Ui/Button/V8.elm Html DEPRECATED
13 src/Nri/Ui/Button/V5.elm Nri.Ui.Icon 3
14 src/Nri/Ui/SegmentedControl/V6.elm Nri.Ui.Icon 3

View File

@ -6,6 +6,9 @@ module Nri.Ui.Alert.V4 exposing
{-|
# DEPRECATED: Use `Nri.Ui.Message.V1.tiny` instead
# Changes from V3:
- Changes the error font color from `purpleDark` to `purple`
@ -30,12 +33,16 @@ import Markdown
import Nri.Ui
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Icon.V3 as Icon
import Nri.Ui.SpriteSheet exposing (bulb, checkmark, exclamationMark)
import Nri.Ui.Svg.V1 as NriSvg exposing (Svg)
{-| -}
{-|
# DEPRECATED: Use `Nri.Ui.Message.V1.somethingWentWrong` instead
-}
somethingWentWrong : String -> Html msg
somethingWentWrong errorMessageForEngineers =
Html.div []
@ -68,10 +75,10 @@ somethingWentWrong errorMessageForEngineers =
]
{-| import Nri.Ui.Alert.V4 as Alert
{-|
view =
Alert.error "Some **awesome** message!"
# DEPRECATED: Use `Nri.Ui.Message.V1.tiny Error` instead
-}
error : String -> Html msg
@ -82,10 +89,10 @@ error content =
]
{-| import Nri.Ui.Alert.V4 as Alert
{-|
view =
Alert.success "Some **awesome** message!"
# DEPRECATED: Use `Nri.Ui.Message.V1.tiny Success` instead
-}
success : String -> Html msg
@ -103,10 +110,10 @@ success content =
]
{-| import Nri.Ui.Alert.V4 as Alert
{-|
view =
Alert.tip "Some **awesome** message!"
# DEPRECATED: Use `Nri.Ui.Message.V1.tiny Tip` instead
-}
tip : String -> Html msg
@ -117,10 +124,10 @@ tip content =
]
{-| import Nri.Ui.Alert.V4 as Alert
{-|
view =
Alert.warning "Some **awesome** message!"
# DEPRECATED: Use `Nri.Ui.Message.V1.tiny Alert` instead
-}
warning : String -> Html msg

View File

@ -5,6 +5,9 @@ module Nri.Ui.BannerAlert.V6 exposing
{-|
# DEPRECATED: Use `Nri.Ui.Message.V1.banner` instead
@docs alert, error, neutral, success
@docs custom
@ -24,7 +27,7 @@ import Accessibility.Styled as Html exposing (Html)
import Accessibility.Styled.Widget as Widget
import Css
import Css.Global
import Html.Styled.Attributes as Attributes exposing (css)
import Html.Styled.Attributes exposing (css)
import Html.Styled.Events
import Nri.Ui
import Nri.Ui.Colors.V1 as Colors
@ -33,7 +36,11 @@ import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Nri.Ui.UiIcon.V1 as UiIcon
{-| A banner to show error alerts
{-|
# DEPRECATED: Use `Nri.Ui.Message.V1.banner Alert` instead
-}
alert : List (Html msg) -> Maybe msg -> Html msg
alert content maybeDismiss =
@ -52,7 +59,11 @@ alert content maybeDismiss =
}
{-| A banner to show error alerts
{-|
# DEPRECATED: Use `Nri.Ui.Message.V1.banner Error` instead
-}
error : List (Html msg) -> Maybe msg -> Html msg
error content maybeDismiss =
@ -71,7 +82,11 @@ error content maybeDismiss =
}
{-| A banner to show neutral alerts
{-|
# DEPRECATED: Use `Nri.Ui.Message.V1.banner Tip` instead
-}
neutral : List (Html msg) -> Maybe msg -> Html msg
neutral content maybeDismiss =
@ -90,7 +105,11 @@ neutral content maybeDismiss =
}
{-| A banner for success alerts
{-|
# DEPRECATED: Use `Nri.Ui.Message.V1.banner Success` instead
-}
success : List (Html msg) -> Maybe msg -> Html msg
success content maybeDismiss =
@ -109,7 +128,11 @@ success content maybeDismiss =
}
{-| Use to construct a custom banner. Prefer to use a pre-made banner when possible.
{-|
# DEPRECATED: Use `Nri.Ui.Message.V1.banner Custom` instead
-}
custom :
{ color : Css.Color

View File

@ -7,6 +7,9 @@ module Nri.Ui.Callout.V1 exposing
{-|
# DEPRECATED: talk with your designer, but generally prefer `Message.large`, or consider adding `Message.medium`
@docs Attribute, callout
@docs label

544
src/Nri/Ui/Message/V1.elm Normal file
View File

@ -0,0 +1,544 @@
module Nri.Ui.Message.V1 exposing
( tiny, large, banner
, Theme(..), Content(..), mapContent, BannerAttribute
, onDismiss
, somethingWentWrong
)
{-|
@docs tiny, large, banner
@docs Theme, Content, mapContent, BannerAttribute
@docs onDismiss
@docs somethingWentWrong
-}
import Accessibility.Styled as Html exposing (..)
import Accessibility.Styled.Widget as Widget
import Css exposing (..)
import Css.Global
import Html.Styled exposing (styled)
import Html.Styled.Attributes exposing (css)
import Html.Styled.Events exposing (onClick)
import Markdown
import Nri.Ui
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Svg.V1 as NriSvg exposing (Svg)
import Nri.Ui.UiIcon.V1 as UiIcon
{-| `Error` / `Alert` / `Tip` / `Success`
-}
type Theme
= Error
| Alert
| Tip
| Success
| Custom
{ color : Color
, backgroundColor : Color
, icon : Svg
}
{-| Prefer using the simplest variant that meets your needs.
- `Plain`: provide a plain-text string
- `Markdown`: provide a string that will be rendered as markdown
- `Html`: provide custom HTML
-}
type Content msg
= Plain String
| Markdown String
| Html (List (Html msg))
{-| Transform the messages produced by some `Content`.
-}
mapContent : (a -> b) -> Content a -> Content b
mapContent f content =
case content of
Plain string ->
Plain string
Markdown string ->
Markdown string
Html html ->
Html (List.map (Html.map f) html)
{-| PRIVATE
-}
contentToHtml : Content msg -> List (Html msg)
contentToHtml content =
case content of
Plain stringContent ->
[ text stringContent ]
Markdown markdownContent ->
Markdown.toHtml Nothing markdownContent |> List.map fromUnstyled
Html html ->
html
{-| Shows a tiny alert message. We commonly use these for validation errors and small hints to users.
import Nri.Ui.Message.V1 as Message
view =
Message.tiny Message.Tip (Message.Markdown "Don't tip too much, or your waitress will **fall over**!")
NOTE: When using a `Custom` theme, `tiny` ignores the custom `backgroundColor`.
-}
tiny : Theme -> Content msg -> Html msg
tiny theme content =
let
config =
case theme of
Error ->
{ icon =
UiIcon.exclamation
|> NriSvg.withColor Colors.purple
|> NriSvg.withLabel "Error"
, fontColor = Colors.purple
}
Alert ->
{ icon =
UiIcon.exclamation
|> NriSvg.withColor Colors.red
|> NriSvg.withLabel "Alert"
, fontColor = Colors.redDark
}
Tip ->
{ icon =
UiIcon.bulb
|> NriSvg.withColor Colors.yellow
|> NriSvg.withLabel "Tip"
, fontColor = Colors.navy
}
Success ->
{ icon =
UiIcon.checkmarkInCircle
|> NriSvg.withColor Colors.green
|> NriSvg.withLabel "Success"
, fontColor = Colors.greenDarkest
}
Custom customTheme ->
{ icon = customTheme.icon
, fontColor = customTheme.color
}
in
Nri.Ui.styled div
"Nri-Ui-Message-V1--tiny"
[ displayFlex
, justifyContent start
, paddingTop (px 6)
, paddingBottom (px 8)
]
[]
[ styled div
[]
[]
[ Nri.Ui.styled div
"Nri-Ui-Message-V1--tinyIconContainer"
[ -- Content positioning
displayFlex
, alignItems center
, justifyContent center
, marginRight (px 5)
, lineHeight (px 13)
, flexShrink zero
-- Size
, borderRadius (px 13)
, height (px 20)
, width (px 20)
]
[]
[ NriSvg.toHtml config.icon ]
]
, styled div
[ displayFlex
, alignItems center
]
[]
[ Nri.Ui.styled div
"Nri-Ui-Message-V1--alert"
[ color config.fontColor
, Fonts.baseFont
, fontSize (px 13)
--, lineHeight (px 20)
, listStyleType none
-- This global selector and overrides are necessary due to
-- old stylesheets used on the monolith that set the
-- `.txt p { font-size: 18px; }` -- without these overrides,
-- we may see giant ugly alerts.
-- Remove these if you want to! but be emotionally prepped
-- to deal with visual regressions. 🙏
, Css.Global.descendants
[ Css.Global.p
[ margin zero
--, lineHeight (px 20)
, fontSize (px 13)
, Fonts.baseFont
]
]
]
[]
(contentToHtml content)
]
]
{-| Shows a large alert or callout message. We commonly use these for highlighted tips, instructions, or asides in page copy.
import Nri.Ui.Message.V1 as Message
view =
Message.large Message.Tip (Message.Plain "Two out of two parents agree: NoRedInk sounds like a fun place to work.")
-}
large : Theme -> Content msg -> Html msg
large theme content =
let
config =
case theme of
Error ->
{ backgroundColor = Colors.purpleLight
, fontColor = Colors.purpleDark
, icon =
UiIcon.exclamation
|> NriSvg.withColor Colors.purple
|> NriSvg.withLabel "Error"
}
Alert ->
{ backgroundColor = Colors.sunshine
, fontColor = Colors.navy
, icon =
UiIcon.exclamation
|> NriSvg.withColor Colors.ochre
|> NriSvg.withLabel "Alert"
}
Tip ->
{ backgroundColor = Colors.sunshine
, fontColor = Colors.navy
, icon =
UiIcon.bulb
|> NriSvg.withColor Colors.navy
|> NriSvg.withLabel "Tip"
}
Success ->
{ backgroundColor = Colors.greenLightest
, fontColor = Colors.greenDarkest
, icon =
UiIcon.checkmarkInCircle
|> NriSvg.withColor Colors.green
|> NriSvg.withLabel "Success"
}
Custom customTheme ->
{ backgroundColor = customTheme.backgroundColor
, fontColor = customTheme.color
, icon = customTheme.icon
}
in
Nri.Ui.styled div
"Nri-Ui-Message-V1--large"
[ width (pct 100)
, backgroundColor config.backgroundColor
, Fonts.baseFont
, fontSize (px 15)
, fontWeight (int 600)
, boxSizing borderBox
, padding (px 20)
, borderRadius (px 8)
, color config.fontColor
, displayFlex
, alignItems center
]
[]
[ styled div
[ width (px 35)
, marginRight (px 10)
]
[]
[ NriSvg.toHtml config.icon
]
, styled div
[ minWidth (px 100)
, flexBasis (px 100)
, flexGrow (int 1)
]
[]
(contentToHtml content)
]
{-| PRIVATE
-}
type BannerAttribute msg
= BannerAttribute (BannerConfig msg -> BannerConfig msg)
{-| Adds a dismiss ("X" icon) to a banner which will produce the given `msg` when clicked.
-}
onDismiss : msg -> BannerAttribute msg
onDismiss msg =
BannerAttribute <|
\config ->
{ config | onDismiss = Just msg }
{-| PRIVATE
-}
type alias BannerConfig msg =
{ onDismiss : Maybe msg
}
{-| PRIVATE
-}
bannerConfigFromAttributes : List (BannerAttribute msg) -> BannerConfig msg
bannerConfigFromAttributes attr =
List.foldl (\(BannerAttribute set) -> set)
{ onDismiss = Nothing }
attr
{-| Shows a banner alert message. This is even more prominent than `Message.large`.
We commonly use these for flash messages at the top of pages.
import Nri.Ui.Message.V1 as Message
view =
Message.banner Message.Success (Message.Plain "John Jacob Jingleheimer Schmidt has been dropped from First Period English.")
-}
banner : Theme -> Content msg -> List (BannerAttribute msg) -> Html msg
banner theme content attr =
let
config =
case theme of
Error ->
{ backgroundColor = Colors.purpleLight
, color = Colors.purpleDark
, icon =
UiIcon.exclamation
|> NriSvg.withColor Colors.purple
|> NriSvg.withLabel "Error"
|> NriSvg.toHtml
}
Alert ->
{ backgroundColor = Colors.sunshine
, color = Colors.navy
, icon =
UiIcon.exclamation
|> NriSvg.withColor Colors.ochre
|> NriSvg.withLabel "Alert"
|> NriSvg.toHtml
}
Tip ->
{ backgroundColor = Colors.frost
, color = Colors.navy
, icon =
inCircle
{ backgroundColor = Colors.navy
, color = Colors.mustard
, height = Css.px 32
, icon = UiIcon.bulb
}
}
Success ->
{ backgroundColor = Colors.greenLightest
, color = Colors.greenDarkest
, icon =
UiIcon.checkmarkInCircle
|> NriSvg.withColor Colors.green
|> NriSvg.withLabel "Success"
|> NriSvg.toHtml
}
Custom customTheme ->
{ backgroundColor = customTheme.backgroundColor
, color = customTheme.color
, icon = NriSvg.toHtml customTheme.icon
}
attributes =
bannerConfigFromAttributes attr
in
styled div
[ displayFlex
, justifyContent center
, alignItems center
, backgroundColor config.backgroundColor
, color config.color
]
[]
[ styled span
[ alignItems center
, displayFlex
, justifyContent center
, padding (px 20)
, width (Css.pct 100)
, Css.Global.children
[ Css.Global.button
[ position relative
, right (px 15)
]
]
]
[]
[ styled div
[ width (px 50)
, height (px 50)
, marginRight (px 20)
, -- NOTE: I think it's normally best to avoid relying on flexShrink (and use flexGrow/flexBasis) instead,
-- But using shrink here and on the next div lets us have the text content be centered rather than
-- left-aligned when the content is shorter than one line
flexShrink zero
]
[]
[ config.icon ]
, Nri.Ui.styled div
"banner-alert-notification"
[ fontSize (px 20)
, fontWeight (int 700)
, lineHeight (px 27)
, maxWidth (px 600)
, minWidth (px 100)
, flexShrink (int 1)
, Fonts.baseFont
, Css.Global.descendants
[ Css.Global.a
[ textDecoration none
, color Colors.azure
, borderBottom3 (px 1) solid Colors.azure
, visited [ color Colors.azure ]
]
]
]
[]
(contentToHtml content)
]
, case attributes.onDismiss of
Nothing ->
text ""
Just msg ->
bannerDismissButton msg
]
{-| Shows an appropriate error message for when something unhandled happened.
import Nri.Ui.Message.V1 as Message
view maybeDetailedErrorMessage =
viewMaybe Message.somethingWentWrong maybeDetailedErrorMessage
-}
somethingWentWrong : String -> Html msg
somethingWentWrong errorMessageForEngineers =
div []
[ tiny Error (Plain "Sorry, something went wrong. Please try again later.")
, details []
[ summary
[ css
[ Fonts.baseFont
, fontSize (px 14)
, color Colors.gray45
]
]
[ text "Details for NoRedInk engineers" ]
, code
[ css
[ display block
, whiteSpace normal
, overflowWrap breakWord
, color Colors.gray45
, backgroundColor Colors.gray96
, border3 (px 1) solid Colors.gray92
, borderRadius (px 3)
, padding2 (px 2) (px 4)
, fontSize (px 12)
, fontFamily monospace
]
]
[ text errorMessageForEngineers ]
]
]
--
-- PRIVATE
--
inCircle :
{ backgroundColor : Css.Color
, color : Css.Color
, height : Css.Px
, icon : Svg
}
-> Html msg
inCircle config =
styled div
[ borderRadius (pct 50)
, height (pct 100)
, backgroundColor config.backgroundColor
, displayFlex
, alignItems center
, justifyContent center
]
[]
[ config.icon
|> NriSvg.withColor config.color
|> NriSvg.withHeight config.height
|> NriSvg.toHtml
]
bannerDismissButton : msg -> Html msg
bannerDismissButton msg =
Nri.Ui.styled div
"dismiss-button-container"
[ padding (px 25)
]
[]
[ styled button
[ borderWidth zero
, backgroundColor unset
, color Colors.azure
, width (px 30)
, height (px 30)
, padding2 zero (px 7)
, cursor pointer
]
[ onClick msg
, Widget.label "Dismiss banner"
]
[ NriSvg.toHtml UiIcon.x
]
]

View File

@ -147,14 +147,23 @@ viewTab { onSelect, tabs } viewInnerTab selected tab =
let
isSelected =
selected.id == tab.id
tabIndex =
-- From recommendation at https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role#Best_practices
if isSelected then
0
else
-1
in
Html.styled Html.li
Html.styled Html.button
(stylesTabSelectable isSelected)
[ Events.onClick (onSelect tab.id)
, Key.onKeyDown [ Key.enter (onSelect tab.id) ]
, Events.onFocus (onSelect tab.id)
, Attributes.tabindex 0
, Role.presentation
, Attributes.tabindex tabIndex
, Widget.selected (selected.id == tab.id)
, Role.tab
, Attributes.id (tabToId tab)
, Events.on "keyup" <|
Json.Decode.andThen
@ -175,10 +184,9 @@ viewTab { onSelect, tabs } viewInnerTab selected tab =
Json.Decode.fail "Wrong key code"
)
Events.keyCode
]
[ Html.styled Html.div
, Attributes.css
[ Css.color Colors.navy
, Css.display Css.inlineBlock
, Css.margin zero
, Css.padding4 (Css.px 14) (Css.px 20) (Css.px 12) (Css.px 20)
, Css.position Css.relative
, Css.textDecoration Css.none
@ -186,12 +194,10 @@ viewTab { onSelect, tabs } viewInnerTab selected tab =
, Css.fontFamily Css.inherit
, Css.fontSize Css.inherit
, Css.cursor Css.pointer
, Css.border zero
]
[ Role.tab
, Attributes.tabindex -1
, Widget.selected (selected.id == tab.id)
]
[ viewInnerTab tab ]
]
[ viewInnerTab tab
]
@ -249,7 +255,7 @@ links config =
[ Role.tabList
]
(config.tabs
|> mapWithCurrent (viewTabLink config)
|> mapWithCurrent viewTabLink
|> List.Zipper.toList
)
]
@ -257,8 +263,8 @@ links config =
]
viewTabLink : LinkConfig msg -> Bool -> LinkTabConfig msg -> Html msg
viewTabLink config isSelected tabConfig =
viewTabLink : Bool -> LinkTabConfig msg -> Html msg
viewTabLink isSelected tabConfig =
let
( tabLabel, tabHref, preventDefault ) =
case tabConfig of

View File

@ -10,7 +10,7 @@ module Nri.Ui.UiIcon.V1 exposing
, document, newspaper
, edit, pen
, arrowTop, arrowRight, arrowDown, arrowLeft, arrowPointingRight
, checkmark, x
, checkmark, checkmarkInCircle, x
, attention, exclamation
, flag, star, starOutline
, equals, plus
@ -18,7 +18,7 @@ module Nri.Ui.UiIcon.V1 exposing
, badge
)
{-|
{-| How to add new icons: <https://paper.dropbox.com/doc/How-to-create-a-new-SVG-icon-for-use-in-Elm--Ay9uhSLfGUAix0ERIiJ0Dm8dAg-8WNqtARdr4EgjmYEHPeYD>
@docs seeMore, openClose, download, sort, gear, flipper, sortArrow
@docs unarchive, share, preview, skip, copyToClipboard, gift
@ -31,7 +31,7 @@ module Nri.Ui.UiIcon.V1 exposing
@docs document, newspaper
@docs edit, pen
@docs arrowTop, arrowRight, arrowDown, arrowLeft, arrowPointingRight
@docs checkmark, x
@docs checkmark, checkmarkInCircle, x
@docs attention, exclamation
@docs flag, star, starOutline
@docs equals, plus
@ -538,6 +538,32 @@ checkmark =
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
checkmarkInCircle : Nri.Ui.Svg.V1.Svg
checkmarkInCircle =
Svg.svg
[ Attributes.width "100%"
, Attributes.height "100%"
, Attributes.fill "currentcolor"
, Attributes.viewBox "0 0 50 50"
]
[ Svg.g []
[ Svg.circle
[ Attributes.cx "25"
, Attributes.cy "25"
, Attributes.r "25"
]
[]
, Svg.path
[ Attributes.fill "#FFFFFF"
, Attributes.d "M20.812258,34.6599998 C20.2178448,34.6599998 19.6442477,34.4310236 19.2140498,34.0181724 L12.7148242,27.802276 C11.790824,26.9199078 11.7584435,25.4558474 12.6419681,24.5330036 C13.5220234,23.6101598 14.9872403,23.5766229 15.9112405,24.4601475 L20.7093343,29.0477682 L32.9896327,15.7451716 C33.8569671,14.8049812 35.3198711,14.7471589 36.2577487,15.6133368 C37.1967827,16.4806712 37.2557614,17.9435752 36.3895835,18.8814528 L22.5122334,33.9152487 C22.0901306,34.3720448 21.5049691,34.6391838 20.8839576,34.6588434 C20.8608287,34.6599998 20.8365434,34.6599998 20.812258,34.6599998"
]
[]
]
]
|> Nri.Ui.Svg.V1.fromHtml
{-| -}
x : Nri.Ui.Svg.V1.Svg
x =

View File

@ -5,7 +5,6 @@ import Css exposing (..)
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes
import Nri.Ui.Colors.V1 exposing (..)
import Sort.Set as Set exposing (Set)
type alias Example state msg =

View File

@ -2,9 +2,7 @@ module Examples exposing (Msg, State, all)
import Example exposing (Example)
import Examples.Accordion as Accordion
import Examples.Alert as Alert
import Examples.AssignmentIcon as AssignmentIcon
import Examples.BannerAlert as BannerAlert
import Examples.Button as Button
import Examples.Callout as Callout
import Examples.Checkbox as Checkbox
@ -19,6 +17,7 @@ import Examples.Icon as Icon
import Examples.Loading as Loading
import Examples.Logo as Logo
import Examples.MasteryIcon as MasteryIcon
import Examples.Message as Message
import Examples.Modal as Modal
import Examples.Page as Page
import Examples.Pennant as Pennant
@ -56,25 +55,6 @@ all =
AccordionState childState ->
Just childState
_ ->
Nothing
)
, Alert.example
|> Example.wrapMsg AlertMsg
(\msg ->
case msg of
AlertMsg childMsg ->
Just childMsg
_ ->
Nothing
)
|> Example.wrapState AlertState
(\msg ->
case msg of
AlertState childState ->
Just childState
_ ->
Nothing
)
@ -94,25 +74,6 @@ all =
AssignmentIconState childState ->
Just childState
_ ->
Nothing
)
, BannerAlert.example
|> Example.wrapMsg BannerAlertMsg
(\msg ->
case msg of
BannerAlertMsg childMsg ->
Just childMsg
_ ->
Nothing
)
|> Example.wrapState BannerAlertState
(\msg ->
case msg of
BannerAlertState childState ->
Just childState
_ ->
Nothing
)
@ -379,6 +340,25 @@ all =
MasteryIconState childState ->
Just childState
_ ->
Nothing
)
, Message.example
|> Example.wrapMsg MessageMsg
(\msg ->
case msg of
MessageMsg childMsg ->
Just childMsg
_ ->
Nothing
)
|> Example.wrapState MessageState
(\msg ->
case msg of
MessageState childState ->
Just childState
_ ->
Nothing
)
@ -710,9 +690,7 @@ all =
type State
= AccordionState Accordion.State
| AlertState Alert.State
| AssignmentIconState AssignmentIcon.State
| BannerAlertState BannerAlert.State
| ButtonState Button.State
| CalloutState Callout.State
| CheckboxState Checkbox.State
@ -727,6 +705,7 @@ type State
| LoadingState Loading.State
| LogoState Logo.State
| MasteryIconState MasteryIcon.State
| MessageState Message.State
| ModalState Modal.State
| PageState Page.State
| PennantState Pennant.State
@ -748,9 +727,7 @@ type State
type Msg
= AccordionMsg Accordion.Msg
| AlertMsg Alert.Msg
| AssignmentIconMsg AssignmentIcon.Msg
| BannerAlertMsg BannerAlert.Msg
| ButtonMsg Button.Msg
| CalloutMsg Callout.Msg
| CheckboxMsg Checkbox.Msg
@ -765,6 +742,7 @@ type Msg
| LoadingMsg Loading.Msg
| LogoMsg Logo.Msg
| MasteryIconMsg MasteryIcon.Msg
| MessageMsg Message.Msg
| ModalMsg Modal.Msg
| PageMsg Page.Msg
| PennantMsg Pennant.Msg

View File

@ -1,134 +0,0 @@
module Examples.BannerAlert exposing (example, State, init, Msg, update)
{-|
@docs example, State, init, Msg, update
@docs example_
-}
import Category exposing (Category(..))
import Css
import Example exposing (Example)
import Html.Styled exposing (Html, a, div, h3, pre, text)
import Html.Styled.Attributes as Attributes
import Nri.Ui.BannerAlert.V6 as BannerAlert
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Pennant.V2 as Pennant
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.UiIcon.V1 as UiIcon
{-| -}
example : Example State Msg
example =
{ name = "Nri.Ui.BannerAlert.V6"
, state = init
, update = update
, subscriptions = \_ -> Sub.none
, view = view
, categories = [ Messaging ]
}
view : State -> List (Html Msg)
view state =
[ if state.show then
div
[]
[ h3 [] [ text "alert" ]
, BannerAlert.alert [ text "Dismiss this alert message to see a success message!" ] (Just Dismiss)
, pre [] [ text "BannerAlert.alert [ text \"Dismiss this alert message to see a success message!\" ] (Just Dismiss)" ]
]
else
div
[]
[ h3 [] [ text "success" ]
, BannerAlert.success [ text "Nice! The alert message was dismissed. 👍" ] Nothing
, pre [] [ text "BannerAlert.success [ text \"Nice! The alert message was dismissed. 👍\" ] Nothing" ]
]
, h3 [] [ text "error" ]
, BannerAlert.error [ text "This is an error message!" ] Nothing
, pre [] [ text "BannerAlert.error [ text \"This is an error message!\" ] Nothing" ]
, h3 [] [ text "neutral" ]
, BannerAlert.neutral [ text "This is a neutral message!" ] Nothing
, pre [] [ text "BannerAlert.neutral [ text \"This is a neutral message!\" ] Nothing" ]
, h3 [] [ text "custom" ]
, BannerAlert.custom
{ color = Colors.aquaDark
, backgroundColor = Colors.gray92
, icon = Pennant.premiumFlag
, content = [ text "This is a a custom message!" ]
, dismiss = Nothing
}
, pre []
[ text
"""BannerAlert.custom
{ color = Colors.aquaDark
, backgroundColor = Colors.gray92
, icon = Pennant.premiumFlag
, content = [ text "This is a a custom message!" ]
, dismiss = Nothing
}
"""
]
, h3 [] [ text "with multi-line link and icon" ]
, BannerAlert.success
[ text "Click "
, a [ Attributes.href "http://www.noredink.com", Attributes.target "_blank" ]
[ text
"""here, yes, HERE, right here on this very long success message.
Wow, how successful! You're the biggest success I've ever seen!
You should feel great about yourself! Give yourself a very big round of applause!
"""
, div [ Attributes.css [ Css.display Css.inlineBlock, Css.width (Css.px 20) ] ]
[ Svg.toHtml UiIcon.gear ]
]
, text " to check out NoRedInk."
]
Nothing
, pre []
[ text
"""BannerAlert.success
[ text "Click "
, a [ Attributes.href "http://www.noredink.com", Attributes.target "_blank" ]
[ text
\"\"\"here, yes, HERE, right here on this very long success message.
Wow, how successful! You're the biggest success I've ever seen!
You should feel great about yourself! Give yourself a very big round of applause!
\"\"\"
, div [ Attributes.css [ Css.display Css.inlineBlock, Css.width (Css.px 20) ] ]
[ Svg.toHtml UiIcon.gear ]
]
, text " to check out NoRedInk."
]
Nothing
"""
]
]
type alias State =
{ show : Bool }
init : State
init =
{ show = True }
type Msg
= NoOp
| Dismiss
update : Msg -> State -> ( State, Cmd Msg )
update msg state =
case msg of
NoOp ->
( state, Cmd.none )
Dismiss ->
( { state | show = False }, Cmd.none )

View File

@ -6,12 +6,14 @@ module Examples.Callout exposing (example, State, Msg)
-}
import Accessibility.Styled exposing (text)
import Category exposing (Category(..))
import Css
import Example exposing (Example)
import Html.Styled as Html
import Html.Styled.Attributes exposing (href, title)
import Nri.Ui.Callout.V1 as Callout exposing (callout)
import Nri.Ui.Heading.V2 as Heading
type alias State =
@ -32,8 +34,11 @@ example =
, update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none
, view =
\_ ->
[ -- PLAIN
\() ->
[ Heading.h2 [ Heading.style Heading.Top ]
[ text "DEPRECATED: talk with your designer, but generally prefer `Message.large`, or consider adding `Message.medium`"
]
, -- PLAIN
Html.h3 [] [ Html.text "Originally Designed Use Case" ]
, callout
[ Callout.label (Html.text "BETA")

View File

@ -1,60 +1,174 @@
module Examples.Alert exposing (example, State, Msg)
{-|
@docs example, State, Msg
-}
module Examples.Message exposing (Msg, State, example)
import Accessibility.Styled as Html exposing (..)
import Category exposing (Category(..))
import Css exposing (..)
import Debug.Control as Control exposing (Control)
import Example exposing (Example)
import Html.Styled as Html
import Nri.Ui.Alert.V4 as Alert
import Html.Styled exposing (styled)
import Html.Styled.Attributes as Attributes exposing (href)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Message.V1 as Message
import Nri.Ui.Pennant.V2 as Pennant
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.UiIcon.V1 as UiIcon
type alias State =
()
{-| -}
type alias Msg =
()
{-| -}
example : Example State Msg
example =
{ name = "Nri.Ui.Alert.V4"
, categories = [ Messaging ]
, state = ()
, update = \_ state -> ( state, Cmd.none )
, subscriptions = \_ -> Sub.none
, view =
\_ ->
[ Heading.h3 [] [ Html.text "Markdown-supporting:" ]
, Alert.error "This is an **error**"
, Alert.warning "This is a **warning**"
, Alert.tip "This is a **tip**"
, Alert.success "This is a **success**"
, Html.hr [] []
, Heading.h3 [] [ Html.text "Stacktraces-supporting:" ]
, Alert.somethingWentWrong exampleRailsError
]
{ show : Bool
, control : Control ExampleConfig
}
complexHtml : String -> Html.Html msg
complexHtml name =
Html.div []
[ Html.p [] [ Html.text "We support more complex alerts as well." ]
, Html.p [] [ Html.text "Like this, for example!" ]
, Html.p [] [ Html.text ("I'm a " ++ name) ]
]
type alias ExampleConfig =
{ themes : List Message.Theme
, content : Message.Content Never
}
init : State
init =
{ show = True
, control =
Control.record ExampleConfig
|> Control.field "theme"
(Control.choice
[ ( "Error / Alert / Tip / Success"
, Control.value
[ Message.Error
, Message.Alert
, Message.Tip
, Message.Success
]
)
, ( "Custom (aquaDark, gray92, premiumFlag)"
, Control.value
[ Message.Custom
{ color = Colors.aquaDark
, backgroundColor = Colors.gray92
, icon = Pennant.premiumFlag
}
]
)
]
)
|> Control.field "content"
(Control.choice
[ ( "plain text (short)"
, Control.string "Comic books do count as literature."
|> Control.map Message.Plain
)
, ( "plain text (long)"
, Control.stringTextarea "Share this link with students as an easy shortcut to join Jeffy's Favorite Class (no class code needed). The link works for students new to NoRedInk and those with existing accounts. Students only need to use this link once to join."
|> Control.map Message.Plain
)
, ( "markdown"
, Control.string "_Katie's dad suggests:_ Don't tip too much, or your waitress will **fall over**!"
|> Control.map Message.Markdown
)
, ( "HTML"
, Control.value
(Message.Html
[ text "Click "
, a [ href "http://www.noredink.com", Attributes.target "_blank" ]
[ text "here, yes, HERE, right here on this very long success message. "
, text "Wow, how successful! You're the biggest success I've ever seen! "
, text "You should feel great about yourself! Give yourself a very big round of applause! "
, styled div
[ display inlineBlock
, width (px 20)
]
[]
[ Svg.toHtml UiIcon.gear ]
]
, text " to check out NoRedInk."
]
)
)
, ( "HTML (short)"
, Control.value
(Message.Html
[ code [] [ text "git status" ]
, text " "
, Html.em [] [ text "tries again" ]
]
)
)
]
)
}
-- INTERNAL
type Msg
= NoOp
| Dismiss
| UpdateControl (Control ExampleConfig)
update : Msg -> State -> ( State, Cmd Msg )
update msg state =
case msg of
NoOp ->
( state, Cmd.none )
Dismiss ->
( { state | show = False }, Cmd.none )
UpdateControl newControl ->
( { state | control = newControl }, Cmd.none )
example : Example State Msg
example =
{ name = "Nri.Ui.Message.V1"
, categories = [ Messaging ]
, state = init
, update = update
, subscriptions = \_ -> Sub.none
, view =
\state ->
let
exampleConfig =
Control.currentValue state.control
content =
Message.mapContent never exampleConfig.content
in
[ Control.view UpdateControl state.control
|> Html.fromUnstyled
, Heading.h3 [] [ text "Message.tiny" ]
, List.map (\theme -> Message.tiny theme content) exampleConfig.themes
|> div []
, Html.hr [] []
, Heading.h3 [] [ text "Message.large" ]
, List.map (\theme -> Message.large theme content) exampleConfig.themes
|> List.intersperse (br [])
|> div []
, Html.hr [] []
, Heading.h3 [] [ text "Message.banner" ]
, List.map (\theme -> Message.banner theme content []) exampleConfig.themes
|> List.intersperse (br [])
|> div []
, Heading.h3 [] [ text "Message.banner ... [ onDismiss msg ]" ]
, if state.show then
List.map
(\theme ->
Message.banner theme
content
[ Message.onDismiss Dismiss ]
)
exampleConfig.themes
|> List.intersperse (br [])
|> div []
else
text "Nice! The banner was dismissed. 👍"
, Html.hr [] []
, Heading.h3 [] [ text "Message.somethingWentWrong" ]
, Message.somethingWentWrong exampleRailsError
]
}
exampleRailsError : String

View File

@ -14,7 +14,6 @@ import Nri.Ui.Button.V5 as Button
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Table.V5 as Table
import Sort.Set as Set exposing (Set)
{-| -}
@ -36,7 +35,7 @@ example =
, subscriptions = \_ -> Sub.none
, categories = [ Tables ]
, view =
\state ->
\() ->
let
columns =
[ Table.string

View File

@ -41,14 +41,16 @@ example =
, tabs =
case tab of
First ->
List.Zipper.from []
List.Zipper.from
[]
(Tabs.Tab "First tab" First)
[ Tabs.Tab "Second tab" Second ]
Second ->
List.Zipper.from []
(Tabs.Tab "Second tab" Second)
List.Zipper.from
[ Tabs.Tab "First tab" First ]
(Tabs.Tab "Second tab" Second)
[]
, content =
\id ->
case id of

View File

@ -9,7 +9,6 @@ module Examples.UiIcon exposing (example, State, Msg)
import Category exposing (Category(..))
import Example exposing (Example)
import Examples.IconExamples as IconExamples
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.UiIcon.V1 as UiIcon
@ -82,6 +81,7 @@ example =
]
, IconExamples.view "Sticky things"
[ ( "checkmark", UiIcon.checkmark )
, ( "checkmarkInCircle", UiIcon.checkmarkInCircle )
, ( "x", UiIcon.x )
, ( "attention", UiIcon.attention )
, ( "exclamation", UiIcon.exclamation )

View File

@ -0,0 +1,36 @@
module Spec.Nri.Ui.Tabs.V4 exposing (all)
import Accessibility.Styled as Html
import Expect
import List.Zipper.Extra
import Nri.Ui.Tabs.V4 as Tabs
import ProgramTest
import Test exposing (..)
all : Test
all =
describe "Nri.Ui.Tabs.V4"
[ test "works with ProgramTest.clickButton" <|
\() ->
ProgramTest.createSandbox
{ init = Err "No msg"
, update = \newResult _ -> newResult
, view =
\_ ->
Tabs.view
{ title = Nothing
, onSelect = Ok
, tabs =
List.Zipper.Extra.from []
(Tabs.Tab "First tab" "ID_FIRST")
[ Tabs.Tab "Second tab" "ID_SECOND" ]
, content = \_ -> Html.text ""
, alignment = Tabs.Center
}
|> Html.toUnstyled
}
|> ProgramTest.start ()
|> ProgramTest.clickButton "Second tab"
|> ProgramTest.expectModel (Expect.equal (Ok "ID_SECOND"))
]

View File

@ -28,6 +28,7 @@
"Nri.Ui.Loading.V1",
"Nri.Ui.Logo.V1",
"Nri.Ui.MasteryIcon.V1",
"Nri.Ui.Message.V1",
"Nri.Ui.Modal.V2",
"Nri.Ui.Modal.V3",
"Nri.Ui.Modal.V8",