feat: add light/dark theme toggle to studio chrome - #148
jackgranatowski wants to merge 1 commit into
Conversation
Re-syncs configurator/src (the SLASHED framework added a light/dark theme toggle to the Studio chrome) and rebuilds the admin SPA bundle. Also pins AppOverlay.svelte's root to the `dark` class: it reuses SidebarNav/DomainPanel/CommandPalette from the vendored core, which now default to light unless an ancestor opts into dark via Tailwind's class-based dark variant. The frontend overlay's own shell markup is plugin-specific and still hardcoded dark, so forcing `dark` on its root keeps the embedded components visually consistent with it instead of mismatching (light nav inside a dark shell).
|
Warning Review limit reached
Next review available in: 59 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (38)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Summary by QodoAdd light/dark theme toggle to Studio chrome
AI Description
Diagram
High-Level Assessment
Files changed (38)
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
5 rules 1. src/App.svelte vendored edited
|
| aria-pressed={mobileView === view} | ||
| class={`flex-1 flex items-center justify-center gap-1.5 py-2.5 text-[11px] font-bold transition-colors cursor-pointer ${ | ||
| mobileView === view ? "text-indigo-300 bg-indigo-500/10" : "text-slate-500 hover:text-slate-300" | ||
| mobileView === view ? "text-indigo-700 dark:text-indigo-300 bg-indigo-500/10" : "text-slate-500 hover:text-slate-700 dark:hover:text-slate-300" |
There was a problem hiding this comment.
1. src/app.svelte vendored edited 📘 Rule violation § Compliance
The PR modifies SLASHED-for-WP/admin-app/src/App.svelte, which is listed as a vendored file in SLASHED-for-WP/admin-app/.vendored-manifest.json. Per the checklist, files listed in the vendored manifest must not be changed in this repository.
Agent Prompt
## Issue description
Files listed in `SLASHED-for-WP/admin-app/.vendored-manifest.json` are being modified in this PR (e.g., `src/App.svelte`). The compliance rule requires that these vendored files are not changed directly in this repository.
## Issue Context
`SLASHED-for-WP/admin-app/.vendored-manifest.json` explicitly tracks vendored files; changes should be applied in the upstream/framework source and then re-vendored into this repo via the normal sync/vendoring mechanism.
## Fix Focus Areas
- SLASHED-for-WP/admin-app/src/App.svelte[264-264]
- SLASHED-for-WP/admin-app/.vendored-manifest.json[9-17]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| if (typeof matchMedia !== "undefined") { | ||
| matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => { | ||
| if (!followSystem) return; | ||
| themeState.value = e.matches ? "dark" : "light"; | ||
| applyToRoot(); | ||
| }); |
There was a problem hiding this comment.
2. Matchmedia listener crash risk 🐞 Bug ☼ Reliability
theme.svelte.ts calls MediaQueryList.addEventListener at module-evaluation time without feature-detecting the method, which can throw in environments where only addListener exists and abort loading the entire bundle. Because plugin-main.ts imports main.ts unconditionally, an import-time throw prevents the frontend overlay bootstrap from running too.
Agent Prompt
### Issue description
`src/lib/theme.svelte.ts` registers a `prefers-color-scheme` change handler at module load via `matchMedia(...).addEventListener(...)` without checking whether `addEventListener` exists on the returned `MediaQueryList`. In environments that only support `addListener`, this throws during module import and can prevent the entire plugin JS entry from executing.
### Issue Context
This module is imported by `src/main.ts`, and `src/plugin-main.ts` imports `main.ts` unconditionally, so any import-time exception can stop the overlay bootstrap from running.
### Fix Focus Areas
- SLASHED-for-WP/admin-app/src/lib/theme.svelte.ts[61-67]
### Suggested fix
- Create and reuse a `const mql = matchMedia('(prefers-color-scheme: dark)')`.
- Register the handler using:
- `mql.addEventListener?.('change', handler)` when available, else
- `mql.addListener(handler)` as a fallback.
- (Optional, preferred) move the listener registration behind an initialization function that is called from `bindThemeRoot()` so it only runs when the studio chrome is actually mounted/bound.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| <button | ||
| onclick={toggleTheme} | ||
| title={themeState.value === "dark" ? "Switch to light mode" : "Switch to dark mode"} | ||
| class="p-1.5 rounded-lg text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white hover:bg-black/8 dark:hover:bg-white/8 transition-all cursor-pointer" | ||
| > | ||
| {#if themeState.value === "dark"} | ||
| <Sun class="w-3.5 h-3.5" /> | ||
| {:else} | ||
| <Moon class="w-3.5 h-3.5" /> | ||
| {/if} |
There was a problem hiding this comment.
3. Theme toggle missing aria 🐞 Bug ⚙ Maintainability
StudioHeader’s theme toggle is an icon-only button that relies on a title tooltip and does not expose an accessible name or pressed state, making it hard to use with assistive technology. This is a regression risk for accessibility expectations given past accessibility fixes in this codebase.
Agent Prompt
### Issue description
The theme toggle in `StudioHeader.svelte` is icon-only and currently relies on `title` for description. Screen readers need a stable accessible name and a state signal (e.g. `aria-pressed`) to understand and announce what the control does.
### Issue Context
The project has previously accepted accessibility fixes for toggles/controls; this button should follow the same standard.
### Fix Focus Areas
- SLASHED-for-WP/admin-app/src/components/shell/StudioHeader.svelte[167-177]
### Suggested fix
- Add `aria-label={themeState.value === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}`.
- Add `aria-pressed={themeState.value === 'dark'}` (or `aria-checked` with `role="switch"` if you prefer a switch semantic).
- Optionally add an `sr-only` text span to provide visible-in-AT labeling independent of `title`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
The upstream framework PR this synced from (SLASHED#500) has been split into a stacked chain of 3 smaller PRs for reviewability: codeslash-dev/SLASHED#506, #507, #508. I'm not splitting this PR the same way — every Generated by Claude Code |
Summary
Adds a light/dark theme toggle to the SLASHED Studio configurator UI, independent of the framework's own token theme. The studio chrome now respects the system's
prefers-color-schemepreference by default and allows users to manually override it, with the choice persisted in localStorage.All UI panels and components have been updated with Tailwind's
dark:variant to support both light and dark modes, ensuring consistent contrast and readability across the entire configurator interface.Type
Changes
New files
src/lib/theme.svelte.ts— Theme state management with system preference detection, manual override, and localStorage persistenceModified files
src/main.ts— Bind theme root element on app mountsrc/app.css— Add CSS comment documenting the theme systemsrc/components/shell/StudioHeader.svelte— Add Sun/Moon icons and theme toggle buttonTypographyPanel,ColorsPanel,MiscPanel,LayoutPanel,MacrosPanel,MotionPanel,EffectsPanel,BordersPanel,ShadowsPanel,SpacingPanel,WcagPanel,CheatsheetPanel,ThemesPanel,HomePanel,ExportPanel) — Update Tailwind classes withdark:variants for text, backgrounds, borders, and interactive statesSliderRow,ColorInput,PowerKnobRow,ClampField,OklchColorDesk,TokenRow,RangeWithNumber) — Add dark mode supportPreviewPanel,SidebarNav,StatusBar,DomainPanel,CommandPalette) — Update for light/dark themingAllTokensTab.svelte— Update search input styling for both modesUpdated manifest
.vendored-manifest.json— Synced from local framework source (timestamp updated)Notes
previewTheme), which only controls what the live preview iframe rendersslate-50backgrounds andslate-900/slate-800text; dark mode preserves the existing dark theme colorsChecklist
feat:)npm testpassesnpm run lintpassesnpm run verifypassesCHANGELOG.mdupdated (user-facing feature, should be added under## [Unreleased])assets/admin-app/app.js,assets/admin-app/app.css)https://claude.ai/code/session_01LmmKpKVFUw5XNAAJxPFQep