-
Notifications
You must be signed in to change notification settings - Fork 4
/
lazy-list.js
101 lines (98 loc) · 3.22 KB
/
lazy-list.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { LitElement, html, css } from "lit-element";
import { repeat } from "lit-html/directives/repeat";
import "@vaadin/vaadin-button";
import "j-elements";
import { VisibilityTrigger } from "./visibility-trigger";
import { classMap } from "lit-html/directives/class-map.js";
import "a-avataaar";
class LazyList extends LitElement {
static get properties() {
return {
persons: Array,
loading: Boolean
};
}
static get styles() {
return css`
:host {
overflow-y: auto;
-webkit-overflow-scrolling: touch;
margin: 1em;
}
j-card {
width: 100%;
}
j-card.selected {
background: #daa;
}
j-card [slot="title"] {
align-items: center;
display: flex;
}
`;
}
render() {
return html`
${repeat(
this.persons,
person => person.id,
(person, index) => html`
<j-card class=${classMap(
person.classes ? person.classes : {}
)} @click="${e => this.personSelected(person)}">
<h3 slot="title"><a-avataaar identifier="${person.firstName} ${
person.lastName
}"></a-avataaar>${person.firstName} ${person.lastName}</h3>
<div>${person.company}</div>
<div>${person.address}</div>
<span>${person.zip} ${person.city}</div>
</j-card> `
)}
<vaadin-button id="loadMore" @click="${e => this.loadMore()}">Load more</vaadin-button>
<lazy-loading-indicator ?hidden="${!this.loading}"></lazy-loading-indicator>
`;
}
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties);
document.body.addEventListener("person-selected", async e => {
const person = this.persons.find(p => p.id == e.detail.person.id);
this.persons.forEach(person => {
person.classes = {};
});
person.classes = { selected: true };
this.requestUpdate("persons");
await this.updateComplete;
const selectedElement = this.shadowRoot.querySelector(".selected");
selectedElement.scrollIntoView({ block: "nearest" });
});
const trigger = new VisibilityTrigger();
const loadMore = this.shadowRoot.querySelector("#loadMore");
trigger.connect(loadMore, () => {
this.loadMore();
});
setTimeout(() => {
this.dispatchEvent(new CustomEvent('persons-available', { bubbles: true, detail: { persons: this.persons } }));
}, 100);
}
async loadMore() {
this.loading = true;
const persons = await this.$server.loadPersons(this.persons.length);
this.loading = false;
this.persons.push(...persons);
this.requestUpdate("persons");
this.dispatchEvent(new CustomEvent('persons-available', {bubbles: true, detail: { persons: this.persons }}));
}
personSelected(person) {
this.dispatchEvent(new CustomEvent("person-selected", { bubbles: true, detail: { person: person } }));
}
personUpdated(personData) {
const person = this.persons.find(p => p.id == personData.id);
if (!person) {
return;
}
person.longitude = personData.longitude;
person.latitude = personData.latitude;
this.dispatchEvent(new CustomEvent("person-updated", { bubbles: true, detail: { person: person } }));
}
}
customElements.define("lazy-list", LazyList);