@aotearoan/neon
Version:
Neon is a lightweight design library of Vue 3 components with minimal dependencies.
220 lines (219 loc) • 7.52 kB
JavaScript
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