React library for creating accessible floating UI elements like tooltips, popovers, and dropdowns with advanced positioning
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Composable hooks for handling user interactions like clicks, hovers, focus, dismissal, and custom pointer events with floating elements.
Merges multiple interaction hooks' props into unified prop getters for composable behavior.
/**
* Merges interaction hooks' props into prop getters
* @param propsList - Array of ElementProps from interaction hooks
* @returns Prop getters for reference, floating, and item elements
*/
function useInteractions(
propsList?: Array<ElementProps | void>
): UseInteractionsReturn;
interface UseInteractionsReturn {
getReferenceProps: (userProps?: React.HTMLProps<Element>) => Record<string, unknown>;
getFloatingProps: (userProps?: React.HTMLProps<HTMLElement>) => Record<string, unknown>;
getItemProps: (userProps?: Omit<React.HTMLProps<HTMLElement>, 'selected' | 'active'> & ExtendedUserProps) => Record<string, unknown>;
}
interface ExtendedUserProps {
active?: boolean;
selected?: boolean;
}Usage Example:
import { useFloating, useInteractions, useClick, useHover, useDismiss } from '@floating-ui/react';
function MultiInteraction() {
const [isOpen, setIsOpen] = useState(false);
const { refs, floatingStyles, context } = useFloating({
open: isOpen,
onOpenChange: setIsOpen,
});
const click = useClick(context);
const hover = useHover(context);
const dismiss = useDismiss(context);
const { getReferenceProps, getFloatingProps } = useInteractions([
click,
hover,
dismiss,
]);
return (
<>
<button ref={refs.setReference} {...getReferenceProps()}>
Reference
</button>
{isOpen && (
<div ref={refs.setFloating} style={floatingStyles} {...getFloatingProps()}>
Floating content
</div>
)}
</>
);
}Opens or closes the floating element when clicking the reference element.
/**
* Handles click interactions for opening/closing floating elements
* @param context - Floating UI context
* @param props - Click behavior configuration
* @returns Element props for click handling
*/
function useClick(
context: FloatingRootContext,
props?: UseClickProps
): ElementProps;
interface UseClickProps {
enabled?: boolean;
event?: 'click' | 'mousedown';
toggle?: boolean;
ignoreMouse?: boolean;
keyboardHandlers?: boolean;
stickIfOpen?: boolean;
}Usage Examples:
import { useClick } from '@floating-ui/react';
// Basic click
const click = useClick(context);
// Click with options
const click = useClick(context, {
event: 'mousedown',
toggle: false,
keyboardHandlers: true,
});Opens the floating element while hovering over the reference element.
/**
* Handles hover interactions like CSS :hover
* @param context - Floating UI context
* @param props - Hover behavior configuration
* @returns Element props for hover handling
*/
function useHover(
context: FloatingRootContext,
props?: UseHoverProps
): ElementProps;
interface UseHoverProps {
enabled?: boolean;
handleClose?: HandleClose | null;
restMs?: number | (() => number);
delay?: Delay | (() => Delay);
mouseOnly?: boolean;
move?: boolean;
}
interface HandleClose {
(context: HandleCloseContext): (event: MouseEvent) => void;
__options?: SafePolygonOptions;
}
interface HandleCloseContext extends FloatingContext {
onClose: () => void;
tree?: FloatingTreeType | null;
leave?: boolean;
x?: number;
y?: number;
}Usage Examples:
import { useHover, safePolygon } from '@floating-ui/react';
// Basic hover
const hover = useHover(context);
// Hover with delay
const hover = useHover(context, {
delay: { open: 200, close: 100 },
});
// Hover with safe polygon
const hover = useHover(context, {
handleClose: safePolygon({
buffer: 2,
blockPointerEvents: true,
}),
});Opens the floating element while the reference element has focus.
/**
* Handles focus interactions like CSS :focus
* @param context - Floating UI context
* @param props - Focus behavior configuration
* @returns Element props for focus handling
*/
function useFocus(
context: FloatingRootContext,
props?: UseFocusProps
): ElementProps;
interface UseFocusProps {
enabled?: boolean;
visibleOnly?: boolean;
}Usage Example:
import { useFocus } from '@floating-ui/react';
// Focus on any focus (including programmatic)
const focus = useFocus(context);
// Focus only on visible focus (keyboard/mouse)
const focus = useFocus(context, {
visibleOnly: true,
});Closes the floating element when dismissal is requested (escape key, outside press, etc.).
/**
* Handles dismissal interactions (escape, outside press, etc.)
* @param context - Floating UI context
* @param props - Dismissal behavior configuration
* @returns Element props for dismissal handling
*/
function useDismiss(
context: FloatingRootContext,
props?: UseDismissProps
): ElementProps;
interface UseDismissProps {
enabled?: boolean;
escapeKey?: boolean;
referencePress?: boolean;
referencePressEvent?: 'pointerdown' | 'mousedown' | 'click';
outsidePress?: boolean | ((event: MouseEvent) => boolean);
outsidePressEvent?: 'pointerdown' | 'mousedown' | 'click';
ancestorScroll?: boolean;
bubbles?: boolean | {escapeKey?: boolean; outsidePress?: boolean};
capture?: boolean | {escapeKey?: boolean; outsidePress?: boolean};
}Usage Examples:
import { useDismiss } from '@floating-ui/react';
// Basic dismissal (escape + outside press)
const dismiss = useDismiss(context);
// Custom dismissal behavior
const dismiss = useDismiss(context, {
outsidePress: (event) => {
// Custom logic for outside press
return !event.target.closest('.allowed-area');
},
escapeKey: false,
ancestorScroll: true,
});Adds base screen reader props for accessibility based on the floating element's role.
/**
* Adds ARIA props for accessibility based on role
* @param context - Floating UI context
* @param props - Role configuration
* @returns Element props with ARIA attributes
*/
function useRole(
context: FloatingRootContext,
props?: UseRoleProps
): ElementProps;
interface UseRoleProps {
enabled?: boolean;
role?: AriaRole | ComponentRole;
}
type AriaRole = 'tooltip' | 'dialog' | 'alertdialog' | 'menu' | 'listbox' | 'grid' | 'tree';
type ComponentRole = 'select' | 'label' | 'combobox';Usage Examples:
import { useRole } from '@floating-ui/react';
// Tooltip role (default)
const role = useRole(context);
// Dialog role
const role = useRole(context, { role: 'dialog' });
// Menu role
const role = useRole(context, { role: 'menu' });Positions the floating element relative to a client point (mouse cursor by default).
/**
* Positions element relative to client point (e.g., mouse cursor)
* @param context - Floating UI context
* @param props - Client point configuration
* @returns Element props for client point positioning
*/
function useClientPoint(
context: FloatingRootContext,
props?: UseClientPointProps
): ElementProps;
interface UseClientPointProps {
enabled?: boolean;
axis?: 'x' | 'y' | 'both';
x?: number | null;
y?: number | null;
}Usage Examples:
import { useClientPoint } from '@floating-ui/react';
// Follow mouse cursor
const clientPoint = useClientPoint(context);
// Follow only x-axis
const clientPoint = useClientPoint(context, {
axis: 'x',
});
// Fixed position
const clientPoint = useClientPoint(context, {
x: 100,
y: 200,
});Creates a safe polygon area for hover interactions to prevent accidental closing.
/**
* Creates safe polygon area for hover interactions
* @param options - Polygon configuration
* @returns HandleClose function for useHover
*/
function safePolygon(options?: SafePolygonOptions): HandleClose;
interface SafePolygonOptions {
buffer?: number;
blockPointerEvents?: boolean;
requireIntent?: boolean;
}Usage Example:
import { useHover, safePolygon } from '@floating-ui/react';
const hover = useHover(context, {
handleClose: safePolygon({
buffer: 2,
blockPointerEvents: true,
requireIntent: true,
}),
});Handles typeahead functionality for lists, allowing users to type characters to find and navigate to list items.
/**
* Handles typeahead functionality for lists
* @param context - Floating UI context
* @param props - Typeahead configuration
* @returns Element props for typeahead handling
*/
function useTypeahead(
context: FloatingRootContext,
props: UseTypeaheadProps
): ElementProps;
interface UseTypeaheadProps {
listRef: React.MutableRefObject<Array<string | null>>;
activeIndex: number | null;
onMatch?: (index: number) => void;
onTypingChange?: (isTyping: boolean) => void;
enabled?: boolean;
findMatch?: null | ((list: Array<string | null>, typedString: string) => string | null | undefined);
resetMs?: number;
ignoreKeys?: Array<string>;
selectedIndex?: number | null;
}Merges multiple refs into a single callback ref for easier ref management.
/**
* Merges multiple refs into a single callback ref
* @param refs - Array of refs to merge
* @returns Single merged callback ref or null
*/
function useMergeRefs<Instance>(
refs: Array<React.Ref<Instance> | undefined>
): null | React.RefCallback<Instance>;Provides a unique ID that works with React 18's useId or falls back to a custom implementation.
/**
* Generates a unique ID using React 18's useId when available
* @returns Unique string ID or undefined during SSR
*/
function useId(): string | undefined;interface ElementProps {
reference?: React.HTMLProps<Element>;
floating?: React.HTMLProps<HTMLElement>;
item?: React.HTMLProps<HTMLElement> | ((props: ExtendedUserProps) => React.HTMLProps<HTMLElement>);
}
type Delay = number | Partial<{open: number; close: number}>;