Menu toggles styling and icons

This commit is contained in:
2026-05-18 10:08:07 +02:00
parent 800edc41b9
commit 6777037d3d
2 changed files with 44 additions and 8 deletions

View File

@@ -35,6 +35,15 @@ export default class extends Controller {
const id = event?.params.node; const id = event?.params.node;
const status = event?.target?.checked; const status = event?.target?.checked;
const node = AppState.normalizedNodes.find(n => n.id === id); const node = AppState.normalizedNodes.find(n => n.id === id);
/**
* @type {HTMLElement|null}
*/
const eye = event.target.parentElement.querySelector('i');
if (eye) {
eye.classList.toggle('bi-eye');
eye.classList.toggle('bi-eye-slash');
}
if (node.children.length > 0) { if (node.children.length > 0) {
this.#toggleGroup(node, status); this.#toggleGroup(node, status);
@@ -113,16 +122,22 @@ export default class extends Controller {
} }
/** /**
* @param {import("../state.js").NormalizedSceneNode} node * @param {import("../state.js").NormalizedSceneNode} node
* @param {boolean} isGroup
* @returns {HTMLDivElement} * @returns {HTMLDivElement}
*/ */
#createLayerToggle(node) { #createLayerToggle(node, isGroup = false) {
// This should be calculated somehow!
const labelIndent = node.depth < 3 ? '1.5rem' : '1rem';
const labelText = isGroup ? '<i class="bi bi-eye"></i>' : node.id;
const toggle = html` const toggle = html`
<label class="toggle-control ms-${node.depth} ps-${node.depth} mt-1 mb-1"> <label class="toggle-control ms-${node.depth} ps-${node.depth} mt-1 mb-1">
<input id="${node.id}" type="checkbox" ${node.active ? 'checked' : ''} role="switch" <input id="${node.id}" type="checkbox" ${node.active ? 'checked' : ''} role="switch"
data-menu-node-param="${node.id}" data-menu-node-param="${node.id}"
data-action="change->menu#toggleNode"> data-action="change->menu#toggleNode">
<span class="control"></span> <span class="control"></span>
<span class="ms-4 ps-1 fs-6" title="Mostra / nascondi layer">${node.id}</span> <span class="ps-2 fs-6" title="Mostra / nascondi ${isGroup ? 'gruppo' : 'layer'}" style="margin-left: ${labelIndent}">
${labelText}
</span>
</label> </label>
`; `;
@@ -135,8 +150,9 @@ export default class extends Controller {
#createLayerGroup(node) { #createLayerGroup(node) {
const { trigger, collapseDiv } = this.#createNodeCollapse(node); const { trigger, collapseDiv } = this.#createNodeCollapse(node);
const wrapper = document.createElement('div'); const wrapper = document.createElement('div');
wrapper.classList.add('w-max-content', 'ps-1', 'mb-1');
collapseDiv.appendChild(this.#createLayerToggle(node)); collapseDiv.appendChild(this.#createLayerToggle(node, true));
for (const child of node.children) { for (const child of node.children) {
collapseDiv.appendChild( collapseDiv.appendChild(
@@ -148,11 +164,10 @@ export default class extends Controller {
wrapper.appendChild(trigger); wrapper.appendChild(trigger);
wrapper.appendChild(collapseDiv); wrapper.appendChild(collapseDiv);
wrapper.classList.add('m-0', 'p-0'); wrapper.classList.add('border-start', 'border-bottom', 'rounded', `ms-${node.depth}`);
return wrapper; return wrapper;
} }
/** /**
* *
* @param {import("../state.js").NormalizedSceneNode} node * @param {import("../state.js").NormalizedSceneNode} node
@@ -164,10 +179,18 @@ export default class extends Controller {
trigger.className = 'btn btn-link p-0 fs-6 fw-bold text-decoration-none text-reset'; trigger.className = 'btn btn-link p-0 fs-6 fw-bold text-decoration-none text-reset';
trigger.setAttribute('data-bs-toggle', 'collapse'); trigger.setAttribute('data-bs-toggle', 'collapse');
trigger.setAttribute('data-bs-target', `#group-${cleanId}`); trigger.setAttribute('data-bs-target', `#group-${cleanId}`);
trigger.innerHTML = ` trigger.setAttribute('data-action', 'menu#toggleChevron');
trigger.innerHTML = html`
<i class="bi bi-chevron-down me-1"></i>${node.id} <i class="bi bi-chevron-down me-1"></i>${node.id}
<div class="d-inline-block border rounded ms-2" style="background-color: ${node.color}; height: 15px; width:15px"></div>
`; `;
// Add color "swatch" only for first level groups
if (node.depth === 2) {
trigger.innerHTML += html`
<div class="d-inline-block border rounded ms-2"
style="background-color: ${node.color}; height: 15px; width:15px">
</div>
`;
}
const collapseDiv = document.createElement('div'); const collapseDiv = document.createElement('div');
collapseDiv.className = 'collapse'; collapseDiv.className = 'collapse';
@@ -175,6 +198,19 @@ export default class extends Controller {
return {trigger, collapseDiv}; return {trigger, collapseDiv};
} }
/**
*
* @param {Event} event
*/
toggleChevron(event) {
/**
* @type {HTMLButtonElement} collapse
*/
const collapse = event.target;
const icon = collapse.querySelector('i');
icon.classList.toggle('bi-chevron-down');
icon.classList.toggle('bi-chevron-up');
}
/** /**
* Temporary implementation to show domains only * Temporary implementation to show domains only
* @todo Don't rebuild it every time, use caching, return a container * @todo Don't rebuild it every time, use caching, return a container

View File

@@ -147,7 +147,7 @@
</ul> </ul>
<!-- Tab panes --> <!-- Tab panes -->
<div class="tab-content ps-2 ms-2 overflow-y-auto"> <div class="tab-content ps-2 ms-2 overflow-y-auto">
<div class="tab-pane active ps-3 pt-0 mt-4 ms-0 border-start" data-menu-target="layers" id="layer" role="tabpanel" aria-labelledby="layer-tab" tabindex="0"></div> <div class="tab-pane active ps-3 pt-0 mt-4 ms-0" data-menu-target="layers" id="layer" role="tabpanel" aria-labelledby="layer-tab" tabindex="0"></div>
<div class="tab-pane pt-3" data-menu-target="ontology" id="content" role="tabpanel" aria-labelledby="media-tab" tabindex="0"> <div class="tab-pane pt-3" data-menu-target="ontology" id="content" role="tabpanel" aria-labelledby="media-tab" tabindex="0">
<!-- Temporary --> <!-- Temporary -->
<ul class="list-group me-4 ms-0"> <ul class="list-group me-4 ms-0">