From ed7314a9485ffab3dccddd605a146cfa9cc16d48 Mon Sep 17 00:00:00 2001 From: sairaj mote Date: Wed, 21 Dec 2022 20:34:23 +0530 Subject: [PATCH] text-field code refactoring --- components/dist/copy.js | 5 - components/dist/copy.min.js | 2 +- components/dist/text-field.js | 156 +++++++++++------------------- components/dist/text-field.min.js | 2 +- components/test.html | 3 + 5 files changed, 60 insertions(+), 108 deletions(-) diff --git a/components/dist/copy.js b/components/dist/copy.js index 31b82ec..cb1716a 100644 --- a/components/dist/copy.js +++ b/components/dist/copy.js @@ -48,11 +48,6 @@ smCopy.innerHTML = ` .copy-button:active{ background-color: var(--button-background-color); } -.icon{ - height: 1.2rem; - width: 1.2rem; - fill: rgba(var(--text-color, (17,17,17)), 0.8); -} @media (any-hover: hover){ .copy:hover .copy-button{ opacity: 1; diff --git a/components/dist/copy.min.js b/components/dist/copy.min.js index 0949787..78b4907 100644 --- a/components/dist/copy.min.js +++ b/components/dist/copy.min.js @@ -1 +1 @@ -const smCopy=document.createElement("template");smCopy.innerHTML='\n\n
\n

\n \n
\n',customElements.define("sm-copy",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smCopy.content.cloneNode(!0)),this.copyContent=this.shadowRoot.querySelector(".copy-content"),this.copyButton=this.shadowRoot.querySelector(".copy-button"),this.copy=this.copy.bind(this)}static get observedAttributes(){return["value"]}set value(n){this.setAttribute("value",n)}get value(){return this.getAttribute("value")}fireEvent(){this.dispatchEvent(new CustomEvent("copy",{composed:!0,bubbles:!0,cancelable:!0}))}copy(){navigator.clipboard.writeText(this.copyContent.textContent).then(n=>this.fireEvent()).catch(n=>console.error(n))}connectedCallback(){this.copyButton.addEventListener("click",this.copy)}attributeChangedCallback(n,t,o){"value"===n&&(this.copyContent.textContent=o)}disconnectedCallback(){this.copyButton.removeEventListener("click",this.copy)}}); \ No newline at end of file +const smCopy=document.createElement("template");smCopy.innerHTML='\n\n
\n

\n \n
\n',customElements.define("sm-copy",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smCopy.content.cloneNode(!0)),this.copyContent=this.shadowRoot.querySelector(".copy-content"),this.copyButton=this.shadowRoot.querySelector(".copy-button"),this.copy=this.copy.bind(this)}static get observedAttributes(){return["value"]}set value(t){this.setAttribute("value",t)}get value(){return this.getAttribute("value")}fireEvent(){this.dispatchEvent(new CustomEvent("copy",{composed:!0,bubbles:!0,cancelable:!0}))}copy(){navigator.clipboard.writeText(this.copyContent.textContent).then(t=>this.fireEvent()).catch(t=>console.error(t))}connectedCallback(){this.copyButton.addEventListener("click",this.copy)}attributeChangedCallback(t,n,o){"value"===t&&(this.copyContent.textContent=o)}disconnectedCallback(){this.copyButton.removeEventListener("click",this.copy)}}); \ No newline at end of file diff --git a/components/dist/text-field.js b/components/dist/text-field.js index 0b4330b..013fe60 100644 --- a/components/dist/text-field.js +++ b/components/dist/text-field.js @@ -30,44 +30,41 @@ textField.innerHTML = ` outline: none; background: solid rgba(var(--text-color), 0.06); } - .editable{ - border-bottom: 0.15rem solid rgba(var(--text-color), 0.6); - } - .icon-container{ - position: relative; - margin-left: 0.5rem; - height: 1.8rem; - width: 1.8rem; - } - .icon{ - position: absolute; + .edit-button{ + display: inline-flex; + justify-content: center; cursor: pointer; - fill: none; - stroke-width: 8; - stroke: rgba(var(--text-color), 1); - height: 1.8rem; - width: 1.8rem; + border: none; padding: 0.4rem; - overflow: visible; - stroke-linecap: round; - stroke-linejoin: round; + background-color: rgba(var(--text-color, (17,17,17)), 0.06); + border-radius: var(--button-border-radius, 0.3rem); + transition: background-color 0.2s; + font-family: inherit; + color: inherit; + font-size: 0.7rem; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.05rem; + margin-left: 0.3rem; + } + .edit-button:active{ + background-color: var(--button-background-color); + } + :host([editable]){ + border-bottom: 0.15rem solid rgba(var(--text-color), 0.6); } .hide{ display: none; } + @media (any-hover: hover){ + .edit-button:hover{ + background-color: var(--button-background-color); + } + }
-
- - Edit - - - - Save - - -
+
` @@ -80,11 +77,14 @@ customElements.define('text-field', class extends HTMLElement { this.textField = this.shadowRoot.querySelector('.text-field') this.textContainer = this.textField.children[0] - this.iconsContainer = this.textField.children[1] this.editButton = this.textField.querySelector('.edit-button') - this.saveButton = this.textField.querySelector('.save-button') this.isTextEditable = false this.isDisabled = false + + this.setEditable = this.setEditable.bind(this) + this.setNonEditable = this.setNonEditable.bind(this) + this.toggleEditable = this.toggleEditable.bind(this) + this.revert = this.revert.bind(this) } static get observedAttributes() { @@ -106,54 +106,39 @@ customElements.define('text-field', class extends HTMLElement { else this.removeAttribute('disable') } - fireEvent = (value) => { - let event = new CustomEvent('contentchanged', { - bubbles: true, - cancelable: true, - composed: true, - detail: { - value - } - }); - this.dispatchEvent(event); - } - - setEditable = () => { + setEditable() { if (this.isTextEditable) return this.textContainer.contentEditable = true - this.textContainer.classList.add('editable') + this.setAttribute('editable', '') this.textContainer.focus() document.execCommand('selectAll', false, null); - this.editButton.animate(this.rotateOut, this.animOptions).onfinish = () => { - this.editButton.classList.add('hide') - } - setTimeout(() => { - this.saveButton.classList.remove('hide') - this.saveButton.animate(this.rotateIn, this.animOptions) - }, 100); + this.editButton.textContent = 'Done' this.isTextEditable = true } - setNonEditable = () => { + setNonEditable() { if (!this.isTextEditable) return this.textContainer.contentEditable = false - this.textContainer.classList.remove('editable') + this.removeAttribute('editable') if (this.text !== this.textContainer.textContent.trim()) { this.setAttribute('value', this.textContainer.textContent) this.text = this.textContainer.textContent.trim() - this.fireEvent(this.text) + this.dispatchEvent(new CustomEvent('change', { + bubbles: true, + cancelable: true, + composed: true + })); } - this.saveButton.animate(this.rotateOut, this.animOptions).onfinish = () => { - this.saveButton.classList.add('hide') - } - setTimeout(() => { - this.editButton.classList.remove('hide') - this.editButton.animate(this.rotateIn, this.animOptions) - }, 100); + this.editButton.textContent = 'Edit' this.isTextEditable = false } - - revert = () => { + toggleEditable() { + if (this.isTextEditable) + this.setNonEditable() + else + this.setEditable() + } + revert() { if (this.textContainer.isContentEditable) { this.value = this.text this.setNonEditable() @@ -170,59 +155,28 @@ customElements.define('text-field', class extends HTMLElement { this.isDisabled = true else this.isDisabled = false - - this.rotateOut = [ - { - transform: 'rotate(0)', - opacity: 1 - }, - { - transform: 'rotate(90deg)', - opacity: 0 - }, - ] - this.rotateIn = [ - { - transform: 'rotate(-90deg)', - opacity: 0 - }, - { - transform: 'rotate(0)', - opacity: 1 - }, - ] - this.animOptions = { - duration: 300, - easing: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', - fill: 'forwards' - } if (!this.isDisabled) { - this.iconsContainer.classList.remove('hide') this.textContainer.addEventListener('dblclick', this.setEditable) - this.editButton.addEventListener('click', this.setEditable) - this.saveButton.addEventListener('click', this.setNonEditable) + this.editButton.addEventListener('click', this.toggleEditable) } } attributeChangedCallback(name) { if (name === 'disable') { if (this.hasAttribute('disable')) { - this.iconsContainer.classList.add('hide') + this.editButton.classList.add('hide') this.textContainer.removeEventListener('dblclick', this.setEditable) - this.editButton.removeEventListener('click', this.setEditable) - this.saveButton.removeEventListener('click', this.setNonEditable) + this.editButton.removeEventListener('click', this.toggleEditable) this.revert() } else { - this.iconsContainer.classList.remove('hide') + this.editButton.classList.remove('hide') this.textContainer.addEventListener('dblclick', this.setEditable) - this.editButton.addEventListener('click', this.setEditable) - this.saveButton.addEventListener('click', this.setNonEditable) + this.editButton.addEventListener('click', this.toggleEditable) } } } disconnectedCallback() { this.textContainer.removeEventListener('dblclick', this.setEditable) - this.editButton.removeEventListener('click', this.setEditable) - this.saveButton.removeEventListener('click', this.setNonEditable) + this.editButton.removeEventListener('click', this.toggleEditable) } }) \ No newline at end of file diff --git a/components/dist/text-field.min.js b/components/dist/text-field.min.js index ef77ecc..955bb75 100644 --- a/components/dist/text-field.min.js +++ b/components/dist/text-field.min.js @@ -1 +1 @@ -const textField=document.createElement("template");textField.innerHTML='\n\n
\n
\n \n
\n',customElements.define("text-field",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(textField.content.cloneNode(!0)),this.textField=this.shadowRoot.querySelector(".text-field"),this.textContainer=this.textField.children[0],this.iconsContainer=this.textField.children[1],this.editButton=this.textField.querySelector(".edit-button"),this.isTextEditable=!1,this.isDisabled=!1,this.fireEvent=this.fireEvent.bind(this),this.setEditable=this.setEditable.bind(this),this.setNonEditable=this.setNonEditable.bind(this),this.toggleEditable=this.toggleEditable.bind(this),this.revert=this.revert.bind(this)}static get observedAttributes(){return["disabled","value"]}get value(){return this.text}set value(t){this.setAttribute("value",t)}set disabled(t){this.isDisabled=t,this.isDisabled?this.setAttribute("disabled",""):this.removeAttribute("disabled")}fireEvent(t){let e=new CustomEvent("change",{bubbles:!0,cancelable:!0,composed:!0,detail:{value:t}});this.dispatchEvent(e)}setEditable(){this.isTextEditable||(this.textContainer.contentEditable=!0,this.textContainer.classList.add("editable"),this.textContainer.focus(),document.execCommand("selectAll",!1,null),this.editButton.children[0].animate(this.rotateOut,this.animOptions).onfinish=(()=>{this.editButton.children[0].classList.add("hide")}),setTimeout(()=>{this.editButton.children[1].classList.remove("hide"),this.editButton.children[1].animate(this.rotateIn,this.animOptions)},100),this.isTextEditable=!0)}setNonEditable(){if(!this.isTextEditable)return;this.textContainer.contentEditable=!1,this.textContainer.classList.remove("editable");const t=this.textContainer.textContent.trim();this.text!==t&&""!==t?(this.setAttribute("value",this.textContainer.textContent),this.text=this.textContainer.textContent.trim(),this.fireEvent(this.text)):this.value=this.text,this.editButton.children[1].animate(this.rotateOut,this.animOptions).onfinish=(()=>{this.editButton.children[1].classList.add("hide")}),setTimeout(()=>{this.editButton.children[0].classList.remove("hide"),this.editButton.children[0].animate(this.rotateIn,this.animOptions)},100),this.isTextEditable=!1}toggleEditable(){this.isTextEditable?this.setNonEditable():this.setEditable()}revert(){this.textContainer.isContentEditable&&(this.value=this.text,this.setNonEditable())}connectedCallback(){this.text,this.hasAttribute("value")&&(this.text=this.getAttribute("value"),this.textContainer.textContent=this.text),this.hasAttribute("disabled")?this.isDisabled=!0:this.isDisabled=!1,this.rotateOut=[{transform:"rotate(0)",opacity:1},{transform:"rotate(90deg)",opacity:0}],this.rotateIn=[{transform:"rotate(-90deg)",opacity:0},{transform:"rotate(0)",opacity:1}],this.animOptions={duration:300,easing:"cubic-bezier(0.175, 0.885, 0.32, 1.275)",fill:"forwards"},this.isDisabled||(this.iconsContainer.classList.remove("hide"),this.textContainer.addEventListener("dblclick",this.setEditable),this.editButton.addEventListener("click",this.toggleEditable))}attributeChangedCallback(t,e,i){"disabled"===t?this.hasAttribute("disabled")?(this.textContainer.removeEventListener("dblclick",this.setEditable),this.editButton.removeEventListener("click",this.toggleEditable),this.revert()):(this.textContainer.addEventListener("dblclick",this.setEditable),this.editButton.addEventListener("click",this.toggleEditable)):"value"===t&&(this.text=i,this.textContainer.textContent=i)}disconnectedCallback(){this.textContainer.removeEventListener("dblclick",this.setEditable),this.editButton.removeEventListener("click",this.toggleEditable)}}); \ No newline at end of file +const textField=document.createElement("template");textField.innerHTML='\n\n
\n
\n \n
\n',customElements.define("text-field",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(textField.content.cloneNode(!0)),this.textField=this.shadowRoot.querySelector(".text-field"),this.textContainer=this.textField.children[0],this.editButton=this.textField.querySelector(".edit-button"),this.isTextEditable=!1,this.isDisabled=!1,this.setEditable=this.setEditable.bind(this),this.setNonEditable=this.setNonEditable.bind(this),this.toggleEditable=this.toggleEditable.bind(this),this.revert=this.revert.bind(this)}static get observedAttributes(){return["disable"]}get value(){return this.text}set value(t){this.text=t,this.textContainer.textContent=t,this.setAttribute("value",t)}set disabled(t){this.isDisabled=t,this.isDisabled?this.setAttribute("disable",""):this.removeAttribute("disable")}setEditable(){this.isTextEditable||(this.textContainer.contentEditable=!0,this.setAttribute("editable",""),this.textContainer.focus(),document.execCommand("selectAll",!1,null),this.editButton.textContent="Done",this.isTextEditable=!0)}setNonEditable(){this.isTextEditable&&(this.textContainer.contentEditable=!1,this.removeAttribute("editable"),this.text!==this.textContainer.textContent.trim()&&(this.setAttribute("value",this.textContainer.textContent),this.text=this.textContainer.textContent.trim(),this.dispatchEvent(new CustomEvent("change",{bubbles:!0,cancelable:!0,composed:!0}))),this.editButton.textContent="Edit",this.isTextEditable=!1)}toggleEditable(){this.isTextEditable?this.setNonEditable():this.setEditable()}revert(){this.textContainer.isContentEditable&&(this.value=this.text,this.setNonEditable())}connectedCallback(){this.text,this.hasAttribute("value")&&(this.text=this.getAttribute("value"),this.textContainer.textContent=this.text),this.hasAttribute("disable")?this.isDisabled=!0:this.isDisabled=!1,this.isDisabled||(this.textContainer.addEventListener("dblclick",this.setEditable),this.editButton.addEventListener("click",this.toggleEditable))}attributeChangedCallback(t){"disable"===t&&(this.hasAttribute("disable")?(this.editButton.classList.add("hide"),this.textContainer.removeEventListener("dblclick",this.setEditable),this.editButton.removeEventListener("click",this.toggleEditable),this.revert()):(this.editButton.classList.remove("hide"),this.textContainer.addEventListener("dblclick",this.setEditable),this.editButton.addEventListener("click",this.toggleEditable)))}disconnectedCallback(){this.textContainer.removeEventListener("dblclick",this.setEditable),this.editButton.removeEventListener("click",this.toggleEditable)}}); \ No newline at end of file diff --git a/components/test.html b/components/test.html index af559a4..0a9600c 100644 --- a/components/test.html +++ b/components/test.html @@ -14,6 +14,7 @@ + @@ -48,6 +49,8 @@ +