UNPKG

@bookbox/view-html

Version:

Bookbox view for html

195 lines (194 loc) 8.46 kB
import { rootBookHeader } from '@bookbox/core'; import { listToHtml } from './model'; export function getBookBoxHtmlSettings({ bookData, settingsOptions, layoutOptions, }) { const { tokens, meta, store } = bookData; const { viewTumbler = true, design = true, media = true, contents = true, custom = {} } = settingsOptions !== null && settingsOptions !== void 0 ? settingsOptions : {}; const { fullPage = false } = layoutOptions !== null && layoutOptions !== void 0 ? layoutOptions : {}; const viewId = `settings-view`; return ` <input type="checkbox" id="${viewId}" style="display: none;" class="book-box_layout-settings-view-tumbler" value="1" ${fullPage ? 'checked' : ''}/> <label for="${viewId}" class="book-box_layout-settings-item book-box_layout-settings-view" ${viewTumbler ? '' : `style="display:none"`}></label> <div class="book-box_layout-settings"> ${design ? getBookBoxHtmlSettingsDesign({ bookData }) : ''} ${media ? getBookBoxHtmlSettingsMedia({ bookData }) : ''} ${contents ? getBookBoxHtmlSettingsContents({ bookData }) : ''} ${Object.keys(custom) .map(settingsNamespace => { const { icon, getItems } = custom[settingsNamespace]; const items = getItems({ bookData }); return getNavigationPanel({ settingsNamespace, icon, content: listToHtml(items.map(item => getBookBoxHtmlNavigationItem(Object.assign(Object.assign({}, item), { settingsNamespace })))), }); }) .join('\n')} </div> `; } export function getBookBoxHtmlSettingsDesign({ bookData }) { const { tokens, meta, store } = bookData; const { contents } = meta; const themes = ['light', 'dark', 'sepia']; const getThemeItem = (theme, color, name) => ` <div onclick=" document.querySelector('.book-box').classList.add('book-box_theme-${theme}'); ${themes .filter(x => theme !== x) .map(otherTheme => `document.querySelector('.book-box').classList.remove('book-box_theme-${otherTheme}');`) .join('')} localStorage.setItem('book-box-theme', '${theme}') " class="book-box_layout-settings-design-theme" > <div style="background: ${color}"></div> ${name} </div>`; const content = `<div> <h2>Theme</h2> <div style="display: flex; gap: 16px"> ${getThemeItem('light', 'white', 'Light')} ${getThemeItem('dark', 'var(--book-box-color-label-dark)', 'Dark')} ${getThemeItem('sepia', 'var(--book-box-color-label-sepia)', 'Sepia')} </div> </div>`; const panel = getPanel({ prefix: 'settings-design', tumbler: { content: '🛠', classes: ['book-box_layout-settings-item'] }, panel: { content, name: 'Settings', classes: ['book-box_layout-settings-panel'], }, fast: true, }); return `<div class="book-box_layout-settings-design"> ${panel} </div>`; } function getBookBoxHtmlNavigationItem(params) { const { settingsNamespace, key, value, level = 1 } = params; const offset = Math.max(level, 1); const offsetCss = `${offset * 2}ch`; return `<div class="book-box_layout-settings-navigation_item book-box_layout-settings-${settingsNamespace}-item" style="padding-left: ${offsetCss};" data-level="${level}" data-ref-key="${key}" onclick="gotoKey('${key}')" > ${listToHtml(value)} </div>`; } function getBookBoxHtmlContentHeader(item) { const { value, level, key } = item; return getBookBoxHtmlNavigationItem({ settingsNamespace: 'contents', key, value, level }); } function getNavigationPanel(params) { const { settingsNamespace, icon, content } = params; const panel = getPanel({ prefix: `settings-${settingsNamespace}`, tumbler: { content: icon, classes: ['book-box_layout-settings-item'] }, panel: { content, name: settingsNamespace[0].toUpperCase() + settingsNamespace.slice(1), classes: ['book-box_layout-settings-panel'], }, fast: true, }); return `<div class="book-box_layout-settings-namespace book-box_layout-settings-${settingsNamespace}"> ${panel} </div>`; } export function getBookBoxHtmlSettingsContents({ bookData }) { const { tokens, meta, store } = bookData; const { contents } = meta; const content = listToHtml(contents.map(getBookBoxHtmlContentHeader)); return getNavigationPanel({ content, icon: '📚', settingsNamespace: 'contents' }); } function bookBoxHtmlSettingsMediaBlockGetter(mediaMeta, store, type) { return (header) => { var _a; const { key, value } = header; const mediaKeys = (_a = mediaMeta.keysByHeader[key]) !== null && _a !== void 0 ? _a : []; if (mediaKeys.length === 0) { return ''; } const mediaValues = mediaKeys .map(imgKey => [imgKey, store.dataByKeys[imgKey]]) .filter(e => Boolean(e[1])) .map(([key, imgHtml]) => `<div style="overflow: hidden;" onclick="gotoKey('${key}')">${listToHtml(imgHtml)}</div>`); if (mediaValues.length === 0) { return ''; } const mediaList = mediaValues; const mediaListHtml = listToHtml(mediaList); return `<div style="padding: 1rem;"> <div>${listToHtml(value)}</div> <div class="book-box_layout-settings-media-${type}">${mediaListHtml}</div> </div>`; }; } export function getBookBoxHtmlSettingsMedia({ bookData }) { const { meta, store } = bookData; const { contents, media } = meta; const mediaId = `panel-media`; const getImages = bookBoxHtmlSettingsMediaBlockGetter(media.image, store, 'grid'); const getAudio = bookBoxHtmlSettingsMediaBlockGetter(media.audio, store, 'list'); const getVideo = bookBoxHtmlSettingsMediaBlockGetter(media.video, store, 'list'); const headers = [rootBookHeader, ...contents]; const imgContent = listToHtml(headers.map(getImages)); const audioContent = listToHtml(headers.map(getAudio)); const videoContent = listToHtml(headers.map(getVideo)); const tabs = getTabs([ { tab: 'images', content: imgContent }, { tab: 'video', content: videoContent }, { tab: 'audio', content: audioContent }, ].filter(e => e.content !== ''), 'layout-media'); const panel = getPanel({ prefix: 'settings-media', tumbler: { content: '🖼', classes: ['book-box_layout-settings-item'] }, panel: { content: tabs, name: `Media`, classes: ['book-box_layout-settings-panel'], }, }); return `<div class="book-box_layout-settings-media"> ${panel} </div>`; } export function getPanel({ prefix, tumbler, panel, fast, }) { var _a, _b, _c, _d; const id = `${prefix}-panel`; return `<input type="checkbox" id="${id}" class="book-box_layout-panel-tumbler ${fast ? 'book-box_layout-panel-tumbler-fast' : ''} ${((_a = tumbler.inputClasses) !== null && _a !== void 0 ? _a : []).join(' ')}" value="1"/> <label for="${id}" class="${((_b = tumbler.classes) !== null && _b !== void 0 ? _b : []).join(' ')}"> ${tumbler.content} </label> <div class="book-box_layout-panel ${((_c = panel.classes) !== null && _c !== void 0 ? _c : []).join(' ')}"> <label for="${id}">&nbsp;</label> <div class="book-box_layout-panel-content"> <div class="book-box_layout-panel-header"> <div>${(_d = panel.name) !== null && _d !== void 0 ? _d : ''}</div> <label for="${id}" class="book-box_control-close book-box_clickable">×</label> </div> ${panel.content .replace(/<input type="checkbox" id="(\w+|-)+"/g, `<input type="checkbox"`) .replace(/data-layout="top"/g, '')} </div> </div>`; } function getTabs(tabsData, prefix) { const tabList = tabsData.map(({ tab }, i) => { const id = `${prefix}-tab-${i}`; return `<input type="radio" id="${id}" name="tabs-${prefix}" ${i === 0 ? 'checked' : ''}></input><label for="${id}">${tab}</label>`; }); const contentList = tabsData.map(({ content }, i) => { return `<div class="book-box_layout-tabs-content">${content}</div>`; }); return `<div class="book-box_layout-tabs"> ${listToHtml(tabList)} ${listToHtml(contentList)} </div>`; }