Skip to content

Commit 266b8aa

Browse files
fix(ChatbotHeaderMenu): Adjust tooltip (#758)
1 parent f68865f commit 266b8aa

File tree

1 file changed

+56
-14
lines changed

1 file changed

+56
-14
lines changed

packages/module/src/ChatbotHeader/ChatbotHeaderMenu.tsx

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Ref, FunctionComponent } from 'react';
2-
import { forwardRef } from 'react';
2+
import { forwardRef, useEffect, useMemo, useRef, useState } from 'react';
33

44
import { Button, ButtonProps, Icon, Tooltip, TooltipProps } from '@patternfly/react-core';
55
import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
@@ -30,21 +30,43 @@ const ChatbotHeaderMenuBase: FunctionComponent<ChatbotHeaderMenuProps> = ({
3030
tooltipContent = 'Chat history menu',
3131
isCompact,
3232
...props
33-
}: ChatbotHeaderMenuProps) => (
34-
<div className={`pf-chatbot__menu ${className}`}>
35-
<Tooltip
36-
content={tooltipContent}
37-
position="bottom"
38-
// prevents VO announcements of both aria label and tooltip
39-
aria="none"
40-
{...tooltipProps}
41-
>
33+
}: ChatbotHeaderMenuProps) => {
34+
const [isDrawerAnimating, setIsDrawerAnimating] = useState(false);
35+
// I'd like to use a prop here later if this works
36+
const drawerState = props['aria-expanded'];
37+
const isDrawerOpen = drawerState === true;
38+
const prevDrawerStateRef = useRef<boolean | undefined>(isDrawerOpen);
39+
const buttonRef = useRef<HTMLButtonElement | null>(null);
40+
41+
useEffect(() => {
42+
if (drawerState !== undefined) {
43+
const wasDrawerOpen = prevDrawerStateRef.current === true;
44+
const isDrawerClosing = wasDrawerOpen && !isDrawerOpen;
45+
46+
setIsDrawerAnimating(true);
47+
const timeout = setTimeout(() => {
48+
setIsDrawerAnimating(false);
49+
50+
if (isDrawerClosing) {
51+
requestAnimationFrame(() => {
52+
buttonRef.current?.focus();
53+
});
54+
}
55+
}, 350);
56+
57+
prevDrawerStateRef.current = isDrawerOpen;
58+
return () => clearTimeout(timeout);
59+
}
60+
}, [drawerState, isDrawerOpen]);
61+
62+
const button = useMemo(
63+
() => (
4264
<Button
4365
className={`pf-chatbot__button--toggle-menu ${isCompact ? 'pf-m-compact' : ''}`}
4466
variant="plain"
4567
onClick={onMenuToggle}
4668
aria-label={menuAriaLabel}
47-
ref={innerRef}
69+
ref={innerRef ?? buttonRef}
4870
icon={
4971
<Icon size={isCompact ? 'lg' : 'xl'} isInline>
5072
<BarsIcon />
@@ -53,9 +75,29 @@ const ChatbotHeaderMenuBase: FunctionComponent<ChatbotHeaderMenuProps> = ({
5375
size={isCompact ? 'sm' : undefined}
5476
{...props}
5577
/>
56-
</Tooltip>
57-
</div>
58-
);
78+
),
79+
// eslint-disable-next-line react-hooks/exhaustive-deps
80+
[isCompact, menuAriaLabel, onMenuToggle, innerRef, buttonRef]
81+
);
82+
83+
return (
84+
<div className={`pf-chatbot__menu ${className}`}>
85+
{isDrawerAnimating ? (
86+
button
87+
) : (
88+
<Tooltip
89+
content={tooltipContent}
90+
position="bottom"
91+
// prevents VO announcements of both aria label and tooltip
92+
aria="none"
93+
{...tooltipProps}
94+
>
95+
{button}
96+
</Tooltip>
97+
)}
98+
</div>
99+
);
100+
};
59101

60102
export const ChatbotHeaderMenu = forwardRef((props: ChatbotHeaderMenuProps, ref: Ref<HTMLButtonElement>) => (
61103
<ChatbotHeaderMenuBase innerRef={ref} {...props} />

0 commit comments

Comments
 (0)