From 86a0626d1511488a3d036e28cd082ae288dc5dc8 Mon Sep 17 00:00:00 2001 From: Christian Stewart Date: Mon, 23 Oct 2023 15:43:42 -0700 Subject: [PATCH 1/2] fix: make TabButton aria compliant as a button Allows using the keyboard to select tabs by pressing the Tab key to switch between elements on the page, and then pressing "enter" or space " " to select the highlighted tab. Signed-off-by: Christian Stewart --- src/view/TabButton.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/view/TabButton.tsx b/src/view/TabButton.tsx index e0f7a744..74f6dcfc 100755 --- a/src/view/TabButton.tsx +++ b/src/view/TabButton.tsx @@ -196,12 +196,23 @@ export const TabButton = (props: ITabButtonProps) => { ); } + const onKeyDown = (event: React.KeyboardEvent) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + onClick(); + } + }; + return (
Date: Fri, 3 Nov 2023 16:49:42 -0700 Subject: [PATCH 2/2] fix: make TabButton close button aria compliant as a button Make the close button on TabButton a button instead of a div. It looks identical and is aria compliant as a button, supporting screen readers and keyboard navigation with tab to select and enter or space to click. Note that a event handler for onCloseKeyDown was added to stop event propagation when pressing enter or space, so that the button's normal onClick logic is called, and the keyboard event does not propagate to the TabButton keyboard event handler. Allows using the keyboard to select the tab close button by pressing the Tab key to switch between elements on the page, and then pressing "enter" or space " " to select the highlighted button. Signed-off-by: Christian Stewart --- src/view/TabButton.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/view/TabButton.tsx b/src/view/TabButton.tsx index 74f6dcfc..6f58739c 100755 --- a/src/view/TabButton.tsx +++ b/src/view/TabButton.tsx @@ -81,7 +81,8 @@ export const TabButton = (props: ITabButtonProps) => { return false; }; - const onClose = (event: React.MouseEvent) => { + const onClose = (event: React.MouseEvent) => { + event.preventDefault(); if (isClosable()) { layout.doAction(Actions.deleteTab(node.getId())); } else { @@ -89,7 +90,11 @@ export const TabButton = (props: ITabButtonProps) => { } }; - const onCloseMouseDown = (event: React.MouseEvent | React.TouchEvent) => { + const onCloseMouseDown = (event: React.MouseEvent | React.TouchEvent) => { + event.stopPropagation(); + }; + + const onCloseKeyDown = (event: React.KeyboardEvent) => { event.stopPropagation(); }; @@ -183,16 +188,17 @@ export const TabButton = (props: ITabButtonProps) => { if (node.isEnableClose() && !isStretch) { const closeTitle = layout.i18nName(I18nLabel.Close_Tab); renderState.buttons.push( -
+ onTouchStart={onCloseMouseDown} + onKeyDown={onCloseKeyDown}> {(typeof icons.close === "function") ? icons.close(node) : icons.close} -
+ ); }