Cp breadcrumbs v1 to v2

This commit is contained in:
Tessa Kelly 2022-09-13 09:47:31 -06:00
parent ce819c4cc8
commit fba1e236b1
7 changed files with 381 additions and 3 deletions

View File

@ -1,2 +1,3 @@
Nri.Ui.BreadCrumbs.V1,upgrade to V2
Nri.Ui.Checkbox.V5,upgrade to V6
Nri.Ui.Tabs.V6,upgrade to V7

1 Nri.Ui.Checkbox.V5 Nri.Ui.BreadCrumbs.V1 upgrade to V6 upgrade to V2
1 Nri.Ui.BreadCrumbs.V1 upgrade to V2
2 Nri.Ui.Checkbox.V5 Nri.Ui.Checkbox.V5 upgrade to V6 upgrade to V6
3 Nri.Ui.Tabs.V6 Nri.Ui.Tabs.V6 upgrade to V7 upgrade to V7

View File

@ -12,6 +12,7 @@
"Nri.Ui.AssignmentIcon.V2",
"Nri.Ui.Balloon.V1",
"Nri.Ui.BreadCrumbs.V1",
"Nri.Ui.BreadCrumbs.V2",
"Nri.Ui.Button.V10",
"Nri.Ui.Carousel.V1",
"Nri.Ui.Checkbox.V5",

View File

@ -38,6 +38,9 @@ usages = ['styleguide-app/../src/Nri/Ui/Button/V8.elm']
[forbidden."Nri.Ui.Accordion.V1"]
hint = 'upgrade to V3'
[forbidden."Nri.Ui.BreadCrumbs.V1"]
hint = 'upgrade to V2'
[forbidden."Nri.Ui.Button.V8"]
hint = 'upgrade to V10'
usages = ['styleguide-app/../src/Nri/Ui/SlideModal/V2.elm']

View File

@ -0,0 +1,372 @@
module Nri.Ui.BreadCrumbs.V2 exposing
( view, IconStyle(..)
, BreadCrumbs, init
, BreadCrumb, after
, headerId
, toPageTitle, toPageTitleWithSecondaryBreadCrumbs
)
{-| Learn more about 'breadcrumbs' to help a user orient themselves within a site here: <https://www.w3.org/WAI/WCAG21/Techniques/general/G65>.
Wide Viewport (with Circled IconStyle):
Home
🏠 Home > 🟠 Category 1
🏠 > 🟠 Category 1 > 🟣 Sub-Category 2
Narrow Viewport (with Circled IconStyle):
Home
🏠 > 🟠 Category 1
🏠 > 🟠 > 🟣 Sub-Category 2
@docs view, IconStyle
@docs BreadCrumbs, init
@docs BreadCrumb, after
@docs headerId
@docs toPageTitle, toPageTitleWithSecondaryBreadCrumbs
-}
import Accessibility.Styled exposing (..)
import Accessibility.Styled.Aria as Aria
import Accessibility.Styled.Style as Style
import Css exposing (..)
import Css.Global
import Css.Media as Media
import Html.Styled
import Html.Styled.Attributes as Attributes exposing (css)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.MediaQuery.V1 as MediaQuery
import Nri.Ui.Svg.V1 as Svg
import Nri.Ui.UiIcon.V1 as UiIcon
{-| -}
type alias BreadCrumb route =
{ icon : Maybe Svg.Svg
, iconStyle : IconStyle
, id : String
, text : String
, route : route
}
{-| -}
type BreadCrumbs route
= BreadCrumbs (List (BreadCrumb route))
{-| -}
init : BreadCrumb route -> BreadCrumbs route
init breadCrumb =
BreadCrumbs [ breadCrumb ]
{-| -}
after : BreadCrumbs route -> BreadCrumb route -> BreadCrumbs route
after (BreadCrumbs previous) new =
BreadCrumbs (new :: previous)
{-| -}
headerId : BreadCrumbs route -> String
headerId (BreadCrumbs list) =
case list of
{ id } :: _ ->
id
_ ->
-- It should be impossible to construct a BreadCrumbs without
-- any elements.
--
""
{-| -}
type IconStyle
= Circled
| Default
{-| Generate an HTML page title using the breadcrumbs,
in the form "Sub-Category | Category | NoRedInk" for breadCrumbs like:
Category > Sub - Category
-}
toPageTitle : BreadCrumbs a -> String
toPageTitle (BreadCrumbs breadcrumbs) =
String.join " | " (List.map .text breadcrumbs ++ [ "NoRedInk" ])
{-| -}
toPageTitleWithSecondaryBreadCrumbs : BreadCrumbs a -> String
toPageTitleWithSecondaryBreadCrumbs (BreadCrumbs breadcrumbs) =
(List.take 1 breadcrumbs |> List.map .text)
++ [ "NoRedInk" ]
|> String.join " | "
{-| Usually, the label value will be the string "breadcrumbs".
It's configurable so that if more than one set of BreadCrumbs ever appear on the page, the aria-label for the nav can still be unique.
-}
view :
{ aTagAttributes : route -> List (Attribute msg)
, isCurrentRoute : route -> Bool
, label : String
}
-> BreadCrumbs route
-> Html msg
view config (BreadCrumbs breadCrumbs) =
styled nav
[ alignItems center
, displayFlex
, Media.withMedia [ MediaQuery.mobile ] [ marginBottom (px 10) ]
]
[ Aria.label config.label ]
(viewBreadCrumbs config (List.reverse breadCrumbs))
viewBreadCrumbs :
{ config
| aTagAttributes : route -> List (Attribute msg)
, isCurrentRoute : route -> Bool
}
-> List (BreadCrumb route)
-> List (Html msg)
viewBreadCrumbs config breadCrumbs =
let
breadCrumbCount : Int
breadCrumbCount =
List.length breadCrumbs
in
List.indexedMap
(\i ->
viewBreadCrumb config
{ isFirst = i == 0
, isLast = (i + 1) == breadCrumbCount
, isIconOnly =
-- the first breadcrumb should collapse when there
-- are 3 breadcrumbs or more
--
-- Hypothetically, if there were 4 breadcrumbs, then the
-- first 2 breadcrumbs should collapse
(breadCrumbCount - i) > 2
}
)
breadCrumbs
|> List.intersperse (Svg.toHtml arrowRight)
viewBreadCrumb :
{ config
| aTagAttributes : route -> List (Attribute msg)
, isCurrentRoute : route -> Bool
}
-> { isFirst : Bool, isLast : Bool, isIconOnly : Bool }
-> BreadCrumb route
-> Html msg
viewBreadCrumb config iconConfig crumb =
let
isLink =
not (config.isCurrentRoute crumb.route)
linkAttrs =
if isLink then
css
[ hover
[ Css.Global.descendants
[ Css.Global.class circleIconClass
[ backgroundColor Colors.glacier
, borderColor Colors.azureDark
, color Colors.azure
]
]
]
]
:: config.aTagAttributes crumb.route
else
[]
withIconIfPresent viewIcon =
case crumb.icon of
Just icon ->
[ viewIcon iconConfig.isFirst crumb.iconStyle icon
, viewHeadingWithIcon iconConfig crumb.text
]
Nothing ->
[ text crumb.text ]
in
case ( iconConfig.isLast, isLink ) of
( True, False ) ->
pageHeader crumb.id
(withIconIfPresent viewIconForHeading)
( True, True ) ->
pageHeader crumb.id
[ Html.Styled.styled Html.Styled.a
[]
(css commonCss :: linkAttrs)
(withIconIfPresent viewIconForLink)
]
( False, _ ) ->
Html.Styled.styled Html.Styled.a
[ fontWeight normal ]
(css commonCss :: Attributes.id crumb.id :: linkAttrs)
(withIconIfPresent viewIconForLink)
pageHeader : String -> List (Html msg) -> Html msg
pageHeader id =
styled h1
[ fontWeight bold ]
[ Aria.currentPage
, Attributes.id id
, Attributes.tabindex -1
, css commonCss
]
viewIconForHeading : Bool -> IconStyle -> Svg.Svg -> Html msg
viewIconForHeading isFirst iconStyle svg =
case iconStyle of
Circled ->
text ""
Default ->
withoutIconCircle isFirst svg
viewIconForLink : Bool -> IconStyle -> Svg.Svg -> Html msg
viewIconForLink isFirst iconStyle svg =
case iconStyle of
Circled ->
withIconCircle svg
Default ->
withoutIconCircle isFirst svg
viewHeadingWithIcon : { config | isLast : Bool, isIconOnly : Bool } -> String -> Html msg
viewHeadingWithIcon { isIconOnly, isLast } title =
span
(if isIconOnly then
Style.invisible
else if isLast then
[ css [ marginLeft horizontalSpacing ] ]
else
[ css
[ marginLeft horizontalSpacing
, Media.withMedia [ MediaQuery.mobile ]
[ Style.invisibleStyle
]
]
]
)
[ text title
]
commonCss : List Style
commonCss =
[ alignItems center
, displayFlex
, margin zero
, fontSize (px 30)
, Media.withMedia [ MediaQuery.mobile ] [ fontSize (px 25) ]
, Fonts.baseFont
, textDecoration none
, color Colors.navy
]
circleIconClass : String
circleIconClass =
"Nri-BreadCrumb-base-circled-icon"
withIconCircle : Svg.Svg -> Html msg
withIconCircle icon =
styled span
[ borderRadius (pct 50)
, border3 (px 1) solid Colors.azure
, color Colors.azure
, borderBottomWidth (px 2)
, backgroundColor Colors.white
, height largeIconSize
, width largeIconSize
, fontSize (px 16)
, property "transition" "background-color 0.2s, color 0.2s"
, displayFlex
, alignItems center
, justifyContent center
]
[ Attributes.class circleIconClass ]
[ icon
|> Svg.withWidth circledInnerIconSize
|> Svg.withHeight circledInnerIconSize
|> Svg.toHtml
]
withoutIconCircle : Bool -> Svg.Svg -> Html msg
withoutIconCircle isFirst icon =
let
size =
if isFirst then
largeIconSize
else
iconSize
in
icon
|> Svg.withWidth size
|> Svg.withHeight size
|> Svg.withCss [ Css.flexShrink Css.zero ]
|> Svg.toHtml
horizontalSpacing : Css.Px
horizontalSpacing =
Css.px 10
circledInnerIconSize : Css.Px
circledInnerIconSize =
Css.px 25
largeIconSize : Css.Px
largeIconSize =
Css.px 40
iconSize : Css.Px
iconSize =
Css.px 31
arrowRight : Svg.Svg
arrowRight =
UiIcon.arrowRight
|> Svg.withColor Colors.gray75
|> Svg.withHeight (px 15)
|> Svg.withWidth (px 15)
|> Svg.withCss
[ marginRight horizontalSpacing
, marginLeft horizontalSpacing
, flexShrink zero
]

View File

@ -16,7 +16,7 @@ import Debug.Control.Extra as ControlExtra
import Debug.Control.View as ControlView
import Example exposing (Example)
import Html.Styled.Attributes exposing (css, href)
import Nri.Ui.BreadCrumbs.V1 as BreadCrumbs exposing (BreadCrumbs)
import Nri.Ui.BreadCrumbs.V2 as BreadCrumbs exposing (BreadCrumbs)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Heading.V3 as Heading
@ -37,7 +37,7 @@ moduleName =
version : Int
version =
1
2
{-| -}

View File

@ -5,7 +5,7 @@ import Category
import Dict exposing (Dict)
import Example exposing (Example)
import Html.Styled.Attributes as Attributes
import Nri.Ui.BreadCrumbs.V1 as BreadCrumbs exposing (BreadCrumb, BreadCrumbs)
import Nri.Ui.BreadCrumbs.V2 as BreadCrumbs exposing (BreadCrumb, BreadCrumbs)
import Nri.Ui.Util exposing (dashify)
import Parser exposing ((|.), (|=), Parser)
import Url exposing (Url)

View File

@ -8,6 +8,7 @@
"Nri.Ui.AssignmentIcon.V2",
"Nri.Ui.Balloon.V1",
"Nri.Ui.BreadCrumbs.V1",
"Nri.Ui.BreadCrumbs.V2",
"Nri.Ui.Button.V10",
"Nri.Ui.Carousel.V1",
"Nri.Ui.Checkbox.V5",