A JavaScript library to position floating elements and create interactions for them.
MIT License
Bot releases are visible (Hide)
Published by github-actions[bot] over 1 year ago
fix(getClippingRect): prevent fixed ancestors from creating a clipping ancestor (#2170)
fix(types): re-export middleware options types (#2175)
Published by github-actions[bot] over 1 year ago
MiddlewareArguments
in favor of MiddlewareState
type (#2175)Published by github-actions[bot] over 1 year ago
feat(platform): add ability to polyfill offsetParent
access (in a pure way) to fix a platform gap where the incorrect value is returned inside shadow DOM. (#2160)
This was previously done internally a while ago (1.0.1
) but reportedly causes a performance issue in certain scenarios, meaning it cannot be a default. This allows the polyfill to be conditionally enabled by libraries. The polyfill and its usage is available here, which ideally would be made into its own package (that can be iterated on and potentially improved perf-wise).
feat(detectOverflow): accept virtual Rect
boundaries (#2161)
platform
object now has all methods non-optional with Required<Platform>
(#2166)Published by github-actions[bot] over 1 year ago
feat(autoPlacement): crossAxis
option (#2159)
By default, aligned placements like top-start
/top-end
use a "fallback" strategy for the crossAxis
to ensure different axes' placements can be chosen, and to keep the preferred alignment
as much as possible.
However, if you only have placements along one axis you can now use a "most space" strategy for the alignment as well, e.g.:
autoPlacement({
allowedPlacements: [
'top-start',
'top-end',
'bottom-start',
'bottom-end'
],
crossAxis: true,
});
feat(detectOverflow): accept virtual Rect
boundaries (#2161)
fix(size): consider case where shift()
is in the middleware array before size()
for center aligned placements (#2163)
fix(autoPlacement): prevent resetting placement unexpectedly to opposite alignment when it overflows on all sides (#2159)
fix(flip): when no placements fit, but before fallbackStrategy
phase, if multiple placements fit on the mainAxis of overflow, choose the placement that fits best on the main crossAxis side of overflow (#2163)
fix(autoPlacement): general algorithm improvements (#2159)
fix(size): general algorithm improvements (#2163)
Published by github-actions[bot] over 1 year ago
Published by github-actions[bot] over 1 year ago
mainAxis
overflow check first once in fallback phase (#2151)Published by github-actions[bot] over 1 year ago
refactor(safePolygon): change blockPointerEvents
option to false
by default and revert to pointer-events
strategy instead of real polygon — this works more reliably but has notable side-effects. (#2149)
If you need to enable blockPointerEvents
, and want to avoid the two side-effects with scrolling containers:
A [data-floating-ui-safe-polygon]
selector is available as a parent like so:
[data-floating-ui-safe-polygon] [data-scrolling-container] {
pointer-events: auto;
}
[data-floating-ui-safe-polygon] [data-scrolling-container] > div {
pointer-events: none;
}
<div data-scrolling-container>
<div>
blocked content
{/* reference inside here */}
</div>
</div>
It's also recommended that it's set to false
in tests.
id
string to add no id attribute (#2148)getItemProps
getter change less frequently (#2147)Published by github-actions[bot] over 1 year ago
SVGElement
as the arrow (#2146)Published by github-actions[bot] over 1 year ago
fix(types): allow SVGElement
as the arrow element (#2146)
fix(arrow): re-allow SVGElement
s to be measured (#2146)
Published by github-actions[bot] almost 2 years ago
fix: prevent setState loop when placing getFloatingProps
as a dependency of a hook and the ref setter is inside (#2130)
fix(useFocus): only prevent onBlur
if an outside focus guard was hit (#2131)
fix(useListNavigation): avoid synchronizing the activeIndex
if the floating element is unmounting (transitioning out) (#2134)
fix(safePolygon): improve cursor landing logic (#2135)
Published by github-actions[bot] almost 2 years ago
isInstantPhase
boolean for conditionally applying fast transition durations with useTransition
hooks (#2119)fix: avoid arrow
re-export collision (#2113)
fix(safePolygon): destroy polygon once cursor is over floating element rect when it overlaps it (#2116)
fix(FloatingDelayGroup): simplify usage by syncing current id internally (#2117)
You no longer need to wrap your onOpenChange
callback or use setCurrentId
from the delay context.
Usage can just be:
onOpenChange: setOpen,
fix(useHover): prevent clearing a delay timeout unexpectedly if requesting an open while an unmount is in transition (#2118)
fix: improve useDismiss
bubbles logic for nested floating elements (#2114)
fix: avoid useFloating
re-export collision (#2113)
Published by github-actions[bot] almost 2 years ago
arrow
re-export collision (#2113)Published by github-actions[bot] almost 2 years ago
@floating-ui/react-dom
APIs (#2101)Published by github-actions[bot] almost 2 years ago
@floating-ui/react-dom
APIs (#2101)fix(FloatingFocusManager): prevent FloatingPortal
focus guard from not respecting closeOnFocusOut
option (#2105)
fix(FloatingFocusManager): prevent sync return focus edge cases (#2108)
fix(FloatingFocusManager): aria-hidden
not being applied to outside nodes when no reference is present (#2101)
fix(useListNavigation): scrollIntoView
should be invoked if the modality is pointer when the selectedIndex
matches activeIndex
(#2108)
Published by github-actions[bot] almost 2 years ago
feat: add element setters to refs
object (#2101)
const {refs} = useFloating();
<div ref={refs.setReference} />
<div ref={refs.setFloating} />
These replace the reference
and floating
callback refs (which are now aliases) by being more explicit and less confusing regarding how refs are updated.
The refs
object contains:
{
reference: MutableRefObject,
floating: MutableRefObject,
setReference: (node) => void,
setFloating: (node) => void,
}
feat: return elements
object from hook (#2101)
If you need to read the elements during render, where refs are not suitable, these contain the elements rather than refs.
Published by github-actions[bot] almost 2 years ago
feat: useTransitionStatus
and useTransitionStyles
hooks (#2089)
These hooks make it easy to add CSS transitions to your floating elements, namely if you aren't using a spring library already like framer-motion
/react-spring
etc, but especially makes "placement-aware" transitions straightforward.
A basic symmetric scale transition looks like:
const {isMounted, styles} = useTransitionStyles(context, {
initial: {
opacity: 0,
transform: 'scale(0.8)',
},
});
return isMounted && <div style={styles} />;
A placement/side-aware transition looks like:
const {isMounted, styles} = useTransitionStyles(context, {
initial: ({side}) => ({
opacity: 0,
transform: {
top: 'translateY(5px)',
bottom: 'translateY(-5px)',
right: 'translateX(-5px)',
left: 'translateX(5px)',
}[side],
}),
});
return isMounted && <div style={styles} />;
fix: preserve backwards-compatibility for multiple reference()
calls for old virtual element position technique (#2092)
Going forward, the new positionReference
callback ref is recommended instead, this is only to ensure upgrading does not break your old code.
fix(FloatingFocusManager): make return focus calls sync under certain conditions (#2092)
Only in Strict Mode, Safari would not navigate via arrow down keys due to sync navigation (<Menu>
example)
Published by github-actions[bot] almost 2 years ago
dataRef.current
to isPositioned
(#2098)Published by github-actions[bot] almost 2 years ago
fix: re-allow unstable ref
callbacks (prevent infinite loop) (#2087)
Since v1.0.0
you didn't need to memoize the callback ref (although is recommended), but in v1.1.0
this caused an infinite loop again:
ref={node => floating(node)}
perf: optimize calling floating
and reference
callback refs directly in render (#2087)
The docs recommended to use effects to synchronize external elements, but now there's an optimization that allows you to call either during render without needing an effect:
function App({externalNode}) {
const {reference} = useFloating();
// Works and is optimized, no effect needed
reference(externalNode);
}
Published by github-actions[bot] almost 2 years ago
open
option and isPositioned
return value (#2083)Published by github-actions[bot] almost 2 years ago
feat(flip): fallbackAxisSideDirection
option (#2082)
This option adds the ability to compute placements on the opposite axis of the preferred placement without needing to use an explicit fallbackPlacements
list, meaning you no longer need to manage a custom map of fallbackPlacements
and instead use this option to leverage automatic computing of the array.
This option determines whether to allow fallback to the opposite axis if no placements along the preferred placement axis fit, and if so, which side direction along that axis to choose. If necessary, it will fallback to the other direction.
'none'
signals that no fallback to the opposite axis should take place. (default)'start'
represents 'top'
or 'left'
.'end'
represents 'bottom'
or 'right'
.Note:
In RTL writing direction, the x-axis directions are reversed.
For instance, by default, if the initial placement
is set to 'right'
, then the placements to try (in order) are:
['right', 'left']
On a narrow viewport, it's possible or even likely that neither of these will fit.
By specifying a string other than 'none'
, you allow placements along the opposite axis of the initial placement to be tried. The direction determines which side of placement is tried first:
flip({
fallbackAxisSideDirection: 'start',
});
The above results in: ['right', 'left', 'top', 'bottom']
.
flip({
fallbackAxisSideDirection: 'end',
});
The above results in: ['right', 'left', 'bottom', 'top']
.
As an example, if you'd like a tooltip that has a placement of 'right'
to be placed on top on mobile (assuming it doesn't fit), then you'd use 'start'
. For an interactive popover, you likely want to use 'end'
so it's placed on the bottom, closer to the user's fingers.
shift
If shift()
is in use in the middleware array, you may desire to disable crossAxis
overflow checking, which will allow shift()
to perform its work without falling back to the opposite axis (therefore preserving the original axis as best as possible):
const middleware = [
flip({
fallbackAxisSideDirection: 'start',
crossAxis: false,
}),
shift(),
];
This will depend on the desired positioning you want to achieve, e.g. if the placement has an explicit alignment specified or not.