Skip to content

Commit

Permalink
Update tabs docs (#4354)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshwooding authored Nov 20, 2024
1 parent bae6882 commit 833b54d
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 13 deletions.
4 changes: 4 additions & 0 deletions packages/lab/src/tabs-next/TabListNext.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@
.saltTabListNext-activeColorTertiary {
--saltTabListNext-activeColor: var(--salt-container-tertiary-background);
}

.saltTabListNext-overflowWarning {
display: none;
}
11 changes: 11 additions & 0 deletions packages/lab/src/tabs-next/TabListNext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
capitalize,
makePrefixer,
useForkRef,
useId,
useIsomorphicLayoutEffect,
} from "@salt-ds/core";
import { useComponentCssInjection } from "@salt-ds/styles";
Expand Down Expand Up @@ -38,6 +39,7 @@ export const TabListNext = forwardRef<HTMLDivElement, TabListNextProps>(
const {
appearance = "bordered",
activeColor = "primary",
"aria-describedby": ariaDescribedBy,
children,
className,
onKeyDown,
Expand Down Expand Up @@ -118,6 +120,8 @@ export const TabListNext = forwardRef<HTMLDivElement, TabListNextProps>(
});
}, [visible, returnFocus, targetWindow, items, selected]);

const warningId = useId();

return (
<div
role="tablist"
Expand All @@ -131,8 +135,15 @@ export const TabListNext = forwardRef<HTMLDivElement, TabListNextProps>(
data-ismeasuring={isMeasuring ? true : undefined}
ref={handleRef}
onKeyDown={handleKeyDown}
aria-describedby={clsx(ariaDescribedBy, warningId)}
{...rest}
>
{hidden.length > 0 && (
<span id={warningId} className={withBaseName("overflowWarning")}>
Note: This tab list includes overflow; tab positions may be
inaccurate or change when a tab is selected
</span>
)}
{visible}
<TabOverflowList
isMeasuring={isMeasuring}
Expand Down
8 changes: 4 additions & 4 deletions packages/lab/stories/tabs-next/tabs-next.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export const Closable: StoryFn<typeof TabsNext> = (args) => {
<TabNextAction
onClick={() => {
setTabs((old) => old.filter((tab) => tab !== label));
announce(`${label} tab has been closed`);
announce(`${label} tab has been closed`, 150);
}}
aria-label="Close tab"
>
Expand Down Expand Up @@ -322,7 +322,7 @@ export const AddTabs: StoryFn<typeof TabsNext> = (args) => {
newCount.current += 1;

setTabs((old) => old.concat(newTab));
announce(`${newTab} tab added`);
announce(`${newTab} tab added`, 150);
}}
>
<AddIcon aria-hidden />
Expand Down Expand Up @@ -430,7 +430,7 @@ export const AddWithDialog = () => {
const handleConfirm = (newTab: string) => {
setTabs((old) => old.concat(newTab));
setConfirmationOpen(false);
announce(`${newTab} tab added`);
announce(`${newTab} tab added`, 150);
};

const handleCancel = () => {
Expand Down Expand Up @@ -508,7 +508,7 @@ export const CloseWithConfirmation = () => {
const handleConfirm = () => {
setTabs((old) => old.filter((tab) => tab !== valueToRemove));
setOpen(false);
announce(`${valueToRemove} tab has been removed`);
announce(`${valueToRemove} tab has been removed`, 150);
};

const handleCancel = () => {
Expand Down
35 changes: 27 additions & 8 deletions site/docs/components/tabs/accessibility.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,43 @@ data:

Any focusable elements included in the tab content will need to be checked and tested accordingly.

## Axe false positives
## Accessibility considerations

Axe flags a few false positives that do not impact the accessibility of Tabs:
### Scrollable region must have keyboard access ([scrollable-region-focusable](https://dequeuniversity.com/rules/axe/4.9/scrollable-region-focusable))

#### Issue context

This aXe issue is flagged when tabindex="-1" is applied to the overflow menu, which is technically a scrollable region. This implementation was added to prevent an additional, unnecessary tab stop in the navigation flow due to new browser enhancements that automatically apply focus to scrollable regions. While the menu itself is not focusable, its contents remain accessible via arrow key navigation when revealed.

### Certain ARIA roles must contain particular children ([aria-required-children](https://dequeuniversity.com/rules/axe/4.9/aria-required-children))

This is flagged in two scenarios:
#### Issue context

- When an overflow menu is present. `tabIndex={-1}` is applied to the overflow menu to prevent it being tabbable.
- When `TabNextAction` is present. `TabNextAction` follows the experimental example of [Tabs with Action Buttons](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/examples/tabs-actions/) which causes the action to be a descendant of the tab list.
This aXe issue is flagged in two scenarios:

### Scrollable region must have keyboard access ([scrollable-region-focusable](https://dequeuniversity.com/rules/axe/4.9/scrollable-region-focusable))
1. When an overflow menu is present within the tab list, where tabindex="-1" is applied to prevent focus, due to new browser enhancements, ensuring users don't encounter an additional tab stop when navigating away from the tab list

- When an overflow menu is present. `tabIndex={-1}` is applied to the overflow menu to prevent it being tabbable.
2. When using nested action buttons within tabs. This example follows the W3C's experimental "Tabs with Action Buttons" example and maintains expected keyboard and screen reader interaction patterns

### ARIA attributes must conform to valid names ([aria-valid-attr](https://dequeuniversity.com/rules/axe/4.9/aria-valid-attr))

- When `TabNextAction` is present. `TabNextAction` uses [`aria-actions`](https://pr-preview.s3.amazonaws.com/w3c/aria/pull/1805.html#aria-actions) which is still in a draft state and is not recognised by Axe.
#### Issue context

This aXe issue is flagged due to the use of aria-actions, which is currently in draft status for the upcoming WAI-ARIA 1.3 release. However:

- The implementation follows the W3C's experimental "Tabs with Action Buttons" example and maintains expected keyboard and screen reader interaction patterns
- Screen readers properly announce and interact with the actions

We anticipate when the release is published and aria actions is officially supported that this will no longer be a defect. We will confirm and update this guidance after the release.

### Note for overflow example

- VoiceOver users receive inaccurate tab position information when navigating the overflow menu as it's treated as a separate tab list
- In addition, when selecting a tab in the overflow menu, that tab is visually repositioned before the tab list to ensure visibility. Due to these position issues, the following announcement is provided to screen reader users: "Note: This tab list includes overflow; tab positions may be inaccurate or change when a tab is selected"

Digital accessibility guidance continues to evolve as new design patterns and component challenges emerge. While we have worked to align with existing guidelines, some complex interactions and modern UI patterns present unique accessibility challenges that current guidelines may not fully address. We have implemented solutions that we believe create the most understandable and accessible experience possible, even when they conflict with current automated testing tools.

We welcome feedback and alternative approaches to addressing any of these accessibility considerations. If you have suggestions for improving these components, please reach out to us as we are committed to continuous accessibility improvement of our user experiences.

## Keyboard interactions

Expand Down
2 changes: 2 additions & 0 deletions site/docs/components/tabs/examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Buttons can be nested inside `TabBar` to provide related actions e.g. adding a n

- Provide enough space to display several newly added tabs before overflow is enabled.
- Set the new tab to be the active tab when it is added.
- `useAriaAnnouncer` should be used to provide feedback to screen reader users.

</LivePreview>

Expand All @@ -76,6 +77,7 @@ Buttons can be nested inside `TabBar` to provide related actions e.g. adding a n

- Don't use closable tabs for tabs that are essential to the user's workflow.
- Don't allow users to close the last tab in a tabstrip.
- `useAriaAnnouncer` should be used to provide feedback to screen reader users.

</LivePreview>

Expand Down
4 changes: 3 additions & 1 deletion site/src/examples/tabs/AddANewTab.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button } from "@salt-ds/core";
import { Button, useAriaAnnouncer } from "@salt-ds/core";
import { AddIcon } from "@salt-ds/icons";
import {
TabBar,
Expand All @@ -13,6 +13,7 @@ export const AddANewTab = (): ReactElement => {
const [tabs, setTabs] = useState(["Home", "Transactions", "Loans"]);
const [value, setValue] = useState(tabs[0]);
const newCount = useRef(0);
const { announce } = useAriaAnnouncer();

return (
<TabsNext value={value} onChange={(_event, newValue) => setValue(newValue)}>
Expand All @@ -32,6 +33,7 @@ export const AddANewTab = (): ReactElement => {
newCount.current += 1;

setTabs((old) => old.concat(newTab));
announce(`${newTab} tab added`, 150);
}}
>
<AddIcon aria-hidden />
Expand Down
4 changes: 4 additions & 0 deletions site/src/examples/tabs/ClosableTabs.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useAriaAnnouncer } from "@salt-ds/core";
import { CloseIcon } from "@salt-ds/icons";
import {
TabBar,
Expand All @@ -18,6 +19,8 @@ export const ClosableTabs = (): ReactElement => {
"Liquidity",
]);

const { announce } = useAriaAnnouncer();

return (
<TabsNext defaultValue={tabs[0]}>
<TabBar inset divider>
Expand All @@ -29,6 +32,7 @@ export const ClosableTabs = (): ReactElement => {
<TabNextAction
onClick={() => {
setTabs(tabs.filter((tab) => tab !== label));
announce(`${label} tab has been removed`, 150);
}}
aria-label="Close tab"
>
Expand Down

0 comments on commit 833b54d

Please sign in to comment.