UNPKG

@aotearoan/neon

Version:

Neon is a lightweight design library of Vue 3 components with minimal dependencies.

220 lines (219 loc) 7.52 kB
import { defineComponent as L, useAttrs as z, ref as m, computed as o } from "vue"; import { NeonInputType as D } from "../../../model/user-input/input/NeonInputType.es.js"; import { NeonState as l } from "../../../model/common/state/NeonState.es.js"; import { NeonSize as F } from "../../../model/common/size/NeonSize.es.js"; import { NeonFunctionalColor as i } from "../../../model/common/color/NeonFunctionalColor.es.js"; import T from "../../presentation/icon/NeonIcon.vue.es.js"; import { NeonDebounceUtils as E } from "../../../utils/common/debounce/NeonDebounceUtils.es.js"; import { NeonInputMode as M } from "../../../model/user-input/input/NeonInputMode.es.js"; const q = L({ name: "NeonInput", components: { NeonIcon: T }, props: { /** * The id the input */ id: { type: String, default: null }, /** * The value of the input */ modelValue: { type: String, default: null }, /** * The type of input this is. NOTE: Neon provides custom components as alternatives in the following cases: * * file (use <a href="/user-input/file">NeonFile</a>) * * password (use <a href="/user-input/password">NeonPassword</a>) */ type: { type: String, default: D.Text }, /** * Placeholder text to display in the input */ placeholder: { type: String, default: null }, /** * Size of the input */ size: { type: String, default: F.Medium }, /** * Color of the input */ color: { type: String, default: i.Primary }, /** * The HTML input mode as specified <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode">here</a>. */ inputmode: { type: String, default: M.Text }, /** * The HTML autocomplete mode as specified <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#values">here</a>. * NOTE: No enum is provided in Neon as some values can be used in combination, please refer to the full list of values in the preceding link. */ autocomplete: { type: String, default: "on" }, /** * The state of the input */ state: { type: String, default: l.Ready }, /** * The number of rows to display in the case of a textarea */ rows: { type: Number, default: null }, /** * The name of a clickable icon to display inside the input. This is used for clearing contents or e.g. in the case of * NeonPassword toggle showing/hiding the password. Defaults to <em>times</em> (for clearing the input's contents). */ icon: { type: String, default: null }, /** * Make the input field icon read-only, i.e. it will not emit events or be treated as a focusable button. */ iconReadonly: { type: Boolean, default: !1 }, /** * Hide the icon button, e.g. the X button to clear the input's contents. */ hideIcon: { type: Boolean, default: !1 }, /** * Tabindex to assign to the input. */ tabindex: { type: Number, default: 0 }, /** * The disabled state of the input */ disabled: { type: Boolean, default: !1 }, /** * When the state is success or error, display the field with the state color indicator, e.g. border or background * color. */ stateHighlight: { type: Boolean, default: !0 }, /** * When the state is success or error, display the state icon. */ stateIcon: { type: Boolean, default: !0 }, /** * The character limit for a textarea. */ maxlength: { type: Number, default: null }, /** * The label template for the character limit. This is a string in the vue-i18n Pluralization format with a * <em>{count}</em> placeholder. */ maxlengthLabel: { type: String, default: "No characters left | 1 character left | {count} characters left" }, /** * Debounce time in ms. If no value is provided, the default value set in NeonDebounceUtils is used (=0ms). */ debounce: { type: Number, default: void 0 } }, emits: [ /** * Emitted when the input has gained focus * @type {void} */ "focus", /** * Emitted when the input has lost focus * @type {void} */ "blur", /** * Emitted when the icon is clicked * @type {void} */ "icon-click", /** * Emitted when the input value is changed, NOTE: is not triggered if input is over the textarea length limit * @type {string} the contents of the input */ "update:modelValue" ], setup(e, { emit: u, expose: g }) { const h = z(), c = m(null), r = m(!1), y = o(() => { const { // eslint-disable-next-line @typescript-eslint/no-unused-vars onBlur: t, // eslint-disable-next-line @typescript-eslint/no-unused-vars onFocus: n, // eslint-disable-next-line @typescript-eslint/no-unused-vars onIconClick: a, ...w } = h; return w; }), d = E.debounce((t) => { u("update:modelValue", t); }, e.debounce), s = o(() => { var t; switch (e.state) { case l.Loading: return "loading"; case l.Success: return e.stateIcon ? "check" : void 0; case l.Error: return e.stateIcon ? "times" : void 0; default: return e.icon ? e.icon : e.modelValue && (((t = e.modelValue) == null ? void 0 : t.length) || 0) > 0 ? "times" : void 0; } }), b = o(() => { var t; return s.value && !e.hideIcon && (e.state !== "ready" || e.icon || e.modelValue && !e.disabled && (((t = e.modelValue) == null ? void 0 : t.length) || 0) > 0); }), S = o(() => { switch (e.state) { case l.Success: return i.Success; case l.Error: return i.Error; case l.Loading: return e.color; default: return i.LowContrast; } }), x = o(() => { var t; if (e.maxlength && e.maxlength > 0) { const n = e.maxlengthLabel.split(" | "), a = e.maxlength - (((t = e.modelValue) == null ? void 0 : t.length) || 0); switch (a) { case 0: return n[0]; case 1: return n[1]; default: return n[2].replace("{count}", `${a}`); } } return null; }), f = () => { var t; (t = c.value) == null || t.focus(); }, N = () => { var t; (t = c.value) == null || t.click(); }, V = () => { r.value = !0, u("focus"); }, v = () => { r.value = !1, u("blur"); }, I = (t) => { e.disabled || (e.icon ? u("icon-click") : (d(""), setTimeout(f)), t.preventDefault(), t.stopPropagation()); }, k = (t) => { const n = t.target.value, a = e.maxlength && n.length > e.maxlength ? n.substring(0, e.maxlength) : n; e.modelValue !== a && d(a); }, B = (t) => { var n; t.key !== "Backspace" && e.maxlength && e.modelValue && (((n = e.modelValue) == null ? void 0 : n.length) || 0) >= e.maxlength && t.preventDefault(); }, C = o(() => e.placeholder || ""); return g({ neonInput: c }), { neonInput: c, focused: r, sanitizedAttributes: y, iconVisible: b, iconName: s, iconColor: S, computedPlaceholder: C, counterLabel: x, focus: f, click: N, onFocus: V, onBlur: v, iconClicked: I, changeValue: k, onKeyDown: B }; } }); export { q as default }; //# sourceMappingURL=NeonInput.es.js.map