From db741315558a2c428436969612c9bd81f75e5b36 Mon Sep 17 00:00:00 2001 From: Sarka Chwastkova Date: Thu, 5 Dec 2024 14:14:46 +0100 Subject: [PATCH] feat(Popover): add ariaLabel, ariaLabelledby props and focus state This commit adds ariaLabel and ariaLabelledby props to enhance the component's accessibility. It also updates the tabIndex value to make the Popover element focusable and readable by screen readers. --- packages/orbit-components/src/Popover/README.md | 10 ++++++++++ .../src/Popover/components/ContentWrapper.tsx | 6 ++++++ packages/orbit-components/src/Popover/index.tsx | 6 +++++- packages/orbit-components/src/Popover/types.d.ts | 2 ++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/orbit-components/src/Popover/README.md b/packages/orbit-components/src/Popover/README.md index d01b3ae34f..c3aaef9e4d 100644 --- a/packages/orbit-components/src/Popover/README.md +++ b/packages/orbit-components/src/Popover/README.md @@ -42,6 +42,8 @@ The table below contains all types of props available in the Popover component. | labelClose | `React.Node` | `Close` | The label for close button. | | renderTimeout | `number` | `0` | The timeout for rendering the Popover. | | zIndex | `number` | `710` | The zIndex value of the Popover component. | +| ariaLabel | `string` | | Optional prop for `aria-label` value. | +| ariaLabelledby | `string` | | Optional prop for `aria-labelledby` value. | ## enum @@ -110,3 +112,11 @@ The table below contains all types of props available in the Popover component. ``` + +## Accessibility + +- The `Button` component inside the `Popover` component is the most common trigger component for the opening and closing of the popover. The Popover component includes the `role="button"` attribute. Ensure that the `Button` is set as a non-interactive component to avoid the accessibility violation of nesting interactive controls (`Interactive controls must not be nested`). + +- The `ariaLabelledby` prop allows you to specify an `aria-labelledby` attribute for the popover content component. This attribute provides a reference to one or more elements that label the popover content. By using `ariaLabelledby`, the accessibility of popover component is improved and easier for users with assistive technologies to understand the context and purpose of the content. + +- The `ariaLabel` prop allows you to specify an `aria-label` attribute for the popover content component. This attribute provides additional information to screen readers, enhancing the accessibility of the component. By using `ariaLabel`, you can ensure that users who rely on assistive technologies receive the necessary context and information about the component's purpose and functionality. diff --git a/packages/orbit-components/src/Popover/components/ContentWrapper.tsx b/packages/orbit-components/src/Popover/components/ContentWrapper.tsx index 0c479f831f..08603bfc04 100644 --- a/packages/orbit-components/src/Popover/components/ContentWrapper.tsx +++ b/packages/orbit-components/src/Popover/components/ContentWrapper.tsx @@ -45,6 +45,8 @@ export interface Props extends Common.Globals { actions?: React.ReactNode; offset?: Offset; onClose: (ev?: MouseEvent | React.SyntheticEvent) => void; + ariaLabel?: string; + ariaLabelledby?: string; } const PopoverContentWrapper = ({ @@ -67,6 +69,8 @@ const PopoverContentWrapper = ({ allowOverflow, lockScrolling = true, actions, + ariaLabelledby, + ariaLabel, }: Props) => { const [actionsHeight, setActionsHeight] = React.useState(null); const { isInsideModal } = React.useContext(ModalContext); @@ -198,6 +202,8 @@ const PopoverContentWrapper = ({ shown ? "lm:opacity-100" : "lm:opacity-0", )} style={cssVars} + aria-label={ariaLabel} + aria-labelledby={ariaLabelledby} >
{ const ref = React.useRef(null); const popoverId = useRandomId(); @@ -142,6 +144,8 @@ const Popover = ({ referenceElement={ref.current} onClose={handleOut} placement={placement} + ariaLabel={ariaLabel} + ariaLabelledby={ariaLabelledby} > {content} @@ -159,7 +163,7 @@ const Popover = ({ popovertarget={id || popoverId} // according to our docs button should be used for opening popover inside children (uncontrolled behavior), // that's why this div shouldn't be focusable in order to avoid double focus - tabIndex={-1} + tabIndex={0} onClick={handleClick} onKeyDown={handleKeyDown(handleClick)} > diff --git a/packages/orbit-components/src/Popover/types.d.ts b/packages/orbit-components/src/Popover/types.d.ts index 1b5a375850..b38214745c 100644 --- a/packages/orbit-components/src/Popover/types.d.ts +++ b/packages/orbit-components/src/Popover/types.d.ts @@ -32,4 +32,6 @@ export interface Props extends Common.Globals { readonly renderInPortal?: boolean; readonly onClose?: Common.Callback; readonly zIndex?: number; + readonly ariaLabel?: string; + readonly ariaLabelledby?: string; }