Add more styling and changed undo behaviour to work correctly when multiple selection is deleted
This commit is contained in:
parent
37401a85c8
commit
1749249c1c
|
|
@ -6,6 +6,9 @@ class AppBase extends HTMLElement {
|
|||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
this.text = text;
|
||||
this.properties = {
|
||||
color: '#324BFF',
|
||||
};
|
||||
this.store = new Store();
|
||||
}
|
||||
|
||||
|
|
@ -14,27 +17,101 @@ class AppBase extends HTMLElement {
|
|||
this.render();
|
||||
}
|
||||
|
||||
renderText() {
|
||||
renderOptions() {
|
||||
const textList = this.store.getRecords();
|
||||
return textList.map((item) => `<option value=${item.id}>${item.text}</option>`).join('\n');
|
||||
}
|
||||
|
||||
render(action = 'INITIAL') {
|
||||
if (![Store.actions.ADD_LINE, Store.actions.REMOVE_LINE, Store.actions.UNDO, 'INITIAL'].includes(action)) {
|
||||
render(action = 'INIT') {
|
||||
if (![Store.actions.ADD_LINE, Store.actions.REMOVE_LINE, Store.actions.UNDO, 'INIT'].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">
|
||||
${this.renderText()}
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
}
|
||||
#window {
|
||||
width: 800px;
|
||||
height: 477px;
|
||||
background: #FFFFFF 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 5px 12px #0000001F;
|
||||
border-radius: 20px;
|
||||
opacity: 1;
|
||||
padding: 50px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 35px;
|
||||
}
|
||||
#title {
|
||||
height: 49px;;
|
||||
margin-bottom: -12px;
|
||||
text-align: center;
|
||||
font-size: 40px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-weight: normal;
|
||||
letter-spacing: 0px;
|
||||
color: #333333;
|
||||
opacity: 1;
|
||||
}
|
||||
#description {
|
||||
text-align: center;
|
||||
height: 74px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-weight: normal;
|
||||
letter-spacing: 0px;
|
||||
color: #333333;
|
||||
opacity: 1;
|
||||
}
|
||||
#list {
|
||||
padding: 13px;
|
||||
}
|
||||
#list > option {
|
||||
height: 40px;
|
||||
align-content: center;
|
||||
padding-left: 15px;
|
||||
font-size: 18px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
font-weight: normal;
|
||||
}
|
||||
#list > option:checked {
|
||||
background: ${this.properties.color} linear-gradient(0deg, ${this.properties.color} 0%, ${this.properties.color} 100%);
|
||||
box-shadow: 0 0 10px 100px ${this.properties.color} inset;
|
||||
color: #fff;
|
||||
outline: none;
|
||||
}
|
||||
#button-bar {
|
||||
display: flex;
|
||||
column-gap: 35px
|
||||
}
|
||||
#button-bar > custom-button:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
#undo-char {
|
||||
margin-top: 3px;
|
||||
}
|
||||
</style>
|
||||
<div id="window">
|
||||
<h1 id="title">${this.text.title}</h1>
|
||||
<p id="description">${this.text.description}</p>
|
||||
<select id="list" multiple is="item-list">
|
||||
${this.renderOptions()}
|
||||
</select>
|
||||
<span id="button-bar">
|
||||
<custom-button action="${Store.actions.REMOVE_LINE}" color="#324bff">Delete</custom-button>
|
||||
<custom-button action="${Store.actions.ADD_LINE}" color="#324bff">Add</custom-button>
|
||||
<custom-button action="${Store.actions.UNDO}" outline color="#324bff">Undo</custom-button>
|
||||
<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 action="${Store.actions.ADD_LINE}" width="138px" color="${this.properties.color}">Add</custom-button>
|
||||
</span>
|
||||
</main-window>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import Store from '../modules/store.js';
|
||||
|
||||
class CustomButton extends HTMLElement {
|
||||
static observedAttributes = ['outline', 'color', 'action'];
|
||||
static observedAttributes = ['outline', 'color', 'width', 'action'];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
|
@ -36,7 +36,7 @@ class CustomButton extends HTMLElement {
|
|||
border-style: ${isOutline ? 'solid' : 'hidden'};
|
||||
border-color: ${this.getAttribute('color')};
|
||||
opacity: 1;
|
||||
width: 138px;
|
||||
width: ${this.getAttribute('width')};
|
||||
height: 49px;
|
||||
background-color: ${isOutline ? 'white' : this.getAttribute('color')};
|
||||
color: ${isOutline ? this.getAttribute('color') : 'white'};
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class ItemList extends HTMLSelectElement {
|
|||
}
|
||||
|
||||
updateStyle() {
|
||||
this.style.width = '800px';
|
||||
this.style.width = '100%';
|
||||
this.style.height = '227px';
|
||||
this.style.background = '#F7F7F7 0% 0% no-repeat padding-box';
|
||||
this.style.border = '1px solid #CCCCCC';
|
||||
|
|
|
|||
|
|
@ -15,27 +15,23 @@ class MainWindow extends HTMLElement {
|
|||
}
|
||||
|
||||
render() {
|
||||
const title = this.getAttribute('title') || "No title";
|
||||
const description = this.getAttribute('description') || "No description";
|
||||
|
||||
this.shadowRoot.innerHTML = `
|
||||
<style>
|
||||
#window {
|
||||
width: 900px;
|
||||
height: 577px;
|
||||
width: 800px;
|
||||
height: 477px;
|
||||
background: #FFFFFF 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 5px 12px #0000001F;
|
||||
border-radius: 20px;
|
||||
opacity: 1;
|
||||
}
|
||||
#content {
|
||||
width: 800px;
|
||||
margin: 0 50px 13px 50px;
|
||||
padding: 50px;
|
||||
display: flex
|
||||
}
|
||||
h1 {
|
||||
top: 221px;
|
||||
margin: 50px 50px 13px 50px;
|
||||
height: 49px;
|
||||
margin: 0;
|
||||
margin-bottom: 13px;
|
||||
text-align: center;
|
||||
font-size: 40px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
|
|
@ -45,12 +41,10 @@ class MainWindow extends HTMLElement {
|
|||
opacity: 1;
|
||||
}
|
||||
p {
|
||||
margin: 0 50px 0 50px;
|
||||
text-align: center;
|
||||
height: 74px;
|
||||
|
||||
/* UI Properties */
|
||||
|
||||
margin: 0;
|
||||
margin-bottom: 35px;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
|
|
@ -63,9 +57,7 @@ class MainWindow extends HTMLElement {
|
|||
<div id="window">
|
||||
<h1>${title}</h1>
|
||||
<p>${description}</p>
|
||||
<div id="content" >
|
||||
<slot></slot>
|
||||
<div/>
|
||||
<slot></slot>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import './components/app-base.js';
|
||||
import './components/main-window.js';
|
||||
import './components/custom-button.js';
|
||||
import './components/item-list.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -48,14 +48,13 @@ 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.state.records, ...linesToRemove],
|
||||
records: [ ...this.state.records, {
|
||||
id: this.state.records.length,
|
||||
targetIds: this.state.selected,
|
||||
action: 'remove',
|
||||
}],
|
||||
selected: [],
|
||||
};
|
||||
break;
|
||||
|
|
@ -85,7 +84,11 @@ export default class Store {
|
|||
return acc.concat({id: current.id, text: current.text});
|
||||
}
|
||||
if (current.action === "remove") {
|
||||
return acc.filter((item) => item.id !== current.targetId);
|
||||
let temp = acc;
|
||||
for (const id of current.targetIds) {
|
||||
temp = temp.filter((item) => item.id !== id);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
console.error(`Action ${current.action} not valid`);
|
||||
}, []);
|
||||
|
|
|
|||
Loading…
Reference in New Issue