UNPKG

maz-ui

Version:

A standalone components library for Vue.Js 3 & Nuxt.Js 3

152 lines (151 loc) 6.93 kB
import { defineComponent, ref, watch, computed, createElementBlock, openBlock, normalizeStyle, normalizeClass, createElementVNode, Fragment, renderList, mergeProps, toDisplayString } from "vue"; import { _ as _export_sfc } from "../chunks/_plugin-vue_export-helper.B--vMWp3.js"; import '../assets/MazInputCode.CimXArpg.css';const _hoisted_1 = ["disabled"], _hoisted_2 = { class: "m-input-code__wrapper" }, _hoisted_3 = ["id", "name", "inputmode", "pattern", "required", "value", "onInput", "onKeydown", "onClick"], _sfc_main = /* @__PURE__ */ defineComponent({ inheritAttrs: !1, __name: "MazInputCode", props: { style: { default: void 0 }, class: { default: void 0 }, modelValue: { default: void 0 }, codeLength: { default: 4 }, type: { default: "text" }, acceptAlpha: { type: Boolean, default: !1 }, required: { type: Boolean, default: !1 }, disabled: { type: Boolean, default: !1 }, error: { type: Boolean, default: !1 }, success: { type: Boolean, default: !1 }, warning: { type: Boolean, default: !1 }, size: { default: "md" }, color: { default: "primary" }, hint: {} }, emits: ["update:model-value", "completed"], setup(__props, { emit: __emit }) { const props = __props, emits = __emit, inputList = ref([]), localMap = ref(/* @__PURE__ */ new Map()); watch( () => props.modelValue, (value, oldValue) => { value !== oldValue && (localMap.value = getMapValues()); }, { immediate: !0 } ); const inputValues = computed({ get: () => localMap.value, set: (value) => { const emittedValue = getEmittedValue(value); emits("update:model-value", emittedValue), emittedValue?.toString().length === props.codeLength && emits("completed"); } }); function getMapValues(value = props.modelValue) { const map = /* @__PURE__ */ new Map(); for (const item of Array.from({ length: props.codeLength }, (_, i) => i)) if (value === void 0) map.set(item + 1, void 0); else { const values = [...value.toString()]; map.set(item + 1, values[item]); } return map; } function handleNewValue(event, item) { const newValue = getValueSanitized(event.target?.value); inputValues.value = localMap.value.set(item, newValue), newValue && focusAndSelectInputByIndex(item); } function getEmittedValue(map) { const stringValue = [...map.values()].join(""); return props.type === "text" ? stringValue : stringValue && !Number.isNaN(Number(stringValue)) ? Number(stringValue) : void 0; } function getValueSanitized(value) { return (props.acceptAlpha ? value.match(/^[\w.]$/) : value.match(/\d+/g))?.toString(); } function handleKeydown(event, inputIndex) { const currentInputValue = localMap.value.get(inputIndex); if (event.key === "ArrowRight" && focusAndSelectInputByIndex(inputIndex), event.key === "ArrowLeft" && focusAndSelectInputByIndex(inputIndex - 2), event.key === "Backspace" && !currentInputValue) { const previousInputIndexToFocus = inputIndex - 1 < 0 ? 0 : inputIndex - 1; inputValues.value = localMap.value.set(previousInputIndexToFocus, void 0), focusAndSelectInputByIndex(previousInputIndexToFocus - 1); } } function setValueOnPaste(event) { const pasteData = event.clipboardData?.getData("text"); if (!pasteData) return; const indexInputsFromPastePlace = Array.from({ length: props.codeLength }, (_, i) => ({ index: i + 1, value: [...pasteData.toString()][i] ?? void 0 })); for (const { index, value } of indexInputsFromPastePlace) { const sanitizedValue = value ? getValueSanitized(value) : void 0; sanitizedValue && localMap.value.set(index, sanitizedValue); } setTimeout(() => { const lastInputWithoutValueIndex = getLastInputWithoutValueIndex(), lastIndex = lastInputWithoutValueIndex >= props.codeLength ? props.codeLength - 1 : lastInputWithoutValueIndex; focusAndSelectInputByIndex(lastIndex, !1); }, 0); } function getLastInputWithoutValueIndex() { return [...localMap.value.values()].filter(Boolean).length; } function focusAndSelectInputByIndex(index, selectValue = !0) { setTimeout(() => { const input = inputList.value[index]; index + 1 > props.codeLength || !input || (input.focus(), selectValue && selectInputByIndex(index)); }, 0); } function selectInputByIndex(index) { const input = inputList.value[index]; index + 1 > props.codeLength || !input || input.select(); } const borderColorState = computed(() => { if (props.error) return "!maz-border-destructive"; if (props.success) return "!maz-border-success"; if (props.warning) return "!maz-border-warning"; }); return (_ctx, _cache) => (openBlock(), createElementBlock("fieldset", { class: normalizeClass(["m-input-code m-reset-css", [__props.size ? `--${__props.size}` : void 0, props.class]]), disabled: __props.disabled, style: normalizeStyle([__props.style, { "--input-border-color": `hsl(var(--maz-${props.color}))` }]) }, [ createElementVNode("div", _hoisted_2, [ (openBlock(!0), createElementBlock(Fragment, null, renderList(__props.codeLength, (item) => (openBlock(), createElementBlock("div", { key: item, class: normalizeClass(["input-wrapper", borderColorState.value]) }, [ createElementVNode("input", mergeProps({ id: `m-input-code-${item}`, ref_for: !0, ref: (el) => { inputList.value[item - 1] = el; }, type: "text", name: `m-input-code-${item}`, minlength: "1", maxlength: "1", inputmode: __props.acceptAlpha ? "text" : "numeric", pattern: __props.acceptAlpha ? "[a-zA-Z0-9]{1}" : "[0-9]{1}", autocomplete: "do-not-autofill", required: __props.required }, { ref_for: !0 }, _ctx.$attrs, { value: inputValues.value.get(item), onInput: ($event) => handleNewValue($event, item), onKeydown: ($event) => handleKeydown($event, item), onClick: ($event) => selectInputByIndex(item - 1), onPaste: setValueOnPaste }), null, 16, _hoisted_3) ], 2))), 128)) ]), createElementVNode("span", { class: normalizeClass(["m-input-code__hint", { "--error": __props.error, "--success": __props.success, "--warning": __props.warning }]) }, toDisplayString(__props.hint), 3) ], 14, _hoisted_1)); } }), MazInputCode = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d5705617"]]); export { MazInputCode as default };