@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
JavaScript
import './mt-action-menu-item.css';
;
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