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