Skip to content

Commit 781a609

Browse files
committed
fix: make sure badge shows as hovered while inside tooltip
1 parent 0ad68af commit 781a609

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

site/src/components/FeatureBadge/FeatureBadge.stories.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,19 @@ export const SmallInteractiveExperimental: Story = {
2727
variant: "interactive",
2828
},
2929
};
30+
31+
export const LargeInteractiveBeta: Story = {
32+
args: {
33+
type: "beta",
34+
size: "lg",
35+
variant: "interactive",
36+
},
37+
};
38+
39+
export const LargeStaticBeta: Story = {
40+
args: {
41+
type: "beta",
42+
size: "lg",
43+
variant: "static",
44+
},
45+
};

site/src/components/FeatureBadge/FeatureBadge.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const styles = {
4343
backgroundColor: theme.roles.preview.background,
4444
borderRadius: "6px",
4545
transition:
46-
"color 0.4s ease-in-out, border-color 0.4s ease-in-out, background-color 0.4s ease-in-out",
46+
"color 0.2s ease-in-out, border-color 0.2s ease-in-out, background-color 0.2s ease-in-out",
4747
}),
4848

4949
badgeHover: (theme) => ({
@@ -105,27 +105,35 @@ export const FeatureBadge: FC<FeatureBadgeProps> = ({
105105
onPointerLeave,
106106
...delegatedProps
107107
}) => {
108+
// Not a big fan of having two hover variables, but we need to make sure the
109+
// badge maintains its hover styling while the mouse is inside the tooltip
108110
const [isBadgeHovering, setIsBadgeHovering] = useState(false);
111+
const [isTooltipHovering, setIsTooltipHovering] = useState(false);
112+
109113
useEffect(() => {
110114
const onWindowBlur = () => {
111115
setIsBadgeHovering(false);
116+
setIsTooltipHovering(false);
112117
};
113118

114119
window.addEventListener("blur", onWindowBlur);
115120
return () => window.removeEventListener("blur", onWindowBlur);
116121
}, []);
117122

118123
const featureType = featureBadgeTypes[type];
119-
const showHoverStyles =
120-
variant === "staticHover" || (variant === "interactive" && isBadgeHovering);
124+
const showBadgeHoverStyle =
125+
variant === "staticHover" ||
126+
(variant === "interactive" && (isBadgeHovering || isTooltipHovering));
121127

122128
const coreContent = (
123129
<span
124130
css={[
125131
styles.badge,
126132
size === "lg" && styles.badgeLargeText,
127-
showHoverStyles && styles.badgeHover,
133+
showBadgeHoverStyle && styles.badgeHover,
128134
]}
135+
onPointerEnter={variant === "interactive" ? undefined : onPointerEnter}
136+
onPointerLeave={variant === "interactive" ? undefined : onPointerLeave}
129137
{...delegatedProps}
130138
>
131139
<span style={visuallyHidden}> (This is a</span>
@@ -156,14 +164,16 @@ export const FeatureBadge: FC<FeatureBadgeProps> = ({
156164
<HelpTooltipContent
157165
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
158166
transformOrigin={{ vertical: "top", horizontal: "center" }}
167+
onPointerEnter={() => setIsTooltipHovering(true)}
168+
onPointerLeave={() => setIsTooltipHovering(false)}
159169
>
160170
<h5 css={styles.tooltipTitle}>
161171
{capitalizeFirstLetter(featureType)} Feature
162172
</h5>
163173

164174
<p css={styles.tooltipDescription}>
165175
This is {getGrammaticalArticle(featureType)} {featureType} feature. It
166-
has not yet been marked for general availability.
176+
has not yet reached generally availability (GA).
167177
</p>
168178

169179
<Link

site/src/components/Popover/Popover.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
type FC,
66
type HTMLAttributes,
77
type PointerEvent,
8+
type PointerEventHandler,
89
type ReactElement,
910
type ReactNode,
1011
type RefObject,
@@ -133,6 +134,8 @@ export type PopoverContentProps = Omit<
133134

134135
export const PopoverContent: FC<PopoverContentProps> = ({
135136
horizontal = "left",
137+
onPointerEnter,
138+
onPointerLeave,
136139
...popoverProps
137140
}) => {
138141
const popover = usePopover();
@@ -155,7 +158,7 @@ export const PopoverContent: FC<PopoverContentProps> = ({
155158
},
156159
}}
157160
{...horizontalProps(horizontal)}
158-
{...modeProps(popover)}
161+
{...modeProps(popover, onPointerEnter, onPointerLeave)}
159162
{...popoverProps}
160163
id={popover.id}
161164
open={popover.open}
@@ -165,14 +168,20 @@ export const PopoverContent: FC<PopoverContentProps> = ({
165168
);
166169
};
167170

168-
const modeProps = (popover: PopoverContextValue) => {
171+
const modeProps = (
172+
popover: PopoverContextValue,
173+
externalOnPointerEnter: PointerEventHandler<HTMLDivElement> | undefined,
174+
externalOnPointerLeave: PointerEventHandler<HTMLDivElement> | undefined,
175+
) => {
169176
if (popover.mode === "hover") {
170177
return {
171-
onPointerEnter: () => {
178+
onPointerEnter: (event: PointerEvent<HTMLDivElement>) => {
172179
popover.setOpen(true);
180+
externalOnPointerEnter?.(event);
173181
},
174-
onPointerLeave: () => {
182+
onPointerLeave: (event: PointerEvent<HTMLDivElement>) => {
175183
popover.setOpen(false);
184+
externalOnPointerLeave?.(event);
176185
},
177186
};
178187
}

0 commit comments

Comments
 (0)