diff --git a/elm.json b/elm.json index 64eada44..87f06a41 100644 --- a/elm.json +++ b/elm.json @@ -47,6 +47,7 @@ "Nri.Ui.RadioButton.V3", "Nri.Ui.SegmentedControl.V14", "Nri.Ui.Select.V8", + "Nri.Ui.SideNav.V1", "Nri.Ui.Slide.V1", "Nri.Ui.SlideModal.V2", "Nri.Ui.SortableTable.V2", diff --git a/src/ClickableAttributes.elm b/src/ClickableAttributes.elm index f472e903..988f3342 100644 --- a/src/ClickableAttributes.elm +++ b/src/ClickableAttributes.elm @@ -23,9 +23,10 @@ import Nri.Ui.Html.Attributes.V2 as AttributeExtras exposing (targetBlank) {-| -} -type alias ClickableAttributes msg = +type alias ClickableAttributes route msg = { linkType : Link - , url : String + , url : Maybe route + , urlString : Maybe String , onClick : Maybe msg } @@ -40,58 +41,67 @@ type Link {-| -} -init : ClickableAttributes msg +init : ClickableAttributes route msg init = { linkType = Default - , url = "#" + , url = Nothing + , urlString = Nothing , onClick = Nothing } {-| -} -onClick : msg -> ClickableAttributes msg -> ClickableAttributes msg +onClick : msg -> ClickableAttributes route msg -> ClickableAttributes route msg onClick msg clickableAttributes = { clickableAttributes | onClick = Just msg } {-| -} -href : String -> ClickableAttributes msg -> ClickableAttributes msg +href : route -> ClickableAttributes route msg -> ClickableAttributes route msg href url clickableAttributes = - { clickableAttributes | url = url } + { clickableAttributes | url = Just url } {-| -} -linkSpa : String -> ClickableAttributes msg -> ClickableAttributes msg +linkSpa : route -> ClickableAttributes route msg -> ClickableAttributes route msg linkSpa url clickableAttributes = - { clickableAttributes | linkType = SinglePageApp, url = url } + { clickableAttributes | linkType = SinglePageApp, url = Just url } {-| -} -linkWithMethod : { method : String, url : String } -> ClickableAttributes msg -> ClickableAttributes msg +linkWithMethod : { method : String, url : route } -> ClickableAttributes route msg -> ClickableAttributes route msg linkWithMethod { method, url } clickableAttributes = - { clickableAttributes | linkType = WithMethod method, url = url } + { clickableAttributes | linkType = WithMethod method, url = Just url } {-| -} -linkWithTracking : { track : msg, url : String } -> ClickableAttributes msg -> ClickableAttributes msg -linkWithTracking { track, url } _ = - { linkType = WithTracking, url = url, onClick = Just track } +linkWithTracking : { track : msg, url : route } -> ClickableAttributes route msg -> ClickableAttributes route msg +linkWithTracking { track, url } clickableAttributes = + { clickableAttributes + | linkType = WithTracking + , url = Just url + , onClick = Just track + } {-| -} -linkExternal : String -> ClickableAttributes msg -> ClickableAttributes msg +linkExternal : String -> ClickableAttributes route msg -> ClickableAttributes route msg linkExternal url clickableAttributes = - { clickableAttributes | linkType = External, url = url } + { clickableAttributes | linkType = External, urlString = Just url } {-| -} -linkExternalWithTracking : { track : msg, url : String } -> ClickableAttributes msg -> ClickableAttributes msg -linkExternalWithTracking { track, url } _ = - { linkType = ExternalWithTracking, url = url, onClick = Just track } +linkExternalWithTracking : { track : msg, url : String } -> ClickableAttributes route msg -> ClickableAttributes route msg +linkExternalWithTracking { track, url } clickableAttributes = + { clickableAttributes + | linkType = ExternalWithTracking + , urlString = Just url + , onClick = Just track + } {-| -} -toButtonAttributes : ClickableAttributes msg -> List (Attribute msg) +toButtonAttributes : ClickableAttributes route msg -> List (Attribute msg) toButtonAttributes clickableAttributes = case clickableAttributes.onClick of Just handler -> @@ -102,12 +112,24 @@ toButtonAttributes clickableAttributes = {-| -} -toLinkAttributes : ClickableAttributes msg -> ( String, List (Attribute msg) ) -toLinkAttributes clickableAttributes = +toLinkAttributes : (route -> String) -> ClickableAttributes route msg -> ( String, List (Attribute msg) ) +toLinkAttributes routeToString clickableAttributes = + let + stringUrl = + case ( clickableAttributes.urlString, clickableAttributes.url ) of + ( Just url, _ ) -> + url + + ( _, Just route ) -> + routeToString route + + ( Nothing, Nothing ) -> + "#" + in case clickableAttributes.linkType of Default -> ( "link" - , [ Attributes.href clickableAttributes.url + , [ Attributes.href stringUrl , Attributes.target "_self" ] ) @@ -116,17 +138,17 @@ toLinkAttributes clickableAttributes = ( "linkSpa" , case clickableAttributes.onClick of Just handler -> - [ Attributes.href clickableAttributes.url + [ Attributes.href stringUrl , EventExtras.onClickPreventDefaultForLinkWithHref handler ] Nothing -> - [ Attributes.href clickableAttributes.url ] + [ Attributes.href stringUrl ] ) WithMethod method -> ( "linkWithMethod" - , [ Attributes.href clickableAttributes.url + , [ Attributes.href stringUrl , Attributes.attribute "data-method" method ] ) @@ -135,18 +157,18 @@ toLinkAttributes clickableAttributes = ( "linkWithTracking" , case clickableAttributes.onClick of Just track -> - [ Attributes.href clickableAttributes.url + [ Attributes.href stringUrl , Events.preventDefaultOn "click" (Json.Decode.succeed ( track, True )) ] Nothing -> - [ Attributes.href clickableAttributes.url ] + [ Attributes.href stringUrl ] ) External -> ( "linkExternal" - , Attributes.href clickableAttributes.url + , Attributes.href stringUrl :: targetBlank ) @@ -154,13 +176,13 @@ toLinkAttributes clickableAttributes = ( "linkExternalWithTracking" , case clickableAttributes.onClick of Just handler -> - [ Attributes.href clickableAttributes.url + [ Attributes.href stringUrl , Events.onClick handler , Events.on "auxclick" (Json.Decode.succeed handler) ] ++ targetBlank Nothing -> - Attributes.href clickableAttributes.url + Attributes.href stringUrl :: targetBlank ) diff --git a/src/Nri/Ui/Button/V10.elm b/src/Nri/Ui/Button/V10.elm index d499f850..24dff7d5 100644 --- a/src/Nri/Ui/Button/V10.elm +++ b/src/Nri/Ui/Button/V10.elm @@ -187,7 +187,7 @@ css styles = setClickableAttributes : - (ClickableAttributes msg -> ClickableAttributes msg) + (ClickableAttributes String msg -> ClickableAttributes String msg) -> Attribute msg setClickableAttributes apply = set @@ -467,7 +467,7 @@ type ButtonOrLink msg type alias ButtonOrLinkAttributes msg = - { clickableAttributes : ClickableAttributes msg + { clickableAttributes : ClickableAttributes String msg , size : ButtonSize , style : ColorPalette , width : ButtonWidth @@ -523,7 +523,7 @@ renderLink ((ButtonOrLink config) as link_) = getColorPalette link_ ( linkFunctionName, attributes ) = - ClickableAttributes.toLinkAttributes config.clickableAttributes + ClickableAttributes.toLinkAttributes identity config.clickableAttributes in Nri.Ui.styled Styled.a (styledName linkFunctionName) diff --git a/src/Nri/Ui/ClickableSvg/V2.elm b/src/Nri/Ui/ClickableSvg/V2.elm index fd76d617..e58f8322 100644 --- a/src/Nri/Ui/ClickableSvg/V2.elm +++ b/src/Nri/Ui/ClickableSvg/V2.elm @@ -87,7 +87,7 @@ link name icon attributes = setClickableAttributes : - (ClickableAttributes msg -> ClickableAttributes msg) + (ClickableAttributes String msg -> ClickableAttributes String msg) -> Attribute msg setClickableAttributes apply = set @@ -384,7 +384,7 @@ type ButtonOrLink msg type alias ButtonOrLinkAttributes msg = - { clickableAttributes : ClickableAttributes msg + { clickableAttributes : ClickableAttributes String msg , label : String , icon : Svg , disabled : Bool @@ -435,7 +435,7 @@ renderLink : ButtonOrLink msg -> Html msg renderLink ((ButtonOrLink config) as link_) = let ( linkFunctionName, extraAttrs ) = - ClickableAttributes.toLinkAttributes config.clickableAttributes + ClickableAttributes.toLinkAttributes identity config.clickableAttributes theme = if config.disabled then diff --git a/src/Nri/Ui/ClickableText/V3.elm b/src/Nri/Ui/ClickableText/V3.elm index 2dcb23e0..620662a9 100644 --- a/src/Nri/Ui/ClickableText/V3.elm +++ b/src/Nri/Ui/ClickableText/V3.elm @@ -178,7 +178,7 @@ css styles = setClickableAttributes : - (ClickableAttributes msg -> ClickableAttributes msg) + (ClickableAttributes String msg -> ClickableAttributes String msg) -> Attribute msg setClickableAttributes apply = set @@ -269,7 +269,7 @@ link label_ attributes = |> List.foldl (\(Attribute attribute) l -> attribute l) defaults ( name, clickableAttributes ) = - ClickableAttributes.toLinkAttributes config.clickableAttributes + ClickableAttributes.toLinkAttributes identity config.clickableAttributes in Nri.Ui.styled Html.a (dataDescriptor name) @@ -366,7 +366,7 @@ dataDescriptor descriptor = type alias ClickableTextAttributes msg = - { clickableAttributes : ClickableAttributes msg + { clickableAttributes : ClickableAttributes String msg , label : String , size : Size , icon : Maybe Svg diff --git a/src/Nri/Ui/SideNav/V1.elm b/src/Nri/Ui/SideNav/V1.elm new file mode 100644 index 00000000..bd7f0884 --- /dev/null +++ b/src/Nri/Ui/SideNav/V1.elm @@ -0,0 +1,462 @@ +module Nri.Ui.SideNav.V1 exposing + ( view, Config + , entry, entryWithChildren, html, Entry + , icon, custom, css, nriDescription, testId, id + , onClick + , href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking + , primary, secondary + , premiumLevel + ) + +{-| + +@docs view, Config +@docs entry, entryWithChildren, html, Entry +@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 premiumLevel + +-} + +import Accessibility.Styled exposing (..) +import ClickableAttributes exposing (ClickableAttributes) +import Css exposing (..) +import Css.Media as Media +import Html.Styled +import Html.Styled.Attributes as Attributes exposing (css) +import Html.Styled.Events as Events +import Nri.Ui +import Nri.Ui.ClickableText.V3 as ClickableText +import Nri.Ui.Colors.V1 as Colors +import Nri.Ui.Data.PremiumLevel as PremiumLevel exposing (PremiumLevel) +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.Svg.V1 as Svg exposing (Svg) +import Nri.Ui.UiIcon.V1 as UiIcon +import String exposing (toLower) +import String.Extra exposing (dasherize) + + +{-| 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 = + { userPremiumLevel : PremiumLevel + , isCurrentRoute : route -> Bool + , routeToString : route -> String + , onSkipNav : msg + , css : List Style + } + + +{-| -} +view : Config route msg -> List (Entry route msg) -> Html msg +view config entries = + styled nav + [ flexBasis (px 250) + , flexShrink (num 0) + , borderRadius (px 8) + , backgroundColor Colors.gray96 + , padding (px 20) + , marginRight (px 20) + , batch config.css + ] + [] + (viewSkipLink config.onSkipNav + :: 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)" + -- TODO: use Accessibility.Styled.Style.invisibleStyle + -- when we're on a higher version of tesk9/accessible-html-with-css + -- than 2.2.1 + [ Css.property "clip" "rect(1px, 1px, 1px, 1px)" + , Css.position Css.absolute + , Css.height (Css.px 1) + , Css.width (Css.px 1) + , Css.overflow Css.hidden + , Css.margin (Css.px -1) + , Css.padding Css.zero + , Css.border Css.zero + ] + ] + , 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 PremiumLevel.allowedFor entryConfig.premiumLevel config.userPremiumLevel then + 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 + + else + viewLockedEntry 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 config.routeToString + 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 = + [ paddingLeft (px 20) + , paddingRight (px 20) + , height (px 45) + , 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 + , premiumLevel : PremiumLevel + , onLockedContent : Maybe msg + } + + +build : String -> EntryConfig route msg +build title = + { icon = Nothing + , title = title + , route = Nothing + , clickableAttributes = ClickableAttributes.init + , customAttributes = [] + , customStyles = [] + , premiumLevel = PremiumLevel.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_ }) + + +{-| -} +premiumLevel : PremiumLevel -> msg -> Attribute route msg +premiumLevel level ifLocked = + Attribute + (\attributes -> + { attributes + | premiumLevel = level + , 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 tag, but change the Events.onClick behavior to avoid reloading the page. + +See 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) diff --git a/styleguide-app/Main.elm b/styleguide-app/Main.elm index 17065f63..f5f1a297 100644 --- a/styleguide-app/Main.elm +++ b/styleguide-app/Main.elm @@ -4,7 +4,7 @@ import Accessibility.Styled as Html exposing (Html) import Browser exposing (Document, UrlRequest(..)) import Browser.Dom import Browser.Navigation exposing (Key) -import Category +import Category exposing (Category) import Css exposing (..) import Css.Media exposing (withMedia) import Dict exposing (Dict) @@ -16,10 +16,13 @@ import Html.Styled.Events as Events import Nri.Ui.ClickableText.V3 as ClickableText import Nri.Ui.Colors.V1 as Colors import Nri.Ui.CssVendorPrefix.V1 as VendorPrefixed +import Nri.Ui.Data.PremiumLevel as PremiumLevel import Nri.Ui.Fonts.V1 as Fonts import Nri.Ui.Heading.V2 as Heading import Nri.Ui.MediaQuery.V1 exposing (mobile, notMobile) import Nri.Ui.Page.V3 as Page +import Nri.Ui.SideNav.V1 as SideNav +import Nri.Ui.UiIcon.V1 as UiIcon import Routes as Routes exposing (Route(..)) import Sort.Set as Set exposing (Set) import Task @@ -145,7 +148,12 @@ view_ model = Routes.Doodad doodad -> case List.head (examples (\m -> m.name == doodad)) of Just example -> - Html.main_ [] + Html.main_ + [ css + [ maxWidth (Css.px 1400) + , margin auto + ] + ] [ Example.view model.previousRoute example |> Html.map (UpdateModuleStates example.name) ] @@ -182,6 +190,8 @@ withSideNav currentRoute content = [ displayFlex , withMedia [ mobile ] [ flexDirection column, alignItems stretch ] , alignItems flexStart + , maxWidth (Css.px 1400) + , margin auto ] ] [ navigation currentRoute @@ -221,92 +231,29 @@ viewPreviews containerId examples = navigation : Route -> Html Msg -navigation route = +navigation currentRoute = let - isActive category = - case route of - Routes.Category routeCategory -> - category == routeCategory - - _ -> - False - - link active hash displayName = - ClickableText.link displayName - [ ClickableText.small - , ClickableText.css - [ Css.color Colors.navy - , Css.display Css.block - , Css.padding (Css.px 8) - , Css.borderRadius (Css.px 8) - , if active then - Css.backgroundColor Colors.glacier - - else - Css.batch [] - ] - , ClickableText.href hash - ] - - navLink category = - link (isActive category) - (Routes.toString (Routes.Category category)) - (Category.forDisplay category) - - toNavLi element = - Html.li - [ css - [ margin zero - , listStyle none - , textDecoration none - ] - ] - [ element ] + categoryNavLinks : List (SideNav.Entry Route Msg) + categoryNavLinks = + List.map + (\category -> + SideNav.entry (Category.forDisplay category) + [ SideNav.href (Routes.Category category) ] + ) + Category.all in - Html.nav - [ css - [ backgroundColor Colors.gray96 - , withMedia [ notMobile ] + SideNav.view + { userPremiumLevel = PremiumLevel.Free + , isCurrentRoute = (==) currentRoute + , routeToString = Routes.toString + , onSkipNav = SkipToMainContent + , css = + [ withMedia [ notMobile ] [ VendorPrefixed.value "position" "sticky" , top (px 55) - , flexShrink zero - , borderRadius (px 8) - , marginRight (px 40) - , padding (px 20) - , flexBasis (px 200) ] ] - , attribute "aria-label" "Main Navigation" - ] - [ Html.button - [ css - [ backgroundColor transparent - , borderStyle none - , textDecoration none - , color Colors.azure - , Fonts.baseFont - , Css.marginBottom (px 20) - , Css.pseudoClass "not(:focus)" - [ Css.property "clip" "rect(1px, 1px, 1px, 1px)" - , Css.position Css.absolute - , Css.height (Css.px 1) - , Css.width (Css.px 1) - , Css.overflow Css.hidden - , Css.margin (Css.px -1) - , Css.padding Css.zero - , Css.border Css.zero - ] - ] - , Events.onClick SkipToMainContent - , id "skip" - ] - [ Html.text "Skip to main content" ] - , (link (route == Routes.All) "#/" "All" - :: List.map navLink Category.all - ) - |> List.map toNavLi - |> Html.ul - [ css [ margin zero, padding zero ] - , id "categories" - ] - ] + } + (SideNav.entry "All" [ SideNav.href Routes.All ] + :: categoryNavLinks + ) diff --git a/tests/elm-verify-examples.json b/tests/elm-verify-examples.json index 27b74fe3..c4fa36d3 100644 --- a/tests/elm-verify-examples.json +++ b/tests/elm-verify-examples.json @@ -43,6 +43,7 @@ "Nri.Ui.RadioButton.V3", "Nri.Ui.SegmentedControl.V14", "Nri.Ui.Select.V8", + "Nri.Ui.SideNav.V1", "Nri.Ui.Slide.V1", "Nri.Ui.SlideModal.V2", "Nri.Ui.SortableTable.V2",