diff options
author | Joris | 2023-09-09 13:50:17 +0200 |
---|---|---|
committer | Joris | 2023-09-09 13:50:17 +0200 |
commit | 82429caf3c2886c2d94e09d020e645b06bd4680d (patch) | |
tree | 3183bf0c687c25e17fd36a23ced58fd1e6e29dda /src/view | |
parent | 08a5f3519f29cd486d7fe4c295e5d5c7f031104a (diff) |
Allow to open book detail in modal
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/books.ts | 61 | ||||
-rw-r--r-- | src/view/components/modal.ts | 26 |
2 files changed, 87 insertions, 0 deletions
diff --git a/src/view/books.ts b/src/view/books.ts new file mode 100644 index 0000000..6ea0c12 --- /dev/null +++ b/src/view/books.ts @@ -0,0 +1,61 @@ +import { h, withVar, mount, Html, Rx } from 'lib/rx' +import * as Book from 'book' +import * as Modal from 'view/components/modal' + +export function view(books: Rx<Array<Book.Book>>): Html { + return h('div', + { className: 'g-Books' }, + withVar<Book.Book | undefined>(undefined, (focusBook, updateFocusBook) => [ + focusBook.map(book => book && bookDetailModal({ + book, + onClose: () => updateFocusBook(_ => undefined) + })), + books.map(bs => bs.map(book => viewBook({ + book, + onSelect: (book) => updateFocusBook(_ => book) + }))) + ]) + ) +} + +interface ViewBookParams { + book: Book.Book + onSelect: (book: Book.Book) => void +} + +function viewBook({ book, onSelect }: ViewBookParams): Html { + return h('button', + { className: 'g-Book' }, + h('img', + { src: book.cover, + className: 'g-Book__Image', + onclick: () => onSelect(book) + } + ) + ) +} + +interface BookDetailModalParams { + book: Book.Book + onClose: () => void +} + +function bookDetailModal({ book, onClose }: BookDetailModalParams): Html { + return Modal.view({ + content: h('div', + { className: 'g-BookDetail' }, + h('div', + h('div', { className: 'g-BookDetail__Title' }, `${book.title}, ${book.date}`), + book.subtitle && h('div', { className: 'g-BookDetail__Subtitle' }, book.subtitle), + book.authors.join(', '), + h('div', + { className: 'g-BookDetail__Genres' }, + book.genres.length > 1 ? 'Genres : ' : 'Genre : ', + book.genres.join(', ') + ) + ), + h('img', { src: book.cover }) + ), + onClose + }) +} diff --git a/src/view/components/modal.ts b/src/view/components/modal.ts new file mode 100644 index 0000000..fe08272 --- /dev/null +++ b/src/view/components/modal.ts @@ -0,0 +1,26 @@ +import { h, Html } from 'lib/rx' + +interface Params { + content: Html, + onClose: () => void +} + +export function view({ content, onClose }: Params): Html { + return h('div', + { className: 'g-Modal', + onclick: () => onClose() + }, + h('div', + { className: 'g-Modal__Content', + onclick: (e: Event) => e.stopPropagation() + }, + h('button', + { className: 'g-Modal__Close', + onclick: () => onClose() + }, + '✖' + ), + content + ) + ) +} |