@flexilla/alpine-dropdown 0.1.0 → 0.2.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/dist/cdn.js CHANGED
@@ -1,69 +1,69 @@
1
1
  (() => {
2
2
  // ../../node_modules/@flexilla/dropdown/dist/dropdown.js
3
- var j = Object.defineProperty;
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 a = (s, e, t) => q(s, typeof e != "symbol" ? e + "" : e, t);
6
3
  var B = Object.defineProperty;
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 d = (s, e, t) => N(s, typeof e != "symbol" ? e + "" : e, t);
4
+ var j = (i, e, t) => e in i ? B(i, e, { enumerable: true, configurable: true, writable: true, value: t }) : i[e] = t;
5
+ var a = (i, e, t) => j(i, typeof e != "symbol" ? e + "" : e, t);
6
+ var G = Object.defineProperty;
7
+ var q = (i, e, t) => e in i ? G(i, e, { enumerable: true, configurable: true, writable: true, value: t }) : i[e] = t;
8
+ var p = (i, e, t) => q(i, typeof e != "symbol" ? e + "" : e, t);
9
9
  var V = "bottom";
10
- var X = ({ reference: s, popper: e }) => {
11
- if (!s || !e)
10
+ var X = ({ reference: i, popper: e }) => {
11
+ if (!i || !e)
12
12
  throw new Error("Reference or popper element is null or undefined");
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);
13
+ const t = /* @__PURE__ */ new WeakMap(), n = (o) => (t.has(o) || t.set(o, o.getBoundingClientRect()), t.get(o)), r = n(e), s = n(i);
14
14
  return {
15
- popperHeight: o.height,
16
- popperWidth: o.width,
17
- refHeight: i.height,
18
- refWidth: i.width,
19
- refLeft: i.left,
20
- refTop: i.top,
21
- refRight: i.right
15
+ popperHeight: r.height,
16
+ popperWidth: r.width,
17
+ refHeight: s.height,
18
+ refWidth: s.width,
19
+ refLeft: s.left,
20
+ refTop: s.top,
21
+ refRight: s.right
22
22
  };
23
23
  };
24
- var Y = (s, e, t, n) => {
25
- const o = t, i = n - (t + e);
26
- return o >= (s - e) / 2 && i >= (s - e) / 2;
24
+ var Y = (i, e, t, n) => {
25
+ const r = t, s = n - (t + e);
26
+ return r >= (i - e) / 2 && s >= (i - e) / 2;
27
27
  };
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;
28
+ var J = (i, e, t, n) => (i - e) / 2 <= t && t + i / 2 + e / 2 <= n;
29
+ var Q = (i, e, t, n, r) => t > r - n ? e() ? window.innerHeight - r : t - r : i() ? 0 : t + n;
30
+ var Z = (i, e, t, n) => i <= n && t - i <= e;
31
+ var _ = (i, e, t, n) => t <= n && -i <= e;
32
+ var ee = (i, e, t, n, r, s) => {
33
+ const o = r - t - s, l = t - n, m = t + s - n + (r - t - s), c = o >= 0 ? r - n : l >= 0 ? t - n : t;
34
+ return i() ? 0 : e() ? m : c;
35
35
  };
36
- var te = (s, e, t, n) => s <= t && e - s - n >= s;
37
- var ne = (s, e) => s >= e;
38
- var se = ({
39
- placement: s,
36
+ var te = (i, e, t, n) => i <= t && e - i - n >= i;
37
+ var ne = (i, e) => i >= e;
38
+ var ie = ({
39
+ placement: i,
40
40
  refWidth: e,
41
41
  refTop: t,
42
42
  refLeft: n,
43
- refHeight: o,
44
- popperWidth: i,
45
- popperHeight: r,
46
- windowHeight: h,
47
- windowWidth: g,
48
- offsetDistance: p
43
+ refHeight: r,
44
+ popperWidth: s,
45
+ popperHeight: o,
46
+ windowHeight: l,
47
+ windowWidth: m,
48
+ offsetDistance: c
49
49
  }) => {
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),
50
+ const d = m - n - e, f = n, E = l - t - r, g = t, w = () => Q(
51
+ () => _(t, r, o, l),
52
+ () => Z(t, r, o, l),
53
53
  t,
54
- o,
55
- r
56
- ), y = () => ee(
57
- () => te(n, g, i, e),
58
- () => ne(n, i),
54
+ r,
55
+ o
56
+ ), b = () => ee(
57
+ () => te(n, m, s, e),
58
+ () => ne(n, s),
59
59
  n,
60
- i,
61
- g,
60
+ s,
61
+ m,
62
62
  e
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();
64
- let u = 0, E = 0;
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) {
63
+ ), H = () => Y(s, e, n, m) ? n + e / 2 - s / 2 : b(), M = () => J(o, r, t, l) ? t + r / 2 - o / 2 : w(), A = () => n + s <= m ? n : b(), k = () => n + e - s >= 0 ? n + e - s : b(), L = () => t + o <= l ? t : w(), U = () => t + r - o >= 0 ? t + r - o : w();
64
+ let u = 0, v = 0;
65
+ const C = t - o - c, x = t + r + c, I = n - s - c, D = n + e + c, W = g >= o + c, F = E >= o + c, R = f >= s + c, $ = d >= s + c;
66
+ switch (i.startsWith("top") ? v = W ? C : F ? x : Math.max(C, x) : i.startsWith("bottom") ? v = F ? x : W ? C : Math.max(x) : i.startsWith("left") ? u = R ? I : $ ? D : Math.max(I, D) : i.startsWith("right") && (u = $ ? D : R ? I : Math.max(D, I)), i) {
67
67
  case "bottom":
68
68
  case "bottom-middle":
69
69
  case "top":
@@ -74,28 +74,28 @@
74
74
  case "left-middle":
75
75
  case "right":
76
76
  case "right-middle":
77
- E = T();
77
+ v = M();
78
78
  break;
79
79
  case "bottom-start":
80
80
  case "top-start":
81
- u = C();
81
+ u = A();
82
82
  break;
83
83
  case "bottom-end":
84
84
  case "top-end":
85
- u = O();
85
+ u = k();
86
86
  break;
87
87
  case "left-start":
88
88
  case "right-start":
89
- E = L();
89
+ v = L();
90
90
  break;
91
91
  case "left-end":
92
92
  case "right-end":
93
- E = G();
93
+ v = U();
94
94
  break;
95
95
  }
96
- return { x: u, y: E };
96
+ return { x: u, y: v };
97
97
  };
98
- var ie = class {
98
+ var se = class {
99
99
  /**
100
100
  * Flexilla Popper
101
101
  * @param reference
@@ -115,51 +115,51 @@
115
115
  * @param {Function} [options.onUpdate] - Callback function when position updates
116
116
  */
117
117
  constructor(e, t, n = {}) {
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", () => {
118
+ p(this, "reference"), p(this, "popper"), p(this, "offsetDistance"), p(this, "placement"), p(this, "disableOnResize"), p(this, "disableOnScroll"), p(this, "onUpdate"), p(this, "isWindowEventsRegistered"), p(this, "validateElements", () => {
119
119
  if (!(this.reference instanceof HTMLElement))
120
120
  throw new Error("Invalid HTMLElement for Reference Element");
121
121
  if (!(this.popper instanceof HTMLElement))
122
122
  throw new Error("Invalid HTMLElement for Popper");
123
123
  if (typeof this.offsetDistance != "number")
124
124
  throw new Error("OffsetDistance must be a number");
125
- }), d(this, "setPopperStyleProperty", (c, f) => {
126
- this.popper.style.setProperty("--fx-popper-placement-x", `${c}px`), this.popper.style.setProperty("--fx-popper-placement-y", `${f}px`);
127
- }), d(this, "setInitialStyles", () => {
125
+ }), p(this, "setPopperStyleProperty", (d, f) => {
126
+ this.popper.style.setProperty("--fx-popper-placement-x", `${d}px`), this.popper.style.setProperty("--fx-popper-placement-y", `${f}px`);
127
+ }), p(this, "setInitialStyles", () => {
128
128
  this.popper.style.setProperty("--fx-popper-placement-x", ""), this.popper.style.setProperty("--fx-popper-placement-y", "");
129
- }), d(this, "initPlacement", () => {
130
- var c;
129
+ }), p(this, "initPlacement", () => {
130
+ var d;
131
131
  this.validateElements(), this.setInitialStyles();
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(
132
+ const f = window.innerWidth, E = window.innerHeight, { popperHeight: g, popperWidth: w, refHeight: b, refWidth: H, refLeft: M, refTop: A } = X({ reference: this.reference, popper: this.popper }), { x: k, y: L } = ie(
133
133
  {
134
134
  placement: this.placement,
135
135
  refWidth: H,
136
- refTop: C,
137
- refLeft: T,
136
+ refTop: A,
137
+ refLeft: M,
138
138
  popperWidth: w,
139
- refHeight: y,
140
- popperHeight: m,
141
- windowHeight: v,
139
+ refHeight: b,
140
+ popperHeight: g,
141
+ windowHeight: E,
142
142
  windowWidth: f,
143
143
  offsetDistance: this.offsetDistance
144
144
  }
145
145
  );
146
- this.setPopperStyleProperty(O, L), (c = this.onUpdate) == null || c.call(this, { x: O, y: L, placement: this.placement });
147
- }), d(this, "removeWindowEvents", () => {
146
+ this.setPopperStyleProperty(k, L), (d = this.onUpdate) == null || d.call(this, { x: k, y: L, placement: this.placement });
147
+ }), p(this, "removeWindowEvents", () => {
148
148
  this.isWindowEventsRegistered && (!this.disableOnResize && window.removeEventListener("resize", this.updatePosition), !this.disableOnScroll && window.removeEventListener("scroll", this.updatePosition), this.isWindowEventsRegistered = false);
149
- }), d(this, "attachWindowEvent", () => {
149
+ }), p(this, "attachWindowEvent", () => {
150
150
  this.isWindowEventsRegistered && this.removeWindowEvents(), this.disableOnResize || window.addEventListener("resize", this.updatePosition), this.disableOnScroll || window.addEventListener("scroll", this.updatePosition), this.isWindowEventsRegistered = true;
151
- }), d(this, "resetPosition", () => {
151
+ }), p(this, "resetPosition", () => {
152
152
  this.setInitialStyles();
153
- }), d(this, "updatePosition", () => {
153
+ }), p(this, "updatePosition", () => {
154
154
  this.initPlacement(), this.attachWindowEvent();
155
- }), d(this, "cleanupEvents", () => {
155
+ }), p(this, "cleanupEvents", () => {
156
156
  this.setInitialStyles(), this.removeWindowEvents();
157
157
  });
158
158
  const {
159
- offsetDistance: o = 10,
160
- placement: i = V,
161
- eventEffect: r = {},
162
- onUpdate: h
159
+ offsetDistance: r = 10,
160
+ placement: s = V,
161
+ eventEffect: o = {},
162
+ onUpdate: l
163
163
  } = n;
164
164
  if (!(e instanceof HTMLElement))
165
165
  throw new Error("Invalid HTMLElement for Reference Element");
@@ -167,8 +167,8 @@
167
167
  throw new Error("Invalid HTMLElement for Popper");
168
168
  if (n.offsetDistance && typeof n.offsetDistance != "number")
169
169
  throw new Error("OffsetDistance must be a number");
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;
170
+ const { disableOnResize: m, disableOnScroll: c } = o;
171
+ this.isWindowEventsRegistered = false, this.reference = e, this.popper = t, this.offsetDistance = r, this.placement = s, this.disableOnResize = m || false, this.disableOnScroll = c || false, this.onUpdate = l;
172
172
  }
173
173
  /**
174
174
  * Updates popper configuration and recalculates position
@@ -181,45 +181,49 @@
181
181
  this.placement = e, this.offsetDistance = t || this.offsetDistance, this.initPlacement(), this.attachWindowEvent();
182
182
  }
183
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
- var ae = (s, e = document.body) => e.querySelector(s);
188
- var A = (s, e) => {
184
+ var re = Object.defineProperty;
185
+ var oe = (i, e, t) => e in i ? re(i, e, { enumerable: true, configurable: true, writable: true, value: t }) : i[e] = t;
186
+ var h = (i, e, t) => oe(i, typeof e != "symbol" ? e + "" : e, t);
187
+ var ae = (i, e = document.body) => e.querySelector(i);
188
+ var N = (i, e) => {
189
189
  for (const [t, n] of Object.entries(e))
190
- s.setAttribute(t, n);
190
+ i.setAttribute(t, n);
191
191
  };
192
192
  var le = ({
193
- element: s,
193
+ element: i,
194
194
  callback: e,
195
195
  type: t,
196
196
  keysCheck: n
197
197
  }) => {
198
- const o = getComputedStyle(s), i = o.transition;
199
- if (i !== "none" && i !== "" && !n.includes(i)) {
200
- const r = "transitionend", h = () => {
201
- s.removeEventListener(r, h), e();
198
+ const r = getComputedStyle(i), s = r.transition;
199
+ if (s !== "none" && s !== "" && !n.includes(s)) {
200
+ const o = "transitionend", l = () => {
201
+ i.removeEventListener(o, l), e();
202
202
  };
203
- s.addEventListener(r, h, { once: true });
203
+ i.addEventListener(o, l, { once: true });
204
204
  } else
205
205
  e();
206
206
  };
207
207
  var he = ({
208
- element: s,
208
+ element: i,
209
209
  callback: e
210
210
  }) => {
211
211
  le({
212
- element: s,
212
+ element: i,
213
213
  callback: e,
214
214
  type: "transition",
215
215
  keysCheck: ["all 0s ease 0s", "all"]
216
216
  });
217
217
  };
218
- var b = ({ state: s, trigger: e, popper: t }) => {
219
- const n = s === "open";
220
- A(t, {
221
- "data-state": s
222
- }), A(e, {
218
+ var de = (i, e, t) => {
219
+ const n = new CustomEvent(e, { detail: t });
220
+ i.dispatchEvent(n);
221
+ };
222
+ var y = ({ state: i, trigger: e, popper: t }) => {
223
+ const n = i === "open";
224
+ N(t, {
225
+ "data-state": i
226
+ }), N(e, {
223
227
  "aria-expanded": `${n}`
224
228
  });
225
229
  };
@@ -232,53 +236,53 @@
232
236
  * @param {OverlayOptions} [params.options] - Configuration options for the overlay
233
237
  */
234
238
  constructor({ trigger: e, content: t, options: n = {} }) {
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
- 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
- }), l(this, "handleKeyDown", (i) => {
238
- i.preventDefault(), this.triggerStrategy !== "hover" && i.key === "Escape" && this.contentElement.getAttribute("data-state") === "open" && (this.preventFromCloseOutside || this.hide());
239
- }), l(this, "toggleStateOnClick", () => {
239
+ h(this, "triggerElement"), h(this, "contentElement"), h(this, "triggerStrategy"), h(this, "placement"), h(this, "offsetDistance"), h(this, "preventFromCloseOutside"), h(this, "preventFromCloseInside"), h(this, "options"), h(this, "defaultState"), h(this, "popper"), h(this, "eventEffect"), h(this, "getElement", (s) => typeof s == "string" ? ae(s) : s instanceof HTMLElement ? s : void 0), h(this, "handleDocumentClick", (s) => {
240
+ this.contentElement.getAttribute("data-state") === "open" && (!this.triggerElement.contains(s.target) && !this.preventFromCloseInside && !this.preventFromCloseOutside ? this.hide() : !this.triggerElement.contains(s.target) && !this.contentElement.contains(s.target) && !this.preventFromCloseOutside ? this.hide() : !this.triggerElement.contains(s.target) && !this.contentElement.contains(s.target) && !this.preventFromCloseOutside ? this.hide() : !this.triggerElement.contains(s.target) && this.contentElement.contains(s.target) && !this.preventFromCloseInside && this.hide());
241
+ }), h(this, "handleKeyDown", (s) => {
242
+ s.preventDefault(), this.triggerStrategy !== "hover" && s.key === "Escape" && this.contentElement.getAttribute("data-state") === "open" && (this.preventFromCloseOutside || this.hide());
243
+ }), h(this, "toggleStateOnClick", () => {
240
244
  (this.contentElement.dataset.state || "close") === "close" ? (this.show(), this.triggerStrategy === "hover" && this.addEventOnMouseEnter()) : this.hide();
241
- }), l(this, "hideOnMouseLeaseTrigger", () => {
245
+ }), h(this, "hideOnMouseLeaseTrigger", () => {
242
246
  setTimeout(() => {
243
247
  this.contentElement.matches(":hover") || this.hide();
244
248
  }, 150);
245
- }), l(this, "hideOnMouseLeave", () => {
249
+ }), h(this, "hideOnMouseLeave", () => {
246
250
  setTimeout(() => {
247
251
  this.triggerElement.matches(":hover") || this.hide();
248
252
  }, 150);
249
- }), l(this, "addEventOnMouseEnter", () => {
253
+ }), h(this, "addEventOnMouseEnter", () => {
250
254
  this.triggerElement.addEventListener("mouseleave", this.hideOnMouseLeaseTrigger), this.contentElement.addEventListener("mouseleave", this.hideOnMouseLeave);
251
- }), l(this, "showOnMouseEnter", () => {
255
+ }), h(this, "showOnMouseEnter", () => {
252
256
  this.show(), this.addEventOnMouseEnter();
253
- }), l(this, "setShowOptions", ({ placement: i, offsetDistance: r }) => {
254
- var h, g, p, c;
257
+ }), h(this, "setShowOptions", ({ placement: s, offsetDistance: o }) => {
258
+ var l, m, c, d;
255
259
  this.popper.setOptions({
256
- placement: i,
257
- offsetDistance: r
258
- }), document.addEventListener("keydown", this.handleKeyDown), document.addEventListener("click", this.handleDocumentClick), (g = (h = this.options).beforeShow) == null || g.call(h), b({
260
+ placement: s,
261
+ offsetDistance: o
262
+ }), document.addEventListener("keydown", this.handleKeyDown), document.addEventListener("click", this.handleDocumentClick), (m = (l = this.options).beforeShow) == null || m.call(l), y({
259
263
  state: "open",
260
264
  popper: this.contentElement,
261
265
  trigger: this.triggerElement
262
- }), this.onToggleState(false), (c = (p = this.options).onShow) == null || c.call(p);
263
- }), l(this, "setPopperOptions", ({ placement: i, offsetDistance: r }) => {
266
+ }), this.onToggleState(false), (d = (c = this.options).onShow) == null || d.call(c);
267
+ }), h(this, "setPopperOptions", ({ placement: s, offsetDistance: o }) => {
264
268
  this.popper.setOptions({
265
- placement: i,
266
- offsetDistance: r || this.offsetDistance
269
+ placement: s,
270
+ offsetDistance: o || this.offsetDistance
267
271
  });
268
- }), l(this, "setPopperTrigger", (i, r) => {
272
+ }), h(this, "setPopperTrigger", (s, o) => {
269
273
  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", () => {
274
+ placement: o.placement || this.placement,
275
+ offsetDistance: o.offsetDistance || this.offsetDistance
276
+ }), this.triggerElement = s, this.triggerElement.addEventListener("click", this.toggleStateOnClick), this.triggerStrategy === "hover" && this.triggerElement.addEventListener("mouseenter", this.showOnMouseEnter);
277
+ }), h(this, "cleanup", () => {
274
278
  this.triggerElement.removeEventListener("click", this.toggleStateOnClick), this.triggerStrategy === "hover" && this.triggerElement.removeEventListener("mouseenter", this.showOnMouseEnter);
275
279
  });
276
- var o;
280
+ var r;
277
281
  if (this.contentElement = this.getElement(t), this.triggerElement = this.getElement(e), !(this.triggerElement instanceof HTMLElement))
278
282
  throw new Error("Trigger element must be a valid HTML element");
279
283
  if (!(this.contentElement instanceof HTMLElement))
280
284
  throw new Error("Content element must be a valid HTML element");
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(
285
+ 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 = (r = this.options.popper) == null ? void 0 : r.eventEffect, this.popper = new se(
282
286
  this.triggerElement,
283
287
  this.contentElement,
284
288
  {
@@ -297,94 +301,132 @@
297
301
  * Positions the overlay, adds event listeners, and triggers related callbacks
298
302
  */
299
303
  show() {
300
- var e, t, n, o;
301
- this.popper.updatePosition(), document.addEventListener("keydown", this.handleKeyDown), document.addEventListener("click", this.handleDocumentClick), (t = (e = this.options).beforeShow) == null || t.call(e), b({
304
+ var e, t, n, r;
305
+ this.popper.updatePosition(), document.addEventListener("keydown", this.handleKeyDown), document.addEventListener("click", this.handleDocumentClick), (t = (e = this.options).beforeShow) == null || t.call(e), y({
302
306
  state: "open",
303
307
  popper: this.contentElement,
304
308
  trigger: this.triggerElement
305
- }), this.onToggleState(false), (o = (n = this.options).onShow) == null || o.call(n);
309
+ }), this.onToggleState(false), (r = (n = this.options).onShow) == null || r.call(n);
306
310
  }
307
311
  /**
308
312
  * Hides the overlay
309
313
  * Removes event listeners and triggers related callbacks
310
314
  */
311
315
  hide() {
312
- var e, t;
313
- (t = (e = this.options).beforeHide) == null || t.call(e), b({
316
+ var e, t, n;
317
+ let r = false;
318
+ de(this.contentElement, "before-hide", {
319
+ setExitAction: (o) => {
320
+ r = o;
321
+ }
322
+ });
323
+ const s = (n = (t = (e = this.options).beforeHide) == null ? void 0 : t.call(e)) == null ? void 0 : n.cancelAction;
324
+ r || s || (y({
314
325
  state: "close",
315
326
  popper: this.contentElement,
316
327
  trigger: this.triggerElement
317
328
  }), this.triggerStrategy === "click" && document.removeEventListener("click", this.handleDocumentClick), document.removeEventListener("keydown", this.handleKeyDown), this.triggerStrategy === "hover" && (this.triggerElement.removeEventListener("mouseleave", this.hideOnMouseLeaseTrigger), this.contentElement.removeEventListener("mouseleave", this.hideOnMouseLeave)), he({
318
329
  element: this.contentElement,
319
330
  callback: () => {
320
- var n, o;
321
- this.onToggleState(true), this.popper.cleanupEvents(), (o = (n = this.options).onHide) == null || o.call(n);
331
+ var o, l;
332
+ this.onToggleState(true), this.popper.cleanupEvents(), (l = (o = this.options).onHide) == null || l.call(o);
322
333
  }
323
- });
334
+ }));
324
335
  }
325
336
  initInstance() {
326
- b({
337
+ y({
327
338
  state: this.defaultState,
328
339
  popper: this.contentElement,
329
340
  trigger: this.triggerElement
330
- }), this.defaultState === "open" ? this.show() : b({
341
+ }), this.defaultState === "open" ? this.show() : y({
331
342
  state: "close",
332
343
  popper: this.contentElement,
333
344
  trigger: this.triggerElement
334
345
  }), this.triggerElement.addEventListener("click", this.toggleStateOnClick), this.triggerStrategy === "hover" && this.triggerElement.addEventListener("mouseenter", this.showOnMouseEnter);
335
346
  }
336
347
  };
337
- var P = (s, e = document.body) => e.querySelector(s);
338
- var U = (s, e = document.body) => Array.from(e.querySelectorAll(s));
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 }) => {
348
+ var P = (i, e = document.body) => e.querySelector(i);
349
+ var O = (i, e = document.body) => Array.from(e.querySelectorAll(i));
350
+ var pe = (i) => typeof i == "string" ? P(i) : i;
351
+ var me = ({ containerElement: i, targetChildren: e = "a:not([disabled]), button:not([disabled])", direction: t }) => {
341
352
  let n = false;
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)
353
+ const r = pe(i) || document.body, s = typeof e == "string" ? O(e, r) : e, o = (l) => {
354
+ if (l.preventDefault(), r.focus(), s.length === 0)
344
355
  return;
345
- const g = h.key, p = document.activeElement;
346
- let c = i.findIndex((m) => m === p);
347
- if (c === -1) {
348
- g === "ArrowUp" || g === "ArrowLeft" ? i[i.length - 1].focus() : i[0].focus();
356
+ const m = l.key, c = document.activeElement;
357
+ let d = s.findIndex((g) => g === c);
358
+ if (d === -1) {
359
+ m === "ArrowUp" || m === "ArrowLeft" ? s[s.length - 1].focus() : s[0].focus();
349
360
  return;
350
361
  }
351
- const f = (m) => m > 0 ? m - 1 : i.length - 1, v = (m) => m < i.length - 1 ? m + 1 : 0;
352
- switch (g) {
362
+ const f = (g) => g > 0 ? g - 1 : s.length - 1, E = (g) => g < s.length - 1 ? g + 1 : 0;
363
+ switch (m) {
353
364
  case "ArrowDown":
354
- h.preventDefault(), c = v(c);
365
+ l.preventDefault(), d = E(d);
355
366
  break;
356
367
  case "ArrowRight":
357
368
  break;
358
369
  case "ArrowUp":
359
- h.preventDefault(), c = f(c);
370
+ l.preventDefault(), d = f(d);
360
371
  break;
361
372
  case "ArrowLeft":
362
373
  break;
363
374
  case "Home":
364
- h.preventDefault(), c = 0;
375
+ l.preventDefault(), d = 0;
365
376
  break;
366
377
  case "End":
367
- h.preventDefault(), c = i.length - 1;
378
+ l.preventDefault(), d = s.length - 1;
368
379
  break;
369
380
  default:
370
381
  return;
371
382
  }
372
- i[c] !== p && i[c].focus();
383
+ s[d] !== c && s[d].focus();
373
384
  };
374
385
  return {
375
386
  make: () => {
376
- n || (document.addEventListener("keydown", r), n = true);
387
+ n || (document.addEventListener("keydown", o), n = true);
377
388
  },
378
389
  destroy: () => {
379
- n && (document.removeEventListener("keydown", r), n = false);
390
+ n && (document.removeEventListener("keydown", o), n = false);
380
391
  }
381
392
  };
382
393
  };
383
- var z = (s, e, t) => {
394
+ var K = (i, e, t) => {
384
395
  const n = new CustomEvent(e, { detail: t });
385
- s.dispatchEvent(n);
396
+ i.dispatchEvent(n);
386
397
  };
387
- var x = class {
398
+ function ge(i, e, t = "move") {
399
+ if (!(i instanceof HTMLElement))
400
+ throw new Error("Source element must be an HTMLElement");
401
+ if (!(e instanceof HTMLElement))
402
+ throw new Error("Target element must be an HTMLElement");
403
+ if (!["move", "detachable"].includes(t))
404
+ throw new Error(`Invalid teleport mode: ${t}. Must be "move" or "detachable".`);
405
+ let n = document.createComment("teleporter-placeholder");
406
+ const r = i.parentNode;
407
+ return r ? r.insertBefore(n, i) : console.warn("Element has no parent; placeholder not inserted."), t === "move" ? (i.parentNode && e.appendChild(i), {
408
+ append() {
409
+ i.parentNode !== e && e.appendChild(i);
410
+ },
411
+ remove() {
412
+ n != null && n.parentNode && i.parentNode && n.parentNode.insertBefore(i, n);
413
+ },
414
+ restore() {
415
+ n != null && n.parentNode && i.parentNode !== r && n.parentNode.insertBefore(i, n);
416
+ }
417
+ }) : (i.parentNode && e.appendChild(i), {
418
+ append() {
419
+ e.contains(i) || e.appendChild(i);
420
+ },
421
+ remove() {
422
+ i.parentNode && i.remove();
423
+ },
424
+ restore() {
425
+ n != null && n.parentNode && !i.parentNode && n.parentNode.insertBefore(i, n);
426
+ }
427
+ });
428
+ }
429
+ var T = class {
388
430
  static initGlobalRegistry() {
389
431
  window.$flexillaInstances || (window.$flexillaInstances = {});
390
432
  }
@@ -392,10 +434,10 @@
392
434
  return this.initGlobalRegistry(), window.$flexillaInstances[e] || (window.$flexillaInstances[e] = []), this.getInstance(e, t) || (window.$flexillaInstances[e].push({ element: t, instance: n }), n);
393
435
  }
394
436
  static getInstance(e, t) {
395
- var n, o;
396
- return this.initGlobalRegistry(), (o = (n = window.$flexillaInstances[e]) == null ? void 0 : n.find(
397
- (i) => i.element === t
398
- )) == null ? void 0 : o.instance;
437
+ var n, r;
438
+ return this.initGlobalRegistry(), (r = (n = window.$flexillaInstances[e]) == null ? void 0 : n.find(
439
+ (s) => s.element === t
440
+ )) == null ? void 0 : r.instance;
399
441
  }
400
442
  static removeInstance(e, t) {
401
443
  this.initGlobalRegistry(), window.$flexillaInstances[e] && (window.$flexillaInstances[e] = window.$flexillaInstances[e].filter(
@@ -403,6 +445,10 @@
403
445
  ));
404
446
  }
405
447
  };
448
+ var fe = {
449
+ teleport: true,
450
+ teleportMode: "move"
451
+ };
406
452
  var S = class S2 {
407
453
  /**
408
454
  * Creates a new Dropdown instance
@@ -413,43 +459,108 @@
413
459
  constructor(e, t = {}) {
414
460
  a(this, "triggerElement");
415
461
  a(this, "contentElement");
462
+ a(this, "items", []);
416
463
  a(this, "options");
417
464
  a(this, "OverlayInstance");
418
465
  a(this, "navigationKeys");
466
+ a(this, "keyObserver");
467
+ a(this, "subtriggerObserver");
419
468
  a(this, "triggerStrategy");
420
469
  a(this, "placement");
421
470
  a(this, "offsetDistance");
422
471
  a(this, "preventFromCloseOutside");
423
472
  a(this, "preventFromCloseInside");
424
473
  a(this, "defaultState");
474
+ a(this, "experimentalOptions");
475
+ a(this, "teleporter");
476
+ a(this, "updateSubtriggerAttr", (e2, t2) => {
477
+ t2 === "add" ? (e2.setAttribute("data-current-subtrigger", ""), e2.setAttribute("data-focus", "active")) : (e2.removeAttribute("data-current-subtrigger"), e2.removeAttribute("data-focus"));
478
+ });
479
+ a(this, "updateObserverFor", (e2) => {
480
+ const t2 = O("[data-dropdown-trigger]", this.contentElement);
481
+ for (const n2 of t2)
482
+ e2.observe(n2, {
483
+ attributes: true,
484
+ attributeFilter: ["aria-expanded"]
485
+ });
486
+ });
487
+ a(this, "observeEl", () => {
488
+ this.keyObserver = new MutationObserver((e2) => {
489
+ for (const t2 of e2)
490
+ t2.type === "attributes" && t2.attributeName === "aria-expanded" && (t2.target.getAttribute("aria-expanded") === "true" ? this.navigationKeys.destroy() : this.contentElement.dataset.state === "open" && this.navigationKeys.make());
491
+ }), this.updateObserverFor(this.keyObserver);
492
+ });
493
+ a(this, "observeSubtriggers", () => {
494
+ this.subtriggerObserver = new MutationObserver((e2) => {
495
+ for (const t2 of e2)
496
+ if (t2.type === "attributes" && t2.attributeName === "aria-expanded") {
497
+ const n2 = t2.target, r2 = n2.getAttribute("aria-expanded");
498
+ this.updateSubtriggerAttr(n2, r2 === "true" ? "add" : "remove");
499
+ }
500
+ }), this.updateObserverFor(this.subtriggerObserver);
501
+ });
425
502
  a(this, "onToggle", ({ isHidden: e2 }) => {
426
503
  var t2, n2;
427
504
  (n2 = (t2 = this.options).onToggle) == null || n2.call(t2, { isHidden: e2 });
428
505
  });
506
+ a(this, "moveElOnInit", () => {
507
+ this.experimentalOptions.teleport && (this.experimentalOptions.teleportMode === "detachable" ? this.teleporter.remove() : this.teleporter.append());
508
+ });
509
+ a(this, "moveEl", () => {
510
+ this.experimentalOptions.teleport && this.experimentalOptions.teleportMode === "detachable" && this.teleporter.remove();
511
+ });
512
+ a(this, "restoreEl", () => {
513
+ this.experimentalOptions.teleport && this.experimentalOptions.teleportMode === "detachable" && this.teleporter.append();
514
+ });
429
515
  a(this, "beforeShow", () => {
430
- this.contentElement.focus(), this.navigationKeys.make();
516
+ this.restoreEl(), this.contentElement.focus(), this.navigationKeys.make(), this.addArrowEvent();
431
517
  });
432
518
  a(this, "beforeHide", () => {
433
- this.contentElement.blur(), this.navigationKeys.destroy();
519
+ this.contentElement.blur(), this.navigationKeys.destroy(), this.removeArrowEvent();
520
+ });
521
+ a(this, "showHideOnArrow", (e2) => {
522
+ e2.preventDefault();
523
+ const t2 = e2.key, n2 = document.activeElement;
524
+ if (n2 != null && n2.hasAttribute("data-dropdown-trigger"))
525
+ switch (t2) {
526
+ case "ArrowRight":
527
+ n2.getAttribute("aria-expanded") !== "true" && (n2.click(), this.updateSubtriggerAttr(n2, "add"));
528
+ break;
529
+ case "ArrowLeft":
530
+ n2.getAttribute("aria-expanded") === "true" && (n2.click(), this.updateSubtriggerAttr(n2, "remove"));
531
+ break;
532
+ default:
533
+ return;
534
+ }
535
+ if (this.triggerElement.hasAttribute("data-current-subtrigger"))
536
+ switch (t2) {
537
+ case "ArrowLeft":
538
+ this.triggerElement.click(), this.triggerElement.focus(), this.updateSubtriggerAttr(this.triggerElement, "remove");
539
+ break;
540
+ default:
541
+ return;
542
+ }
543
+ });
544
+ a(this, "addArrowEvent", () => {
545
+ document.addEventListener("keydown", this.showHideOnArrow);
546
+ });
547
+ a(this, "removeArrowEvent", () => {
548
+ document.removeEventListener("keydown", this.showHideOnArrow);
434
549
  });
435
550
  a(this, "onShow", () => {
436
551
  var e2, t2;
437
- z(this.contentElement, "dropdown-show", {
552
+ K(this.contentElement, "dropdown-show", {
438
553
  isHidden: false
439
- }), (t2 = (e2 = this.options).onShow) == null || t2.call(e2);
554
+ }), (t2 = (e2 = this.options).onShow) == null || t2.call(e2), this.observeEl(), this.observeSubtriggers();
440
555
  });
441
556
  a(this, "onHide", () => {
442
557
  var e2, t2;
443
- z(this.contentElement, "dropdown-hide", {
558
+ K(this.contentElement, "dropdown-hide", {
444
559
  isHidden: true
445
- }), (t2 = (e2 = this.options).onHide) == null || t2.call(e2);
446
- });
447
- a(this, "show", () => {
448
- this.OverlayInstance.show();
449
- });
450
- a(this, "hide", () => {
451
- this.OverlayInstance.hide();
560
+ }), (t2 = (e2 = this.options).onHide) == null || t2.call(e2), this.moveEl(), this.triggerElement.hasAttribute("data-current-subtrigger") && this.updateSubtriggerAttr(this.triggerElement, "remove"), this.disconnectObserver();
452
561
  });
562
+ a(this, "show", () => this.OverlayInstance.show());
563
+ a(this, "hide", () => this.OverlayInstance.hide());
453
564
  a(this, "setShowOptions", ({ placement: e2, offsetDistance: t2 }) => {
454
565
  this.OverlayInstance.setShowOptions({ placement: e2, offsetDistance: t2 });
455
566
  });
@@ -459,8 +570,11 @@
459
570
  a(this, "setPopperTrigger", (e2, t2) => {
460
571
  this.OverlayInstance.setPopperTrigger(e2, t2);
461
572
  });
573
+ a(this, "disconnectObserver", () => {
574
+ this.keyObserver && this.keyObserver.disconnect(), this.subtriggerObserver && this.subtriggerObserver.disconnect();
575
+ });
462
576
  a(this, "cleanup", () => {
463
- this.OverlayInstance.cleanup(), x.removeInstance("dropdown", this.contentElement);
577
+ this.disconnectObserver(), this.OverlayInstance.cleanup(), T.removeInstance("dropdown", this.contentElement);
464
578
  });
465
579
  const n = typeof e == "string" ? P(e) : e;
466
580
  if (!(n instanceof HTMLElement))
@@ -470,13 +584,13 @@
470
584
  if (!n.id)
471
585
  throw new Error("Dropdown content element must have an 'id' attribute for trigger association");
472
586
  this.contentElement = n;
473
- const o = x.getInstance("dropdown", this.contentElement);
474
- if (o)
475
- return o;
476
- const i = `[data-dropdown-trigger][data-dropdown-id=${this.contentElement.id}]`;
477
- if (this.triggerElement = P(i), !(this.triggerElement instanceof HTMLElement))
587
+ const r = T.getInstance("dropdown", this.contentElement);
588
+ if (r)
589
+ return r;
590
+ const s = `[data-dropdown-trigger][data-dropdown-id=${this.contentElement.id}]`;
591
+ if (this.triggerElement = P(s), !(this.triggerElement instanceof HTMLElement))
478
592
  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}"`);
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({
593
+ this.options = t, this.triggerStrategy = this.contentElement.dataset.triggerStrategy || this.options.triggerStrategy || "click", this.placement = this.contentElement.dataset.placement || this.options.placement || "bottom-start", this.offsetDistance = parseInt(`${this.contentElement.dataset.offsetDistance}`) || this.options.offsetDistance || 6, this.preventFromCloseOutside = this.contentElement.hasAttribute("data-prevent-close-outside") || this.options.preventFromCloseOutside || false, this.preventFromCloseInside = this.contentElement.hasAttribute("data-prevent-close-inside") || this.options.preventCloseFromInside || false, this.defaultState = this.contentElement.dataset.defaultState || this.options.defaultState || "close", this.experimentalOptions = Object.assign({}, fe, t.experimental), this.teleporter = ge(this.contentElement, document.body, this.experimentalOptions.teleportMode), this.OverlayInstance = new ce({
480
594
  trigger: this.triggerElement,
481
595
  content: this.contentElement,
482
596
  options: {
@@ -487,19 +601,23 @@
487
601
  preventCloseFromInside: this.preventFromCloseInside,
488
602
  defaultState: this.defaultState,
489
603
  beforeShow: this.beforeShow,
490
- beforeHide: this.beforeHide,
604
+ beforeHide: () => {
605
+ if (O("[data-dropdown-trigger][aria-expanded=true]", this.contentElement).length >= 1)
606
+ return { cancelAction: true };
607
+ this.beforeHide();
608
+ },
491
609
  onShow: this.onShow,
492
610
  onHide: this.onHide,
493
- onToggle: ({ isHidden: r }) => {
494
- this.onToggle({ isHidden: r });
611
+ onToggle: ({ isHidden: o }) => {
612
+ this.onToggle({ isHidden: o });
495
613
  },
496
614
  popper: this.options.popper
497
615
  }
498
- }), this.navigationKeys = de({
616
+ }), this.moveElOnInit(), this.items = O("a:not([disabled]), button:not([disabled])", this.contentElement), this.navigationKeys = me({
499
617
  containerElement: this.contentElement,
500
- targetChildren: "a:not([disabled]), button:not([disabled])",
618
+ targetChildren: this.items,
501
619
  direction: "up-down"
502
- }), x.register("dropdown", this.contentElement, this);
620
+ }), T.register("dropdown", this.contentElement, this);
503
621
  }
504
622
  /**
505
623
  * Initializes a single dropdown instance
@@ -512,16 +630,16 @@
512
630
  }
513
631
  };
514
632
  a(S, "autoInit", (e = "[data-fx-dropdown]") => {
515
- const t = U(e);
633
+ const t = O(e);
516
634
  for (const n of t)
517
635
  new S(n);
518
636
  });
519
- var K = S;
637
+ var z = S;
520
638
 
521
639
  // src/index.js
522
640
  function Dropdown(Alpine) {
523
641
  Alpine.directive("dropdown", (el, {}, { cleanup }) => {
524
- const dropdown_ = new K(el);
642
+ const dropdown_ = new z(el);
525
643
  cleanup(() => {
526
644
  dropdown_.cleanup();
527
645
  });