@flexilla/alpine-dropdown 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -9
- package/dist/cdn.js +125 -114
- package/dist/cdn.min.js +1 -1
- package/dist/module.cjs.js +125 -114
- package/dist/module.esm.js +125 -114
- package/package.json +5 -3
- package/src/index.d.ts +7 -0
package/README.md
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
<h1 align="center">Alpine
|
|
1
|
+
<h1 align="center">Alpine Dropdown</h1>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
Simple
|
|
4
|
+
Simple Interactive Dropdown Component for <a href="https://alpinejs.dev">Alpine.js</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
+
<p align="center">
|
|
8
|
+
Part of the <a href="https://flexilla-docs.vercel.app">Flexilla</a> library - A collection of UI components for Alpine.js
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The Alpine Dropdown component provides a lightweight and flexible dropdown menu implementation for Alpine.js applications. It features:
|
|
14
|
+
|
|
15
|
+
- 🎯 Precise positioning
|
|
16
|
+
- 🎨 Customizable styling with Tailwind CSS support
|
|
17
|
+
- ⌨️ Keyboard navigation support
|
|
18
|
+
- 🔄 Smooth transitions and animations
|
|
7
19
|
|
|
8
20
|
## Installation
|
|
9
21
|
|
|
@@ -12,32 +24,48 @@
|
|
|
12
24
|
Include the following `<script>` tag in the `<head>` of your document, just before Alpine.
|
|
13
25
|
|
|
14
26
|
```html
|
|
15
|
-
|
|
27
|
+
<script src="https://cdn.jsdelivr.net/npm/@flexilla/alpine-dropdown@latest/dist/cdn.min.js" defer></script>
|
|
16
28
|
```
|
|
17
29
|
|
|
18
30
|
### NPM
|
|
19
31
|
|
|
20
32
|
```shell
|
|
21
|
-
npm install @flexilla/alpine-
|
|
33
|
+
npm install @flexilla/alpine-dropdown
|
|
22
34
|
```
|
|
23
35
|
|
|
24
|
-
Add the `x-
|
|
36
|
+
Add the `x-dropdown` directive to your project by importing the package **before** starting Alpine.
|
|
25
37
|
|
|
26
38
|
```js
|
|
27
39
|
import Alpine from 'alpinejs';
|
|
28
|
-
import
|
|
40
|
+
import PluginDropdown from '@flexilla/alpine-dropdown';
|
|
29
41
|
|
|
30
|
-
Alpine.plugin(
|
|
42
|
+
Alpine.plugin(PluginDropdown);
|
|
31
43
|
|
|
32
44
|
Alpine.start();
|
|
33
45
|
```
|
|
34
46
|
|
|
35
|
-
##
|
|
47
|
+
## Basic Usage
|
|
36
48
|
|
|
37
49
|
```html
|
|
38
|
-
|
|
50
|
+
<button data-dropdown-trigger data-dropdown-id="dropdown-1"
|
|
51
|
+
class="border border-zinc-800 hover:bg-zinc-950 bg-zinc-900 text-white px-4 py-2 rounded-lg text-sm">
|
|
52
|
+
Open Dropdown
|
|
53
|
+
</button>
|
|
54
|
+
<div x-dropdown x-data role="list" id="dropdown-1" data-fx-popper
|
|
55
|
+
class="fixed top-[--fx-popper-placement-y] left-[--fx-popper-placement-x] z-20 w-56 border border-zinc-800 bg-zinc-900/80 text-zinc-50 backdrop-filter backdrop-blur-xl rounded-lg flex flex-col overflow-hidden opacity-0 invisible fx-open:opacity-100 fx-open:visible ease-linear transition-transform translate-y-4 fx-open:translate-y-0">
|
|
56
|
+
<a href="#" class="focus:outline focus:bg-zinc-900/90 outline-none focus:outline-blue-500 ease-linear flex hover-bg-zinc-800/80 p-2 rounded-md">
|
|
57
|
+
Item 1
|
|
58
|
+
</a>
|
|
59
|
+
<a href="/" class="focus:outline focus:bg-zinc-900/90 outline-none focus:outline-blue-500 ease-linear flex hover-bg-zinc-800/80 p-2 rounded-md">Item 2</a>
|
|
60
|
+
<a href="#" class="focus:outline focus:bg-zinc-900/90 outline-none focus:outline-blue-500 ease-linear flex hover-bg-zinc-800/80 p-2 rounded-md">Item 3</a>
|
|
61
|
+
<a href="#" class="focus:outline focus:bg-zinc-900/90 outline-none focus:outline-blue-500 ease-linear flex hover-bg-zinc-800/80 p-2 rounded-md">Item 4</a>
|
|
62
|
+
</div>
|
|
39
63
|
```
|
|
40
64
|
|
|
65
|
+
## Documentation
|
|
66
|
+
|
|
67
|
+
For detailed documentation, customization options, and advanced usage examples, visit the [Flexilla Dropdown documentation](https://flexilla-docs.vercel.app/docs/components/dropdown).
|
|
68
|
+
|
|
41
69
|
## License
|
|
42
70
|
|
|
43
71
|
Copyright (c) 2025 Johnkat MJ and contributors.
|
package/dist/cdn.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
// ../../node_modules/@flexilla/dropdown/dist/dropdown.js
|
|
3
3
|
var j = Object.defineProperty;
|
|
4
4
|
var q = (s, e, t) => e in s ? j(s, e, { enumerable: true, configurable: true, writable: true, value: t }) : s[e] = t;
|
|
5
|
-
var
|
|
5
|
+
var a = (s, e, t) => q(s, typeof e != "symbol" ? e + "" : e, t);
|
|
6
6
|
var B = Object.defineProperty;
|
|
7
7
|
var N = (s, e, t) => e in s ? B(s, e, { enumerable: true, configurable: true, writable: true, value: t }) : s[e] = t;
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var
|
|
8
|
+
var d = (s, e, t) => N(s, typeof e != "symbol" ? e + "" : e, t);
|
|
9
|
+
var V = "bottom";
|
|
10
|
+
var X = ({ reference: s, popper: e }) => {
|
|
11
11
|
if (!s || !e)
|
|
12
12
|
throw new Error("Reference or popper element is null or undefined");
|
|
13
13
|
const t = /* @__PURE__ */ new WeakMap(), n = (r) => (t.has(r) || t.set(r, r.getBoundingClientRect()), t.get(r)), o = n(e), i = n(s);
|
|
@@ -21,24 +21,21 @@
|
|
|
21
21
|
refRight: i.right
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
|
-
var V = Object.defineProperty;
|
|
25
|
-
var X = (s, e, t) => e in s ? V(s, e, { enumerable: true, configurable: true, writable: true, value: t }) : s[e] = t;
|
|
26
|
-
var p = (s, e, t) => X(s, typeof e != "symbol" ? e + "" : e, t);
|
|
27
24
|
var Y = (s, e, t, n) => {
|
|
28
25
|
const o = t, i = n - (t + e);
|
|
29
26
|
return o >= (s - e) / 2 && i >= (s - e) / 2;
|
|
30
27
|
};
|
|
31
|
-
var
|
|
32
|
-
var
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
const r = o - t - i,
|
|
37
|
-
return s() ? 0 : e() ?
|
|
28
|
+
var J = (s, e, t, n) => (s - e) / 2 <= t && t + s / 2 + e / 2 <= n;
|
|
29
|
+
var Q = (s, e, t, n, o) => t > o - n ? e() ? window.innerHeight - o : t - o : s() ? 0 : t + n;
|
|
30
|
+
var Z = (s, e, t, n) => s <= n && t - s <= e;
|
|
31
|
+
var _ = (s, e, t, n) => t <= n && -s <= e;
|
|
32
|
+
var ee = (s, e, t, n, o, i) => {
|
|
33
|
+
const r = o - t - i, h = t - n, g = t + i - n + (o - t - i), p = r >= 0 ? o - n : h >= 0 ? t - n : t;
|
|
34
|
+
return s() ? 0 : e() ? g : p;
|
|
38
35
|
};
|
|
39
|
-
var
|
|
40
|
-
var
|
|
41
|
-
var
|
|
36
|
+
var te = (s, e, t, n) => s <= t && e - s - n >= s;
|
|
37
|
+
var ne = (s, e) => s >= e;
|
|
38
|
+
var se = ({
|
|
42
39
|
placement: s,
|
|
43
40
|
refWidth: e,
|
|
44
41
|
refTop: t,
|
|
@@ -46,27 +43,27 @@
|
|
|
46
43
|
refHeight: o,
|
|
47
44
|
popperWidth: i,
|
|
48
45
|
popperHeight: r,
|
|
49
|
-
windowHeight:
|
|
50
|
-
windowWidth:
|
|
51
|
-
offsetDistance:
|
|
46
|
+
windowHeight: h,
|
|
47
|
+
windowWidth: g,
|
|
48
|
+
offsetDistance: p
|
|
52
49
|
}) => {
|
|
53
|
-
const c =
|
|
54
|
-
() =>
|
|
55
|
-
() =>
|
|
50
|
+
const c = g - n - e, f = n, v = h - t - o, m = t, w = () => Q(
|
|
51
|
+
() => _(t, o, r, h),
|
|
52
|
+
() => Z(t, o, r, h),
|
|
56
53
|
t,
|
|
57
54
|
o,
|
|
58
55
|
r
|
|
59
|
-
), y = () =>
|
|
60
|
-
() =>
|
|
61
|
-
() =>
|
|
56
|
+
), y = () => ee(
|
|
57
|
+
() => te(n, g, i, e),
|
|
58
|
+
() => ne(n, i),
|
|
62
59
|
n,
|
|
63
60
|
i,
|
|
64
|
-
|
|
61
|
+
g,
|
|
65
62
|
e
|
|
66
|
-
), H = () => Y(i, e, n,
|
|
63
|
+
), H = () => Y(i, e, n, g) ? n + e / 2 - i / 2 : y(), T = () => J(r, o, t, h) ? t + o / 2 - r / 2 : w(), C = () => n + i <= g ? n : y(), O = () => n + e - i >= 0 ? n + e - i : y(), L = () => t + r <= h ? t : w(), G = () => t + o - r >= 0 ? t + o - r : w();
|
|
67
64
|
let u = 0, E = 0;
|
|
68
|
-
const M = t - r -
|
|
69
|
-
switch (s.startsWith("top") ? E =
|
|
65
|
+
const M = t - r - p, k = t + o + p, D = n - i - p, I = n + e + p, W = m >= r + p, F = v >= r + p, R = f >= i + p, $ = c >= i + p;
|
|
66
|
+
switch (s.startsWith("top") ? E = W ? M : F ? k : Math.max(M, k) : s.startsWith("bottom") ? E = F ? k : W ? M : Math.max(k) : s.startsWith("left") ? u = R ? D : $ ? I : Math.max(D, I) : s.startsWith("right") && (u = $ ? I : R ? D : Math.max(I, D)), s) {
|
|
70
67
|
case "bottom":
|
|
71
68
|
case "bottom-middle":
|
|
72
69
|
case "top":
|
|
@@ -77,11 +74,11 @@
|
|
|
77
74
|
case "left-middle":
|
|
78
75
|
case "right":
|
|
79
76
|
case "right-middle":
|
|
80
|
-
E =
|
|
77
|
+
E = T();
|
|
81
78
|
break;
|
|
82
79
|
case "bottom-start":
|
|
83
80
|
case "top-start":
|
|
84
|
-
u =
|
|
81
|
+
u = C();
|
|
85
82
|
break;
|
|
86
83
|
case "bottom-end":
|
|
87
84
|
case "top-end":
|
|
@@ -98,7 +95,7 @@
|
|
|
98
95
|
}
|
|
99
96
|
return { x: u, y: E };
|
|
100
97
|
};
|
|
101
|
-
var
|
|
98
|
+
var ie = class {
|
|
102
99
|
/**
|
|
103
100
|
* Flexilla Popper
|
|
104
101
|
* @param reference
|
|
@@ -118,51 +115,51 @@
|
|
|
118
115
|
* @param {Function} [options.onUpdate] - Callback function when position updates
|
|
119
116
|
*/
|
|
120
117
|
constructor(e, t, n = {}) {
|
|
121
|
-
|
|
118
|
+
d(this, "reference"), d(this, "popper"), d(this, "offsetDistance"), d(this, "placement"), d(this, "disableOnResize"), d(this, "disableOnScroll"), d(this, "onUpdate"), d(this, "isWindowEventsRegistered"), d(this, "validateElements", () => {
|
|
122
119
|
if (!(this.reference instanceof HTMLElement))
|
|
123
120
|
throw new Error("Invalid HTMLElement for Reference Element");
|
|
124
121
|
if (!(this.popper instanceof HTMLElement))
|
|
125
122
|
throw new Error("Invalid HTMLElement for Popper");
|
|
126
123
|
if (typeof this.offsetDistance != "number")
|
|
127
124
|
throw new Error("OffsetDistance must be a number");
|
|
128
|
-
}),
|
|
125
|
+
}), d(this, "setPopperStyleProperty", (c, f) => {
|
|
129
126
|
this.popper.style.setProperty("--fx-popper-placement-x", `${c}px`), this.popper.style.setProperty("--fx-popper-placement-y", `${f}px`);
|
|
130
|
-
}),
|
|
127
|
+
}), d(this, "setInitialStyles", () => {
|
|
131
128
|
this.popper.style.setProperty("--fx-popper-placement-x", ""), this.popper.style.setProperty("--fx-popper-placement-y", "");
|
|
132
|
-
}),
|
|
129
|
+
}), d(this, "initPlacement", () => {
|
|
133
130
|
var c;
|
|
134
131
|
this.validateElements(), this.setInitialStyles();
|
|
135
|
-
const f = window.innerWidth, v = window.innerHeight, { popperHeight:
|
|
132
|
+
const f = window.innerWidth, v = window.innerHeight, { popperHeight: m, popperWidth: w, refHeight: y, refWidth: H, refLeft: T, refTop: C } = X({ reference: this.reference, popper: this.popper }), { x: O, y: L } = se(
|
|
136
133
|
{
|
|
137
134
|
placement: this.placement,
|
|
138
135
|
refWidth: H,
|
|
139
|
-
refTop:
|
|
140
|
-
refLeft:
|
|
136
|
+
refTop: C,
|
|
137
|
+
refLeft: T,
|
|
141
138
|
popperWidth: w,
|
|
142
139
|
refHeight: y,
|
|
143
|
-
popperHeight:
|
|
140
|
+
popperHeight: m,
|
|
144
141
|
windowHeight: v,
|
|
145
142
|
windowWidth: f,
|
|
146
143
|
offsetDistance: this.offsetDistance
|
|
147
144
|
}
|
|
148
145
|
);
|
|
149
146
|
this.setPopperStyleProperty(O, L), (c = this.onUpdate) == null || c.call(this, { x: O, y: L, placement: this.placement });
|
|
150
|
-
}),
|
|
147
|
+
}), d(this, "removeWindowEvents", () => {
|
|
151
148
|
this.isWindowEventsRegistered && (!this.disableOnResize && window.removeEventListener("resize", this.updatePosition), !this.disableOnScroll && window.removeEventListener("scroll", this.updatePosition), this.isWindowEventsRegistered = false);
|
|
152
|
-
}),
|
|
149
|
+
}), d(this, "attachWindowEvent", () => {
|
|
153
150
|
this.isWindowEventsRegistered && this.removeWindowEvents(), this.disableOnResize || window.addEventListener("resize", this.updatePosition), this.disableOnScroll || window.addEventListener("scroll", this.updatePosition), this.isWindowEventsRegistered = true;
|
|
154
|
-
}),
|
|
151
|
+
}), d(this, "resetPosition", () => {
|
|
155
152
|
this.setInitialStyles();
|
|
156
|
-
}),
|
|
153
|
+
}), d(this, "updatePosition", () => {
|
|
157
154
|
this.initPlacement(), this.attachWindowEvent();
|
|
158
|
-
}),
|
|
155
|
+
}), d(this, "cleanupEvents", () => {
|
|
159
156
|
this.setInitialStyles(), this.removeWindowEvents();
|
|
160
157
|
});
|
|
161
158
|
const {
|
|
162
159
|
offsetDistance: o = 10,
|
|
163
|
-
placement: i =
|
|
160
|
+
placement: i = V,
|
|
164
161
|
eventEffect: r = {},
|
|
165
|
-
onUpdate:
|
|
162
|
+
onUpdate: h
|
|
166
163
|
} = n;
|
|
167
164
|
if (!(e instanceof HTMLElement))
|
|
168
165
|
throw new Error("Invalid HTMLElement for Reference Element");
|
|
@@ -170,8 +167,8 @@
|
|
|
170
167
|
throw new Error("Invalid HTMLElement for Popper");
|
|
171
168
|
if (n.offsetDistance && typeof n.offsetDistance != "number")
|
|
172
169
|
throw new Error("OffsetDistance must be a number");
|
|
173
|
-
const { disableOnResize:
|
|
174
|
-
this.isWindowEventsRegistered = false, this.reference = e, this.popper = t, this.offsetDistance = o, this.placement = i, this.disableOnResize =
|
|
170
|
+
const { disableOnResize: g, disableOnScroll: p } = r;
|
|
171
|
+
this.isWindowEventsRegistered = false, this.reference = e, this.popper = t, this.offsetDistance = o, this.placement = i, this.disableOnResize = g || false, this.disableOnScroll = p || false, this.onUpdate = h;
|
|
175
172
|
}
|
|
176
173
|
/**
|
|
177
174
|
* Updates popper configuration and recalculates position
|
|
@@ -184,6 +181,9 @@
|
|
|
184
181
|
this.placement = e, this.offsetDistance = t || this.offsetDistance, this.initPlacement(), this.attachWindowEvent();
|
|
185
182
|
}
|
|
186
183
|
};
|
|
184
|
+
var oe = Object.defineProperty;
|
|
185
|
+
var re = (s, e, t) => e in s ? oe(s, e, { enumerable: true, configurable: true, writable: true, value: t }) : s[e] = t;
|
|
186
|
+
var l = (s, e, t) => re(s, typeof e != "symbol" ? e + "" : e, t);
|
|
187
187
|
var ae = (s, e = document.body) => e.querySelector(s);
|
|
188
188
|
var A = (s, e) => {
|
|
189
189
|
for (const [t, n] of Object.entries(e))
|
|
@@ -197,10 +197,10 @@
|
|
|
197
197
|
}) => {
|
|
198
198
|
const o = getComputedStyle(s), i = o.transition;
|
|
199
199
|
if (i !== "none" && i !== "" && !n.includes(i)) {
|
|
200
|
-
const r = "transitionend",
|
|
201
|
-
s.removeEventListener(r,
|
|
200
|
+
const r = "transitionend", h = () => {
|
|
201
|
+
s.removeEventListener(r, h), e();
|
|
202
202
|
};
|
|
203
|
-
s.addEventListener(r,
|
|
203
|
+
s.addEventListener(r, h, { once: true });
|
|
204
204
|
} else
|
|
205
205
|
e();
|
|
206
206
|
};
|
|
@@ -216,10 +216,11 @@
|
|
|
216
216
|
});
|
|
217
217
|
};
|
|
218
218
|
var b = ({ state: s, trigger: e, popper: t }) => {
|
|
219
|
+
const n = s === "open";
|
|
219
220
|
A(t, {
|
|
220
221
|
"data-state": s
|
|
221
222
|
}), A(e, {
|
|
222
|
-
"aria-expanded": `${
|
|
223
|
+
"aria-expanded": `${n}`
|
|
223
224
|
});
|
|
224
225
|
};
|
|
225
226
|
var ce = class {
|
|
@@ -229,43 +230,47 @@
|
|
|
229
230
|
* @param {string | HTMLElement} params.trigger - The trigger element selector or HTMLElement
|
|
230
231
|
* @param {string | HTMLElement} params.content - The content element selector or HTMLElement
|
|
231
232
|
* @param {OverlayOptions} [params.options] - Configuration options for the overlay
|
|
232
|
-
* @throws {Error} When trigger or content elements are invalid
|
|
233
233
|
*/
|
|
234
234
|
constructor({ trigger: e, content: t, options: n = {} }) {
|
|
235
|
-
|
|
235
|
+
l(this, "triggerElement"), l(this, "contentElement"), l(this, "triggerStrategy"), l(this, "placement"), l(this, "offsetDistance"), l(this, "preventFromCloseOutside"), l(this, "preventFromCloseInside"), l(this, "options"), l(this, "defaultState"), l(this, "popper"), l(this, "eventEffect"), l(this, "getElement", (i) => typeof i == "string" ? ae(i) : i instanceof HTMLElement ? i : void 0), l(this, "handleDocumentClick", (i) => {
|
|
236
236
|
this.contentElement.getAttribute("data-state") === "open" && (!this.triggerElement.contains(i.target) && !this.preventFromCloseInside && !this.preventFromCloseOutside ? this.hide() : !this.triggerElement.contains(i.target) && !this.contentElement.contains(i.target) && !this.preventFromCloseOutside ? this.hide() : !this.triggerElement.contains(i.target) && !this.contentElement.contains(i.target) && !this.preventFromCloseOutside ? this.hide() : !this.triggerElement.contains(i.target) && this.contentElement.contains(i.target) && !this.preventFromCloseInside && this.hide());
|
|
237
|
-
}),
|
|
237
|
+
}), l(this, "handleKeyDown", (i) => {
|
|
238
238
|
i.preventDefault(), this.triggerStrategy !== "hover" && i.key === "Escape" && this.contentElement.getAttribute("data-state") === "open" && (this.preventFromCloseOutside || this.hide());
|
|
239
|
-
}),
|
|
239
|
+
}), l(this, "toggleStateOnClick", () => {
|
|
240
240
|
(this.contentElement.dataset.state || "close") === "close" ? (this.show(), this.triggerStrategy === "hover" && this.addEventOnMouseEnter()) : this.hide();
|
|
241
|
-
}),
|
|
241
|
+
}), l(this, "hideOnMouseLeaseTrigger", () => {
|
|
242
242
|
setTimeout(() => {
|
|
243
243
|
this.contentElement.matches(":hover") || this.hide();
|
|
244
244
|
}, 150);
|
|
245
|
-
}),
|
|
245
|
+
}), l(this, "hideOnMouseLeave", () => {
|
|
246
246
|
setTimeout(() => {
|
|
247
247
|
this.triggerElement.matches(":hover") || this.hide();
|
|
248
248
|
}, 150);
|
|
249
|
-
}),
|
|
249
|
+
}), l(this, "addEventOnMouseEnter", () => {
|
|
250
250
|
this.triggerElement.addEventListener("mouseleave", this.hideOnMouseLeaseTrigger), this.contentElement.addEventListener("mouseleave", this.hideOnMouseLeave);
|
|
251
|
-
}),
|
|
251
|
+
}), l(this, "showOnMouseEnter", () => {
|
|
252
252
|
this.show(), this.addEventOnMouseEnter();
|
|
253
|
-
}),
|
|
254
|
-
var
|
|
253
|
+
}), l(this, "setShowOptions", ({ placement: i, offsetDistance: r }) => {
|
|
254
|
+
var h, g, p, c;
|
|
255
255
|
this.popper.setOptions({
|
|
256
256
|
placement: i,
|
|
257
257
|
offsetDistance: r
|
|
258
|
-
}), document.addEventListener("keydown", this.handleKeyDown), document.addEventListener("click", this.handleDocumentClick), (
|
|
258
|
+
}), document.addEventListener("keydown", this.handleKeyDown), document.addEventListener("click", this.handleDocumentClick), (g = (h = this.options).beforeShow) == null || g.call(h), b({
|
|
259
259
|
state: "open",
|
|
260
260
|
popper: this.contentElement,
|
|
261
261
|
trigger: this.triggerElement
|
|
262
|
-
}), this.onToggleState(false), (c = (
|
|
263
|
-
}),
|
|
262
|
+
}), this.onToggleState(false), (c = (p = this.options).onShow) == null || c.call(p);
|
|
263
|
+
}), l(this, "setPopperOptions", ({ placement: i, offsetDistance: r }) => {
|
|
264
264
|
this.popper.setOptions({
|
|
265
265
|
placement: i,
|
|
266
|
-
offsetDistance: r
|
|
266
|
+
offsetDistance: r || this.offsetDistance
|
|
267
267
|
});
|
|
268
|
-
}),
|
|
268
|
+
}), l(this, "setPopperTrigger", (i, r) => {
|
|
269
|
+
this.cleanup(), this.popper.setOptions({
|
|
270
|
+
placement: r.placement || this.placement,
|
|
271
|
+
offsetDistance: r.offsetDistance || this.offsetDistance
|
|
272
|
+
}), this.triggerElement = i, this.triggerElement.addEventListener("click", this.toggleStateOnClick), this.triggerStrategy === "hover" && this.triggerElement.addEventListener("mouseenter", this.showOnMouseEnter);
|
|
273
|
+
}), l(this, "cleanup", () => {
|
|
269
274
|
this.triggerElement.removeEventListener("click", this.toggleStateOnClick), this.triggerStrategy === "hover" && this.triggerElement.removeEventListener("mouseenter", this.showOnMouseEnter);
|
|
270
275
|
});
|
|
271
276
|
var o;
|
|
@@ -273,7 +278,7 @@
|
|
|
273
278
|
throw new Error("Trigger element must be a valid HTML element");
|
|
274
279
|
if (!(this.contentElement instanceof HTMLElement))
|
|
275
280
|
throw new Error("Content element must be a valid HTML element");
|
|
276
|
-
this.options = n, this.triggerStrategy = this.options.triggerStrategy || "click", this.placement = this.options.placement || "bottom", this.offsetDistance = this.options.offsetDistance || 6, this.preventFromCloseOutside = this.options.preventFromCloseOutside || false, this.preventFromCloseInside = this.options.preventCloseFromInside || false, this.defaultState = this.options.defaultState || "close", this.eventEffect = (o = this.options.popper) == null ? void 0 : o.eventEffect, this.popper = new
|
|
281
|
+
this.options = n, this.triggerStrategy = this.options.triggerStrategy || "click", this.placement = this.options.placement || "bottom", this.offsetDistance = this.options.offsetDistance || 6, this.preventFromCloseOutside = this.options.preventFromCloseOutside || false, this.preventFromCloseInside = this.options.preventCloseFromInside || false, this.defaultState = this.options.defaultState || "close", this.eventEffect = (o = this.options.popper) == null ? void 0 : o.eventEffect, this.popper = new ie(
|
|
277
282
|
this.triggerElement,
|
|
278
283
|
this.contentElement,
|
|
279
284
|
{
|
|
@@ -329,42 +334,42 @@
|
|
|
329
334
|
}), this.triggerElement.addEventListener("click", this.toggleStateOnClick), this.triggerStrategy === "hover" && this.triggerElement.addEventListener("mouseenter", this.showOnMouseEnter);
|
|
330
335
|
}
|
|
331
336
|
};
|
|
332
|
-
var
|
|
337
|
+
var P = (s, e = document.body) => e.querySelector(s);
|
|
333
338
|
var U = (s, e = document.body) => Array.from(e.querySelectorAll(s));
|
|
334
|
-
var
|
|
335
|
-
var
|
|
339
|
+
var pe = (s) => typeof s == "string" ? P(s) : s;
|
|
340
|
+
var de = ({ containerElement: s, targetChildren: e = "a:not([disabled]), button:not([disabled])", direction: t }) => {
|
|
336
341
|
let n = false;
|
|
337
|
-
const o =
|
|
338
|
-
if (
|
|
342
|
+
const o = pe(s) || document.body, i = typeof e == "string" ? U(e, o) : e, r = (h) => {
|
|
343
|
+
if (h.preventDefault(), o.focus(), i.length === 0)
|
|
339
344
|
return;
|
|
340
|
-
const
|
|
341
|
-
let c = i.findIndex((
|
|
345
|
+
const g = h.key, p = document.activeElement;
|
|
346
|
+
let c = i.findIndex((m) => m === p);
|
|
342
347
|
if (c === -1) {
|
|
343
|
-
|
|
348
|
+
g === "ArrowUp" || g === "ArrowLeft" ? i[i.length - 1].focus() : i[0].focus();
|
|
344
349
|
return;
|
|
345
350
|
}
|
|
346
|
-
const f = (
|
|
347
|
-
switch (
|
|
351
|
+
const f = (m) => m > 0 ? m - 1 : i.length - 1, v = (m) => m < i.length - 1 ? m + 1 : 0;
|
|
352
|
+
switch (g) {
|
|
348
353
|
case "ArrowDown":
|
|
349
|
-
|
|
354
|
+
h.preventDefault(), c = v(c);
|
|
350
355
|
break;
|
|
351
356
|
case "ArrowRight":
|
|
352
357
|
break;
|
|
353
358
|
case "ArrowUp":
|
|
354
|
-
|
|
359
|
+
h.preventDefault(), c = f(c);
|
|
355
360
|
break;
|
|
356
361
|
case "ArrowLeft":
|
|
357
362
|
break;
|
|
358
363
|
case "Home":
|
|
359
|
-
|
|
364
|
+
h.preventDefault(), c = 0;
|
|
360
365
|
break;
|
|
361
366
|
case "End":
|
|
362
|
-
|
|
367
|
+
h.preventDefault(), c = i.length - 1;
|
|
363
368
|
break;
|
|
364
369
|
default:
|
|
365
370
|
return;
|
|
366
371
|
}
|
|
367
|
-
i[c] !==
|
|
372
|
+
i[c] !== p && i[c].focus();
|
|
368
373
|
};
|
|
369
374
|
return {
|
|
370
375
|
make: () => {
|
|
@@ -375,7 +380,7 @@
|
|
|
375
380
|
}
|
|
376
381
|
};
|
|
377
382
|
};
|
|
378
|
-
var
|
|
383
|
+
var z = (s, e, t) => {
|
|
379
384
|
const n = new CustomEvent(e, { detail: t });
|
|
380
385
|
s.dispatchEvent(n);
|
|
381
386
|
};
|
|
@@ -406,52 +411,58 @@
|
|
|
406
411
|
* @throws {Error} If provided elements are not valid HTMLElements
|
|
407
412
|
*/
|
|
408
413
|
constructor(e, t = {}) {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
414
|
+
a(this, "triggerElement");
|
|
415
|
+
a(this, "contentElement");
|
|
416
|
+
a(this, "options");
|
|
417
|
+
a(this, "OverlayInstance");
|
|
418
|
+
a(this, "navigationKeys");
|
|
419
|
+
a(this, "triggerStrategy");
|
|
420
|
+
a(this, "placement");
|
|
421
|
+
a(this, "offsetDistance");
|
|
422
|
+
a(this, "preventFromCloseOutside");
|
|
423
|
+
a(this, "preventFromCloseInside");
|
|
424
|
+
a(this, "defaultState");
|
|
425
|
+
a(this, "onToggle", ({ isHidden: e2 }) => {
|
|
421
426
|
var t2, n2;
|
|
422
427
|
(n2 = (t2 = this.options).onToggle) == null || n2.call(t2, { isHidden: e2 });
|
|
423
428
|
});
|
|
424
|
-
|
|
429
|
+
a(this, "beforeShow", () => {
|
|
425
430
|
this.contentElement.focus(), this.navigationKeys.make();
|
|
426
431
|
});
|
|
427
|
-
|
|
432
|
+
a(this, "beforeHide", () => {
|
|
428
433
|
this.contentElement.blur(), this.navigationKeys.destroy();
|
|
429
434
|
});
|
|
430
|
-
|
|
435
|
+
a(this, "onShow", () => {
|
|
431
436
|
var e2, t2;
|
|
432
|
-
|
|
437
|
+
z(this.contentElement, "dropdown-show", {
|
|
433
438
|
isHidden: false
|
|
434
439
|
}), (t2 = (e2 = this.options).onShow) == null || t2.call(e2);
|
|
435
440
|
});
|
|
436
|
-
|
|
441
|
+
a(this, "onHide", () => {
|
|
437
442
|
var e2, t2;
|
|
438
|
-
|
|
443
|
+
z(this.contentElement, "dropdown-hide", {
|
|
439
444
|
isHidden: true
|
|
440
445
|
}), (t2 = (e2 = this.options).onHide) == null || t2.call(e2);
|
|
441
446
|
});
|
|
442
|
-
|
|
447
|
+
a(this, "show", () => {
|
|
443
448
|
this.OverlayInstance.show();
|
|
444
449
|
});
|
|
445
|
-
|
|
450
|
+
a(this, "hide", () => {
|
|
446
451
|
this.OverlayInstance.hide();
|
|
447
452
|
});
|
|
448
|
-
|
|
453
|
+
a(this, "setShowOptions", ({ placement: e2, offsetDistance: t2 }) => {
|
|
449
454
|
this.OverlayInstance.setShowOptions({ placement: e2, offsetDistance: t2 });
|
|
450
455
|
});
|
|
451
|
-
|
|
456
|
+
a(this, "setOptions", ({ placement: e2, offsetDistance: t2 }) => {
|
|
457
|
+
this.OverlayInstance.setPopperOptions({ placement: e2, offsetDistance: t2 });
|
|
458
|
+
});
|
|
459
|
+
a(this, "setPopperTrigger", (e2, t2) => {
|
|
460
|
+
this.OverlayInstance.setPopperTrigger(e2, t2);
|
|
461
|
+
});
|
|
462
|
+
a(this, "cleanup", () => {
|
|
452
463
|
this.OverlayInstance.cleanup(), x.removeInstance("dropdown", this.contentElement);
|
|
453
464
|
});
|
|
454
|
-
const n = typeof e == "string" ?
|
|
465
|
+
const n = typeof e == "string" ? P(e) : e;
|
|
455
466
|
if (!(n instanceof HTMLElement))
|
|
456
467
|
throw new Error(
|
|
457
468
|
"Invalid dropdown content element: Must provide either a valid HTMLElement or a selector string that resolves to an existing HTMLElement"
|
|
@@ -463,7 +474,7 @@
|
|
|
463
474
|
if (o)
|
|
464
475
|
return o;
|
|
465
476
|
const i = `[data-dropdown-trigger][data-dropdown-id=${this.contentElement.id}]`;
|
|
466
|
-
if (this.triggerElement =
|
|
477
|
+
if (this.triggerElement = P(i), !(this.triggerElement instanceof HTMLElement))
|
|
467
478
|
throw new Error(`No valid trigger element found. Ensure a trigger element exists with attributes: data-dropdown-trigger and data-dropdown-id="${this.contentElement.id}"`);
|
|
468
479
|
this.options = t, this.triggerStrategy = this.options.triggerStrategy || this.contentElement.dataset.triggerStrategy || "click", this.placement = this.options.placement || this.contentElement.dataset.placement || "bottom-start", this.offsetDistance = this.options.offsetDistance || parseInt(`${this.contentElement.dataset.offsetDistance}`) | 6, this.preventFromCloseOutside = this.options.preventFromCloseOutside || this.contentElement.hasAttribute("data-prevent-close-outside") || false, this.preventFromCloseInside = this.options.preventCloseFromInside || this.contentElement.hasAttribute("data-prevent-close-inside") || false, this.defaultState = this.options.defaultState || this.contentElement.dataset.defaultState || "close", this.OverlayInstance = new ce({
|
|
469
480
|
trigger: this.triggerElement,
|
|
@@ -484,7 +495,7 @@
|
|
|
484
495
|
},
|
|
485
496
|
popper: this.options.popper
|
|
486
497
|
}
|
|
487
|
-
}), this.navigationKeys =
|
|
498
|
+
}), this.navigationKeys = de({
|
|
488
499
|
containerElement: this.contentElement,
|
|
489
500
|
targetChildren: "a:not([disabled]), button:not([disabled])",
|
|
490
501
|
direction: "up-down"
|
|
@@ -500,17 +511,17 @@
|
|
|
500
511
|
new S2(e, t);
|
|
501
512
|
}
|
|
502
513
|
};
|
|
503
|
-
|
|
514
|
+
a(S, "autoInit", (e = "[data-fx-dropdown]") => {
|
|
504
515
|
const t = U(e);
|
|
505
516
|
for (const n of t)
|
|
506
517
|
new S(n);
|
|
507
518
|
});
|
|
508
|
-
var
|
|
519
|
+
var K = S;
|
|
509
520
|
|
|
510
521
|
// src/index.js
|
|
511
522
|
function Dropdown(Alpine) {
|
|
512
523
|
Alpine.directive("dropdown", (el, {}, { cleanup }) => {
|
|
513
|
-
const dropdown_ = new
|
|
524
|
+
const dropdown_ = new K(el);
|
|
514
525
|
cleanup(() => {
|
|
515
526
|
dropdown_.cleanup();
|
|
516
527
|
});
|