Skip to content

Commit b227737

Browse files
fix(Tabs): make tooltips more accessible (#6940)
* fix(Tabs): make tooltips more accessible * Add notes to examples and new props * Update snapshots * Update examples with tooltips
1 parent 94e4c09 commit b227737

File tree

3 files changed

+563
-281
lines changed

3 files changed

+563
-281
lines changed

packages/react-core/src/components/Tabs/Tab.tsx

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { OUIAProps } from '../../helpers';
44
import { TabButton } from './TabButton';
55
import { TabsContext } from './TabsContext';
66
import { css } from '@patternfly/react-styles';
7+
import { Tooltip } from '../Tooltip';
78

89
export interface TabProps extends Omit<React.HTMLProps<HTMLAnchorElement | HTMLButtonElement>, 'title'>, OUIAProps {
910
/** content rendered inside the Tab content area. */
@@ -30,6 +31,8 @@ export interface TabProps extends Omit<React.HTMLProps<HTMLAnchorElement | HTMLB
3031
inoperableEvents?: string[];
3132
/** Forwarded ref */
3233
innerRef?: React.Ref<any>;
34+
/** Optional Tooltip rendered to a Tab. Should be <Tooltip> with appropriate props for proper rendering. */
35+
tooltip?: React.ReactElement<any>;
3336
}
3437

3538
const TabBase: React.FunctionComponent<TabProps> = ({
@@ -45,6 +48,7 @@ const TabBase: React.FunctionComponent<TabProps> = ({
4548
inoperableEvents = ['onClick', 'onKeyPress'],
4649
href,
4750
innerRef,
51+
tooltip,
4852
...props
4953
}: TabProps) => {
5054
const preventedEvents = inoperableEvents.reduce(
@@ -69,31 +73,34 @@ const TabBase: React.FunctionComponent<TabProps> = ({
6973
return null;
7074
}
7175
};
72-
return (
73-
<li
74-
className={css(styles.tabsItem, eventKey === localActiveKey && styles.modifiers.current, childClassName)}
75-
ref={innerRef}
76+
77+
const tabButton = (
78+
<TabButton
79+
parentInnerRef={innerRef}
80+
className={css(
81+
styles.tabsLink,
82+
isDisabled && href && styles.modifiers.disabled,
83+
isAriaDisabled && styles.modifiers.ariaDisabled
84+
)}
85+
disabled={isButtonElement ? isDisabled : null}
86+
aria-disabled={isDisabled || isAriaDisabled}
87+
tabIndex={getDefaultTabIdx()}
88+
onClick={(event: any) => handleTabClick(event, eventKey, tabContentRef)}
89+
{...(isAriaDisabled ? preventedEvents : null)}
90+
id={`pf-tab-${eventKey}-${childId || uniqueId}`}
91+
aria-controls={ariaControls}
92+
tabContentRef={tabContentRef}
93+
ouiaId={childOuiaId}
94+
href={href}
95+
{...props}
7696
>
77-
<TabButton
78-
className={css(
79-
styles.tabsLink,
80-
isDisabled && href && styles.modifiers.disabled,
81-
isAriaDisabled && styles.modifiers.ariaDisabled
82-
)}
83-
disabled={isButtonElement ? isDisabled : null}
84-
aria-disabled={isDisabled || isAriaDisabled}
85-
tabIndex={getDefaultTabIdx()}
86-
onClick={(event: any) => handleTabClick(event, eventKey, tabContentRef)}
87-
{...(isAriaDisabled ? preventedEvents : null)}
88-
id={`pf-tab-${eventKey}-${childId || uniqueId}`}
89-
aria-controls={ariaControls}
90-
tabContentRef={tabContentRef}
91-
ouiaId={childOuiaId}
92-
href={href}
93-
{...props}
94-
>
95-
{title}
96-
</TabButton>
97+
{title}
98+
</TabButton>
99+
);
100+
101+
return (
102+
<li className={css(styles.tabsItem, eventKey === localActiveKey && styles.modifiers.current, childClassName)}>
103+
{tooltip ? <Tooltip {...tooltip.props}>{tabButton}</Tooltip> : tabButton}
97104
</li>
98105
);
99106
};

packages/react-core/src/components/Tabs/TabButton.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,23 @@ export interface TabButtonProps extends Omit<React.HTMLProps<HTMLAnchorElement |
1010
href?: string;
1111
/** child reference for case in which a TabContent section is defined outside of a Tabs component */
1212
tabContentRef?: React.Ref<any>;
13+
/** Parents' innerRef passed down for properly displaying Tooltips */
14+
parentInnerRef?: React.Ref<any>;
1315
}
1416

1517
export const TabButton: React.FunctionComponent<TabButtonProps> = ({
1618
children,
1719
// eslint-disable-next-line @typescript-eslint/no-unused-vars
1820
tabContentRef,
1921
ouiaId,
22+
parentInnerRef,
2023
ouiaSafe,
2124
...props
2225
}: TabButtonProps) => {
2326
const Component = (props.href ? 'a' : 'button') as any;
27+
2428
return (
25-
<Component {...getOUIAProps(TabButton.displayName, ouiaId, ouiaSafe)} {...props}>
29+
<Component ref={parentInnerRef} {...getOUIAProps(TabButton.displayName, ouiaId, ouiaSafe)} {...props}>
2630
{children}
2731
</Component>
2832
);

0 commit comments

Comments
 (0)