UNPKG

@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/).

674 lines (673 loc) 22 kB
import './mt-action-menu-item.css'; "use strict"; const vue = require("vue"); const MenuSub = require("./MenuSub-89e22f51.js"); const Primitive = require("./Primitive-20a16e64.js"); const mtIcon_vue_vue_type_style_index_0_lang = require("./mt-icon.vue_vue_type_style_index_0_lang-0a28c7b6.js"); const vueI18n = require("vue-i18n"); const _pluginVue_exportHelper = require("./_plugin-vue_export-helper-9c783a34.js"); var PopperAnchor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({ __name: "PopperAnchor", props: { reference: { type: null, required: false }, asChild: { type: Boolean, required: false }, as: { type: null, required: false } }, setup(__props) { const props = __props; const { forwardRef, currentElement } = Primitive.useForwardExpose(); const rootContext = MenuSub.injectPopperRootContext(); vue.watchPostEffect(() => { rootContext.onAnchorChange(props.reference ?? currentElement.value); }); return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(vue.unref(Primitive.Primitive), { ref: vue.unref(forwardRef), as: _ctx.as, "as-child": _ctx.asChild }, { default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]), _: 3 }, 8, ["as", "as-child"]); }; } }); var PopperAnchor_default = PopperAnchor_vue_vue_type_script_setup_true_lang_default; var MenuAnchor_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({ __name: "MenuAnchor", props: { reference: { type: null, required: false }, asChild: { type: Boolean, required: false }, as: { type: null, required: false } }, setup(__props) { const props = __props; return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(vue.unref(PopperAnchor_default), vue.normalizeProps(vue.guardReactiveProps(props)), { default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]), _: 3 }, 16); }; } }); var MenuAnchor_default = MenuAnchor_vue_vue_type_script_setup_true_lang_default; var MenuItemImpl_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({ inheritAttrs: false, __name: "MenuItemImpl", props: { disabled: { type: Boolean, required: false }, textValue: { type: String, required: false }, asChild: { type: Boolean, required: false }, as: { type: null, required: false } }, setup(__props) { const props = __props; const contentContext = MenuSub.injectMenuContentContext(); const { forwardRef } = Primitive.useForwardExpose(); const { CollectionItem } = MenuSub.useCollection(); const isFocused = vue.ref(false); async function handlePointerMove(event) { if (event.defaultPrevented) return; if (!MenuSub.isMouseEvent(event)) return; if (props.disabled) contentContext.onItemLeave(event); else { const defaultPrevented = contentContext.onItemEnter(event); if (!defaultPrevented) { const item = event.currentTarget; item == null ? void 0 : item.focus({ preventScroll: true }); } } } async function handlePointerLeave(event) { await vue.nextTick(); if (event.defaultPrevented) return; if (!MenuSub.isMouseEvent(event)) return; contentContext.onItemLeave(event); } return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(vue.unref(CollectionItem), { value: { textValue: _ctx.textValue } }, { default: vue.withCtx(() => [vue.createVNode(vue.unref(Primitive.Primitive), vue.mergeProps({ ref: vue.unref(forwardRef), role: "menuitem", tabindex: "-1" }, _ctx.$attrs, { as: _ctx.as, "as-child": _ctx.asChild, "aria-disabled": _ctx.disabled || void 0, "data-disabled": _ctx.disabled ? "" : void 0, "data-highlighted": isFocused.value ? "" : void 0, onPointermove: handlePointerMove, onPointerleave: handlePointerLeave, onFocus: _cache[0] || (_cache[0] = async (event) => { await vue.nextTick(); if (event.defaultPrevented || _ctx.disabled) return; isFocused.value = true; }), onBlur: _cache[1] || (_cache[1] = async (event) => { await vue.nextTick(); if (event.defaultPrevented) return; isFocused.value = false; }) }), { default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]), _: 3 }, 16, [ "as", "as-child", "aria-disabled", "data-disabled", "data-highlighted" ])]), _: 3 }, 8, ["value"]); }; } }); var MenuItemImpl_default = MenuItemImpl_vue_vue_type_script_setup_true_lang_default; var MenuItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({ __name: "MenuItem", props: { disabled: { type: Boolean, required: false }, textValue: { type: String, required: false }, asChild: { type: Boolean, required: false }, as: { type: null, required: false } }, emits: ["select"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; const { forwardRef, currentElement } = Primitive.useForwardExpose(); const rootContext = MenuSub.injectMenuRootContext(); const contentContext = MenuSub.injectMenuContentContext(); const isPointerDownRef = vue.ref(false); async function handleSelect() { const menuItem = currentElement.value; if (!props.disabled && menuItem) { const itemSelectEvent = new CustomEvent(MenuSub.ITEM_SELECT, { bubbles: true, cancelable: true }); emits("select", itemSelectEvent); await vue.nextTick(); if (itemSelectEvent.defaultPrevented) isPointerDownRef.value = false; else rootContext.onClose(); } } return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(MenuItemImpl_default, vue.mergeProps(props, { ref: vue.unref(forwardRef), onClick: handleSelect, onPointerdown: _cache[0] || (_cache[0] = () => { isPointerDownRef.value = true; }), onPointerup: _cache[1] || (_cache[1] = async (event) => { var _a; await vue.nextTick(); if (event.defaultPrevented) return; if (!isPointerDownRef.value) (_a = event.currentTarget) == null ? void 0 : _a.click(); }), onKeydown: _cache[2] || (_cache[2] = async (event) => { const isTypingAhead = vue.unref(contentContext).searchRef.value !== ""; if (_ctx.disabled || isTypingAhead && event.key === " ") return; if (vue.unref(MenuSub.SELECTION_KEYS).includes(event.key)) { event.currentTarget.click(); event.preventDefault(); } }) }), { default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]), _: 3 }, 16); }; } }); var MenuItem_default = MenuItem_vue_vue_type_script_setup_true_lang_default; var MenuSubTrigger_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({ __name: "MenuSubTrigger", props: { disabled: { type: Boolean, required: false }, textValue: { type: String, required: false }, asChild: { type: Boolean, required: false }, as: { type: null, required: false } }, setup(__props) { const props = __props; const menuContext = MenuSub.injectMenuContext(); const rootContext = MenuSub.injectMenuRootContext(); const subContext = MenuSub.injectMenuSubContext(); const contentContext = MenuSub.injectMenuContentContext(); const openTimerRef = vue.ref(null); subContext.triggerId || (subContext.triggerId = MenuSub.useId(void 0, "reka-menu-sub-trigger")); function clearOpenTimer() { if (openTimerRef.value) window.clearTimeout(openTimerRef.value); openTimerRef.value = null; } vue.onUnmounted(() => { clearOpenTimer(); }); function handlePointerMove(event) { if (!MenuSub.isMouseEvent(event)) return; const defaultPrevented = contentContext.onItemEnter(event); if (defaultPrevented) return; if (!props.disabled && !menuContext.open.value && !openTimerRef.value) { contentContext.onPointerGraceIntentChange(null); openTimerRef.value = window.setTimeout(() => { menuContext.onOpenChange(true); clearOpenTimer(); }, 100); } } async function handlePointerLeave(event) { var _a, _b; if (!MenuSub.isMouseEvent(event)) return; clearOpenTimer(); const contentRect = (_a = menuContext.content.value) == null ? void 0 : _a.getBoundingClientRect(); if (contentRect == null ? void 0 : contentRect.width) { const side = (_b = menuContext.content.value) == null ? void 0 : _b.dataset.side; const rightSide = side === "right"; const bleed = rightSide ? -5 : 5; const contentNearEdge = contentRect[rightSide ? "left" : "right"]; const contentFarEdge = contentRect[rightSide ? "right" : "left"]; contentContext.onPointerGraceIntentChange({ area: [ { x: event.clientX + bleed, y: event.clientY }, { x: contentNearEdge, y: contentRect.top }, { x: contentFarEdge, y: contentRect.top }, { x: contentFarEdge, y: contentRect.bottom }, { x: contentNearEdge, y: contentRect.bottom } ], side }); window.clearTimeout(contentContext.pointerGraceTimerRef.value); contentContext.pointerGraceTimerRef.value = window.setTimeout(() => contentContext.onPointerGraceIntentChange(null), 300); } else { const defaultPrevented = contentContext.onTriggerLeave(event); if (defaultPrevented) return; contentContext.onPointerGraceIntentChange(null); } } async function handleKeyDown(event) { var _a; const isTypingAhead = contentContext.searchRef.value !== ""; if (props.disabled || isTypingAhead && event.key === " ") return; if (MenuSub.SUB_OPEN_KEYS[rootContext.dir.value].includes(event.key)) { menuContext.onOpenChange(true); await vue.nextTick(); (_a = menuContext.content.value) == null ? void 0 : _a.focus(); event.preventDefault(); } } return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(MenuAnchor_default, { "as-child": "" }, { default: vue.withCtx(() => [vue.createVNode(MenuItemImpl_default, vue.mergeProps(props, { id: vue.unref(subContext).triggerId, ref: (vnode) => { var _a; (_a = vue.unref(subContext)) == null ? void 0 : _a.onTriggerChange(vnode == null ? void 0 : vnode.$el); return void 0; }, "aria-haspopup": "menu", "aria-expanded": vue.unref(menuContext).open.value, "aria-controls": vue.unref(subContext).contentId, "data-state": vue.unref(MenuSub.getOpenState)(vue.unref(menuContext).open.value), onClick: _cache[0] || (_cache[0] = async (event) => { if (props.disabled || event.defaultPrevented) return; event.currentTarget.focus(); if (!vue.unref(menuContext).open.value) vue.unref(menuContext).onOpenChange(true); }), onPointermove: handlePointerMove, onPointerleave: handlePointerLeave, onKeydown: handleKeyDown }), { default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]), _: 3 }, 16, [ "id", "aria-expanded", "aria-controls", "data-state" ])]), _: 3 }); }; } }); var MenuSubTrigger_default = MenuSubTrigger_vue_vue_type_script_setup_true_lang_default; var DropdownMenuItem_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({ __name: "DropdownMenuItem", props: { disabled: { type: Boolean, required: false }, textValue: { type: String, required: false }, asChild: { type: Boolean, required: false }, as: { type: null, required: false } }, emits: ["select"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; const emitsAsProps = MenuSub.useEmitAsProps(emits); Primitive.useForwardExpose(); return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(vue.unref(MenuItem_default), vue.normalizeProps(vue.guardReactiveProps({ ...props, ...vue.unref(emitsAsProps) })), { default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]), _: 3 }, 16); }; } }); var DropdownMenuItem_default = DropdownMenuItem_vue_vue_type_script_setup_true_lang_default; var DropdownMenuSubTrigger_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ vue.defineComponent({ __name: "DropdownMenuSubTrigger", props: { disabled: { type: Boolean, required: false }, textValue: { type: String, required: false }, asChild: { type: Boolean, required: false }, as: { type: null, required: false } }, setup(__props) { const props = __props; Primitive.useForwardExpose(); return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(vue.unref(MenuSubTrigger_default), vue.normalizeProps(vue.guardReactiveProps(props)), { default: vue.withCtx(() => [vue.renderSlot(_ctx.$slots, "default")]), _: 3 }, 16); }; } }); var DropdownMenuSubTrigger_default = DropdownMenuSubTrigger_vue_vue_type_script_setup_true_lang_default; const _hoisted_1 = { key: 2, class: "mt-action-menu-item__arrow" }; const _hoisted_2 = { key: 3, class: "mt-action-menu-item__external-link" }; const _sfc_main = /* @__PURE__ */ vue.defineComponent({ __name: "mt-action-menu-item", props: { variant: { default: "default" }, icon: { default: void 0 }, disabled: { type: Boolean, default: false }, shortcut: { default: void 0 }, isSubTrigger: { type: Boolean }, as: { default: void 0 }, link: { default: void 0 } }, setup(__props) { const MAC_SYMBOLS = { mod: "⌘", ctrl: "⌃", alt: "⌥", meta: "⌘", up: "↑", down: "↓", left: "←", right: "→" }; const SPECIAL_KEYS = [ "enter", "esc", "tab", "space", "backspace", "delete", "up", "down", "left", "right" ]; const MODIFIER_PRIORITY = { mod: 1, ctrl: 1, meta: 1, alt: 2, shift: 3 }; const ARIA_MODIFIER_KEYS = { mod: { mac: "Meta", pc: "Control" }, ctrl: { mac: "Control", pc: "Control" }, alt: { mac: "Alt", pc: "Alt" }, shift: { mac: "Shift", pc: "Shift" }, meta: { mac: "Meta", pc: "Meta" } }; const ARIA_SPECIAL_KEYS = { enter: "Enter", esc: "Escape", tab: "Tab", space: "Space", backspace: "Backspace", delete: "Delete", up: "ArrowUp", down: "ArrowDown", left: "ArrowLeft", right: "ArrowRight" }; const { t } = vueI18n.useI18n({ useScope: "global", messages: { en: { "mt-action-menu-item": { keys: { shift: "Shift", ctrl: "Ctrl", alt: "Alt", meta: "Win", enter: "Enter", esc: "Esc", tab: "Tab", space: "Space", backspace: "Backspace", delete: "Delete" } } }, de: { "mt-action-menu-item": { keys: { shift: "Umschalt", ctrl: "Strg", alt: "Alt", meta: "Win", enter: "Eingabe", esc: "Esc", tab: "Tab", space: "Leertaste", backspace: "Rücktaste", delete: "Entf" } } } } }); const props = __props; const group = vue.inject( "mt-action-menu-group", null ); vue.onMounted(() => { if (group) { group.registerItem(!!props.icon); } }); const isMac = typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform); const getKeyLabel = (key, forMac) => { if (forMac && MAC_SYMBOLS[key]) return MAC_SYMBOLS[key]; if (["up", "down", "left", "right"].includes(key)) return MAC_SYMBOLS[key]; if (key === "mod") return t("mt-action-menu-item.keys.ctrl"); return t(`mt-action-menu-item.keys.${key}`); }; const formatShortcut = (def) => { const { modifiers = [], key } = def; const sortedModifiers = [...modifiers].sort( (a, b) => MODIFIER_PRIORITY[a] - MODIFIER_PRIORITY[b] ); const isSpecial = SPECIAL_KEYS.includes(key); return { pc: [ ...sortedModifiers.map((m) => getKeyLabel(m, false)), isSpecial ? getKeyLabel(key, false) : key.toUpperCase() ], mac: [ ...sortedModifiers.map((m) => getKeyLabel(m, true)), isSpecial ? getKeyLabel(key, true) : key.toUpperCase() ] }; }; const shortcutKeys = vue.computed(() => { if (!props.shortcut) return []; const formatted = formatShortcut(props.shortcut); return isMac ? formatted.mac : formatted.pc; }); const ariaKeyShortcuts = vue.computed(() => { if (!props.shortcut) return void 0; const { modifiers = [], key } = props.shortcut; const sortedModifiers = [...modifiers].sort( (a, b) => MODIFIER_PRIORITY[a] - MODIFIER_PRIORITY[b] ); const platform = isMac ? "mac" : "pc"; const parts = sortedModifiers.map((m) => ARIA_MODIFIER_KEYS[m][platform]); const isSpecial = SPECIAL_KEYS.includes(key); parts.push(isSpecial ? ARIA_SPECIAL_KEYS[key] : key.toUpperCase()); return parts.join("+"); }); return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.isSubTrigger ? vue.unref(DropdownMenuSubTrigger_default) : vue.unref(DropdownMenuItem_default)), { as: _ctx.link ? "a" : _ctx.as, href: _ctx.link, target: _ctx.link ? "_blank" : void 0, rel: _ctx.link ? "noopener noreferrer" : void 0, class: vue.normalizeClass(["mt-action-menu-item", `mt-action-menu-item--variant-${_ctx.variant}`]), disabled: _ctx.disabled, "data-has-icon": !!_ctx.icon || void 0, "aria-keyshortcuts": ariaKeyShortcuts.value }, { default: vue.withCtx(() => [ !!_ctx.icon ? (vue.openBlock(), vue.createBlock(mtIcon_vue_vue_type_style_index_0_lang._sfc_main, { key: 0, name: _ctx.icon, size: "14", mode: "solid" }, null, 8, ["name"])) : vue.createCommentVNode("", true), vue.renderSlot(_ctx.$slots, "default", {}, void 0, true), shortcutKeys.value.length && !_ctx.isSubTrigger && !_ctx.link ? (vue.openBlock(), vue.createElementBlock("kbd", { key: 1, "aria-hidden": "true", class: vue.normalizeClass([ "mt-action-menu-item__shortcut", { "mt-action-menu-item__shortcut--disabled": _ctx.disabled } ]) }, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(shortcutKeys.value, (key, index) => { return vue.openBlock(), vue.createElementBlock("span", { key: index }, vue.toDisplayString(key), 1); }), 128)) ], 2)) : vue.createCommentVNode("", true), _ctx.isSubTrigger && !_ctx.link ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ vue.createVNode(mtIcon_vue_vue_type_style_index_0_lang._sfc_main, { name: "chevron-right-s", size: "10", color: "var(--color-icon-primary-default)", mode: "regular" }) ])) : vue.createCommentVNode("", true), _ctx.link ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, [ vue.createVNode(mtIcon_vue_vue_type_style_index_0_lang._sfc_main, { name: "external-link-s", size: "10", color: "var(--color-icon-secondary-default)", mode: "regular" }) ])) : vue.createCommentVNode("", true) ]), _: 3 }, 8, ["as", "href", "target", "rel", "class", "disabled", "data-has-icon", "aria-keyshortcuts"]); }; } }); const mtActionMenuItem_vue_vue_type_style_index_0_scoped_de4ae728_lang = ""; const mtActionMenuItem = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["__scopeId", "data-v-de4ae728"]]); exports.MenuAnchor_default = MenuAnchor_default; exports.mtActionMenuItem = mtActionMenuItem; //# sourceMappingURL=mt-action-menu-item-b369ea13.js.map