From 0c46aa1e28b7a97d98426e5ba5b26dd583a2cf5b Mon Sep 17 00:00:00 2001 From: Tessa Kelly Date: Thu, 25 Aug 2022 16:06:57 -0700 Subject: [PATCH 1/7] Update min required accessible-html-with-css dep --- elm.json | 2 +- styleguide/elm.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/elm.json b/elm.json index c6ba1b58..9db7c214 100644 --- a/elm.json +++ b/elm.json @@ -79,7 +79,7 @@ "elm-community/string-extra": "4.0.1 <= v < 5.0.0", "pablohirafuji/elm-markdown": "2.0.5 <= v < 3.0.0", "rtfeldman/elm-css": "17.0.1 <= v < 18.0.0", - "tesk9/accessible-html-with-css": "3.1.0 <= v < 4.0.0", + "tesk9/accessible-html-with-css": "3.2.0 <= v < 4.0.0", "tesk9/palette": "3.0.1 <= v < 4.0.0" }, "test-dependencies": { diff --git a/styleguide/elm.json b/styleguide/elm.json index dea96987..cc57ebca 100644 --- a/styleguide/elm.json +++ b/styleguide/elm.json @@ -25,7 +25,7 @@ "pablohirafuji/elm-markdown": "2.0.5", "rtfeldman/elm-css": "17.0.5", "rtfeldman/elm-sorter-experiment": "2.1.1", - "tesk9/accessible-html-with-css": "3.1.0", + "tesk9/accessible-html-with-css": "3.2.0", "tesk9/palette": "3.0.1", "wernerdegroot/listzipper": "4.0.0" }, From a4885f4643894a1a9d146fa7c9c761df28b5847c Mon Sep 17 00:00:00 2001 From: Tessa Kelly Date: Thu, 25 Aug 2022 16:07:09 -0700 Subject: [PATCH 2/7] Use onKeyDownPreventDefault for Menu --- src/Nri/Ui/Menu/V3.elm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nri/Ui/Menu/V3.elm b/src/Nri/Ui/Menu/V3.elm index f17251c1..bf2a0def 100644 --- a/src/Nri/Ui/Menu/V3.elm +++ b/src/Nri/Ui/Menu/V3.elm @@ -446,7 +446,7 @@ viewCustom config = in div (Attributes.id (config.buttonId ++ "__container") - :: Key.onKeyDown + :: Key.onKeyDownPreventDefault (Key.escape (config.focusAndToggle { isOpen = False @@ -540,7 +540,7 @@ viewCustom config = -- as long as it's not a Disclosed case ( config.purpose, maybeFirstFocusableElementId, maybeLastFocusableElementId ) of ( NavMenu, Just firstFocusableElementId, Just lastFocusableElementId ) -> - onKeyDownPreventDefault + Key.onKeyDownPreventDefault [ Key.down (config.focusAndToggle { isOpen = True From e4b498fb8059e732593789ec22d06b70ac7c24c8 Mon Sep 17 00:00:00 2001 From: Tessa Kelly Date: Thu, 25 Aug 2022 16:23:43 -0700 Subject: [PATCH 3/7] Use onKeyUpPreventDefault for tab key events --- src/TabsInternal/V2.elm | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/src/TabsInternal/V2.elm b/src/TabsInternal/V2.elm index 53875fe7..d5cbffd9 100644 --- a/src/TabsInternal/V2.elm +++ b/src/TabsInternal/V2.elm @@ -11,6 +11,7 @@ module TabsInternal.V2 exposing -} import Accessibility.Styled.Aria as Aria +import Accessibility.Styled.Key as Key import Accessibility.Styled.Role as Role import Css import EventExtras @@ -138,8 +139,7 @@ viewTab_ config index tab = , Aria.selected isSelected , Role.tab , Attributes.id (tabToId tab.idString) - , Events.on "keyup" <| - Json.Decode.andThen (keyEvents config tab) Events.keyCode + , Key.onKeyUpPreventDefault (keyEvents config tab) ] ++ (case tab.labelledBy of Nothing -> @@ -178,8 +178,8 @@ viewTab_ config index tab = ) -keyEvents : Config id msg -> Tab id msg -> Int -> Json.Decode.Decoder msg -keyEvents { focusAndSelect, tabs } thisTab keyCode = +keyEvents : Config id msg -> Tab id msg -> List (Json.Decode.Decoder msg) +keyEvents { focusAndSelect, tabs } thisTab = let findAdjacentTab tab acc = case acc of @@ -206,27 +206,10 @@ keyEvents { focusAndSelect, tabs } thisTab keyCode = List.foldr findAdjacentTab ( False, Nothing ) tabs |> Tuple.second in - case keyCode of - 39 -> - -- Right - case nextTab of - Just next -> - Json.Decode.succeed (focusAndSelect next) - - Nothing -> - Json.Decode.fail "No next tab" - - 37 -> - -- Left - case previousTab of - Just previous -> - Json.Decode.succeed (focusAndSelect previous) - - Nothing -> - Json.Decode.fail "No previous tab" - - _ -> - Json.Decode.fail "Upsupported key event" + [ Maybe.map (Key.right << focusAndSelect) nextTab + , Maybe.map (Key.left << focusAndSelect) previousTab + ] + |> List.filterMap identity viewTabPanels : Config id msg -> Html msg From 46ed6ce18de5b1fc077e05dcdb451c68a3004df3 Mon Sep 17 00:00:00 2001 From: Tessa Kelly Date: Thu, 25 Aug 2022 16:26:37 -0700 Subject: [PATCH 4/7] Pre-filter out disabled tabs --- src/TabsInternal/V2.elm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/TabsInternal/V2.elm b/src/TabsInternal/V2.elm index d5cbffd9..0293e670 100644 --- a/src/TabsInternal/V2.elm +++ b/src/TabsInternal/V2.elm @@ -188,22 +188,21 @@ keyEvents { focusAndSelect, tabs } thisTab = ( True, Nothing ) -> ( True - , if tab.disabled then - Nothing - - else - Just { select = tab.id, focus = Just (tabToId tab.idString) } + , Just { select = tab.id, focus = Just (tabToId tab.idString) } ) ( False, Nothing ) -> ( tab.id == thisTab.id, Nothing ) + nonDisabledTabs = + List.filter (not << .disabled) tabs + nextTab = - List.foldl findAdjacentTab ( False, Nothing ) tabs + List.foldl findAdjacentTab ( False, Nothing ) nonDisabledTabs |> Tuple.second previousTab = - List.foldr findAdjacentTab ( False, Nothing ) tabs + List.foldr findAdjacentTab ( False, Nothing ) nonDisabledTabs |> Tuple.second in [ Maybe.map (Key.right << focusAndSelect) nextTab From 4436e8db71d8c7d58a0ed00854d651b89d027135 Mon Sep 17 00:00:00 2001 From: Tessa Kelly Date: Thu, 25 Aug 2022 16:28:29 -0700 Subject: [PATCH 5/7] :art: refactor tab logic to be simpler -- and to allow for a different starting condition --- src/TabsInternal/V2.elm | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/TabsInternal/V2.elm b/src/TabsInternal/V2.elm index 0293e670..0f25cb19 100644 --- a/src/TabsInternal/V2.elm +++ b/src/TabsInternal/V2.elm @@ -181,18 +181,14 @@ viewTab_ config index tab = keyEvents : Config id msg -> Tab id msg -> List (Json.Decode.Decoder msg) keyEvents { focusAndSelect, tabs } thisTab = let - findAdjacentTab tab acc = - case acc of - ( _, Just _ ) -> - acc + findAdjacentTab tab ( isAdjacentTab, acc ) = + if isAdjacentTab then + ( False + , Just { select = tab.id, focus = Just (tabToId tab.idString) } + ) - ( True, Nothing ) -> - ( True - , Just { select = tab.id, focus = Just (tabToId tab.idString) } - ) - - ( False, Nothing ) -> - ( tab.id == thisTab.id, Nothing ) + else + ( tab.id == thisTab.id, acc ) nonDisabledTabs = List.filter (not << .disabled) tabs From 6f2c3d1550b3726446937428c0c6cde6c4c30cab Mon Sep 17 00:00:00 2001 From: Tessa Kelly Date: Thu, 25 Aug 2022 16:31:05 -0700 Subject: [PATCH 6/7] :art: add types and simplify mapping --- src/TabsInternal/V2.elm | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/TabsInternal/V2.elm b/src/TabsInternal/V2.elm index 0f25cb19..00540627 100644 --- a/src/TabsInternal/V2.elm +++ b/src/TabsInternal/V2.elm @@ -181,30 +181,36 @@ viewTab_ config index tab = keyEvents : Config id msg -> Tab id msg -> List (Json.Decode.Decoder msg) keyEvents { focusAndSelect, tabs } thisTab = let + onFocus : Tab id msg -> msg + onFocus tab = + focusAndSelect { select = tab.id, focus = Just (tabToId tab.idString) } + + findAdjacentTab : Tab id msg -> ( Bool, Maybe msg ) -> ( Bool, Maybe msg ) findAdjacentTab tab ( isAdjacentTab, acc ) = if isAdjacentTab then - ( False - , Just { select = tab.id, focus = Just (tabToId tab.idString) } - ) + ( False, Just (onFocus tab) ) else ( tab.id == thisTab.id, acc ) - nonDisabledTabs = + activeTabs : List (Tab id msg) + activeTabs = List.filter (not << .disabled) tabs - nextTab = - List.foldl findAdjacentTab ( False, Nothing ) nonDisabledTabs + goToNextTab : Maybe msg + goToNextTab = + List.foldl findAdjacentTab ( False, Nothing ) activeTabs |> Tuple.second - previousTab = - List.foldr findAdjacentTab ( False, Nothing ) nonDisabledTabs + goToPreviousTab : Maybe msg + goToPreviousTab = + List.foldr findAdjacentTab ( False, Nothing ) activeTabs |> Tuple.second in - [ Maybe.map (Key.right << focusAndSelect) nextTab - , Maybe.map (Key.left << focusAndSelect) previousTab - ] - |> List.filterMap identity + List.filterMap identity + [ Maybe.map Key.right goToNextTab + , Maybe.map Key.left goToPreviousTab + ] viewTabPanels : Config id msg -> Html msg From 34e4b553ba164be28a98a397444f8649090ea739 Mon Sep 17 00:00:00 2001 From: Tessa Kelly Date: Thu, 25 Aug 2022 16:33:50 -0700 Subject: [PATCH 7/7] Wrap selections --- src/TabsInternal/V2.elm | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/TabsInternal/V2.elm b/src/TabsInternal/V2.elm index 00540627..358be113 100644 --- a/src/TabsInternal/V2.elm +++ b/src/TabsInternal/V2.elm @@ -199,12 +199,22 @@ keyEvents { focusAndSelect, tabs } thisTab = goToNextTab : Maybe msg goToNextTab = - List.foldl findAdjacentTab ( False, Nothing ) activeTabs + List.foldl findAdjacentTab + ( False + , -- if there is no adjacent tab, default to the first tab + Maybe.map onFocus (List.head activeTabs) + ) + activeTabs |> Tuple.second goToPreviousTab : Maybe msg goToPreviousTab = - List.foldr findAdjacentTab ( False, Nothing ) activeTabs + List.foldr findAdjacentTab + ( False + , -- if there is no adjacent tab, default to the last tab + Maybe.map onFocus (List.head (List.reverse activeTabs)) + ) + activeTabs |> Tuple.second in List.filterMap identity