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

548 lines (547 loc) 20.7 kB
import './mt-popover-item-result.css'; "use strict"; const vue = require("vue"); const MtSearch = require("./common/MtSearch.js"); const MtPopoverItem = require("./common/MtPopoverItem.js"); const MtSmoothReflow = require("./common/MtSmoothReflow.js"); const MtText = require("./common/MtText.js"); const _pluginVue_exportHelper = require("./_plugin-vue_export-helper-9c783a34.js"); let currentDrag = null; let currentDrop = null; let dragElement = null; let dragMouseOffsetX = 0; let dragMouseOffsetY = 0; let delayTimeout = null; const dropZones = []; const defaultDragConfig = { delay: 100, dragGroup: 1, draggableCls: "is--draggable", draggingStateCls: "is--dragging", dragElementCls: "is--drag-element", validDragCls: "is--valid-drag", invalidDragCls: "is--invalid-drag", preventEvent: true, validateDrop: null, validateDrag: null, validateDragStart: null, onDragStart: null, onDragEnter: null, onDragLeave: null, onDrop: null, data: null, disabled: false }; const defaultDropConfig = { dragGroup: 1, droppableCls: "is--droppable", validDropCls: "is--valid-drop", invalidDropCls: "is--invalid-drop", validateDrop: null, onDrop: null, data: null }; function onDrag(el, dragConfig, event) { if (event instanceof MouseEvent && event.buttons !== 1) { return false; } if (dragConfig.preventEvent) { event.preventDefault(); event.stopPropagation(); } if (dragConfig.delay === null || dragConfig.delay <= 0) { startDrag(el, dragConfig, event); } else { delayTimeout = window.setTimeout(startDrag.bind({}, el, dragConfig, event), dragConfig.delay); } document.addEventListener("mouseup", stopDrag); document.addEventListener("touchend", stopDrag); return true; } function startDrag(el, dragConfig, event) { if (dragConfig.validateDragStart !== null && !dragConfig.validateDragStart(dragConfig.data, el, event)) { return; } delayTimeout = null; if (currentDrag !== null) { return; } currentDrag = { el, dragConfig }; const elBoundingBox = el.getBoundingClientRect(); const pageX = event instanceof MouseEvent && event.pageX || event instanceof TouchEvent && event.touches[0].pageX; const pageY = event instanceof MouseEvent && event.pageY || event instanceof TouchEvent && event.touches[0].pageY; dragMouseOffsetX = pageX - elBoundingBox.left; dragMouseOffsetY = pageY - elBoundingBox.top; dragElement = el.cloneNode(true); dragElement.classList.add(dragConfig.dragElementCls); dragElement.style.width = `${elBoundingBox.width}px`; dragElement.style.translate = `${pageX - dragMouseOffsetX}px ${pageY - dragMouseOffsetY}px`; dragElement.style.left = "0"; dragElement.style.top = "0"; document.body.appendChild(dragElement); el.classList.add(dragConfig.draggingStateCls); if (typeof currentDrag.dragConfig.onDragStart === "function") { currentDrag.dragConfig.onDragStart(currentDrag.dragConfig, el, dragElement); } document.addEventListener("mousemove", moveDrag); document.addEventListener("touchmove", moveDrag); } let rotationTimeout = 0; function calculateRotation(oldX, newX) { if (oldX && Math.abs(newX - oldX) > 2) { const moveRight = newX - oldX > 0; return `${moveRight ? 5 : -5}deg`; } return ""; } function moveDrag(event) { if (currentDrag === null) { stopDrag(); return; } const pageX = event instanceof MouseEvent && event.pageX || event instanceof TouchEvent && event.touches[0].pageX; const pageY = event instanceof MouseEvent && event.pageY || event instanceof TouchEvent && event.touches[0].pageY; if (dragElement) { const oldX = Number(dragElement.dataset.translateX); const newX = pageX - dragMouseOffsetX; const newY = pageY - dragMouseOffsetY; dragElement.style.rotate = calculateRotation(oldX, newX); clearTimeout(rotationTimeout); rotationTimeout = window.setTimeout(() => { if (dragElement) dragElement.style.rotate = "0deg"; }, 100); dragElement.style.translate = `${newX}px ${newY}px`; dragElement.dataset.translateX = newX.toString(); } if (event.type === "touchmove") { const foundZone = dropZones.find((zone) => isEventOverElement(event, zone.el)); clearAllDropZoneHighlights(); if (foundZone) { enterDropZone(foundZone.el, foundZone.dropConfig); } else if (currentDrop) { leaveDropZone(currentDrop.el, currentDrop.dropConfig); } } } function isEventOverElement(event, el) { const pageX = event instanceof MouseEvent && event.pageX || event instanceof TouchEvent && event.touches[0].pageX; const pageY = event instanceof MouseEvent && event.pageY || event instanceof TouchEvent && event.touches[0].pageY; const box = el.getBoundingClientRect(); return pageX >= box.x && pageX <= box.x + box.width && pageY >= box.y && pageY <= box.y + box.height; } function stopDrag() { var _a; if (delayTimeout !== null) { window.clearTimeout(delayTimeout); delayTimeout = null; return; } const validDrag = validateDrag(); const validDrop = validateDrop(); if (validDrag && currentDrag) { if (typeof currentDrag.dragConfig.onDrop === "function") { currentDrag.dragConfig.onDrop( currentDrag.dragConfig.data, validDrop ? (_a = currentDrop == null ? void 0 : currentDrop.dropConfig) == null ? void 0 : _a.data : null ); } } if (validDrop && currentDrop) { if (typeof currentDrop.dropConfig.onDrop === "function") { currentDrop.dropConfig.onDrop(currentDrag == null ? void 0 : currentDrag.dragConfig.data, currentDrop.dropConfig.data); } } document.removeEventListener("mousemove", moveDrag); document.removeEventListener("touchmove", moveDrag); document.removeEventListener("mouseup", stopDrag); document.removeEventListener("touchend", stopDrag); if (dragElement !== null) { dragElement.remove(); dragElement = null; } if (currentDrag !== null) { currentDrag.el.classList.remove(currentDrag.dragConfig.draggingStateCls); currentDrag.el.classList.remove(currentDrag.dragConfig.validDragCls); currentDrag.el.classList.remove(currentDrag.dragConfig.invalidDragCls); currentDrag = null; } if (currentDrop !== null) { currentDrop.el.classList.remove(currentDrop.dropConfig.validDropCls); currentDrop.el.classList.remove(currentDrop.dropConfig.invalidDropCls); currentDrop = null; } dragMouseOffsetX = 0; dragMouseOffsetY = 0; } function enterDropZone(el, dropConfig) { if (currentDrag === null) { return; } currentDrop = { el, dropConfig }; const valid = validateDrop(); if (valid) { el.classList.add(dropConfig.validDropCls); el.classList.remove(dropConfig.invalidDropCls); if (dragElement) { dragElement.classList.add(currentDrag.dragConfig.validDragCls); dragElement.classList.remove(currentDrag.dragConfig.invalidDragCls); } } else { el.classList.add(dropConfig.invalidDropCls); el.classList.remove(dropConfig.validDropCls); if (dragElement) { dragElement.classList.add(currentDrag.dragConfig.invalidDragCls); dragElement.classList.remove(currentDrag.dragConfig.validDragCls); } } if (typeof currentDrag.dragConfig.onDragEnter === "function") { currentDrag.dragConfig.onDragEnter( currentDrag.dragConfig.data, currentDrop.dropConfig.data, valid ); } } function leaveDropZone(el, dropConfig) { if (currentDrag === null) { return; } if (currentDrop === null) { return; } if (typeof currentDrag.dragConfig.onDragLeave === "function") { currentDrag.dragConfig.onDragLeave(currentDrag.dragConfig.data, currentDrop.dropConfig.data); } el.classList.remove(dropConfig.validDropCls); el.classList.remove(dropConfig.invalidDropCls); if (dragElement) { dragElement.classList.remove(currentDrag.dragConfig.validDragCls); dragElement.classList.remove(currentDrag.dragConfig.invalidDragCls); } currentDrop = null; } function validateDrop() { let valid = true; let customDragValidation = true; let customDropValidation = true; if (currentDrag === null || currentDrop === null || currentDrop.dropConfig.dragGroup !== currentDrag.dragConfig.dragGroup) { valid = false; } if (currentDrag !== null && typeof currentDrag.dragConfig.validateDrop === "function") { customDragValidation = currentDrag.dragConfig.validateDrop( currentDrag.dragConfig.data, currentDrop == null ? void 0 : currentDrop.dropConfig.data ); } if (currentDrop !== null && typeof currentDrop.dropConfig.validateDrop === "function") { customDropValidation = currentDrop.dropConfig.validateDrop( currentDrag == null ? void 0 : currentDrag.dragConfig.data, currentDrop.dropConfig.data ); } return valid && customDragValidation && customDropValidation; } function validateDrag() { let valid = true; let customDragValidation = true; if (currentDrag === null) { valid = false; } if (currentDrag !== null && typeof currentDrag.dragConfig.validateDrag === "function") { customDragValidation = currentDrag.dragConfig.validateDrag( currentDrag.dragConfig.data, currentDrop == null ? void 0 : currentDrop.dropConfig.data ); } return valid && customDragValidation; } function mergeConfigs(defaultConfig, binding) { const mergedConfig = { ...defaultConfig }; if (binding.value instanceof Object) { Object.assign(mergedConfig, binding.value); } else { Object.assign(mergedConfig, { data: binding.value }); } return mergedConfig; } const draggable = { mounted(el, binding) { const dragConfig = mergeConfigs(defaultDragConfig, binding); el.dragConfig = dragConfig; el.boundDragListener = onDrag.bind(this, el, el.dragConfig); if (!dragConfig.disabled) { el.classList.add(dragConfig.draggableCls); el.addEventListener("mousedown", el.boundDragListener); el.addEventListener("touchstart", el.boundDragListener); } }, updated(el, binding) { const dragConfig = mergeConfigs(defaultDragConfig, binding); if (el.dragConfig && el.dragConfig.disabled !== dragConfig.disabled) { if (!dragConfig.disabled) { el.classList.remove(el.dragConfig.draggableCls); el.classList.add(dragConfig.draggableCls); if (el.boundDragListener) { el.addEventListener("mousedown", el.boundDragListener); el.addEventListener("touchstart", el.boundDragListener); } } else { el.classList.remove(el.dragConfig.draggableCls); if (el.boundDragListener) { el.removeEventListener("mousedown", el.boundDragListener); el.removeEventListener("touchstart", el.boundDragListener); } } } Object.assign(el.dragConfig, dragConfig); }, unmounted(el, binding) { const dragConfig = mergeConfigs(defaultDragConfig, binding); el.classList.remove(dragConfig.draggableCls); if (el.boundDragListener) { el.removeEventListener("mousedown", el.boundDragListener); el.removeEventListener("touchstart", el.boundDragListener); } } }; const droppable = { mounted(el, binding) { const dropConfig = mergeConfigs(defaultDropConfig, binding); dropZones.push({ el, dropConfig }); el.classList.add(dropConfig.droppableCls); el.addEventListener("mouseenter", enterDropZone.bind(this, el, dropConfig)); el.addEventListener("mouseleave", leaveDropZone.bind(this, el, dropConfig)); }, unmounted(el, binding) { const dropConfig = mergeConfigs(defaultDropConfig, binding); dropZones.splice( dropZones.findIndex((zone) => zone.el === el), 1 ); el.classList.remove(dropConfig.droppableCls); el.removeEventListener("mouseenter", enterDropZone.bind(this, el, dropConfig)); el.removeEventListener("mouseleave", leaveDropZone.bind(this, el, dropConfig)); }, updated: (el, binding) => { const dropZone = dropZones.find((zone) => zone.el === el); if (binding.value instanceof Object) { Object.assign(dropZone == null ? void 0 : dropZone.dropConfig, binding.value); } else { Object.assign(dropZone == null ? void 0 : dropZone.dropConfig, { data: binding.value }); } } }; function clearAllDropZoneHighlights() { dropZones.forEach((zone) => { zone.el.classList.remove(zone.dropConfig.validDropCls); zone.el.classList.remove(zone.dropConfig.invalidDropCls); }); } const _sfc_main = vue.defineComponent({ name: "MtPopoverItemResult", directives: { draggable, droppable }, components: { "mt-search": MtSearch, "mt-popover-item": MtPopoverItem, "mt-smooth-reflow": MtSmoothReflow, "mt-text": MtText }, props: { options: { type: Array, required: true }, groups: { type: Array, required: false, default: () => [] }, hideSearch: { type: Boolean, default: false }, draggable: { type: Boolean, default: false }, selectable: { type: Boolean, default: false }, hidable: { type: Boolean, default: false } }, emits: [ "change-checkbox", "change-visibility", "click-group-action", "click-option", "change-order", "search" ], setup(props, { emit }) { const dropConfig = {}; const dragConfig = { disabled: !props.draggable, delay: 200, onDragStart: () => { document.body.classList.add("is-popover-item-result-dragging"); }, onDrop: (dragConfigData, dropConfigData) => { document.body.classList.remove("is-popover-item-result-dragging"); emit("change-order", { itemId: dragConfigData == null ? void 0 : dragConfigData.id, dropZone: dropConfigData == null ? void 0 : dropConfigData.dropZone, dropId: dropConfigData == null ? void 0 : dropConfigData.id }); } }; const isOptionDraggable = (option) => { return props.draggable && option.isSortable; }; const getDragConfigForOption = (option) => { return { ...dragConfig, disabled: !isOptionDraggable(option) }; }; const getOptionsForGroup = (groupId) => { return props.options.filter((option) => option.parentGroup === groupId); }; const getIconForOption = (option) => { if (isOptionDraggable(option)) { return "solid-grip-vertical-s"; } if (props.draggable) { return "solid-thumbtack"; } return void 0; }; return { getOptionsForGroup, getDragConfigForOption, isOptionDraggable, getIconForOption, dropConfig, dragConfig }; } }); const mtPopoverItemResult_vue_vue_type_style_index_0_lang = ""; const _hoisted_1 = { class: "mt-popover-item-result" }; const _hoisted_2 = ["aria-label"]; const _hoisted_3 = ["onClick"]; const _hoisted_4 = ["aria-label"]; const _hoisted_5 = { key: 0, class: "mt-popover-item-result__option_drop_before" }; const _hoisted_6 = { key: 1, class: "mt-popover-item-result__option_drop_after" }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_mt_search = vue.resolveComponent("mt-search"); const _component_mt_text = vue.resolveComponent("mt-text"); const _component_mt_popover_item = vue.resolveComponent("mt-popover-item"); const _component_mt_smooth_reflow = vue.resolveComponent("mt-smooth-reflow"); const _directive_droppable = vue.resolveDirective("droppable"); const _directive_draggable = vue.resolveDirective("draggable"); return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ !_ctx.hideSearch ? (vue.openBlock(), vue.createBlock(_component_mt_search, { key: 0, size: "small", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("search", $event)) })) : vue.createCommentVNode("", true), (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList([void 0, ..._ctx.groups], (group) => { return vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: "transition-group-" + (group && group.id) }, [ vue.createVNode(vue.Transition, { name: "option-fade" }, { default: vue.withCtx(() => [ group && _ctx.getOptionsForGroup(group.id).length > 0 ? (vue.openBlock(), vue.createElementBlock("div", { key: group.id, class: "mt-popover-item-result__group-header", "aria-label": group.label }, [ vue.createVNode(_component_mt_text, { as: "span", size: "xs", color: "color-text-secondary-default", class: "mt-popover-item-result__group-label" }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(group.label), 1) ]), _: 2 }, 1024), group.actionLabel ? (vue.openBlock(), vue.createElementBlock("button", { key: 0, type: "button", class: "mt-popover-item-result__group-action", onClick: () => _ctx.$emit("click-group-action", group.id) }, vue.toDisplayString(group.actionLabel), 9, _hoisted_3)) : vue.createCommentVNode("", true) ], 8, _hoisted_2)) : vue.createCommentVNode("", true) ]), _: 2 }, 1024), vue.createVNode(_component_mt_smooth_reflow, null, { default: vue.withCtx(() => [ vue.createVNode(vue.TransitionGroup, { name: "option-item", tag: "div" }, { default: vue.withCtx(() => [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.getOptionsForGroup(group && group.id), (option) => { return vue.openBlock(), vue.createElementBlock("div", { key: option.id, class: "mt-popover-item-result__option", "aria-label": (group && group.label ? group.label : "No group") + ": " + option.label }, [ _ctx.isOptionDraggable(option) ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", _hoisted_5, null, 512)), [ [_directive_droppable, { ..._ctx.dropConfig, data: { ...option, dropZone: "before" } }] ]) : vue.createCommentVNode("", true), vue.withDirectives(vue.createVNode(_component_mt_popover_item, { class: "mt-popover-item-result__option_item", "is-option-item": _ctx.isOptionDraggable(option), label: option.label, "show-checkbox": _ctx.selectable, "checkbox-checked": option.isSelected, "contextual-detail": option.contextualDetail, "meta-copy": option.metaCopy, "show-visibility": _ctx.hidable && option.isHidable, visible: option.isVisible, icon: _ctx.getIconForOption(option), "on-label-click": option.isClickable ? () => _ctx.$emit("click-option", option.id) : void 0, disabled: option.disabled, onChangeCheckbox: ($event) => _ctx.$emit("change-checkbox", option.id, $event), onChangeVisibility: ($event) => _ctx.$emit("change-visibility", option.id, $event) }, null, 8, ["is-option-item", "label", "show-checkbox", "checkbox-checked", "contextual-detail", "meta-copy", "show-visibility", "visible", "icon", "on-label-click", "disabled", "onChangeCheckbox", "onChangeVisibility"]), [ [_directive_draggable, { ..._ctx.getDragConfigForOption(option), data: option }] ]), _ctx.isOptionDraggable(option) ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", _hoisted_6, null, 512)), [ [_directive_droppable, { ..._ctx.dropConfig, data: { ...option, dropZone: "after" } }] ]) : vue.createCommentVNode("", true) ], 8, _hoisted_4); }), 128)) ]), _: 2 }, 1024) ]), _: 2 }, 1024) ], 64); }), 128)) ]); } const MtPopoverItemResult = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["render", _sfc_render]]); exports.MtPopoverItemResult = MtPopoverItemResult; exports.draggable = draggable; exports.droppable = droppable; //# sourceMappingURL=mt-popover-item-result-77871fb7.js.map