Skip to content

Instantly share code, notes, and snippets.

@markmals
Last active August 18, 2023 02:20
Show Gist options
  • Save markmals/4c68f01fd820aaeb0368867df49ff023 to your computer and use it in GitHub Desktop.
Save markmals/4c68f01fd820aaeb0368867df49ff023 to your computer and use it in GitHub Desktop.
import { subject } from '@webstd/combine';
import type { Publisher } from '@webstd/combine';
import type { Identifiable } from '@webstd/types';
import { element, ReactiveElement, html, environment } from '@webstd/custom-elements';
import { Author } from './author.js'
class Book implements Identifiable {
id = crypto.randomUUID(); // A unique identifier that never changes.
title$ = subject('Sample Book Title');
author$ = subject(new Author());
isAvailable$ = subject(true);
}
class Library {
books$ = subject([new Book(), new Book(), new Book()]);
availableBooksLength$: Publisher<number> = this.books$.map(
books => books.filter(book => book.isAvailable).length
)
}
@element('app-root')
export class RootElement extends ReactiveElement {
#library = new Library();
get template() {
return html`
<std-environment .value=${this.#library}>
<app-library></app-library>
</std-environment>
`;
}
}
@element('app-library')
export class LibraryElement extends ReactiveElement {
@environment(Library) accessor #library: Library;
titleElement!: HTMLHeadingElement
get template() {
return html`
<nav>
<h1 #ref=${el => (this.titleElement = el)}>
Books available: ${this.#library.availableBooksCount$}
</h1>
</nav>
{#for ${this.#library.books$}}
${book => html`<app-book .book=${book}></app-book>`}
{/for}
`;
}
}
@element('app-book')
export class BookElement extends ReactiveElement {
book: Book;
isEditorPresented$ = subject(false);
constructor(book: Book) {
this.book = book;
}
get template() {
return html`
{#if ${this.isEditorPresented$}}
<ui-modal-sheet>
<app-book-edit .book=${this.book}> </app-book-edit>
</ui-modal-sheet>
{/if}
<div class="flex flex-row gap-2">
<span class="mb-auto">
${this.book.title$}
</span>
<button on:click=${() => this.isEditorPresented.send(true)}>
Edit
</button>
</div>
`;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment