Conversation
7150a3c to
875d61e
Compare
There was a problem hiding this comment.
Pull request overview
Adds a dark-mode implementation to the democracy/desktop Next.js app using Tailwind’s dark: variants, with pre-paint theme application to avoid FOUC and a UI toggle in the navigation.
Changes:
- Enable Tailwind
darkMode: 'class'and add base background styling forhtml/html.dark. - Introduce a
useThemehook and an inline_documentscript to apply the theme early and persist preference. - Apply
dark:variants across key UI components (navigation, cards, filters, details, dialogs, charts).
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| democracy/desktop/tailwind.config.js | Enables class-based dark mode for Tailwind. |
| democracy/desktop/src/utils/useTheme.ts | Adds theme hook with persistence + applying dark class. |
| democracy/desktop/src/styles/global.css | Sets base background for html and html.dark. |
| democracy/desktop/src/pages/_document.tsx | Injects blocking inline theme script + dark body background. |
| democracy/desktop/src/templates/Main.tsx | Adds dark-mode text/footer styling. |
| democracy/desktop/src/components/molecules/Navigation.tsx | Adds theme toggle button + dark nav/search styles. |
| democracy/desktop/src/components/molecules/Card.tsx | Adds dark card background/border/text styling. |
| democracy/desktop/src/components/templates/FilteredPage.tsx | Adds dark header + sticky group header background. |
| democracy/desktop/src/pages/[...details].tsx | Adds dark styling for details panel, text, dividers, docs list. |
| democracy/desktop/src/components/molecules/Filters.tsx | Adds dark styling for filter panel, dividers, labels, checkboxes. |
| democracy/desktop/src/components/molecules/FilterDropdown.tsx | Adds dark dropdown/menu item styling. |
| democracy/desktop/src/components/organisms/DonateDialog.tsx | Adds dark dialog background/text + focus ring offset. |
| democracy/desktop/src/components/molecules/ChartPair.tsx | Adds dark chart container + ring background/text styling. |
You can also share your feedback on Copilot code review. Take the survey.
| const getInitialTheme = (): Theme => { | ||
| if (typeof window === 'undefined') return 'light'; | ||
| const stored = localStorage.getItem(STORAGE_KEY) as Theme | null; | ||
| if (stored === 'dark' || stored === 'light') return stored; | ||
| return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; | ||
| }; |
There was a problem hiding this comment.
getInitialTheme/toggleTheme call localStorage.getItem/setItem without guarding for unavailable/throwing storage (e.g. Safari private mode, disabled storage). In this codebase donateDialogStorage explicitly checks typeof window !== 'undefined' && window.localStorage and wraps storage calls in try/catch; doing the same here would prevent the theme hook from crashing the app on mount or click.
There was a problem hiding this comment.
Done in a56488b. All localStorage access in useTheme.ts is now wrapped in try/catch (matching the pattern in donateDialogStorage.ts). The STORAGE_KEY constant is now exported and imported into _document.tsx so the key is defined in one place and can't drift.
| <button | ||
| type="button" | ||
| onClick={toggleTheme} | ||
| className="rounded-md p-2 text-gray-500 hover:bg-gray-100 hover:text-gray-700 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-ci-blue dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-200" | ||
| aria-label={theme === 'dark' ? 'Zu hellem Modus wechseln' : 'Zu dunklem Modus wechseln'} | ||
| > | ||
| {theme === 'dark' ? ( | ||
| <SunIcon className="h-5 w-5" aria-hidden="true" /> | ||
| ) : ( | ||
| <MoonIcon className="h-5 w-5" aria-hidden="true" /> | ||
| )} |
There was a problem hiding this comment.
The theme toggle’s icon/aria-label depends on theme from useTheme, but useTheme initializes state to 'light' and only syncs to the real theme in an effect. When the pre-paint _document script applies html.dark, the first render can briefly show the wrong icon/label (e.g. dark theme applied but button says “switch to dark”). Consider exposing an initialized flag from the hook and rendering the toggle only after initialization, or deriving the initial value from document.documentElement.classList in a way that avoids hydration mismatch.
There was a problem hiding this comment.
Done in 7888c7c. useTheme now exposes an initialized flag that becomes true after the first effect run. The toggle button in Navigation is only rendered when initialized === true, so the icon/aria-label are never shown with stale SSR state — no hydration mismatch.
| const themeScript = ` | ||
| (function() { | ||
| try { | ||
| var stored = localStorage.getItem('democracy-theme'); | ||
| var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; | ||
| if (stored === 'dark' || (!stored && prefersDark)) { | ||
| document.documentElement.classList.add('dark'); | ||
| } |
There was a problem hiding this comment.
The localStorage key 'democracy-theme' is duplicated here and in useTheme.ts (STORAGE_KEY). Consider importing a shared exported constant (or exporting the key from useTheme.ts) so the inline script and hook can’t drift if the key ever changes.
There was a problem hiding this comment.
Already addressed in a56488b — _document.tsx imports STORAGE_KEY from useTheme.ts and interpolates it into the inline script, so the key is defined in one place.
|
TODO: das democracy logo sollte noch ausgetauscht werden im dark mode damit der Schriftzug nicht schwarz auf dunkel sondern weiß ist. |
Co-authored-by: ManAnRuck <2183135+ManAnRuck@users.noreply.github.com>
…gation Co-authored-by: ManAnRuck <2183135+ManAnRuck@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2119d3b to
9fc3ca6
Compare
…e logo Co-authored-by: ManAnRuck <2183135+ManAnRuck@users.noreply.github.com>
Done in a56488b. Added |
…e render Co-authored-by: ManAnRuck <2183135+ManAnRuck@users.noreply.github.com>
darkMode: 'class'in tailwind.config.jsuseThemehook with localStorage + system preference detectionSTORAGE_KEYconstant to share with_document.tsxsetThemedead codeinitializedflag; set totrueafter first effect run_document.tsxusing sharedSTORAGE_KEYinitialized === trueto avoid hydration icon mismatchlogo-text-dark.svg— white-text version for dark modeOriginal prompt
Start implementation
The user has attached the following file paths as relevant context:
- .github/copilot-instructions.md
[Chronological Review: The conversation began with the user requesting the addition of a dark mode to the democracy/desktop project, emphasizing the need for good aesthetics and readability of text. The user was working within the context of the garden.yml file, specifically focusing on the configuration related to the "democracy-desktop" target.][Intent Mapping: The explicit user request was to "add a dark mode to democracy/desktop that looks good and ensures all text is readable." This indicates a focus on UI/UX improvements for the desktop application.]
[Technical Inventory: The conversation involved the garden.yml configuration file, which is used for managing build and deployment settings in the project. The user is working with a deployment target named "democracy-desktop."]
[Code Archaeology: The user is currently editing the garden.yml file, particularly lines related to the deployment configuration for "democracy-desktop." The relevant sections include manifest templates, default target settings, sync paths, and resource patches.]
[Progress Assessment: The user has not yet implemented the dark mode feature; the request is still pending. The current state is focused on understanding the existing configuration before proceeding with the dark mode implementation.]
[Context Validation: All critical information for continuation is captured, including the user's request for a dark mode and the specific file being edited.]
[Recent Commands Analysis: The last agent commands involved retrieving the contents of the garden.yml file, specifically focusing on the "democracy-desktop" target. The tool results included the configuration details of the file, which are essential for understanding how to implement the requested dark mode. The agent was actively working on providing context from the garden.yml file when the token budget was exceeded.]
1. Conversation Overview: - Primary Objectives: The user requested to "add a dark mode to democracy/desktop that looks good and ensures all text is readable." - Session Context: The conversation has focused on the user's intention to enhance the UI of the democracy/desktop application by implementing a dark mode, with specific attention to aesthetics and readability. - User Intent Evolution: The user's needs have remained consistent, centered around improving the visual design of the application.- Technical Foundation:
- Core Technology: Garden (a build and deployment tool) is being used to manage the project.
- Framework/Library: The project is structured using YAML configuration for deployment settings.
- Architectural Pattern: The deployment target is defined in the garden.yml file, which includes sync paths and resource patches.
- Codebase Status:
- File Name: garden.yml
- Purpose: This file is crucial for defining the build and deployment settings for the democracy/desktop application.
- Current State: The user is currently focused on the section related to the "democracy-desktop" deployment target.
- Key Code Segments: The file includes settings for manifest templates, default target, sync paths, and resource patches.
- Dependencies: The configuration directly impacts how the application is built and deployed.
- Problem Resolution:
- Issues Encountered: No specific technical problems have been reported yet; the focus is on the implementation of the dark mode.
- Solutions Implemented: None yet, as the request is still in the planning phase.
- Debugging Context: No ongoing troubleshooting efforts have been mentioned.
- Lessons Learned: The importance of aesthetics and readability in UI design has been highlighted.
- Progress Tracking:
- Completed Tasks: No tasks have been completed regarding the dark mode implementation.
- Partially Complete Work: The user is in the process of planning the dark mode feature.
- Validated Outcomes: No features have been confirmed working through testing yet.
- Active Work State:
- Current Focus: The user is working on the garden.yml file to prepare for the dark mode implementation.
- Recent Context: The user has been reviewing the configuration settings for the "democracy-desktop" target in the garden.yml file.
- Working Code: The relevant code segments from the garden.yml file have been retrieved for context.
- Immediate Context: The user is preparing to implement a dark mode feature for the application.
- Recent Operations:
- Last Agent Commands: The agent retrieved the contents of the garden.yml file, focusing on the "democracy-desktop" target.
- Tool Results Summary: The results included the configuration details for the deployment target, which are essential for understanding how to implement the dark mode.
- Pre-Summary State: The agent was actively providing context from the garden.yml file when the token budget was exceeded.
- Operation Context: T...
Created from VS Code.
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.