Files
AtreidesAssetsFree/client/ui/loading.js
T
2026-10-29 11:57:29 +01:00

82 lines
3.6 KiB
JavaScript

// Generated, do not edit. sha256:3eb303d976e1be5498b5aef4a7cdd95c577070d967bef44ed7c9e2767146c564
import { esc } from './escape.js';
const DEFAULT_LABELS = Object.freeze({ loading: 'Loading…', loadError: 'Could not load this.' });
let labels = { ...DEFAULT_LABELS };
export function configureLoading({ labels: l = null } = {}) {
labels = { ...DEFAULT_LABELS, ...(l || {}) };
}
const sizes = ({ w, h, r, flex } = {}) =>
(w ? ` data-skel-w="${esc(w)}"` : '') + (h ? ` data-skel-h="${esc(h)}"` : '')
+ (r ? ` data-skel-r="${esc(r)}"` : '') + (flex ? ` data-skel-flex="${esc(flex)}"` : '');
export function sizeSkeleton(host) {
if (!host) return;
for (const el of host.querySelectorAll('[data-skel-w], [data-skel-h], [data-skel-r], [data-skel-flex]')) {
const d = el.dataset;
if (d.skelW) el.style.setProperty('width', d.skelW);
if (d.skelH) el.style.setProperty('height', d.skelH);
if (d.skelR) el.style.setProperty('border-radius', d.skelR);
if (d.skelFlex) el.style.setProperty('flex', d.skelFlex);
}
}
export function block(w = '100%', h = '1rem', radius = 'var(--radius-sm)') {
return `<span class="skel skel-block"${sizes({ w, h, r: radius })}></span>`;
}
export function line(w = '100%') {
return `<span class="skel skel-line"${sizes({ w })}></span>`;
}
export function circle(size = '2rem') {
return `<span class="skel skel-block"${sizes({ w: size, h: size, r: '50%', flex: 'none' })}></span>`;
}
export function card({ lines = 3 } = {}) {
const body = Array.from({ length: lines }, (_, i) =>
`<div class="skel-row">${line(i === 0 ? '55%' : '35%')}${line('20%')}</div>`).join('');
return `<div class="skel-card">
<div class="skel-row"><div class="skel-row-l">${circle('1.6rem')}${line('40%')}</div>${block('3rem', '1.1rem')}</div>
<div class="skel-card-body">${body}</div>
</div>`;
}
export function table({ rows = 6, cols = 4 } = {}) {
const cell = (head) => `<span class="skel ${head ? 'skel-line' : 'skel-cell'}"${sizes({ w: head ? '60%' : '80%' })}></span>`;
const row = (head) => `<div class="skel-trow">${Array.from({ length: cols }, () => `<div class="skel-td">${cell(head)}</div>`).join('')}</div>`;
const bodyRows = Array.from({ length: rows }, () => row(false)).join('');
return `<div class="skel-table">${row(true)}${bodyRows}</div>`;
}
export function cards({ count = 3, lines = 3 } = {}) {
return `<div class="skel-grid">${Array.from({ length: count }, () => card({ lines })).join('')}</div>`;
}
export function skeleton(parts) {
const inner = Array.isArray(parts) ? parts.join('') : String(parts ?? '');
const label = `<span class="sr-only">${esc(labels.loading)}</span>`;
return `<div class="skel-wrap" aria-busy="true" aria-live="polite">${label}<div aria-hidden="true">${inner}</div></div>`;
}
export function show(host, variant = 'lines', opts = {}) {
if (!host) return;
let parts;
if (variant === 'cards') parts = cards(opts);
else if (variant === 'table') parts = table(opts);
else if (variant === 'card') parts = card(opts);
else parts = Array.from({ length: opts.count || 3 }, (_, i) => line(i % 2 ? '70%' : '90%'));
host.innerHTML = skeleton(parts);
sizeSkeleton(host);
}
export function spinner(host, label = labels.loading) {
if (!host) return;
host.innerHTML = `<div class="skel-spin-wrap" aria-busy="true" aria-live="polite">
<span class="skel-spinner" aria-hidden="true"></span>
<span class="t-body-sm t-muted">${esc(label)}</span>
</div>`;
}
export function error(host, msg) {
if (!host) return;
host.innerHTML = `<div class="skel-error t-body-sm t-neg" role="alert">⚠ ${esc(msg || labels.loadError)}</div>`;
}