/*! * Tectum * Copyright © 2026 Machiel Heinen. * Alle rechten voorbehouden. Gebruik uitsluitend met schriftelijke toestemming. * Zie LICENTIE.md. */ // Eigenschappenpaneel rechts: eigenschappen van de selectie, of van de woning als er niets geselecteerd is. // Een sectie = { key, label, icon, groups() → [{ label, html }], wire(el) }; elke sectie krijgt een eigen element, // zodat wire() alleen de eigen knoppen koppelt. window.Inspector = (() => { const { icon, esc } = UI; const big = UI.btnOf('ins-btn ins-big'); const small = UI.btnOf('ins-btn'); const kv = (label, value, unit) => `
${label}${value}${unit ? `${unit}` : ''}
`; const PREF_KEY = 'tectum.inspector.open'; let open; try { open = new Set(JSON.parse(localStorage.getItem(PREF_KEY) || 'null') || ['gevel']); } catch (e) { open = new Set(['gevel']); } const saveOpen = () => { try { localStorage.setItem(PREF_KEY, JSON.stringify([...open])); } catch (e) { } }; // Een groepskop gelijk aan de sectienaam (bijv. Elektra › Elektra) vervalt. const groupsHtml = (groups, secLabel) => groups.filter(Boolean).map(g => `
${g.label && g.label.toLowerCase() !== String(secLabel || '').toLowerCase() ? `

${g.label}

` : ''}
${g.html}
`).join(''); // view = { crumbs: [{ label, attrs }], title, icon, sub, top: html, sections: [...], collapsible, onBack } function render(el, view) { const scrollKey = view.title + '|' + (view.sub || ''); const keepScroll = el._insKey === scrollKey ? el.scrollTop : 0; el._insKey = scrollKey; el.innerHTML = `
${view.crumbs && view.crumbs.length ? `
${view.crumbs.map(c => ``).join(icon('chevron-right'))}${icon('chevron-right')}
` : ''}

${view.icon ? icon(view.icon) : ''}${esc(view.title)}

${view.sub ? `
${esc(view.sub)}
` : ''}
${view.top ? `
${view.top}
` : ''}
`; const host = el.querySelector('.ins-sections'); view.sections.filter(Boolean).forEach(sec => { const node = document.createElement('section'); const collapsible = view.collapsible; const isOpen = !collapsible || open.has(sec.key); node.className = 'ins-section' + (collapsible ? ' ins-collapsible' : '') + (isOpen ? ' open' : ''); node.innerHTML = (collapsible ? `` : '') + '
'; host.appendChild(node); // Een dichte sectie wordt pas opgebouwd (en gekoppeld) als hij opengaat. let built = false; const build = () => { if (built) return; built = true; node.querySelector('.ins-section-body').innerHTML = groupsHtml(sec.groups ? sec.groups() : [], sec.label); if (sec.wire) sec.wire(node); }; if (isOpen) build(); if (collapsible) node.querySelector('.ins-section-head').addEventListener('click', () => { const now = !node.classList.contains('open'); if (now) build(); node.classList.toggle('open', now); node.querySelector('.ins-section-head').setAttribute('aria-expanded', now); if (now) open.add(sec.key); else open.delete(sec.key); saveOpen(); }); }); el.scrollTop = keepScroll; } return { big, small, kv, render }; })();