This repository has been archived by the owner on Nov 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdropdown.js
57 lines (50 loc) · 1.91 KB
/
dropdown.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import {
computePosition,
flip,
size,
autoUpdate,
} from 'https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.6.3/+esm';
export class Dropdown {
constructor(dropdown) {
this.dropdown = dropdown;
this.button = this.dropdown.querySelector('[data-dropdown]');
this.menu = this.dropdown.querySelector('.dropdown-contents');
this.button.addEventListener('mouseenter', this.onOpen.bind(this));
this.button.addEventListener('mouseleave', this.onClose.bind(this));
console.log('Dropdown initialized', this.dropdown, this.button, this.menu);
this.cleanup = () => {};
}
onOpen() {
this.dropdown.setAttribute('data-open', 'true');
this.cleanup = autoUpdate(this.button, this.menu, () => {
computePosition(this.button, this.menu, {
middleware: [
flip({padding: 5}),
size({
padding: 5,
apply({availableWidth, availableHeight, elements}) {
// Change styles, e.g.
Object.assign(elements.floating.style, {
maxWidth: `${availableWidth}px`,
maxHeight: `${availableHeight}px`,
});
},
}),
],
placement: this.button.getAttribute('data-dropdown-placement') ?? 'bottom-start',
}).then(({x, y}) => {
Object.assign(this.menu.style, {
left: `${x}px`,
top: `${y}px`,
});
});
});
}
onClose() {
this.dropdown.setAttribute('data-open', 'false');
this.cleanup();
}
}
export function initDropdowns() {
document.querySelectorAll('.dropdown').forEach(dropdown => new Dropdown(dropdown));
}