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();
|
super();
|
||||||
this.attachShadow({ mode: 'open' });
|
this.attachShadow({ mode: 'open' });
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
this.properties = {
|
||||||
|
color: '#324BFF',
|
||||||
|
};
|
||||||
this.store = new Store();
|
this.store = new Store();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -14,27 +17,101 @@ class AppBase extends HTMLElement {
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderText() {
|
renderOptions() {
|
||||||
const textList = this.store.getRecords();
|
const textList = this.store.getRecords();
|
||||||
return textList.map((item) => `<option value=${item.id}>${item.text}</option>`).join('\n');
|
return textList.map((item) => `<option value=${item.id}>${item.text}</option>`).join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
render(action = 'INITIAL') {
|
render(action = 'INIT') {
|
||||||
if (![Store.actions.ADD_LINE, Store.actions.REMOVE_LINE, Store.actions.UNDO, 'INITIAL'].includes(action)) {
|
if (![Store.actions.ADD_LINE, Store.actions.REMOVE_LINE, Store.actions.UNDO, 'INIT'].includes(action)) {
|
||||||
return; // Only render if content changed
|
return; // Only render if content changed
|
||||||
}
|
}
|
||||||
|
|
||||||
this.shadowRoot.innerHTML = `
|
this.shadowRoot.innerHTML = `
|
||||||
<main-window title="${this.text.title}" description="${this.text.description}">
|
<style>
|
||||||
<select multiple is="item-list">
|
* {
|
||||||
${this.renderText()}
|
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>
|
</select>
|
||||||
<span id="button-bar">
|
<span id="button-bar">
|
||||||
<custom-button action="${Store.actions.REMOVE_LINE}" color="#324bff">Delete</custom-button>
|
<custom-button action="${Store.actions.UNDO}" outline width="81px" color="${this.properties.color}">
|
||||||
<custom-button action="${Store.actions.ADD_LINE}" color="#324bff">Add</custom-button>
|
<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">
|
||||||
<custom-button action="${Store.actions.UNDO}" outline color="#324bff">Undo</custom-button>
|
<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>
|
</span>
|
||||||
</main-window>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import Store from '../modules/store.js';
|
import Store from '../modules/store.js';
|
||||||
|
|
||||||
class CustomButton extends HTMLElement {
|
class CustomButton extends HTMLElement {
|
||||||
static observedAttributes = ['outline', 'color', 'action'];
|
static observedAttributes = ['outline', 'color', 'width', 'action'];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
@ -36,7 +36,7 @@ class CustomButton extends HTMLElement {
|
||||||
border-style: ${isOutline ? 'solid' : 'hidden'};
|
border-style: ${isOutline ? 'solid' : 'hidden'};
|
||||||
border-color: ${this.getAttribute('color')};
|
border-color: ${this.getAttribute('color')};
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
width: 138px;
|
width: ${this.getAttribute('width')};
|
||||||
height: 49px;
|
height: 49px;
|
||||||
background-color: ${isOutline ? 'white' : this.getAttribute('color')};
|
background-color: ${isOutline ? 'white' : this.getAttribute('color')};
|
||||||
color: ${isOutline ? this.getAttribute('color') : 'white'};
|
color: ${isOutline ? this.getAttribute('color') : 'white'};
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class ItemList extends HTMLSelectElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStyle() {
|
updateStyle() {
|
||||||
this.style.width = '800px';
|
this.style.width = '100%';
|
||||||
this.style.height = '227px';
|
this.style.height = '227px';
|
||||||
this.style.background = '#F7F7F7 0% 0% no-repeat padding-box';
|
this.style.background = '#F7F7F7 0% 0% no-repeat padding-box';
|
||||||
this.style.border = '1px solid #CCCCCC';
|
this.style.border = '1px solid #CCCCCC';
|
||||||
|
|
|
||||||
|
|
@ -15,27 +15,23 @@ class MainWindow extends HTMLElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const title = this.getAttribute('title') || "No title";
|
|
||||||
const description = this.getAttribute('description') || "No description";
|
|
||||||
|
|
||||||
this.shadowRoot.innerHTML = `
|
this.shadowRoot.innerHTML = `
|
||||||
<style>
|
<style>
|
||||||
#window {
|
#window {
|
||||||
width: 900px;
|
width: 800px;
|
||||||
height: 577px;
|
height: 477px;
|
||||||
background: #FFFFFF 0% 0% no-repeat padding-box;
|
background: #FFFFFF 0% 0% no-repeat padding-box;
|
||||||
box-shadow: 0px 5px 12px #0000001F;
|
box-shadow: 0px 5px 12px #0000001F;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
padding: 50px;
|
||||||
#content {
|
display: flex
|
||||||
width: 800px;
|
|
||||||
margin: 0 50px 13px 50px;
|
|
||||||
}
|
}
|
||||||
h1 {
|
h1 {
|
||||||
top: 221px;
|
|
||||||
margin: 50px 50px 13px 50px;
|
|
||||||
height: 49px;
|
height: 49px;
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 13px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
font-family: "Montserrat", sans-serif;
|
font-family: "Montserrat", sans-serif;
|
||||||
|
|
@ -45,12 +41,10 @@ class MainWindow extends HTMLElement {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
margin: 0 50px 0 50px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 74px;
|
height: 74px;
|
||||||
|
margin: 0;
|
||||||
/* UI Properties */
|
margin-bottom: 35px;
|
||||||
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-family: "Montserrat", sans-serif;
|
font-family: "Montserrat", sans-serif;
|
||||||
|
|
@ -63,9 +57,7 @@ class MainWindow extends HTMLElement {
|
||||||
<div id="window">
|
<div id="window">
|
||||||
<h1>${title}</h1>
|
<h1>${title}</h1>
|
||||||
<p>${description}</p>
|
<p>${description}</p>
|
||||||
<div id="content" >
|
<slot></slot>
|
||||||
<slot></slot>
|
|
||||||
<div/>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import './components/app-base.js';
|
import './components/app-base.js';
|
||||||
import './components/main-window.js';
|
|
||||||
import './components/custom-button.js';
|
import './components/custom-button.js';
|
||||||
import './components/item-list.js';
|
import './components/item-list.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,13 @@ export default class Store {
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case this.constructor.actions.REMOVE_LINE:
|
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 = {
|
||||||
...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: [],
|
selected: [],
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
@ -85,7 +84,11 @@ export default class Store {
|
||||||
return acc.concat({id: current.id, text: current.text});
|
return acc.concat({id: current.id, text: current.text});
|
||||||
}
|
}
|
||||||
if (current.action === "remove") {
|
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`);
|
console.error(`Action ${current.action} not valid`);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue