zhaohai666 opened a new pull request, #435:
URL: https://github.com/apache/rocketmq-dashboard/pull/435
## Summary
Introduce centralized theme management built on React Context, refactor
scattered local dark mode `useState` inside `MainLayout`. The exported
`useTheme` hook exposes `darkMode`, `setDarkMode` and `toggleTheme`, following
the same design pattern as existing `useLang` i18n hook.
## Changes
| File | Type | Description |
|------|------|-------------|
| `web/src/theme/ThemeContext.tsx` | Added | Implement `ThemeProvider` and
`useTheme` hook with TypeScript. Load initial theme preference from
`localStorage`, fall back to system `prefers-color-scheme`. Automatically
persist updated selection to `localStorage`. |
| `web/src/layouts/MainLayout.tsx` | Modified | Remove local
`useState(false)` dark mode state, consume shared state via `useTheme()`.
Delete redundant inline `ConfigProvider` theme wrapper (moved globally).
Replace manual `() => setDarkMode(!darkMode)` calls with built-in
`toggleTheme`. |
| `web/src/main.tsx` | Modified | Wrap root application with
`<ThemeProvider>`. Lift Ant Design `ConfigProvider` theme logic to entry level;
`darkAlgorithm` / `defaultAlgorithm` switching and dark-mode token overrides
apply globally for the whole app. |
## Design Decisions
1. **React Context instead of Redux**
The codebase already adopts React Context for i18n (`LangContext`) and
Zustand for authentication & cluster state. Theme state is presentation-layer
UI state and mainly consumed inside layout components. React Context keeps
consistent architecture with internationalization module, avoiding heavy state
library dependency for a single boolean flag.
2. **localStorage persistence**
User selected theme will survive page refresh. Storage key:
`rocketmq-studio-theme`.
3. **System color scheme fallback**
For first-time visitors without saved preference, automatically detect OS
appearance via `window.matchMedia('(prefers-color-scheme: dark)')`.
4. **Global root ConfigProvider**
Moving theme algorithm switching out of `MainLayout` guarantees all Ant
Design components (including standalone modals created by `ReactDOM.createRoot`
outside layout tree) correctly render dark style.
## Hook API Usage
```typescript
import { useTheme } from '../theme/ThemeContext';
const { darkMode, setDarkMode, toggleTheme } = useTheme();
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]