Modify components to only update the changes
This commit is contained in:
parent
7b3e8498c0
commit
cfc41309ec
17
src/app.js
17
src/app.js
|
|
@ -49,6 +49,7 @@ class AppBase extends HTMLElement {
|
|||
min-height: 100%;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-weight: normal;
|
||||
font-size: 18px;
|
||||
letter-spacing: 0px;
|
||||
}
|
||||
#title {
|
||||
|
|
@ -94,27 +95,27 @@ class AppBase extends HTMLElement {
|
|||
<main-window width="900px" gap="35px">
|
||||
<h1 id="title">${this.text.title}</h1>
|
||||
<p id="description">${this.text.description}</p>
|
||||
<select id="list" multiple is="item-list" height="227px">
|
||||
<select id="list" multiple is="item-list" action="${Store.actions.SELECT}" height="227px">
|
||||
${this.renderOptions()}
|
||||
</select>
|
||||
<span class="button-bar">
|
||||
<custom-button action="${Store.actions.UNDO}" outline width="81px" color="${this.properties.color}">
|
||||
<button is="custom-button" action="${Store.actions.UNDO}" outline width="81px" color="${this.properties.color}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" id="undo-char" width="21" height="19" viewBox="0 0 5.556 5.027">
|
||||
<path d="M.681 2.22a2.38 2.38 0 0 1 4.742.294v0a2.38 2.38 0 0 1-4.526 1.03" style="fill:none;stroke:${this.properties.color};stroke-width:.264583;stroke-linecap:round;stroke-dasharray:none"/>
|
||||
<path d="m.132 1.525.437.964.964-.437" style="fill:none;stroke:${this.properties.color};stroke-width:.264583;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"/>
|
||||
</svg>
|
||||
|
||||
</custom-button>
|
||||
<custom-button action="${Store.actions.REMOVE_LINE}" outline width="124px" color="${this.properties.color}">Delete</custom-button>
|
||||
<custom-button class="right-button" action="${Store.actions.OPEN_MODAL}" width="138px" color="${this.properties.color}">Add</custom-button>
|
||||
</button>
|
||||
<button is="custom-button" action="${Store.actions.REMOVE_LINE}" outline width="124px" color="${this.properties.color}">Delete</button>
|
||||
<button is="custom-button" class="right-button" action="${Store.actions.OPEN_MODAL}" width="138px" color="${this.properties.color}">Add</button>
|
||||
</span>
|
||||
</main-window>
|
||||
<custom-modal active="${this.store.state.modalActive}">
|
||||
<p>${text.modal.description}</p>
|
||||
<input is="custom-text"/>
|
||||
<input is="custom-text" placeholder="${this.text.modal.placeholder}"/>
|
||||
<span class="button-bar">
|
||||
<custom-button class="right-button" action="${Store.actions.ADD_LINE}" width="138px" color="${this.properties.color}">Add</custom-button>
|
||||
<custom-button action="${Store.actions.CLOSE_MODAL}" outline width="124px" color="${this.properties.color}">Cancel</custom-button>
|
||||
<button is="custom-button" class="right-button" action="${Store.actions.ADD_LINE}" width="138px" color="${this.properties.color}">Add</button>
|
||||
<button is="custom-button" action="${Store.actions.CLOSE_MODAL}" outline width="124px" color="${this.properties.color}">Cancel</button>
|
||||
</span>
|
||||
</custom-modal>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,58 +1,66 @@
|
|||
import Store from '../modules/store.js';
|
||||
|
||||
class CustomButton extends HTMLElement {
|
||||
static observedAttributes = ['outline', 'color', 'width', 'action'];
|
||||
class CustomButton extends HTMLButtonElement {
|
||||
static observedAttributes = ['outline', 'color', 'width'];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.publish = Store.publish;
|
||||
this.attachShadow({ mode: 'open' });
|
||||
}
|
||||
|
||||
onClick(e) {
|
||||
this.publish(this.getAttribute('action'));
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
this.shadowRoot.getElementById('button').addEventListener('click', this.onClick.bind(this));
|
||||
this.updateStyle();
|
||||
this.addEventListener('click', this.onClick.bind(this));
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.shadowRoot.getElementById('button').removeEventListener('click', this.onClick);
|
||||
this.removeEventListener('click', this.onClick);
|
||||
}
|
||||
|
||||
attributeChangedCallback() {
|
||||
this.render();
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
|
||||
let isOutline;
|
||||
let color;
|
||||
|
||||
switch (name) {
|
||||
case 'outline':
|
||||
isOutline = (newValue !== null && newValue !== 'false')
|
||||
color = this.getAttribute('color');
|
||||
this.style.backgroundColor = isOutline ? 'white' : color;
|
||||
this.style.color = isOutline ? color : 'white';
|
||||
break;
|
||||
case 'color':
|
||||
isOutline = this.getAttribute('outline') !== null && this.getAttribute('outline') !== 'false';
|
||||
this.style.backgroundColor = isOutline ? 'white' : newValue;
|
||||
this.style.color = isOutline ? newValue : 'white';
|
||||
this.style.borderColor = newValue;
|
||||
break;
|
||||
case 'width':
|
||||
this.style.width = newValue;
|
||||
break;
|
||||
default:
|
||||
console.error(`Unhandled attribute change: ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const isOutline = this.getAttribute('outline') !== null && this.getAttribute('outline') !== 'false';
|
||||
this.shadowRoot.innerHTML = `
|
||||
<style>
|
||||
button {
|
||||
border-radius: 50px;
|
||||
border-width: 1px;
|
||||
border-style: ${isOutline ? 'solid' : 'hidden'};
|
||||
border-color: ${this.getAttribute('color')};
|
||||
opacity: 1;
|
||||
width: ${this.getAttribute('width')};
|
||||
height: 49px;
|
||||
background-color: ${isOutline ? 'white' : this.getAttribute('color')};
|
||||
color: ${isOutline ? this.getAttribute('color') : 'white'};
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-weight: normal
|
||||
letter-spacing: 0px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
<button id="button">
|
||||
<slot></slot>
|
||||
</button>
|
||||
`;
|
||||
updateStyle() {
|
||||
this.style.borderRadius = '50px';
|
||||
this.style.borderWidth = '1px';
|
||||
this.style.borderStyle = 'solid';
|
||||
this.style.opacity = '1';
|
||||
this.style.textAlign = 'center';
|
||||
this.style.fontSize = '16px';
|
||||
this.style.fontFamily = '"Montserrat", sans-serif';
|
||||
this.style.fontWeight = 'normal';
|
||||
this.style.letterSpacing = '0px';
|
||||
this.style.textTransform = 'uppercase';
|
||||
this.style.height = '49px';
|
||||
}
|
||||
|
||||
onClick() {
|
||||
this.publish(this.getAttribute('action'));
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('custom-button', CustomButton);
|
||||
customElements.define('custom-button', CustomButton, { extends: 'button' });
|
||||
|
|
|
|||
|
|
@ -2,26 +2,6 @@ class CustomModal extends HTMLElement {
|
|||
static observedAttributes = ['active'];
|
||||
|
||||
#templateHtml = `
|
||||
<style>
|
||||
div.overlay {
|
||||
position: fixed;
|
||||
margin: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
padding-top: 50px;
|
||||
justify-content: center;
|
||||
background: #0000001A 0% 0% no-repeat padding-box;
|
||||
opacity: 1;
|
||||
transition: all 0.35s ease-in;
|
||||
}
|
||||
mainWindow {
|
||||
top: 25px;
|
||||
transition: all 0.35s ease-in;
|
||||
}
|
||||
</style>
|
||||
<div class="overlay">
|
||||
<main-window width="700px" gap="25px">
|
||||
<slot></slot>
|
||||
|
|
@ -32,12 +12,12 @@ class CustomModal extends HTMLElement {
|
|||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
|
||||
const template = document.createElement('template')
|
||||
template.innerHTML = this.#templateHtml;
|
||||
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
|
||||
this.overlay = this.shadowRoot.querySelector('div.overlay');
|
||||
console.log(this.overlay);
|
||||
this.mainWindow = this.shadowRoot.querySelector('main-window');
|
||||
}
|
||||
|
||||
|
|
@ -45,14 +25,32 @@ class CustomModal extends HTMLElement {
|
|||
this.updateStyle();
|
||||
}
|
||||
|
||||
attributeChangedCallback() {
|
||||
console.log("attributeChanged");
|
||||
this.updateStyle();
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
|
||||
switch (name) {
|
||||
case 'active':
|
||||
this.overlay.style.visibility = newValue === "true" ? 'visible' : 'hidden';
|
||||
break;
|
||||
default:
|
||||
console.error(`Unhandled attribute change: ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
updateStyle() {
|
||||
console.log(this.getAttribute('active'), typeof this.getAttribute('active'));
|
||||
this.overlay.style.visibility = this.getAttribute('active') === "true" ? 'visible' : 'hidden';
|
||||
this.overlay.style.position = 'fixed';
|
||||
this.overlay.style.margin = '0';
|
||||
this.overlay.style.top = '0';
|
||||
this.overlay.style.left = '0';
|
||||
this.overlay.style.right = '0';
|
||||
this.overlay.style.bottom = '0';
|
||||
this.overlay.style.display = 'flex';
|
||||
this.overlay.style.paddingTop = '50px';
|
||||
this.overlay.style.justifyContent = 'center';
|
||||
this.overlay.style.background = '#0000001A 0% 0% no-repeat padding-box';
|
||||
this.overlay.style.opacity = '1';
|
||||
this.overlay.style.transition = 'all 0.35s ease-in';
|
||||
this.mainWindow.style.top = '25px';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,21 @@ class CustomText extends HTMLInputElement {
|
|||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.updateStyle();
|
||||
this.addEventListener('input', this.onInput.bind(this));
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.removeEventListener('input', this.onInput);
|
||||
}
|
||||
|
||||
updateStyle() {
|
||||
this.style.height = '60px';
|
||||
this.style.fontSize = '18px';
|
||||
this.style.fontFamily = 'inherit';
|
||||
this.style.paddingLeft = '21px';
|
||||
}
|
||||
|
||||
onInput() {
|
||||
Store.publish(Store.actions.INPUT_TEXT, this.value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,31 +2,31 @@ import Store from '../modules/store.js';
|
|||
|
||||
class ItemList extends HTMLSelectElement {
|
||||
static observedAttributes = ['height'];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.publish = Store.publish
|
||||
this.publish = Store.publish;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.addEventListener('click', this.onChange.bind(this));
|
||||
this.updateStyle();
|
||||
}
|
||||
|
||||
onChange() {
|
||||
const selectedIds = Array.from(this.selectedOptions).map((option) => +option.value);
|
||||
this.publish(Store.actions.SELECT, selectedIds);
|
||||
this.addEventListener('click', this.onChange.bind(this));
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.removeEventListener('click', this.onChange.bind(this));
|
||||
}
|
||||
|
||||
attributeChangedCallback() {
|
||||
this.updateParametrizedStyle();
|
||||
}
|
||||
|
||||
updateParametrizedStyle() {
|
||||
this.style.height = this.getAttribute('height');
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
|
||||
switch (name) {
|
||||
case 'height':
|
||||
this.style.height = newValue;
|
||||
break;
|
||||
default:
|
||||
console.error(`Unhandled attribute change: ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
updateStyle() {
|
||||
|
|
@ -37,7 +37,11 @@ class ItemList extends HTMLSelectElement {
|
|||
this.style.fontSize = '18px';
|
||||
this.style.padding = '13px';
|
||||
this.style.boxSizing = 'border-box';
|
||||
this.updateParametrizedStyle();
|
||||
}
|
||||
|
||||
onChange() {
|
||||
const selectedIds = Array.from(this.selectedOptions).map((option) => +option.value);
|
||||
this.publish(this.getAttribute('action'), selectedIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,40 +1,50 @@
|
|||
class MainWindow extends HTMLElement {
|
||||
static observedAttributes = ['width', 'gap'];
|
||||
|
||||
#templateHtml = `
|
||||
<div class="window">
|
||||
<slot></slot>
|
||||
</div>
|
||||
`;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = this.#templateHtml;
|
||||
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
|
||||
this.window = this.shadowRoot.querySelector('div.window');
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
this.updateStyle();
|
||||
}
|
||||
|
||||
attributeChangedCallback() {
|
||||
this.render();
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
|
||||
switch (name) {
|
||||
case 'width':
|
||||
this.window.style.width = newValue;
|
||||
break;
|
||||
case 'gap':
|
||||
this.window.style.rowGap = newValue;
|
||||
break;
|
||||
default:
|
||||
console.error(`Unhandled attribute change: ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
this.shadowRoot.innerHTML = `
|
||||
<style>
|
||||
div {
|
||||
width: ${this.getAttribute('width')};
|
||||
box-sizing: border-box;
|
||||
padding: 50px;
|
||||
background: #FFFFFF 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 5px 12px #0000001F;
|
||||
border-radius: 20px;
|
||||
opacity: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: ${this.getAttribute('gap')};
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
`;
|
||||
updateStyle() {
|
||||
this.window.style.boxSizing = 'border-box';
|
||||
this.window.style.padding = '50px';
|
||||
this.window.style.background = '#FFFFFF 0% 0% no-repeat padding-box';
|
||||
this.window.style.boxShadow = '0px 5px 12px #0000001F';
|
||||
this.window.style.borderRadius = '20px';
|
||||
this.window.style.opacity = '1';
|
||||
this.window.style.display = 'flex';
|
||||
this.window.style.flexDirection = 'column';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@ export default {
|
|||
description: 'Lorem ipsum dolor sit amet consectetur adipiscing, elit mus primis nec inceptos. Lacinia habitasse arcu molestie maecenas cursus quam nunc, hendrerit posuere augue fames dictumst placerat porttitor, dis mi pharetra vestibulum venenatis phasellus.',
|
||||
modal: {
|
||||
description: 'Add item to list',
|
||||
placeholder: 'Type the text here...',
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue