@discoveryjs/discovery
Version:
Frontend framework for rapid data (JSON) analysis, shareable serverless reports and dashboards
124 lines (101 loc) • 3.66 kB
JavaScript
/* eslint-env browser */
import usage from './tabs.usage.js';
const props = `undefined | {
name,
value,
tabs,
tabConfig,
content,
beforeTabs,
afterTabs,
onInit,
onChange
} | overrideProps() | {
...,
name is string ?: 'filter',
value: value is not undefined ? value :
name is string and name in #.context ? #.context[name]
}`;
export default function(host) {
host.view.define('tabs', function(el, config, data, context) {
async function renderContent(value) {
const handler = inited ? onChange : onInit;
if (currentValue === value) {
return;
}
const renderContext = beforeTabs || afterTabs || content
? { ...context, [name]: value }
: null;
currentValue = value;
inited = true;
if (Array.isArray(tabs)) {
tabsEl.innerHTML = '';
if (beforeTabs) {
beforeTabsEl.innerHTML = '';
await host.view.render(beforeTabsEl, beforeTabs, data, renderContext);
tabsEl.appendChild(beforeTabsEl);
}
await Promise.all(tabs.map(tab =>
host.view.render(tabsEl, host.view.composeConfig(tab, {
active: tab.value === currentValue
}), data, context)
));
if (afterTabs) {
afterTabsEl.innerHTML = '';
await host.view.render(afterTabsEl, afterTabs, data, renderContext);
tabsEl.appendChild(afterTabsEl);
}
}
if (content) {
contentEl.innerHTML = '';
await host.view.render(contentEl, content, data, renderContext);
}
if (typeof handler === 'function') {
handler(currentValue, name, data, context);
}
}
const { content, beforeTabs, afterTabs, onInit, onChange } = config;
let { name, value: initValue, tabs, tabConfig } = config;
const tabsEl = el.appendChild(document.createElement('div'));
let contentEl = null;
let beforeTabsEl = null;
let afterTabsEl = null;
let inited = false;
let currentValue = NaN;
tabConfig = host.view.composeConfig({
view: 'tab',
onClick: renderContent
}, tabConfig);
tabsEl.className = 'view-tabs-buttons';
if (beforeTabs) {
beforeTabsEl = document.createElement('div');
beforeTabsEl.className = 'view-tabs-buttons-before';
}
if (afterTabs) {
afterTabsEl = document.createElement('div');
afterTabsEl.className = 'view-tabs-buttons-after';
}
if (content) {
contentEl = el.appendChild(document.createElement('div'));
contentEl.className = 'view-tabs-content';
}
if (Array.isArray(tabs)) {
tabs = tabs.map(tab => {
const type = typeof tab;
if (type === 'string' || type === 'number' || type === 'boolean') {
tab = { value: tab };
}
if (initValue === undefined || tab.active) {
initValue = tab.value;
}
return host.view.composeConfig(
tabConfig,
tab
);
});
} else {
tabs = [];
}
return renderContent(initValue);
}, { usage, props });
}