fix: complete devops theme compatibility

This commit is contained in:
Hermes VM 2026-05-31 20:06:09 +00:00
parent d6fa1d9e28
commit 09b16c4b19
3 changed files with 130 additions and 2 deletions

View File

@ -5,6 +5,8 @@
html,
body {
font-family: var(--ml-font-body), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background: var(--bl-bg-canvas);
color: var(--bl-text-primary);
}
@media (max-width: 767px) {
@ -12,3 +14,97 @@ body {
padding-top: 3.5rem;
}
}
/*
Legacy pages still use Tailwind gray/white utilities directly. Keep them
theme-aware while those pages are migrated to shared @bytelyst/ui primitives.
*/
[data-theme="dark"] .bg-white {
background-color: var(--bl-surface-card) !important;
}
[data-theme="dark"] .bg-gray-50,
[data-theme="dark"] .bg-gray-100 {
background-color: var(--bl-bg-canvas) !important;
}
[data-theme="dark"] .bg-gray-200,
[data-theme="dark"] .bg-gray-300 {
background-color: var(--bl-surface-muted) !important;
}
[data-theme="dark"] .bg-gray-700,
[data-theme="dark"] .bg-gray-800 {
background-color: var(--bl-surface-card) !important;
}
[data-theme="dark"] .bg-blue-50,
[data-theme="dark"] .bg-green-50,
[data-theme="dark"] .bg-yellow-50,
[data-theme="dark"] .bg-red-50,
[data-theme="dark"] .bg-purple-50,
[data-theme="dark"] .bg-red-50\/40 {
background-color: var(--bl-surface-muted) !important;
}
[data-theme="dark"] .text-gray-900,
[data-theme="dark"] .text-gray-800,
[data-theme="dark"] .text-gray-700 {
color: var(--bl-text-primary) !important;
}
[data-theme="dark"] .text-gray-600,
[data-theme="dark"] .text-gray-500,
[data-theme="dark"] .text-gray-400,
[data-theme="dark"] .text-gray-300 {
color: var(--bl-text-secondary) !important;
}
[data-theme="dark"] .border-gray-100,
[data-theme="dark"] .border-gray-200,
[data-theme="dark"] .border-gray-300,
[data-theme="dark"] .border-gray-600 {
border-color: var(--bl-border) !important;
}
[data-theme="dark"] .border-blue-200,
[data-theme="dark"] .border-green-200,
[data-theme="dark"] .border-yellow-200,
[data-theme="dark"] .border-red-200,
[data-theme="dark"] .border-purple-200 {
border-color: var(--bl-border) !important;
}
[data-theme="dark"] input,
[data-theme="dark"] select,
[data-theme="dark"] textarea {
background-color: var(--bl-input) !important;
border-color: var(--bl-border) !important;
color: var(--bl-text-primary) !important;
}
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder {
color: var(--bl-text-tertiary) !important;
}
[data-theme="dark"] .shadow,
[data-theme="dark"] .shadow-md,
[data-theme="dark"] .shadow-lg,
[data-theme="dark"] .shadow-xl,
[data-theme="dark"] .shadow-sm {
box-shadow: var(--bl-shadow-sm) !important;
}
@media (hover: hover) {
[data-theme="dark"] .hover\:bg-gray-50:hover,
[data-theme="dark"] .hover\:bg-gray-100:hover,
[data-theme="dark"] .hover\:bg-gray-200:hover {
background-color: var(--bl-surface-muted) !important;
}
[data-theme="dark"] .hover\:text-gray-600:hover,
[data-theme="dark"] .hover\:text-gray-700:hover {
color: var(--bl-text-primary) !important;
}
}

View File

@ -23,6 +23,7 @@ import { useAuth } from '@/lib/auth';
const THEME_STORAGE_KEY = 'bytelyst.theme.v1';
const SIDEBAR_STORAGE_KEY = 'bytelyst.devops.sidebar.collapsed.v1';
const THEME_EVENT = 'bytelyst-theme-change';
type Theme = 'light' | 'dark';
const navItems = [
@ -46,6 +47,14 @@ export function SidebarNav() {
const [theme, setTheme] = useState<Theme>('dark');
useEffect(() => {
function handleThemeChange(event: Event) {
const next = (event as CustomEvent<Theme>).detail;
if (next === 'light' || next === 'dark') {
setTheme(next);
applyTheme(next);
}
}
try {
const savedTheme = window.localStorage.getItem(THEME_STORAGE_KEY) as Theme | null;
const legacyTheme = window.localStorage.getItem('theme') as Theme | null;
@ -61,6 +70,9 @@ export function SidebarNav() {
} catch {
applyTheme('dark');
}
window.addEventListener(THEME_EVENT, handleThemeChange);
return () => window.removeEventListener(THEME_EVENT, handleThemeChange);
}, []);
function applyTheme(next: Theme) {
@ -75,6 +87,7 @@ export function SidebarNav() {
try {
window.localStorage.setItem(THEME_STORAGE_KEY, next);
window.localStorage.setItem('theme', next);
window.dispatchEvent(new CustomEvent(THEME_EVENT, { detail: next }));
} catch {
// localStorage can be unavailable in private browsing.
}

View File

@ -13,6 +13,7 @@ import { Button } from '@/components/ui/Primitives';
// `app/layout.tsx`.
const STORAGE_KEY = 'bytelyst.theme.v1';
const THEME_EVENT = 'bytelyst-theme-change';
type Theme = 'dark' | 'light';
const THEMES: Theme[] = ['dark', 'light'];
@ -30,6 +31,7 @@ function readPersisted(): Theme {
function applyTheme(theme: Theme) {
if (typeof document === 'undefined') return;
document.documentElement.setAttribute('data-theme', theme);
document.documentElement.classList.toggle('dark', theme === 'dark');
}
export function ThemeToggle() {
@ -37,14 +39,31 @@ export function ThemeToggle() {
const [theme, setTheme] = useState<Theme>('dark');
useEffect(() => {
setTheme(readPersisted());
const persisted = readPersisted();
setTheme(persisted);
applyTheme(persisted);
function handleThemeChange(event: Event) {
const next = (event as CustomEvent<Theme>).detail;
if ((THEMES as string[]).includes(next)) {
setTheme(next);
applyTheme(next);
}
}
window.addEventListener(THEME_EVENT, handleThemeChange);
return () => window.removeEventListener(THEME_EVENT, handleThemeChange);
}, []);
const toggle = useCallback(() => {
setTheme((prev) => {
const next = prev === 'dark' ? 'light' : 'dark';
try {
if (typeof window !== 'undefined') window.localStorage.setItem(STORAGE_KEY, next);
if (typeof window !== 'undefined') {
window.localStorage.setItem(STORAGE_KEY, next);
window.localStorage.setItem('theme', next);
window.dispatchEvent(new CustomEvent(THEME_EVENT, { detail: next }));
}
} catch {
// ignore
}