From 969e337e9f847876a1059372c16f737b4603bf95 Mon Sep 17 00:00:00 2001 From: sairaj mote Date: Sat, 3 Dec 2022 19:58:44 +0530 Subject: [PATCH] Added search functionality --- css/main.css | 108 ++++++++-- css/main.min.css | 2 +- css/main.scss | 98 +++++++-- index.html | 474 +++++++++++++++++++++++++----------------- scripts/components.js | 3 +- 5 files changed, 443 insertions(+), 242 deletions(-) diff --git a/css/main.css b/css/main.css index e30c3de..b098071 100644 --- a/css/main.css +++ b/css/main.css @@ -2,7 +2,7 @@ padding: 0; margin: 0; box-sizing: border-box; - font-family: "Times New Roman", Times, serif; + font-family: "Roboto", sans-serif; } :root { @@ -52,23 +52,58 @@ button { cursor: pointer; } -input[type=date] { - padding: 1rem 0.8rem; - font-size: inherit; - background-color: rgba(var(--text-color), 0.06); - border: none; - border-radius: 0.3rem; - font-weight: 500; +.wrap-around { + overflow-wrap: break-word; + word-wrap: break-word; + word-break: break-word; + -webkit-hyphens: auto; + hyphens: auto; } -#details { - align-content: flex-start; - padding: 1.5rem; - display: grid; - gap: 1rem; +.observe-empty-state:empty { + display: none; } -#details * { - font-family: "Roboto", sans-serif; + +.observe-empty-state:not(:empty) ~ .empty-state { + display: none; +} + +#home > * { + width: min(100%, 56rem); + margin: 0 auto; +} +#home h1 { + padding: 1rem; + padding-top: 10vmax; + font-size: max(1.8rem, 4vw); + text-align: center; + background: linear-gradient(135deg, #fa00ff, #00e0ff 50%, #fa00ff); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-size: 200%; + animation: gradient 20s ease infinite alternate-reverse; +} +@-webkit-keyframes gradient { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 100% 50%; + } +} +@keyframes gradient { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 100% 50%; + } +} +#home header { + width: 100%; + background-color: rgba(var(--text-color), 0.06); + padding-bottom: 2rem; + margin-bottom: -2rem; } #cert_sec { @@ -76,11 +111,27 @@ input[type=date] { font-family: "intern"; } +#search_certificates { + position: -webkit-sticky; + position: sticky; + top: 1rem; + width: min(24rem, 100% - 2rem); + margin: 0 auto; + --border-radius: 0.5rem; + border-radius: 0.5rem; + --padding: 1rem 1.2rem; + background-color: rgba(var(--foreground-color), 1); + box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.1); + border: solid thin rgba(var(--text-color), 0.2); +} + #issued_cert_list { display: flex; flex-direction: column; gap: 1rem; - padding: 1.5rem; + padding: 1rem; + padding-bottom: 4rem; + margin-top: 1rem; } .cert-card { @@ -93,12 +144,25 @@ input[type=date] { .cert-card h4 { font-size: 1.2rem; } -.cert-card > * { - font-family: "Roboto", sans-serif; +.cert-card p { + font-size: 0.9rem; + color: rgba(var(--text-color), 0.9); } -@media (min-width: 768px) { - #main { - display: grid; - } +#certificate { + display: flex; + align-items: center; + justify-content: center; +} +#certificate * { + font-family: "Times New Roman", Times, serif; +} + +#certificate_svg { + flex-shrink: 0; + background-color: white; +} + +.hidden { + display: none !important; } \ No newline at end of file diff --git a/css/main.min.css b/css/main.min.css index 35c802d..30abf4f 100644 --- a/css/main.min.css +++ b/css/main.min.css @@ -1 +1 @@ -*{padding:0;margin:0;box-sizing:border-box;font-family:"Times New Roman",Times,serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%}body{--accent-color: #3d5afe;--secondary-color: #ffac2e;--text-color: 34, 34, 34;--foreground-color: 252, 253, 255;--background-color: 241, 243, 248;--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: rgb(220, 165, 0);color:rgba(var(--text-color), 1);background-color:rgba(var(--background-color), 1)}body[data-theme=dark]{--accent-color: #92a2ff;--secondary-color: #d60739;--text-color: 200, 200, 200;--foreground-color: 27, 28, 29;--background-color: 21, 22, 22;--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: rgb(255, 213, 5)}body[data-theme=dark] ::-webkit-calendar-picker-indicator{filter:invert(1)}button{padding:1rem;font-size:inherit;background-color:var(--accent-color);border:none;border-radius:.3rem;color:#fff;font-weight:500;cursor:pointer}input[type=date]{padding:1rem .8rem;font-size:inherit;background-color:rgba(var(--text-color), 0.06);border:none;border-radius:.3rem;font-weight:500}#details{align-content:flex-start;padding:1.5rem;display:grid;gap:1rem}#details *{font-family:"Roboto",sans-serif}#cert_sec{padding:1.5rem;font-family:"intern"}#issued_cert_list{display:flex;flex-direction:column;gap:1rem;padding:1.5rem}.cert-card{display:grid;gap:.5rem;padding:1rem;background-color:rgba(var(--text-color), 0.06);border-radius:.5rem}.cert-card h4{font-size:1.2rem}.cert-card>*{font-family:"Roboto",sans-serif}@media(min-width: 768px){#main{display:grid}} \ No newline at end of file +*{padding:0;margin:0;box-sizing:border-box;font-family:"Roboto",sans-serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%}body{--accent-color: #3d5afe;--secondary-color: #ffac2e;--text-color: 34, 34, 34;--foreground-color: 252, 253, 255;--background-color: 241, 243, 248;--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: rgb(220, 165, 0);color:rgba(var(--text-color), 1);background-color:rgba(var(--background-color), 1)}body[data-theme=dark]{--accent-color: #92a2ff;--secondary-color: #d60739;--text-color: 200, 200, 200;--foreground-color: 27, 28, 29;--background-color: 21, 22, 22;--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: rgb(255, 213, 5)}body[data-theme=dark] ::-webkit-calendar-picker-indicator{filter:invert(1)}button{padding:1rem;font-size:inherit;background-color:var(--accent-color);border:none;border-radius:.3rem;color:#fff;font-weight:500;cursor:pointer}.wrap-around{overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;-webkit-hyphens:auto;hyphens:auto}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}#home>*{width:min(100%,56rem);margin:0 auto}#home h1{padding:1rem;padding-top:10vmax;font-size:max(1.8rem,4vw);text-align:center;background:linear-gradient(135deg, #fa00ff, #00e0ff 50%, #fa00ff);-webkit-background-clip:text;-webkit-text-fill-color:rgba(0,0,0,0);background-size:200%;animation:gradient 20s ease infinite alternate-reverse}@-webkit-keyframes gradient{0%{background-position:0% 50%}100%{background-position:100% 50%}}@keyframes gradient{0%{background-position:0% 50%}100%{background-position:100% 50%}}#home header{width:100%;background-color:rgba(var(--text-color), 0.06);padding-bottom:2rem;margin-bottom:-2rem}#cert_sec{padding:1.5rem;font-family:"intern"}#search_certificates{position:-webkit-sticky;position:sticky;top:1rem;width:min(24rem,100% - 2rem);margin:0 auto;--border-radius: 0.5rem;border-radius:.5rem;--padding: 1rem 1.2rem;background-color:rgba(var(--foreground-color), 1);box-shadow:0 .5rem 1.5rem rgba(0,0,0,.1);border:solid thin rgba(var(--text-color), 0.2)}#issued_cert_list{display:flex;flex-direction:column;gap:1rem;padding:1rem;padding-bottom:4rem;margin-top:1rem}.cert-card{display:grid;gap:.5rem;padding:1rem;background-color:rgba(var(--text-color), 0.06);border-radius:.5rem}.cert-card h4{font-size:1.2rem}.cert-card p{font-size:.9rem;color:rgba(var(--text-color), 0.9)}#certificate{display:flex;align-items:center;justify-content:center}#certificate *{font-family:"Times New Roman",Times,serif}#certificate_svg{flex-shrink:0;background-color:#fff}.hidden{display:none !important} \ No newline at end of file diff --git a/css/main.scss b/css/main.scss index 5227f2f..ba82853 100644 --- a/css/main.scss +++ b/css/main.scss @@ -2,7 +2,7 @@ padding: 0; margin: 0; box-sizing: border-box; - font-family: "Times New Roman", Times, serif; + font-family: "Roboto", sans-serif; } :root { @@ -51,32 +51,74 @@ button { font-weight: 500; cursor: pointer; } -input[type="date"] { - padding: 1rem 0.8rem; - font-size: inherit; - background-color: rgba(var(--text-color), 0.06); - border: none; - border-radius: 0.3rem; - font-weight: 500; +.wrap-around { + overflow-wrap: break-word; + word-wrap: break-word; + word-break: break-word; + hyphens: auto; } -#details { - align-content: flex-start; - padding: 1.5rem; - display: grid; - gap: 1rem; - * { - font-family: "Roboto", sans-serif; + +.observe-empty-state:empty { + display: none; +} + +.observe-empty-state:not(:empty) ~ .empty-state { + display: none; +} +#home { + & > * { + width: min(100%, 56rem); + margin: 0 auto; + } + h1 { + padding: 1rem; + padding-top: 10vmax; + font-size: max(1.8rem, 4vw); + text-align: center; + background: linear-gradient(135deg, #fa00ff, #00e0ff 50%, #fa00ff); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-size: 200%; + animation: gradient 20s ease infinite alternate-reverse; + } + @keyframes gradient { + 0% { + background-position: 0% 50%; + } + 100% { + background-position: 100% 50%; + } + } + header { + width: 100%; + background-color: rgba(var(--text-color), 0.06); + padding-bottom: 2rem; + margin-bottom: -2rem; } } #cert_sec { padding: 1.5rem; font-family: "intern"; } +#search_certificates { + position: sticky; + top: 1rem; + width: min(24rem, calc(100% - 2rem)); + margin: 0 auto; + --border-radius: 0.5rem; + border-radius: 0.5rem; + --padding: 1rem 1.2rem; + background-color: rgba(var(--foreground-color), 1); + box-shadow: 0 0.5rem 1.5rem rgba(0 0 0 /0.1); + border: solid thin rgba(var(--text-color), 0.2); +} #issued_cert_list { display: flex; flex-direction: column; gap: 1rem; - padding: 1.5rem; + padding: 1rem; + padding-bottom: 4rem; + margin-top: 1rem; } .cert-card { display: grid; @@ -87,12 +129,26 @@ input[type="date"] { h4 { font-size: 1.2rem; } - & > * { - font-family: "Roboto", sans-serif; + p { + font-size: 0.9rem; + color: rgba(var(--text-color), 0.9); } } +#certificate { + display: flex; + align-items: center; + justify-content: center; + * { + font-family: "Times New Roman", Times, serif; + } +} +#certificate_svg { + flex-shrink: 0; + background-color: white; +} @media (min-width: 768px) { - #main { - display: grid; - } +} + +.hidden { + display: none !important; } diff --git a/index.html b/index.html index 9ec0985..8af336a 100644 --- a/index.html +++ b/index.html @@ -32,123 +32,121 @@ -
- -
-
-
- - - - - - - - - SALOMI SARKAR - - - F7HVKrF68Y6YKE9XXpHhAcxt6MwRLcUD67 - - - FLO ID - - - RanchiMall, a blockchain incorporated entity certifies that - - - 16th Dec 2020 - - - - - - - Scan to verify this certificate - - - - CERTIFICATE TYPE - - - - - - - INTERNSHIP CONTRACT ADDRESS - - - FDaX363r1ooANA9A2erhehhigNTnidq3o4 - - - - - CERTIFICATE ISSUER ADDRESS - - - FFCpiaZi31TpbYw5q5VNk8qJMeDiTLgsrE - - - - - - - - - - - - - - - - - - - - - - - - - - +
+
+

RanchiMall Certificates

+ + + + + - - -
-
- - -
-
+ + +
+

No related certificates issued yet

+
+ + diff --git a/scripts/components.js b/scripts/components.js index b60499e..ae599d7 100644 --- a/scripts/components.js +++ b/scripts/components.js @@ -1,2 +1 @@ -const smInput = document.createElement("template"); smInput.innerHTML = '
', customElements.define("sm-input", class extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(smInput.content.cloneNode(!0)), this.inputParent = this.shadowRoot.querySelector(".input"), this.input = this.shadowRoot.querySelector("input"), this.clearBtn = this.shadowRoot.querySelector(".clear"), this.label = this.shadowRoot.querySelector(".label"), this.feedbackText = this.shadowRoot.querySelector(".feedback-text"), this.outerContainer = this.shadowRoot.querySelector(".outer-container"), this.optionList = this.shadowRoot.querySelector(".datalist"), this._helperText = "", this._errorText = "", this.isRequired = !1, this.datalist = [], this.validationFunction = void 0, this.reflectedAttributes = ["value", "required", "disabled", "type", "inputmode", "readonly", "min", "max", "pattern", "minlength", "maxlength", "step", "list", "autocomplete"], this.reset = this.reset.bind(this), this.clear = this.clear.bind(this), this.focusIn = this.focusIn.bind(this), this.focusOut = this.focusOut.bind(this), this.fireEvent = this.fireEvent.bind(this), this.checkInput = this.checkInput.bind(this), this.allowOnlyNum = this.allowOnlyNum.bind(this), this.vibrate = this.vibrate.bind(this), this.handleOptionClick = this.handleOptionClick.bind(this), this.handleInputNavigation = this.handleInputNavigation.bind(this), this.handleDatalistNavigation = this.handleDatalistNavigation.bind(this), this.handleFocus = this.handleFocus.bind(this), this.handleBlur = this.handleBlur.bind(this) } static get observedAttributes() { return ["value", "placeholder", "required", "disabled", "type", "inputmode", "readonly", "min", "max", "pattern", "minlength", "maxlength", "step", "helper-text", "error-text", "list"] } get value() { return this.input.value } set value(t) { t !== this.input.value && (this.input.value = t, this.checkInput()) } get placeholder() { return this.getAttribute("placeholder") } set placeholder(t) { this.setAttribute("placeholder", t) } get type() { return this.getAttribute("type") } set type(t) { this.setAttribute("type", t) } get validity() { return this.input.validity } get disabled() { return this.hasAttribute("disabled") } set disabled(t) { t ? this.inputParent.classList.add("disabled") : this.inputParent.classList.remove("disabled") } get readOnly() { return this.hasAttribute("readonly") } set readOnly(t) { t ? this.setAttribute("readonly", "") : this.removeAttribute("readonly") } set customValidation(t) { this.validationFunction = t } set errorText(t) { this._errorText = t } set helperText(t) { this._helperText = t } get isValid() { if ("" !== this.input.value) { const t = this.input.checkValidity(); let e = !0; return this.validationFunction && (e = Boolean(this.validationFunction(this.input.value))), t && e ? (this.feedbackText.classList.remove("error"), this.feedbackText.classList.add("success"), this.feedbackText.textContent = "") : this._errorText && (this.feedbackText.classList.add("error"), this.feedbackText.classList.remove("success"), this.feedbackText.innerHTML = `${this._errorText}`), t && e } } reset() { this.value = "" } clear() { this.value = "", this.input.focus(), this.fireEvent() } focusIn() { this.input.focus() } focusOut() { this.input.blur() } fireEvent() { let t = new Event("input", { bubbles: !0, cancelable: !0, composed: !0 }); this.dispatchEvent(t) } searchDatalist(t) { const e = this.datalist.filter(e => e.toLowerCase().includes(t.toLowerCase())); if (e.sort((e, n) => { const i = e.toLowerCase().indexOf(t.toLowerCase()), s = n.toLowerCase().indexOf(t.toLowerCase()); return i - s }), e.length) { if (this.optionList.children.length > e.length) { const t = this.optionList.children.length - e.length; for (let e = 0; e < t; e++)this.optionList.removeChild(this.optionList.lastChild) } e.forEach((t, e) => { if (this.optionList.children[e]) this.optionList.children[e].textContent = t; else { const e = document.createElement("li"); e.textContent = t, e.classList.add("datalist-item"), e.setAttribute("tabindex", "0"), this.optionList.appendChild(e) } }), this.optionList.classList.remove("hidden") } else this.optionList.classList.add("hidden") } checkInput(t) { this.hasAttribute("readonly") || (this.clearBtn.style.visibility = "" !== this.input.value ? "visible" : "hidden"), this.hasAttribute("placeholder") && "" !== this.getAttribute("placeholder").trim() && ("" !== this.input.value ? (this.animate ? this.inputParent.classList.add("animate-placeholder") : this.label.classList.add("hidden"), this.datalist.length && (this.searchTimeout && clearTimeout(this.searchTimeout), this.searchTimeout = setTimeout(() => { this.searchDatalist(this.input.value.trim()) }, 100))) : (this.animate ? this.inputParent.classList.remove("animate-placeholder") : this.label.classList.remove("hidden"), this.feedbackText.textContent = "", this.datalist.length && (this.optionList.innerHTML = "", this.optionList.classList.add("hidden")))) } allowOnlyNum(t) { 1 === t.key.length && (("." !== t.key || !t.target.value.includes(".") && 0 !== t.target.value.length) && ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."].includes(t.key) || t.preventDefault()) } vibrate() { this.outerContainer.animate([{ transform: "translateX(-1rem)" }, { transform: "translateX(1rem)" }, { transform: "translateX(-0.5rem)" }, { transform: "translateX(0.5rem)" }, { transform: "translateX(0)" }], { duration: 300, easing: "ease" }) } handleOptionClick(t) { this.input.value = t.target.textContent, this.optionList.classList.add("hidden"), this.input.focus() } handleInputNavigation(t) { "ArrowDown" === t.key ? (t.preventDefault(), this.optionList.children.length && this.optionList.children[0].focus()) : "ArrowUp" === t.key && (t.preventDefault(), this.optionList.children.length && this.optionList.children[this.optionList.children.length - 1].focus()) } handleDatalistNavigation(t) { "ArrowUp" === t.key ? (t.preventDefault(), this.shadowRoot.activeElement.previousElementSibling ? this.shadowRoot.activeElement.previousElementSibling.focus() : this.input.focus()) : "ArrowDown" === t.key ? (t.preventDefault(), this.shadowRoot.activeElement.nextElementSibling ? this.shadowRoot.activeElement.nextElementSibling.focus() : this.input.focus()) : "Enter" !== t.key && " " !== t.key || (t.preventDefault(), this.input.value = t.target.textContent, this.optionList.classList.add("hidden"), this.input.focus()) } handleFocus(t) { this.datalist.length && this.searchDatalist(this.input.value.trim()) } handleBlur(t) { this.datalist.length && this.optionList.classList.add("hidden") } connectedCallback() { this.animate = this.hasAttribute("animate"), this.setAttribute("role", "textbox"), this.input.addEventListener("input", this.checkInput), this.clearBtn.addEventListener("click", this.clear), this.datalist.length && (this.optionList.addEventListener("click", this.handleOptionClick), this.input.addEventListener("keydown", this.handleInputNavigation), this.optionList.addEventListener("keydown", this.handleDatalistNavigation)), this.input.addEventListener("focusin", this.handleFocus), this.addEventListener("focusout", this.handleBlur) } attributeChangedCallback(t, e, n) { e !== n && (this.reflectedAttributes.includes(t) && (this.hasAttribute(t) ? this.input.setAttribute(t, this.getAttribute(t) ? this.getAttribute(t) : "") : this.input.removeAttribute(t)), "placeholder" === t ? (this.label.textContent = n, this.setAttribute("aria-label", n)) : this.hasAttribute("value") ? this.checkInput() : "type" === t ? this.hasAttribute("type") && "number" === this.getAttribute("type") ? (this.input.setAttribute("inputmode", "decimal"), this.input.addEventListener("keydown", this.allowOnlyNum)) : this.input.removeEventListener("keydown", this.allowOnlyNum) : "helper-text" === t ? this._helperText = this.getAttribute("helper-text") : "error-text" === t ? this._errorText = this.getAttribute("error-text") : "required" === t ? (this.isRequired = this.hasAttribute("required"), this.isRequired ? this.setAttribute("aria-required", "true") : this.setAttribute("aria-required", "false")) : "readonly" === t ? this.hasAttribute("readonly") ? this.inputParent.classList.add("readonly") : this.inputParent.classList.remove("readonly") : "disabled" === t ? this.hasAttribute("disabled") ? this.inputParent.classList.add("disabled") : this.inputParent.classList.remove("disabled") : "list" === t && this.hasAttribute("list") && "" !== this.getAttribute("list").trim() && (this.datalist = this.getAttribute("list").split(","))) } disconnectedCallback() { this.input.removeEventListener("input", this.checkInput), this.clearBtn.removeEventListener("click", this.clear), this.input.removeEventListener("keydown", this.allowOnlyNum), this.optionList.removeEventListener("click", this.handleOptionClick), this.input.removeEventListener("keydown", this.handleInputNavigation), this.optionList.removeEventListener("keydown", this.handleDatalistNavigation), this.input.removeEventListener("focusin", this.handleFocus), this.removeEventListener("focusout", this.handleBlur) } }); -const smTextarea = document.createElement("template"); smTextarea.innerHTML = '', customElements.define("sm-textarea", class extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(smTextarea.content.cloneNode(!0)), this.textarea = this.shadowRoot.querySelector("textarea"), this.textareaBox = this.shadowRoot.querySelector(".textarea"), this.placeholder = this.shadowRoot.querySelector(".placeholder"), this.reflectedAttributes = ["disabled", "required", "readonly", "rows", "minlength", "maxlength"], this.reset = this.reset.bind(this), this.focusIn = this.focusIn.bind(this), this.fireEvent = this.fireEvent.bind(this), this.checkInput = this.checkInput.bind(this) } static get observedAttributes() { return ["disabled", "value", "placeholder", "required", "readonly", "rows", "minlength", "maxlength"] } get value() { return this.textarea.value } set value(e) { this.setAttribute("value", e), this.fireEvent() } get disabled() { return this.hasAttribute("disabled") } set disabled(e) { e ? this.setAttribute("disabled", "") : this.removeAttribute("disabled") } get isValid() { return this.textarea.checkValidity() } reset() { this.setAttribute("value", "") } focusIn() { this.textarea.focus() } fireEvent() { let e = new Event("input", { bubbles: !0, cancelable: !0, composed: !0 }); this.dispatchEvent(e) } checkInput() { this.hasAttribute("placeholder") && "" !== this.getAttribute("placeholder") && ("" !== this.textarea.value ? this.placeholder.classList.add("hide") : this.placeholder.classList.remove("hide")) } connectedCallback() { this.textarea.addEventListener("input", e => { this.textareaBox.dataset.value = this.textarea.value, this.checkInput() }) } attributeChangedCallback(e, t, n) { this.reflectedAttributes.includes(e) ? this.hasAttribute(e) ? this.textarea.setAttribute(e, this.getAttribute(e) ? this.getAttribute(e) : "") : this.textContent.removeAttribute(e) : "placeholder" === e ? this.placeholder.textContent = this.getAttribute("placeholder") : "value" === e && (this.textarea.value = n, this.textareaBox.dataset.value = n, this.checkInput()) } }); +const smInput = document.createElement("template"); smInput.innerHTML = '
', customElements.define("sm-input", class extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(smInput.content.cloneNode(!0)), this.inputParent = this.shadowRoot.querySelector(".input"), this.input = this.shadowRoot.querySelector("input"), this.clearBtn = this.shadowRoot.querySelector(".clear"), this.label = this.shadowRoot.querySelector(".label"), this.feedbackText = this.shadowRoot.querySelector(".feedback-text"), this.outerContainer = this.shadowRoot.querySelector(".outer-container"), this.optionList = this.shadowRoot.querySelector(".datalist"), this._helperText = "", this._errorText = "", this.isRequired = !1, this.datalist = [], this.validationFunction = void 0, this.reflectedAttributes = ["value", "required", "disabled", "type", "inputmode", "readonly", "min", "max", "pattern", "minlength", "maxlength", "step", "list", "autocomplete"], this.reset = this.reset.bind(this), this.clear = this.clear.bind(this), this.focusIn = this.focusIn.bind(this), this.focusOut = this.focusOut.bind(this), this.fireEvent = this.fireEvent.bind(this), this.checkInput = this.checkInput.bind(this), this.allowOnlyNum = this.allowOnlyNum.bind(this), this.vibrate = this.vibrate.bind(this), this.handleOptionClick = this.handleOptionClick.bind(this), this.handleInputNavigation = this.handleInputNavigation.bind(this), this.handleDatalistNavigation = this.handleDatalistNavigation.bind(this), this.handleFocus = this.handleFocus.bind(this), this.handleBlur = this.handleBlur.bind(this) } static get observedAttributes() { return ["value", "placeholder", "required", "disabled", "type", "inputmode", "readonly", "min", "max", "pattern", "minlength", "maxlength", "step", "helper-text", "error-text", "list"] } get value() { return this.input.value } set value(t) { t !== this.input.value && (this.input.value = t, this.checkInput()) } get placeholder() { return this.getAttribute("placeholder") } set placeholder(t) { this.setAttribute("placeholder", t) } get type() { return this.getAttribute("type") } set type(t) { this.setAttribute("type", t) } get validity() { return this.input.validity } get disabled() { return this.hasAttribute("disabled") } set disabled(t) { t ? this.inputParent.classList.add("disabled") : this.inputParent.classList.remove("disabled") } get readOnly() { return this.hasAttribute("readonly") } set readOnly(t) { t ? this.setAttribute("readonly", "") : this.removeAttribute("readonly") } set customValidation(t) { this.validationFunction = t } set errorText(t) { this._errorText = t } set helperText(t) { this._helperText = t } get isValid() { if ("" !== this.input.value) { const t = this.input.checkValidity(); let e = !0; return this.validationFunction && (e = Boolean(this.validationFunction(this.input.value))), t && e ? (this.feedbackText.classList.remove("error"), this.feedbackText.classList.add("success"), this.feedbackText.textContent = "") : this._errorText && (this.feedbackText.classList.add("error"), this.feedbackText.classList.remove("success"), this.feedbackText.innerHTML = `${this._errorText}`), t && e } } reset() { this.value = "" } clear() { this.value = "", this.input.focus(), this.fireEvent() } focusIn() { this.input.focus() } focusOut() { this.input.blur() } fireEvent() { let t = new Event("input", { bubbles: !0, cancelable: !0, composed: !0 }); this.dispatchEvent(t) } searchDatalist(t) { const e = this.datalist.filter(e => e.toLowerCase().includes(t.toLowerCase())); if (e.sort((e, n) => { const i = e.toLowerCase().indexOf(t.toLowerCase()), s = n.toLowerCase().indexOf(t.toLowerCase()); return i - s }), e.length) { if (this.optionList.children.length > e.length) { const t = this.optionList.children.length - e.length; for (let e = 0; e < t; e++)this.optionList.removeChild(this.optionList.lastChild) } e.forEach((t, e) => { if (this.optionList.children[e]) this.optionList.children[e].textContent = t; else { const e = document.createElement("li"); e.textContent = t, e.classList.add("datalist-item"), e.setAttribute("tabindex", "0"), this.optionList.appendChild(e) } }), this.optionList.classList.remove("hidden") } else this.optionList.classList.add("hidden") } checkInput(t) { this.hasAttribute("readonly") || (this.clearBtn.style.visibility = "" !== this.input.value ? "visible" : "hidden"), this.hasAttribute("placeholder") && "" !== this.getAttribute("placeholder").trim() && ("" !== this.input.value ? (this.animate ? this.inputParent.classList.add("animate-placeholder") : this.label.classList.add("hidden"), this.datalist.length && (this.searchTimeout && clearTimeout(this.searchTimeout), this.searchTimeout = setTimeout(() => { this.searchDatalist(this.input.value.trim()) }, 100))) : (this.animate ? this.inputParent.classList.remove("animate-placeholder") : this.label.classList.remove("hidden"), this.feedbackText.textContent = "", this.datalist.length && (this.optionList.innerHTML = "", this.optionList.classList.add("hidden")))) } allowOnlyNum(t) { 1 === t.key.length && (("." !== t.key || !t.target.value.includes(".") && 0 !== t.target.value.length) && ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."].includes(t.key) || t.preventDefault()) } vibrate() { this.outerContainer.animate([{ transform: "translateX(-1rem)" }, { transform: "translateX(1rem)" }, { transform: "translateX(-0.5rem)" }, { transform: "translateX(0.5rem)" }, { transform: "translateX(0)" }], { duration: 300, easing: "ease" }) } handleOptionClick(t) { this.input.value = t.target.textContent, this.optionList.classList.add("hidden"), this.input.focus() } handleInputNavigation(t) { "ArrowDown" === t.key ? (t.preventDefault(), this.optionList.children.length && this.optionList.children[0].focus()) : "ArrowUp" === t.key && (t.preventDefault(), this.optionList.children.length && this.optionList.children[this.optionList.children.length - 1].focus()) } handleDatalistNavigation(t) { "ArrowUp" === t.key ? (t.preventDefault(), this.shadowRoot.activeElement.previousElementSibling ? this.shadowRoot.activeElement.previousElementSibling.focus() : this.input.focus()) : "ArrowDown" === t.key ? (t.preventDefault(), this.shadowRoot.activeElement.nextElementSibling ? this.shadowRoot.activeElement.nextElementSibling.focus() : this.input.focus()) : "Enter" !== t.key && " " !== t.key || (t.preventDefault(), this.input.value = t.target.textContent, this.optionList.classList.add("hidden"), this.input.focus()) } handleFocus(t) { this.datalist.length && this.searchDatalist(this.input.value.trim()) } handleBlur(t) { this.datalist.length && this.optionList.classList.add("hidden") } connectedCallback() { this.animate = this.hasAttribute("animate"), this.setAttribute("role", "textbox"), this.input.addEventListener("input", this.checkInput), this.clearBtn.addEventListener("click", this.clear), this.datalist.length && (this.optionList.addEventListener("click", this.handleOptionClick), this.input.addEventListener("keydown", this.handleInputNavigation), this.optionList.addEventListener("keydown", this.handleDatalistNavigation)), this.input.addEventListener("focusin", this.handleFocus), this.addEventListener("focusout", this.handleBlur) } attributeChangedCallback(t, e, n) { e !== n && (this.reflectedAttributes.includes(t) && (this.hasAttribute(t) ? this.input.setAttribute(t, this.getAttribute(t) ? this.getAttribute(t) : "") : this.input.removeAttribute(t)), "placeholder" === t ? (this.label.textContent = n, this.setAttribute("aria-label", n)) : this.hasAttribute("value") ? this.checkInput() : "type" === t ? this.hasAttribute("type") && "number" === this.getAttribute("type") ? (this.input.setAttribute("inputmode", "decimal"), this.input.addEventListener("keydown", this.allowOnlyNum)) : this.input.removeEventListener("keydown", this.allowOnlyNum) : "helper-text" === t ? this._helperText = this.getAttribute("helper-text") : "error-text" === t ? this._errorText = this.getAttribute("error-text") : "required" === t ? (this.isRequired = this.hasAttribute("required"), this.isRequired ? this.setAttribute("aria-required", "true") : this.setAttribute("aria-required", "false")) : "readonly" === t ? this.hasAttribute("readonly") ? this.inputParent.classList.add("readonly") : this.inputParent.classList.remove("readonly") : "disabled" === t ? this.hasAttribute("disabled") ? this.inputParent.classList.add("disabled") : this.inputParent.classList.remove("disabled") : "list" === t && this.hasAttribute("list") && "" !== this.getAttribute("list").trim() && (this.datalist = this.getAttribute("list").split(","))) } disconnectedCallback() { this.input.removeEventListener("input", this.checkInput), this.clearBtn.removeEventListener("click", this.clear), this.input.removeEventListener("keydown", this.allowOnlyNum), this.optionList.removeEventListener("click", this.handleOptionClick), this.input.removeEventListener("keydown", this.handleInputNavigation), this.optionList.removeEventListener("keydown", this.handleDatalistNavigation), this.input.removeEventListener("focusin", this.handleFocus), this.removeEventListener("focusout", this.handleBlur) } }); \ No newline at end of file