FloatingDelayGroup
Provides context for a group of floating elements that should
share a delay
delay
which temporarily becomes 1
1
ms after the first floating element of the group opens.
This allows higher discovery of floating elements when they have a hover delay (like tooltips) when their reference elements are placed near each other.
import {FloatingDelayGroup} from '@floating-ui/react';
function App() {
return (
<FloatingDelayGroup delay={{open: 1000, close: 200}}>
<Tooltip label="One">
<button>Ref</button>
</Tooltip>
<Tooltip label="Two">
<button>Ref</button>
</Tooltip>
<Tooltip label="Three">
<button>Ref</button>
</Tooltip>
</FloatingDelayGroup>
);
}
import {FloatingDelayGroup} from '@floating-ui/react';
function App() {
return (
<FloatingDelayGroup delay={{open: 1000, close: 200}}>
<Tooltip label="One">
<button>Ref</button>
</Tooltip>
<Tooltip label="Two">
<button>Ref</button>
</Tooltip>
<Tooltip label="Three">
<button>Ref</button>
</Tooltip>
</FloatingDelayGroup>
);
}
Example
Hooks
These hooks are used:
useDelayGroupContext()
useDelayGroupContext()
— accessible due to a<FloatingDelayGroup />
<FloatingDelayGroup />
context wrapper, which provides the contextual delay for the group.useDelayGroup()
useDelayGroup()
— a hook called inside the component.
function Tooltip() {
const {delay} = useDelayGroupContext();
const id = useId();
const [isOpen, setIsOpen] = useState(false);
const {context} = useFloating({
open: isOpen,
onOpenChange: setIsOpen,
});
const hover = useHover(context, {
delay,
});
const {getReferenceProps, getFloatingProps} = useInteractions([
hover,
]);
useDelayGroup(context, {
// Must be unique
id,
});
// ...
}
function Tooltip() {
const {delay} = useDelayGroupContext();
const id = useId();
const [isOpen, setIsOpen] = useState(false);
const {context} = useFloating({
open: isOpen,
onOpenChange: setIsOpen,
});
const hover = useHover(context, {
delay,
});
const {getReferenceProps, getFloatingProps} = useInteractions([
hover,
]);
useDelayGroup(context, {
// Must be unique
id,
});
// ...
}
Props
interface Props {
delay: Delay;
timeoutMs?: number;
}
interface Props {
delay: Delay;
timeoutMs?: number;
}
delay
Required
default: 0
0
The delay to use for the group.
<FloatingDelayGroup
// Both open and close
delay={200}
// Or, configured individually
delay={{open: 1000, close: 200}}
>
{/* ... */}
</FloatingDelayGroup>
<FloatingDelayGroup
// Both open and close
delay={200}
// Or, configured individually
delay={{open: 1000, close: 200}}
>
{/* ... */}
</FloatingDelayGroup>
timeoutMs
default: 0
0
An optional explicit timeout to use for the group, which represents when grouping logic will no longer be active after the close delay completes. This is useful if you want grouping to “last” longer than the close delay, for example if there is no close delay at all.
<FloatingDelayGroup timeoutMs={500}>
{/* ... */}
</FloatingDelayGroup>
<FloatingDelayGroup timeoutMs={500}>
{/* ... */}
</FloatingDelayGroup>
Transitions
The isInstantPhase
isInstantPhase
boolean determines whether the
delay is currently in the instant phase. This allows you to make
transitions instant/faster. See
useTransitionStyles
.
const {currentId, isInstantPhase} = useDelayGroupContext();
const id = useId();
useDelayGroup(context, {
id,
});
const instantDuration = 0;
const duration = 200;
const {isMounted, styles} = useTransitionStyles(context, {
duration: isInstantPhase
? {
open: instantDuration,
// `id` is this component's `id`
// `currentId` is the current group's `id`
close: currentId === id ? duration : instantDuration,
}
: duration,
// ...
});
const {currentId, isInstantPhase} = useDelayGroupContext();
const id = useId();
useDelayGroup(context, {
id,
});
const instantDuration = 0;
const duration = 200;
const {isMounted, styles} = useTransitionStyles(context, {
duration: isInstantPhase
? {
open: instantDuration,
// `id` is this component's `id`
// `currentId` is the current group's `id`
close: currentId === id ? duration : instantDuration,
}
: duration,
// ...
});