DSingh0304 opened a new issue, #3322:
URL: https://github.com/apache/apisix-dashboard/issues/3322

   ## Summary
   
   Add dark mode theme support to the APISIX Dashboard, allowing users to 
switch between light, dark, and system preferred color schemes. This improves 
accessibility, reduces eye strain in low light environments, and aligns the 
dashboard with modern UI standards.
   
   ## Motivation
   
   - Users frequently work with the dashboard for extended periods; dark mode 
reduces eye fatigue
   - Many modern admin dashboards (Grafana, Kibana, Cloudflare) offer dark mode 
as a standard feature
   - System level dark mode preferences (`prefers-color-scheme`) are widely 
adopted across OSes
   - Improved accessibility and WCAG compliance
   
   ## Current Architecture
   
   The dashboard currently uses a **light-only theme** with two UI libraries 
running side by side:
   
   | Layer | Library | Usage |
   |-------|---------|-------|
   | **Layout shell** | Mantine v8 (`@mantine/core`) | `AppShell`, `Header`, 
`Navbar`, form inputs (`TextInput`, `Select`, `TagsInput`, etc.), `Modal`, 
`Drawer`, `Notifications`, `Button`, `Group` |
   | **Data tables** | Ant Design v5 + Pro Components (`antd`, 
`@ant-design/pro-components`) | `ProTable` across all list pages (routes, 
consumers, upstreams, services, SSLs, secrets, etc.) |
   | **Code editor** | Monaco Editor (`@monaco-editor/react`) | JSON/YAML 
editing in forms, currently hardcoded to `vs-light` theme |
   | **State management** | Jotai (`jotai`) | `atomWithStorage` for persisted 
settings (admin key) |
   | **Icons** | Unplugin Icons (`@iconify-json/material-symbols`) | Material 
Symbols icon set |
   | **Styling** | PostCSS with Mantine preset | CSS variables 
(`--mantine-color-*`), minimal custom CSS in `global.css` |
   
   ### Key observations
   
   - **Mantine** is the primary UI library, it has **first-class dark mode 
support** via `MantineProvider` with a `forceColorScheme` or `colorScheme` prop 
and a `useMantineColorScheme` hook
   - **Ant Design** is used only for `ProTable` , its `ConfigProvider` already 
accepts a `theme.algorithm` prop (`theme.darkAlgorithm`) for dark mode
   - **Monaco Editor** supports `vs-dark` theme out of the box
   - **Jotai** `atomWithStorage` is already used for persistent settings, same 
pattern can store the color scheme preference
   - Custom CSS in `global.css` already uses Mantine CSS variables 
(`--mantine-color-gray-*`), which automatically adapt when Mantine's color 
scheme changes
   
   ## Implementation Plan
   
   ### Phase 1: Theme Infrastructure
   
   **Goal**: Wire up the theme switching mechanism across all three UI layers.
   
   1. **Add color scheme atom** in `src/stores/global.ts`:
      - Create a `colorSchemeAtom` using `atomWithStorage` with values `'light' 
| 'dark' | 'auto'`
      - Default to `'auto'` (respect system preference)
   
   2. **Update `MantineProvider`** in `src/main.tsx`:
      - Read the `colorSchemeAtom` value
      - Pass `forceColorScheme` (or use `defaultColorScheme` + 
`useMantineColorScheme`) to `MantineProvider`
      - Mantine components will automatically adapt no per component changes 
needed
   
   3. **Update `AntdConfigProvider`** in `src/config/antdConfigProvider.tsx`:
      - Conditionally apply `theme.darkAlgorithm` based on the active color 
scheme
      - This makes all `ProTable` instances dark-mode aware without touching 
individual table files
   
   4. **Update Monaco Editor** in `src/components/form/Editor.tsx`:
      - Change the hardcoded `theme: 'vs-light'` to dynamically use `'vs-dark'` 
when dark mode is active
   
   ### Phase 2: Theme Toggle UI
   
   **Goal**: Provide a user-facing control to switch themes.
   
   1. **Create `ThemeToggle` component** in `src/components/Header/`:
      - A segmented control or action icon button with three states: Light ☀️ / 
Dark 🌙 / Auto 💻
      - Uses `useAtom(colorSchemeAtom)` to read/write the preference
      - Placed in the header alongside the existing `SettingModalBtn` and 
`LanguageMenu`
   
   2. **Update `Header/index.tsx`**:
      - Add `<ThemeToggle />` to the right-side `Group`
   
   ### Phase 3: Custom CSS Adjustments
   
   **Goal**: Fix any remaining hardcoded colors that don't adapt automatically.
   
   1. **Audit `global.css`**:
      - The Monaco editor wrapper uses `--mantine-color-gray-0`, 
`--mantine-color-gray-3`, etc. these auto-adapt with Mantine's dark mode
      - Verify and fix any remaining hardcoded hex colors
   
   2. **Audit inline styles**:
      - Search for any hardcoded color values in `.tsx` files (e.g., `color: 
'#xxx'`, `bg="white"`)
      - Replace with Mantine color tokens or CSS variables
   
   ### Phase 4: Testing & Polish
   
   1. **Visual verification** of all pages in both themes:
      - All list pages (routes, services, upstreams, consumers, SSLs, etc.)
      - All detail/edit forms
      - Settings modal
      - Navigation sidebar
      - Monaco editor
   
   2. **Contrast** ratio checks (WCAG AA ≥ 4.5:1) using browser DevTools or 
Lighthouse
   
   3. **Transition smoothness**: Add CSS transition (`transition: 
background-color 0.2s, color 0.2s`) on `body` for a non jarring switch
   
   4. **E2E tests**: Add a basic test to verify theme persistence across page 
reloads
   
   ## Files to Modify
   
   | File | Change |
   |------|--------|
   | `src/stores/global.ts` | Add `colorSchemeAtom` with `atomWithStorage` |
   | `src/main.tsx` | Wire `colorSchemeAtom` to `MantineProvider` color scheme |
   | `src/config/antdConfigProvider.tsx` | Conditionally apply 
`theme.darkAlgorithm` |
   | `src/components/form/Editor.tsx` | Dynamic Monaco theme (`vs-light` / 
`vs-dark`) |
   | `src/components/Header/index.tsx` | Add `ThemeToggle` to header |
   | `src/styles/global.css` | Audit and fix any hardcoded colors |
   
   ## New Files
   
   | File | Purpose |
   |------|---------|
   | `src/components/Header/ThemeToggle.tsx` | Theme switcher UI component 
(Light / Dark / Auto) |
   
   ## Why This Is Low Risk
   
   - **Mantine v8** handles dark mode natively most components just work
   - **Ant Design v5** `ConfigProvider` dark algorithm is a one line change
   - **Monaco** has built in `vs-dark` theme
   - The custom CSS is minimal (one file, ~60 lines) and already uses CSS 
variables
   - State persistence pattern (`atomWithStorage`) is already established in 
the codebase
   - No structural or architectural changes are needed this is purely additive
   
   ## Open Questions
   
   - [ ] Should the default be `auto` (follow system) or `light` (current 
behavior)?
   - [ ] Preferred toggle UI: segmented control in header, or a dropdown/icon 
button?
   - [ ] Any specific brand color adjustments for dark mode? 
   
   ## References
   
   - [Mantine Dark Mode Guide](https://mantine.dev/guides/dark-theme/)
   - [Ant Design Dark 
Theme](https://ant.design/docs/react/customize-theme#use-dark-theme)
   - [Monaco Editor Themes](https://microsoft.github.io/monaco-editor/)
   


-- 
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]

Reply via email to