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)} />