fix: complete devops theme compatibility
This commit is contained in:
parent
d6fa1d9e28
commit
09b16c4b19
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user