Replace light/dark switch with sun/moon icon button
- Remove toggle switch, Light/Dark labels, knob/track CSS - Single button with sun (light) and moon (dark) FA icons - Icons cross-fade with rotation transition on theme change - Compact circular button matches FAB aesthetic - Removed duplicate old switch CSS rules Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17064,7 +17064,7 @@ form .form-select {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: .5rem;
|
gap: .5rem;
|
||||||
padding: calc(var(--padding-x, 0.25rem) * 2) calc(var(--padding-y, 0.25rem) * 3) calc(var(--padding-x, 0.25rem) * 2) calc(var(--padding-y, 0.25rem) * 8);
|
padding: .4rem .6rem;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: none;
|
border: none;
|
||||||
background: var(--muted-color, #6d757e);
|
background: var(--muted-color, #6d757e);
|
||||||
@@ -17094,46 +17094,47 @@ form .form-select {
|
|||||||
top: 1rem;
|
top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mokoThemeFab .switch {
|
/* Sun/Moon theme toggle button */
|
||||||
display: inline-flex;
|
.theme-icon-btn {
|
||||||
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
justify-content: center;
|
||||||
width: 44px;
|
width: 32px;
|
||||||
height: 24px;
|
height: 32px;
|
||||||
background: var(--secondary-color, #e6ebf1bf);
|
border: none;
|
||||||
transition: background .2s, border-color .2s;
|
border-radius: 50%;
|
||||||
border-radius: var(--border-radius-xxl, 2rem);
|
background: rgba(255,255,255,.15);
|
||||||
}
|
|
||||||
|
|
||||||
#mokoThemeFab .knob {
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
left: 2px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border-radius: var(--border-radius-xxl, 2rem);
|
|
||||||
background: var(--bs-body-bg, #fff);
|
|
||||||
box-shadow: var(--box-shadow, 0 .5rem 1rem #00000066);
|
|
||||||
transition: transform .2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mokoThemeFab [role="switch"][aria-checked="true"] .knob {
|
|
||||||
transform: translateX(20px);
|
|
||||||
}
|
|
||||||
|
|
||||||
#mokoThemeFab [role="switch"][aria-checked="true"] .switch {
|
|
||||||
background: rgba(var(--secondary-color, #e6ebf1bf), .15);
|
|
||||||
}
|
|
||||||
|
|
||||||
button#mokoThemeSwitch {
|
|
||||||
border: unset;
|
|
||||||
background-color: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mokoThemeFab .label {
|
|
||||||
user-select: none;
|
|
||||||
font-size: .875rem;
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-icon-btn .fa-sun,
|
||||||
|
.theme-icon-btn .fa-moon {
|
||||||
|
position: absolute;
|
||||||
|
transition: opacity .2s, transform .2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Light mode: show sun, hide moon */
|
||||||
|
.theme-icon-btn.is-light .fa-sun {
|
||||||
|
opacity: 1;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
.theme-icon-btn.is-light .fa-moon {
|
||||||
|
opacity: 0;
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode: show moon, hide sun */
|
||||||
|
.theme-icon-btn.is-dark .fa-moon {
|
||||||
|
opacity: 1;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
.theme-icon-btn.is-dark .fa-sun {
|
||||||
|
opacity: 0;
|
||||||
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Auto toggle switch (on/off style) */
|
/* Auto toggle switch (on/off style) */
|
||||||
@@ -17357,37 +17358,6 @@ body.site.error-page {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mokoThemeFab .knob {
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
left: 2px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border-radius: var(--border-radius-xxl, 2rem);
|
|
||||||
background: var(--bs-body-bg, #fff);
|
|
||||||
box-shadow: var(--box-shadow, 0 .5rem 1rem #00000066);
|
|
||||||
transition: transform .2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mokoThemeFab [role="switch"][aria-checked="true"] .knob {
|
|
||||||
transform: translateX(20px);
|
|
||||||
}
|
|
||||||
|
|
||||||
#mokoThemeFab [role="switch"][aria-checked="true"] .switch {
|
|
||||||
background: rgba(var(--secondary-color, #e6ebf1bf), .15);
|
|
||||||
}
|
|
||||||
|
|
||||||
button#mokoThemeSwitch {
|
|
||||||
border: unset;
|
|
||||||
background-color: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mokoThemeFab .label {
|
|
||||||
user-select: none;
|
|
||||||
font-size: .875rem;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mokoThemeFab.debug-outline {
|
#mokoThemeFab.debug-outline {
|
||||||
outline: 2px dashed var(--pink, #ff8fc0);
|
outline: 2px dashed var(--pink, #ff8fc0);
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
|
|||||||
@@ -62,30 +62,33 @@
|
|||||||
wrap.id = 'mokoThemeFab';
|
wrap.id = 'mokoThemeFab';
|
||||||
wrap.className = posClassFromBody();
|
wrap.className = posClassFromBody();
|
||||||
|
|
||||||
// Light label
|
// Sun/Moon toggle button
|
||||||
var lblL = doc.createElement('span');
|
|
||||||
lblL.className = 'label';
|
|
||||||
lblL.textContent = 'Light';
|
|
||||||
|
|
||||||
// Switch
|
|
||||||
var switchWrap = doc.createElement('button');
|
var switchWrap = doc.createElement('button');
|
||||||
switchWrap.id = 'mokoThemeSwitch';
|
switchWrap.id = 'mokoThemeSwitch';
|
||||||
switchWrap.type = 'button';
|
switchWrap.type = 'button';
|
||||||
switchWrap.setAttribute('role', 'switch');
|
switchWrap.className = 'theme-icon-btn';
|
||||||
switchWrap.setAttribute('aria-label', 'Toggle dark mode');
|
switchWrap.setAttribute('aria-label', 'Toggle dark mode');
|
||||||
switchWrap.setAttribute('aria-checked', 'false');
|
|
||||||
|
|
||||||
var track = doc.createElement('span');
|
var sunIcon = doc.createElement('i');
|
||||||
track.className = 'switch';
|
sunIcon.className = 'fa-solid fa-sun';
|
||||||
var knob = doc.createElement('span');
|
sunIcon.setAttribute('aria-hidden', 'true');
|
||||||
knob.className = 'knob';
|
|
||||||
track.appendChild(knob);
|
|
||||||
switchWrap.appendChild(track);
|
|
||||||
|
|
||||||
// Dark label
|
var moonIcon = doc.createElement('i');
|
||||||
var lblD = doc.createElement('span');
|
moonIcon.className = 'fa-solid fa-moon';
|
||||||
lblD.className = 'label';
|
moonIcon.setAttribute('aria-hidden', 'true');
|
||||||
lblD.textContent = 'Dark';
|
|
||||||
|
switchWrap.appendChild(sunIcon);
|
||||||
|
switchWrap.appendChild(moonIcon);
|
||||||
|
|
||||||
|
function updateThemeIcon(theme) {
|
||||||
|
if (theme === 'dark') {
|
||||||
|
switchWrap.classList.add('is-dark');
|
||||||
|
switchWrap.classList.remove('is-light');
|
||||||
|
} else {
|
||||||
|
switchWrap.classList.add('is-light');
|
||||||
|
switchWrap.classList.remove('is-dark');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Auto toggle (on/off switch style)
|
// Auto toggle (on/off switch style)
|
||||||
var autoWrap = doc.createElement('div');
|
var autoWrap = doc.createElement('div');
|
||||||
@@ -127,7 +130,7 @@
|
|||||||
var current = (root.getAttribute('data-bs-theme') || 'light').toLowerCase();
|
var current = (root.getAttribute('data-bs-theme') || 'light').toLowerCase();
|
||||||
var next = current === 'dark' ? 'light' : 'dark';
|
var next = current === 'dark' ? 'light' : 'dark';
|
||||||
applyTheme(next);
|
applyTheme(next);
|
||||||
switchWrap.setAttribute('aria-checked', next === 'dark' ? 'true' : 'false');
|
updateThemeIcon(next);
|
||||||
// Turn off auto when manually switching
|
// Turn off auto when manually switching
|
||||||
auto.classList.remove('on');
|
auto.classList.remove('on');
|
||||||
auto.setAttribute('aria-checked', 'false');
|
auto.setAttribute('aria-checked', 'false');
|
||||||
@@ -145,7 +148,7 @@
|
|||||||
clearStored();
|
clearStored();
|
||||||
var sys = systemTheme();
|
var sys = systemTheme();
|
||||||
applyTheme(sys);
|
applyTheme(sys);
|
||||||
switchWrap.setAttribute('aria-checked', sys === 'dark' ? 'true' : 'false');
|
updateThemeIcon(sys);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -154,7 +157,7 @@
|
|||||||
if (!getStored()) {
|
if (!getStored()) {
|
||||||
var sys = systemTheme();
|
var sys = systemTheme();
|
||||||
applyTheme(sys);
|
applyTheme(sys);
|
||||||
switchWrap.setAttribute('aria-checked', sys === 'dark' ? 'true' : 'false');
|
updateThemeIcon(sys);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (typeof mql.addEventListener === 'function') mql.addEventListener('change', onMql);
|
if (typeof mql.addEventListener === 'function') mql.addEventListener('change', onMql);
|
||||||
@@ -162,12 +165,10 @@
|
|||||||
|
|
||||||
// Initial state
|
// Initial state
|
||||||
var initial = getStored() || systemTheme();
|
var initial = getStored() || systemTheme();
|
||||||
switchWrap.setAttribute('aria-checked', initial === 'dark' ? 'true' : 'false');
|
updateThemeIcon(initial);
|
||||||
|
|
||||||
// Mount
|
// Mount
|
||||||
wrap.appendChild(lblL);
|
|
||||||
wrap.appendChild(switchWrap);
|
wrap.appendChild(switchWrap);
|
||||||
wrap.appendChild(lblD);
|
|
||||||
wrap.appendChild(autoWrap);
|
wrap.appendChild(autoWrap);
|
||||||
wrap.appendChild(divider);
|
wrap.appendChild(divider);
|
||||||
wrap.appendChild(a11ySlot);
|
wrap.appendChild(a11ySlot);
|
||||||
|
|||||||
Reference in New Issue
Block a user