Refactor codebase. Functioning item list

This commit is contained in:
Alex Piqueras 2024-10-10 20:04:31 +02:00
parent a9eaa5dbde
commit 37401a85c8
7 changed files with 46 additions and 82 deletions

View File

@ -8,8 +8,24 @@
<link rel="icon" href="./favicon.ico" type="image/x-icon">
</head>
<body>
<script type="module" src="src/main.js" defer></script>
<main id="root"></main>
<script type="module" src="src/components/app-base.js" defer></script>
<script type="module" src="src/components/main-window.js" defer></script>
<script type="module" src="src/components/custom-button.js" defer></script>
<script type="module" src="src/components/item-list.js" defer></script>
<style>
html {
height: 100%;
}
body {
background: transparent linear-gradient(135deg, #A1C4FD 0%, #C2E9FB 100%) 0% 0% no-repeat padding-box;
opacity: 1;
display: flex;
justify-content: center;
align-items: center;
min-height: 100%;
}
</style>
<app-base></app-base>
</body>
</html>

View File

@ -2,8 +2,6 @@ import Store from '../modules/store.js';
import text from '../modules/text.js';
class AppBase extends HTMLElement {
static observedAttributes = ['title', 'description'];
constructor() {
super();
this.attachShadow({ mode: 'open' });
@ -14,25 +12,18 @@ class AppBase extends HTMLElement {
connectedCallback() {
this.store.subscribe(this.render.bind(this));
this.render();
console.log('Component constructed', this);
}
disconnectedCallback() {
console.log('Component disconnected', this);
}
attributeChangedCallback() {
this.render();
}
renderText() {
const textList = this.store.getRecords();
const selected = this.store.getSelected();
return textList.map((item) => `<option value=${item.id} ${selected.includes(item.id) && "selected"}>${item.text}</option>`).join('\n');
return textList.map((item) => `<option value=${item.id}>${item.text}</option>`).join('\n');
}
render() {
render(action = 'INITIAL') {
if (![Store.actions.ADD_LINE, Store.actions.REMOVE_LINE, Store.actions.UNDO, 'INITIAL'].includes(action)) {
return; // Only render if content changed
}
this.shadowRoot.innerHTML = `
<main-window title="${this.text.title}" description="${this.text.description}">
<select multiple is="item-list">

View File

@ -16,14 +16,10 @@ class CustomButton extends HTMLElement {
connectedCallback() {
this.render();
this.shadowRoot.getElementById('button').addEventListener('click', this.onClick.bind(this));
console.log('Component constructed', this);
}
disconnectedCallback() {
this.shadowRoot.getElementById('button').removeEventListener('click', this.onClick);
console.log('Component disconnected', this);
}
attributeChangedCallback() {
@ -52,7 +48,9 @@ class CustomButton extends HTMLElement {
text-transform: uppercase;
}
</style>
<button id="button"><slot></slot></button>
<button id="button">
<slot></slot>
</button>
`;
}
}

View File

@ -9,23 +9,15 @@ class ItemList extends HTMLSelectElement {
connectedCallback() {
this.addEventListener('click', this.onChange.bind(this));
this.updateStyle();
console.log('Component constructed', this);
}
onChange() {
const selectedIds = Array.from(this.selectedOptions).map((option) => option.value);
const selectedIds = Array.from(this.selectedOptions).map((option) => +option.value);
this.publish(Store.actions.SELECT, selectedIds);
}
disconnectedCallback() {
this.removeEventListener('change', this.onChange.bind(this));
console.log('Component disconnected', this);
}
attributeChangedCallback() {
this.updateStyle();
this.removeEventListener('click', this.onChange.bind(this));
}
updateStyle() {

View File

@ -8,11 +8,6 @@ class MainWindow extends HTMLElement {
connectedCallback() {
this.render();
console.log('Component constructed', this);
}
disconnectedCallback() {
console.log('Component disconnected', this);
}
attributeChangedCallback() {
@ -25,7 +20,7 @@ class MainWindow extends HTMLElement {
this.shadowRoot.innerHTML = `
<style>
div {
#window {
width: 900px;
height: 577px;
background: #FFFFFF 0% 0% no-repeat padding-box;
@ -33,12 +28,10 @@ class MainWindow extends HTMLElement {
border-radius: 20px;
opacity: 1;
}
span {
#content {
width: 800px;
margin: 0 50px 13px 50px;
}
h1 {
top: 221px;
margin: 50px 50px 13px 50px;
@ -66,14 +59,13 @@ class MainWindow extends HTMLElement {
color: #333333;
opacity: 1;
}
slot {
margin: 0 50px 0 50px;
}
</style>
<div>
<div id="window">
<h1>${title}</h1>
<p>${description}</p>
<span><slot></slot></span>
<div id="content" >
<slot></slot>
<div/>
</div>
`;
}

View File

@ -3,32 +3,3 @@ import './components/main-window.js';
import './components/custom-button.js';
import './components/item-list.js';
class App {
constructor(root, text, store) {
this.root = root;
}
start() {
this.root.innerHTML = `
<style>
html {
height: 100%;
}
body {
background: transparent linear-gradient(135deg, #A1C4FD 0%, #C2E9FB 100%) 0% 0% no-repeat padding-box;
opacity: 1;
display: flex;
justify-content: center;
align-items: center;
min-height: 100%;
}
</style>
<app-base></app-base>
`;
}
}
const app = new App(document.getElementById('root'));
app.start();

View File

@ -11,7 +11,7 @@ export default class Store {
records: [],
selected: [],
};
this.callbacks = [];
this.callbacks = [() => console.log(this.state)];
Object.values(this.constructor.actions).forEach(action => document.addEventListener(action, this.eventHandler.bind(this), false));
}
@ -48,12 +48,15 @@ export default class Store {
};
break;
case this.constructor.actions.REMOVE_LINE:
const linesToRemove = this.state.selected.map((id, index) => ({
id: this.state.records.length + index,
targetId: id,
action: 'remove',
}));
this.state = {
...this.state,
records: this.records.concat({
id: this.state.records.length,
action: 'remove',
}),
records: [ ...this.state.records, ...linesToRemove],
selected: [],
};
break;
case this.constructor.actions.UNDO:
@ -73,11 +76,11 @@ export default class Store {
return;
}
this.callbacks.forEach((cb) => cb());
this.callbacks.forEach((cb) => cb(event.type));
}
getRecords() {
return this.state.records.reduce((acc, current) => {
const result = this.state.records.reduce((acc, current) => {
if (current.action === "add") {
return acc.concat({id: current.id, text: current.text});
}
@ -86,6 +89,7 @@ export default class Store {
}
console.error(`Action ${current.action} not valid`);
}, []);
return result;
}
getSelected() {