Versie 0.2.0
This commit is contained in:
commit
e77d8fd373
495 files changed
+81026
No files matched your search
@@ -0,0 +1,109 @@
|
||||
// Generated, do not edit. sha256:09856719543cb019750495d6ca12c5afc9eb3cc35cdf6a20a0f887e365cc177f
|
||||
import { esc } from './escape.js';
|
||||
|
||||
function plainError(panel, err, id) {
|
||||
console.error(`[tabs] ${id || ''}`, err);
|
||||
panel.innerHTML = `<div class="alert alert-error">${esc(err && err.message ? err.message : String(err))}</div>`;
|
||||
}
|
||||
let onError = plainError;
|
||||
|
||||
export function configureTabs({ onError: handler = null } = {}) {
|
||||
onError = handler || plainError;
|
||||
}
|
||||
|
||||
export function rowLayout(count, content, room) {
|
||||
const rows = count > 1 && content > room ? 2 : 1;
|
||||
return { rows, cols: Math.ceil(count / rows) };
|
||||
}
|
||||
|
||||
export function create(host, opts = {}) {
|
||||
if (!host) return null;
|
||||
const { items = [], render, onChange, size = '', syncOn = [], barHost = null } = opts;
|
||||
const list = items.filter(it => it && (!it.when || it.when()));
|
||||
|
||||
let current = opts.active;
|
||||
if (!list.some(it => it.id === current)) current = list[0] && list[0].id;
|
||||
|
||||
const bar = document.createElement('div');
|
||||
bar.className = 'tabset' + (size === 'lg' ? ' tabset--lg' : '');
|
||||
bar.setAttribute('role', 'tablist');
|
||||
const panel = document.createElement('div');
|
||||
panel.setAttribute('role', 'tabpanel');
|
||||
|
||||
if (host._tabsCleanup) host._tabsCleanup();
|
||||
host.innerHTML = '';
|
||||
if (barHost) { barHost.innerHTML = ''; barHost.append(bar); host.append(panel); }
|
||||
else host.append(bar, panel);
|
||||
|
||||
function drawBar() {
|
||||
bar.innerHTML = list.map(it => {
|
||||
const on = it.id === current;
|
||||
const dot = typeof it.dot === 'function' ? (it.dot() || '') : (it.dot || '');
|
||||
return `<button class="tabset-tab${on ? ' is-on' : ''}" role="tab" aria-selected="${on}" data-tab="${it.id}">${it.label}${dot}</button>`;
|
||||
}).join('');
|
||||
bar.querySelectorAll('[data-tab]').forEach(b => { b.onclick = () => select(b.dataset.tab); });
|
||||
if (size === 'lg') fitRows();
|
||||
}
|
||||
|
||||
function fitRows() {
|
||||
if (!bar.isConnected) return;
|
||||
bar.classList.remove('tabset--rows');
|
||||
const box = bar.getBoundingClientRect();
|
||||
const last = bar.children[bar.children.length - 1];
|
||||
const reach = last ? last.getBoundingClientRect().right - box.left : 0;
|
||||
const { rows, cols } = rowLayout(list.length, Math.round(reach), Math.round(box.width));
|
||||
if (rows < 2) return;
|
||||
bar.classList.add('tabset--rows');
|
||||
bar.style.setProperty('--tabset-cols', String(cols));
|
||||
}
|
||||
let seenWidth = -1;
|
||||
const resize = size === 'lg' && typeof ResizeObserver === 'function'
|
||||
? new ResizeObserver(entries => {
|
||||
if (!bar.isConnected) { cleanup(); return; }
|
||||
const width = entries[entries.length - 1].contentRect.width;
|
||||
if (width === seenWidth) return;
|
||||
seenWidth = width;
|
||||
fitRows();
|
||||
})
|
||||
: null;
|
||||
|
||||
function drawPanel() {
|
||||
panel.innerHTML = '';
|
||||
if (!render) return;
|
||||
try {
|
||||
const r = render(current, panel);
|
||||
if (r && typeof r.then === 'function') r.catch(err => onError(panel, err, current));
|
||||
} catch (err) { onError(panel, err, current); }
|
||||
}
|
||||
|
||||
function select(id, force) {
|
||||
if (!force && id === current) return;
|
||||
if (!list.some(it => it.id === id)) return;
|
||||
current = id;
|
||||
drawBar();
|
||||
drawPanel();
|
||||
if (onChange) onChange(id);
|
||||
}
|
||||
|
||||
const onSync = () => { if (!bar.isConnected) { cleanup(); return; } drawBar(); };
|
||||
function cleanup() {
|
||||
syncOn.forEach(ev => document.removeEventListener(ev, onSync));
|
||||
if (resize) resize.disconnect();
|
||||
if (host._tabsCleanup === cleanup) host._tabsCleanup = null;
|
||||
}
|
||||
syncOn.forEach(ev => document.addEventListener(ev, onSync));
|
||||
if (resize) resize.observe(bar);
|
||||
host._tabsCleanup = cleanup;
|
||||
|
||||
drawBar();
|
||||
drawPanel();
|
||||
|
||||
return {
|
||||
el: host, bar, panel,
|
||||
get active() { return current; },
|
||||
select: id => select(id),
|
||||
refresh: () => drawBar(),
|
||||
redraw: () => drawPanel(),
|
||||
destroy: cleanup,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user