From 8876c5be328dfb3378fa584e2554775a8c9bcd2d Mon Sep 17 00:00:00 2001 From: Tessa Kelly Date: Fri, 3 Dec 2021 11:10:15 -0800 Subject: [PATCH] Generalize ClickableAttributes to improve the routing links --- src/ClickableAttributes.elm | 63 ++++++++++++++++++--------------- src/Nri/Ui/Button/V10.elm | 6 ++-- src/Nri/Ui/ClickableSvg/V2.elm | 6 ++-- src/Nri/Ui/ClickableText/V3.elm | 6 ++-- src/Nri/Ui/SideNav/V1.elm | 20 ++++++----- styleguide-app/Main.elm | 8 +++-- 6 files changed, 59 insertions(+), 50 deletions(-) diff --git a/src/ClickableAttributes.elm b/src/ClickableAttributes.elm index f472e903..3cc22907 100644 --- a/src/ClickableAttributes.elm +++ b/src/ClickableAttributes.elm @@ -23,9 +23,9 @@ 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 , onClick : Maybe msg } @@ -40,58 +40,58 @@ type Link {-| -} -init : ClickableAttributes msg +init : ClickableAttributes route msg init = { linkType = Default - , url = "#" + , url = 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 : msg, url : route } -> ClickableAttributes route msg -> ClickableAttributes route msg linkWithTracking { track, url } _ = - { linkType = WithTracking, url = url, onClick = Just track } + { linkType = WithTracking, url = Just url, onClick = Just track } {-| -} -linkExternal : String -> ClickableAttributes msg -> ClickableAttributes msg +linkExternal : route -> ClickableAttributes route msg -> ClickableAttributes route msg linkExternal url clickableAttributes = - { clickableAttributes | linkType = External, url = url } + { clickableAttributes | linkType = External, url = Just url } {-| -} -linkExternalWithTracking : { track : msg, url : String } -> ClickableAttributes msg -> ClickableAttributes msg +linkExternalWithTracking : { track : msg, url : route } -> ClickableAttributes route msg -> ClickableAttributes route msg linkExternalWithTracking { track, url } _ = - { linkType = ExternalWithTracking, url = url, onClick = Just track } + { linkType = ExternalWithTracking, url = 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 +102,17 @@ 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 = + Maybe.map routeToString clickableAttributes.url + |> Maybe.withDefault "#" + in case clickableAttributes.linkType of Default -> ( "link" - , [ Attributes.href clickableAttributes.url + , [ Attributes.href stringUrl , Attributes.target "_self" ] ) @@ -116,17 +121,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 +140,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 +159,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 index dddb7520..ce88a456 100644 --- a/src/Nri/Ui/SideNav/V1.elm +++ b/src/Nri/Ui/SideNav/V1.elm @@ -70,6 +70,7 @@ entry title route attributes = type alias Config route msg = { userPremiumLevel : PremiumLevel , isCurrentRoute : route -> Bool + , routeToString : route -> String , onSkipNav : msg , css : List Style } @@ -157,7 +158,8 @@ viewSidebarLeaf : viewSidebarLeaf config extraStyles entryConfig = let ( linkFunctionName, attributes ) = - ClickableAttributes.toLinkAttributes entryConfig.clickableAttributes + ClickableAttributes.toLinkAttributes config.routeToString + entryConfig.clickableAttributes in Nri.Ui.styled Html.Styled.a ("Nri-Ui-SideNav-" ++ linkFunctionName) @@ -242,7 +244,7 @@ type alias EntryConfig route msg = { icon : Maybe Svg , title : String , route : route - , clickableAttributes : ClickableAttributes msg + , clickableAttributes : ClickableAttributes route msg , customAttributes : List (Html.Styled.Attribute msg) , customStyles : List Style , children : List (Entry route msg) @@ -352,7 +354,7 @@ secondary = setClickableAttributes : - (ClickableAttributes msg -> ClickableAttributes msg) + (ClickableAttributes route msg -> ClickableAttributes route msg) -> Attribute route msg setClickableAttributes apply = Attribute @@ -368,7 +370,7 @@ onClick msg = {-| -} -href : String -> Attribute route msg +href : route -> Attribute route msg href url = setClickableAttributes (ClickableAttributes.href url) @@ -380,30 +382,30 @@ This will make a normal tag, but change the Events.onClick behavior to avoid See for details on this implementation. -} -linkSpa : String -> Attribute route msg +linkSpa : route -> Attribute route msg linkSpa url = setClickableAttributes (ClickableAttributes.linkSpa url) {-| -} -linkWithMethod : { method : String, url : String } -> Attribute route msg +linkWithMethod : { method : String, url : route } -> Attribute route msg linkWithMethod config = setClickableAttributes (ClickableAttributes.linkWithMethod config) {-| -} -linkWithTracking : { track : msg, url : String } -> Attribute route msg +linkWithTracking : { track : msg, url : route } -> Attribute route msg linkWithTracking config = setClickableAttributes (ClickableAttributes.linkWithTracking config) {-| -} -linkExternal : String -> Attribute route msg +linkExternal : route -> Attribute route msg linkExternal url = setClickableAttributes (ClickableAttributes.linkExternal url) {-| -} -linkExternalWithTracking : { track : msg, url : String } -> Attribute route msg +linkExternalWithTracking : { track : msg, url : route } -> Attribute route msg linkExternalWithTracking config = setClickableAttributes (ClickableAttributes.linkExternalWithTracking config) diff --git a/styleguide-app/Main.elm b/styleguide-app/Main.elm index 4660d318..3c11ca28 100644 --- a/styleguide-app/Main.elm +++ b/styleguide-app/Main.elm @@ -232,14 +232,14 @@ navigation currentRoute = (Category.forDisplay category) (Routes.Category category) [ -- TODO: we shouldn't require manually adding the href - SideNav.href (Routes.toString (Routes.Category category)) + SideNav.href (Routes.Category category) ] navLinks : List (SideNav.Entry Route Msg) navLinks = SideNav.entry "All" Routes.All - [ SideNav.href (Routes.toString Routes.All) + [ SideNav.href Routes.All ] :: List.map toNavLinkConfig Category.all ++ [ SideNav.entry "Example of Locked Premium content" @@ -252,13 +252,15 @@ navigation currentRoute = Routes.All [ SideNav.icon UiIcon.gear , SideNav.secondary - , SideNav.linkExternal "external-link" + + --, SideNav.linkExternal "external-link" ] ] in SideNav.view { userPremiumLevel = PremiumLevel.Free , isCurrentRoute = (==) currentRoute + , routeToString = Routes.toString , onSkipNav = SkipToMainContent , css = [ withMedia [ notMobile ]