Merge branch 'master' into checkbox-custom-css

This commit is contained in:
charbelrami 2022-07-26 17:30:07 -03:00
commit 87a1a6c11b
44 changed files with 1905 additions and 175 deletions

View File

@ -1,6 +1,9 @@
Nri.Ui.Accordion.V1,upgrade to V3
Nri.Ui.Checkbox.V5,upgrade to V6
Nri.Ui.Heading.V2,upgrade to V3
Nri.Ui.Menu.V1,upgrade to V3
Nri.Ui.SideNav.V3,upgrade to V4
Nri.Ui.SortableTable.V2,upgrade to V3
Nri.Ui.Table.V5,upgrade to V6
Nri.Ui.Tabs.V6,upgrade to V7
Nri.Ui.Tooltip.V1,upgrade to V3

1 Nri.Ui.Accordion.V1 upgrade to V3
2 Nri.Ui.Checkbox.V5 upgrade to V6
3 Nri.Ui.Heading.V2 upgrade to V3
4 Nri.Ui.Menu.V1 upgrade to V3
5 Nri.Ui.SideNav.V3 upgrade to V4
6 Nri.Ui.SortableTable.V2 upgrade to V3
7 Nri.Ui.Table.V5 upgrade to V6
8 Nri.Ui.Tabs.V6 upgrade to V7
9 Nri.Ui.Tooltip.V1 upgrade to V3

View File

@ -3,7 +3,7 @@
"name": "NoRedInk/noredink-ui",
"summary": "UI Widgets we use at NRI",
"license": "BSD-3-Clause",
"version": "17.0.0",
"version": "17.2.0",
"exposed-modules": [
"Nri.Ui",
"Nri.Ui.Accordion.V1",
@ -31,6 +31,7 @@
"Nri.Ui.FocusTrap.V1",
"Nri.Ui.Fonts.V1",
"Nri.Ui.Heading.V2",
"Nri.Ui.Heading.V3",
"Nri.Ui.Html.Attributes.V2",
"Nri.Ui.Html.V3",
"Nri.Ui.InputStyles.V3",
@ -51,12 +52,14 @@
"Nri.Ui.Select.V8",
"Nri.Ui.Shadows.V1",
"Nri.Ui.SideNav.V3",
"Nri.Ui.SideNav.V4",
"Nri.Ui.SortableTable.V2",
"Nri.Ui.SortableTable.V3",
"Nri.Ui.Sprite.V1",
"Nri.Ui.Svg.V1",
"Nri.Ui.Switch.V2",
"Nri.Ui.Table.V5",
"Nri.Ui.Table.V6",
"Nri.Ui.Tabs.V6",
"Nri.Ui.Tabs.V7",
"Nri.Ui.Text.V6",

View File

@ -52,6 +52,9 @@ usages = ['styleguide-app/Examples/Tooltip.elm']
[forbidden."Nri.Ui.Container.V1"]
hint = 'upgrade to V2'
[forbidden."Nri.Ui.Heading.V2"]
hint = 'upgrade to V3'
[forbidden."Nri.Ui.Icon.V3"]
hint = 'upgrade to V5'
usages = ['styleguide-app/../src/Nri/Ui/Modal/V3.elm']
@ -117,6 +120,9 @@ hint = 'upgrade to V3'
[forbidden."Nri.Ui.SideNav.V2"]
hint = 'upgrade to V3'
[forbidden."Nri.Ui.SideNav.V3"]
hint = 'upgrade to V4'
[forbidden."Nri.Ui.SortableTable.V2"]
hint = 'upgrade to V3'
@ -126,6 +132,9 @@ hint = 'upgrade to V2'
[forbidden."Nri.Ui.Table.V4"]
hint = 'upgrade to V5'
[forbidden."Nri.Ui.Table.V5"]
hint = 'upgrade to V6'
[forbidden."Nri.Ui.Tabs.V6"]
hint = 'upgrade to V7'

View File

@ -23,10 +23,10 @@
"homepage": "",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "41cc1d5d9584103be4108c1815c350e07c807036",
"sha256": "1zwbkijhgb8a5wzsm1dya1a4y79bz6di5h49gcmw6klai84xxisv",
"rev": "e2b34f0f11ed8ad83d9ec9c14260192c3bcccb0d",
"sha256": "1n9lhqprqnsiv4nw59mh5ab7hchx7lhvq43kkv64473jwz1xv7ki",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/41cc1d5d9584103be4108c1815c350e07c807036.tar.gz",
"url": "https://github.com/NixOS/nixpkgs/archive/e2b34f0f11ed8ad83d9ec9c14260192c3bcccb0d.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}
}

View File

@ -49,7 +49,10 @@ describe("UI tests", function () {
const goTo = async (name, location) => {
await page.goto(location, { waitUntil: "load" });
await page.waitForSelector(`#${name.replace(".", "-")}`, { visible: true });
await page.waitForXPath(
`//h1[contains(., 'Nri.Ui.${name}') and @aria-current='page']`,
200
);
};
const defaultProcessing = async (name, location) => {
@ -73,11 +76,13 @@ describe("UI tests", function () {
const options = await select.$x(
`//label[contains(., '${labelName}')]//option`
);
for (const optionEl of options) {
const option = await page.evaluate((el) => el.innerText, optionEl);
await page.select("select", option);
callback(option);
}
// Actually doing the select was super flakey.
// Temporarily just using the first element to get
// CI consistent again. We can cover all the cases separately...
const optionEl = options[0];
const option = await page.evaluate((el) => el.innerText, optionEl);
await page.select("select", option);
await callback(option);
};
const messageProcessing = async (name, location) => {
@ -125,10 +130,8 @@ describe("UI tests", function () {
.analyze();
handleAxeResults(name, axe);
await forAllOptions("page", async (option) => {
await percySnapshot(page, `${name} - ${option}`, {
scope: "[data-page-container='']",
});
await percySnapshot(page, name, {
scope: "[data-page-container='']",
});
};

View File

@ -6,9 +6,10 @@ module Nri.Ui.ClickableSvg.V2 exposing
, exactSize, exactWidth, exactHeight
, disabled
, withBorder
, primary, secondary, danger, dangerSecondary
, primary, secondary, tertiary, danger, dangerSecondary
, custom, nriDescription, testId, id
, css, notMobileCss, mobileCss, quizEngineMobileCss
, iconForMobile
, small, medium, large
)
@ -18,6 +19,7 @@ module Nri.Ui.ClickableSvg.V2 exposing
# Patch changes:
- adds `nriDescription`, `testId`, and `id` helpers
- adds `iconForMobile`
# Create a button or link
@ -45,7 +47,7 @@ module Nri.Ui.ClickableSvg.V2 exposing
## Customization
@docs withBorder
@docs primary, secondary, danger, dangerSecondary
@docs primary, secondary, tertiary, danger, dangerSecondary
@docs custom, nriDescription, testId, id
@ -53,6 +55,7 @@ module Nri.Ui.ClickableSvg.V2 exposing
### CSS
@docs css, notMobileCss, mobileCss, quizEngineMobileCss
@docs iconForMobile
### DEPRECATED
@ -247,6 +250,7 @@ withBorder =
type Theme
= Primary
| Secondary
| Tertiary
| Danger
| DangerSecondary
@ -257,7 +261,9 @@ type alias AppliedTheme =
, background : Color
, backgroundHovered : Color
, includeBorder : Bool
, borderColor : Color
, borderBottom : Color
, borderHover : Color
}
@ -268,7 +274,9 @@ disabledTheme =
, background = Colors.white
, backgroundHovered = Colors.white
, includeBorder = True
, borderColor = Colors.gray75
, borderBottom = Colors.gray75
, borderHover = Colors.gray75
}
@ -281,7 +289,9 @@ applyTheme theme =
, background = Colors.azure
, backgroundHovered = Colors.azureDark
, includeBorder = False
, borderColor = Colors.white
, borderBottom = Colors.azureDark
, borderHover = Colors.azureDark
}
Secondary ->
@ -290,7 +300,20 @@ applyTheme theme =
, background = Colors.white
, backgroundHovered = Colors.glacier
, includeBorder = True
, borderColor = Colors.azure
, borderBottom = Colors.azure
, borderHover = Colors.azure
}
Tertiary ->
{ main_ = Colors.gray45
, mainHovered = Colors.azure
, background = Colors.gray96
, backgroundHovered = Colors.glacier
, includeBorder = True
, borderColor = Colors.gray92
, borderBottom = Colors.gray92
, borderHover = Colors.azure
}
Danger ->
@ -299,7 +322,9 @@ applyTheme theme =
, background = Colors.red
, backgroundHovered = Colors.redDark
, includeBorder = False
, borderColor = Colors.white
, borderBottom = Colors.redDark
, borderHover = Colors.redDark
}
DangerSecondary ->
@ -308,7 +333,9 @@ applyTheme theme =
, background = Colors.white
, backgroundHovered = Colors.redLight
, includeBorder = True
, borderColor = Colors.red
, borderBottom = Colors.red
, borderHover = Colors.red
}
@ -327,6 +354,13 @@ secondary =
set (\attributes -> { attributes | theme = Secondary })
{-| Used to de-emphasize elements when not hovered.
-}
tertiary : Attribute msg
tertiary =
set (\attributes -> { attributes | theme = Tertiary })
{-| White/transparent icon on a red background.
-}
danger : Attribute msg
@ -420,6 +454,12 @@ quizEngineMobileCss styles =
css [ Css.Media.withMedia [ MediaQuery.quizEngineMobile ] styles ]
{-| -}
iconForMobile : Svg -> Attribute msg
iconForMobile icon =
set (\config -> { config | iconForMobile = Just icon })
-- INTERNALS
@ -437,6 +477,7 @@ build label icon =
{ clickableAttributes = ClickableAttributes.init
, label = label
, icon = icon
, iconForMobile = Nothing
, disabled = False
, size = Small
, width = Nothing
@ -456,6 +497,7 @@ type alias ButtonOrLinkAttributes msg =
{ clickableAttributes : ClickableAttributes String msg
, label : String
, icon : Svg
, iconForMobile : Maybe Svg
, disabled : Bool
, size : Size
, width : Maybe Float
@ -487,8 +529,7 @@ renderButton ((ButtonOrLink config) as button_) =
++ ClickableAttributes.toButtonAttributes config.clickableAttributes
++ config.customAttributes
)
[ renderIcon config theme.includeBorder
]
(renderIcons config theme.includeBorder)
renderLink : ButtonOrLink msg -> Html msg
@ -522,12 +563,11 @@ renderLink ((ButtonOrLink config) as link_) =
)
++ config.customAttributes
)
[ renderIcon config theme.includeBorder
]
(renderIcons config theme.includeBorder)
renderIcon : ButtonOrLinkAttributes msg -> Bool -> Html msg
renderIcon config includeBorder =
renderIcons : ButtonOrLinkAttributes msg -> Bool -> List (Html msg)
renderIcons config includeBorder =
let
size =
getSize config.size
@ -556,20 +596,43 @@ renderIcon config includeBorder =
else
Maybe.withDefault size config.height
in
config.icon
|> Svg.withCss
iconStyles =
[ Css.displayFlex
, Css.maxWidth (Css.px iconWidth)
, Css.maxHeight (Css.px iconHeight)
, Css.height (Css.pct 100)
, Css.margin Css.auto
]
|> Svg.toHtml
hideFor breakpoint =
Svg.withCss
[ Css.Media.withMedia [ breakpoint ]
[ Css.display Css.none
]
]
in
case config.iconForMobile of
Just iconForMobile_ ->
[ config.icon
|> Svg.withCss iconStyles
|> hideFor MediaQuery.mobile
|> Svg.toHtml
, iconForMobile_
|> Svg.withCss iconStyles
|> hideFor MediaQuery.notMobile
|> Svg.toHtml
]
Nothing ->
[ config.icon
|> Svg.withCss iconStyles
|> Svg.toHtml
]
buttonOrLinkStyles : ButtonOrLinkAttributes msg -> AppliedTheme -> List Style
buttonOrLinkStyles config { main_, mainHovered, background, backgroundHovered, borderBottom, includeBorder } =
buttonOrLinkStyles config { main_, mainHovered, background, backgroundHovered, borderColor, borderBottom, borderHover, includeBorder } =
let
cursor =
if config.disabled then
@ -600,7 +663,7 @@ buttonOrLinkStyles config { main_, mainHovered, background, backgroundHovered, b
, Css.batch <|
if config.hasBorder then
[ Css.borderRadius (Css.px 8)
, Css.borderColor main_
, Css.borderColor borderColor
, Css.borderBottomColor borderBottom
, Css.borderStyle Css.solid
, if includeBorder then
@ -615,7 +678,7 @@ buttonOrLinkStyles config { main_, mainHovered, background, backgroundHovered, b
, Css.borderBottomWidth (Css.px bordersAndPadding.bottomBorder)
, Css.backgroundColor background
, Css.hover
[ Css.borderColor borderBottom
[ Css.borderColor borderHover
, Css.backgroundColor backgroundHovered
]
, Css.padding4

View File

@ -17,10 +17,10 @@ Changes from V1:
-}
import Css exposing (Color)
import Css.Media exposing (withMediaQuery)
import Html.Styled as Html
import Html.Styled.Attributes as Attributes exposing (css)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.MediaQuery.V1 as MediaQuery
import Particle exposing (Particle)
import Particle.System as ParticleSystem
import Random exposing (Generator)
@ -68,8 +68,7 @@ view (System system _) =
, Css.width (Css.pct 100)
, Css.height (Css.vh 100)
, Css.pointerEvents Css.none
, withMediaQuery [ "(prefers-reduced-motion)" ]
[ Css.display Css.none ]
, MediaQuery.prefersReducedMotion [ Css.display Css.none ]
]
]
)

266
src/Nri/Ui/Heading/V3.elm Normal file
View File

@ -0,0 +1,266 @@
module Nri.Ui.Heading.V3 exposing
( h1, h2, h3, h4, h5
, plaintext, markdown, html
, Attribute
, top, subhead, small
, custom, css, nriDescription, testId, id
)
{-|
# Changes from V2:
- changes default h2 style to subhead
- remove `customAttr`
- remove `error` and `errorIf`
- replaces `style` with `top`, `subhead`, and `small`
- replaces list of HTML attributes with content approach (`plaintext`, `markdown`, `html`) used in Text
Headings with customization options.
@docs h1, h2, h3, h4, h5
# Content
@docs plaintext, markdown, html
## Customizations
@docs Attribute
@docs top, subhead, small
@docs custom, css, nriDescription, testId, id
-}
import Css exposing (..)
import Html.Styled exposing (..)
import Html.Styled.Attributes as Attributes
import Markdown
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Html.Attributes.V2 as ExtraAttributes
{-| Make a first-level heading (styled like a top-level heading by default.)
-}
h1 : List (Attribute msg) -> Html msg
h1 attributes =
view Html.Styled.h1 (top :: attributes)
{-| Make a second-level heading (styled like a tagline by default.)
-}
h2 : List (Attribute msg) -> Html msg
h2 attributes =
view Html.Styled.h2 (subhead :: attributes)
{-| Make a third-level heading (styled like a subhead by default.)
-}
h3 : List (Attribute msg) -> Html msg
h3 attributes =
view Html.Styled.h3 (small :: attributes)
{-| Make a fourth-level heading (styled like a small heading by default.)
-}
h4 : List (Attribute msg) -> Html msg
h4 attributes =
view Html.Styled.h4 (small :: attributes)
{-| Make a fifth-level heading (styled like a small heading by default.)
-}
h5 : List (Attribute msg) -> Html msg
h5 attributes =
view Html.Styled.h5 (small :: attributes)
view :
(List (Html.Styled.Attribute msg) -> List (Html msg) -> Html msg)
-> List (Attribute msg)
-> Html msg
view tag attrs =
let
final =
List.foldl (\(Attribute f) acc -> f acc) emptyCustomizations attrs
in
tag (Attributes.css final.css :: final.attributes) final.content
{-| Provide a plain-text string.
-}
plaintext : String -> Attribute msg
plaintext content =
Attribute <| \config -> { config | content = [ text content ] }
{-| Provide a string that will be rendered as markdown.
-}
markdown : String -> Attribute msg
markdown content =
Attribute <|
\config ->
{ config
| content =
Markdown.toHtml Nothing content
|> List.map fromUnstyled
}
{-| Provide a list of custom HTML.
-}
html : List (Html msg) -> Attribute msg
html content =
Attribute <| \config -> { config | content = content }
{-| Like an `Html.Attribute msg`, but specifically for headings. Use things
like `style` in this module to construct an Attribute.
-}
type Attribute msg
= Attribute (Customizations msg -> Customizations msg)
{-| Set some custom CSS in this heading. For example, maybe you need to tweak
margins.
-}
css : List Css.Style -> Attribute msg
css css_ =
Attribute
(\customizations ->
{ customizations | css = customizations.css ++ css_ }
)
{-| Set some custom attributes.
Please don't make headers interactive! Use buttons or links instead so that keyboard and screen
reader users can use the site too.
For style customizations, be sure to use the Heading.css helper.
-}
custom : List (Html.Styled.Attribute msg) -> Attribute msg
custom attributes =
Attribute
(\customizations ->
{ customizations | attributes = customizations.attributes ++ attributes }
)
{-| -}
nriDescription : String -> Attribute msg
nriDescription description =
custom [ ExtraAttributes.nriDescription description ]
{-| -}
testId : String -> Attribute msg
testId id_ =
custom [ ExtraAttributes.testId id_ ]
{-| -}
id : String -> Attribute msg
id id_ =
custom [ Attributes.id id_ ]
emptyCustomizations : Customizations msg
emptyCustomizations =
{ content = []
, css = []
, attributes = []
}
type alias Customizations msg =
{ content : List (Html msg)
, css : List Css.Style
, attributes : List (Html.Styled.Attribute msg)
}
-- Style
{-| `top` headings are Colors.navy and have:
font-size: 30px
line-height: 38px
font-weight: 700
By default.
-}
top : Attribute msg
top =
(css << headingStyles)
{ color = Colors.navy
, size = 30
, lineHeight = 38
}
{-| `subhead` headings are Colors.navy and have:
font-size: 20px
line-height: 26px
font-weight: 700
By default.
-}
subhead : Attribute msg
subhead =
(css << headingStyles)
{ color = Colors.navy
, size = 20
, lineHeight = 26
}
{-| `small` headings are Colors.gray20 and have:
font-size: 16px
line-height: 21px
font-weight: 700
By default.
`small` heading default styles also make the [letter-spacing](https://developer.mozilla.org/en-US/docs/Web/CSS/letter-spacing) slightly narrower, by 0.13px.
-}
small : Attribute msg
small =
css
(letterSpacing (px -0.13)
:: headingStyles
{ color = Colors.gray20
, size = 16
, lineHeight = 21
}
)
headingStyles :
{ color : Color
, lineHeight : Float
, size : Float
}
-> List Css.Style
headingStyles config =
[ Fonts.baseFont
, fontSize (px config.size)
, color config.color
, lineHeight (px config.lineHeight)
, fontWeight (int 700)
, padding zero
, textAlign left
, margin zero
]

View File

@ -1,5 +1,5 @@
module Nri.Ui.Logo.V1 exposing
( noredink
( noredink, noredinkMonochrome
, clever, cleverC, cleverLibrary
, googleClassroom, googleG
, canvas
@ -11,7 +11,7 @@ module Nri.Ui.Logo.V1 exposing
{-|
@docs noredink
@docs noredink, noredinkMonochrome
@docs clever, cleverC, cleverLibrary
@docs googleClassroom, googleG
@docs canvas
@ -40,23 +40,48 @@ noredink =
]
[ Svg.path
[ 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"
, Attributes.d noD
]
[]
, Svg.path
[ Attributes.fill "#333"
, Attributes.d "M32.246 6.257h1.95v2.698h.065c.748-1.918 2.34-3.088 4.356-3.088.227 0 .455.033.682.098v1.95a4.878 4.878 0 0 0-.942-.097c-2.145 0-4.16 1.56-4.16 4.907v10.791h-1.95V6.257zM49.994 13.342c-.065-4.29-1.268-5.85-3.673-5.85-2.405 0-3.608 1.56-3.673 5.85h7.346zm1.918 4.454c-.293 3.672-2.308 6.11-5.558 6.11-3.64 0-5.786-2.535-5.786-9.035 0-5.981 2.145-9.004 5.948-9.004 3.836 0 5.558 2.633 5.558 8.386v.715h-9.426v.813c0 4.972 1.755 6.5 3.673 6.5 2.048 0 3.315-1.463 3.64-4.485h1.95zM60.266 22.28c1.983 0 3.77-1.007 3.77-7.41 0-6.37-1.787-7.378-3.77-7.378-1.95 0-3.77 1.008-3.77 7.379 0 6.402 1.82 7.41 3.77 7.41zm3.965-1.624h-.065c-.52 1.983-2.177 3.25-4.225 3.25-3.802 0-5.525-3.055-5.525-9.035 0-5.948 1.723-9.004 5.525-9.004 2.145 0 3.608 1.17 4.03 2.99h.065V.31h1.95v23.206h-1.755v-2.86z"
, Attributes.d redD
]
[]
, Svg.path
[ 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"
, Attributes.d inkD
]
[]
]
]
{-| -}
noredinkMonochrome : Nri.Ui.Svg.V1.Svg
noredinkMonochrome =
Nri.Ui.Svg.V1.init "0 0 109 24"
[ Svg.path [ Attributes.d noD ] []
, Svg.path [ Attributes.d redD ] []
, Svg.path [ Attributes.d inkD ] []
]
noD : String
noD =
"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"
redD : String
redD =
"M32.246 6.257h1.95v2.698h.065c.748-1.918 2.34-3.088 4.356-3.088.227 0 .455.033.682.098v1.95a4.878 4.878 0 0 0-.942-.097c-2.145 0-4.16 1.56-4.16 4.907v10.791h-1.95V6.257zM49.994 13.342c-.065-4.29-1.268-5.85-3.673-5.85-2.405 0-3.608 1.56-3.673 5.85h7.346zm1.918 4.454c-.293 3.672-2.308 6.11-5.558 6.11-3.64 0-5.786-2.535-5.786-9.035 0-5.981 2.145-9.004 5.948-9.004 3.836 0 5.558 2.633 5.558 8.386v.715h-9.426v.813c0 4.972 1.755 6.5 3.673 6.5 2.048 0 3.315-1.463 3.64-4.485h1.95zM60.266 22.28c1.983 0 3.77-1.007 3.77-7.41 0-6.37-1.787-7.378-3.77-7.378-1.95 0-3.77 1.008-3.77 7.379 0 6.402 1.82 7.41 3.77 7.41zm3.965-1.624h-.065c-.52 1.983-2.177 3.25-4.225 3.25-3.802 0-5.525-3.055-5.525-9.035 0-5.948 1.723-9.004 5.525-9.004 2.145 0 3.608 1.17 4.03 2.99h.065V.31h1.95v23.206h-1.755v-2.86z"
inkD : String
inkD =
"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"
{-| -}
facebook : Nri.Ui.Svg.V1.Svg
facebook =

View File

@ -1,5 +1,6 @@
module Nri.Ui.MediaQuery.V1 exposing
( mobile, notMobile
( anyMotion, prefersReducedMotion
, mobile, notMobile
, mobileBreakpoint
, quizEngineMobile
, quizEngineBreakpoint
@ -20,6 +21,8 @@ module Nri.Ui.MediaQuery.V1 exposing
[ Css.padding (Css.px 2)
]
@docs anyMotion, prefersReducedMotion
@docs mobile, notMobile
@docs mobileBreakpoint
@ -31,8 +34,20 @@ module Nri.Ui.MediaQuery.V1 exposing
-}
import Css exposing (px)
import Css.Media exposing (MediaQuery, maxWidth, minWidth, only, screen)
import Css exposing (Style, px)
import Css.Media exposing (MediaQuery, maxWidth, minWidth, only, screen, withMediaQuery)
{-| -}
anyMotion : List Style -> Style
anyMotion =
withMediaQuery [ "(prefers-reduced-motion: no-preference)" ]
{-| -}
prefersReducedMotion : List Style -> Style
prefersReducedMotion =
withMediaQuery [ "(prefers-reduced-motion)" ]
{-| Styles using the `mobileBreakpoint` value as the maxWidth.

View File

@ -18,8 +18,9 @@ import Html.Styled.Attributes as Attributes
import Http
import Nri.Ui.Button.V10 as Button
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Html.V3 exposing (viewIf)
import Nri.Ui.Text.V6 as Text
{-| The default page information is for the button
@ -202,8 +203,15 @@ view : Config msg -> Html msg
view config =
viewContainer
[ viewEmoji [ Html.text config.emoji ]
, Heading.h1 [] [ Html.text config.title ]
, Heading.h2 [] [ Html.text config.subtitle ]
, Heading.h1 [ Heading.plaintext config.title ]
, Text.mediumBody
[ Text.plaintext config.subtitle
, Text.css
[ Css.fontSize (Css.px 20)
, Css.color Colors.gray45
, Css.marginBottom Css.zero
]
]
, viewButton
[ viewExit config ]
, viewIf

674
src/Nri/Ui/SideNav/V4.elm Normal file
View File

@ -0,0 +1,674 @@
module Nri.Ui.SideNav.V4 exposing
( view, Config, NavAttribute
, collapsible
, navLabel, navId
, navCss, navNotMobileCss, navMobileCss, navQuizEngineMobileCss
, entry, entryWithChildren, html, Entry, Attribute
, icon, custom, css, nriDescription, testId, id
, onClick
, href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
, primary, secondary
, premiumDisplay
)
{-|
# Changes from V3
- make the nav configurably collapsible
@docs view, Config, NavAttribute
@docs collapsible
@docs navLabel, navId
@docs navCss, navNotMobileCss, navMobileCss, navQuizEngineMobileCss
## Entries
@docs entry, entryWithChildren, html, Entry, Attribute
@docs icon, custom, css, nriDescription, testId, id
## Behavior
@docs onClick
@docs href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
## Change the color scheme
@docs primary, secondary
## Change the state
@docs premiumDisplay
-}
import Accessibility.Styled exposing (..)
import Accessibility.Styled.Aria as Aria
import Accessibility.Styled.Style as Style
import ClickableAttributes exposing (ClickableAttributes)
import Css exposing (..)
import Css.Media
import Html.Styled
import Html.Styled.Attributes as Attributes
import Html.Styled.Events as Events
import Nri.Ui
import Nri.Ui.ClickableSvg.V2 as ClickableSvg
import Nri.Ui.ClickableText.V3 as ClickableText
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Data.PremiumDisplay as PremiumDisplay exposing (PremiumDisplay)
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Html.Attributes.V2 as ExtraAttributes
import Nri.Ui.Html.V3 exposing (viewJust)
import Nri.Ui.MediaQuery.V1 as MediaQuery
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Nri.Ui.Tooltip.V3 as Tooltip
import Nri.Ui.UiIcon.V1 as UiIcon
{-| Use `entry` to create a sidebar entry.
-}
type Entry route msg
= Entry (List (Entry route msg)) (EntryConfig route msg)
| Html (List (Html msg))
{-| -}
entry : String -> List (Attribute route msg) -> Entry route msg
entry title attributes =
attributes
|> List.foldl (\(Attribute attribute) b -> attribute b) (build title)
|> Entry []
{-| -}
entryWithChildren : String -> List (Attribute route msg) -> List (Entry route msg) -> Entry route msg
entryWithChildren title attributes children =
attributes
|> List.foldl (\(Attribute attribute) b -> attribute b) (build title)
|> Entry children
{-| -}
html : List (Html msg) -> Entry route msg
html =
Html
{-| -}
type alias Config route msg =
{ isCurrentRoute : route -> Bool
, routeToString : route -> String
, onSkipNav : msg
}
{-| -}
type NavAttribute msg
= NavAttribute (NavAttributeConfig msg -> NavAttributeConfig msg)
type alias NavAttributeConfig msg =
{ navLabel : Maybe String
, navId : Maybe String
, css : List Style
, collapsible : Maybe (CollapsibleConfig msg)
}
defaultNavAttributeConfig : NavAttributeConfig msg
defaultNavAttributeConfig =
{ navLabel = Nothing
, navId = Nothing
, css = []
, collapsible = Nothing
}
{-| Give screenreader users context on what this particular sidenav is for.
If the nav is collapsible, this value will also be used for the sidenav tooltips.
-}
navLabel : String -> NavAttribute msg
navLabel str =
NavAttribute (\config -> { config | navLabel = Just str })
{-| -}
navId : String -> NavAttribute msg
navId str =
NavAttribute (\config -> { config | navId = Just str })
{-| These styles are included automatically in the nav container:
[ flexBasis (px 250)
, flexShrink (num 0)
, borderRadius (px 8)
, backgroundColor Colors.gray96
, padding (px 20)
, marginRight (px 20)
]
-}
navCss : List Style -> NavAttribute msg
navCss styles =
NavAttribute (\config -> { config | css = List.append config.css styles })
{-| -}
navNotMobileCss : List Style -> NavAttribute msg
navNotMobileCss styles =
navCss [ Css.Media.withMedia [ MediaQuery.notMobile ] styles ]
{-| -}
navMobileCss : List Style -> NavAttribute msg
navMobileCss styles =
navCss [ Css.Media.withMedia [ MediaQuery.mobile ] styles ]
{-| -}
navQuizEngineMobileCss : List Style -> NavAttribute msg
navQuizEngineMobileCss styles =
navCss [ Css.Media.withMedia [ MediaQuery.quizEngineMobile ] styles ]
{-| -}
type alias CollapsibleConfig msg =
{ isOpen : Bool
, toggle : Bool -> msg
, isTooltipOpen : Bool
, toggleTooltip : Bool -> msg
}
{-| -}
collapsible : CollapsibleConfig msg -> NavAttribute msg
collapsible collapsible_ =
NavAttribute (\config -> { config | collapsible = Just collapsible_ })
{-| -}
view : Config route msg -> List (NavAttribute msg) -> List (Entry route msg) -> Html msg
view config navAttributes entries =
let
appliedNavAttributes =
List.foldl (\(NavAttribute f) b -> f b) defaultNavAttributeConfig navAttributes
showNav =
Maybe.map .isOpen appliedNavAttributes.collapsible
|> Maybe.withDefault True
sidenavId =
Maybe.withDefault defaultSideNavId appliedNavAttributes.navId
defaultCss =
[ if showNav then
case appliedNavAttributes.collapsible of
Just _ ->
Css.batch
[ Css.flexBasis (Css.px 245)
, Css.padding4 (Css.px 25) (Css.px 25) (Css.px 20) (Css.px 20)
]
Nothing ->
Css.batch
[ Css.flexBasis (Css.px 250)
, Css.padding (Css.px 20)
]
else
Css.flexBasis (Css.px 5)
, flexShrink (num 0)
, marginRight (px 20)
, position relative
, borderRadius (px 8)
, backgroundColor Colors.gray96
]
in
div [ Attributes.css (defaultCss ++ appliedNavAttributes.css) ]
[ viewSkipLink config.onSkipNav
, viewJust (viewOpenCloseButton sidenavId appliedNavAttributes.navLabel) appliedNavAttributes.collapsible
, viewNav sidenavId config appliedNavAttributes entries showNav
]
defaultSideNavId : String
defaultSideNavId =
"sidenav"
viewOpenCloseButton : String -> Maybe String -> CollapsibleConfig msg -> Html msg
viewOpenCloseButton sidenavId navLabel_ { isOpen, toggle, isTooltipOpen, toggleTooltip } =
let
name =
Maybe.withDefault "sidebar" navLabel_
( action, icon_, attributes ) =
if isOpen then
( "Close " ++ name
, UiIcon.openClose
, [ ClickableSvg.css [ Css.padding (Css.px 5) ]
, ClickableSvg.iconForMobile UiIcon.x
]
)
else
( "Open " ++ name
, UiIcon.openClose
|> Svg.withCss [ Css.transform (rotate (deg 180)) ]
, [ ClickableSvg.withBorder
, ClickableSvg.iconForMobile UiIcon.hamburger
]
)
trigger tooltipAttributes =
ClickableSvg.button action
icon_
([ ClickableSvg.custom
[ Aria.controls [ sidenavId ]
, Aria.expanded isOpen
]
, ClickableSvg.custom tooltipAttributes
, ClickableSvg.onClick (toggle (not isOpen))
, ClickableSvg.tertiary
]
++ attributes
)
in
Tooltip.view
{ trigger = trigger
, id = "open-close-sidebar-tooltip"
}
[ Tooltip.open isTooltipOpen
, Tooltip.onToggle toggleTooltip
, Tooltip.plaintext action
, Tooltip.smallPadding
, Tooltip.fitToContent
, if isOpen then
Tooltip.onLeft
else
Tooltip.onRight
, Tooltip.onRightForMobile
, Tooltip.containerCss
(if isOpen then
[ Css.Media.withMedia [ MediaQuery.notMobile ]
[ Css.position Css.absolute
, Css.top Css.zero
, Css.right Css.zero
]
]
else
[]
)
]
viewNav : String -> Config route msg -> NavAttributeConfig msg -> List (Entry route msg) -> Bool -> Html msg
viewNav sidenavId config appliedNavAttributes entries showNav =
nav
([ Maybe.map Aria.label appliedNavAttributes.navLabel
, Just (Attributes.id sidenavId)
, if showNav then
Nothing
else
Just (Attributes.css [ Css.display Css.none ])
]
|> List.filterMap identity
)
(List.map (viewSidebarEntry config []) entries)
viewSkipLink : msg -> Html msg
viewSkipLink onSkip =
ClickableText.button "Skip to main content"
[ ClickableText.icon UiIcon.arrowPointingRight
, ClickableText.small
, ClickableText.css
[ Css.pseudoClass "not(:focus)"
[ Style.invisibleStyle
]
]
, ClickableText.onClick onSkip
]
viewSidebarEntry : Config route msg -> List Css.Style -> Entry route msg -> Html msg
viewSidebarEntry config extraStyles entry_ =
case entry_ of
Entry children entryConfig ->
if entryConfig.premiumDisplay == PremiumDisplay.PremiumLocked then
viewLockedEntry extraStyles entryConfig
else if anyLinkDescendants (isCurrentRoute config) children then
div [ Attributes.css extraStyles ]
(styled span
(sharedEntryStyles
++ [ backgroundColor Colors.gray92
, color Colors.navy
, fontWeight bold
, cursor default
, marginBottom (px 10)
]
)
[]
[ text entryConfig.title ]
:: List.map (viewSidebarEntry config [ marginLeft (px 20) ]) children
)
else
viewSidebarLeaf config extraStyles entryConfig
Html html_ ->
div [ Attributes.css extraStyles ] html_
isCurrentRoute : Config route msg -> EntryConfig route msg -> Bool
isCurrentRoute config { route } =
Maybe.map config.isCurrentRoute route
|> Maybe.withDefault False
anyLinkDescendants : (EntryConfig route msg -> Bool) -> List (Entry route msg) -> Bool
anyLinkDescendants f children =
List.any
(\entry_ ->
case entry_ of
Entry children_ entryConfig ->
f entryConfig || anyLinkDescendants f children_
Html _ ->
False
)
children
viewSidebarLeaf :
Config route msg
-> List Style
-> EntryConfig route msg
-> Html msg
viewSidebarLeaf config extraStyles entryConfig =
let
( linkFunctionName, attributes ) =
ClickableAttributes.toLinkAttributes
{ routeToString = config.routeToString
, isDisabled = False
}
entryConfig.clickableAttributes
in
Nri.Ui.styled Html.Styled.a
("Nri-Ui-SideNav-" ++ linkFunctionName)
(sharedEntryStyles
++ extraStyles
++ (if isCurrentRoute config entryConfig then
[ backgroundColor Colors.glacier
, color Colors.navy
, fontWeight bold
, visited [ color Colors.navy ]
]
else
[]
)
++ entryConfig.customStyles
)
(attributes ++ entryConfig.customAttributes)
[ viewJust
(\icon_ ->
icon_
|> Svg.withWidth (px 20)
|> Svg.withHeight (px 20)
|> Svg.withCss [ marginRight (px 5) ]
|> Svg.toHtml
)
entryConfig.icon
, text entryConfig.title
]
viewLockedEntry : List Style -> EntryConfig route msg -> Html msg
viewLockedEntry extraStyles entryConfig =
styled Html.Styled.button
[ batch sharedEntryStyles
, important (color Colors.gray45)
, borderWidth zero
, batch extraStyles
]
(case entryConfig.onLockedContent of
Just event ->
Events.onClick event :: entryConfig.customAttributes
Nothing ->
entryConfig.customAttributes
)
[ UiIcon.premiumLock
|> Svg.withWidth (px 17)
|> Svg.withHeight (px 25)
|> Svg.withCss [ marginRight (px 10), minWidth (px 17) ]
|> Svg.toHtml
, text entryConfig.title
]
sharedEntryStyles : List Style
sharedEntryStyles =
[ padding2 (px 13) (px 20)
, Css.property "word-break" "normal"
, Css.property "overflow-wrap" "anywhere"
, displayFlex
, borderRadius (px 8)
, alignItems center
, Fonts.baseFont
, color Colors.navy
, backgroundColor transparent
, textDecoration none
, fontSize (px 15)
, fontWeight (int 600)
, textAlign left
, cursor pointer
]
-- Entry Customization helpers
{-| -}
type alias EntryConfig route msg =
{ icon : Maybe Svg
, title : String
, route : Maybe route
, clickableAttributes : ClickableAttributes route msg
, customAttributes : List (Html.Styled.Attribute msg)
, customStyles : List Style
, premiumDisplay : PremiumDisplay
, onLockedContent : Maybe msg
}
build : String -> EntryConfig route msg
build title =
{ icon = Nothing
, title = title
, route = Nothing
, clickableAttributes = ClickableAttributes.init
, customAttributes = []
, customStyles = []
, premiumDisplay = PremiumDisplay.Free
, onLockedContent = Nothing
}
{-| -}
type Attribute route msg
= Attribute (EntryConfig route msg -> EntryConfig route msg)
{-| -}
icon : Svg -> Attribute route msg
icon icon_ =
Attribute (\attributes -> { attributes | icon = Just icon_ })
{-| -}
premiumDisplay : PremiumDisplay -> msg -> Attribute route msg
premiumDisplay display ifLocked =
Attribute
(\attributes ->
{ attributes
| premiumDisplay = display
, onLockedContent = Just ifLocked
}
)
{-| Use this helper to add custom attributes.
Do NOT use this helper to add css styles, as they may not be applied the way
you want/expect if underlying Button styles change.
Instead, please use the `css` helper.
-}
custom : List (Html.Styled.Attribute msg) -> Attribute route msg
custom attributes =
Attribute
(\config ->
{ config
| customAttributes = List.append config.customAttributes attributes
}
)
{-| -}
nriDescription : String -> Attribute route msg
nriDescription description =
custom [ ExtraAttributes.nriDescription description ]
{-| -}
testId : String -> Attribute route msg
testId id_ =
custom [ ExtraAttributes.testId id_ ]
{-| -}
id : String -> Attribute route msg
id id_ =
custom [ Attributes.id id_ ]
{-| -}
css : List Style -> Attribute route msg
css styles =
Attribute
(\config ->
{ config
| customStyles = List.append config.customStyles styles
}
)
{-| -}
primary : Attribute route msg
primary =
Attribute (\attributes -> { attributes | customStyles = [] })
{-| -}
secondary : Attribute route msg
secondary =
Attribute
(\attributes ->
{ attributes
| customStyles =
[ backgroundColor Colors.white
, boxShadow3 zero (px 2) Colors.gray75
, border3 (px 1) solid Colors.gray75
]
}
)
-- LINKING, CLICKING, and TRACKING BEHAVIOR
setClickableAttributes :
Maybe route
-> (ClickableAttributes route msg -> ClickableAttributes route msg)
-> Attribute route msg
setClickableAttributes route apply =
Attribute
(\attributes ->
{ attributes
| route =
case route of
Just r ->
Just r
Nothing ->
attributes.route
, clickableAttributes = apply attributes.clickableAttributes
}
)
{-| -}
onClick : msg -> Attribute route msg
onClick msg =
setClickableAttributes Nothing (ClickableAttributes.onClick msg)
{-| -}
href : route -> Attribute route msg
href route =
setClickableAttributes (Just route) (ClickableAttributes.href route)
{-| Use this link for routing within a single page app.
This will make a normal <a> tag, but change the Events.onClick behavior to avoid reloading the page.
See <https://github.com/elm-lang/html/issues/110> for details on this implementation.
-}
linkSpa : route -> Attribute route msg
linkSpa route =
setClickableAttributes (Just route)
(ClickableAttributes.linkSpa route)
{-| -}
linkWithMethod : { method : String, url : route } -> Attribute route msg
linkWithMethod config =
setClickableAttributes (Just config.url)
(ClickableAttributes.linkWithMethod config)
{-| -}
linkWithTracking : { track : msg, url : route } -> Attribute route msg
linkWithTracking config =
setClickableAttributes (Just config.url)
(ClickableAttributes.linkWithTracking config)
{-| -}
linkExternal : String -> Attribute route msg
linkExternal url =
setClickableAttributes Nothing (ClickableAttributes.linkExternal url)
{-| -}
linkExternalWithTracking : { track : msg, url : String } -> Attribute route msg
linkExternalWithTracking config =
setClickableAttributes Nothing (ClickableAttributes.linkExternalWithTracking config)

View File

@ -24,7 +24,7 @@ import Html.Styled.Events
import Nri.Ui.Colors.Extra exposing (toCssString)
import Nri.Ui.Colors.V1
import Nri.Ui.CssVendorPrefix.V1 as CssVendorPrefix
import Nri.Ui.Table.V5
import Nri.Ui.Table.V6
import Svg.Styled as Svg
import Svg.Styled.Attributes as SvgAttributes
@ -187,7 +187,7 @@ viewLoading config state =
tableColumns =
List.map (buildTableColumn config.updateMsg state) config.columns
in
Nri.Ui.Table.V5.viewLoading
Nri.Ui.Table.V6.viewLoading
tableColumns
@ -201,7 +201,7 @@ view config state entries =
sorter =
findSorter config.columns state.column
in
Nri.Ui.Table.V5.view
Nri.Ui.Table.V6.view
tableColumns
(List.sortWith (sorter state.sortDirection) entries)
@ -236,13 +236,14 @@ identitySorter =
EQ
buildTableColumn : (State id -> msg) -> State id -> Column id entry msg -> Nri.Ui.Table.V5.Column entry msg
buildTableColumn : (State id -> msg) -> State id -> Column id entry msg -> Nri.Ui.Table.V6.Column entry msg
buildTableColumn updateMsg state (Column column) =
Nri.Ui.Table.V5.custom
Nri.Ui.Table.V6.custom
{ header = viewSortHeader column.header updateMsg state column.id
, view = column.view
, width = Css.px (toFloat column.width)
, cellStyles = column.cellStyles
, sort = Nothing -- use SortableTable.V3 for better accessibility!
}

View File

@ -32,15 +32,10 @@ import Nri.Ui.Colors.V1
import Nri.Ui.CssVendorPrefix.V1 as CssVendorPrefix
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Svg.V1
import Nri.Ui.Table.V5
import Nri.Ui.Table.V6 as Table exposing (SortDirection(..))
import Nri.Ui.UiIcon.V1
type SortDirection
= Ascending
| Descending
{-| -}
type alias Sorter a =
SortDirection -> a -> a -> Order
@ -194,7 +189,7 @@ viewLoading config state =
tableColumns =
List.map (buildTableColumn config.updateMsg state) config.columns
in
Nri.Ui.Table.V5.viewLoading
Table.viewLoading
tableColumns
@ -208,7 +203,7 @@ view config state entries =
sorter =
findSorter config.columns state.column
in
Nri.Ui.Table.V5.view
Table.view
tableColumns
(List.sortWith (sorter state.sortDirection) entries)
@ -243,13 +238,19 @@ identitySorter =
EQ
buildTableColumn : (State id -> msg) -> State id -> Column id entry msg -> Nri.Ui.Table.V5.Column entry msg
buildTableColumn : (State id -> msg) -> State id -> Column id entry msg -> Table.Column entry msg
buildTableColumn updateMsg state (Column column) =
Nri.Ui.Table.V5.custom
Table.custom
{ header = viewSortHeader (column.sorter /= Nothing) column.header updateMsg state column.id
, view = column.view
, width = Css.px (toFloat column.width)
, cellStyles = column.cellStyles
, sort =
if state.column == column.id then
Just state.sortDirection
else
Nothing
}

View File

@ -36,13 +36,13 @@ import Accessibility.Styled as Html exposing (Html)
import Accessibility.Styled.Aria as Aria
import Css exposing (Color, Style)
import Css.Global as Global
import Css.Media
import Html.Styled.Attributes as Attributes
import Html.Styled.Events as Events
import Nri.Ui.Colors.Extra exposing (toCssString)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Html.Attributes.V2 as Extra
import Nri.Ui.MediaQuery.V1 as MediaQuery
import Nri.Ui.Svg.V1 exposing (Svg)
import Svg.Styled as Svg
import Svg.Styled.Attributes as SvgAttributes
@ -373,6 +373,4 @@ stroke color =
transition : String -> Css.Style
transition transitionRules =
Css.Media.withMediaQuery
[ "(prefers-reduced-motion: no-preference)" ]
[ Css.property "transition" transitionRules ]
MediaQuery.anyMotion [ Css.property "transition" transitionRules ]

298
src/Nri/Ui/Table/V6.elm Normal file
View File

@ -0,0 +1,298 @@
module Nri.Ui.Table.V6 exposing
( Column, SortDirection(..), custom, string
, view, viewWithoutHeader
, viewLoading, viewLoadingWithoutHeader
)
{-| Upgrading from V5:
- The columns take an additional `sort` property that allows
you to specify ARIA sorting
@docs Column, SortDirection, custom, string
@docs view, viewWithoutHeader
@docs viewLoading, viewLoadingWithoutHeader
-}
import Accessibility.Styled.Style as Style
import Css exposing (..)
import Css.Animations
import Html.Styled as Html exposing (..)
import Html.Styled.Attributes as Attributes exposing (css)
import Nri.Ui.Colors.V1 exposing (..)
import Nri.Ui.Fonts.V1 exposing (baseFont)
{-| Closed representation of how to render the header and cells of a column
in the table
-}
type Column data msg
= Column (Html msg) (data -> Html msg) Style (data -> List Style) (Maybe SortDirection)
{-| Which direction is a table column sorted? Only set these on columns that
actually have an explicit sort!
-}
type SortDirection
= Ascending
| Descending
{-| A column that renders some aspect of a value as text
-}
string :
{ header : String
, value : data -> String
, width : LengthOrAuto compatible
, cellStyles : data -> List Style
, sort : Maybe SortDirection
}
-> Column data msg
string { header, value, width, cellStyles, sort } =
Column (Html.text header) (value >> Html.text) (Css.width width) cellStyles sort
{-| A column that renders however you want it to
-}
custom :
{ header : Html msg
, view : data -> Html msg
, width : LengthOrAuto compatible
, cellStyles : data -> List Style
, sort : Maybe SortDirection
}
-> Column data msg
custom options =
Column options.header options.view (Css.width options.width) options.cellStyles options.sort
-- VIEW
{-| Displays a table of data without a header row
-}
viewWithoutHeader : List (Column data msg) -> List data -> Html msg
viewWithoutHeader columns =
tableWithoutHeader [] columns (viewRow columns)
{-| Displays a table of data based on the provided column definitions
-}
view : List (Column data msg) -> List data -> Html msg
view columns =
tableWithHeader [] columns (viewRow columns)
viewRow : List (Column data msg) -> data -> Html msg
viewRow columns data =
tr
[ css rowStyles ]
(List.map (viewColumn data) columns)
viewColumn : data -> Column data msg -> Html msg
viewColumn data (Column _ renderer width cellStyles _) =
td
[ css ([ width, verticalAlign middle ] ++ cellStyles data)
]
[ renderer data ]
-- VIEW LOADING
{-| Display a table with the given columns but instead of data, show blocked
out text with an interesting animation. This view lets the user know that
data is on its way and what it will look like when it arrives.
-}
viewLoading : List (Column data msg) -> Html msg
viewLoading columns =
tableWithHeader loadingTableStyles columns (viewLoadingRow columns) (List.range 0 8)
{-| Display the loading table without a header row
-}
viewLoadingWithoutHeader : List (Column data msg) -> Html msg
viewLoadingWithoutHeader columns =
tableWithoutHeader loadingTableStyles columns (viewLoadingRow columns) (List.range 0 8)
viewLoadingRow : List (Column data msg) -> Int -> Html msg
viewLoadingRow columns index =
tr
[ css rowStyles ]
(List.indexedMap (viewLoadingColumn index) columns)
viewLoadingColumn : Int -> Int -> Column data msg -> Html msg
viewLoadingColumn rowIndex colIndex (Column _ _ width _ _) =
td
[ css (stylesLoadingColumn rowIndex colIndex width ++ [ verticalAlign middle ] ++ loadingCellStyles)
]
[ span [ css loadingContentStyles ] [] ]
stylesLoadingColumn : Int -> Int -> Style -> List Style
stylesLoadingColumn rowIndex colIndex width =
[ width
, property "animation-delay" (String.fromFloat (toFloat (rowIndex + colIndex) * 0.1) ++ "s")
]
-- HELP
tableWithoutHeader : List Style -> List (Column data msg) -> (a -> Html msg) -> List a -> Html msg
tableWithoutHeader styles columns toRow data =
table styles
[ thead [] [ tr Style.invisible (List.map tableRowHeader columns) ]
, tableBody toRow data
]
tableWithHeader : List Style -> List (Column data msg) -> (a -> Html msg) -> List a -> Html msg
tableWithHeader styles columns toRow data =
table styles
[ tableHeader columns
, tableBody toRow data
]
table : List Style -> List (Html msg) -> Html msg
table styles =
Html.table [ css (styles ++ tableStyles) ]
tableHeader : List (Column data msg) -> Html msg
tableHeader columns =
thead []
[ tr [ css headersStyles ]
(List.map tableRowHeader columns)
]
tableRowHeader : Column data msg -> Html msg
tableRowHeader (Column header _ width _ sort) =
th
[ Attributes.scope "col"
, css (width :: headerStyles)
, Attributes.attribute "aria-sort" <|
case sort of
Nothing ->
"none"
Just Ascending ->
"ascending"
Just Descending ->
"descending"
]
[ header ]
tableBody : (a -> Html msg) -> List a -> Html msg
tableBody toRow items =
tbody [] (List.map toRow items)
-- STYLES
headersStyles : List Style
headersStyles =
[ borderBottom3 (px 3) solid gray75
, height (px 45)
, fontSize (px 15)
]
headerStyles : List Style
headerStyles =
[ padding4 (px 15) (px 12) (px 11) (px 12)
, textAlign left
, fontWeight bold
]
rowStyles : List Style
rowStyles =
[ height (px 45)
, fontSize (px 14)
, color gray20
, pseudoClass "nth-child(odd)"
[ backgroundColor gray96 ]
]
loadingContentStyles : List Style
loadingContentStyles =
[ width (pct 100)
, display inlineBlock
, height (Css.em 1)
, borderRadius (Css.em 1)
, backgroundColor gray75
]
loadingCellStyles : List Style
loadingCellStyles =
[ batch flashAnimation
, padding2 (px 14) (px 10)
]
loadingTableStyles : List Style
loadingTableStyles =
fadeInAnimation
tableStyles : List Style
tableStyles =
[ borderCollapse collapse
, baseFont
, Css.width (Css.pct 100)
]
flash : Css.Animations.Keyframes {}
flash =
Css.Animations.keyframes
[ ( 0, [ Css.Animations.opacity (Css.num 0.6) ] )
, ( 50, [ Css.Animations.opacity (Css.num 0.2) ] )
, ( 100, [ Css.Animations.opacity (Css.num 0.6) ] )
]
fadeIn : Css.Animations.Keyframes {}
fadeIn =
Css.Animations.keyframes
[ ( 0, [ Css.Animations.opacity (Css.num 0) ] )
, ( 100, [ Css.Animations.opacity (Css.num 1) ] )
]
flashAnimation : List Css.Style
flashAnimation =
[ animationName flash
, property "animation-duration" "2s"
, property "animation-iteration-count" "infinite"
, opacity (num 0.6)
]
fadeInAnimation : List Css.Style
fadeInAnimation =
[ animationName fadeIn
, property "animation-duration" "0.4s"
, property "animation-delay" "0.2s"
, property "animation-fill-mode" "forwards"
, animationIterationCount (int 1)
, opacity (num 0)
]

View File

@ -27,7 +27,7 @@ module Nri.Ui.Text.V6 exposing
## Headings
You're in the wrong place! Headings live in Nri.Ui.Heading.V2.
You're in the wrong place! Headings live in Nri.Ui.Heading.V3.
## Paragraph styles

View File

@ -1,6 +1,6 @@
module Nri.Ui.TextInput.V7 exposing
( view, generateId
, number, float, text, newPassword, currentPassword, email, search
, number, float, text, newPassword, currentPassword, email, search, addressLevel2, addressLine1, familyName, givenName, organization, organizationTitle, postalCode, sex, tel
, readOnlyText
, value, map
, onFocus, onBlur, onEnter
@ -27,7 +27,7 @@ module Nri.Ui.TextInput.V7 exposing
### Input types
@docs number, float, text, newPassword, currentPassword, email, search
@docs number, float, text, newPassword, currentPassword, email, search, addressLevel2, addressLine1, familyName, givenName, organization, organizationTitle, postalCode, sex, tel
@docs readOnlyText
@ -269,6 +269,177 @@ search onInput_ =
)
{-| An input that allows given-name entry
-}
givenName : (String -> msg) -> Attribute String msg
givenName onInput_ =
Attribute
{ emptyEventsAndValues
| toString = Just identity
, fromString = Just identity
, onInput = Just (identity >> onInput_)
}
(\config ->
{ config
| fieldType = Just "text"
, inputMode = Nothing
, autocomplete = Just "given-name"
}
)
{-| An input that allows family-name entry
-}
familyName : (String -> msg) -> Attribute String msg
familyName onInput_ =
Attribute
{ emptyEventsAndValues
| toString = Just identity
, fromString = Just identity
, onInput = Just (identity >> onInput_)
}
(\config ->
{ config
| fieldType = Just "text"
, inputMode = Nothing
, autocomplete = Just "family-name"
}
)
{-| An input that allows organization entry
-}
organization : (String -> msg) -> Attribute String msg
organization onInput_ =
Attribute
{ emptyEventsAndValues
| toString = Just identity
, fromString = Just identity
, onInput = Just (identity >> onInput_)
}
(\config ->
{ config
| fieldType = Just "text"
, inputMode = Nothing
, autocomplete = Just "organization"
}
)
{-| An input that allows organization-title entry
-}
organizationTitle : (String -> msg) -> Attribute String msg
organizationTitle onInput_ =
Attribute
{ emptyEventsAndValues
| toString = Just identity
, fromString = Just identity
, onInput = Just (identity >> onInput_)
}
(\config ->
{ config
| fieldType = Just "text"
, inputMode = Nothing
, autocomplete = Just "organization-title"
}
)
{-| An input that allows address-line1 entry
-}
addressLine1 : (String -> msg) -> Attribute String msg
addressLine1 onInput_ =
Attribute
{ emptyEventsAndValues
| toString = Just identity
, fromString = Just identity
, onInput = Just (identity >> onInput_)
}
(\config ->
{ config
| fieldType = Just "text"
, inputMode = Nothing
, autocomplete = Just "address-line1"
}
)
{-| An input that allows address-level2 entry
-}
addressLevel2 : (String -> msg) -> Attribute String msg
addressLevel2 onInput_ =
Attribute
{ emptyEventsAndValues
| toString = Just identity
, fromString = Just identity
, onInput = Just (identity >> onInput_)
}
(\config ->
{ config
| fieldType = Just "text"
, inputMode = Nothing
, autocomplete = Just "address-level2"
}
)
{-| An input that allows postal-code entry
-}
postalCode : (String -> msg) -> Attribute String msg
postalCode onInput_ =
Attribute
{ emptyEventsAndValues
| toString = Just identity
, fromString = Just identity
, onInput = Just (identity >> onInput_)
}
(\config ->
{ config
| fieldType = Just "text"
, inputMode = Nothing
, autocomplete = Just "postal-code"
}
)
{-| An input that allows tel entry
-}
tel : (String -> msg) -> Attribute String msg
tel onInput_ =
Attribute
{ emptyEventsAndValues
| toString = Just identity
, fromString = Just identity
, onInput = Just (identity >> onInput_)
}
(\config ->
{ config
| fieldType = Just "tel"
, inputMode = Just "tel"
, autocomplete = Just "tel"
}
)
{-| An input that allows sex entry
-}
sex : (String -> msg) -> Attribute String msg
sex onInput_ =
Attribute
{ emptyEventsAndValues
| toString = Just identity
, fromString = Just identity
, onInput = Just (identity >> onInput_)
}
(\config ->
{ config
| fieldType = Just "text"
, inputMode = Nothing
, autocomplete = Just "sex"
}
)
{-| -}
value : value -> Attribute value msg
value value_ =

View File

@ -1,5 +1,5 @@
module Nri.Ui.UiIcon.V1 exposing
( seeMore, openClose, download, sort, gear, flipper
( seeMore, openClose, download, sort, gear, flipper, hamburger
, archive, unarchive
, playInCircle, pauseInCircle, stopInCircle
, play, skip
@ -20,7 +20,7 @@ module Nri.Ui.UiIcon.V1 exposing
, flag, star, starFilled, starOutline
, equals, plus, null
, key, lock, premiumLock
, badge, tada
, badge, tada, count
, bold, italic, underline, list, link, undo, redo
, home, library
, search, searchInCicle
@ -29,11 +29,12 @@ module Nri.Ui.UiIcon.V1 exposing
, openInNewTab, sync
, school, highSchool, company, homeSchool, graduateCap
, flagUs, globe
, info
)
{-| 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
@docs seeMore, openClose, download, sort, gear, flipper, hamburger
@docs archive, unarchive
@docs playInCircle, pauseInCircle, stopInCircle
@docs play, skip
@ -54,7 +55,7 @@ module Nri.Ui.UiIcon.V1 exposing
@docs flag, star, starFilled, starOutline
@docs equals, plus, null
@docs key, lock, premiumLock
@docs badge, tada
@docs badge, tada, count
@docs bold, italic, underline, list, link, undo, redo
@docs home, library
@docs search, searchInCicle
@ -63,6 +64,7 @@ module Nri.Ui.UiIcon.V1 exposing
@docs openInNewTab, sync
@docs school, highSchool, company, homeSchool, graduateCap
@docs flagUs, globe
@docs info
import Html.Styled exposing (..)
import Nri.Ui.Colors.V1 as Colors
@ -179,6 +181,17 @@ copyToClipboard =
]
{-| -}
info : Nri.Ui.Svg.V1.Svg
info =
Nri.Ui.Svg.V1.init "0 0 25 25"
[ Svg.path [ Attributes.d "M12.5,25 C5.59644063,25 0,19.4035594 0,12.5 C0,5.59644063 5.59644063,0 12.5,0 C19.4035594,0 25,5.59644063 25,12.5 C25,19.4035594 19.4035594,25 12.5,25 Z M12.5,23 C18.2989899,23 23,18.2989899 23,12.5 C23,6.70101013 18.2989899,2 12.5,2 C6.70101013,2 2,6.70101013 2,12.5 C2,18.2989899 6.70101013,23 12.5,23 Z" ] []
, Svg.g
[ Attributes.transform "translate(1, 0)" ]
[ Svg.path [ Attributes.d "M13.9802 17.28H9.24023V16.7325C9.37023 16.7225 9.49773 16.71 9.62273 16.695C9.74773 16.68 9.85523 16.655 9.94523 16.62C10.1052 16.56 10.2177 16.475 10.2827 16.365C10.3477 16.25 10.3802 16.1 10.3802 15.915V11.55C10.3802 11.375 10.3402 11.2225 10.2602 11.0925C10.1802 10.9575 10.0802 10.85 9.96023 10.77C9.87023 10.71 9.73273 10.6525 9.54773 10.5975C9.36773 10.5425 9.20273 10.5075 9.05273 10.4925V9.94504L12.7277 9.75004L12.8402 9.86254V15.8175C12.8402 15.9925 12.8777 16.1425 12.9527 16.2675C13.0277 16.3875 13.1352 16.4775 13.2752 16.5375C13.3752 16.5825 13.4852 16.6225 13.6052 16.6575C13.7252 16.6925 13.8502 16.7175 13.9802 16.7325V17.28ZM12.8852 7.05004C12.8852 7.43004 12.7377 7.75504 12.4427 8.02504C12.1527 8.29004 11.8077 8.42254 11.4077 8.42254C11.0027 8.42254 10.6527 8.29004 10.3577 8.02504C10.0677 7.75504 9.92273 7.43004 9.92273 7.05004C9.92273 6.67004 10.0677 6.34504 10.3577 6.07504C10.6527 5.80504 11.0027 5.67004 11.4077 5.67004C11.8127 5.67004 12.1602 5.80504 12.4502 6.07504C12.7402 6.34504 12.8852 6.67004 12.8852 7.05004Z" ] [] ]
]
{-| -}
performance : Nri.Ui.Svg.V1.Svg
performance =
@ -217,10 +230,17 @@ download =
{-| -}
edit : Nri.Ui.Svg.V1.Svg
edit =
Nri.Ui.Svg.V1.init "0 0 30 30"
[ Svg.path [ Attributes.d "M27.3,7.9l-5.2-5.2l2.3-2.3c0.5-0.5,1.2-0.5,1.7,0L29.7,4c0.5,0.5,0.5,1.2,0,1.7L27.3,7.9z M25.9,9.4L8.6,26.6l-5.2-5.2L20.6,4.1L25.9,9.4z M0,30l1.9-7L7,28.1L0,30z" ] []
, Svg.path [ Attributes.fill "none", Attributes.d "M-753.8-401V715h1024V-401H-753.8z" ] []
, Svg.path [ Attributes.fill "none", Attributes.d "M-775.9-385.9v1116h1024v-1116L-775.9-385.9L-775.9-385.9z" ] []
Nri.Ui.Svg.V1.init "0 0 95 95"
[ Svg.path
[ Attributes.d "M93.7748134,12.5537834 C92.2748134,10.3545834 90.4740134,8.2529834 88.4740134,6.2529834 C86.6732134,4.5537834 84.0756134,2.5537834 82.2748134,1.3545834 C79.2748134,-0.747016601 75.1732134,-0.344616601 72.6732134,2.1553634 L8.9742134,65.7533634 C8.7749934,65.9525834 8.5757734,66.2533634 8.4742134,66.5541434 L0.1734134,90.1561434 C-0.2250266,91.4569434 0.0718534003,92.8553434 0.9741934,93.7577434 C1.6734134,94.4569634 2.4741934,94.7577434 3.3725934,94.7577434 C3.7710334,94.7577434 4.1733734,94.6561834 4.5717934,94.5585234 L28.0717934,86.2577234 C28.3725734,86.1561634 28.6733534,85.9569434 28.8725734,85.7577234 L92.6735734,21.9567234 C95.2751734,19.4567234 95.6735734,15.4567234 93.7751734,12.5544234 L93.7748134,12.5537834 Z"
, Attributes.fill "#none"
]
[]
, Svg.path
[ Attributes.d "M12.3728134,68.6557834 C17.7712134,72.3549834 22.3728134,76.9565834 26.0718134,82.3547834 L12.3728134,87.1555834 C11.8728134,86.1555834 11.2712134,85.1555834 10.3728134,84.2571834 C9.4743734,83.3587434 8.4744134,82.7571834 7.4744134,82.2571834 L12.3728134,68.6557834 Z"
, Attributes.fill "#FFFFFF"
]
[]
]
@ -903,6 +923,37 @@ pauseInCircle =
]
{-| -}
hamburger : Nri.Ui.Svg.V1.Svg
hamburger =
Nri.Ui.Svg.V1.init "0 0 25 25"
[ Svg.rect
[ Attributes.x "0"
, Attributes.y "0"
, Attributes.width "25"
, Attributes.height "5"
, Attributes.rx "2.5"
]
[]
, Svg.rect
[ Attributes.x "0"
, Attributes.y "10"
, Attributes.width "25"
, Attributes.height "5"
, Attributes.rx "2.5"
]
[]
, Svg.rect
[ Attributes.x "0"
, Attributes.y "20"
, Attributes.width "25"
, Attributes.height "5"
, Attributes.rx "2.5"
]
[]
]
{-| -}
equals : Nri.Ui.Svg.V1.Svg
equals =
@ -1346,7 +1397,7 @@ checklistComplete =
{-| -}
openBook : Nri.Ui.Svg.V1.Svg
openBook =
Nri.Ui.Svg.V1.init "0 0 16 13"
Nri.Ui.Svg.V1.init "0 0 15 12"
[ Svg.g [ Attributes.transform "translate(0.256349, 0.281480)" ]
[ Svg.path [ Attributes.d "M5.97967784,7.68594033 L6.3357413,7.774016 L6.3357413,8.297421 C4.90871699,7.91726562 3.51632767,7.87765319 2.08989378,8.17910991 L1.7325363,8.26158 L1.7325363,7.737499 C3.16515353,7.37982238 4.55798757,7.36210421 5.97967784,7.68594033 L5.97967784,7.68594033 Z" ] []
, Svg.path [ Attributes.d "M5.97967784,6.20834789 L6.3357413,6.296302 L6.3357413,6.820381 C4.90871699,6.43960069 3.51632767,6.40051534 2.08989378,6.70152673 L1.7325363,6.783864 L1.7325363,6.26046 C3.16515353,5.90153631 4.55798757,5.88487164 5.97967784,6.20834789 L5.97967784,6.20834789 Z" ] []
@ -1533,6 +1584,16 @@ tada =
]
{-| -}
count : Nri.Ui.Svg.V1.Svg
count =
Nri.Ui.Svg.V1.init "0 0 75 75"
[ Svg.g []
[ Svg.path [ Attributes.d "M56.2502,0 L18.7502,0 C13.7775,0 9.008,1.9766 5.4922,5.4922 C1.9766,9.0078 0,13.7774 0,18.7502 L0,56.2502 C0,61.2229 1.9766,65.9924 5.4922,69.5082 C9.0078,73.0238 13.7774,75.0004 18.7502,75.0004 L56.2502,75.0004 C61.2229,75.0004 65.9924,73.0238 69.5082,69.5082 C73.0238,65.9926 75.0004,61.223 75.0004,56.2502 L75.0004,18.7502 C75.0004,13.7775 73.0238,9.008 69.5082,5.4922 C65.9926,1.9766 61.223,0 56.2502,0 Z M68.7502,56.25 C68.7502,59.5664 67.4338,62.7461 65.09,65.0898 C62.7462,67.4335 59.5666,68.75 56.2502,68.75 L18.7502,68.75 C11.8479,68.75 6.2502,63.1523 6.2502,56.25 L6.2502,18.75 C6.2502,11.8477 11.8479,6.25 18.7502,6.25 L56.2502,6.25 C59.5666,6.25 62.7463,7.5664 65.09,9.9102 C67.4337,12.254 68.7502,15.4336 68.7502,18.75 L68.7502,56.25 Z M57.0942,25.312 L52.0942,25.312 L53.1254,20.2495 C53.45352,18.5229 52.32071,16.8589 50.5942,16.5307 C48.86769,16.2025 47.2036,17.33539 46.8754,19.0619 L45.6879,25.3119 L33.9689,25.3119 L34.9689,20.2494 C35.29702,18.5228 34.16421,16.8588 32.4377,16.5306 C30.71119,16.2024 29.0471,17.33529 28.7189,19.0618 L27.5314,25.3118 L21.2814,25.3118 C19.5548,25.3118 18.1564,26.7102 18.1564,28.4368 C18.1564,30.1634 19.5548,31.5618 21.2814,31.5618 L26.2814,31.5618 L23.9689,43.4368 L17.7189,43.4368 C15.9923,43.4368 14.5939,44.8352 14.5939,46.5618 C14.5939,48.2884 15.9923,49.6868 17.7189,49.6868 L22.7189,49.6868 L21.87515,54.7493 C21.71109,55.56571 21.879056,56.4134 22.33999,57.1087 C22.80483,57.80011 23.52749,58.2767 24.34389,58.4368 L25.00014,58.4368 C26.51964,58.464144 27.83604,57.3977 28.12514,55.9056 L29.31264,49.6556 L41.09364,49.6556 L40.09364,54.7181 C39.92958,55.53451 40.097546,56.3822 40.55848,57.0775 C41.02332,57.76891 41.74598,58.2455 42.56238,58.4056 L43.15613,58.4056 C44.67563,58.432944 45.99203,57.3665 46.28113,55.8744 L47.46863,49.6244 L53.71863,49.6244 C55.44523,49.6244 56.84363,48.226 56.84363,46.4994 C56.84363,44.7728 55.44523,43.3744 53.71863,43.3744 L48.71863,43.3744 L51.03113,31.4994 L57.28113,31.4994 C59.00773,31.4994 60.40613,30.101 60.40613,28.3744 C60.40613,26.6478 59.00773,25.2494 57.28113,25.2494 L57.0942,25.312 Z M42.2192,43.437 L30.4692,43.437 L32.7817,31.562 L44.5317,31.562 L42.2192,43.437 Z" ] []
]
]
{-| -}
openInNewTab : Nri.Ui.Svg.V1.Svg
openInNewTab =

View File

@ -15,10 +15,10 @@ import Html.Styled.Attributes exposing (..)
import Http
import Json.Decode as Decode
import Nri.Ui.CssVendorPrefix.V1 as VendorPrefixed
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.MediaQuery.V1 exposing (mobile)
import Nri.Ui.Page.V3 as Page
import Nri.Ui.SideNav.V3 as SideNav
import Nri.Ui.SideNav.V4 as SideNav
import Nri.Ui.Sprite.V1 as Sprite
import Nri.Ui.UiIcon.V1 as UiIcon
import Routes
@ -36,6 +36,8 @@ type alias Model key =
route : Route
, previousRoute : Maybe Route
, moduleStates : Dict String (Example Examples.State Examples.Msg)
, isSideNavOpen : Bool
, openTooltip : Maybe TooltipId
, navigationKey : key
, elliePackageDependencies : Result Http.Error (Dict String String)
}
@ -51,6 +53,8 @@ init () url key =
( { route = Routes.fromLocation moduleStates url
, previousRoute = Nothing
, moduleStates = moduleStates
, isSideNavOpen = True
, openTooltip = Nothing
, navigationKey = key
, elliePackageDependencies = Ok Dict.empty
}
@ -62,12 +66,18 @@ init () url key =
)
type TooltipId
= SideNavOpenCloseTooltip
type Msg
= UpdateModuleStates String Examples.Msg
| OnUrlRequest Browser.UrlRequest
| OnUrlChange Url
| ChangeRoute Route
| SkipToMainContent
| ToggleSideNav Bool
| ToggleTooltip TooltipId Bool
| LoadedPackages (Result Http.Error (Dict String String))
| Focused (Result Browser.Dom.Error ())
@ -125,6 +135,15 @@ update action model =
, FocusOn "maincontent"
)
ToggleSideNav isOpen ->
( { model | isSideNavOpen = isOpen }, None )
ToggleTooltip tooltipId True ->
( { model | openTooltip = Just tooltipId }, None )
ToggleTooltip _ False ->
( { model | openTooltip = Nothing }, None )
LoadedPackages newPackagesResult ->
let
-- Ellie gets really slow to compile if we include all the packages, unfortunately!
@ -280,10 +299,7 @@ viewCategory model category =
)
withSideNav :
{ model | route : Route, moduleStates : Dict String (Example Examples.State Examples.Msg) }
-> Html Msg
-> Html Msg
withSideNav : Model key -> Html Msg -> Html Msg
withSideNav model content =
Html.div
[ css
@ -333,10 +349,8 @@ viewPreviews containerId navConfig examples =
]
navigation :
{ model | route : Route, moduleStates : Dict String (Example Examples.State Examples.Msg) }
-> Html Msg
navigation { moduleStates, route } =
navigation : Model key -> Html Msg
navigation { moduleStates, route, isSideNavOpen, openTooltip } =
let
examples =
Dict.values moduleStates
@ -370,6 +384,14 @@ navigation { moduleStates, route } =
[ VendorPrefixed.value "position" "sticky"
, top (px 55)
]
, SideNav.collapsible
{ isOpen = isSideNavOpen
, toggle = ToggleSideNav
, isTooltipOpen = openTooltip == Just SideNavOpenCloseTooltip
, toggleTooltip = ToggleTooltip SideNavOpenCloseTooltip
}
, SideNav.navLabel "categories"
, SideNav.navId "sidenav__categories"
]
(SideNav.entry "Usage Guidelines"
[ SideNav.linkExternal "https://paper.dropbox.com/doc/UI-Style-Guide-and-Caveats--BhJHYronm1RGM1hRfnkvhrZMAg-PvOLxeX3oyujYEzdJx5pu"

View File

@ -26,7 +26,7 @@ import Example
import Html.Styled exposing (..)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Html.V3 exposing (viewIf)
import Nri.Ui.MediaQuery.V1 exposing (mobile)
import Nri.Ui.Text.V6 as Text
@ -89,9 +89,8 @@ viewExampleCode ellieLink component values =
[ summary []
[ Heading.h3
[ Heading.css [ Css.display Css.inline ]
, Heading.style Heading.Small
, Heading.plaintext example.sectionName
]
[ text example.sectionName ]
]
, ellieLink
{ fullModuleName = Example.fullName component
@ -117,8 +116,9 @@ viewExampleCode ellieLink component values =
viewSection : String -> List Css.Style -> List (Html msg) -> Html msg
viewSection name styles children =
section [ css (flex (int 1) :: styles) ]
(Heading.h2 [ Heading.style Heading.Subhead ] [ text name ]
section
[ css (flex (int 1) :: styles) ]
(Heading.h2 [ Heading.plaintext name ]
:: children
)

View File

@ -18,9 +18,9 @@ import Html.Styled.Attributes exposing (css, href)
import Nri.Ui.BreadCrumbs.V1 as BreadCrumbs exposing (BreadCrumbs)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Nri.Ui.Table.V5 as Table
import Nri.Ui.Table.V6 as Table
import Nri.Ui.UiIcon.V1 as UiIcon
@ -72,7 +72,7 @@ example =
, toExampleCode = \settings -> [ { sectionName = moduleName ++ ".view", code = viewExampleCode settings } ]
}
, section [ css [ Css.margin2 (Css.px 20) Css.zero ] ]
[ Heading.h2 [] [ text "Example" ]
[ Heading.h2 [ Heading.plaintext "Example" ]
, viewExample breadCrumbs
]
, Table.view
@ -81,18 +81,21 @@ example =
, value = .name
, width = Css.pct 15
, cellStyles = always []
, sort = Nothing
}
, Table.string
{ header = "About"
, value = .about
, width = Css.px 200
, cellStyles = always []
, sort = Nothing
}
, Table.string
{ header = "Result"
, value = \{ result } -> result breadCrumbs
, width = Css.px 50
, cellStyles = always []
, sort = Nothing
}
]
[ { name = "headerId"

View File

@ -18,7 +18,7 @@ import Example exposing (Example)
import Html.Styled exposing (..)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Button.V10 as Button
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.UiIcon.V1 as UiIcon
import Set exposing (Set)
@ -306,7 +306,7 @@ buttons model =
toggleButtons : Set Int -> Html Msg
toggleButtons pressedToggleButtons =
div []
[ Heading.h3 [] [ text "Button toggle" ]
[ Heading.h3 [ Heading.plaintext "Button toggle" ]
, div [ css [ Css.displayFlex, Css.marginBottom (Css.px 20) ] ]
[ Button.toggleButton
{ onDeselect = ToggleToggleButton 0

View File

@ -17,7 +17,7 @@ import Nri.Ui.Checkbox.V6 as Checkbox
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Data.PremiumDisplay as PremiumDisplay
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.PremiumCheckbox.V8 as PremiumCheckbox
import Nri.Ui.Svg.V1 as Svg
import Set exposing (Set)
@ -51,7 +51,7 @@ example =
, viewLockedOnInsideCheckbox "styleguide-locked-on-inside-checkbox" state
, viewDisabledCheckbox "styleguide-checkbox-disabled" state
, viewMultilineCheckboxes state
, Heading.h2 [ Heading.style Heading.Subhead ] [ text "Premium Checkboxes" ]
, Heading.h2 [ Heading.plaintext "Premium Checkboxes" ]
, viewPremiumCheckboxes state
, viewCustomStyledCheckbox state
, viewCustomStyledPremiumCheckboxes state
@ -185,7 +185,7 @@ viewMultilineCheckboxes : State -> Html Msg
viewMultilineCheckboxes state =
Html.section
[ css [ Css.width (Css.px 500) ] ]
[ Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "Multiline Text in Checkboxes" ]
[ Heading.h2 [ Heading.plaintext "Multiline Text in Checkboxes" ]
, let
id =
"styleguide-checkbox-multiline"

View File

@ -187,6 +187,7 @@ viewExampleTable { label, icon, attributes } =
[ ( "primary", ClickableSvg.primary )
, ( "secondary", ClickableSvg.secondary )
, ( "danger", ClickableSvg.danger )
, ( "tertiary", ClickableSvg.tertiary )
, ( "dangerSecondary", ClickableSvg.dangerSecondary )
]
, Html.tfoot []
@ -295,4 +296,13 @@ initSettings =
{ moduleName = "ClickableSvg"
, use = ClickableSvg.notMobileCss
}
|> ControlExtra.optionalListItem "iconForMobile"
(Control.map
(\( name, icon ) ->
( "ClickableSvg.iconForMobile " ++ name
, ClickableSvg.iconForMobile icon
)
)
CommonControls.uiIcon
)
)

View File

@ -14,7 +14,7 @@ import Html.Styled.Attributes as Attributes exposing (css)
import Nri.Ui.Colors.Extra
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Text.V6 as Text
import SolidColor exposing (highContrast)
@ -91,7 +91,7 @@ example =
, ( "sunshine", Colors.sunshine, "Yellow highlights, tips" )
]
|> viewColors
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "Background Highlight Colors" ]
, Heading.h2 [ Heading.plaintext "Background Highlight Colors" ]
, Text.mediumBody [ Text.plaintext "Background highlights should be used as the default highlight style because they are more noticeable and readable. The dark colors should be used in the case where headings need to harmonize with highlighted containers, such as in Guided Drafts." ]
, [ ( "highlightYellow", Colors.highlightYellow, "Yellow background highlights" )
, ( "highlightYellowDark", Colors.highlightYellowDark, "Dark yellow background highlights" )
@ -109,7 +109,7 @@ example =
, ( "highlightBrownDark", Colors.highlightBrownDark, "Dark brown background highlights" )
]
|> viewColors
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "Text Highlight Colors" ]
, Heading.h2 [ Heading.plaintext "Text Highlight Colors" ]
, Text.mediumBody [ Text.plaintext "Colors for highlighting text on a white background. These colors are readable at 14px bold and bigger." ]
, [ ( "textHighlightYellow", Colors.textHighlightYellow, "Neutral text highlight #1" )
, ( "textHighlightCyan", Colors.textHighlightCyan, "Neutral text highlight #2" )

View File

@ -16,7 +16,7 @@ import Example exposing (Example)
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Container.V2 as Container
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
moduleName : String
@ -119,7 +119,7 @@ viewExample { name, description } attributes =
[ Css.marginTop (Css.px 20)
]
]
[ Heading.h3 [] [ Html.text name ]
[ Heading.h3 [ Heading.plaintext name ]
, Html.text description
, Container.view attributes
]

View File

@ -12,7 +12,7 @@ import Example exposing (Example)
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
{-| -}
@ -43,13 +43,13 @@ example =
|> List.map viewPreview
, view =
\ellieLinkConfig _ ->
[ Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "baseFont" ]
[ Heading.h2 [ Heading.plaintext "baseFont" ]
, Html.p [ css [ Fonts.baseFont ] ]
[ Html.text "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" ]
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "quizFont" ]
, Heading.h2 [ Heading.plaintext "quizFont" ]
, Html.p [ css [ Fonts.quizFont ] ]
[ Html.text "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" ]
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "ugFont" ]
, Heading.h2 [ Heading.plaintext "ugFont" ]
, Html.p [ css [ Fonts.ugFont ] ]
[ Html.text "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" ]
]

View File

@ -12,8 +12,7 @@ import Debug.Control as Control exposing (Control)
import Debug.Control.Extra as ControlExtra
import Debug.Control.View as ControlView
import Example exposing (Example)
import Html.Styled as Html
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import ViewHelpers exposing (viewExamples)
@ -24,7 +23,7 @@ moduleName =
version : Int
version =
2
3
{-| -}
@ -38,20 +37,20 @@ example =
, update = update
, subscriptions = \_ -> Sub.none
, preview =
[ Heading.h1 [] [ Html.text "h1" ]
, Heading.h2 [] [ Html.text "h2" ]
, Heading.h3 [] [ Html.text "h3" ]
, Heading.h4 [] [ Html.text "h4" ]
[ Heading.h1 [ Heading.plaintext "h1" ]
, Heading.h2 [ Heading.plaintext "h2" ]
, Heading.h3 [ Heading.plaintext "h3" ]
, Heading.h4 [ Heading.plaintext "h4" ]
]
, view =
\ellieLinkConfig state ->
let
examples =
[ ( "h1", Heading.h1, "This is the main page heading." )
, ( "h2", Heading.h2, "This is a tagline" )
, ( "h3", Heading.h3, "This is a subHeading" )
, ( "h4", Heading.h4, "This is a smallHeading" )
, ( "h5", Heading.h5, "This is also a smallHeading" )
[ ( "h1", Heading.h1 )
, ( "h2", Heading.h2 )
, ( "h3", Heading.h3 )
, ( "h4", Heading.h4 )
, ( "h5", Heading.h5 )
]
attributes =
@ -68,7 +67,7 @@ example =
, toExampleCode =
\settings ->
let
toExampleCode ( name, _, content ) =
toExampleCode ( name, _ ) =
{ sectionName = name
, code =
moduleName
@ -77,16 +76,12 @@ example =
++ "\n [ "
++ String.join "\n , " (List.map Tuple.first settings)
++ "\n ]"
++ ("\n [ Html.text \"" ++ content ++ "\" ]")
}
in
List.map toExampleCode examples
}
, examples
|> List.map
(\( name, view, content ) ->
( name, view attributes [ Html.text content ] )
)
|> List.map (\( name, view ) -> ( name, view attributes ))
|> viewExamples
]
}
@ -102,29 +97,30 @@ init : State
init =
{ control =
ControlExtra.list
|> ControlExtra.listItem "content" controlContent
|> CommonControls.css { moduleName = moduleName, use = Heading.css }
|> ControlExtra.optionalBoolListItem "error" ( "Heading.error", Heading.error )
|> ControlExtra.optionalListItem "style" controlStyle
}
controlContent : Control ( String, Heading.Attribute msg )
controlContent =
CommonControls.content
{ moduleName = moduleName
, plaintext = Heading.plaintext
, markdown = Just Heading.markdown
, html = Heading.html
, httpError = Nothing
}
controlStyle : Control ( String, Heading.Attribute msg )
controlStyle =
[ ( "Top", Heading.Top )
, ( "Tagline", Heading.Tagline )
, ( "Subhead", Heading.Subhead )
, ( "Small", Heading.Small )
]
|> List.map
(\( name, val ) ->
( name
, Control.value
( "Heading.style Heading." ++ name
, Heading.style val
)
)
)
|> Control.choice
CommonControls.choice moduleName
[ ( "top", Heading.top )
, ( "subhead", Heading.subhead )
, ( "small", Heading.small )
]
type alias Settings =

View File

@ -24,7 +24,7 @@ import Html.Styled.Events as Events
import Nri.Ui.Checkbox.V6 as Checkbox
import Nri.Ui.Colors.Extra exposing (fromCssColor, toCssColor)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Select.V8 as Select
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Nri.Ui.Text.V6 as Text
@ -189,7 +189,7 @@ view settings groups =
viewSettings settings
:: List.map viewExampleSection groups
++ [ Html.section [ css [ Css.margin2 (Css.px 30) Css.zero ] ]
[ Heading.h3 [] [ Html.text "Example Usage" ]
[ Heading.h3 [ Heading.plaintext "Example Usage" ]
, viewSingularExampleSettings groups settings
, viewResults settings
]
@ -214,8 +214,8 @@ viewWithCustomStyles { showIconName } headerText icons =
, Css.lineHeight (Css.num 1.2)
, Css.fontWeight (Css.int 700)
]
, Heading.plaintext headerText
]
[ Html.text headerText ]
, Html.div
[ css
[ Css.displayFlex

View File

@ -58,6 +58,13 @@ all =
, Css.margin (Css.px 4)
]
)
, ( "noredinkMonochrome"
, Logo.noredinkMonochrome
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
]
)
, ( "Social Media"

View File

@ -9,7 +9,7 @@ import Debug.Control.Extra as ControlExtra
import Debug.Control.View as ControlView
import Example exposing (Example)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Message.V3 as Message
import ViewHelpers exposing (viewExamples)
@ -194,8 +194,8 @@ example =
, Css.borderTop3 (Css.px 2) Css.solid Colors.gray96
, Css.paddingTop (Css.px 20)
]
, Heading.plaintext "Message.somethingWentWrong"
]
[ text "Message.somethingWentWrong" ]
, Message.somethingWentWrong exampleRailsError
]
}

View File

@ -17,7 +17,7 @@ import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Page.V3 as Page exposing (DefaultPage, RecoveryText(..))
@ -113,7 +113,7 @@ example =
}
]
}
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "Example" ]
, Heading.h2 [ Heading.plaintext "Example" ]
, Tuple.second settings.page
{ link = ShowItWorked
, recoveryText = settings.recoveryText

View File

@ -20,13 +20,13 @@ import Debug.Control.Extra as ControlExtra
import Debug.Control.View as ControlView
import EllieLink
import Example exposing (Example)
import Html.Styled as Html exposing (..)
import Html.Styled exposing (..)
import Html.Styled.Attributes exposing (css)
import KeyboardSupport exposing (Direction(..), Key(..))
import Nri.Ui.Button.V10 as Button
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Data.PremiumDisplay as PremiumDisplay
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Modal.V11 as Modal
import Nri.Ui.RadioButton.V4 as RadioButton
import Nri.Ui.Text.V6 as Text
@ -125,7 +125,7 @@ view ellieLinkConfig state =
}
]
}
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "Example" ]
, Heading.h2 [ Heading.plaintext "Example" ]
, viewExamples selectionSettings state.selectedValue
, Modal.view
{ title = "Go Premium!"

View File

@ -15,7 +15,7 @@ import Debug.Control.View as ControlView
import Example exposing (Example)
import Html.Styled
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Select.V8 as Select exposing (Choice)
@ -77,7 +77,7 @@ example =
}
]
}
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.Styled.text "Example" ]
, Heading.h2 [ Heading.plaintext "Example" ]
, Select.view label attributes
|> Html.Styled.map ConsoleLog
]

View File

@ -17,12 +17,12 @@ import EllieLink
import Example exposing (Example)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.SideNav.V3 as SideNav
import Nri.Ui.SideNav.V4 as SideNav
version : Int
version =
3
4
{-| -}
@ -124,7 +124,7 @@ type alias State =
type alias Settings =
{ currentRoute : String
, navAttributes : List ( String, SideNav.NavAttribute )
, navAttributes : List ( String, SideNav.NavAttribute Msg )
, entries : List ( String, SideNav.Entry String Msg )
}
@ -140,7 +140,7 @@ init =
}
controlNavAttributes : Control (List ( String, SideNav.NavAttribute ))
controlNavAttributes : Control (List ( String, SideNav.NavAttribute Msg ))
controlNavAttributes =
ControlExtra.list
|> ControlExtra.optionalListItemDefaultChecked "navLabel"

View File

@ -13,10 +13,10 @@ import Html.Styled as Html exposing (..)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Button.V10 as Button
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.SortableTable.V3 as SortableTable
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
import Nri.Ui.Table.V5 as Table
import Nri.Ui.Table.V6 as Table
import Nri.Ui.UiIcon.V1 as UiIcon
@ -84,12 +84,14 @@ example =
, view = .x >> Html.text
, width = px 50
, cellStyles = always []
, sort = Nothing
}
, Table.custom
{ header = header "Y"
, view = .y >> Html.text
, width = px 50
, cellStyles = always []
, sort = Nothing
}
]
[ { x = "Row 1 X"
@ -152,9 +154,9 @@ example =
, { firstName = "First5", lastName = "Last5", coins = 5 }
]
in
[ Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "With sortable headers" ]
[ Heading.h2 [ Heading.plaintext "With sortable headers" ]
, SortableTable.view config sortState data
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "Loading" ]
, Heading.h2 [ Heading.plaintext "Loading" ]
, SortableTable.viewLoading config sortState
]
}

View File

@ -13,8 +13,8 @@ import Debug.Control as Control exposing (Control)
import Debug.Control.View as ControlView
import Example exposing (Example)
import Nri.Ui.Button.V10 as Button
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Table.V5 as Table exposing (Column)
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Table.V6 as Table exposing (Column)
{-| -}
@ -49,12 +49,14 @@ example =
, value = .a
, width = Css.px 50
, cellStyles = always []
, sort = Nothing
}
, Table.string
{ header = "B"
, value = .b
, width = Css.px 50
, cellStyles = always []
, sort = Nothing
}
]
[ { a = "Row 1 A"
@ -104,7 +106,7 @@ example =
, toExampleCode "viewLoadingWithoutHeader" ""
]
}
, Heading.h2 [ Heading.style Heading.Subhead ] [ text "Example" ]
, Heading.h2 [ Heading.plaintext "Example" ]
, case ( showHeader, isLoading ) of
( True, False ) ->
Table.view columns data
@ -187,6 +189,7 @@ columnsWithCode =
, " , value = .firstName"
, " , width = Css.calc (Css.pct 50) Css.minus (Css.px 250)"
, " , cellStyles = always []"
, " , sort = Nothing"
, " }"
]
|> String.join "\n\t "
@ -195,6 +198,7 @@ columnsWithCode =
, value = .firstName
, width = Css.calc (Css.pct 50) Css.minus (Css.px 250)
, cellStyles = always []
, sort = Nothing
}
)
, ( [ "Table.string"
@ -202,6 +206,7 @@ columnsWithCode =
, " , value = .lastName"
, " , width = Css.calc (Css.pct 50) Css.minus (Css.px 250)"
, " , cellStyles = always []"
, " , sort = Nothing"
, " }"
]
|> String.join "\n\t "
@ -210,6 +215,7 @@ columnsWithCode =
, value = .lastName
, width = Css.calc (Css.pct 50) Css.minus (Css.px 250)
, cellStyles = always []
, sort = Nothing
}
)
, ( [ "Table.string"
@ -217,6 +223,7 @@ columnsWithCode =
, " , value = .submitted >> String.fromInt"
, " , width = Css.px 125"
, " , cellStyles = always [ Css.textAlign Css.center ]"
, " , sort = Nothing"
, " }"
]
|> String.join "\n\t "
@ -225,6 +232,7 @@ columnsWithCode =
, value = .submitted >> String.fromInt
, width = Css.px 125
, cellStyles = \value -> [ Css.textAlign Css.center ]
, sort = Nothing
}
)
, ( [ "Table.custom"
@ -232,6 +240,7 @@ columnsWithCode =
, " , width = Css.px 250"
, " , view = \\_ -> Button.button \"Action\" [ Button.small ]"
, " , cellStyles = always []"
, " , sort = Nothing"
, " }"
]
|> String.join "\n\t "
@ -240,6 +249,7 @@ columnsWithCode =
, width = Css.px 250
, view = \_ -> Button.button "Action" [ Button.small, Button.onClick (ConsoleLog "Clicked button!") ]
, cellStyles = always []
, sort = Nothing
}
)
]

View File

@ -15,7 +15,7 @@ import Debug.Control.View as ControlView
import Example exposing (Example)
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes exposing (css)
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Text.V6 as Text
@ -82,8 +82,8 @@ example =
, toExampleCode "ugSmallBody"
]
}
, Heading.h2 [] [ Html.text "Examples" ]
, Heading.h3 [] [ Html.text "Paragraph styles" ]
, Heading.h2 [ Heading.plaintext "Examples" ]
, Heading.h3 [ Heading.plaintext "Paragraph styles" ]
, viewExamples
[ ( "mediumBody", Text.mediumBody )
, ( "smallBody", Text.smallBody )
@ -91,7 +91,7 @@ example =
, ( "caption", Text.caption )
]
attributes
, Heading.h3 [] [ Html.text "Paragraph styles for user-authored content" ]
, Heading.h3 [ Heading.plaintext "Paragraph styles for user-authored content" ]
, viewExamples
[ ( "ugMediumBody", Text.ugMediumBody )
, ( "ugSmallBody", Text.ugSmallBody )

View File

@ -14,7 +14,7 @@ import Html.Styled as Html
import Html.Styled.Attributes as Attributes exposing (css)
import Nri.Ui.Checkbox.V6 as Checkbox
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.InputStyles.V3 as InputStyles exposing (Theme(..))
import Nri.Ui.TextArea.V4 as TextArea
@ -71,7 +71,7 @@ example =
]
, view =
\ellieLinkConfig state ->
[ Heading.h1 [] [ Html.text "Textarea controls" ]
[ Heading.h1 [ Heading.plaintext "Textarea controls" ]
, Html.div []
[ Checkbox.viewWithLabel
{ identifier = "show-textarea-label"

View File

@ -6,7 +6,7 @@ module Examples.TextInput exposing (Msg, State, example)
-}
import Accessibility.Styled as Html exposing (..)
import Accessibility.Styled exposing (..)
import Accessibility.Styled.Key as Key
import Category exposing (Category(..))
import Css
@ -16,7 +16,7 @@ import Debug.Control.View as ControlView
import Dict exposing (Dict)
import Example exposing (Example)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.TextInput.V7 as TextInput
import ViewHelpers exposing (viewExamples)
@ -62,7 +62,7 @@ example =
, extraImports = []
, toExampleCode = \_ -> []
}
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "Example" ]
, Heading.h2 [ Heading.plaintext "Example" ]
, viewExamples <|
( "readOnlyText"
, TextInput.view "Shareable Assignment Link"
@ -165,6 +165,78 @@ customizableExamples state =
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
, toExample
{ name = "givenName"
, toString = identity
, inputType = TextInput.givenName
, onFocus = "Focused!!!"
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
, toExample
{ name = "familyName"
, toString = identity
, inputType = TextInput.familyName
, onFocus = "Focused!!!"
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
, toExample
{ name = "organization"
, toString = identity
, inputType = TextInput.organization
, onFocus = "Focused!!!"
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
, toExample
{ name = "organizationTitle"
, toString = identity
, inputType = TextInput.organizationTitle
, onFocus = "Focused!!!"
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
, toExample
{ name = "addressLine1"
, toString = identity
, inputType = TextInput.addressLine1
, onFocus = "Focused!!!"
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
, toExample
{ name = "addressLevel2"
, toString = identity
, inputType = TextInput.addressLevel2
, onFocus = "Focused!!!"
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
, toExample
{ name = "postalCode"
, toString = identity
, inputType = TextInput.postalCode
, onFocus = "Focused!!!"
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
, toExample
{ name = "tel"
, toString = identity
, inputType = TextInput.tel
, onFocus = "Focused!!!"
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
, toExample
{ name = "sex"
, toString = identity
, inputType = TextInput.sex
, onFocus = "Focused!!!"
, onBlur = "Blurred!!!"
, onEnter = "Entered!!!"
}
]

View File

@ -22,9 +22,9 @@ import Markdown
import Nri.Ui.ClickableSvg.V2 as ClickableSvg
import Nri.Ui.ClickableText.V3 as ClickableText
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.Table.V5 as Table
import Nri.Ui.Table.V6 as Table
import Nri.Ui.Tooltip.V3 as Tooltip
import Nri.Ui.UiIcon.V1 as UiIcon
@ -134,31 +134,35 @@ update msg model =
view : EllieLink.Config -> State -> List (Html Msg)
view ellieLinkConfig model =
[ viewCustomizableExample ellieLinkConfig model.staticExampleSettings
, Heading.h2 [ Heading.style Heading.Subhead ] [ Html.text "What type of tooltip should I use?" ]
, Heading.h2 [ Heading.plaintext "What type of tooltip should I use?" ]
, Table.view
[ Table.string
{ header = "Type"
, value = .name
, width = Css.pct 15
, cellStyles = always [ Css.padding2 (Css.px 14) (Css.px 7), Css.verticalAlign Css.top, Css.fontWeight Css.bold ]
, sort = Nothing
}
, Table.custom
{ header = Html.text "Usage"
, view = .usage >> Markdown.toHtml Nothing >> List.map Html.fromUnstyled >> Html.span []
, width = Css.px 150
, cellStyles = always [ Css.padding2 Css.zero (Css.px 7), Css.verticalAlign Css.top ]
, sort = Nothing
}
, Table.custom
{ header = Html.text "About"
, view = .description >> Markdown.toHtml Nothing >> List.map Html.fromUnstyled >> Html.span []
, width = Css.px 200
, cellStyles = always [ Css.padding2 Css.zero (Css.px 7), Css.verticalAlign Css.top ]
, sort = Nothing
}
, Table.custom
{ header = Html.text "Example"
, view = .example
, width = Css.px 50
, cellStyles = always [ Css.textAlign Css.center ]
, sort = Nothing
}
]
[ { name = "Tooltip.primaryLabel"

View File

@ -58,6 +58,7 @@ all =
, ( "download", UiIcon.download, [] )
, ( "sort", UiIcon.sort, [] )
, ( "gear", UiIcon.gear, [] )
, ( "hamburger", UiIcon.hamburger, [] )
]
)
, ( "Archive & Unarchive"
@ -89,6 +90,7 @@ all =
, ( "Guidance"
, [ ( "footsteps", UiIcon.footsteps, [] )
, ( "help", UiIcon.help, [] )
, ( "info", UiIcon.info, [] )
, ( "checklist", UiIcon.checklist, [] )
, ( "checklistComplete", UiIcon.checklistComplete, [] )
]
@ -184,6 +186,7 @@ all =
, ( "Badges & Celebration"
, [ ( "badge", UiIcon.badge, [] )
, ( "tada", UiIcon.tada, [] )
, ( "count", UiIcon.count, [] )
]
)
, ( "Lock & Key"

View File

@ -27,6 +27,7 @@
"Nri.Ui.FocusTrap.V1",
"Nri.Ui.Fonts.V1",
"Nri.Ui.Heading.V2",
"Nri.Ui.Heading.V3",
"Nri.Ui.Html.Attributes.V2",
"Nri.Ui.Html.V3",
"Nri.Ui.InputStyles.V3",
@ -47,12 +48,14 @@
"Nri.Ui.Select.V8",
"Nri.Ui.Shadows.V1",
"Nri.Ui.SideNav.V3",
"Nri.Ui.SideNav.V4",
"Nri.Ui.SortableTable.V2",
"Nri.Ui.SortableTable.V3",
"Nri.Ui.Sprite.V1",
"Nri.Ui.Svg.V1",
"Nri.Ui.Switch.V2",
"Nri.Ui.Table.V5",
"Nri.Ui.Table.V6",
"Nri.Ui.Tabs.V6",
"Nri.Ui.Tabs.V7",
"Nri.Ui.Text.V6",