sb-floating-panel-vue 3.0.0 → 5.0.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,60 +1,130 @@
1
- import { Teleport as e, Transition as t, computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createVNode as o, defineComponent as s, inject as c, mergeModels as l, mergeProps as u, nextTick as d, normalizeStyle as f, onScopeDispose as p, openBlock as m, provide as h, ref as g, renderSlot as _, resolveDynamicComponent as v, toRef as y, toValue as b, unref as x, useId as S, useModel as C, watch as w, withCtx as T } from "vue";
2
- import { autoUpdate as E, flip as D, hide as O, limitShift as k, offset as A, shift as j, size as M, useFloating as N } from "@floating-ui/vue";
1
+ import { Teleport as e, Transition as t, computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createVNode as o, defineComponent as s, inject as c, mergeModels as l, mergeProps as u, nextTick as d, normalizeStyle as f, onBeforeUnmount as p, onMounted as m, onScopeDispose as h, openBlock as g, provide as _, ref as v, renderSlot as y, resolveDynamicComponent as b, toRef as x, toValue as S, unref as C, useAttrs as w, useId as T, useModel as E, watch as D, watchEffect as O, withCtx as k } from "vue";
2
+ import { autoUpdate as A, flip as j, hide as M, limitShift as N, offset as P, shift as F, size as ee, useFloating as te } from "@floating-ui/vue";
3
3
  //#region src/composables/useSbFloatingPanel.ts
4
- var P = (e) => `${Math.max(0, e)}px`;
5
- function F(e) {
6
- let t = g(null), r = g(null), i = n(() => {
7
- let t = b(e.padding), n = b(e.matchWidth), r = b(e.placement).includes("-"), i = D({
4
+ var I = (e) => `${Math.max(0, e)}px`, L = (e, t) => {
5
+ let [n, r] = e.split("-"), i = t && (n === "top" || n === "bottom"), a = r === "start" ? i ? "100%" : "0%" : r === "end" ? i ? "0%" : "100%" : "50%";
6
+ return n === "top" ? `${a} 100%` : n === "bottom" ? `${a} 0%` : n === "left" ? `100% ${a}` : `0% ${a}`;
7
+ };
8
+ function R(e) {
9
+ let t = v(null), r = v(null), i = n(() => {
10
+ let t = S(e.padding), n = S(e.matchWidth), r = S(e.placement).includes("-"), i = j({
8
11
  padding: t,
9
12
  crossAxis: "alignment",
10
13
  fallbackAxisSideDirection: "end"
11
- }), a = j({
14
+ }), a = F({
12
15
  padding: t,
13
- limiter: k()
16
+ limiter: N()
14
17
  }), o = [
15
- A(b(e.offset)),
18
+ P(S(e.offset)),
16
19
  ...r ? [i, a] : [a, i],
17
- M({
20
+ ee({
18
21
  padding: t,
19
- apply({ rects: e, elements: t, availableWidth: r, availableHeight: i }) {
20
- let { style: a } = t.floating, o = P(e.reference.width);
21
- a.setProperty("--sbf-reference-width", o), a.setProperty("--sbf-available-width", P(r)), a.setProperty("--sbf-available-height", P(i)), a.width = n === !0 ? o : "", a.minWidth = n === "min" ? o : "";
22
+ apply({ rects: e, elements: t, availableWidth: r, availableHeight: i, placement: a }) {
23
+ let { style: o } = t.floating, s = I(e.reference.width);
24
+ o.setProperty("--sbf-reference-width", s);
25
+ let c = getComputedStyle(t.floating).direction === "rtl";
26
+ o.setProperty("--sbf-transform-origin", L(a, c)), o.setProperty("--sbf-available-width", I(r)), o.setProperty("--sbf-available-height", I(i)), o.width = n === !0 ? s : "", o.minWidth = n === "min" ? s : "";
22
27
  }
23
28
  })
24
29
  ];
25
- return b(e.hideWhenDetached) && o.push(O({ padding: t })), o;
26
- }), { floatingStyles: a, middlewareData: o, placement: s, isPositioned: c, update: l } = N(t, r, {
27
- open: () => b(e.isOpen),
28
- placement: () => b(e.placement),
29
- strategy: () => b(e.strategy),
30
+ return S(e.hideWhenDetached) && o.push(M({ padding: t })), o;
31
+ }), { floatingStyles: a, middlewareData: o, placement: s, isPositioned: c, update: l } = te(t, r, {
32
+ open: () => S(e.isOpen),
33
+ placement: () => S(e.placement),
34
+ strategy: () => S(e.strategy),
30
35
  middleware: i,
31
- whileElementsMounted: E
32
- });
36
+ whileElementsMounted: A
37
+ }), u = n(() => !!o.value.hide?.referenceHidden);
33
38
  return {
34
39
  reference: t,
35
40
  floating: r,
36
41
  floatingStyles: n(() => ({
37
42
  ...a.value,
38
- ...o.value.hide?.referenceHidden ? { visibility: "hidden" } : {}
43
+ ...u.value ? { visibility: "hidden" } : {}
39
44
  })),
40
45
  placement: s,
41
46
  side: n(() => s.value.split("-")[0]),
42
47
  align: n(() => s.value.split("-")[1]),
43
48
  isPositioned: c,
49
+ referenceHidden: u,
44
50
  update: l
45
51
  };
46
52
  }
47
53
  //#endregion
54
+ //#region src/dev.ts
55
+ var z = (() => {
56
+ try {
57
+ return process.env.NODE_ENV !== "production";
58
+ } catch {
59
+ return !1;
60
+ }
61
+ })();
62
+ function B(e) {
63
+ z && console.warn(`[sb-floating-panel-vue] ${e}`);
64
+ }
65
+ //#endregion
48
66
  //#region src/context.ts
49
- var I = Symbol("SbFloatingContext");
50
- function L(e) {
51
- let t = c(I, null);
67
+ var V = {
68
+ dialog: "dialog",
69
+ alertdialog: "dialog",
70
+ menu: "menu",
71
+ listbox: "listbox",
72
+ tree: "tree",
73
+ grid: "grid"
74
+ }, H = Symbol("SbFloatingContext");
75
+ function ne(e) {
76
+ let t = e && typeof e == "object" && "$el" in e ? e.$el : e;
77
+ return t instanceof HTMLElement ? t : null;
78
+ }
79
+ function re(e, t, n) {
80
+ return ++e.parts[t] > 1 && B(`<SbContainer> has more than one <${n}>: they share one open state and position, so only the last one works. Use one SbContainer for each panel.`), () => e.parts[t]--;
81
+ }
82
+ function ie(e) {
83
+ let t = c(H, null);
52
84
  if (!t) throw Error(`[sb-floating-panel-vue] <${e}> must be used inside <SbContainer>.`);
53
85
  return t;
54
86
  }
55
87
  //#endregion
88
+ //#region src/focus.ts
89
+ var ae = "data-sbf-focus-guard", U = [
90
+ "a[href]",
91
+ "button:not([disabled])",
92
+ "input:not([disabled]):not([type=\"hidden\"])",
93
+ "select:not([disabled])",
94
+ "textarea:not([disabled])",
95
+ "summary",
96
+ "audio[controls]",
97
+ "video[controls]",
98
+ "[tabindex]",
99
+ "[contenteditable=\"true\"]"
100
+ ].join(","), W = (e) => e.tabIndex >= 0 && !e.hasAttribute("data-sbf-focus-guard") && !e.closest("[inert]") && (e.checkVisibility?.() ?? !0);
101
+ function G(e) {
102
+ let t = e instanceof Element ? e.closest(U) : null;
103
+ return !!t && !t.closest("[inert]");
104
+ }
105
+ function K(e) {
106
+ return [...e.querySelectorAll(U)].filter(W);
107
+ }
108
+ var q = {
109
+ menu: "[role=\"menuitem\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"]",
110
+ listbox: "[role=\"option\"]"
111
+ }, oe = (e) => !!e && Object.hasOwn(q, e);
112
+ function se(e, t) {
113
+ return [...e.querySelectorAll(q[t])].filter((n) => n.closest(`[role="${t}"]`) === e && !n.matches(":disabled") && (n.checkVisibility?.() ?? !0));
114
+ }
115
+ var ce = (e) => e instanceof Element && !!e.closest("input, textarea, select, [contenteditable]:not([contenteditable=\"false\"])"), le = (e) => getComputedStyle(e).direction === "rtl" ? {
116
+ open: "ArrowLeft",
117
+ close: "ArrowRight"
118
+ } : {
119
+ open: "ArrowRight",
120
+ close: "ArrowLeft"
121
+ };
122
+ function ue(e, t) {
123
+ return K(e.ownerDocument).find((n) => !!(e.compareDocumentPosition(n) & Node.DOCUMENT_POSITION_FOLLOWING) && !e.contains(n) && !t(n));
124
+ }
125
+ //#endregion
56
126
  //#region src/components/SbContainer.vue?vue&type=script&setup=true&lang.ts
57
- var R = /* @__PURE__ */ new WeakSet(), z = /* @__PURE__ */ s({
127
+ var J = [], Y = /* @__PURE__ */ s({
58
128
  inheritAttrs: !1,
59
129
  __name: "SbContainer",
60
130
  props: /*@__PURE__*/ l({
@@ -67,7 +137,7 @@ var R = /* @__PURE__ */ new WeakSet(), z = /* @__PURE__ */ s({
67
137
  default: !1
68
138
  },
69
139
  hideWhenDetached: {
70
- type: Boolean,
140
+ type: [Boolean, String],
71
141
  default: !1
72
142
  },
73
143
  defaultOpen: {
@@ -79,6 +149,10 @@ var R = /* @__PURE__ */ new WeakSet(), z = /* @__PURE__ */ s({
79
149
  default: !1
80
150
  },
81
151
  trigger: { default: "click" },
152
+ delay: { default: () => ({
153
+ open: 300,
154
+ close: 150
155
+ }) },
82
156
  closeOnEscape: {
83
157
  type: Boolean,
84
158
  default: !0
@@ -86,6 +160,10 @@ var R = /* @__PURE__ */ new WeakSet(), z = /* @__PURE__ */ s({
86
160
  closeOnClickOutside: {
87
161
  type: Boolean,
88
162
  default: !0
163
+ },
164
+ closeOnFocusOut: {
165
+ type: Boolean,
166
+ default: !0
89
167
  }
90
168
  }, {
91
169
  open: {
@@ -96,86 +174,172 @@ var R = /* @__PURE__ */ new WeakSet(), z = /* @__PURE__ */ s({
96
174
  }),
97
175
  emits: /*@__PURE__*/ l(["open", "close"], ["update:open"]),
98
176
  setup(e, { expose: t, emit: r }) {
99
- let i = e, a = C(e, "open"), o = r, s = n(() => !i.disabled && (a.value ?? i.defaultOpen)), l = (e) => {
100
- e && i.disabled || e !== s.value && (a.value = e);
101
- }, u = () => l(!0), d = () => l(!1), f = () => l(!s.value), m = F({
102
- isOpen: s,
177
+ let i = e, a = E(e, "open"), o = r, s = i.defaultOpen, l = n(() => !i.disabled && (a.value ?? s)), u;
178
+ h(() => clearTimeout(u));
179
+ let d = (e) => {
180
+ clearTimeout(u), !(e && i.disabled) && e !== l.value && (a.value = e);
181
+ }, f = () => d(!0), m = () => d(!1), g = () => d(!l.value), b = (e) => {
182
+ if (i.trigger !== "hover" || e.pointerType === "touch") return;
183
+ let t = e.type === "pointerenter";
184
+ if (clearTimeout(u), t === l.value) return;
185
+ let { delay: n } = i, r = typeof n == "number" ? {
186
+ open: n,
187
+ close: n
188
+ } : n, a = (t ? r.open : r.close) ?? (t ? 300 : 150);
189
+ u = setTimeout(() => d(t), a);
190
+ }, S = R({
191
+ isOpen: l,
103
192
  placement: () => i.placement,
104
193
  strategy: () => i.strategy,
105
194
  offset: () => i.offset,
106
195
  padding: () => i.padding,
107
196
  matchWidth: () => i.matchWidth,
108
197
  hideWhenDetached: () => i.hideWhenDetached
109
- }), g = /* @__PURE__ */ new Set(), v = {
110
- ...m,
111
- isOpen: s,
112
- disabled: y(i, "disabled"),
113
- trigger: y(i, "trigger"),
114
- floatingId: `${S()}-floating`,
115
- open: u,
116
- close: d,
117
- toggle: f,
118
- contains: (e) => e instanceof Node ? m.reference.value?.contains(e) || m.floating.value?.contains(e) ? !0 : [...g].some((t) => t.contains(e)) : !1,
119
- hasOpenChild: () => [...g].some((e) => e.isOpen.value || e.hasOpenChild()),
120
- registerChild: (e) => (g.add(e), () => g.delete(e))
121
- }, b = c(I, null);
122
- b && p(b.registerChild(v)), h(I, v);
123
- let T = (e) => {
124
- e.key === "Escape" && i.closeOnEscape && !v.hasOpenChild() && (R.has(e) || (R.add(e), d()));
125
- }, E = (e) => {
126
- i.closeOnClickOutside && (v.contains(e.composedPath()[0] ?? e.target) || d());
198
+ }), w = /* @__PURE__ */ new Set(), O = c(H, null), k = {
199
+ ...S,
200
+ isOpen: l,
201
+ disabled: x(i, "disabled"),
202
+ trigger: x(i, "trigger"),
203
+ floatingId: `${T()}-floating`,
204
+ referenceId: v(),
205
+ floatingRole: v("dialog"),
206
+ navigation: v(null),
207
+ focusRequest: v(null),
208
+ parent: O,
209
+ skipFocusReturn: !1,
210
+ parts: {
211
+ reference: 0,
212
+ floating: 0
213
+ },
214
+ isUnmounting: !1,
215
+ open: f,
216
+ close: m,
217
+ toggle: g,
218
+ hover: b,
219
+ contains: (e) => e instanceof Node ? S.reference.value?.contains(e) || S.floating.value?.contains(e) ? !0 : [...w].some((t) => t.contains(e)) : !1,
220
+ registerChild: (e) => (w.add(e), () => w.delete(e))
127
221
  };
128
- return w(s, (e, t, n) => {
129
- e && typeof document < "u" && (document.addEventListener("keydown", T), document.addEventListener("pointerdown", E, !0), n(() => {
130
- document.removeEventListener("keydown", T), document.removeEventListener("pointerdown", E, !0);
222
+ O && h(O.registerChild(k)), _(H, k), p(() => k.isUnmounting = !0);
223
+ let A = (e) => {
224
+ let t = e.composedPath()[0] ?? e.target;
225
+ return J.findLast((e) => e.contains(t)) ?? J[J.length - 1];
226
+ }, j = (e) => {
227
+ e.key === "Escape" && A(e) === k && (!i.closeOnEscape || e.defaultPrevented || e.isComposing || (e.preventDefault(), m()));
228
+ }, M = (e) => {
229
+ k.contains(e) || (k.skipFocusReturn = G(e), m());
230
+ }, N, P = (e) => {
231
+ if (N?.(), !i.closeOnClickOutside) return;
232
+ let t = e.composedPath()[0] ?? e.target;
233
+ if (e.pointerType !== "touch") {
234
+ M(t);
235
+ return;
236
+ }
237
+ if (k.contains(t)) return;
238
+ let n = (e) => {
239
+ N?.(), M(e.composedPath()[0] ?? e.target);
240
+ };
241
+ document.addEventListener("click", n, !0), N = () => {
242
+ document.removeEventListener("click", n, !0), N = void 0;
243
+ };
244
+ }, F = (e) => {
245
+ i.closeOnFocusOut && (k.contains(e.composedPath()[0] ?? e.target) || m());
246
+ };
247
+ return D(l, (e, t, n) => {
248
+ e && typeof document < "u" && (J.push(k), document.addEventListener("keydown", j), document.addEventListener("pointerdown", P, !0), document.addEventListener("focusin", F), n(() => {
249
+ document.removeEventListener("keydown", j), document.removeEventListener("pointerdown", P, !0), document.removeEventListener("focusin", F), N?.(), J.splice(J.indexOf(k), 1);
131
250
  }));
132
- }, { immediate: !0 }), w(s, (e) => o(e ? "open" : "close")), w(() => i.disabled, (e) => {
133
- e && a.value && (a.value = !1);
251
+ }, { immediate: !0 }), D(l, (e) => o(e ? "open" : "close")), D(S.referenceHidden, (e) => {
252
+ e && i.hideWhenDetached === "close" && m();
253
+ }), D(() => i.disabled, (e) => {
254
+ e && (a.value ?? s) && (a.value = !1);
134
255
  }), t({
135
- open: u,
136
- close: d,
137
- toggle: f,
138
- update: m.update
139
- }), (e, t) => _(e.$slots, "default", {
140
- isOpen: s.value,
141
- open: u,
142
- close: d,
143
- toggle: f,
144
- placement: x(m).placement.value,
145
- side: x(m).side.value
256
+ get isOpen() {
257
+ return l.value;
258
+ },
259
+ open: f,
260
+ close: m,
261
+ toggle: g,
262
+ update: S.update
263
+ }), (e, t) => y(e.$slots, "default", {
264
+ isOpen: l.value,
265
+ open: f,
266
+ close: m,
267
+ toggle: g,
268
+ placement: C(S).placement.value,
269
+ side: C(S).side.value,
270
+ align: C(S).align.value,
271
+ floatingId: k.floatingId,
272
+ referenceId: k.referenceId.value
146
273
  });
147
274
  }
148
- }), B = /* @__PURE__ */ s({
275
+ }), X = /* @__PURE__ */ s({
149
276
  __name: "SbReference",
150
277
  props: {
151
278
  as: { default: "button" },
152
- ariaHaspopup: { default: "dialog" }
279
+ id: { default: void 0 },
280
+ ariaHaspopup: { default: void 0 }
153
281
  },
154
282
  setup(e) {
155
- let t = e, i = L("SbReference"), { isOpen: a, disabled: o, floatingId: s } = i, c = n(() => t.as === "button" || t.as === "a"), l = (e) => {
156
- i.reference.value = e instanceof HTMLElement ? e : null;
157
- }, u = () => {
158
- i.trigger.value === "click" && i.toggle();
159
- }, d = (e) => {
160
- c.value || e.key !== "Enter" && e.key !== " " || (e.preventDefault(), u());
283
+ let t = e, i = w(), a = ie("SbReference"), { isOpen: o, disabled: s, floatingId: c, floatingRole: l } = a, u = re(a, "reference", "SbReference"), d = () => typeof t.as != "string" || t.as === "button" || t.as === "a" && i.href != null, f = `${T()}-reference`, h = n(() => t.id ?? f);
284
+ O(() => {
285
+ a.referenceId.value = h.value;
286
+ }), m(() => {
287
+ a.reference.value || B("<SbReference> rendered no element, so the panel cannot be positioned: a component in `as` must render a single root element.");
288
+ }), p(() => {
289
+ a.referenceId.value === h.value && (a.referenceId.value = void 0), u(), !a.parts.reference && !a.isUnmounting && a.close();
290
+ });
291
+ let _ = n(() => t.ariaHaspopup ?? (l.value && Object.hasOwn(V, l.value) ? V[l.value] : void 0)), v = (e) => {
292
+ a.reference.value = ne(e);
293
+ }, x = () => {
294
+ a.trigger.value === "click" && a.toggle();
295
+ }, S = n(() => l.value === "tooltip"), E = () => a.trigger.value === "hover" || a.trigger.value === "focus", D = (e) => {
296
+ E() && !a.contains(e.relatedTarget) && a.open();
297
+ }, A = (e) => {
298
+ E() && !a.contains(e.relatedTarget) && a.close();
299
+ }, j = (e) => {
300
+ let t = a.floating.value, n = t && K(t)[0];
301
+ n && (e.preventDefault(), n.focus());
302
+ }, M = (e) => {
303
+ if (a.navigation.value && !s.value && a.trigger.value !== "manual") {
304
+ if (a.parent?.navigation.value === "menu") {
305
+ let t = e.currentTarget;
306
+ return e.key === le(t).open ? "first" : void 0;
307
+ }
308
+ return e.key === "ArrowDown" ? "first" : e.key === "ArrowUp" ? "last" : void 0;
309
+ }
310
+ }, N = (e) => {
311
+ let t = a.parent?.navigation.value === "menu";
312
+ if (e.key === "Tab" && !e.shiftKey && o.value && !t) {
313
+ j(e);
314
+ return;
315
+ }
316
+ let n = M(e);
317
+ n ? (e.preventDefault(), a.focusRequest.value = n, a.open()) : d() || e.key !== "Enter" && e.key !== " " || (e.preventDefault(), x());
161
318
  };
162
- return (e, n) => (m(), r(v(t.as), {
163
- ref: l,
319
+ return (e, n) => (g(), r(b(t.as), {
320
+ id: h.value,
321
+ ref: v,
164
322
  type: t.as === "button" ? "button" : void 0,
165
- role: c.value ? void 0 : "button",
166
- tabindex: c.value ? void 0 : x(o) ? -1 : 0,
167
- disabled: t.as === "button" && x(o) ? !0 : void 0,
168
- "aria-disabled": !c.value && x(o) ? "true" : void 0,
169
- "aria-haspopup": t.ariaHaspopup,
170
- "aria-expanded": x(a) ? "true" : "false",
171
- "aria-controls": x(a) ? x(s) : void 0,
172
- "data-sbf-state": x(a) ? "open" : "closed",
173
- onClick: u,
174
- onKeydown: d
323
+ role: d() ? void 0 : "button",
324
+ tabindex: d() ? void 0 : C(s) ? -1 : 0,
325
+ disabled: t.as === "button" && C(s) ? !0 : void 0,
326
+ "aria-disabled": t.as !== "button" && C(s) ? "true" : void 0,
327
+ "aria-haspopup": _.value,
328
+ "aria-expanded": S.value ? void 0 : C(o) ? "true" : "false",
329
+ "aria-controls": C(o) && !S.value ? C(c) : void 0,
330
+ "aria-describedby": C(o) && S.value ? C(c) : void 0,
331
+ "data-sbf-state": C(o) ? "open" : "closed",
332
+ onClick: x,
333
+ onKeydown: N,
334
+ onFocusin: D,
335
+ onFocusout: A,
336
+ onPointerenter: C(a).hover,
337
+ onPointerleave: C(a).hover
175
338
  }, {
176
- default: T(() => [_(e.$slots, "default")]),
339
+ default: k(() => [y(e.$slots, "default")]),
177
340
  _: 3
178
341
  }, 40, [
342
+ "id",
179
343
  "type",
180
344
  "role",
181
345
  "tabindex",
@@ -184,87 +348,180 @@ var R = /* @__PURE__ */ new WeakSet(), z = /* @__PURE__ */ s({
184
348
  "aria-haspopup",
185
349
  "aria-expanded",
186
350
  "aria-controls",
187
- "data-sbf-state"
351
+ "aria-describedby",
352
+ "data-sbf-state",
353
+ "onPointerenter",
354
+ "onPointerleave"
188
355
  ]));
189
356
  }
190
- }), V = "a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"]), [contenteditable=\"true\"]", H = /* @__PURE__ */ s({
357
+ }), Z = /* @__PURE__ */ s({
191
358
  inheritAttrs: !1,
192
359
  __name: "SbFloating",
193
360
  props: {
194
361
  as: { default: "div" },
195
362
  role: { default: "dialog" },
196
363
  transition: { default: void 0 },
197
- teleportTo: { default: "body" },
198
- teleportDisabled: {
199
- type: Boolean,
200
- default: !1
364
+ teleport: {
365
+ type: [String, Boolean],
366
+ default: "body"
201
367
  },
202
368
  zIndex: { default: void 0 },
203
369
  autoFocus: {
204
370
  type: Boolean,
205
- default: !1
371
+ default: void 0
372
+ },
373
+ keyboardNavigation: {
374
+ type: Boolean,
375
+ default: !0
206
376
  }
207
377
  },
208
378
  emits: ["after-enter", "after-leave"],
209
379
  setup(s, { emit: c }) {
210
- let l = s, p = c, h = L("SbFloating"), { isOpen: y, floatingId: b, side: S, align: C } = h, E = g(y.value), D = g(null), O = (e) => {
211
- h.floating.value = e instanceof HTMLElement ? e : null;
212
- }, k = (e) => {
213
- D.value = e instanceof HTMLElement ? e : null;
214
- }, A = n(() => ({
215
- ...h.floatingStyles.value,
380
+ let l = s, m = c, _ = w(), x = ie("SbFloating");
381
+ p(re(x, "floating", "SbFloating"));
382
+ let { isOpen: S, floatingId: T, referenceId: E, side: A, align: j } = x;
383
+ O(() => {
384
+ x.floatingRole.value = l.role, x.navigation.value = l.keyboardNavigation && oe(l.role) ? l.role : null;
385
+ });
386
+ let M = v(S.value), N = v(null), P = (e) => {
387
+ x.floating.value = e instanceof HTMLElement ? e : null;
388
+ }, F = (e) => {
389
+ N.value = ne(e);
390
+ }, ee = n(() => ({
391
+ ...x.floatingStyles.value,
216
392
  ...l.zIndex === void 0 ? {} : { zIndex: l.zIndex }
217
- })), j = () => p("after-enter"), M = () => {
218
- y.value || (E.value = !1), p("after-leave");
219
- }, N = () => {
220
- let e = D.value;
221
- e && (e.querySelector("[autofocus]") ?? e.querySelector(V) ?? e).focus({ preventScroll: !0 });
393
+ })), te = () => ({
394
+ "aria-labelledby": l.role && Object.hasOwn(V, l.role) && _["aria-label"] == null ? E.value : void 0,
395
+ ..._
396
+ }), I = n(() => l.autoFocus ?? (l.role !== "tooltip" && x.trigger.value !== "hover" && x.trigger.value !== "focus")), L = n(() => S.value && l.teleport !== !1 && l.role !== "tooltip"), R = {
397
+ [ae]: "",
398
+ tabindex: 0,
399
+ style: {
400
+ position: "fixed",
401
+ opacity: 0,
402
+ outline: "none",
403
+ pointerEvents: "none"
404
+ }
405
+ }, z = n(() => {
406
+ let { transition: e } = l;
407
+ return e ? typeof e == "string" ? { name: e } : e : { css: !1 };
408
+ }), B = (e) => e.setAttribute("data-sbf-state", "closed"), H = () => m("after-enter"), U = () => {
409
+ S.value || (M.value = !1), m("after-leave");
410
+ }, W = (e) => e instanceof Node && !!N.value?.contains(e), G = (e) => {
411
+ let t = N.value;
412
+ if (!t) return;
413
+ let n = K(t);
414
+ ((e === "first" ? n[0] : n[n.length - 1]) ?? t).focus({ preventScroll: !0 });
415
+ }, q = (e) => {
416
+ W(e.relatedTarget) ? x.reference.value?.focus() : G("first");
417
+ }, J = (e) => {
418
+ if (!W(e.relatedTarget)) {
419
+ G("last");
420
+ return;
421
+ }
422
+ let t = x.reference.value;
423
+ ((t && ue(t, (e) => x.contains(e))) ?? t)?.focus();
424
+ }, Y = () => {
425
+ let e = x.navigation.value;
426
+ return N.value && e ? se(N.value, e) : [];
427
+ }, X = (e) => {
428
+ let t = N.value;
429
+ if (!t) return;
430
+ let n = Y();
431
+ (n.find((e) => e.getAttribute("aria-selected") === "true") ?? (e === "last" ? n[n.length - 1] : e ? n[0] : void 0) ?? t.querySelector("[autofocus]") ?? n[0] ?? K(t)[0] ?? t).focus({ preventScroll: !0 });
432
+ }, Z = () => {
433
+ let e = x.focusRequest.value;
434
+ return x.focusRequest.value = null, e;
435
+ }, Q = "", $;
436
+ h(() => clearTimeout($));
437
+ let de = (e, t, n) => {
438
+ Q += n.toLowerCase(), clearTimeout($), $ = setTimeout(() => Q = "", 500);
439
+ let r = [...Q].every((e) => e === Q[0]) ? Q[0] : Q, i = Math.max(t, 0), a = [...e.slice(i), ...e.slice(0, i)];
440
+ return r.length === 1 && t >= 0 && a.push(a.shift()), a.find((e) => e.textContent?.trim().toLowerCase().startsWith(r));
441
+ }, fe = (e) => {
442
+ let t = x, n = [t];
443
+ for (; t.parent?.navigation.value === "menu";) t = t.parent, n.push(t);
444
+ let r = t.reference.value, i = e ? r : (r && ue(r, (e) => t.contains(e))) ?? r;
445
+ for (let e of n) e.skipFocusReturn = !0, e.close();
446
+ i?.focus();
447
+ }, pe = (e) => {
448
+ let t = x.navigation.value;
449
+ if (!t || e.defaultPrevented || e.isComposing || ce(e.target)) return;
450
+ let n = Y(), r = n.findIndex((t) => t.contains(e.target)), i = n.length - 1, a = t === "menu", o;
451
+ if (e.key === "ArrowDown") o = n[r < i ? r + 1 : a ? 0 : i];
452
+ else if (e.key === "ArrowUp") o = n[r > 0 ? r - 1 : a || r < 0 ? i : 0];
453
+ else if (e.key === "Home") o = n[0];
454
+ else if (e.key === "End") o = n[i];
455
+ else if (e.key === "Tab" && t === "menu") {
456
+ e.preventDefault(), fe(e.shiftKey);
457
+ return;
458
+ } else if (t === "menu" && x.parent?.navigation.value === "menu" && N.value && e.key === le(N.value).close) {
459
+ e.preventDefault(), x.close();
460
+ return;
461
+ } else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && (e.key !== " " || Q)) e.preventDefault(), o = de(n, r, e.key);
462
+ else if ((e.key === "Enter" || e.key === " ") && e.target === n[r]) {
463
+ let t = n[r];
464
+ if (t.matches("button, a[href], input, summary")) return;
465
+ e.preventDefault(), t.getAttribute("aria-disabled") !== "true" && t.click();
466
+ return;
467
+ }
468
+ o && (e.preventDefault(), o.focus());
222
469
  };
223
- return w(y, (e) => {
224
- if (e) {
225
- E.value = !0;
470
+ return D(S, (e) => {
471
+ let t = x.skipFocusReturn;
472
+ if (x.skipFocusReturn = !1, e) {
473
+ M.value = !0;
226
474
  return;
227
475
  }
228
- let t = document.activeElement;
229
- t && h.floating.value?.contains(t) && h.reference.value?.focus();
230
- }), w(() => y.value && h.isPositioned.value, async (e) => {
231
- e && l.autoFocus && (await d(), N());
232
- }), (n, s) => (m(), r(e, {
233
- to: l.teleportTo,
234
- disabled: l.teleportDisabled
235
- }, [E.value ? (m(), a("div", {
476
+ let n = document.activeElement;
477
+ !t && n && x.floating.value?.contains(n) && x.reference.value?.focus({ preventScroll: !0 });
478
+ }), D(() => S.value && x.isPositioned.value, async (e) => {
479
+ if (!e) return;
480
+ let t = Z();
481
+ (t || I.value) && (await d(), X(t));
482
+ }), D(x.focusRequest, (e) => {
483
+ e && S.value && x.isPositioned.value && X(Z());
484
+ }), (n, s) => (g(), r(e, {
485
+ to: l.teleport || "body",
486
+ disabled: l.teleport === !1
487
+ }, [M.value ? (g(), a("div", {
236
488
  key: 0,
237
- ref: O,
238
- style: f(A.value)
239
- }, [o(t, {
240
- name: l.transition,
241
- css: !!l.transition,
242
- appear: "",
243
- onAfterEnter: j,
244
- onAfterLeave: M
245
- }, {
246
- default: T(() => [x(y) ? (m(), r(v(l.as), u({ key: 0 }, n.$attrs, {
247
- id: x(b),
248
- ref: k,
249
- role: l.role,
250
- tabindex: l.autoFocus ? -1 : void 0,
251
- "data-sbf-state": x(y) ? "open" : "closed",
252
- "data-sbf-side": x(S),
253
- "data-sbf-align": x(C)
489
+ ref: P,
490
+ style: f(ee.value),
491
+ onPointerenter: s[0] ||= (...e) => C(x).hover && C(x).hover(...e),
492
+ onPointerleave: s[1] ||= (...e) => C(x).hover && C(x).hover(...e)
493
+ }, [
494
+ L.value ? (g(), a("span", u({ key: 0 }, R, { onFocus: q }), null, 16)) : i("", !0),
495
+ o(t, u(z.value, {
496
+ appear: "",
497
+ onBeforeLeave: B,
498
+ onAfterEnter: H,
499
+ onAfterLeave: U
254
500
  }), {
255
- default: T(() => [_(n.$slots, "default")]),
501
+ default: k(() => [C(S) ? (g(), r(b(l.as), u({ key: 0 }, te(), {
502
+ id: C(T),
503
+ ref: F,
504
+ role: l.role ?? void 0,
505
+ tabindex: I.value ? -1 : void 0,
506
+ "data-sbf-state": "open",
507
+ "data-sbf-side": C(A),
508
+ "data-sbf-align": C(j),
509
+ onKeydown: pe
510
+ }), {
511
+ default: k(() => [y(n.$slots, "default")]),
512
+ _: 3
513
+ }, 16, [
514
+ "id",
515
+ "role",
516
+ "tabindex",
517
+ "data-sbf-side",
518
+ "data-sbf-align"
519
+ ])) : i("", !0)]),
256
520
  _: 3
257
- }, 16, [
258
- "id",
259
- "role",
260
- "tabindex",
261
- "data-sbf-state",
262
- "data-sbf-side",
263
- "data-sbf-align"
264
- ])) : i("", !0)]),
265
- _: 3
266
- }, 8, ["name", "css"])], 4)) : i("", !0)], 8, ["to", "disabled"]));
521
+ }, 16),
522
+ L.value ? (g(), a("span", u({ key: 1 }, R, { onFocus: J }), null, 16)) : i("", !0)
523
+ ], 36)) : i("", !0)], 8, ["to", "disabled"]));
267
524
  }
268
525
  });
269
526
  //#endregion
270
- export { z as SbContainer, H as SbFloating, B as SbReference };
527
+ export { Y as SbContainer, Z as SbFloating, X as SbReference };