text-field code refactoring

This commit is contained in:
sairaj mote 2022-12-21 20:34:23 +05:30
parent 2b82198848
commit ed7314a948
5 changed files with 60 additions and 108 deletions

View File

@ -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;

View File

@ -1 +1 @@
const smCopy=document.createElement("template");smCopy.innerHTML='\n<style> \n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n:host{\n display: -webkit-box;\n display: flex;\n --padding: 0;\n --button-background-color: rgba(var(--text-color, (17,17,17)), 0.2);\n}\n.copy{\n display: grid;\n gap: 0.5rem;\n padding: var(--padding);\n align-items: center;\n grid-template-columns: minmax(0, 1fr) auto;\n}\n:host(:not([clip-text])) .copy-content{\n overflow-wrap: break-word;\n word-wrap: break-word;\n}\n:host([clip-text]) .copy-content{\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.copy-button{\n display: inline-flex;\n justify-content: center;\n cursor: pointer;\n border: none;\n padding: 0.4rem;\n background-color: rgba(var(--text-color, (17,17,17)), 0.06);\n border-radius: var(--button-border-radius, 0.3rem);\n transition: background-color 0.2s;\n font-family: inherit;\n color: inherit;\n font-size: 0.7rem;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.05rem;\n}\n.copy-button:active{\n background-color: var(--button-background-color);\n}\n.icon{\n height: 1.2rem;\n width: 1.2rem;\n fill: rgba(var(--text-color, (17,17,17)), 0.8);\n}\n@media (any-hover: hover){\n .copy:hover .copy-button{\n opacity: 1;\n }\n .copy-button:hover{\n background-color: var(--button-background-color);\n }\n}\n</style>\n<section class="copy">\n <p class="copy-content"></p>\n <button part="button" class="copy-button" title="copy">\n <slot name="copy-icon">\n COPY\n </slot>\n </button>\n</section>\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)}});
const smCopy=document.createElement("template");smCopy.innerHTML='\n<style> \n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n:host{\n display: -webkit-box;\n display: flex;\n --padding: 0;\n --button-background-color: rgba(var(--text-color, (17,17,17)), 0.2);\n}\n.copy{\n display: grid;\n gap: 0.5rem;\n padding: var(--padding);\n align-items: center;\n grid-template-columns: minmax(0, 1fr) auto;\n}\n:host(:not([clip-text])) .copy-content{\n overflow-wrap: break-word;\n word-wrap: break-word;\n}\n:host([clip-text]) .copy-content{\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.copy-button{\n display: inline-flex;\n justify-content: center;\n cursor: pointer;\n border: none;\n padding: 0.4rem;\n background-color: rgba(var(--text-color, (17,17,17)), 0.06);\n border-radius: var(--button-border-radius, 0.3rem);\n transition: background-color 0.2s;\n font-family: inherit;\n color: inherit;\n font-size: 0.7rem;\n font-weight: 500;\n text-transform: uppercase;\n letter-spacing: 0.05rem;\n}\n.copy-button:active{\n background-color: var(--button-background-color);\n}\n@media (any-hover: hover){\n .copy:hover .copy-button{\n opacity: 1;\n }\n .copy-button:hover{\n background-color: var(--button-background-color);\n }\n}\n</style>\n<section class="copy">\n <p class="copy-content"></p>\n <button part="button" class="copy-button" title="copy">\n <slot name="copy-icon">\n COPY\n </slot>\n </button>\n</section>\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)}});

View File

@ -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);
}
}
</style>
<div class="text-field">
<div class="text" part="text"></div>
<div class="icon-container">
<svg class="edit-button icon" viewBox="0 0 64 64">
<title>Edit</title>
<path d="M46.73,14.81l7,7,7.65-7.6A7.15,7.15,0,0,0,61.39,4L60.11,2.77a7.23,7.23,0,0,0-10.19,0L3.87,48.57a5,5,0,0,0-1.39,2.6L.53,61.27a1.74,1.74,0,0,0,2,2l10.15-1.94A5.06,5.06,0,0,0,15.34,60L49.6,25.9"/>
</svg>
<svg class="save-button icon hide" viewBox="0 0 64 64">
<title>Save</title>
<polyline points="0.35 31.82 21.45 52.98 63.65 10.66"/>
</svg>
</div>
<button class="edit-button" part="edit-button">Edit</button>
</div>
`
@ -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)
}
})

File diff suppressed because one or more lines are too long

View File

@ -14,6 +14,7 @@
<script src="dist/radio.js"></script>
<script src="dist/input.js"></script>
<script src="dist/textarea.js"></script>
<script src="dist/text-field.js"></script>
<script src="dist/button.js"></script>
<script src="dist/menu.js"></script>
<script src="dist/cube-loader.js"></script>
@ -48,6 +49,8 @@
<input type="text" placeholder="fds">
<button>dsfsd</button>
</sm-popup>
<text-field value="eetur adipisicing elit. Architecto minima maiores autem iusto porro, odit
iure"></text-field>
</body>
<script>
const popup = document.querySelector('sm-popup');