@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/).
569 lines (568 loc) • 19.3 kB
JavaScript
import { defineComponent, resolveComponent, openBlock, createBlock, mergeProps, withCtx, renderSlot, createVNode, normalizeProps, guardReactiveProps, createTextVNode, toDisplayString, createElementBlock, Fragment } from "vue";
import { d as debounce } from "../debounce-b18437e2.mjs";
import { g as getPropertyValue } from "../object-e11d5dd3.mjs";
import MtSelectBase from "./MtSelectBase.js";
import MtSelectResultList from "./MtSelectResultList.js";
import MtSelectResult from "./MtSelectResult.js";
import MtSelectSelectionList from "./MtSelectSelectionList.js";
import { _ as _sfc_main$1 } from "../mt-highlight-text.vue_vue_type_style_index_0_lang-550f3bfe.mjs";
import { useI18n } from "vue-i18n";
import { _ as _export_sfc } from "../_plugin-vue_export-helper-cc2b3d55.mjs";
import "../mt-base-field-7a978dcf.mjs";
import "./MtInheritanceSwitch.js";
import "../mt-icon.vue_vue_type_style_index_0_lang-2cc5f73e.mjs";
import "./MtTooltip.js";
import "../floating-ui.vue-fe27ebef.mjs";
import "../floating-ui.dom-f450fda4.mjs";
import "../useIsInsideTooltip-0c3bd290.mjs";
import "../index-221bad05.mjs";
import "./MtFieldCopyable.js";
import "../tooltip.directive-a5042569.mjs";
import "../id-1e5b8276.mjs";
import "./MtHelpText.js";
import "../useFutureFlags-2be3e179.mjs";
import "./MtLoader.js";
import "./MtFieldError.js";
import "./MtText.js";
import "./MtPopoverDeprecated.js";
import "../provideInjectKeys-47aad241.mjs";
import "../mt-label.vue_vue_type_style_index_0_lang-13843d32.mjs";
import "./MtColorBadge.js";
import "./MtButton.js";
function isPromise(value) {
return !!value && typeof value === "object" && "then" in value && typeof value.then === "function" && "catch" in value && typeof value.catch === "function";
}
const _sfc_main = defineComponent({
name: "MtSelect",
components: {
"mt-select-base": MtSelectBase,
"mt-select-result-list": MtSelectResultList,
"mt-select-selection-list": MtSelectSelectionList,
"mt-highlight-text": _sfc_main$1,
"mt-select-result": MtSelectResult
},
inheritAttrs: false,
props: {
/**
* An array of objects with the labelProperty and valueProperty.
*
* @example [{label: 'Option A', value: 'a'}, {label: 'Option B', value: 'b'}]
*/
options: {
type: Array,
required: true
},
/**
* Toggles if either one or more items can be selected.
*/
enableMultiSelection: {
type: Boolean,
default: false
},
/**
* Dependent on multiSelection, either a single value or an array of values.
*/
modelValue: {
type: [String, Number, Boolean, Array, Object, null, void 0],
required: false,
default: null
},
/**
* The object key of the label property. Can be a single string or an array of strings.
* If an array is provided, the first property that has a non-empty value will be used.
*/
labelProperty: {
type: [String, Array],
required: false,
default: "label"
},
/**
* The object key to use for the value.
*/
valueProperty: {
type: String,
required: false,
default: "value"
},
/**
* The number of items that are expanded by default.
*/
valueLimit: {
type: Number,
required: false,
default: 5
},
/**
* The label for the select field itself.
*/
label: {
type: String,
required: false,
default: ""
},
/**
* The placeholder for the select field.
*/
placeholder: {
type: String,
required: false,
default: ""
},
/**
* Determines if the placeholder should be shown even when there are no selections.
*/
alwaysShowPlaceholder: {
type: Boolean,
required: false,
default: true
},
/**
* Toggles the loading state of the select field.
*/
isLoading: {
type: Boolean,
required: false,
default: false
},
/**
* Disables or enables the select field.
*/
disabled: {
type: Boolean,
required: false,
default: false
},
/**
* Toggles a button to clear all selections.
*/
hideClearableButton: {
type: Boolean,
required: false,
default: false
},
/**
* Determines to highlight the searched term or not.
*/
highlightSearchTerm: {
type: Boolean,
required: false,
default: true
},
/**
* Used to implement a custom search function.
* Parameters passed: { options, labelProperty, valueProperty, searchTerm }
*/
searchFunction: {
type: Function,
required: false,
default: ({
options,
labelProperty,
searchTerm
}) => {
return options.filter((option) => {
if (Array.isArray(labelProperty)) {
for (const property of labelProperty) {
const label2 = getPropertyValue(option, property);
if (label2 && typeof label2 === "string" && label2.toLowerCase().includes(searchTerm.toLowerCase())) {
return true;
}
}
return false;
}
const label = getPropertyValue(option, labelProperty);
if (!label) {
return false;
}
return label.toLowerCase().includes(searchTerm.toLowerCase());
});
}
},
/**
* An error in your business logic related to this field.
*
* For example: {"code": 500, "detail": "Error while saving"}
*/
error: {
type: Object,
required: false,
default: null
},
/**
* Toggles the inheritance visualization.
*/
isInherited: {
type: Boolean,
required: false,
default: false
},
/**
* Determines if the field is inheritable.
*/
isInheritanceField: {
type: Boolean,
required: false,
default: false
},
/**
* Determines the active state of the inheritance toggle.
*/
disableInheritanceToggle: {
type: Boolean,
required: false,
default: false
},
/**
* Render the select field in small without a search input
*/
small: {
type: Boolean,
required: false,
default: false
}
},
emits: [
"update:modelValue",
"change",
"item-add",
"item-remove",
"display-values-expand",
"paginate",
"search-term-change",
"inheritance-restore",
"inheritance-remove"
],
setup() {
const { t } = useI18n({
messages: {
en: {
messageNoResults: 'No results found for "{term}".'
},
de: {
messageNoResults: 'Es wurden keine Ergebnisse für "{term}" gefunden.'
}
}
});
return {
t,
getKey: getPropertyValue
};
},
data() {
return {
searchTerm: "",
limit: this.valueLimit,
searchResults: [],
isSearchResultsLoading: false
};
},
computed: {
visibleValues() {
if (typeof this.currentValue === "string" || typeof this.currentValue === "number" || typeof this.currentValue === "boolean") {
const value = this.currentValue;
return this.options.filter((item) => value === this.getKey(item, this.valueProperty));
}
if (Array.isArray(this.currentValue)) {
const value = this.currentValue;
if (this.currentValue.length <= 0) {
return [];
}
return this.options.filter((item) => {
return value.includes(this.getKey(item, this.valueProperty));
}).slice(0, this.limit);
}
if (this.currentValue && typeof this.currentValue === "object") {
const property = this.valueProperty || ("id" in this.currentValue ? "id" : void 0);
if (property) {
return this.options.filter(
(item) => this.getKey(item, property) === this.getKey(this.currentValue, property)
);
}
}
return this.options.filter((item) => this.isSelected(item)).slice(0, this.limit);
},
totalValuesCount() {
if (this.enableMultiSelection && Array.isArray(this.currentValue) && this.currentValue.length) {
return this.currentValue.length;
}
if (Array.isArray(this.currentValue)) {
this.currentValue.length;
}
if (this.currentValue !== void 0 || this.currentValue !== null) {
return 1;
}
return 0;
},
invisibleValueCount() {
if (!this.currentValue) {
return 0;
}
return Math.max(0, this.totalValuesCount - this.limit);
},
currentValue: {
get() {
if (this.modelValue === null || this.modelValue === void 0) {
return [];
}
return this.modelValue;
},
set(newValue) {
this.$emit("update:modelValue", newValue);
this.$emit("change", newValue);
}
},
visibleResults() {
if (this.searchTerm) {
return this.searchResults;
}
return this.options;
},
componentClasses() {
return {
"mt-select--small": this.small
};
}
},
watch: {
valueLimit(value) {
this.limit = value;
},
searchTerm(newSearchTerm) {
this.searchTermDebounced(newSearchTerm);
}
},
methods: {
isSelected(item) {
if (this.enableMultiSelection && Array.isArray(this.currentValue)) {
if (this.valueProperty) {
return this.currentValue.includes(this.getKey(item, this.valueProperty));
}
return this.currentValue.find(
(currentItem) => this.getKey(currentItem, this.labelProperty) === this.getKey(item, this.labelProperty)
);
}
if (this.valueProperty) {
return this.getKey(item, this.valueProperty) === this.currentValue;
}
return this.getKey(item, this.labelProperty) === this.getKey(this.currentValue, this.labelProperty);
},
addItem(item) {
const identifier = this.getKey(item, this.valueProperty);
if (this.isSelected(item) && this.enableMultiSelection) {
this.remove(item);
return;
}
this.$emit("item-add", item);
if (this.enableMultiSelection) {
if (Array.isArray(this.currentValue)) {
this.currentValue = [...this.currentValue, identifier];
} else if (this.currentValue === null || this.currentValue === void 0) {
this.currentValue = [identifier];
} else {
this.currentValue = [this.currentValue, identifier];
}
} else if (this.currentValue !== identifier) {
this.currentValue = identifier;
this.$refs.selectBase.collapse();
this.$refs.selectionList.blur();
}
this.$refs.selectionList.focus();
this.$refs.selectionList.select();
},
remove(item) {
this.$emit("item-remove", item);
if (!Array.isArray(this.currentValue)) {
this.currentValue = null;
return;
}
this.currentValue = this.currentValue.filter(
(value) => value !== this.getKey(item, this.valueProperty)
);
},
removeLastItem() {
if (!this.visibleValues.length) {
return;
}
if (this.invisibleValueCount > 0) {
this.expandValueLimit();
return;
}
const lastSelection = this.visibleValues[this.visibleValues.length - 1];
this.remove(lastSelection);
},
expandValueLimit() {
this.$emit("display-values-expand");
this.limit += this.limit;
},
onSearchTermChange(term) {
this.searchTerm = term;
},
searchTermDebounced: debounce(function searchTermDebounced(newSearchTerm) {
this.$emit("search-term-change", newSearchTerm);
this.resetActiveItem();
this.searchResults = [];
if (newSearchTerm !== void 0 && newSearchTerm !== null) {
this.isSearchResultsLoading = true;
const result = this.searchFunction({
// @ts-expect-error - this context will always be available
options: this.options,
// @ts-expect-error - this context will always be available
labelProperty: this.labelProperty,
// @ts-expect-error - this context will always be available
valueProperty: this.valueProperty,
// @ts-expect-error - this context will always be available
searchTerm: this.searchTerm
});
if (isPromise(result)) {
result.then((res) => {
if (res) {
this.searchResults = res;
}
this.isSearchResultsLoading = false;
});
} else {
if (result) {
this.searchResults = result;
}
this.isSearchResultsLoading = false;
}
}
}, 100),
resetActiveItem() {
if (!this.$refs.MtSelectResultList) {
return;
}
this.$refs.MtSelectResultList.setActiveItemIndex(0);
},
onSelectExpanded() {
this.$refs.selectionList.focus();
},
onSelectCollapsed() {
this.searchTerm = "";
this.$refs.selectionList.blur();
},
onClearSelection() {
this.currentValue = this.enableMultiSelection ? [] : null;
},
getFocusElement() {
return this.$refs.selectionList.getFocusEl();
}
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_mt_select_selection_list = resolveComponent("mt-select-selection-list");
const _component_mt_highlight_text = resolveComponent("mt-highlight-text");
const _component_mt_select_result = resolveComponent("mt-select-result");
const _component_mt_select_result_list = resolveComponent("mt-select-result-list");
const _component_mt_select_base = resolveComponent("mt-select-base");
return openBlock(), createBlock(_component_mt_select_base, mergeProps({
ref: "selectBase",
class: ["mt-select", _ctx.componentClasses],
"is-loading": _ctx.isLoading,
label: _ctx.label
}, _ctx.$attrs, {
error: _ctx.error,
disabled: _ctx.disabled,
"show-clearable-button": !_ctx.hideClearableButton,
"is-inherited": _ctx.isInherited,
"is-inheritance-field": _ctx.isInheritanceField,
"disable-inheritance-toggle": _ctx.disableInheritanceToggle,
onSelectExpanded: _ctx.onSelectExpanded,
onSelectCollapsed: _ctx.onSelectCollapsed,
onClear: _ctx.onClearSelection,
onInheritanceRestore: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("inheritance-restore", $event)),
onInheritanceRemove: _cache[2] || (_cache[2] = ($event) => _ctx.$emit("inheritance-remove", $event))
}), {
"mt-select-prefix": withCtx(() => [
renderSlot(_ctx.$slots, "prefix")
]),
"mt-select-selection": withCtx(({ size }) => [
createVNode(_component_mt_select_selection_list, mergeProps({
ref: "selectionList",
"multi-selection": _ctx.enableMultiSelection,
selections: _ctx.visibleValues,
"invisible-count": _ctx.invisibleValueCount,
"always-show-placeholder": _ctx.alwaysShowPlaceholder
}, { size, valueProperty: _ctx.valueProperty, labelProperty: _ctx.labelProperty, placeholder: _ctx.placeholder, searchTerm: _ctx.searchTerm, disabled: _ctx.disabled }, {
size: _ctx.small ? "small" : "default",
onTotalCountClick: _ctx.expandValueLimit,
onItemRemove: _ctx.remove,
onLastItemDelete: _ctx.removeLastItem,
onSearchTermChange: _ctx.onSearchTermChange
}), {
"label-property": withCtx(({ item, index, itemLabelProperty, itemValueProperty }) => [
renderSlot(_ctx.$slots, "selection-label-property", normalizeProps(guardReactiveProps({ item, index, itemLabelProperty, itemValueProperty })), () => [
createTextVNode(toDisplayString(_ctx.getKey(item, _ctx.labelProperty)), 1)
])
]),
_: 2
}, 1040, ["multi-selection", "selections", "invisible-count", "always-show-placeholder", "size", "onTotalCountClick", "onItemRemove", "onLastItemDelete", "onSearchTermChange"])
]),
"results-list": withCtx(() => [
createVNode(_component_mt_select_result_list, {
ref: "MtSelectResultList",
options: _ctx.visibleResults,
"is-loading": _ctx.isLoading || _ctx.isSearchResultsLoading,
"empty-message": _ctx.t("messageNoResults", { term: _ctx.searchTerm }),
"focus-el": _ctx.getFocusElement(),
onPaginate: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("paginate")),
onItemSelect: _ctx.addItem
}, {
"before-item-list": withCtx(() => [
renderSlot(_ctx.$slots, "before-item-list")
]),
"result-item": withCtx(({ item, index }) => [
renderSlot(_ctx.$slots, "result-item", normalizeProps(guardReactiveProps({
item,
index,
labelProperty: _ctx.labelProperty,
valueProperty: _ctx.valueProperty,
searchTerm: _ctx.searchTerm,
highlightSearchTerm: _ctx.highlightSearchTerm,
isSelected: _ctx.isSelected,
addItem: _ctx.addItem,
getKey: _ctx.getKey
})), () => [
createVNode(_component_mt_select_result, mergeProps({
selected: _ctx.isSelected(item),
class: "mt-select-option--" + _ctx.getKey(item, _ctx.valueProperty),
"data-testid": "mt-select-option--" + _ctx.getKey(item, _ctx.valueProperty)
}, { item, index }, {
onItemSelect: _ctx.addItem,
disabled: item.disabled
}), {
default: withCtx(() => [
renderSlot(_ctx.$slots, "result-label-property", normalizeProps(guardReactiveProps({ item, index, labelProperty: _ctx.labelProperty, valueProperty: _ctx.valueProperty, searchTerm: _ctx.searchTerm, getKey: _ctx.getKey })), () => [
_ctx.highlightSearchTerm ? (openBlock(), createBlock(_component_mt_highlight_text, {
key: 0,
text: _ctx.getKey(item, _ctx.labelProperty),
"search-term": _ctx.searchTerm
}, null, 8, ["text", "search-term"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
createTextVNode(toDisplayString(_ctx.getKey(item, _ctx.labelProperty)), 1)
], 64))
])
]),
_: 2
}, 1040, ["selected", "class", "data-testid", "onItemSelect", "disabled"])
])
]),
"after-item-list": withCtx(() => [
renderSlot(_ctx.$slots, "after-item-list")
]),
_: 3
}, 8, ["options", "is-loading", "empty-message", "focus-el", "onItemSelect"])
]),
"mt-select-suffix": withCtx(() => [
renderSlot(_ctx.$slots, "suffix")
]),
"mt-select-hint": withCtx(() => [
renderSlot(_ctx.$slots, "hint")
]),
_: 3
}, 16, ["class", "is-loading", "label", "error", "disabled", "show-clearable-button", "is-inherited", "is-inheritance-field", "disable-inheritance-toggle", "onSelectExpanded", "onSelectCollapsed", "onClear"]);
}
const MtSelect = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
MtSelect as default
};
//# sourceMappingURL=MtSelect.js.map