Skip to content

Commit bc9672a

Browse files
authored
docs: add Popper 2 to Floating UI migration guide (floating-ui#1805)
1 parent 92fc2e4 commit bc9672a

File tree

2 files changed

+263
-1
lines changed

2 files changed

+263
-1
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
<p>
44

55
> **Popper is now Floating UI! For Popper v2, visit
6-
> [its dedicated branch.](https://github.com/floating-ui/floating-ui/tree/v2.x)**
6+
> [its dedicated branch.](https://github.com/floating-ui/floating-ui/tree/v2.x)
7+
> For help on migrating, check out the
8+
> [Migration Guide.](https://floating-ui.com/docs/migration)**
79
810
[Floating UI](https://floating-ui.com) is a tiny, low-level library for creating
911
"floating" elements like tooltips, popovers, dropdowns, menus, and more.

website/pages/docs/migration.mdx

+260
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
# Migrating from Popper 2 to Floating UI
2+
3+
This page is dedicated to helping you migrate from Popper v2 to
4+
Floating UI.
5+
6+
**Rebranding:** The library was rebranded to indicate it offers
7+
more packages and functionality, like the new
8+
[React DOM Interactions](/docs/react-dom-interactions) package,
9+
as Popper only ever offered "anchored positioning".
10+
11+
**New API:** The goal of the new API was to make Floating UI
12+
lower-level and act more like CSS in which you progressively add
13+
properties to achieve the desired positioning behavior, without
14+
preconfiguring anything.
15+
16+
Further, we wanted to make the configuration more ergonomic, the
17+
library smaller and fully tree-shakeable (so new features don't
18+
bloat bundles if unused), and also wanted to support React
19+
Native/Canvas, which the new architecture supports.
20+
21+
**Different, but familiar**: Floating UI forked Popper 2 and
22+
shares a lot of similarities. While the fundamental positioning
23+
function changed to enable full control, many other parts of the
24+
API will feel similar.
25+
26+
Similarities include:
27+
28+
- The order of arguments and types of the positioning function
29+
are practically identical.
30+
- `placement{:.objectKey}` and `strategy{:.objectKey}` are the
31+
same, passed as a third argument options object.
32+
- `middleware{:.objectKey}` in Floating UI is conceptually
33+
similar to `modifiers{:.objectKey}` from Popper 2.
34+
- Options passed to middleware have very similar configuration as
35+
Popper 2, and APIs like `detectOverflow` and virtual elements
36+
are almost identical.
37+
38+
## Change dependencies
39+
40+
First thing's first, uninstall `@popperjs/core` and install
41+
`@floating-ui/dom`.
42+
43+
```diff
44+
npm uninstall @popperjs/core
45+
npm install @floating-ui/dom
46+
```
47+
48+
## Positioning function change
49+
50+
Popper applied styles and added modifiers for you by default.
51+
Floating UI on the other hand is completely bare bones — you add
52+
what you need with nothing preconfigured.
53+
54+
You can think of Floating UI as acting more like CSS, where you
55+
progressively add properties to achieve the behavior you desire.
56+
In this sense, it's very low-level intentionally.
57+
58+
In Popper, you called `createPopper(){:js}` like so and it would
59+
place the popper element for you automatically.
60+
61+
```js
62+
import {createPopper} from '@popperjs/core';
63+
64+
createPopper(reference, popper);
65+
```
66+
67+
In Floating UI, it no longer applies styles or adds modifiers
68+
(now more generically called middleware) for you. Instead it's
69+
**pure** and only returns data that you can use as you please.
70+
71+
Set up the initial styles on the floating element in your CSS:
72+
73+
```css
74+
#floating {
75+
position: absolute;
76+
top: 0;
77+
left: 0;
78+
}
79+
```
80+
81+
Then apply the coordinates using the positioning data resolved by
82+
the function:
83+
84+
```js
85+
import {computePosition} from '@floating-ui/dom';
86+
87+
computePosition(reference, floating).then(({x, y}) => {
88+
Object.assign(floating.style, {
89+
left: `${x}px`,
90+
top: `${y}px`,
91+
});
92+
});
93+
```
94+
95+
Read more about [computePosition here](/docs/computePosition).
96+
97+
## Updating the position automatically
98+
99+
`computePosition(){:js}` is not stateful, it only positions your
100+
element once.
101+
102+
Popper added listeners automatically to update the position on
103+
scroll and resize. In Floating UI, you add this yourself, and
104+
it's much more explicit that it needs to be cleaned up:
105+
106+
```js
107+
import {computePosition, autoUpdate} from '@floating-ui/dom';
108+
109+
// When the floating element is open on the screen
110+
const cleanup = autoUpdate(reference, floating, () => {
111+
computePosition(reference, floating).then(({x, y}) => {
112+
Object.assign(floating.style, {
113+
left: `${x}px`,
114+
top: `${y}px`,
115+
});
116+
});
117+
});
118+
119+
// When the floating element is removed from the screen
120+
cleanup();
121+
```
122+
123+
Floating UI also adds `ResizeObserver{:.class}` listeners by
124+
default, unlike Popper, handling an additional update edge case.
125+
126+
Read more about [autoUpdate here](/docs/autoUpdate).
127+
128+
## Configure middleware
129+
130+
Floating UI honors the `placement{:.objectKey}` you passed in and
131+
does not modify it by default:
132+
133+
```js
134+
import {computePosition} from '@floating-ui/dom';
135+
136+
computePosition(reference, floating, {
137+
placement: 'top',
138+
}).then(({x, y}) => {
139+
// ...
140+
});
141+
```
142+
143+
Even if the floating element will overflow the top of the screen,
144+
it will still be placed and anchored there.
145+
146+
If you'd like to directly match Popper's default behavior, add in
147+
`flip(){:js}`, `shift(){:js}` and `limitShift(){:js}`:
148+
149+
```js
150+
import {
151+
computePosition,
152+
flip,
153+
shift,
154+
limitShift,
155+
} from '@floating-ui/dom';
156+
157+
computePosition(reference, floating, {
158+
placement: 'top',
159+
middleware: [flip(), shift({limiter: limitShift()})],
160+
}).then(({x, y}) => {
161+
// ...
162+
});
163+
```
164+
165+
Unlike Popper 2, the **order of the array matters** and is not
166+
adjusted for you. The [Middleware](/docs/middleware) page
167+
explains the concept in detail. Essentially, if you place one of
168+
the middleware before or after another, the positioning result
169+
can change. This helps enable full control as sometimes you want
170+
different behavior based on the ordering.
171+
172+
The `preventOverflow` modifier from Popper is now called `shift`.
173+
This is because technically many modifiers in Popper 2 "prevented
174+
overflow", which does not describe what it is actually doing
175+
unlike `shift`.
176+
177+
You'll hopefully notice the API of middleware in Floating UI
178+
(modifiers in Popper) is much more ergonomic at the point of the
179+
function call.
180+
181+
Popper 2:
182+
183+
```js
184+
createPopper(reference, popper, {
185+
modifiers: [
186+
{
187+
name: 'offset',
188+
options: {
189+
offset: [0, 10],
190+
},
191+
},
192+
],
193+
});
194+
```
195+
196+
Floating UI:
197+
198+
```js
199+
computePosition(reference, popper, {
200+
middleware: [offset(10)],
201+
});
202+
```
203+
204+
- [offset](/docs/offset)
205+
206+
A lot of the options passed in to middleware options are similar
207+
or the same as Popper 2. To learn about their options, you can
208+
read their pages on the sidebar on the left.
209+
210+
## Arrows styling
211+
212+
In Popper you could add a `data-popper-arrow{:.keyword}` element
213+
inside your popper and it'd automatically be picked up and
214+
styled.
215+
216+
As Floating UI is pure, you now handle these styles yourself, and
217+
you always pass an element in manually. You can read more about
218+
this on the [arrow middleware](/docs/arrow) page.
219+
220+
## Auto placement is now a middleware
221+
222+
In Popper 2, this was part of `flip` but now it's separate and is
223+
no longer a string option for `placement{:.objectKey}`.
224+
225+
Popper 2:
226+
227+
```js
228+
import {createPopper} from '@popperjs/core';
229+
230+
createPopper(reference, popper, {
231+
placement: 'auto',
232+
});
233+
```
234+
235+
Floating UI:
236+
237+
```js
238+
import {computePosition, autoPlacement} from '@floating-ui/dom';
239+
240+
computePosition(reference, floating, {
241+
middleware: [autoPlacement()],
242+
});
243+
```
244+
245+
## Other
246+
247+
APIs like [detectOverflow](/docs/detectOverflow) and
248+
[virtual elements](/docs/virtual-elements) are basically the same
249+
as Popper 2 with only minor differences.
250+
251+
`detectOverflow(){:js}` must now be called with the
252+
`await{:.keyword}` keyword before it but accepts the same options
253+
as Popper 2 with minor differences.
254+
255+
## Conclusion
256+
257+
If you think something is missing or are confused, you can open a
258+
Discussion on the
259+
[GitHub repo](https://github.com/floating-ui/floating-ui) and
260+
we'll try to improve this page.

0 commit comments

Comments
 (0)