A music player that connects to your cloud/distributed storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: hide nav items that were pushed to the next line

+122 -46
+57 -42
src/_components/nav.vto
··· 1 1 {{ set colorClass = (path) => url === "/" + path ? 'button--bg-twist-2' : 'button--transparent' }} 2 2 {{ set slug = (cat) => cat.toLowerCase().replace(/\s+/g, '-') }} 3 3 4 - <nav> 5 - <a href="guide/" class="button {{ colorClass("guide/") }} button--border"> 6 - <span class="with-icon"> 7 - <i class="ph-fill ph-book-open-text"></i> 8 - Guide 9 - </span> 10 - </a> 4 + <div class="nav-container"> 5 + <nav id="diffuse-nav"> 6 + <a href="dashboard/" class="button {{ colorClass("dashboard/") }} button--border"> 7 + <span class="with-icon"> 8 + <i class="ph-fill ph-person"></i> 9 + Your Diffuse 10 + </span> 11 + </a> 11 12 12 - <a href="dashboard/" class="button {{ colorClass("dashboard/") }} button--border"> 13 - <span class="with-icon"> 14 - <i class="ph-fill ph-person"></i> 15 - Your Diffuse 16 - </span> 17 - </a> 13 + <a href="guide/" class="button {{ colorClass("guide/") }} button--border"> 14 + <span class="with-icon"> 15 + <i class="ph-fill ph-book-open-text"></i> 16 + Guide 17 + </span> 18 + </a> 18 19 19 - <a href="featured/" class="button {{ colorClass("featured/") }} button--border"> 20 - <span class="with-icon"> 21 - <i class="ph-fill ph-sparkle"></i> 22 - Featured 23 - </span> 24 - </a> 20 + <a href="featured/" class="button {{ colorClass("featured/") }} button--border"> 21 + <span class="with-icon"> 22 + <i class="ph-fill ph-sparkle"></i> 23 + Featured 24 + </span> 25 + </a> 26 + 27 + <a href="build/" class="button {{ colorClass("build/") }} button--border"> 28 + <span class="with-icon"> 29 + <i class="ph-fill ph-hammer"></i> 30 + Build 31 + </span> 32 + </a> 25 33 26 - <a href="build/" class="button {{ colorClass("build/") }} button--border"> 27 - <span class="with-icon"> 28 - <i class="ph-fill ph-hammer"></i> 29 - Build 30 - </span> 31 - </a> 34 + <div class="divider"></div> 32 35 33 - <div class="divider"></div> 36 + <a href="data/" class="button {{ colorClass("data/") }} button--border"> 37 + Input & Output 38 + </a> 34 39 35 - <a href="data/" class="button {{ colorClass("data/") }} button--border"> 36 - Input & Output 37 - </a> 40 + <a href="playback/" class="button {{ colorClass("playback/") }} button--border"> 41 + Playback 42 + </a> 38 43 39 - <a href="playback/" class="button {{ colorClass("playback/") }} button--border"> 40 - Playback 41 - </a> 44 + <a href="browsing/" class="button {{ colorClass("browsing/") }} button--border"> 45 + Browsing 46 + </a> 42 47 43 - <a href="browsing/" class="button {{ colorClass("browsing/") }} button--border"> 44 - Browsing 45 - </a> 48 + <a href="themes/" class="button {{ colorClass("themes/") }} button--border"> 49 + Themes 50 + </a> 46 51 47 - <a href="themes/" class="button {{ colorClass("themes/") }} button--border"> 48 - Themes 49 - </a> 52 + <a href="misc/" class="button {{ colorClass("misc/") }} button--border"> 53 + <span class="with-icon"> 54 + <i class="ph-fill ph-treasure-chest"></i> 55 + </span> 56 + </a> 57 + </nav> 50 58 51 - <a href="misc/" class="button {{ colorClass("misc/") }} button--border"> 59 + <button 60 + id="nav-overflow-btn" 61 + class="button button--transparent button--border" 62 + style="display: none; flex-shrink: 0" 63 + popovertarget="nav-overflow-menu" 64 + > 52 65 <span class="with-icon"> 53 - <i class="ph-fill ph-treasure-chest"></i> 66 + <i class="ph-fill ph-dots-three-outline"></i> 54 67 </span> 55 - </a> 56 - </nav> 68 + </button> 69 + 70 + <div id="nav-overflow-menu" class="dropdown" popover></div> 71 + </div>
+49
src/common/pages/nav.js
··· 1 + export function update() { 2 + const nav = document.getElementById("diffuse-nav"); 3 + const btn = document.getElementById("nav-overflow-btn"); 4 + const menu = document.getElementById("nav-overflow-menu"); 5 + 6 + if (!nav || !btn || !menu) return; 7 + 8 + const items = /** @type {HTMLElement[]} */ ([...nav.children]); 9 + 10 + // Reset: show all items, hide button 11 + for (const item of items) item.style.display = ""; 12 + btn.style.display = "none"; 13 + 14 + // No overflow — nothing to do 15 + if (nav.scrollWidth <= nav.clientWidth) return; 16 + 17 + // Show button (nav shrinks to accommodate it via flex) 18 + btn.style.display = ""; 19 + 20 + // Hide items from right until nav content fits 21 + const hidden = []; 22 + for (let i = items.length - 1; i >= 0; i--) { 23 + if (nav.scrollWidth <= nav.clientWidth) break; 24 + items[i].style.display = "none"; 25 + hidden.unshift(items[i]); 26 + } 27 + 28 + // Populate dropdown with clones (stripped of button styling) 29 + menu.innerHTML = ""; 30 + for (const el of hidden) { 31 + if (el.classList.contains("divider")) continue; 32 + 33 + const clone = /** @type {HTMLElement} */ (el.cloneNode(true)); 34 + clone.style.display = ""; 35 + clone.classList.remove( 36 + "button", 37 + "button--transparent", 38 + "button--border", 39 + "button--bg-twist-2", 40 + ); 41 + 42 + menu.appendChild(clone); 43 + } 44 + } 45 + 46 + export function watchResize() { 47 + const nav = document.getElementById("diffuse-nav"); 48 + if (nav) new ResizeObserver(update).observe(nav); 49 + }
+4
src/common/pages/ppr.js
··· 2 2 import * as Dashboard from "./dashboard.js"; 3 3 import * as Grid from "./grid.js"; 4 4 import * as Guide from "./guide.js"; 5 + import * as Nav from "./nav.js"; 5 6 6 7 /** Base pathname of the app (e.g. "/" at root, "/diffuse/" in a subdirectory). */ 7 8 const BASE_PATHNAME = new URL(document.baseURI).pathname; ··· 25 26 */ 26 27 async function initJsBasedOnPage(url) { 27 28 const path = relativePathname(url.pathname); 29 + 30 + Nav.update(); 31 + Nav.watchResize(); 28 32 29 33 Grid.insertToggleButtons(); 30 34 await Grid.monitorToggleButtonStates();
+12 -4
src/styles/diffuse/page.css
··· 590 590 * Nav 591 591 */ 592 592 593 - nav { 593 + .nav-container { 594 594 align-items: center; 595 595 border-bottom: 1px solid var(--border-color); 596 596 display: flex; 597 - flex-wrap: wrap; 598 597 gap: var(--space-xs); 599 598 margin-top: var(--space-md); 600 599 padding-bottom: var(--space-md); 600 + } 601 601 602 - .button:not(:has(.with-icon)) { 602 + nav { 603 + align-items: center; 604 + display: flex; 605 + flex: 1; 606 + flex-wrap: nowrap; 607 + gap: var(--space-xs); 608 + overflow: hidden; 609 + 610 + .button { 611 + flex-shrink: 0; 603 612 overflow: hidden; 604 - text-overflow: ellipsis; 605 613 white-space: nowrap; 606 614 } 607 615 }