@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/).
414 lines (413 loc) • 14.1 kB
JavaScript
import '../mt-number-field.css';
"use strict";
const vue = require("vue");
const MtTextField = require("./MtTextField.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");
require("../mt-base-field-6a3a56a0.js");
require("./MtInheritanceSwitch.js");
require("./MtTooltip.js");
require("../floating-ui.vue-48d5c774.js");
require("../floating-ui.dom-fe395b67.js");
require("../useIsInsideTooltip-f4674e27.js");
require("../index-ab705c2a.js");
require("./MtFieldCopyable.js");
require("../tooltip.directive-7b51326d.js");
require("../id-8e80f112.js");
require("./MtHelpText.js");
require("../useFutureFlags-35232480.js");
require("./MtFieldError.js");
require("./MtText.js");
const _sfc_main = vue.defineComponent({
name: "MtNumberField",
components: {
"mt-icon": mtIcon_vue_vue_type_style_index_0_lang._sfc_main
},
extends: MtTextField,
props: {
/**
* Defines if the number should be a floating point number or integer.
*/
numberType: {
type: String,
required: false,
default: "float",
validator(value) {
return ["float", "int"].includes(value);
}
},
/**
* Defines the amount of which the number is increased or decreased per step.
*/
step: {
type: Number,
required: false,
default: null
},
/**
* Defines the minimum value of the number.
*/
min: {
type: Number,
required: false,
default: null
},
/**
* Defines the maximum value of the number.
*/
max: {
type: Number,
required: false,
default: null
},
/**
* The value of the number field.
*/
modelValue: {
type: Number,
required: false,
default: null
},
/**
* Defines how many digits should be displayed after the decimal point.
*/
digits: {
type: Number,
required: false,
default: 2,
validator(value) {
const isInt = value === Math.floor(value);
if (!isInt) {
console.warn("mt-number-field", "Provided prop digits must be of type integer");
}
return isInt;
}
},
/**
* Defines if digits should be filled with zeros if the value is smaller than the minimum value.
*/
fillDigits: {
type: Boolean,
required: false,
default: false
},
/**
* Defines if the field can be empty.
* @deprecated tag:v5
*/
allowEmpty: {
type: Boolean,
required: false,
default: void 0
// will internally be true
},
/**
* Defines if the number should be aligned to the end of the input field.
*/
numberAlignEnd: {
type: Boolean,
required: false,
default: false
},
/**
* Defines if the control arrows should be visible.
*/
showControls: {
type: Boolean,
required: false,
default: true
}
},
emits: [
"update:modelValue",
"input-change",
"inheritance-restore",
"inheritance-remove",
"change"
],
setup() {
const { t } = vueI18n.useI18n({
messages: {
en: {
increaseButton: "Increase",
decreaseButton: "Decrease"
},
de: {
increaseButton: "Erhöhen",
decreaseButton: "Verringern"
}
}
});
return { t };
},
computed: {
realStep() {
if (this.step === null) {
return this.numberType === "int" ? 1 : 0.01;
}
return this.numberType === "int" ? Math.round(this.step) : this.step;
},
realMinimum() {
if (this.min === null) {
return null;
}
return this.numberType === "int" ? Math.ceil(this.min) : this.min;
},
realMaximum() {
if (this.max === null) {
return null;
}
return this.numberType === "int" ? Math.floor(this.max) : this.max;
},
stringRepresentation() {
if (this.currentValue === null) {
return "";
}
return this.fillDigits && this.numberType !== "int" ? (
// @ts-expect-error - wrong type because of component extends
this.currentValue.toFixed(this.digits)
) : this.currentValue.toString();
},
controlClasses() {
return {
"mt-field__controls--disabled": this.disabled,
"mt-field__controls--has-error": !!this.error,
"mt-field__controls--small": this.size === "small"
};
},
// @deprecated tag:v5
allowEmptyWithDefault() {
return this.allowEmpty ?? false;
}
},
watch: {
modelValue: {
handler() {
if (this.modelValue === null || this.modelValue === void 0) {
this.currentValue = null;
return;
}
this.computeValue(this.modelValue.toString());
},
immediate: true
},
min() {
if (this.currentValue === null || this.currentValue === void 0) {
return;
}
if (!Number.isNaN(Number(this.currentValue))) {
this.computeValue(this.currentValue.toString());
this.$emit("update:modelValue", this.currentValue);
}
},
max() {
if (this.currentValue === null || this.currentValue === void 0) {
return;
}
if (!Number.isNaN(Number(this.currentValue))) {
this.computeValue(this.currentValue.toString());
this.$emit("update:modelValue", this.currentValue);
}
},
// @deprecated tag:v5
allowEmpty: {
handler(value) {
if (value === void 0) {
return;
}
console.warn(
"[MtNumberField] The `allowEmpty` prop is deprecated and will be removed. There will be no replacement."
);
},
immediate: true
}
},
methods: {
onChange(event) {
this.computeValue(event.target.value);
this.$emit("change", event);
this.$emit("update:modelValue", this.currentValue);
},
onInput(event) {
const inputValue = event.target.value;
if (inputValue === "" && this.allowEmptyWithDefault) {
this.currentValue = null;
this.$emit("input-change", null);
return;
}
const val = Number.parseFloat(inputValue);
if (!Number.isNaN(val)) {
this.computeValue(val.toString(), true);
this.$emit("input-change", val);
} else if (inputValue === "" || inputValue === "-" || inputValue === ".") {
this.currentValue = null;
this.$emit("input-change", null);
}
},
increaseNumberByStep() {
this.computeValue((Number(this.currentValue) + this.realStep).toString());
this.$emit("update:modelValue", this.currentValue);
},
decreaseNumberByStep() {
this.computeValue((this.currentValue - this.realStep).toString());
this.$emit("update:modelValue", this.currentValue);
},
computeValue(stringRepresentation, skipBoundaries = false) {
const value = this.getNumberFromString(stringRepresentation);
this.currentValue = this.parseValue(value, skipBoundaries);
},
// @ts-expect-error - defined in parent
parseValue(value, skipBoundaries = false) {
if (value === null || Number.isNaN(value) || !Number.isFinite(value)) {
if (this.allowEmptyWithDefault) {
return null;
}
return this.parseValue(0, skipBoundaries);
}
const processedValue = skipBoundaries ? value : this.checkBoundaries(value);
return this.checkForInteger(processedValue);
},
checkBoundaries(value) {
if (this.realMaximum !== null && value > this.realMaximum) {
value = this.realMaximum;
}
if (this.realMinimum !== null && value < this.realMinimum) {
value = this.realMinimum;
}
return value;
},
getNumberFromString(value) {
let splits = value.split("e").shift();
splits = splits.replace(/,/g, ".").split(".");
if (splits.length === 1) {
return parseFloat(splits[0]);
}
if (this.numberType === "int") {
return parseInt(splits.join(""), 10);
}
const decimals = splits[splits.length - 1].length;
const float = parseFloat(splits.join(".")).toFixed(decimals);
return decimals > this.digits ? (
// @ts-expect-error - can be calculated
Math.round(float * 10 ** this.digits) / 10 ** this.digits
) : Number(float);
},
checkForInteger(value) {
if (this.numberType !== "int") {
return value;
}
const floor = Math.floor(value);
if (floor !== value) {
this.$nextTick(() => {
this.$forceUpdate();
});
}
return floor;
}
}
});
const mtNumberField_vue_vue_type_style_index_0_scoped_e7526f45_lang = "";
const mtNumberField_vue_vue_type_style_index_1_lang = "";
const _hoisted_1 = ["id", "name", "disabled", "value", "placeholder"];
const _hoisted_2 = ["disabled", "aria-label"];
const _hoisted_3 = ["disabled", "aria-label"];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_mt_icon = vue.resolveComponent("mt-icon");
const _component_mt_field_error = vue.resolveComponent("mt-field-error");
const _component_mt_base_field = vue.resolveComponent("mt-base-field");
return vue.openBlock(), vue.createBlock(_component_mt_base_field, {
class: vue.normalizeClass(["mt-number-field", _ctx.$attrs.class]),
disabled: _ctx.disabled || _ctx.isInherited,
required: _ctx.required,
"is-inherited": _ctx.isInherited,
"is-inheritance-field": _ctx.isInheritanceField,
"disable-inheritance-toggle": _ctx.disableInheritanceToggle,
copyable: _ctx.copyable,
"copyable-tooltip": _ctx.copyableTooltip,
"copyable-text": _ctx.stringRepresentation,
"has-focus": _ctx.hasFocus,
"help-text": _ctx.helpText,
name: _ctx.name,
size: _ctx.size,
onInheritanceRestore: _cache[8] || (_cache[8] = ($event) => _ctx.$emit("inheritance-restore", $event)),
onInheritanceRemove: _cache[9] || (_cache[9] = ($event) => _ctx.$emit("inheritance-remove", $event))
}, {
label: vue.withCtx(() => [
vue.createTextVNode(vue.toDisplayString(_ctx.label), 1)
]),
"field-prefix": vue.withCtx(() => [
vue.renderSlot(_ctx.$slots, "prefix", {}, void 0, true)
]),
element: vue.withCtx(({ identification }) => [
vue.createElementVNode("input", {
id: _ctx.createInputId(identification),
type: "text",
name: identification,
disabled: _ctx.disabled || _ctx.isInherited,
value: _ctx.stringRepresentation,
placeholder: _ctx.placeholder,
class: vue.normalizeClass(_ctx.numberAlignEnd ? "mt-number-field__align-end" : ""),
onInput: _cache[0] || (_cache[0] = (...args) => _ctx.onInput && _ctx.onInput(...args)),
onKeydown: [
_cache[1] || (_cache[1] = vue.withKeys((...args) => _ctx.increaseNumberByStep && _ctx.increaseNumberByStep(...args), ["up"])),
_cache[2] || (_cache[2] = vue.withKeys((...args) => _ctx.decreaseNumberByStep && _ctx.decreaseNumberByStep(...args), ["down"]))
],
onChange: _cache[3] || (_cache[3] = (...args) => _ctx.onChange && _ctx.onChange(...args)),
onFocus: _cache[4] || (_cache[4] = (...args) => _ctx.setFocusClass && _ctx.setFocusClass(...args)),
onBlur: _cache[5] || (_cache[5] = (...args) => _ctx.removeFocusClass && _ctx.removeFocusClass(...args))
}, null, 42, _hoisted_1),
_ctx.showControls ? (vue.openBlock(), vue.createElementBlock("div", {
key: 0,
class: vue.normalizeClass(["mt-number-field__controls", _ctx.controlClasses])
}, [
vue.createElementVNode("button", {
type: "button",
disabled: _ctx.disabled || _ctx.isInherited,
"aria-label": _ctx.t("increaseButton"),
"data-testid": "mt-number-field-increase-button",
tabindex: "-1",
onClick: _cache[6] || (_cache[6] = (...args) => _ctx.increaseNumberByStep && _ctx.increaseNumberByStep(...args))
}, [
vue.createVNode(_component_mt_icon, {
size: "10",
name: "regular-chevron-up-s",
"aria-hidden": "true"
})
], 8, _hoisted_2),
vue.createElementVNode("button", {
type: "button",
disabled: _ctx.disabled || _ctx.isInherited,
"aria-label": _ctx.t("decreaseButton"),
"data-testid": "mt-number-field-decrease-button",
tabindex: "-1",
onClick: _cache[7] || (_cache[7] = (...args) => _ctx.decreaseNumberByStep && _ctx.decreaseNumberByStep(...args))
}, [
vue.createVNode(_component_mt_icon, {
style: vue.normalizeStyle({ marginTop: _ctx.size === "small" ? "0" : "-3px" }),
size: "10",
name: "regular-chevron-down-s",
"aria-hidden": "true"
}, null, 8, ["style"])
], 8, _hoisted_3)
], 2)) : vue.createCommentVNode("", true),
vue.renderSlot(_ctx.$slots, "_unit-suffix", {}, void 0, true)
]),
"field-suffix": vue.withCtx(() => [
vue.renderSlot(_ctx.$slots, "suffix", {}, void 0, true)
]),
error: vue.withCtx(() => [
_ctx.error ? (vue.openBlock(), vue.createBlock(_component_mt_field_error, {
key: 0,
error: _ctx.error
}, null, 8, ["error"])) : vue.createCommentVNode("", true)
]),
"field-hint": vue.withCtx(() => [
vue.renderSlot(_ctx.$slots, "hint", {}, void 0, true)
]),
_: 3
}, 8, ["class", "disabled", "required", "is-inherited", "is-inheritance-field", "disable-inheritance-toggle", "copyable", "copyable-tooltip", "copyable-text", "has-focus", "help-text", "name", "size"]);
}
const MtNumberField = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-e7526f45"]]);
module.exports = MtNumberField;
//# sourceMappingURL=MtNumberField.js.map