diff --git a/src/app.js b/src/app.js index 885c1f0..56c03b9 100644 --- a/src/app.js +++ b/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 {

${this.text.title}

${this.text.description}

- ${this.renderOptions()} - + + +

${text.modal.description}

- + - Add - Cancel + +
`; diff --git a/src/components/custom-button.js b/src/components/custom-button.js index 7c9c637..8269b23 100644 --- a/src/components/custom-button.js +++ b/src/components/custom-button.js @@ -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 = ` - - - `; + 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' }); diff --git a/src/components/custom-modal.js b/src/components/custom-modal.js index 90fdf76..cd3b425 100644 --- a/src/components/custom-modal.js +++ b/src/components/custom-modal.js @@ -2,26 +2,6 @@ class CustomModal extends HTMLElement { static observedAttributes = ['active']; #templateHtml = ` -
@@ -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'; } } diff --git a/src/components/custom-text.js b/src/components/custom-text.js index 2a753b0..3b80de1 100644 --- a/src/components/custom-text.js +++ b/src/components/custom-text.js @@ -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); } diff --git a/src/components/item-list.js b/src/components/item-list.js index e6004fd..e2710a5 100644 --- a/src/components/item-list.js +++ b/src/components/item-list.js @@ -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); } } diff --git a/src/components/main-window.js b/src/components/main-window.js index daa8375..23d1db7 100644 --- a/src/components/main-window.js +++ b/src/components/main-window.js @@ -1,40 +1,50 @@ class MainWindow extends HTMLElement { static observedAttributes = ['width', 'gap']; + #templateHtml = ` +
+ +
+ `; + 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 = ` - -
- -
- `; + 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'; } } diff --git a/src/modules/text.js b/src/modules/text.js index 3748823..948d3c9 100644 --- a/src/modules/text.js +++ b/src/modules/text.js @@ -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...', }, }