Skip to content

Commit a4de89e

Browse files
committed
Replaced @popperjs/core with @floating-ui/dom.
1 parent 62c6032 commit a4de89e

File tree

10 files changed

+60
-133
lines changed

10 files changed

+60
-133
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
"yarn": "^1.22.10"
112112
},
113113
"dependencies": {
114-
"@popperjs/core": "^2.9.3",
114+
"@floating-ui/dom": "^1.7.0",
115115
"flowbite-datepicker": "^1.3.1",
116116
"mini-svg-data-uri": "^1.4.3",
117117
"postcss": "^8.5.1"

src/components/dropdown/index.ts

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
/* eslint-disable @typescript-eslint/no-empty-function */
2-
import { createPopper } from '@popperjs/core';
3-
import type {
4-
Options as PopperOptions,
5-
Instance as PopperInstance,
6-
} from '@popperjs/core';
2+
import { computePosition, autoUpdate, offset } from '@floating-ui/dom';
73
import type { DropdownOptions } from './types';
84
import type { InstanceOptions } from '../../dom/types';
95
import { DropdownInterface } from './interface';
@@ -32,7 +28,7 @@ class Dropdown implements DropdownInterface {
3228
_triggerEl: HTMLElement;
3329
_options: DropdownOptions;
3430
_visible: boolean;
35-
_popperInstance: PopperInstance;
31+
_cleanupAutoUpdate: Function;
3632
_initialized: boolean;
3733
_clickOutsideEventListener: EventListenerOrEventListenerObject;
3834
_hoverShowTriggerElHandler: EventListenerOrEventListenerObject;
@@ -52,7 +48,7 @@ class Dropdown implements DropdownInterface {
5248
this._targetEl = targetElement;
5349
this._triggerEl = triggerElement;
5450
this._options = { ...Default, ...options };
55-
this._popperInstance = null;
51+
this._cleanupAutoUpdate = null;
5652
this._visible = false;
5753
this._initialized = false;
5854
this.init();
@@ -66,7 +62,6 @@ class Dropdown implements DropdownInterface {
6662

6763
init() {
6864
if (this._triggerEl && this._targetEl && !this._initialized) {
69-
this._popperInstance = this._createPopperInstance();
7065
this._setupEventListeners();
7166
this._initialized = true;
7267
}
@@ -101,7 +96,9 @@ class Dropdown implements DropdownInterface {
10196
});
10297
}
10398

104-
this._popperInstance.destroy();
99+
// stop FloatingUI auto updates
100+
this?._cleanupAutoUpdate();
101+
105102
this._initialized = false;
106103
}
107104

@@ -169,21 +166,13 @@ class Dropdown implements DropdownInterface {
169166
}
170167
}
171168

172-
_createPopperInstance() {
173-
return createPopper(this._triggerEl, this._targetEl, {
174-
placement: this._options.placement,
175-
modifiers: [
176-
{
177-
name: 'offset',
178-
options: {
179-
offset: [
180-
this._options.offsetSkidding,
181-
this._options.offsetDistance,
182-
],
183-
},
184-
},
185-
],
186-
});
169+
_initializeFloatingUI() {
170+
computePosition(this._triggerEl, this._targetEl, {
171+
placement: this._options.placement,
172+
middleware: [offset({ mainAxis: this._options.offsetSkidding, crossAxis: this._options.offsetDistance})]
173+
}).then(({ x, y }) => {
174+
Object.assign(this._targetEl.style, { left: `${x}px`, top: `${y}px` });
175+
});
187176
}
188177

189178
_setupClickOutsideListener() {
@@ -279,19 +268,13 @@ class Dropdown implements DropdownInterface {
279268
this._targetEl.classList.add('block');
280269
this._targetEl.removeAttribute('aria-hidden');
281270

271+
// Update its position
272+
this._initializeFloatingUI();
282273
// Enable the event listeners
283-
this._popperInstance.setOptions((options: PopperOptions) => ({
284-
...options,
285-
modifiers: [
286-
...options.modifiers,
287-
{ name: 'eventListeners', enabled: true },
288-
],
289-
}));
274+
this._cleanupAutoUpdate = autoUpdate(this._triggerEl, this._targetEl, () => { this._initializeFloatingUI() });
290275

291276
this._setupClickOutsideListener();
292277

293-
// Update its position
294-
this._popperInstance.update();
295278
this._visible = true;
296279

297280
// callback function
@@ -304,13 +287,8 @@ class Dropdown implements DropdownInterface {
304287
this._targetEl.setAttribute('aria-hidden', 'true');
305288

306289
// Disable the event listeners
307-
this._popperInstance.setOptions((options: PopperOptions) => ({
308-
...options,
309-
modifiers: [
310-
...options.modifiers,
311-
{ name: 'eventListeners', enabled: false },
312-
],
313-
}));
290+
this._cleanupAutoUpdate();
291+
this._cleanupAutoUpdate = null;
314292

315293
this._visible = false;
316294

src/components/dropdown/interface.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,17 @@ import {
33
DropdownTriggerType,
44
DropdownTriggerEventTypes,
55
} from './types';
6-
import type { Instance as PopperInstance } from '@popperjs/core';
76

87
export declare interface DropdownInterface {
98
_targetEl: HTMLElement;
109
_triggerEl: HTMLElement;
1110
_options: DropdownOptions;
11+
_cleanupAutoUpdate: Function;
1212
_visible: boolean;
13-
_popperInstance: PopperInstance;
1413
_initialized: boolean;
1514
_clickOutsideEventListener: EventListenerOrEventListenerObject;
1615

1716
init(): void;
18-
_createPopperInstance(): PopperInstance;
1917
_setupEventListeners(): void;
2018
_setupClickOutsideListener(): void;
2119
_removeClickOutsideListener(): void;

src/components/dropdown/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { DropdownInterface } from './interface';
2-
import type { Placement } from '@popperjs/core';
2+
import type { Placement } from '@floating-ui/dom';
33

44
export declare type DropdownTriggerType = 'click' | 'hover' | 'none';
55

src/components/popover/index.ts

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
/* eslint-disable @typescript-eslint/no-empty-function */
2-
import { createPopper } from '@popperjs/core';
3-
import type {
4-
Options as PopperOptions,
5-
Instance as PopperInstance,
6-
} from '@popperjs/core';
2+
import { computePosition, autoUpdate, offset } from '@floating-ui/dom';
73
import type { PopoverOptions } from './types';
84
import type { InstanceOptions } from '../../dom/types';
95
import { PopoverInterface } from './interface';
@@ -28,7 +24,7 @@ class Popover implements PopoverInterface {
2824
_targetEl: HTMLElement;
2925
_triggerEl: HTMLElement;
3026
_options: PopoverOptions;
31-
_popperInstance: PopperInstance;
27+
_cleanupAutoUpdate: Function;
3228
_clickOutsideEventListener: EventListenerOrEventListenerObject;
3329
_keydownEventListener: EventListenerOrEventListenerObject;
3430
_visible: boolean;
@@ -48,7 +44,7 @@ class Popover implements PopoverInterface {
4844
this._targetEl = targetEl;
4945
this._triggerEl = triggerEl;
5046
this._options = { ...Default, ...options };
51-
this._popperInstance = null;
47+
this._cleanupAutoUpdate = null;
5248
this._visible = false;
5349
this._initialized = false;
5450
this.init();
@@ -63,7 +59,6 @@ class Popover implements PopoverInterface {
6359
init() {
6460
if (this._triggerEl && this._targetEl && !this._initialized) {
6561
this._setupEventListeners();
66-
this._popperInstance = this._createPopperInstance();
6762
this._initialized = true;
6863
}
6964
}
@@ -89,10 +84,8 @@ class Popover implements PopoverInterface {
8984
// remove event listeners for click outside
9085
this._removeClickOutsideListener();
9186

92-
// destroy the Popper instance if you have one (assuming this._popperInstance is the Popper instance)
93-
if (this._popperInstance) {
94-
this._popperInstance.destroy();
95-
}
87+
// stop FloatingUI auto updates
88+
this?._cleanupAutoUpdate();
9689

9790
this._initialized = false;
9891
}
@@ -133,18 +126,13 @@ class Popover implements PopoverInterface {
133126
});
134127
}
135128

136-
_createPopperInstance() {
137-
return createPopper(this._triggerEl, this._targetEl, {
138-
placement: this._options.placement,
139-
modifiers: [
140-
{
141-
name: 'offset',
142-
options: {
143-
offset: [0, this._options.offset],
144-
},
145-
},
146-
],
147-
});
129+
_initializeFloatingUI() {
130+
computePosition(this._triggerEl, this._targetEl, {
131+
placement: this._options.placement,
132+
middleware: [offset(this._options.offset)]
133+
}).then(({ x, y }) => {
134+
Object.assign(this._targetEl.style, { left: `${x}px`, top: `${y}px` });
135+
});
148136
}
149137

150138
_getTriggerEvents() {
@@ -241,24 +229,17 @@ class Popover implements PopoverInterface {
241229
this._targetEl.classList.remove('opacity-0', 'invisible');
242230
this._targetEl.classList.add('opacity-100', 'visible');
243231

232+
// Update its position
233+
this._initializeFloatingUI();
244234
// Enable the event listeners
245-
this._popperInstance.setOptions((options: PopperOptions) => ({
246-
...options,
247-
modifiers: [
248-
...options.modifiers,
249-
{ name: 'eventListeners', enabled: true },
250-
],
251-
}));
235+
this._cleanupAutoUpdate = autoUpdate(this._triggerEl, this._targetEl, () => { this._initializeFloatingUI() });
252236

253237
// handle click outside
254238
this._setupClickOutsideListener();
255239

256240
// handle esc keydown
257241
this._setupKeydownListener();
258242

259-
// Update its position
260-
this._popperInstance.update();
261-
262243
// set visibility to true
263244
this._visible = true;
264245

@@ -271,13 +252,8 @@ class Popover implements PopoverInterface {
271252
this._targetEl.classList.add('opacity-0', 'invisible');
272253

273254
// Disable the event listeners
274-
this._popperInstance.setOptions((options: PopperOptions) => ({
275-
...options,
276-
modifiers: [
277-
...options.modifiers,
278-
{ name: 'eventListeners', enabled: false },
279-
],
280-
}));
255+
this._cleanupAutoUpdate();
256+
this._cleanupAutoUpdate = null;
281257

282258
// handle click outside
283259
this._removeClickOutsideListener();

src/components/popover/interface.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ import {
33
PopoverTriggerType,
44
PopoverTriggerEventTypes,
55
} from './types';
6-
import type { Instance as PopperInstance } from '@popperjs/core';
76

87
export declare interface PopoverInterface {
98
_targetEl: HTMLElement | null;
109
_triggerEl: HTMLElement | null;
1110
_options: PopoverOptions;
12-
_popperInstance: PopperInstance;
11+
_cleanupAutoUpdate: Function;
1312
_clickOutsideEventListener: EventListenerOrEventListenerObject;
1413
_keydownEventListener: EventListenerOrEventListenerObject;
1514

src/components/popover/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { PopoverInterface } from './interface';
2-
import type { Placement } from '@popperjs/core';
2+
import type { Placement } from '@floating-ui/dom';
33

44
export declare type PopoverTriggerType = 'click' | 'hover' | 'none';
55

0 commit comments

Comments
 (0)