Skip to content

Commit

Permalink
fix(Tabs): make tooltips more accessible (#6940)
Browse files Browse the repository at this point in the history
* fix(Tabs): make tooltips more accessible

* Add notes to examples and new props

* Update snapshots

* Update examples with tooltips
  • Loading branch information
thatblindgeye authored Mar 4, 2022
1 parent 94e4c09 commit b227737
Show file tree
Hide file tree
Showing 3 changed files with 563 additions and 281 deletions.
55 changes: 31 additions & 24 deletions packages/react-core/src/components/Tabs/Tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { OUIAProps } from '../../helpers';
import { TabButton } from './TabButton';
import { TabsContext } from './TabsContext';
import { css } from '@patternfly/react-styles';
import { Tooltip } from '../Tooltip';

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

const TabBase: React.FunctionComponent<TabProps> = ({
Expand All @@ -45,6 +48,7 @@ const TabBase: React.FunctionComponent<TabProps> = ({
inoperableEvents = ['onClick', 'onKeyPress'],
href,
innerRef,
tooltip,
...props
}: TabProps) => {
const preventedEvents = inoperableEvents.reduce(
Expand All @@ -69,31 +73,34 @@ const TabBase: React.FunctionComponent<TabProps> = ({
return null;
}
};
return (
<li
className={css(styles.tabsItem, eventKey === localActiveKey && styles.modifiers.current, childClassName)}
ref={innerRef}

const tabButton = (
<TabButton
parentInnerRef={innerRef}
className={css(
styles.tabsLink,
isDisabled && href && styles.modifiers.disabled,
isAriaDisabled && styles.modifiers.ariaDisabled
)}
disabled={isButtonElement ? isDisabled : null}
aria-disabled={isDisabled || isAriaDisabled}
tabIndex={getDefaultTabIdx()}
onClick={(event: any) => handleTabClick(event, eventKey, tabContentRef)}
{...(isAriaDisabled ? preventedEvents : null)}
id={`pf-tab-${eventKey}-${childId || uniqueId}`}
aria-controls={ariaControls}
tabContentRef={tabContentRef}
ouiaId={childOuiaId}
href={href}
{...props}
>
<TabButton
className={css(
styles.tabsLink,
isDisabled && href && styles.modifiers.disabled,
isAriaDisabled && styles.modifiers.ariaDisabled
)}
disabled={isButtonElement ? isDisabled : null}
aria-disabled={isDisabled || isAriaDisabled}
tabIndex={getDefaultTabIdx()}
onClick={(event: any) => handleTabClick(event, eventKey, tabContentRef)}
{...(isAriaDisabled ? preventedEvents : null)}
id={`pf-tab-${eventKey}-${childId || uniqueId}`}
aria-controls={ariaControls}
tabContentRef={tabContentRef}
ouiaId={childOuiaId}
href={href}
{...props}
>
{title}
</TabButton>
{title}
</TabButton>
);

return (
<li className={css(styles.tabsItem, eventKey === localActiveKey && styles.modifiers.current, childClassName)}>
{tooltip ? <Tooltip {...tooltip.props}>{tabButton}</Tooltip> : tabButton}
</li>
);
};
Expand Down
6 changes: 5 additions & 1 deletion packages/react-core/src/components/Tabs/TabButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,23 @@ export interface TabButtonProps extends Omit<React.HTMLProps<HTMLAnchorElement |
href?: string;
/** child reference for case in which a TabContent section is defined outside of a Tabs component */
tabContentRef?: React.Ref<any>;
/** Parents' innerRef passed down for properly displaying Tooltips */
parentInnerRef?: React.Ref<any>;
}

export const TabButton: React.FunctionComponent<TabButtonProps> = ({
children,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
tabContentRef,
ouiaId,
parentInnerRef,
ouiaSafe,
...props
}: TabButtonProps) => {
const Component = (props.href ? 'a' : 'button') as any;

return (
<Component {...getOUIAProps(TabButton.displayName, ouiaId, ouiaSafe)} {...props}>
<Component ref={parentInnerRef} {...getOUIAProps(TabButton.displayName, ouiaId, ouiaSafe)} {...props}>
{children}
</Component>
);
Expand Down
Loading

0 comments on commit b227737

Please sign in to comment.