UNPKG

jb-number-input

Version:
242 lines (241 loc) 12.7 kB
import { JBInputWebComponent as e } from "jb-input"; import { enToFaDigits as t, faToEnDigits as r } from "jb-core"; import { JBDictionary as n, i18n as a } from "jb-core/i18n"; function o(e) { if (null == e || null == e || 0 == e.trim().length) return !1; { let t = !isNaN(Number(e)); if (!t) { const n = r(e); t = !isNaN(Number(n)); } return t; } } const s = new n({ fa: { numberValidation: "مقدار وارد شده میبایست عدد باشد", increaseValue: "افزایش مقدار", decreaseValue: "کاهش مقدار" }, en: { numberValidation: "Your entered value must be number", increaseValue: "Increase value", decreaseValue: "Decrease value" } }), u = { validator: ({ value: e }) => 0 == e.trim().length || o(e), message: s.get(a, "numberValidation") }; var i = class n extends e { #e = { maxValue: null, minValue: null, decimalPrecision: null, acceptNegative: !0 }; get minValue() { return this.#e.minValue; } set minValue(e) { if (null == e) return void (this.#e.minValue = null); const t = Number(e); Number.isNaN(t) ? console.error("min value is not a valid number") : this.#e.minValue = t; } get maxValue() { return this.#e.maxValue; } set maxValue(e) { if (null == e) return void (this.#e.maxValue = null); const t = Number(e); Number.isNaN(t) ? console.error("max value is not a valid number") : this.#e.maxValue = t; } get decimalPrecision() { return this.#e.decimalPrecision; } set decimalPrecision(e) { if (null == e) return void (this.#e.decimalPrecision = null); const t = Number(e); Number.isNaN(t) ? console.error("decimalPrecision value is not a valid number") : this.#e.decimalPrecision = t; } get acceptNegative() { return this.#e.acceptNegative; } set acceptNegative(e) { this.#e.acceptNegative = Boolean(e); } #t = 1; get step() { return this.#t; } set step(e) { null != e ? Number.isNaN(Number(e)) ? console.error("step must be a number") : this.#t = e : this.#t = null; } #r = !1; get showThousandSeparator() { return this.#r; } set showThousandSeparator(e) { const t = Boolean(e); t !== this.#r && (this.#r = t, this.value = `${this.value}`); } #n = ","; get thousandSeparator() { return this.#n; } set thousandSeparator(e) { this.#n !== e && (this.#n = String(e), this.value = `${this.value}`); } #a = "arabext" == a.locale.numberingSystem; get showPersianNumber() { return this.#a; } set showPersianNumber(e) { this.#a = Boolean(e), this.value = `${this.value}`; } #o = ""; get invalidNumberReplacement() { return this.#o; } set invalidNumberReplacement(e) { this.#o = String(e); } #s = !1; get showControlButton() { return this.#s; } set showControlButton(e) { e != this.#s && (this.#s = e, !0 === e ? this.#u() : !1 === e && this.#i()); } constructor() { super(), this.#l(); } #b() { this.elements.input.addEventListener("beforeinput", this.#c.bind(this)), this.addEventListener("keydown", this.#d.bind(this)); } #l() { const e = document.createElement("template"); e.innerHTML = "<style>.jb-input-web-component{--jb-input-input-direction:var(--input-direction)}.jb-input-web-component .number-control-wrapper .number-control-buttons{cursor:pointer;height:100%;display:flex}.jb-input-web-component .number-control-wrapper .number-control-buttons .number-control-button{all:unset;box-sizing:border-box;cursor:pointer;width:var(--button-width);text-align:center;height:100%}.jb-input-web-component .number-control-wrapper .number-control-buttons .number-control-button:disabled{cursor:default}.jb-input-web-component .number-control-wrapper .number-control-buttons .number-control-button:focus-visible{outline:2px solid var(--jb-number-input-focus-ring-color,Highlight);outline-offset:2px}.jb-input-web-component .number-control-wrapper .number-control-buttons .increase-number-button{background:var(--increase-button-bg);border:var(--increase-button-border);border-radius:var(--increase-button-border-radius);box-sizing:border-box}.jb-input-web-component .number-control-wrapper .number-control-buttons .increase-number-button .increase-icon{stroke:var(--increase-button-color);stroke-width:.875rem;width:100%;height:100%;display:block}.jb-input-web-component .number-control-wrapper .number-control-buttons .increase-number-button:hover .increase-icon{stroke:var(--increase-button-color-hover)}.jb-input-web-component .number-control-wrapper .number-control-buttons .decrease-number-button{border:var(--decrease-button-border);border-radius:var(--decrease-button-border-radius);background:var(--decrease-button-bg);box-sizing:border-box}.jb-input-web-component .number-control-wrapper .number-control-buttons .decrease-number-button .decrease-icon{stroke:var(--decrease-button-color);stroke-width:.875rem;width:100%;height:100%;display:block}.jb-input-web-component .number-control-wrapper .number-control-buttons .decrease-number-button:hover .decrease-icon{stroke:var(--decrease-button-color-hover)} :host{--button-width:var(--jb-number-input-button-width,2.25rem);--increase-button-border-radius:var(--jb-number-input-increase-button-border-radius,0);--decrease-button-border-radius:var(--jb-number-input-decrease-button-border-radius,0);--increase-button-color:var(--jb-number-input-increase-button-color,var(--jb-neutral-7));--increase-button-color-hover:var(--jb-number-input-increase-button-color-hover,oklch(from var(--jb-green) calc(l + .07) calc(c + .07) h));--decrease-button-color:var(--jb-number-input-decrease-button-color,var(--jb-neutral-7));--decrease-button-color-hover:var(--jb-number-input-decrease-button-color-hover,oklch(from var(--jb-red) calc(l + .07) calc(c + .07) h));--increase-button-bg:var(--jb-number-input-increase-button-bg,transparent);--decrease-button-bg:var(--jb-number-input-decrease-button-bg,transparent);--input-direction:var(--jb-number-input-input-direction,ltr);--increase-button-border:var(--jb-number-input-increase-button-border,none);--decrease-button-border:var(--jb-number-input-decrease-button-border,none)}</style>", this.shadowRoot?.appendChild(e.content.cloneNode(!0)), this.validation.addValidationListGetter(this.#m.bind(this)), this.elements.input.inputMode = "numeric", this.numberInputElements = { controlButtons: null }, this.#b(), this.addStandardValueCallback(this.#h.bind(this)); } static get numberInputObservedAttributes() { return [ "thousand-separator", "step", "show-persian-number", "min", "max", "decimal-precision", "accept-negative", "show-control-button" ]; } static get observedAttributes() { return [...e.observedAttributes, ...n.numberInputObservedAttributes]; } attributeChangedCallback(e, t, r) { [...n.numberInputObservedAttributes, "type"].includes(e) ? this.#p(e, r) : (this.onAttributeChange(e, r), "disabled" === e && this.numberInputElements?.controlButtons?.querySelectorAll("button").forEach((e) => { e.disabled = this.disabled; })); } #h(e, n, a, o) { return function(e, n, a, o) { if ("-" == e && 1 == n.acceptNegative) return { displayValue: e, value: "-0" }; let s = e; a.useThousandSeparator && (s = s.replace(new RegExp(`${a.thousandSeparator}`, "g"), "")); const u = "-" == s[0]; s = r(s).replace(/[^0-9.]/g, ""), u && n.acceptNegative && (s = "-" + s); let i = Number(s); isNaN(i) && (s = s.replace(/\u06F0/g, "0").replace(/\u06F1/g, "1").replace(/\u06F2/g, "2").replace(/\u06F3/g, "3").replace(/\u06F4/g, "4").replace(/\u06F5/g, "5").replace(/\u06F6/g, "6").replace(/\u06F7/g, "7").replace(/\u06F8/g, "8").replace(/\u06F9/g, "9"), i = parseFloat(s), isNaN(i) && (s = a.invalidNumberReplacement)), "INPUT" !== o && 0 !== s.length && (null !== n.maxValue && void 0 !== n.maxValue && i > n.maxValue && (i = n.maxValue, s = `${n.maxValue}`), null !== n.minValue && void 0 !== n.minValue && i < n.minValue && (i = n.minValue, s = `${n.minValue}`)), "INPUT" !== o && s.endsWith(".") && (s = s.substring(0, s.length - 1)); const [l, b] = s.split("."), c = b ? b.length : 0; if (n && null !== n.decimalPrecision && null != n.decimalPrecision && c && c > n.decimalPrecision) { const e = new RegExp(`^-?\\d+(?:\\.\\d{0,${n.decimalPrecision}})?`), t = s.match(e); t && t[0] && (s = t[0]); } l.startsWith("0") && l.length > 1 && (s = s.substring(1)), l.startsWith("-") && "0" == l.charAt(1) && l.length > 2 && (s = "-" + s.substring(2)), "INPUT" !== o && b && b.endsWith("0") && (s = s.replace(/(\.\d*?[1-9])0+|\.0+$/, "$1")); const d = { displayValue: s, value: s }; return a.useThousandSeparator && (d.displayValue = s.replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, a.thousandSeparator)), a.showPersianNumber && (d.displayValue = t(d.displayValue)), d; }(e, this.#e, { invalidNumberReplacement: this.#o, thousandSeparator: this.#n, useThousandSeparator: this.showThousandSeparator, showPersianNumber: this.#a }, o); } #p(e, t) { switch (e) { case "thousand-separator": "" == t || "true" == t || "false" == t ? this.showThousandSeparator = "" == t || "true" === t : (this.#r = !0, this.#n = t); break; case "step": this.step = Number(t); break; case "show-persian-number": this.showPersianNumber = "" == t || "true" === t; break; case "min": this.minValue = t; break; case "max": this.maxValue = t; break; case "decimal-precision": this.decimalPrecision = t; break; case "accept-negative": "" != t && "true" != t && "false" != t || (this.acceptNegative = "" == t || "true" === t); break; case "show-control-button": "" != t && "true" != t && "false" != t || (this.showControlButton = "" == t || "true" === t); } } #m() { return [u]; } #v() { const e = new Event("change", { cancelable: !1 }); this.dispatchEvent(e); } #g(e, t) { const r = `${e}`.split(".")[1], n = `${t}`.split(".")[1], a = r ? Math.pow(10, r.length + 1) : 1, o = n ? Math.pow(10, n.length + 1) : 1, s = Math.max(a, o); return (e * s + t * s) / s; } increaseNumber(e = !1) { const t = Number(this.value); if (Number.isNaN(t)) return; const r = this.#t ?? 1, n = this.#g(t, r); this.value = `${n}`, this.validation.checkValidity({ showError: !0 }), e && this.#v(); } decreaseNumber(e = !1) { const t = parseFloat(this.value); if (Number.isNaN(t)) return; const r = this.#t ?? 1; let n = this.#g(t, -1 * r); n < 0 && !this.#e?.acceptNegative && (n = 0), this.value = `${n}`, this.validation.checkValidity({ showError: !0 }), e && this.#v(); } #u() { const e = document.createElement("div"); e.classList.add("number-control-wrapper"), e.innerHTML = `\n <div class="number-control-buttons">\n <button class="increase-number-button number-control-button" type="button" aria-label="${s.get(a, "increaseValue")}">\n <svg class="increase-icon" viewBox="0 0 120 120" aria-hidden="true">\n <path stroke-linecap="round" d="M60,40 L60,80"></path>\n <path stroke-linecap="round" d="M40,60 L80,60"></path>\n </svg>\n </button>\n <button class="decrease-number-button number-control-button" type="button" aria-label="${s.get(a, "decreaseValue")}">\n <svg class="decrease-icon" viewBox="0 0 120 120" aria-hidden="true">\n <path stroke-linecap="round" d="M40,60 L80,60"></path>\n </svg>\n </button>\n </div>\n `, e.querySelectorAll("button").forEach((e) => { e.disabled = this.disabled; }), e.querySelector(".increase-number-button").addEventListener("click", this.increaseNumber.bind(this, !0)), e.querySelector(".decrease-number-button").addEventListener("click", this.decreaseNumber.bind(this, !0)), this.elements.slots.endSection.appendChild(e), this.numberInputElements.controlButtons = e; } #i() { this.numberInputElements.controlButtons && this.numberInputElements.controlButtons.remove(); } #d(e) { const t = e.key; "ArrowUp" == t && (this.increaseNumber(!0), e.preventDefault()), "ArrowDown" == t && (this.decreaseNumber(!0), e.preventDefault()); } #c(e) { const t = e.target.selectionEnd || 0, r = e.target.selectionStart || 0; let n = !1; "deleteContentBackward" === e.inputType || o(e.data) || (n = !0, "." != e.data || 0 === this.#e.decimalPrecision || -1 != this.value.indexOf(".") || 0 == t || 0 == r || null !== this.#e.decimalPrecision && this.value.substring(t).length > this.#e.decimalPrecision || (n = !1), this.#e.acceptNegative && "-" == e.data?.[0] && 0 == r && (n = !1)), n && e.preventDefault(); } }; customElements.get("jb-number-input") || window.customElements.define("jb-number-input", i); export { i as JBNumberInputWebComponent }; //# sourceMappingURL=jb-number-input.js.map