Migration
Learn how to migrate from Popper v2 to Floating UI.
Rebranding: The library was rebranded as it offers more packages and functionality, like the new React package that provides interactions, while Popper only ever offered positioning.
New API: The goal of the new API was to make Floating UI lower-level and act more like CSS in which you progressively add properties to achieve the desired positioning behavior, without pre-configuring anything.
In addition, we wanted to make the configuration more ergonomic, the library smaller and fully tree-shakeable (so new features don’t bloat bundles if unused), and also wanted to support React Native/Canvas as they had been requested, which is now supported.
Different, but familiar: Floating UI forked Popper 2 and shares a lot of similarities. While the main external positioning function changed, many other parts of the API are similar.
Similarities include:
- The order of arguments and types of the positioning function are practically identical.
placement
andstrategy
are the same, passed as a third argument options object.middleware
in Floating UI is conceptually similar tomodifiers
from Popper 2.- Options passed to middleware have very similar configuration as
Popper 2, and APIs like
detectOverflow
and virtual elements are almost identical.
Change dependencies
First thing’s first, uninstall @popperjs/core
and install
@floating-ui/dom
.
Positioning function change
Popper applied styles and added modifiers for you by default. Floating UI on the other hand is completely bare bones — you add what you need with nothing pre-configured.
In Popper, you called createPopper()
like so and it would
place the popper element at the bottom for you automatically.
Floating UI does not apply styles or add modifiers (now more generically called middleware) for you. Instead it’s pure and only returns data that you can use as you please.
Set up the initial styles on the floating element in your CSS:
Then, apply the coordinates using the positioning data resolved by the function:
Read more about computePosition
here.
Updating the position automatically
computePosition()
is not stateful, it only positions your
element once.
Popper added listeners automatically to update the position on scroll and resize. In Floating UI, you add this yourself, and it’s much more explicit that it needs to be cleaned up:
Floating UI also adds ResizeObserver
listeners by
default, unlike Popper, handling an additional update edge case.
Read more about autoUpdate
here.
Configure middleware
Floating UI honors the placement
you passed in and does
not modify it by default:
Even if the floating element will overflow the top of the screen, it will still be placed and anchored there.
If you’d like to directly match Popper’s default behavior to
prevent collisions, add in flip()
, shift()
and
limitShift()
in the following order:
Unlike Popper 2, the order of the array matters and is not adjusted for you. The Middleware page explains the concept in detail. Essentially, if you place one of the middleware before or after another, the positioning result can change. This helps enable full control as sometimes you want different behavior based on the ordering.
The preventOverflow
modifier from Popper is now called shift
.
This is because technically many modifiers in Popper 2 “prevented
overflow”, which does not describe what it is actually doing
unlike shift
.
You’ll hopefully notice the API is much more ergonomic at the point of the function call.
Popper 2:
Floating UI:
A lot of the options passed in to middleware options are similar or the same as Popper 2. To learn about their options, you can read their pages on the sidebar on the left.
Arrows styling
In Popper you could add a data-popper-arrow
element
inside your popper and it’d automatically be picked up and
styled.
As Floating UI is pure, you now handle these styles yourself, and
you always pass an element in manually. You can read more about
this on the arrow
middleware page.
Auto placement is now a middleware
In Popper 2, this was part of flip
but now it’s separate and is
no longer a string option for placement
.
Popper 2:
Floating UI:
Other
APIs like detectOverflow
and
virtual elements are basically the same
as Popper 2 with only minor differences.
detectOverflow()
must now be called with the
await
keyword before it but accepts the same options
as Popper 2 with minor differences.
Conclusion
If you think something is missing or are confused, you can open a Discussion on the GitHub repo and we’ll try to improve this page.