@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
JavaScript
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