Skip to content

Commit 15437be

Browse files
committed
Change Popover component to use forwardRef
2 parents fa6b7ba + 9189a8c commit 15437be

File tree

2 files changed

+49
-24
lines changed

2 files changed

+49
-24
lines changed

src/scripts/Popover.tsx

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import React, {
22
HTMLAttributes,
33
CSSProperties,
44
FC,
5-
useRef,
65
ReactNode,
6+
forwardRef,
77
} from 'react';
88
import classnames from 'classnames';
99
import {
@@ -60,9 +60,10 @@ export type PopoverProps = {
6060
/**
6161
*
6262
*/
63-
export const PopoverInner: FC<PopoverProps & AutoAlignInjectedProps> = (
64-
props
65-
) => {
63+
export const PopoverInner = forwardRef<
64+
HTMLDivElement,
65+
PopoverProps & AutoAlignInjectedProps
66+
>((props, ref) => {
6667
const {
6768
children,
6869
alignment,
@@ -73,7 +74,6 @@ export const PopoverInner: FC<PopoverProps & AutoAlignInjectedProps> = (
7374
bodyStyle,
7475
...rprops
7576
} = props;
76-
const elRef = useRef<HTMLDivElement | null>(null);
7777
const nubbinPosition = alignment.join('-');
7878
const [firstAlign, secondAlign] = alignment;
7979
const popoverClassNames = classnames(
@@ -103,7 +103,7 @@ export const PopoverInner: FC<PopoverProps & AutoAlignInjectedProps> = (
103103
};
104104
return (
105105
<div
106-
ref={elRef}
106+
ref={ref}
107107
className={popoverClassNames}
108108
role={tooltip ? 'tooltip' : 'dialog'}
109109
style={rootStyle}
@@ -112,22 +112,26 @@ export const PopoverInner: FC<PopoverProps & AutoAlignInjectedProps> = (
112112
<PopoverBody style={bodyStyle}>{children}</PopoverBody>
113113
</div>
114114
);
115-
};
115+
});
116116

117117
/**
118118
*
119119
*/
120-
export const Popover: FC<PopoverProps> = ({ position, ...props }) => {
121-
const alignment: RectangleAlignment | undefined = position?.split('-') as
122-
| RectangleAlignment
123-
| undefined;
124-
return (
125-
<AutoAlign
126-
triggerSelector='.slds-dropdown-trigger'
127-
alignmentStyle='popover'
128-
alignment={alignment}
129-
>
130-
{(injectedProps) => <PopoverInner {...props} {...injectedProps} />}
131-
</AutoAlign>
132-
);
133-
};
120+
export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
121+
({ position, ...props }, ref) => {
122+
const alignment: RectangleAlignment | undefined = position?.split('-') as
123+
| RectangleAlignment
124+
| undefined;
125+
return (
126+
<AutoAlign
127+
triggerSelector='.slds-dropdown-trigger'
128+
alignmentStyle='popover'
129+
alignment={alignment}
130+
>
131+
{(injectedProps) => (
132+
<PopoverInner {...props} {...injectedProps} ref={ref} />
133+
)}
134+
</AutoAlign>
135+
);
136+
}
137+
);

stories/Tabs.stories.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useState } from 'react';
1+
import React, { FocusEvent, useCallback, useRef, useState } from 'react';
22
import {
33
Tabs,
44
Tab,
@@ -55,13 +55,34 @@ function CustomTabItemContent(props: TabItemRendererProps & { icon: string }) {
5555
function TooltipContent(props: { text: string }) {
5656
const { text } = props;
5757
const [isHideTooltip, setIsHideTooltip] = useState(true);
58+
const popoverRef = useRef<HTMLDivElement>(null);
5859
const tooltipToggle = useCallback(() => {
5960
setIsHideTooltip((hidden) => !hidden);
6061
}, []);
62+
const onIconBlur = useCallback((e: FocusEvent<HTMLElement>) => {
63+
if (popoverRef.current !== e.relatedTarget) {
64+
setIsHideTooltip(true);
65+
}
66+
}, []);
67+
const onPopoverBlur = useCallback(() => {
68+
setIsHideTooltip(true);
69+
}, []);
6170
return (
6271
<>
63-
<Button type='icon' icon='info' onClick={tooltipToggle} title={text} />
64-
<Popover hidden={isHideTooltip} tooltip>
72+
<Button
73+
type='icon'
74+
icon='info'
75+
onClick={tooltipToggle}
76+
onBlur={onIconBlur}
77+
title={text}
78+
/>
79+
<Popover
80+
ref={popoverRef}
81+
hidden={isHideTooltip}
82+
tabIndex={-1}
83+
onBlur={onPopoverBlur}
84+
tooltip
85+
>
6586
{text}
6687
</Popover>
6788
</>

0 commit comments

Comments
 (0)