diff --git a/src/app/ItemPage.js b/src/app/ItemPage.js
index 1a37ca7..fd1de91 100644
--- a/src/app/ItemPage.js
+++ b/src/app/ItemPage.js
@@ -844,20 +844,22 @@ function SpeciesFaceOption({
]);
const xlShadow = useToken("shadows", "xl");
+ const [labelIsHovered, setLabelIsHovered] = React.useState(false);
+ const [inputIsFocused, setInputIsFocused] = React.useState(false);
+
const isHappy = isLoading || isCompatible;
const emotionId = isHappy ? "1" : "2";
- const tooltipLabel =
- isCompatible || isLoading ? (
- speciesName
- ) : (
-
- {speciesName}
+ const tooltipLabel = (
+
+ {speciesName}
+ {!isLoading && !isCompatible && (
(Not compatible yet)
-
- );
+ )}
+
+ );
const cursor = isLoading ? "wait" : !isCompatible ? "not-allowed" : "pointer";
@@ -872,8 +874,18 @@ function SpeciesFaceOption({
// `pointer-events: none` to the portal container, which I
// think is intercepting the hover even if the label doesn't.
gutter={-12}
+ // We track hover and focus state manually for the tooltip, so that
+ // keyboard nav to switch between options causes the tooltip to
+ // follow. (By default, the tooltip appears on the first tab focus,
+ // but not when you _change_ options!)
+ isOpen={labelIsHovered || inputIsFocused}
>
-
+ setLabelIsHovered(true)}
+ onMouseLeave={() => setLabelIsHovered(false)}
+ >
onChange({ speciesId, colorId })}
+ onFocus={() => setInputIsFocused(true)}
+ onBlur={() => setInputIsFocused(false)}
/>