diff --git a/packages/react/src/Button/ButtonBase.tsx b/packages/react/src/Button/ButtonBase.tsx
index 6303ffc5e5c..bc2c02db9cf 100644
--- a/packages/react/src/Button/ButtonBase.tsx
+++ b/packages/react/src/Button/ButtonBase.tsx
@@ -196,11 +196,11 @@ const ButtonBase = forwardRef(
>
)}
- {loading && (
+ {loading ? (
{loadingAnnouncement}
- )}
+ ) : null}
)
}
@@ -228,7 +228,7 @@ const ButtonBase = forwardRef(
data-variant={variant}
data-label-wrap={labelWrap}
data-has-count={count !== undefined ? true : undefined}
- aria-describedby={[loadingAnnouncementID, ariaDescribedBy]
+ aria-describedby={[loading && loadingAnnouncementID, ariaDescribedBy]
.filter(descriptionID => Boolean(descriptionID))
.join(' ')}
// aria-labelledby is needed because the accessible name becomes unset when the button is in a loading state.
diff --git a/packages/react/src/Button/IconButton.features.stories.tsx b/packages/react/src/Button/IconButton.features.stories.tsx
index 75050d7c805..8175025b5b4 100644
--- a/packages/react/src/Button/IconButton.features.stories.tsx
+++ b/packages/react/src/Button/IconButton.features.stories.tsx
@@ -91,7 +91,10 @@ export const KeybindingHintOnDescription = () => (
aria-label="Notifications"
description="You have unread notifications"
keybindingHint="G+N"
+ keybindingDescription="G, N"
/>
)
-export const KeybindingHint = () =>
+export const KeybindingHint = () => (
+
+)
diff --git a/packages/react/src/Button/IconButton.tsx b/packages/react/src/Button/IconButton.tsx
index 4b86ea1bd48..dbdbf86eb54 100644
--- a/packages/react/src/Button/IconButton.tsx
+++ b/packages/react/src/Button/IconButton.tsx
@@ -22,6 +22,7 @@ const IconButton = forwardRef(
unsafeDisableTooltip = false,
keyshortcuts,
keybindingHint,
+ keybindingDescription,
className,
...props
},
@@ -67,6 +68,7 @@ const IconButton = forwardRef(
type={description ? undefined : 'label'}
direction={tooltipDirection}
keybindingHint={keybindingHint ?? keyshortcuts}
+ keybindingDescription={keybindingDescription}
>
// adopted from React.AnchorHTMLAttributes
diff --git a/packages/react/src/KeybindingHint/props.ts b/packages/react/src/KeybindingHint/props.ts
index 7df8f7ebd21..f3ca3003975 100644
--- a/packages/react/src/KeybindingHint/props.ts
+++ b/packages/react/src/KeybindingHint/props.ts
@@ -3,6 +3,8 @@ export type KeybindingHintFormat = 'condensed' | 'full'
export type KeybindingHintVariant = 'normal' | 'onEmphasis' | 'onPrimary'
export interface KeybindingHintProps {
+ description?: string
+
/**
* The keys involved in this keybinding. These should be the full names of the keys as would
* be returned by `KeyboardEvent.key` (e.g. "Control", "Shift", "ArrowUp", "a", etc.).
diff --git a/packages/react/src/TooltipV2/Tooltip.tsx b/packages/react/src/TooltipV2/Tooltip.tsx
index 2949dc434d5..28cbb8f91e6 100644
--- a/packages/react/src/TooltipV2/Tooltip.tsx
+++ b/packages/react/src/TooltipV2/Tooltip.tsx
@@ -142,6 +142,7 @@ export type TooltipProps = React.PropsWithChildren<
text: string
type?: 'label' | 'description'
keybindingHint?: KeybindingHintProps['keys']
+ keybindingDescription?: KeybindingHintProps['description']
} & SxProp
> &
React.HTMLAttributes
@@ -201,10 +202,21 @@ export const TooltipContext = React.createContext<{tooltipId?: string}>({})
export const Tooltip = React.forwardRef(
(
- {direction = 's', text, type = 'description', children, id, className, keybindingHint, ...rest}: TooltipProps,
+ {
+ direction = 's',
+ text,
+ type = 'description',
+ children,
+ id,
+ className,
+ keybindingHint,
+ keybindingDescription,
+ ...rest
+ }: TooltipProps,
forwardedRef,
) => {
const tooltipId = useId(id)
+ const controlHintId = useId()
const child = Children.only(children)
const triggerRef = useProvidedRefOrCreate(forwardedRef as React.RefObject)
const tooltipElRef = useRef(null)
@@ -355,7 +367,10 @@ export const Tooltip = React.forwardRef(
React.cloneElement(child as React.ReactElement, {
ref: triggerRef,
// If it is a type description, we use tooltip to describe the trigger
- 'aria-describedby': type === 'description' ? tooltipId : child.props['aria-describedby'],
+ 'aria-describedby':
+ type === 'description'
+ ? [tooltipId, controlHintId].join(' ')
+ : [child.props['aria-describedby'], controlHintId].filter(Boolean).join(' '),
// If it is a label type, we use tooltip to label the trigger
'aria-labelledby': type === 'label' ? tooltipId : child.props['aria-labelledby'],
onBlur: (event: React.FocusEvent) => {
@@ -400,19 +415,21 @@ export const Tooltip = React.forwardRef(
role={type === 'description' ? 'tooltip' : undefined}
// stop AT from announcing the tooltip twice: when it is a label type it will be announced with "aria-labelledby",when it is a description type it will be announced with "aria-describedby"
aria-hidden={true}
- id={tooltipId}
// mouse leave and enter on the tooltip itself is needed to keep the tooltip open when the mouse is over the tooltip
onMouseEnter={openTooltip}
onMouseLeave={closeTooltip}
>
- {text}
- {keybindingHint && (
+ {text}
+ {keybindingHint ? (
(
)
- )}
+ ) : null}
+ {keybindingDescription ? (
+ . {keybindingDescription}
+ ) : null}
>