theme selecter moved

This commit is contained in:
2026-08-27 17:43:47 +02:00
parent 60f7107ec9
commit f8fcadb488
14 changed files with 165 additions and 23 deletions
+3
View File
@@ -3,4 +3,7 @@
## Version v0.1.1 ## Version v0.1.1
### Features ### Features
* Ability to add new logs through the web interface * Ability to add new logs through the web interface
### Modification
* Moved the style selection into the hamburger menu
* Toot formatting changed a wee bit
## Version v0.1.0 Initial release ## Version v0.1.0 Initial release
+6
View File
@@ -1250,3 +1250,9 @@ Put the new entry button left of the hamburger menu
### Assistant outcome ### Assistant outcome
Restructured all template headers to position the new-entry button inside the header-actions container, left of the menu-toggle button. Updated feed.html, about.html, admin.html, labels.html, user_profile.html, login.html, and new-entry.html. The button now appears in visual order: new-entry button, then hamburger menu toggle, with proper flexbox alignment and 8px spacing. All 54 backend tests pass. Restructured all template headers to position the new-entry button inside the header-actions container, left of the menu-toggle button. Updated feed.html, about.html, admin.html, labels.html, user_profile.html, login.html, and new-entry.html. The button now appears in visual order: new-entry button, then hamburger menu toggle, with proper flexbox alignment and 8px spacing. All 54 backend tests pass.
### User
The style selection should move into the hamburger menu - but in such a way that it becomes a submenu so that it doesn't clutter the menu structure
### Assistant outcome
Moved the theme selector into the hamburger menu as a collapsible submenu. Added theme-submenu-container with a submenu-title button and submenu-options to all templates (feed.html, about.html, admin.html, labels.html, user_profile.html, login.html, new-entry.html). Updated theme.js to populate the submenu with theme buttons instead of adding a picker to header-actions. Updated auth-header.js to handle submenu toggle with aria-expanded for accessibility. Added comprehensive CSS styling for .theme-submenu-container, .submenu-title, .submenu-options, and .theme-option (including .active state). Theme selection now works cleanly within the menu without cluttering the header. All 54 backend tests pass.
+1
View File
@@ -220,6 +220,7 @@
210. After an entry is saved move to the /<user>/ page 210. After an entry is saved move to the /<user>/ page
211. Don't put new entry in the hamburger menu but present it as a seperate button next to the style selector 211. Don't put new entry in the hamburger menu but present it as a seperate button next to the style selector
212. Put the new entry button left of the hamburger menu 212. Put the new entry button left of the hamburger menu
213. The style selection should move into the hamburger menu - but in such a way that it becomes a submenu so that it doesn't clutter the menu structure
## Future entries ## Future entries
+14
View File
@@ -14,6 +14,10 @@
const menu = document.querySelector('#auth-menu'); const menu = document.querySelector('#auth-menu');
const menuToggle = document.querySelector('.menu-toggle'); const menuToggle = document.querySelector('.menu-toggle');
const logoutButton = document.querySelector('#logout-button'); const logoutButton = document.querySelector('#logout-button');
const themeSubmenuContainer = document.querySelector('#theme-submenu-container');
const themeSubmenuTitle = document.querySelector('.submenu-title');
const themeOptions = document.querySelector('#theme-options');
if (!loginButton || !profileLink || !labelsLink || !adminLink || !session || !username || !menu || !menuToggle || !logoutButton) return; if (!loginButton || !profileLink || !labelsLink || !adminLink || !session || !username || !menu || !menuToggle || !logoutButton) return;
@@ -22,6 +26,16 @@
menu.classList.toggle('hidden', isOpen); menu.classList.toggle('hidden', isOpen);
menuToggle.setAttribute('aria-expanded', String(!isOpen)); menuToggle.setAttribute('aria-expanded', String(!isOpen));
}); });
// Handle theme submenu toggle
if (themeSubmenuTitle && themeOptions) {
themeSubmenuTitle.addEventListener('click', (e) => {
e.preventDefault();
const isOpen = !themeOptions.classList.contains('hidden');
themeOptions.classList.toggle('hidden', isOpen);
themeSubmenuTitle.setAttribute('aria-expanded', String(!isOpen));
});
}
function showSignedOut() { function showSignedOut() {
loginButton.classList.remove('hidden'); loginButton.classList.remove('hidden');
+80 -11
View File
@@ -223,17 +223,6 @@ body::selection {
position: relative; position: relative;
} }
.theme-picker {
width: auto;
min-width: 132px;
padding: 8px 10px;
border: 1px solid var(--surface-2);
border-radius: 7px;
background: var(--surface-0);
color: var(--text);
font: inherit;
}
.menu-toggle { .menu-toggle {
min-width: 0; min-width: 0;
padding: 10px 13px; padding: 10px 13px;
@@ -339,6 +328,86 @@ body::selection {
color: var(--red); color: var(--red);
} }
.theme-submenu-container {
border-top: 1px solid var(--border);
margin-top: 6px;
padding-top: 6px;
}
.theme-submenu-container.hidden {
display: none;
}
.submenu-title {
display: block;
width: 100%;
min-width: 0;
padding: 9px 10px;
border: 0;
border-radius: 6px;
background: transparent;
color: var(--text);
text-align: left;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
}
.submenu-title:hover {
background: var(--surface-1);
color: var(--lavender);
}
.submenu-title::after {
content: ' ▼';
font-size: 0.7em;
opacity: 0.7;
}
.submenu-title[aria-expanded='true']::after {
transform: rotate(-180deg);
display: inline-block;
}
.submenu-options {
display: flex;
flex-direction: column;
gap: 4px;
padding: 4px 8px;
margin-top: 4px;
border-radius: 6px;
background: var(--surface-1);
}
.submenu-options.hidden {
display: none;
}
.theme-option {
padding: 8px 10px;
border: 1px solid var(--border);
border-radius: 5px;
background: transparent;
color: var(--text);
text-align: left;
cursor: pointer;
transition: all 0.2s ease;
font-size: 0.9rem;
}
.theme-option:hover {
background: var(--surface-0);
border-color: var(--lavender);
color: var(--lavender);
}
.theme-option.active {
background: var(--mauve);
border-color: var(--mauve);
color: var(--crust);
font-weight: 600;
}
main.container { main.container {
position: relative; position: relative;
z-index: 1; z-index: 1;
+32 -11
View File
@@ -11,18 +11,39 @@ async function loadAvailableThemes() {
? localStorage.getItem(themePreference) ? localStorage.getItem(themePreference)
: themes[0]?.id; : themes[0]?.id;
if (selected) document.documentElement.dataset.theme = selected; if (selected) document.documentElement.dataset.theme = selected;
const headerActions = document.querySelector('.header-actions');
if (!headerActions || !themes.length) return; const submenuContainer = document.querySelector('#theme-submenu-container');
const picker = document.createElement('select'); const themeOptions = document.querySelector('#theme-options');
picker.className = 'theme-picker'; const submenuTitle = document.querySelector('.submenu-title');
picker.setAttribute('aria-label', 'Theme');
picker.replaceChildren(...themes.map((theme) => new Option(theme.label, theme.id))); if (!submenuContainer || !themeOptions || !themes.length) return;
picker.value = selected || themes[0].id;
picker.addEventListener('change', () => { // Show the submenu container
localStorage.setItem(themePreference, picker.value); submenuContainer.classList.remove('hidden');
document.documentElement.dataset.theme = picker.value;
// Create theme buttons
const buttons = themes.map((theme) => {
const button = document.createElement('button');
button.type = 'button';
button.className = 'theme-option';
button.dataset.themeId = theme.id;
button.textContent = theme.label;
if (theme.id === selected) {
button.classList.add('active');
}
button.addEventListener('click', () => {
localStorage.setItem(themePreference, theme.id);
document.documentElement.dataset.theme = theme.id;
// Update active state
document.querySelectorAll('.theme-option').forEach((btn) => {
btn.classList.remove('active');
});
button.classList.add('active');
});
return button;
}); });
headerActions.prepend(picker);
themeOptions.replaceChildren(...buttons);
} }
loadAvailableThemes(); loadAvailableThemes();
+4
View File
@@ -29,6 +29,10 @@
<a id="auth-admin-link" class="hidden" href="/admin">Admin</a> <a id="auth-admin-link" class="hidden" href="/admin">Admin</a>
<div id="auth-session" class="auth-session hidden"><a id="auth-username" class="user-name" href="/"></a></div> <div id="auth-session" class="auth-session hidden"><a id="auth-username" class="user-name" href="/"></a></div>
<button id="logout-button" class="logout-button hidden" type="button">Sign out</button> <button id="logout-button" class="logout-button hidden" type="button">Sign out</button>
<div id="theme-submenu-container" class="theme-submenu-container hidden">
<button type="button" class="submenu-title" aria-expanded="false" aria-controls="theme-options">Themes</button>
<div id="theme-options" class="submenu-options hidden"></div>
</div>
</nav> </nav>
</div> </div>
</div> </div>
+4
View File
@@ -31,6 +31,10 @@
<a id="auth-username" class="user-name" href="/"></a> <a id="auth-username" class="user-name" href="/"></a>
</div> </div>
<button id="logout-button" class="logout-button hidden" type="button">Sign out</button> <button id="logout-button" class="logout-button hidden" type="button">Sign out</button>
<div id="theme-submenu-container" class="theme-submenu-container hidden">
<button type="button" class="submenu-title" aria-expanded="false" aria-controls="theme-options">Themes</button>
<div id="theme-options" class="submenu-options hidden"></div>
</div>
</nav> </nav>
</div> </div>
</div> </div>
+4
View File
@@ -31,6 +31,10 @@
<a id="auth-username" class="user-name" href="/"></a> <a id="auth-username" class="user-name" href="/"></a>
</div> </div>
<button id="logout-button" class="logout-button hidden" type="button">Sign out</button> <button id="logout-button" class="logout-button hidden" type="button">Sign out</button>
<div id="theme-submenu-container" class="theme-submenu-container hidden">
<button type="button" class="submenu-title" aria-expanded="false" aria-controls="theme-options">Themes</button>
<div id="theme-options" class="submenu-options hidden"></div>
</div>
</nav> </nav>
</div> </div>
<section class="toolbar"> <section class="toolbar">
+4
View File
@@ -29,6 +29,10 @@
<a id="auth-admin-link" class="hidden" href="/admin">Admin</a> <a id="auth-admin-link" class="hidden" href="/admin">Admin</a>
<div id="auth-session" class="auth-session hidden"><a id="auth-username" class="user-name" href="/"></a></div> <div id="auth-session" class="auth-session hidden"><a id="auth-username" class="user-name" href="/"></a></div>
<button id="logout-button" class="logout-button hidden" type="button">Sign out</button> <button id="logout-button" class="logout-button hidden" type="button">Sign out</button>
<div id="theme-submenu-container" class="theme-submenu-container hidden">
<button type="button" class="submenu-title" aria-expanded="false" aria-controls="theme-options">Themes</button>
<div id="theme-options" class="submenu-options hidden"></div>
</div>
</nav> </nav>
</div> </div>
</div> </div>
+4
View File
@@ -30,6 +30,10 @@
<a id="auth-username" class="user-name" href="/"></a> <a id="auth-username" class="user-name" href="/"></a>
</div> </div>
<button id="logout-button" class="logout-button hidden" type="button">Sign out</button> <button id="logout-button" class="logout-button hidden" type="button">Sign out</button>
<div id="theme-submenu-container" class="theme-submenu-container hidden">
<button type="button" class="submenu-title" aria-expanded="false" aria-controls="theme-options">Themes</button>
<div id="theme-options" class="submenu-options hidden"></div>
</div>
</nav> </nav>
</div> </div>
</div> </div>
+4
View File
@@ -31,6 +31,10 @@
<a id="auth-username" class="user-name" href="/"></a> <a id="auth-username" class="user-name" href="/"></a>
</div> </div>
<button id="logout-button" class="logout-button hidden" type="button">Sign out</button> <button id="logout-button" class="logout-button hidden" type="button">Sign out</button>
<div id="theme-submenu-container" class="theme-submenu-container hidden">
<button type="button" class="submenu-title" aria-expanded="false" aria-controls="theme-options">Themes</button>
<div id="theme-options" class="submenu-options hidden"></div>
</div>
</nav> </nav>
</div> </div>
</div> </div>
+4
View File
@@ -32,6 +32,10 @@
<a id="auth-username" class="user-name" href="/"></a> <a id="auth-username" class="user-name" href="/"></a>
</div> </div>
<button id="logout-button" class="logout-button hidden" type="button">Sign out</button> <button id="logout-button" class="logout-button hidden" type="button">Sign out</button>
<div id="theme-submenu-container" class="theme-submenu-container hidden">
<button type="button" class="submenu-title" aria-expanded="false" aria-controls="theme-options">Themes</button>
<div id="theme-options" class="submenu-options hidden"></div>
</div>
</nav> </nav>
</div> </div>
</div> </div>
+1 -1
View File
@@ -1,3 +1,3 @@
{ {
"version": "0.1.0" "version": "0.1.1"
} }