@bookbox/view-html
Version:
Bookbox view for html
209 lines (208 loc) • 9.53 kB
JavaScript
import { rootBookHeader } from '@bookbox/core';
import { listToHtml } from './model';
const SETTINGS_ICONS = {
contents: '📚',
media: '🖼',
design: '🛠',
};
export function getBookBoxHtmlSettings({ bookData, settingsOptions, layoutOptions, }) {
const { tokens, meta, store } = bookData;
const { viewTumbler = true, viewItems = 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`;
const settingsId = `settings-settings`;
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"`} onclick="let p = bbx.getCurrentPage() || 0; (document.fullscreenElement && document.exitFullscreen ? document.exitFullscreen() : document.querySelector('.book-box').requestFullscreen()).then(() => bbx.gotoKey('page-' + p))"></label>
<input type="checkbox" id="${settingsId}" style="display: none;" class="book-box_layout-settings-settings-tumbler" value="1" />`;
}
export function getBookBoxHtmlSettingsTabs({ bookData, settingsOptions }) {
const getContent = (name, body) => `<div class="book-box_layout-settings-namespace book-box_layout-settings-${name}"">${body}</div>`;
const { custom = {}, design = true, media = true, contents = true } = settingsOptions !== null && settingsOptions !== void 0 ? settingsOptions : {};
const tabs = getTabs([
...(contents
? [
{
tab: SETTINGS_ICONS.contents,
content: getContent('contents', getBookBoxHtmlSettingsContentsContent({ bookData })),
},
]
: []),
...(media
? [
{
tab: SETTINGS_ICONS.media,
content: getContent('media', getBookBoxHtmlSettingsMediaContent({ bookData }, 'settings-tabs_')),
},
]
: []),
...(design
? [
{
tab: SETTINGS_ICONS.design,
content: getContent('design', getBookBoxHtmlSettingsDesignContent({ bookData })),
},
]
: []),
...Object.keys(custom).map(settingsNamespace => {
const { icon, getItems } = custom[settingsNamespace];
const items = getItems({ bookData });
return {
tab: icon,
content: listToHtml(items.map(item => getBookBoxHtmlNavigationItem(Object.assign(Object.assign({}, item), { settingsNamespace })))),
};
}),
], 'settings-tabs');
return tabs;
}
export function getBookBoxHtmlSettingsDesignContent({ bookData }) {
const getThemeItem = (theme, color, name) => `
<div
onclick="bbx.setTheme({theme: '${theme}'})"
class="book-box_layout-settings-design-theme"
>
<div style="background: ${color}"></div>
${name}
</div>`;
const content = `<div style="padding: 0 8px">
<h2>Theme</h2>
<div style="display: flex; gap: 16px; flex-wrap: wrap;">
${getThemeItem('light', 'white', 'Light')}
${getThemeItem('dark', 'var(--book-box-color-label-dark)', 'Dark')}
${getThemeItem('sepia', 'var(--book-box-color-label-sepia)', 'Sepia')}
</div>
</div>`;
return content;
}
export function getBookBoxHtmlSettingsDesign({ bookData }) {
return getNavigationPanel({
settingsNamespace: 'design',
icon: SETTINGS_ICONS.design,
content: getBookBoxHtmlSettingsDesignContent({ bookData }),
});
}
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="bbx.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 getBookBoxHtmlSettingsContentsContent({ bookData }) {
const { tokens, meta, store } = bookData;
const { contents } = meta;
const content = listToHtml(contents.map(getBookBoxHtmlContentHeader));
return content;
}
export function getBookBoxHtmlSettingsContents({ bookData }) {
const content = getBookBoxHtmlSettingsContentsContent({ bookData });
return getNavigationPanel({ content, icon: SETTINGS_ICONS.contents, 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 class="book-box_layout-settings-media-item" onclick="bbx.gotoKey('${key}')"><div>${listToHtml(imgHtml)}</div><div>→</div></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 getBookBoxHtmlSettingsMediaContent({ bookData }, prefix = '') {
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 !== ''), prefix + 'layout-media');
return tabs;
}
export function getBookBoxHtmlSettingsMedia({ bookData }) {
return getNavigationPanel({
settingsNamespace: 'media',
icon: SETTINGS_ICONS.media,
content: getBookBoxHtmlSettingsMediaContent({ bookData }),
});
}
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}"> </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>`;
}