@dialpad/dialtone-vue
Version:
Vue component library for Dialpad's design system Dialtone
383 lines (382 loc) • 13.2 kB
JavaScript
import { VALIDATION_MESSAGE_TYPES as h, DESCRIPTION_SIZE_TYPES as c } from "../../common/constants/index.js";
import { INPUT_TYPES as s, DESCRIPTION_SIZE_CLASSES as g, LABEL_SIZE_CLASSES as f, INPUT_STATE_CLASSES as m, INPUT_SIZE_CLASSES as v, INPUT_SIZES as a, INPUT_ICON_SIZES as S } from "./input-constants.js";
import { getValidationState as _, getUniqueString as L } from "../../common/utils/index.js";
import { MessagesMixin as b } from "../../common/mixins/input.js";
import { n as C } from "../../_plugin-vue2_normalizer-DSLOjnn3.js";
import I from "../validation-messages/validation-messages.js";
const y = {
name: "DtInput",
components: { DtValidationMessages: I },
mixins: [b],
inheritAttrs: !1,
props: {
/**
* Name property of the input element
*/
name: {
type: String,
default: ""
},
/**
* Type of the input.
* When `textarea` a `<textarea>` element will be rendered instead of an `<input>` element.
* @values text, password, email, number, textarea, date, time, file, tel, search
* @default 'text'
*/
type: {
type: String,
default: s.TEXT,
validator: (e) => Object.values(s).includes(e)
},
/**
* Value of the input
*/
value: {
type: [String, Number],
default: ""
},
/**
* Disables the input
* @values true, false
*/
disabled: {
type: Boolean,
default: !1
},
/**
* Label for the input
*/
label: {
type: String,
default: ""
},
/**
* Determines visibility of input label.
* @values true, false
*/
labelVisible: {
type: Boolean,
default: !0
},
/**
* Description for the input
*/
description: {
type: String,
default: ""
},
/**
* Size of the input, one of `xs`, `sm`, `md`, `lg`, `xl`
* @values xs, sm, md, lg, xl
*/
size: {
type: String,
default: "md",
validator: (e) => Object.values(a).includes(e)
},
/**
* Additional class name for the input element.
* Can accept String, Object, and Array, i.e. has the
* same API as Vue's built-in handling of the class attribute.
*/
inputClass: {
type: [String, Object, Array],
default: ""
},
/**
* Additional class name for the input wrapper element.
* Can accept all of String, Object, and Array, i.e. has the
* same api as Vue's built-in handling of the class attribute.
*/
inputWrapperClass: {
type: [String, Object, Array],
default: ""
},
/**
* Additional class name for the root element.
* Can accept all of String, Object, and Array, i.e. has the
* same api as Vue's built-in handling of the class attribute.
*/
rootClass: {
type: [String, Object, Array],
default: ""
},
/**
* The current character length that the user has entered into the input.
* This will only need to be used if you are using `validate.length` and
* the string contains abnormal characters.
* For example, an emoji could take up many characters in the input, but should only count as 1 character.
* If no number is provided, a built-in length calculation will be used for the length validation.
*/
currentLength: {
type: Number,
default: null
},
/**
* Whether the input will continue to display a warning validation message even if the input has lost focus.
*/
retainWarning: {
type: Boolean,
default: !1
},
/**
* Validation for the input. Supports maximum length validation with the structure:
* `{ "length": {"description": string, "max": number, "warn": number, "message": string,
* "limitMaxLength": boolean }}`
*/
validate: {
type: Object,
default: null
},
/**
* hidden allows to use input without the element visually present in DOM
*/
hidden: {
type: Boolean,
default: !1
}
},
emits: [
/**
* Native input event
*
* @event input
* @type {String}
*/
"input",
/**
* Native input blur event
*
* @event blur
* @type {FocusEvent}
*/
"blur",
/**
* Input clear event
*
* @event clear
*/
"clear",
/**
* Native input focus event
*
* @event focus
* @type {FocusEvent}
*/
"focus",
/**
* Native input focusin event
*
* @event focusin
* @type {FocusEvent}
*/
"focusin",
/**
* Native input focusout event
*
* @event focusout
* @type {FocusEvent}
*/
"focusout",
/**
* Length of the input when currentLength prop is not passed
*
* @event update:length
* @type {Number}
*/
"update:length",
/**
* Result of the input validation
*
* @event update:invalid
* @type {Boolean}
*/
"update:invalid"
],
data() {
return {
isInputFocused: !1,
isInvalid: !1,
defaultLength: 0
};
},
computed: {
isTextarea() {
return this.type === s.TEXTAREA;
},
isDefaultSize() {
return this.size === a.DEFAULT;
},
iconSize() {
return S[this.size];
},
isValidSize() {
return Object.values(a).includes(this.size);
},
isValidDescriptionSize() {
return Object.values(c).includes(this.size);
},
inputComponent() {
return this.isTextarea ? "textarea" : "input";
},
inputListeners() {
return {
/* TODO
Check if any usages of this component leverage $listeners and either remove if unused or scope the removal
and migration prior to upgrading to Vue 3.x
*/
...this.$listeners,
input: (e) => this.$emit("input", e.target.value),
focus: (e) => {
this.isInputFocused = !0, this.$emit("focus", e);
},
blur: (e) => {
this.isInputFocused = !1, this.onBlur(e);
}
};
},
descriptionKey() {
return `input-description-${L()}`;
},
inputState() {
return _(this.validationMessages);
},
defaultLengthCalculation() {
return this.calculateLength(this.value);
},
validationProps() {
var e, t, i, n, l, r, u, o, d, p;
return {
length: {
description: (t = (e = this == null ? void 0 : this.validate) == null ? void 0 : e.length) == null ? void 0 : t.description,
max: (n = (i = this == null ? void 0 : this.validate) == null ? void 0 : i.length) == null ? void 0 : n.max,
warn: (r = (l = this == null ? void 0 : this.validate) == null ? void 0 : l.length) == null ? void 0 : r.warn,
message: (o = (u = this == null ? void 0 : this.validate) == null ? void 0 : u.length) == null ? void 0 : o.message,
limitMaxLength: (p = (d = this == null ? void 0 : this.validate) == null ? void 0 : d.length) != null && p.limitMaxLength ? this.validate.length.limitMaxLength : !1
}
};
},
validationMessages() {
return this.showLengthLimitValidation ? this.formattedMessages.concat([this.inputLengthErrorMessage()]) : this.formattedMessages;
},
showInputState() {
return this.showMessages && this.inputState;
},
inputLength() {
return this.currentLength ? this.currentLength : this.defaultLengthCalculation;
},
inputLengthState() {
return this.inputLength < this.validationProps.length.warn ? null : this.inputLength <= this.validationProps.length.max ? this.validationProps.length.warn ? h.WARNING : null : h.ERROR;
},
shouldValidateLength() {
return !!(this.validationProps.length.description && this.validationProps.length.max);
},
shouldLimitMaxLength() {
return this.shouldValidateLength && this.validationProps.length.limitMaxLength;
},
showLengthLimitValidation() {
return this.shouldValidateLength && this.inputLengthState !== null && this.validationProps.length.message && (this.retainWarning || this.isInputFocused || this.isInvalid);
},
sizeModifierClass() {
return this.isDefaultSize || !this.isValidSize ? "" : v[this.inputComponent][this.size];
},
stateClass() {
return [m[this.inputState]];
}
},
watch: {
isInvalid(e) {
this.$emit("update:invalid", e);
},
value: {
immediate: !0,
handler(e) {
this.shouldValidateLength && this.validateLength(this.inputLength), this.currentLength == null && this.$emit("update:length", this.calculateLength(e));
}
}
},
beforeMount() {
this.descriptionSizeClasses = g, this.labelSizeClasses = f;
},
methods: {
inputClasses() {
return [
"d-input__input",
this.inputComponent === "input" ? "d-input" : "d-textarea",
{
[this.stateClass]: this.showInputState,
"d-input-icon--left": this.$slots.leftIcon,
"d-input-icon--right": this.$slots.rightIcon
},
this.sizeModifierClass,
this.inputClass
];
},
inputWrapperClasses() {
return this.hidden ? [] : [
"d-input__wrapper",
{ [this.stateClass]: this.showInputState },
this.inputWrapperClass
];
},
calculateLength(e) {
return typeof e != "string" ? 0 : [...e].length;
},
inputLengthErrorMessage() {
return {
message: this.validationProps.length.message,
type: this.inputLengthState
};
},
onBlur(e) {
var t;
(t = this.$refs.container) != null && t.contains(e.relatedTarget) || this.$emit("blur", e);
},
emitClearEvents() {
this.$emit("input", ""), this.$emit("clear"), this.$emit("update:modelValue", "");
},
blur() {
this.$refs.input.blur();
},
focus() {
this.$refs.input.focus();
},
select() {
this.$refs.input.select();
},
getMessageKey(e, t) {
return `message-${e}-${t}`;
},
validateLength(e) {
this.isInvalid = e > this.validationProps.length.max;
},
clearInput() {
this.$refs.input.value = "", this.$refs.input.focus(), this.emitClearEvents();
}
}
};
var $ = function() {
var t = this, i = t._self._c;
return i("div", { ref: "container", class: [t.rootClass, "d-input__root", { "d-input--hidden": t.hidden }], attrs: { "data-qa": "dt-input" } }, [i("label", { staticClass: "d-input__label", attrs: { "aria-details": t.$slots.description || t.description ? t.descriptionKey : void 0, "data-qa": "dt-input-label-wrapper" } }, [t._t("labelSlot", function() {
return [t.labelVisible && t.label ? i("div", { ref: "label", class: [
"d-input__label-text",
"d-label",
t.labelSizeClasses[t.size]
], attrs: { "data-qa": "dt-input-label" } }, [t._v(" " + t._s(t.label) + " ")]) : t._e()];
}), t.$slots.description || t.description || t.shouldValidateLength ? i("div", { ref: "description", class: [
"d-input__description",
"d-description",
t.descriptionSizeClasses[t.size]
], attrs: { id: t.descriptionKey, "data-qa": "dt-input-description" } }, [t.$slots.description || t.description ? i("div", [t._t("description", function() {
return [t._v(t._s(t.description))];
})], 2) : t._e(), t.shouldValidateLength ? i("div", { staticClass: "d-input__length-description", attrs: { "data-qa": "dt-input-length-description" } }, [t._v(" " + t._s(t.validationProps.length.description) + " ")]) : t._e()]) : t._e(), i("div", { class: t.inputWrapperClasses(), attrs: { "read-only": t.disabled } }, [i("span", { staticClass: "d-input-icon d-input-icon--left", attrs: { "data-qa": "dt-input-left-icon-wrapper" }, on: { focusout: t.onBlur } }, [t._t("leftIcon", null, { iconSize: t.iconSize })], 2), t.isTextarea ? i("textarea", t._g(t._b({ ref: "input", class: t.inputClasses(), attrs: { name: t.name, disabled: t.disabled, autocomplete: t.$attrs.autocomplete ?? "off", maxlength: t.shouldLimitMaxLength ? t.validationProps.length.max : null, "data-qa": t.$attrs["data-qa"] ?? "dt-input-input" }, domProps: { value: t.value } }, "textarea", t.$attrs, !1), t.inputListeners)) : i("input", t._g(t._b({ ref: "input", class: t.inputClasses(), attrs: { name: t.name, type: t.type, disabled: t.disabled, autocomplete: t.$attrs.autocomplete ?? "off", maxlength: t.shouldLimitMaxLength ? t.validationProps.length.max : null, "data-qa": t.$attrs["data-qa"] ?? "dt-input-input" }, domProps: { value: t.value } }, "input", t.$attrs, !1), t.inputListeners)), i("span", { staticClass: "d-input-icon d-input-icon--right", attrs: { "data-qa": "dt-input-right-icon-wrapper" }, on: { focusout: t.onBlur } }, [t._t("rightIcon", null, { iconSize: t.iconSize, clear: t.clearInput })], 2)])], 2), i("dt-validation-messages", t._b({ class: t.messagesClass, attrs: { "validation-messages": t.validationMessages, "show-messages": t.showMessages, "data-qa": "dt-input-messages" } }, "dt-validation-messages", t.messagesChildProps, !1))], 1);
}, x = [], E = /* @__PURE__ */ C(
y,
$,
x
);
const V = E.exports;
export {
V as default
};
//# sourceMappingURL=input.js.map