text-field code refactoring
This commit is contained in:
parent
2b82198848
commit
ed7314a948
5
components/dist/copy.js
vendored
5
components/dist/copy.js
vendored
@ -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;
|
||||
|
||||
2
components/dist/copy.min.js
vendored
2
components/dist/copy.min.js
vendored
@ -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)}});
|
||||
156
components/dist/text-field.js
vendored
156
components/dist/text-field.js
vendored
@ -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)
|
||||
}
|
||||
})
|
||||
2
components/dist/text-field.min.js
vendored
2
components/dist/text-field.min.js
vendored
File diff suppressed because one or more lines are too long
@ -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');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user