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