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

201 lines (200 loc) 7 kB
import '../mt-unit-select.css'; import { defineComponent, ref, watch, onMounted, nextTick, onUnmounted, openBlock, createElementBlock, createElementVNode, createTextVNode, toDisplayString, createVNode, createBlock, Teleport, withDirectives, normalizeStyle, unref, Fragment, renderList, normalizeClass, vShow } from "vue"; import { useI18n } from "vue-i18n"; import MtUnitSelectResult from "./MtUnitSelectResult.js"; import { _ as _sfc_main$1 } from "../mt-icon.vue_vue_type_style_index_0_lang-2cc5f73e.mjs"; import { u as useFloating } from "../floating-ui.vue-fe27ebef.mjs"; import { o as onClickOutside } from "../index-c0f92ea5.mjs"; import { o as offset, f as flip, s as shift, a as autoUpdate } from "../floating-ui.dom-f450fda4.mjs"; import { _ as _export_sfc } from "../_plugin-vue_export-helper-cc2b3d55.mjs"; import "../index-221bad05.mjs"; const _hoisted_1 = { class: "mt-unit-select__container" }; const _hoisted_2 = ["aria-expanded", "disabled"]; const _hoisted_3 = ["aria-label"]; const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "mt-unit-select", props: { modelValue: {}, units: {}, disabled: { type: Boolean }, zIndex: {} }, emits: ["update:modelValue"], setup(__props, { emit: __emit }) { const { t } = useI18n({ messages: { de: { units: { mm: "Millimeter", cm: "Zentimeter", m: "Meter", in: "Zoll", ft: "Fuß", yd: "Yard", g: "Gramm", kg: "Kilogramm", oz: "Unze", lb: "Pfund" }, "select-unit": "Einheit auswählen" }, en: { units: { mm: "Millimeters", cm: "Centimeters", m: "Meters", in: "Inches", ft: "Feet", yd: "Yards", g: "Grams", kg: "Kilograms", oz: "Ounces", lb: "Pounds" }, "select-unit": "Select unit" } } }); const props = __props; const emit = __emit; const isOpen = ref(false); const activeIndex = ref(0); const triggerRef = ref(null); const dropdownRef = ref(null); const { floatingStyles, update } = useFloating(triggerRef, dropdownRef, { middleware: [offset(4), flip(), shift()], whileElementsMounted: autoUpdate, placement: "bottom-start" }); onClickOutside(dropdownRef, (event) => { var _a, _b; if (!((_a = dropdownRef.value) == null ? void 0 : _a.contains(event.target)) && !((_b = triggerRef.value) == null ? void 0 : _b.contains(event.target))) { closeDropdown(); } }); const selectUnit = (value) => { emit("update:modelValue", value); activeIndex.value = props.units.findIndex((unit) => unit === value); isOpen.value = false; }; const getUnitLabel = (unit) => { const label = t("units." + unit); return { plural: label, singular: label }; }; const toggleDropdown = () => { if (!props.disabled) { isOpen.value = !isOpen.value; } }; const closeDropdown = () => { isOpen.value = false; activeIndex.value = props.units.findIndex((unit) => unit === props.modelValue); }; const navigateWithKeyboard = (event) => { if (!isOpen.value) return; switch (event.key) { case "ArrowDown": event.preventDefault(); activeIndex.value = (activeIndex.value + 1) % props.units.length; break; case "ArrowUp": event.preventDefault(); activeIndex.value = activeIndex.value === 0 ? props.units.length - 1 : activeIndex.value - 1; break; case "Enter": event.preventDefault(); if (isOpen.value) { selectUnit(props.units[activeIndex.value]); } break; case "Escape": event.preventDefault(); closeDropdown(); break; } }; watch( () => props.modelValue, (newValue) => { activeIndex.value = props.units.findIndex((unit) => unit === newValue); } ); onMounted(() => { activeIndex.value = props.units.findIndex((unit) => unit === props.modelValue); window.addEventListener("keydown", navigateWithKeyboard); nextTick(() => { update == null ? void 0 : update(); }); }); onUnmounted(() => { window.removeEventListener("keydown", navigateWithKeyboard); }); return (_ctx, _cache) => { return openBlock(), createElementBlock("div", _hoisted_1, [ createElementVNode("button", { ref_key: "triggerRef", ref: triggerRef, class: "mt-unit-select__trigger", type: "button", role: "combobox", "aria-controls": "unit-select-listbox", "aria-expanded": isOpen.value, "aria-haspopup": "listbox", disabled: _ctx.disabled, "data-testid": "unit-select-trigger", onClick: toggleDropdown }, [ createTextVNode(toDisplayString(_ctx.modelValue) + " ", 1), createVNode(_sfc_main$1, { name: "chevron-down-xxs", size: "var(--scale-size-8)", "aria-hidden": "true" }) ], 8, _hoisted_2), (openBlock(), createBlock(Teleport, { to: "body" }, [ withDirectives(createElementVNode("div", { ref_key: "dropdownRef", ref: dropdownRef, class: "mt-unit-select", style: normalizeStyle({ ...unref(floatingStyles), ...props.zIndex != null ? { zIndex: props.zIndex } : {} }) }, [ createElementVNode("ul", { id: "unit-select-listbox", role: "listbox", tabindex: "-1", "aria-label": unref(t)("select-unit") }, [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.units, (unit, index) => { return openBlock(), createBlock(MtUnitSelectResult, { key: unit, unit, "unit-label": getUnitLabel(unit), class: normalizeClass({ "mt-unit-select-result--selected": unit === _ctx.modelValue, "mt-unit-select-result--active": index === activeIndex.value }), onClick: ($event) => selectUnit(unit) }, null, 8, ["unit", "unit-label", "class", "onClick"]); }), 128)) ], 8, _hoisted_3) ], 4), [ [vShow, isOpen.value] ]) ])) ]); }; } }); const mtUnitSelect_vue_vue_type_style_index_0_scoped_39787702_lang = ""; const MtUnitSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-39787702"]]); export { MtUnitSelect as default }; //# sourceMappingURL=MtUnitSelect.js.map