@shopware-ag/meteor-component-library
Version:
The meteor component library is a Vue component library developed by Shopware. It is based on the [Meteor Design System](https://shopware.design/).
1,418 lines • 68 kB
JavaScript
"use strict";
const vue = require("vue");
const Primitive = require("./Primitive-20a16e64.js");
const floatingUi_vue = require("./floating-ui.vue-48d5c774.js");
const floatingUi_dom = require("./floating-ui.dom-fe395b67.js");
function _interopNamespaceDefault(e) {
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
if (e) {
for (const k in e) {
if (k !== "default") {
const d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: () => e[k]
});
}
}
}
n.default = e;
return Object.freeze(n);
}
const vue__namespace = /* @__PURE__ */ _interopNamespaceDefault(vue);
function createContext(providerComponentName, contextName) {
const symbolDescription = typeof providerComponentName === "string" && !contextName ? `${providerComponentName}Context` : contextName;
const injectionKey = Symbol(symbolDescription);
const injectContext = (fallback) => {
const context2 = vue.inject(injectionKey, fallback);
if (context2)
return context2;
if (context2 === null)
return context2;
throw new Error(`Injection \`${injectionKey.toString()}\` not found. Component must be used within ${Array.isArray(providerComponentName) ? `one of the following components: ${providerComponentName.join(", ")}` : `\`${providerComponentName}\``}`);
};
const provideContext = (contextValue) => {
vue.provide(injectionKey, contextValue);
return contextValue;
};
return [injectContext, provideContext];
}
function getActiveElement() {
let activeElement = document.activeElement;
if (activeElement == null)
return null;
while (activeElement != null && activeElement.shadowRoot != null && activeElement.shadowRoot.activeElement != null)
activeElement = activeElement.shadowRoot.activeElement;
return activeElement;
}
function handleAndDispatchCustomEvent(name, handler, detail) {
const target = detail.originalEvent.target;
const event = new CustomEvent(name, {
bubbles: false,
cancelable: true,
detail
});
if (handler)
target.addEventListener(name, handler, { once: true });
target.dispatchEvent(event);
}
const ignoredElement = ["INPUT", "TEXTAREA"];
function useArrowNavigation(e, currentElement, parentElement, options = {}) {
if (!currentElement || options.enableIgnoredElement && ignoredElement.includes(currentElement.nodeName))
return null;
const { arrowKeyOptions = "both", attributeName = "[data-reka-collection-item]", itemsArray = [], loop = true, dir = "ltr", preventScroll = true, focus: focus2 = false } = options;
const [right, left, up, down, home, end] = [
e.key === "ArrowRight",
e.key === "ArrowLeft",
e.key === "ArrowUp",
e.key === "ArrowDown",
e.key === "Home",
e.key === "End"
];
const goingVertical = up || down;
const goingHorizontal = right || left;
if (!home && !end && (!goingVertical && !goingHorizontal || arrowKeyOptions === "vertical" && goingHorizontal || arrowKeyOptions === "horizontal" && goingVertical))
return null;
const allCollectionItems = parentElement ? Array.from(parentElement.querySelectorAll(attributeName)) : itemsArray;
if (!allCollectionItems.length)
return null;
if (preventScroll)
e.preventDefault();
let item = null;
if (goingHorizontal || goingVertical) {
const goForward = goingVertical ? down : dir === "ltr" ? right : left;
item = findNextFocusableElement(allCollectionItems, currentElement, {
goForward,
loop
});
} else if (home)
item = allCollectionItems.at(0) || null;
else if (end)
item = allCollectionItems.at(-1) || null;
if (focus2)
item == null ? void 0 : item.focus();
return item;
}
function findNextFocusableElement(elements, currentElement, options, iterations = elements.length) {
if (--iterations === 0)
return null;
const index = elements.indexOf(currentElement);
const newIndex = options.goForward ? index + 1 : index - 1;
if (!options.loop && (newIndex < 0 || newIndex >= elements.length))
return null;
const adjustedNewIndex = (newIndex + elements.length) % elements.length;
const candidate = elements[adjustedNewIndex];
if (!candidate)
return null;
const isDisabled = candidate.hasAttribute("disabled") && candidate.getAttribute("disabled") !== "false";
if (isDisabled)
return findNextFocusableElement(elements, candidate, options, iterations);
return candidate;
}
const [injectConfigProviderContext, provideConfigProviderContext] = createContext("ConfigProvider");
function isPlainObject(value) {
if (value === null || typeof value !== "object") {
return false;
}
const prototype = Object.getPrototypeOf(value);
if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
return false;
}
if (Symbol.iterator in value) {
return false;
}
if (Symbol.toStringTag in value) {
return Object.prototype.toString.call(value) === "[object Module]";
}
return true;
}
function _defu(baseObject, defaults, namespace = ".", merger) {
if (!isPlainObject(defaults)) {
return _defu(baseObject, {}, namespace, merger);
}
const object = Object.assign({}, defaults);
for (const key in baseObject) {
if (key === "__proto__" || key === "constructor") {
continue;
}
const value = baseObject[key];
if (value === null || value === void 0) {
continue;
}
if (merger && merger(object, key, value, namespace)) {
continue;
}
if (Array.isArray(value) && Array.isArray(object[key])) {
object[key] = [...value, ...object[key]];
} else if (isPlainObject(value) && isPlainObject(object[key])) {
object[key] = _defu(
value,
object[key],
(namespace ? `${namespace}.` : "") + key.toString(),
merger
);
} else {
object[key] = value;
}
}
return object;
}
function createDefu(merger) {
return (...arguments_) => (
// eslint-disable-next-line unicorn/no-array-reduce
arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
);
}
const defu = createDefu();
const useBodyLockStackCount = Primitive.createSharedComposable(() => {
const map = vue.ref(/* @__PURE__ */ new Map());
const initialOverflow = vue.ref();
const locked = vue.computed(() => {
for (const value of map.value.values())
if (value)
return true;
return false;
});
const context2 = injectConfigProviderContext({ scrollBody: vue.ref(true) });
let stopTouchMoveListener = null;
const resetBodyStyle = () => {
document.body.style.paddingRight = "";
document.body.style.marginRight = "";
document.body.style.pointerEvents = "";
document.documentElement.style.removeProperty("--scrollbar-width");
document.body.style.overflow = initialOverflow.value ?? "";
Primitive.isIOS && (stopTouchMoveListener == null ? void 0 : stopTouchMoveListener());
initialOverflow.value = void 0;
};
vue.watch(locked, (val, oldVal) => {
var _a;
if (!Primitive.isClient)
return;
if (!val) {
if (oldVal)
resetBodyStyle();
return;
}
if (initialOverflow.value === void 0)
initialOverflow.value = document.body.style.overflow;
const verticalScrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
const defaultConfig = {
padding: verticalScrollbarWidth,
margin: 0
};
const config = ((_a = context2.scrollBody) == null ? void 0 : _a.value) ? typeof context2.scrollBody.value === "object" ? defu({
padding: context2.scrollBody.value.padding === true ? verticalScrollbarWidth : context2.scrollBody.value.padding,
margin: context2.scrollBody.value.margin === true ? verticalScrollbarWidth : context2.scrollBody.value.margin
}, defaultConfig) : defaultConfig : {
padding: 0,
margin: 0
};
if (verticalScrollbarWidth > 0) {
document.body.style.paddingRight = typeof config.padding === "number" ? `${config.padding}px` : String(config.padding);
document.body.style.marginRight = typeof config.margin === "number" ? `${config.margin}px` : String(config.margin);
document.documentElement.style.setProperty("--scrollbar-width", `${verticalScrollbarWidth}px`);
document.body.style.overflow = "hidden";
}
if (Primitive.isIOS)
stopTouchMoveListener = Primitive.useEventListener(document, "touchmove", (e) => preventDefault(e), { passive: false });
vue.nextTick(() => {
document.body.style.pointerEvents = "none";
document.body.style.overflow = "hidden";
});
}, {
immediate: true,
flush: "sync"
});
return map;
});
function useBodyScrollLock(initialState) {
const id = Math.random().toString(36).substring(2, 7);
const map = useBodyLockStackCount();
map.value.set(id, initialState ?? false);
const locked = vue.computed({
get: () => map.value.get(id) ?? false,
set: (value) => map.value.set(id, value)
});
Primitive.tryOnBeforeUnmount(() => {
map.value.delete(id);
});
return locked;
}
function checkOverflowScroll(ele) {
const style = window.getComputedStyle(ele);
if (style.overflowX === "scroll" || style.overflowY === "scroll" || style.overflowX === "auto" && ele.clientWidth < ele.scrollWidth || style.overflowY === "auto" && ele.clientHeight < ele.scrollHeight)
return true;
else {
const parent = ele.parentNode;
if (!(parent instanceof Element) || parent.tagName === "BODY")
return false;
return checkOverflowScroll(parent);
}
}
function preventDefault(rawEvent) {
const e = rawEvent || window.event;
const _target = e.target;
if (_target instanceof Element && checkOverflowScroll(_target))
return false;
if (e.touches.length > 1)
return true;
if (e.preventDefault && e.cancelable)
e.preventDefault();
return false;
}
function useDirection(dir) {
const context2 = injectConfigProviderContext({ dir: vue.ref("ltr") });
return vue.computed(() => {
var _a;
return (dir == null ? void 0 : dir.value) || ((_a = context2.dir) == null ? void 0 : _a.value) || "ltr";
});
}
function useEmitAsProps(emit) {
const vm = vue.getCurrentInstance();
const events = vm == null ? void 0 : vm.type.emits;
const result = {};
if (!(events == null ? void 0 : events.length))
console.warn(`No emitted event found. Please check component: ${vm == null ? void 0 : vm.type.__name}`);
events == null ? void 0 : events.forEach((ev) => {
result[vue.toHandlerKey(vue.camelize(ev))] = (...arg) => emit(ev, ...arg);
});
return result;
}
let count$1 = 0;
function useFocusGuards() {
vue.watchEffect((cleanupFn) => {
if (!Primitive.isClient)
return;
const edgeGuards = document.querySelectorAll("[data-reka-focus-guard]");
document.body.insertAdjacentElement("afterbegin", edgeGuards[0] ?? createFocusGuard());
document.body.insertAdjacentElement("beforeend", edgeGuards[1] ?? createFocusGuard());
count$1++;
cleanupFn(() => {
if (count$1 === 1)
document.querySelectorAll("[data-reka-focus-guard]").forEach((node) => node.remove());
count$1--;
});
});
}
function createFocusGuard() {
const element = document.createElement("span");
element.setAttribute("data-reka-focus-guard", "");
element.tabIndex = 0;
element.style.outline = "none";
element.style.opacity = "0";
element.style.position = "fixed";
element.style.pointerEvents = "none";
return element;
}
let count = 0;
function useId(deterministicId, prefix = "reka") {
var _a;
if (deterministicId)
return deterministicId;
if ("useId" in vue__namespace)
return `${prefix}-${(_a = vue__namespace.useId) == null ? void 0 : _a.call(vue__namespace)}`;
const configProviderContext = injectConfigProviderContext({ useId: void 0 });
if (configProviderContext.useId)
return `${prefix}-${configProviderContext.useId()}`;
return `${prefix}-${++count}`;
}
function useSize(element) {
const size = vue.ref();
const width = vue.computed(() => {
var _a;
return ((_a = size.value) == null ? void 0 : _a.width) ?? 0;
});
const height = vue.computed(() => {
var _a;
return ((_a = size.value) == null ? void 0 : _a.height) ?? 0;
});
vue.onMounted(() => {
const el = Primitive.unrefElement(element);
if (el) {
size.value = {
width: el.offsetWidth,
height: el.offsetHeight
};
const resizeObserver = new ResizeObserver((entries) => {
if (!Array.isArray(entries))
return;
if (!entries.length)
return;
const entry = entries[0];
let width$1;
let height$1;
if ("borderBoxSize" in entry) {
const borderSizeEntry = entry.borderBoxSize;
const borderSize = Array.isArray(borderSizeEntry) ? borderSizeEntry[0] : borderSizeEntry;
width$1 = borderSize.inlineSize;
height$1 = borderSize.blockSize;
} else {
width$1 = el.offsetWidth;
height$1 = el.offsetHeight;
}
size.value = {
width: width$1,
height: height$1
};
});
resizeObserver.observe(el, { box: "border-box" });
return () => resizeObserver.unobserve(el);
} else
size.value = void 0;
});
return {
width,
height
};
}
function useTypeahead(callback) {
const search = Primitive.refAutoReset("", 1e3);
const handleTypeaheadSearch = (key, items) => {
search.value = search.value + key;
if (callback)
callback(key);
else {
const currentItem = getActiveElement();
const itemsWithTextValue = items.map((item) => {
var _a, _b;
return {
...item,
textValue: ((_a = item.value) == null ? void 0 : _a.textValue) ?? ((_b = item.ref.textContent) == null ? void 0 : _b.trim()) ?? ""
};
});
const currentMatch = itemsWithTextValue.find((item) => item.ref === currentItem);
const values = itemsWithTextValue.map((item) => item.textValue);
const nextMatch = getNextMatch(values, search.value, currentMatch == null ? void 0 : currentMatch.textValue);
const newItem = itemsWithTextValue.find((item) => item.textValue === nextMatch);
if (newItem)
newItem.ref.focus();
return newItem == null ? void 0 : newItem.ref;
}
};
const resetTypeahead = () => {
search.value = "";
};
return {
search,
handleTypeaheadSearch,
resetTypeahead
};
}
function wrapArray(array, startIndex) {
return array.map((_, index) => array[(startIndex + index) % array.length]);
}
function getNextMatch(values, search, currentMatch) {
const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
const normalizedSearch = isRepeated ? search[0] : search;
const currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
let wrappedValues = wrapArray(values, Math.max(currentMatchIndex, 0));
const excludeCurrentMatch = normalizedSearch.length === 1;
if (excludeCurrentMatch)
wrappedValues = wrappedValues.filter((v) => v !== currentMatch);
const nextMatch = wrappedValues.find((value) => value.toLowerCase().startsWith(normalizedSearch.toLowerCase()));
return nextMatch !== currentMatch ? nextMatch : void 0;
}
function usePrimitiveElement() {
const primitiveElement = vue.ref();
const currentElement = vue.computed(() => {
var _a, _b;
return ["#text", "#comment"].includes((_a = primitiveElement.value) == null ? void 0 : _a.$el.nodeName) ? (_b = primitiveElement.value) == null ? void 0 : _b.$el.nextElementSibling : Primitive.unrefElement(primitiveElement);
});
return {
primitiveElement,
currentElement
};
}
const POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside";
const FOCUS_OUTSIDE = "dismissableLayer.focusOutside";
function isLayerExist(layerElement, targetElement) {
const targetLayer = targetElement.closest("[data-dismissable-layer]");
const mainLayer = layerElement.dataset.dismissableLayer === "" ? layerElement : layerElement.querySelector("[data-dismissable-layer]");
const nodeList = Array.from(layerElement.ownerDocument.querySelectorAll("[data-dismissable-layer]"));
if (targetLayer && (mainLayer === targetLayer || nodeList.indexOf(mainLayer) < nodeList.indexOf(targetLayer)))
return true;
else
return false;
}
function usePointerDownOutside(onPointerDownOutside, element, enabled = true) {
var _a;
const ownerDocument = ((_a = element == null ? void 0 : element.value) == null ? void 0 : _a.ownerDocument) ?? (globalThis == null ? void 0 : globalThis.document);
const isPointerInsideDOMTree = vue.ref(false);
const handleClickRef = vue.ref(() => {
});
vue.watchEffect((cleanupFn) => {
if (!Primitive.isClient || !vue.toValue(enabled))
return;
const handlePointerDown = async (event) => {
const target = event.target;
if (!(element == null ? void 0 : element.value) || !target)
return;
if (isLayerExist(element.value, target)) {
isPointerInsideDOMTree.value = false;
return;
}
if (event.target && !isPointerInsideDOMTree.value) {
let handleAndDispatchPointerDownOutsideEvent = function() {
handleAndDispatchCustomEvent(POINTER_DOWN_OUTSIDE, onPointerDownOutside, eventDetail);
};
const eventDetail = { originalEvent: event };
if (event.pointerType === "touch") {
ownerDocument.removeEventListener("click", handleClickRef.value);
handleClickRef.value = handleAndDispatchPointerDownOutsideEvent;
ownerDocument.addEventListener("click", handleClickRef.value, { once: true });
} else
handleAndDispatchPointerDownOutsideEvent();
} else
ownerDocument.removeEventListener("click", handleClickRef.value);
isPointerInsideDOMTree.value = false;
};
const timerId = window.setTimeout(() => {
ownerDocument.addEventListener("pointerdown", handlePointerDown);
}, 0);
cleanupFn(() => {
window.clearTimeout(timerId);
ownerDocument.removeEventListener("pointerdown", handlePointerDown);
ownerDocument.removeEventListener("click", handleClickRef.value);
});
});
return { onPointerDownCapture: () => {
if (!vue.toValue(enabled))
return;
isPointerInsideDOMTree.value = true;
} };
}
function useFocusOutside(onFocusOutside, element, enabled = true) {
var _a;
const ownerDocument = ((_a = element == null ? void 0 : element.value) == null ? void 0 : _a.ownerDocument) ?? (globalThis == null ? void 0 : globalThis.document);
const isFocusInsideDOMTree = vue.ref(false);
vue.watchEffect((cleanupFn) => {
if (!Primitive.isClient || !vue.toValue(enabled))
return;
const handleFocus = async (event) => {
if (!(element == null ? void 0 : element.value))
return;
await vue.nextTick();
await vue.nextTick();
const target = event.target;
if (!element.value || !target || isLayerExist(element.value, target))
return;
if (event.target && !isFocusInsideDOMTree.value) {
const eventDetail = { originalEvent: event };
handleAndDispatchCustomEvent(FOCUS_OUTSIDE, onFocusOutside, eventDetail);
}
};
ownerDocument.addEventListener("focusin", handleFocus);
cleanupFn(() => ownerDocument.removeEventListener("focusin", handleFocus));
});
return {
onFocusCapture: () => {
if (!vue.toValue(enabled))
return;
isFocusInsideDOMTree.value = true;
},
onBlurCapture: () => {
if (!vue.toValue(enabled))
return;
isFocusInsideDOMTree.value = false;
}
};
}
const context = vue.reactive({
layersRoot: /* @__PURE__ */ new Set(),
layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(),
branches: /* @__PURE__ */ new Set()
});
var DismissableLayer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({
__name: "DismissableLayer",
props: {
disableOutsidePointerEvents: {
type: Boolean,
required: false,
default: false
},
asChild: {
type: Boolean,
required: false
},
as: {
type: null,
required: false
}
},
emits: [
"escapeKeyDown",
"pointerDownOutside",
"focusOutside",
"interactOutside",
"dismiss"
],
setup(__props, { emit: __emit }) {
const props = __props;
const emits = __emit;
const { forwardRef, currentElement: layerElement } = Primitive.useForwardExpose();
const ownerDocument = vue.computed(() => {
var _a;
return ((_a = layerElement.value) == null ? void 0 : _a.ownerDocument) ?? globalThis.document;
});
const layers = vue.computed(() => context.layersRoot);
const index = vue.computed(() => {
return layerElement.value ? Array.from(layers.value).indexOf(layerElement.value) : -1;
});
const isBodyPointerEventsDisabled = vue.computed(() => {
return context.layersWithOutsidePointerEventsDisabled.size > 0;
});
const isPointerEventsEnabled = vue.computed(() => {
const localLayers = Array.from(layers.value);
const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);
const highestLayerWithOutsidePointerEventsDisabledIndex = localLayers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
return index.value >= highestLayerWithOutsidePointerEventsDisabledIndex;
});
const pointerDownOutside = usePointerDownOutside(async (event) => {
const isPointerDownOnBranch = [...context.branches].some((branch) => branch == null ? void 0 : branch.contains(event.target));
if (!isPointerEventsEnabled.value || isPointerDownOnBranch)
return;
emits("pointerDownOutside", event);
emits("interactOutside", event);
await vue.nextTick();
if (!event.defaultPrevented)
emits("dismiss");
}, layerElement);
const focusOutside = useFocusOutside((event) => {
const isFocusInBranch = [...context.branches].some((branch) => branch == null ? void 0 : branch.contains(event.target));
if (isFocusInBranch)
return;
emits("focusOutside", event);
emits("interactOutside", event);
if (!event.defaultPrevented)
emits("dismiss");
}, layerElement);
Primitive.onKeyStroke("Escape", (event) => {
const isHighestLayer = index.value === layers.value.size - 1;
if (!isHighestLayer)
return;
emits("escapeKeyDown", event);
if (!event.defaultPrevented)
emits("dismiss");
});
let originalBodyPointerEvents;
vue.watchEffect((cleanupFn) => {
if (!layerElement.value)
return;
if (props.disableOutsidePointerEvents) {
if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
originalBodyPointerEvents = ownerDocument.value.body.style.pointerEvents;
ownerDocument.value.body.style.pointerEvents = "none";
}
context.layersWithOutsidePointerEventsDisabled.add(layerElement.value);
}
layers.value.add(layerElement.value);
cleanupFn(() => {
if (props.disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1)
ownerDocument.value.body.style.pointerEvents = originalBodyPointerEvents;
});
});
vue.watchEffect((cleanupFn) => {
cleanupFn(() => {
if (!layerElement.value)
return;
layers.value.delete(layerElement.value);
context.layersWithOutsidePointerEventsDisabled.delete(layerElement.value);
});
});
return (_ctx, _cache) => {
return vue.openBlock(), vue.createBlock(vue.unref(Primitive.Primitive), {
ref: vue.unref(forwardRef),
"as-child": _ctx.asChild,
as: _ctx.as,
"data-dismissable-layer": "",
style: vue.normalizeStyle({ pointerEvents: isBodyPointerEventsDisabled.value ? isPointerEventsEnabled.value ? "auto" : "none" : void 0 }),
onFocusCapture: vue.unref(focusOutside).onFocusCapture,
onBlurCapture: vue.unref(focusOutside).onBlurCapture,
onPointerdownCapture: vue.unref(pointerDownOutside).onPointerDownCapture
}, {
default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]),
_: 3
}, 8, [
"as-child",
"as",
"style",
"onFocusCapture",
"onBlurCapture",
"onPointerdownCapture"
]);
};
}
});
var DismissableLayer_default = DismissableLayer_vue_vue_type_script_setup_true_lang_default;
const useFocusStackState = Primitive.createGlobalState(() => {
const stack = vue.ref([]);
return stack;
});
function createFocusScopesStack() {
const stack = useFocusStackState();
return {
add(focusScope) {
const activeFocusScope = stack.value[0];
if (focusScope !== activeFocusScope)
activeFocusScope == null ? void 0 : activeFocusScope.pause();
stack.value = arrayRemove(stack.value, focusScope);
stack.value.unshift(focusScope);
},
remove(focusScope) {
var _a;
stack.value = arrayRemove(stack.value, focusScope);
(_a = stack.value[0]) == null ? void 0 : _a.resume();
}
};
}
function arrayRemove(array, item) {
const updatedArray = [...array];
const index = updatedArray.indexOf(item);
if (index !== -1)
updatedArray.splice(index, 1);
return updatedArray;
}
function removeLinks(items) {
return items.filter((item) => item.tagName !== "A");
}
const AUTOFOCUS_ON_MOUNT = "focusScope.autoFocusOnMount";
const AUTOFOCUS_ON_UNMOUNT = "focusScope.autoFocusOnUnmount";
const EVENT_OPTIONS$1 = {
bubbles: false,
cancelable: true
};
function focusFirst$2(candidates, { select = false } = {}) {
const previouslyFocusedElement = getActiveElement();
for (const candidate of candidates) {
focus(candidate, { select });
if (getActiveElement() !== previouslyFocusedElement)
return true;
}
}
function getTabbableEdges(container) {
const candidates = getTabbableCandidates(container);
const first = findVisible(candidates, container);
const last = findVisible(candidates.reverse(), container);
return [first, last];
}
function getTabbableCandidates(container) {
const nodes = [];
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, { acceptNode: (node) => {
const isHiddenInput = node.tagName === "INPUT" && node.type === "hidden";
if (node.disabled || node.hidden || isHiddenInput)
return NodeFilter.FILTER_SKIP;
return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
} });
while (walker.nextNode())
nodes.push(walker.currentNode);
return nodes;
}
function findVisible(elements, container) {
for (const element of elements)
if (!isHidden(element, { upTo: container }))
return element;
}
function isHidden(node, { upTo }) {
if (getComputedStyle(node).visibility === "hidden")
return true;
while (node) {
if (upTo !== void 0 && node === upTo)
return false;
if (getComputedStyle(node).display === "none")
return true;
node = node.parentElement;
}
return false;
}
function isSelectableInput(element) {
return element instanceof HTMLInputElement && "select" in element;
}
function focus(element, { select = false } = {}) {
if (element && element.focus) {
const previouslyFocusedElement = getActiveElement();
element.focus({ preventScroll: true });
if (element !== previouslyFocusedElement && isSelectableInput(element) && select)
element.select();
}
}
var FocusScope_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({
__name: "FocusScope",
props: {
loop: {
type: Boolean,
required: false,
default: false
},
trapped: {
type: Boolean,
required: false,
default: false
},
asChild: {
type: Boolean,
required: false
},
as: {
type: null,
required: false
}
},
emits: ["mountAutoFocus", "unmountAutoFocus"],
setup(__props, { emit: __emit }) {
const props = __props;
const emits = __emit;
const { currentRef, currentElement } = Primitive.useForwardExpose();
const lastFocusedElementRef = vue.ref(null);
const focusScopesStack = createFocusScopesStack();
const focusScope = vue.reactive({
paused: false,
pause() {
this.paused = true;
},
resume() {
this.paused = false;
}
});
vue.watchEffect((cleanupFn) => {
if (!Primitive.isClient)
return;
const container = currentElement.value;
if (!props.trapped)
return;
function handleFocusIn(event) {
if (focusScope.paused || !container)
return;
const target = event.target;
if (container.contains(target))
lastFocusedElementRef.value = target;
else
focus(lastFocusedElementRef.value, { select: true });
}
function handleFocusOut(event) {
if (focusScope.paused || !container)
return;
const relatedTarget = event.relatedTarget;
if (relatedTarget === null)
return;
if (!container.contains(relatedTarget))
focus(lastFocusedElementRef.value, { select: true });
}
function handleMutations(mutations) {
const isLastFocusedElementExist = container.contains(lastFocusedElementRef.value);
if (!isLastFocusedElementExist)
focus(container);
}
document.addEventListener("focusin", handleFocusIn);
document.addEventListener("focusout", handleFocusOut);
const mutationObserver = new MutationObserver(handleMutations);
if (container)
mutationObserver.observe(container, {
childList: true,
subtree: true
});
cleanupFn(() => {
document.removeEventListener("focusin", handleFocusIn);
document.removeEventListener("focusout", handleFocusOut);
mutationObserver.disconnect();
});
});
vue.watchEffect(async (cleanupFn) => {
const container = currentElement.value;
await vue.nextTick();
if (!container)
return;
focusScopesStack.add(focusScope);
const previouslyFocusedElement = getActiveElement();
const hasFocusedCandidate = container.contains(previouslyFocusedElement);
if (!hasFocusedCandidate) {
const mountEvent = new CustomEvent(AUTOFOCUS_ON_MOUNT, EVENT_OPTIONS$1);
container.addEventListener(AUTOFOCUS_ON_MOUNT, (ev) => emits("mountAutoFocus", ev));
container.dispatchEvent(mountEvent);
if (!mountEvent.defaultPrevented) {
focusFirst$2(removeLinks(getTabbableCandidates(container)), { select: true });
if (getActiveElement() === previouslyFocusedElement)
focus(container);
}
}
cleanupFn(() => {
container.removeEventListener(AUTOFOCUS_ON_MOUNT, (ev) => emits("mountAutoFocus", ev));
const unmountEvent = new CustomEvent(AUTOFOCUS_ON_UNMOUNT, EVENT_OPTIONS$1);
const unmountEventHandler = (ev) => {
emits("unmountAutoFocus", ev);
};
container.addEventListener(AUTOFOCUS_ON_UNMOUNT, unmountEventHandler);
container.dispatchEvent(unmountEvent);
setTimeout(() => {
if (!unmountEvent.defaultPrevented)
focus(previouslyFocusedElement ?? document.body, { select: true });
container.removeEventListener(AUTOFOCUS_ON_UNMOUNT, unmountEventHandler);
focusScopesStack.remove(focusScope);
}, 0);
});
});
function handleKeyDown(event) {
if (!props.loop && !props.trapped)
return;
if (focusScope.paused)
return;
const isTabKey = event.key === "Tab" && !event.altKey && !event.ctrlKey && !event.metaKey;
const focusedElement = getActiveElement();
if (isTabKey && focusedElement) {
const container = event.currentTarget;
const [first, last] = getTabbableEdges(container);
const hasTabbableElementsInside = first && last;
if (!hasTabbableElementsInside) {
if (focusedElement === container)
event.preventDefault();
} else if (!event.shiftKey && focusedElement === last) {
event.preventDefault();
if (props.loop)
focus(first, { select: true });
} else if (event.shiftKey && focusedElement === first) {
event.preventDefault();
if (props.loop)
focus(last, { select: true });
}
}
}
return (_ctx, _cache) => {
return vue.openBlock(), vue.createBlock(vue.unref(Primitive.Primitive), {
ref_key: "currentRef",
ref: currentRef,
tabindex: "-1",
"as-child": _ctx.asChild,
as: _ctx.as,
onKeydown: handleKeyDown
}, {
default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]),
_: 3
}, 8, ["as-child", "as"]);
};
}
});
var FocusScope_default = FocusScope_vue_vue_type_script_setup_true_lang_default;
const ITEM_SELECT = "menu.itemSelect";
const SELECTION_KEYS = ["Enter", " "];
const FIRST_KEYS = [
"ArrowDown",
"PageUp",
"Home"
];
const LAST_KEYS = [
"ArrowUp",
"PageDown",
"End"
];
const FIRST_LAST_KEYS = [...FIRST_KEYS, ...LAST_KEYS];
const SUB_OPEN_KEYS = {
ltr: [...SELECTION_KEYS, "ArrowRight"],
rtl: [...SELECTION_KEYS, "ArrowLeft"]
};
const SUB_CLOSE_KEYS = {
ltr: ["ArrowLeft"],
rtl: ["ArrowRight"]
};
function getOpenState(open) {
return open ? "open" : "closed";
}
function focusFirst$1(candidates) {
const PREVIOUSLY_FOCUSED_ELEMENT = getActiveElement();
for (const candidate of candidates) {
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT)
return;
candidate.focus();
if (getActiveElement() !== PREVIOUSLY_FOCUSED_ELEMENT)
return;
}
}
function isPointInPolygon(point, polygon) {
const { x, y } = point;
let inside = false;
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
const xi = polygon[i].x;
const yi = polygon[i].y;
const xj = polygon[j].x;
const yj = polygon[j].y;
const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
if (intersect)
inside = !inside;
}
return inside;
}
function isPointerInGraceArea(event, area) {
if (!area)
return false;
const cursorPos = {
x: event.clientX,
y: event.clientY
};
return isPointInPolygon(cursorPos, area);
}
function isMouseEvent(event) {
return event.pointerType === "mouse";
}
const ITEM_DATA_ATTR = "data-reka-collection-item";
function useCollection(options = {}) {
const { key = "", isProvider = false } = options;
const injectionKey = `${key}CollectionProvider`;
let context2;
if (isProvider) {
const itemMap = vue.ref(/* @__PURE__ */ new Map());
const collectionRef = vue.ref();
context2 = {
collectionRef,
itemMap
};
vue.provide(injectionKey, context2);
} else
context2 = vue.inject(injectionKey);
const getItems = (includeDisabledItem = false) => {
const collectionNode = context2.collectionRef.value;
if (!collectionNode)
return [];
const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
const items = Array.from(context2.itemMap.value.values());
const orderedItems = items.sort((a, b) => orderedNodes.indexOf(a.ref) - orderedNodes.indexOf(b.ref));
if (includeDisabledItem)
return orderedItems;
else
return orderedItems.filter((i) => i.ref.dataset.disabled !== "");
};
const CollectionSlot = vue.defineComponent({
name: "CollectionSlot",
setup(_, { slots }) {
const { primitiveElement, currentElement } = usePrimitiveElement();
vue.watch(currentElement, () => {
context2.collectionRef.value = currentElement.value;
});
return () => vue.h(Primitive.Slot, { ref: primitiveElement }, slots);
}
});
const CollectionItem = vue.defineComponent({
name: "CollectionItem",
inheritAttrs: false,
props: { value: { validator: () => true } },
setup(props, { slots, attrs }) {
const { primitiveElement, currentElement } = usePrimitiveElement();
vue.watchEffect((cleanupFn) => {
if (currentElement.value) {
const key$1 = vue.markRaw(currentElement.value);
context2.itemMap.value.set(key$1, {
ref: currentElement.value,
value: props.value
});
cleanupFn(() => context2.itemMap.value.delete(key$1));
}
});
return () => vue.h(Primitive.Slot, {
...attrs,
[ITEM_DATA_ATTR]: "",
ref: primitiveElement
}, slots);
}
});
const reactiveItems = vue.computed(() => Array.from(context2.itemMap.value.values()));
const itemMapSize = vue.computed(() => context2.itemMap.value.size);
return {
getItems,
reactiveItems,
itemMapSize,
CollectionSlot,
CollectionItem
};
}
const ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
const EVENT_OPTIONS = {
bubbles: false,
cancelable: true
};
function focusFirst(candidates, preventScroll = false) {
const PREVIOUSLY_FOCUSED_ELEMENT = getActiveElement();
for (const candidate of candidates) {
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT)
return;
candidate.focus({ preventScroll });
if (getActiveElement() !== PREVIOUSLY_FOCUSED_ELEMENT)
return;
}
}
const [injectRovingFocusGroupContext, provideRovingFocusGroupContext] = createContext("RovingFocusGroup");
var RovingFocusGroup_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({
__name: "RovingFocusGroup",
props: {
orientation: {
type: String,
required: false,
default: void 0
},
dir: {
type: String,
required: false
},
loop: {
type: Boolean,
required: false,
default: false
},
currentTabStopId: {
type: [String, null],
required: false
},
defaultCurrentTabStopId: {
type: String,
required: false
},
preventScrollOnEntryFocus: {
type: Boolean,
required: false,
default: false
},
asChild: {
type: Boolean,
required: false
},
as: {
type: null,
required: false
}
},
emits: ["entryFocus", "update:currentTabStopId"],
setup(__props, { expose: __expose, emit: __emit }) {
const props = __props;
const emits = __emit;
const { loop, orientation, dir: propDir } = vue.toRefs(props);
const dir = useDirection(propDir);
const currentTabStopId = Primitive.useVModel(props, "currentTabStopId", emits, {
defaultValue: props.defaultCurrentTabStopId,
passive: props.currentTabStopId === void 0
});
const isTabbingBackOut = vue.ref(false);
const isClickFocus = vue.ref(false);
const focusableItemsCount = vue.ref(0);
const { getItems, CollectionSlot } = useCollection({ isProvider: true });
function handleFocus(event) {
const isKeyboardFocus = !isClickFocus.value;
if (event.currentTarget && event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut.value) {
const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
event.currentTarget.dispatchEvent(entryFocusEvent);
emits("entryFocus", entryFocusEvent);
if (!entryFocusEvent.defaultPrevented) {
const items = getItems().map((i) => i.ref).filter((i) => i.dataset.disabled !== "");
const activeItem = items.find((item) => item.getAttribute("data-active") === "");
const highlightedItem = items.find((item) => item.getAttribute("data-highlighted") === "");
const currentItem = items.find((item) => item.id === currentTabStopId.value);
const candidateItems = [
activeItem,
highlightedItem,
currentItem,
...items
].filter(Boolean);
focusFirst(candidateItems, props.preventScrollOnEntryFocus);
}
}
isClickFocus.value = false;
}
function handleMouseUp() {
setTimeout(() => {
isClickFocus.value = false;
}, 1);
}
__expose({ getItems });
provideRovingFocusGroupContext({
loop,
dir,
orientation,
currentTabStopId,
onItemFocus: (tabStopId) => {
currentTabStopId.value = tabStopId;
},
onItemShiftTab: () => {
isTabbingBackOut.value = true;
},
onFocusableItemAdd: () => {
focusableItemsCount.value++;
},
onFocusableItemRemove: () => {
focusableItemsCount.value--;
}
});
return (_ctx, _cache) => {
return vue.openBlock(), vue.createBlock(vue.unref(CollectionSlot), null, {
default: vue.withCtx(() => [vue.createVNode(vue.unref(Primitive.Primitive), {
tabindex: isTabbingBackOut.value || focusableItemsCount.value === 0 ? -1 : 0,
"data-orientation": vue.unref(orientation),
as: _ctx.as,
"as-child": _ctx.asChild,
dir: vue.unref(dir),
style: { "outline": "none" },
onMousedown: _cache[0] || (_cache[0] = ($event) => isClickFocus.value = true),
onMouseup: handleMouseUp,
onFocus: handleFocus,
onBlur: _cache[1] || (_cache[1] = ($event) => isTabbingBackOut.value = false)
}, {
default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]),
_: 3
}, 8, [
"tabindex",
"data-orientation",
"as",
"as-child",
"dir"
])]),
_: 3
});
};
}
});
var RovingFocusGroup_default = RovingFocusGroup_vue_vue_type_script_setup_true_lang_default;
const [injectPopperRootContext, providePopperRootContext] = createContext("PopperRoot");
var PopperRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({
inheritAttrs: false,
__name: "PopperRoot",
setup(__props) {
const anchor = vue.ref();
providePopperRootContext({
anchor,
onAnchorChange: (element) => anchor.value = element
});
return (_ctx, _cache) => {
return vue.renderSlot(_ctx.$slots, "default");
};
}
});
var PopperRoot_default = PopperRoot_vue_vue_type_script_setup_true_lang_default;
function isNotNull(value) {
return value !== null;
}
function transformOrigin(options) {
return {
name: "transformOrigin",
options,
fn(data) {
var _a, _b, _c;
const { placement, rects, middlewareData } = data;
const cannotCenterArrow = ((_a = middlewareData.arrow) == null ? void 0 : _a.centerOffset) !== 0;
const isArrowHidden = cannotCenterArrow;
const arrowWidth = isArrowHidden ? 0 : options.arrowWidth;
const arrowHeight = isArrowHidden ? 0 : options.arrowHeight;
const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement);
const noArrowAlign = {
start: "0%",
center: "50%",
end: "100%"
}[placedAlign];
const arrowXCenter = (((_b = middlewareData.arrow) == null ? void 0 : _b.x) ?? 0) + arrowWidth / 2;
const arrowYCenter = (((_c = middlewareData.arrow) == null ? void 0 : _c.y) ?? 0) + arrowHeight / 2;
let x = "";
let y = "";
if (placedSide === "bottom") {
x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
y = `${-arrowHeight}px`;
} else if (placedSide === "top") {
x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
y = `${rects.floating.height + arrowHeight}px`;
} else if (placedSide === "right") {
x = `${-arrowHeight}px`;
y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
} else if (placedSide === "left") {
x = `${rects.floating.width + arrowHeight}px`;
y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
}
return { data: {
x,
y
} };
}
};
}
function getSideAndAlignFromPlacement(placement) {
const [side, align = "center"] = placement.split("-");
return [side, align];
}
const PopperContentPropsDefaultValue = {
side: "bottom",
sideOffset: 0,
sideFlip: true,
align: "center",
alignOffset: 0,
alignFlip: true,
arrowPadding: 0,
avoidCollisions: true,
collisionBoundary: () => [],
collisionPadding: 0,
sticky: "partial",
hideWhenDetached: false,
positionStrategy: "fixed",
updatePositionStrategy: "optimized",
prioritizePosition: false
};
const [injectPopperContentContext, providePopperContentContext] = createContext("PopperContent");
var PopperContent_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({
inheritAttrs: false,
__name: "PopperContent",
props: /* @__PURE__ */ vue.mergeDefaults({
side: {
type: null,
required: false
},
sideOffset: {
type: Number,
required: false
},
sideFlip: {
type: Boolean,
required: false
},
align: {
type: null,
required: false
},
alignOffset: {
type: Number,
required: false
},
alignFlip: {
type: Boolean,
required: false
},
avoidCollisions: {
type: Boolean,
required: false
},
collisionBoundary: {
type: null,
required: false
},
collisionPadding: {
type: [Number, Object],
required: false
},
arrowPadding: {
type: Number,
required: false
},
sticky: {
type: String,
required: false
},
hideWhenDetached: {
type: Boolean,
required: false
},
positionStrategy: {
type: String,
required: false
},
updatePositionStrategy: {
type: String,
required: false
},
disableUpdateOnLayoutShift: {
type: Boolean,
required: false
},
prioritizePosition: {
type: Boolean,
required: false
},
reference: {
type: null,
required: false
},
asChild: {
type: Boolean,
required: false
},
as: {
type: null,
required: false
}
}, { ...PopperContentPropsDefaultValue }),
emits: ["placed"],
setup(__props, { emit: __emit }) {
const props = __props;
const emits = __emit;
const rootContext = injectPopperRootContext();
const { forwardRef, currentElement: contentElement } = Primitive.useForwardExpose();
const floatingRef = vue.ref();
const arrow$1 = vue.ref();
const { width: arrowWidth, height: arrowHeight } = useSize(arrow$1);
const desiredPlacement = vue.computed(() => props.side + (props.align !== "center" ? `-${props.align}` : ""));
const collisionPadding = vue.computed(() => {
return typeof props.collisionPadding === "number" ? props.collisionPadding : {
top: 0,
right: 0,
bottom: 0,
left: 0,
...props.collisionPadding
};
});
const boundary = vue.computed(() => {
return Array.isArray(props.collisionBoundary) ? props.collisionBoundary : [props.collisionBoundary];
});
const detectOverflowOptions = vue.computed(() => {
return {
padding: collisionPadding.value,
boundary: boundary.value.filter(isNotNull),
altBoundary: boundary.value.length > 0
};
});
const flipOptions = vue.computed(() => {
return {
mainAxis: props.sideFlip,
crossAxis: props.alignFlip
};
});
const computedMiddleware = Primitive.computedEager(() => {
return [
floatingUi_dom.offset({
mainAxis: props.sideOffset + arrowHeight.value,
alignmentAxis: props.alignOffset
}),
props.prioritizePosition && props.avoidCollisions && floatingUi_dom.flip({
...detectOverflowOptions.value,
...flipOptions.value
}),
props.avoidCollisions && floatingUi_dom.shift({
mainAxis: true,
crossAxis: !!props.prioritizePosition,
limiter: props.sticky === "partial" ? floatingUi_dom.limitShift() : void 0,
...detectOverflowOptions.value
}),
!props.prioritizePosition && props.avoidCollisions && floatingUi_dom.flip({
...detectOverflowOptions.value,
...flipOptions.value
}),
floatingUi_dom.size({
...detectOverflowOptions.value,
apply: ({ elements, rects, availableWidth, availableHeight }) => {
const { width: anchorWidth, height: anchorHeight } = rects.reference;
const contentStyle = elements.floating.style;
contentStyle.setProperty("--reka-popper-available-width", `${availableWidth}px`);
contentStyle.setProperty("--reka-popper-available-height", `${availableHeight}px`);
contentStyle.setProperty("--reka-popper-anchor-width", `${anchorWidth}px`);
contentStyle.setProperty("--reka-popper-anchor-height", `${anchorHeight}px`);
}
}),
arrow$1.value && floatingUi_vue.arrow({
element: arrow$1.value,
padding: props.arrowPadding
}),
transformOrigin({
arrowWidth: arrowWidth.value,
arrowHeight: arrowHeight.value
}),
props.hideWhenDetached && floatingUi_dom.hide({
strategy: "referenceHidden",
...detectOverflowOptions.value
})
];
});
const reference = vue.computed(() => props.reference ?? rootContext.anchor.value);
const { floatingStyles, placement, isPositioned, middlewareData, update } = floatingUi_vue.useFloating(reference, floatingRef, {
strategy: props.positionStrategy,
placement: desiredPlacement,
whileElementsMounted: (...args) => {
const cleanup = floatingUi_dom.autoUpdate(...args, {
layoutShift: !props.disableUpdateOnLayoutShift,
animat