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%;
|
min-height: 100%;
|
||||||
font-family: "Montserrat", sans-serif;
|
font-family: "Montserrat", sans-serif;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
font-size: 18px;
|
||||||
letter-spacing: 0px;
|
letter-spacing: 0px;
|
||||||
}
|
}
|
||||||
#title {
|
#title {
|
||||||
|
|
@ -94,27 +95,27 @@ class AppBase extends HTMLElement {
|
||||||
<main-window width="900px" gap="35px">
|
<main-window width="900px" gap="35px">
|
||||||
<h1 id="title">${this.text.title}</h1>
|
<h1 id="title">${this.text.title}</h1>
|
||||||
<p id="description">${this.text.description}</p>
|
<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()}
|
${this.renderOptions()}
|
||||||
</select>
|
</select>
|
||||||
<span class="button-bar">
|
<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">
|
<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.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"/>
|
<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>
|
</svg>
|
||||||
|
|
||||||
</custom-button>
|
</button>
|
||||||
<custom-button action="${Store.actions.REMOVE_LINE}" outline width="124px" color="${this.properties.color}">Delete</custom-button>
|
<button is="custom-button" action="${Store.actions.REMOVE_LINE}" outline width="124px" color="${this.properties.color}">Delete</button>
|
||||||
<custom-button class="right-button" action="${Store.actions.OPEN_MODAL}" width="138px" color="${this.properties.color}">Add</custom-button>
|
<button is="custom-button" class="right-button" action="${Store.actions.OPEN_MODAL}" width="138px" color="${this.properties.color}">Add</button>
|
||||||
</span>
|
</span>
|
||||||
</main-window>
|
</main-window>
|
||||||
<custom-modal active="${this.store.state.modalActive}">
|
<custom-modal active="${this.store.state.modalActive}">
|
||||||
<p>${text.modal.description}</p>
|
<p>${text.modal.description}</p>
|
||||||
<input is="custom-text"/>
|
<input is="custom-text" placeholder="${this.text.modal.placeholder}"/>
|
||||||
<span class="button-bar">
|
<span class="button-bar">
|
||||||
<custom-button class="right-button" action="${Store.actions.ADD_LINE}" width="138px" color="${this.properties.color}">Add</custom-button>
|
<button is="custom-button" class="right-button" action="${Store.actions.ADD_LINE}" width="138px" color="${this.properties.color}">Add</button>
|
||||||
<custom-button action="${Store.actions.CLOSE_MODAL}" outline width="124px" color="${this.properties.color}">Cancel</custom-button>
|
<button is="custom-button" action="${Store.actions.CLOSE_MODAL}" outline width="124px" color="${this.properties.color}">Cancel</button>
|
||||||
</span>
|
</span>
|
||||||
</custom-modal>
|
</custom-modal>
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,66 @@
|
||||||
import Store from '../modules/store.js';
|
import Store from '../modules/store.js';
|
||||||
|
|
||||||
class CustomButton extends HTMLElement {
|
class CustomButton extends HTMLButtonElement {
|
||||||
static observedAttributes = ['outline', 'color', 'width', 'action'];
|
static observedAttributes = ['outline', 'color', 'width'];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.publish = Store.publish;
|
this.publish = Store.publish;
|
||||||
this.attachShadow({ mode: 'open' });
|
|
||||||
}
|
|
||||||
|
|
||||||
onClick(e) {
|
|
||||||
this.publish(this.getAttribute('action'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
this.render();
|
this.updateStyle();
|
||||||
this.shadowRoot.getElementById('button').addEventListener('click', this.onClick.bind(this));
|
this.addEventListener('click', this.onClick.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
this.shadowRoot.getElementById('button').removeEventListener('click', this.onClick);
|
this.removeEventListener('click', this.onClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback() {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
this.render();
|
if (oldValue === newValue) return;
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
let isOutline;
|
||||||
const isOutline = this.getAttribute('outline') !== null && this.getAttribute('outline') !== 'false';
|
let color;
|
||||||
this.shadowRoot.innerHTML = `
|
|
||||||
<style>
|
switch (name) {
|
||||||
button {
|
case 'outline':
|
||||||
border-radius: 50px;
|
isOutline = (newValue !== null && newValue !== 'false')
|
||||||
border-width: 1px;
|
color = this.getAttribute('color');
|
||||||
border-style: ${isOutline ? 'solid' : 'hidden'};
|
this.style.backgroundColor = isOutline ? 'white' : color;
|
||||||
border-color: ${this.getAttribute('color')};
|
this.style.color = isOutline ? color : 'white';
|
||||||
opacity: 1;
|
break;
|
||||||
width: ${this.getAttribute('width')};
|
case 'color':
|
||||||
height: 49px;
|
isOutline = this.getAttribute('outline') !== null && this.getAttribute('outline') !== 'false';
|
||||||
background-color: ${isOutline ? 'white' : this.getAttribute('color')};
|
this.style.backgroundColor = isOutline ? 'white' : newValue;
|
||||||
color: ${isOutline ? this.getAttribute('color') : 'white'};
|
this.style.color = isOutline ? newValue : 'white';
|
||||||
text-align: center;
|
this.style.borderColor = newValue;
|
||||||
font-size: 16px;
|
break;
|
||||||
font-family: "Montserrat", sans-serif;
|
case 'width':
|
||||||
font-weight: normal
|
this.style.width = newValue;
|
||||||
letter-spacing: 0px;
|
break;
|
||||||
text-transform: uppercase;
|
default:
|
||||||
}
|
console.error(`Unhandled attribute change: ${name}`);
|
||||||
</style>
|
|
||||||
<button id="button">
|
|
||||||
<slot></slot>
|
|
||||||
</button>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('custom-button', CustomButton);
|
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, { extends: 'button' });
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,6 @@ class CustomModal extends HTMLElement {
|
||||||
static observedAttributes = ['active'];
|
static observedAttributes = ['active'];
|
||||||
|
|
||||||
#templateHtml = `
|
#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">
|
<div class="overlay">
|
||||||
<main-window width="700px" gap="25px">
|
<main-window width="700px" gap="25px">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
|
@ -32,12 +12,12 @@ class CustomModal extends HTMLElement {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.attachShadow({ mode: 'open' });
|
this.attachShadow({ mode: 'open' });
|
||||||
|
|
||||||
const template = document.createElement('template')
|
const template = document.createElement('template')
|
||||||
template.innerHTML = this.#templateHtml;
|
template.innerHTML = this.#templateHtml;
|
||||||
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
||||||
|
|
||||||
this.overlay = this.shadowRoot.querySelector('div.overlay');
|
this.overlay = this.shadowRoot.querySelector('div.overlay');
|
||||||
console.log(this.overlay);
|
|
||||||
this.mainWindow = this.shadowRoot.querySelector('main-window');
|
this.mainWindow = this.shadowRoot.querySelector('main-window');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,14 +25,32 @@ class CustomModal extends HTMLElement {
|
||||||
this.updateStyle();
|
this.updateStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback() {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
console.log("attributeChanged");
|
if (oldValue === newValue) return;
|
||||||
this.updateStyle();
|
|
||||||
|
switch (name) {
|
||||||
|
case 'active':
|
||||||
|
this.overlay.style.visibility = newValue === "true" ? 'visible' : 'hidden';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`Unhandled attribute change: ${name}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStyle() {
|
updateStyle() {
|
||||||
console.log(this.getAttribute('active'), typeof this.getAttribute('active'));
|
this.overlay.style.position = 'fixed';
|
||||||
this.overlay.style.visibility = this.getAttribute('active') === "true" ? 'visible' : 'hidden';
|
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() {
|
connectedCallback() {
|
||||||
|
this.updateStyle();
|
||||||
this.addEventListener('input', this.onInput.bind(this));
|
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() {
|
onInput() {
|
||||||
Store.publish(Store.actions.INPUT_TEXT, this.value);
|
Store.publish(Store.actions.INPUT_TEXT, this.value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,31 +2,31 @@ import Store from '../modules/store.js';
|
||||||
|
|
||||||
class ItemList extends HTMLSelectElement {
|
class ItemList extends HTMLSelectElement {
|
||||||
static observedAttributes = ['height'];
|
static observedAttributes = ['height'];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.publish = Store.publish
|
this.publish = Store.publish;
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
this.addEventListener('click', this.onChange.bind(this));
|
|
||||||
this.updateStyle();
|
this.updateStyle();
|
||||||
}
|
this.addEventListener('click', this.onChange.bind(this));
|
||||||
|
|
||||||
onChange() {
|
|
||||||
const selectedIds = Array.from(this.selectedOptions).map((option) => +option.value);
|
|
||||||
this.publish(Store.actions.SELECT, selectedIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
this.removeEventListener('click', this.onChange.bind(this));
|
this.removeEventListener('click', this.onChange.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback() {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
this.updateParametrizedStyle();
|
if (oldValue === newValue) return;
|
||||||
}
|
|
||||||
|
|
||||||
updateParametrizedStyle() {
|
switch (name) {
|
||||||
this.style.height = this.getAttribute('height');
|
case 'height':
|
||||||
|
this.style.height = newValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`Unhandled attribute change: ${name}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStyle() {
|
updateStyle() {
|
||||||
|
|
@ -37,7 +37,11 @@ class ItemList extends HTMLSelectElement {
|
||||||
this.style.fontSize = '18px';
|
this.style.fontSize = '18px';
|
||||||
this.style.padding = '13px';
|
this.style.padding = '13px';
|
||||||
this.style.boxSizing = 'border-box';
|
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 {
|
class MainWindow extends HTMLElement {
|
||||||
static observedAttributes = ['width', 'gap'];
|
static observedAttributes = ['width', 'gap'];
|
||||||
|
|
||||||
|
#templateHtml = `
|
||||||
|
<div class="window">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.attachShadow({ mode: 'open' });
|
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() {
|
connectedCallback() {
|
||||||
this.render();
|
this.updateStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeChangedCallback() {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
this.render();
|
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() {
|
updateStyle() {
|
||||||
|
this.window.style.boxSizing = 'border-box';
|
||||||
this.shadowRoot.innerHTML = `
|
this.window.style.padding = '50px';
|
||||||
<style>
|
this.window.style.background = '#FFFFFF 0% 0% no-repeat padding-box';
|
||||||
div {
|
this.window.style.boxShadow = '0px 5px 12px #0000001F';
|
||||||
width: ${this.getAttribute('width')};
|
this.window.style.borderRadius = '20px';
|
||||||
box-sizing: border-box;
|
this.window.style.opacity = '1';
|
||||||
padding: 50px;
|
this.window.style.display = 'flex';
|
||||||
background: #FFFFFF 0% 0% no-repeat padding-box;
|
this.window.style.flexDirection = 'column';
|
||||||
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>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.',
|
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: {
|
modal: {
|
||||||
description: 'Add item to list',
|
description: 'Add item to list',
|
||||||
|
placeholder: 'Type the text here...',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue