UNPKG

@vue-interface/form-control

Version:
621 lines (620 loc) 15.8 kB
import { Shadowable as m } from "@vue-interface/shadowable"; import { isPlainObject as F, isNil as p, kebabCase as o, isObject as k } from "lodash-es"; import { defineComponent as l, computed as A, openBlock as y, createElementBlock as g, Fragment as v, renderList as b, unref as u, renderSlot as C, normalizeProps as $, guardReactiveProps as S } from "vue"; const n = {}; function a(...t) { if (!t.length) return n; const [e, s] = t; return typeof e == "string" ? typeof n[e] < "u" ? n[e] : s : Array.isArray(e) ? e.reduce((r, i) => Object.assign(r, { //@ts-ignore [i]: n[i] }), {}) : Object.assign(n, ...t); } const j = /* @__PURE__ */ l({ __name: "FormControlErrors", props: { error: null, errors: null, name: null, id: null }, setup(t) { const e = t, s = String((e == null ? void 0 : e.id) || (e == null ? void 0 : e.name)), r = A(() => e.error ? /* @__PURE__ */ new Map( [[s, [e.error]]] ) : F(e.errors) ? new Map( Object.entries(e.errors) ) : Array.isArray(e.errors) ? /* @__PURE__ */ new Map( [[s, e.errors]] ) : /* @__PURE__ */ new Map()); return (i, c) => (y(!0), g(v, null, b(u(r).get(u(s)), (E) => C(i.$slots, "default", $(S({ key: u(s), error: E })))), 256)); } }), z = /* @__PURE__ */ l({ __name: "FormControlFeedback", props: { feedback: null }, setup(t) { return (e, s) => (y(!0), g(v, null, b([].concat(t.feedback), (r) => C(e.$slots, "default", $(S({ feedback: r })))), 256)); } }); function d(t, e, s = "-") { const r = String(e).replace(new RegExp(`^${t}${s}?`), ""); return [ o(r), t ].filter((i) => !!i).join(s); } const V = l({ components: { FormControlErrors: j, FormControlFeedback: z }, directives: { bindEvents: { created(t, e) { var s, r; (r = (s = e.instance) == null ? void 0 : s.bindEvents) == null || r.call(s, t); } } }, mixins: [ m ], inheritAttrs: !1, props: { /** * Show type activity indicator. */ activity: { type: Boolean, default: !1 }, /** * Animate floating labels inside the input. */ animated: { type: Boolean, default: () => a("animated", !1) }, /** * An inline field validation error. */ error: { type: [String, Array, Boolean], default: void 0 }, /** * An inline field validation errors passed as object with key/value * pairs. If errors passed as an object, the form name will be used for * the key. */ errors: { type: [Array, Object, Boolean], default: void 0 }, /** * Some feedback to add to the field once the field is successfully * valid. */ feedback: { type: [String, Array], default: void 0 }, /** * The primary class assigned to the form control. */ formControlClass: { type: [Array, Object, String], default: () => a("controlClass", "form-control") }, /** * Add form-group wrapper to input. */ group: { type: Boolean, default: () => a("group", !0) }, /** * Some instructions to appear under the field label. */ helpText: { type: [Number, String], default: void 0 }, /** * The activity indicator type. */ indicator: { type: [Object, String, Boolean], default: () => a("indicator", "spinner") }, /** * The activity indicator size. */ indicatorSize: { type: String, default: void 0 }, /** * Force the input to be invalid. */ invalid: Boolean, /** * The value of label element. If no value, no label will appear. */ label: { type: [Number, String], default: void 0 }, /** * The default label class assigned to the label element. */ labelClass: { type: [Object, String], default: () => a("labelClass", "form-label") }, /** * The model default value. */ modelValue: { type: [String, Number, Boolean, Array, Object], default: () => { } }, /** * Should the control look like plaintext. */ plaintext: Boolean, /** * The size of the form control. */ size: { type: String, default: void 0 }, /** * Force the input to be valid. */ valid: Boolean }, emits: [ "focus", "blur", "change", "click", "keypress", "keyup", "keydown", "progress", "paste", "update:modelValue" ], data() { return { currentValue: void 0, hasChanged: !1, hasFocus: !1, isDirty: this }; }, computed: { model: { get() { return this.getModelValue(); }, set(t) { this.setModelValue(t); } }, id() { return this.$attrs.id || Math.random().toString(36).slice(2); }, isEmpty() { return p(this.model); }, isInvalid() { return !!(this.invalid || this.error || this.errors && (Array.isArray(this.errors) ? this.errors.length : this.errors[this.$attrs.id || this.$attrs.name])); }, isValid() { return !!(this.valid || this.feedback); }, componentName() { return this.$options.name; }, controlClass() { return this.formControlClass; }, controlAttributes() { const t = Object.assign({}, this.$attrs, { id: this.id, class: this.controlClasses }); return delete t.value, t; }, controlClasses() { return Object.assign({ [this.controlClass]: !!this.controlClass, [this.controlSizeClass]: !!this.controlSizeClass, [this.plaintextClass]: this.plaintext, "form-control-icon": !!this.$slots.icon, "is-valid": this.isValid, "is-invalid": this.isInvalid }, this.shadowableClass); }, controlSizeClass() { return d(this.size, this.controlClass); }, formGroupClasses() { return Object.assign({ animated: this.animated, "form-group": this.group, "has-activity": this.activity, "has-changed": this.hasChanged, "has-focus": this.hasFocus, "has-icon": !!this.$slots.icon, "is-dirty": this.isDirty, "is-empty": this.isEmpty, "is-invalid": this.isInvalid, "is-valid": this.isValid, [this.$attrs.class]: !!this.$attrs.class, [this.size && d(this.size, "form-group")]: !!this.size, [this.size && d(this.size, this.componentName)]: !!this.size }, !!this.componentName && { [o(this.componentName)]: !0 }); }, plaintextClass() { return "form-control-plaintext"; } }, created() { this.currentValue = this.$attrs.value, this.isDirty = !p(this.model); }, methods: { bindEvents(t) { for (const e of this.$options.emits) t.addEventListener(e, (s) => { this.$emit(e, s); }); t.addEventListener("focus", () => { this.isDirty = !0, this.hasFocus = !0; }), t.addEventListener("blur", () => { this.hasFocus = !1; }); }, blur() { var t; (t = this.$refs.field) == null || t.blur(); }, focus() { var t; (t = this.$refs.field) == null || t.focus(); }, getFieldErrors() { let t = this.error || this.errors; return this.errors && !Array.isArray(this.errors) && (t = this.errors[this.$attrs.name || this.$attrs.id]), !t || Array.isArray(t) || k(t) ? t : [t]; }, getModelValue() { return this.modelValue === void 0 ? this.currentValue : this.modelValue; }, setModelValue(t) { this.hasChanged = !0, this.currentValue = t, this.$emit("update:modelValue", t); } } }); function h(t, e, s = "-") { const r = String(e).replace(new RegExp(`^${t}${s}?`), ""); return [ o(r), t ].filter((i) => !!i).join(s); } function f(t) { return !Array.isArray(t) && typeof t == "object"; } const N = l({ directives: { bindEvents: { beforeMount(t, e) { var s, r; (r = (s = e.instance) == null ? void 0 : s.bindEvents) == null || r.call(s, t); } } }, mixins: [ m ], inheritAttrs: !1, props: { modelValue: { default: void 0 }, /** * Show type activity indicator. */ activity: { type: Boolean, default: !1 }, /** * Animate floating labels inside the input. */ animated: { type: Boolean, default: () => a("animated", !1) }, /** * An array of event names that correlate with callback functions. */ nativeEvents: { type: Array, default() { return ["focus", "blur", "change", "click", "keypress", "keyup", "keydown", "progress", "paste"]; } }, /** * The default class name assigned to the control element. */ defaultControlClass: { type: String, default: () => a("defaultControlClass", "form-control") }, /** * An inline field validation error. */ error: { type: [String, Array, Boolean], default: void 0 }, /** * An inline field validation errors passed as object with key/value * pairs. If errors passed as an object, the form name will be used for * the key. */ errors: { type: [Array, Object, Boolean], default() { return {}; } }, /** * Some feedback to add to the field once the field is successfully * valid. */ feedback: { type: [String, Array], default: void 0 }, /** * Add form-group wrapper to input. */ group: { type: Boolean, default: () => a("group", !0) }, /** * Some instructions to appear under the field label. */ helpText: { type: [Number, String], default: void 0 }, /** * Hide the label for browsers, but leave it for screen readers. */ hideLabel: Boolean, /** * The activity indicator type. */ indicator: { type: [String, Boolean], default: () => a("indicator", "spinner") }, /** * The activity indicator size. */ indicatorSize: { type: String, default: void 0 }, /** * Display the form field inline. */ inline: Boolean, /** * The invalid property. */ invalid: Boolean, /** * The value of label element. If no value, no label will appear. */ label: { type: [Number, String], default: void 0 }, /** * The default label class assigned to the label element. */ labelClass: { type: [Object, String], default: () => a("labelClass", "form-label") }, /** * Should the control look like a pill. */ pill: Boolean, /** * Should the control look like plaintext. */ plaintext: Boolean, /** * The size of the form control. */ size: { type: String, default: void 0 }, /** * Additional margin/padding classes for fine control of spacing. */ spacing: { type: String, default: void 0 }, /** * The valid property. */ valid: Boolean }, emits: [ "blur", "change", "click", "focus", "keydown", "keypress", "keyup", "update:modelValue" ], data() { return { defaultEmpty: !1, hasChanged: !1, hasFocus: !1, isEmpty: !0 }; }, computed: { id() { return this.$attrs.id || this.$attrs.name || (Math.random() + 1).toString(36).substring(7); }, componentName() { return this.$options.name; }, controlAttributes() { return Object.fromEntries( Object.entries(this.$attrs).concat([ ["id", this.id], ["class", this.controlClasses], ["value", this.modelValue] ]) ); }, controlClass() { return this.defaultControlClass; }, controlSizeClass() { return h(this.size, this.controlClass); }, formGroupClasses() { return Object.assign({ [this.size && h(this.size, this.componentName)]: !!this.size, animated: this.animated, "default-empty": this.defaultEmpty, "form-group": this.group, [this.size && h(this.size, "form-group")]: !!this.size, "has-activity": this.activity, "has-changed": this.hasChanged, "has-focus": this.hasFocus, "has-icon": !!this.$slots.icon, "is-empty": this.isEmpty, "is-invalid": !!(this.invalid || this.invalidFeedback), "is-valid": !!(this.valid || this.validFeedback), [this.$attrs.class]: !!this.$attrs.class, [this.$attrs.id]: !!this.$attrs.id }, !!this.componentName && { [o(this.componentName)]: !0 }); }, controlClasses() { return Object.assign({ [this.controlClass]: !!this.controlClass, [this.controlSizeClass]: !!this.controlSizeClass, "form-control-icon": !!this.$slots.icon, "is-valid": !!(this.valid || this.validFeedback), "is-invalid": !!(this.invalid || this.invalidFeedback), [this.pillClasses]: this.pill, [this.plaintextClass]: this.plaintext, [this.spacing]: !!this.spacing }, this.shadowableClass); }, hasDefaultSlot() { return !!this.$slots.default; }, invalidFeedback() { if (this.error === "") return null; if (this.error) return this.error; const t = this.getFieldErrors(); return Array.isArray(t) ? t.filter((e) => e && typeof e == "string").join("<br>") : t; }, pillClasses() { return "rounded rounded-pill"; }, plaintextClass() { return "form-control-plaintext"; }, validFeedback() { return Array.isArray(this.feedback) ? this.feedback.join("<br>") : this.feedback; } }, watch: { hasFocus() { this.shouldChangeOnFocus() && (this.hasChanged = !0); }, defaultEmpty() { this.hasChanged = !0; } }, methods: { bindEvents(t, e) { var r; e || (e = this.onInput); const s = t instanceof HTMLSelectElement ? (r = t.querySelectorAll("option")) == null ? void 0 : r[t.selectedIndex] : null; s && (t.value = s == null ? void 0 : s.value), t.value && e(t.value), this.hasChanged = !!t.value, this.isEmpty = !t.value, t.addEventListener("focus", () => { this.hasFocus = !0; }), t.addEventListener("blur", () => { this.hasFocus = !1; }), t.addEventListener("input", () => { this.isEmpty = !1, this.hasChanged = !0; }), t.addEventListener( t.tagName === "SELECT" ? "change" : "input", () => e(t.value) ), this.nativeEvents.forEach((i) => { t.addEventListener(i, (c) => { this.$emit(i, c); }); }); }, blur() { this.getInputField() && this.getInputField().blur(); }, focus() { this.getInputField() && this.getInputField().focus(); }, getInputField() { return this.$el.querySelector( ".form-control, input, select, textarea" ); }, getFieldErrors() { let t = this.error || this.errors; return this.errors && f(this.errors) && (t = this.errors[this.$attrs.name || this.$attrs.id]), !t || Array.isArray(t) || f(t) ? t : [t]; }, shouldChangeOnFocus() { return !this.getInputField().readOnly; }, onInput(t) { this.$emit("update:modelValue", t); } } }); export { V as FormControl, j as FormControlErrors, N as FormControlLegacy, a as config }; //# sourceMappingURL=form-control.js.map