import { Component, signal } from '@angular/core';
import { LYNX_ELEMENTS } from '@blotch/angular-lynx';
type Contact = { id: string; name: string };
const PAGE_SIZE = 20;
const makeContacts = (offset: number): Contact[] =>
Array.from({ length: PAGE_SIZE }, (_, i) => ({
id: String(offset + i + 1),
name: `Contact ${offset + i + 1}`,
}));
@Component({
selector: 'app-root',
imports: [LYNX_ELEMENTS],
template: `
<view class="screen">
<text class="status">
{{ contacts().length }} loaded{{ loading() ? ', loading more…' : '' }}
</text>
<list
class="contacts"
list-type="single"
scroll-orientation="vertical"
[attr.lower-threshold-item-count]="5"
(bindscrolltolower)="loadMore()"
>
@for (contact of contacts(); track contact.id) {
<list-item [attr.item-key]="contact.id">
<view class="row">
<text class="name">{{ contact.name }}</text>
</view>
</list-item>
}
</list>
</view>
`,
styles: `
.screen {
display: flex;
flex-direction: column;
height: 100vh;
}
.status {
padding: 12px 16px;
font-size: 13px;
color: #71717a;
}
.contacts {
flex: 1;
}
.row {
padding: 16px;
border-bottom: 1px solid #e4e4e7;
}
.name {
font-size: 16px;
}
`,
})
export class App {
readonly contacts = signal(makeContacts(0));
readonly loading = signal(false);
loadMore(): void {
// The list can report the end again before the last batch arrives.
if (this.loading()) return;
this.loading.set(true);
// Stands in for loading the next batch from a data source.
setTimeout(() => {
this.contacts.update((list) => [...list, ...makeContacts(list.length)]);
this.loading.set(false);
}, 800);
}
}