@atlaskit/tag
Version:
A tag labels UI objects for quick recognition and navigation.
61 lines (58 loc) • 2.17 kB
JavaScript
import { useMemo, useRef, useState } from 'react';
/**
* Hook for tracking link/button hover/focus state (replaces CSS :has() selectors in this component)
*/
export function useButtonInteraction() {
const [isLinkHovered, setIsLinkHovered] = useState(false);
const [isOverButton, setIsOverButton] = useState(false);
const [isButtonFocused, setIsButtonFocused] = useState(false);
const [isLinkFocused, setIsLinkFocused] = useState(false);
// Track if last interaction was via mouse (to determine keyboard vs mouse focus)
const hadMouseDownRef = useRef(false);
// Button handlers
const buttonHandlers = useMemo(() => ({
onMouseEnter: () => setIsOverButton(true),
onMouseLeave: () => setIsOverButton(false),
onMouseDown: e => {
// Prevent the browser from moving focus to the remove button on mousedown.
// Without this, parent composite widgets (e.g. Select) lose input focus when
// the user clicks remove, triggering unwanted blur side-effects.
e === null || e === void 0 ? void 0 : e.preventDefault();
hadMouseDownRef.current = true;
},
onFocus: () => {
// Only track keyboard focus for focus ring styles
// If mousedown happened just before focus, it's mouse focus (not keyboard)
if (!hadMouseDownRef.current) {
setIsButtonFocused(true);
}
hadMouseDownRef.current = false;
},
onBlur: () => setIsButtonFocused(false)
}), []);
// Link handlers - includes hover tracking
const linkHandlers = useMemo(() => ({
onMouseEnter: () => setIsLinkHovered(true),
onMouseLeave: () => setIsLinkHovered(false),
onMouseDown: () => {
hadMouseDownRef.current = true;
},
onFocus: () => {
// Only track keyboard focus for focus ring styles
// If mousedown happened just before focus, it's mouse focus (not keyboard)
if (!hadMouseDownRef.current) {
setIsLinkFocused(true);
}
hadMouseDownRef.current = false;
},
onBlur: () => setIsLinkFocused(false)
}), []);
return {
isLinkHovered,
isOverButton,
isButtonFocused,
isLinkFocused,
buttonHandlers,
linkHandlers
};
}