From 82429caf3c2886c2d94e09d020e645b06bd4680d Mon Sep 17 00:00:00 2001 From: Joris Date: Sat, 9 Sep 2023 13:50:17 +0200 Subject: Allow to open book detail in modal --- src/book.ts | 2 +- src/main.ts | 10 +++----- src/view/books.ts | 61 ++++++++++++++++++++++++++++++++++++++++++++ src/view/components/modal.ts | 26 +++++++++++++++++++ 4 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 src/view/books.ts create mode 100644 src/view/components/modal.ts (limited to 'src') diff --git a/src/book.ts b/src/book.ts index a5ddb75..328f8e1 100644 --- a/src/book.ts +++ b/src/book.ts @@ -1,6 +1,6 @@ export interface Book { title: string - subtitle: string + subtitle?: string authors: Array authorsSort: string genres: Array diff --git a/src/main.ts b/src/main.ts index 21bf215..5885871 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,9 @@ -import { h, withVar, mount } from 'lib/rx' +import { h, withVar, mount, Html } from 'lib/rx' import * as Search from 'lib/search' import * as Functions from 'lib/functions' import * as I18n from 'lib/i18n' import * as Filters from 'view/filters' +import * as Books from 'view/books' import * as Book from 'book' // @ts-ignore @@ -34,12 +35,7 @@ mount(withVar({}, (filters, updateFilters) => ), filteredBooks.map(fb => I18n.unit(fb.length, 'livre', 'livres')) ), - h('div', - { className: 'g-Books' }, - filteredBooks.map(fb => - fb.map(book => h('img', { className: 'g-Book', src: book.cover })) - ) - ) + Books.view(filteredBooks) ) ] }) 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>): Html { + return h('div', + { className: 'g-Books' }, + withVar(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 + ) + ) +} -- cgit v1.2.3