v0.5.2: elektra (meterkast 3×25 A, schakelaars met letters op hun lampen, wcd, apparaatgroepen incl. perilex, groepenverklaring met fasen/aardlek, leidingen naar de meterkast met strekkende meters per type, PDF-blad + plattegrond, verplaatsbaar door slepen, bouwfase Elektra met installatiebuizen in 3D); ribbon, bouwfasen, kozijnen, kostenmodel en eerdere ongecommitte wijzigingen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Machiel
2026-10-06 18:40:11 +02:00
co-authored by Claude Opus 5.5
parent 8cdfa21f46
commit e1a688728c
30 changed files with 6667 additions and 868 deletions
+32 -2
View File
@@ -7,7 +7,8 @@
// ============================================================
// core/ui-kit.js — gedeelde UI-bouwstenen (window.UI): iconen (Bootstrap
// Icons, css/vendor), invoervelden, schakelaars, secties, tabbladen,
// specificatie-kaarten en de 3-staps weergave-cyclus (sneltoets T).
// inklapbare secties, schuiven, specificatie-kaarten en de 3-staps
// weergave-cyclus (sneltoets T).
// Eén plek voor opmaak en woordgebruik, zodat alle panelen gelijk ogen.
//
// Woordgebruik labels: zelfstandig naamwoord met hoofdletter, geen dubbele
@@ -34,6 +35,35 @@ window.UI = (() => {
`<span class="ui-unit">${unit}</span>`, o);
}
// Schuif met gekoppeld getal (voor maten met een logisch bereik, zoals
// hoogtes en hellingen). o: { min, max, step, unit ('mm' standaard), hint }.
// Het getal mag buiten het schuifbereik; het model klemt zelf.
function range(id, label, value, o) {
o = o || {};
const unit = o.unit === undefined ? 'mm' : o.unit;
const lim = `min="${o.min}" max="${o.max}" step="${o.step || 10}"`;
return `<div class="ui-field ui-field-range${o.disabled ? ' is-disabled' : ''}"><label for="${id}">${label}${hint(o.hint)}</label>` +
`<div class="ui-control ui-range"><input type="range" id="${id}-r" ${lim} value="${value}"${o.disabled ? ' disabled' : ''}>` +
`<input type="number" id="${id}" step="${o.step || 10}" value="${value}"${o.disabled ? ' disabled' : ''}><span class="ui-unit">${unit}</span></div></div>`;
}
// fn(v) bij schuiven en typen; set(id, v) zet beide zonder event.
function onRange(id, fn, after) {
const n = document.getElementById(id), r = document.getElementById(id + '-r');
if (!n || !r) return;
r.addEventListener('input', () => { n.value = r.value; fn(parseFloat(r.value)); after && after(); });
n.addEventListener('input', () => {
const v = parseFloat(n.value);
if (!isFinite(v)) return;
r.value = v;
fn(v); after && after();
});
}
function setRange(id, v) {
const n = document.getElementById(id), r = document.getElementById(id + '-r');
if (n && document.activeElement !== n) n.value = v;
if (r) r.value = v;
}
// Keuzelijst. options: { waarde: 'Label' }.
function sel(id, label, options, value, o) {
const opts = Object.entries(options).map(([k, v]) => `<option value="${k}"${k === value ? ' selected' : ''}>${v}</option>`).join('');
@@ -126,5 +156,5 @@ window.UI = (() => {
el.classList.toggle('fullscreen-2d');
}
return { esc, icon, hint, num, sel, toggle, color, onColor, section, info, warn, grid, button, actions, tabs, wireTabs, specCard, onNum, onSel, onToggle, cycle3D, toggle2D };
return { esc, icon, hint, num, range, onRange, setRange, sel, toggle, color, onColor, section, info, warn, grid, button, actions, tabs, wireTabs, specCard, onNum, onSel, onToggle, cycle3D, toggle2D };
})();