Skip to content

Implement dark mode#5740

Merged
mstange merged 39 commits intofirefox-devtools:mainfrom
arai-a:dark-mode
Jan 20, 2026
Merged

Implement dark mode#5740
mstange merged 39 commits intofirefox-devtools:mainfrom
arai-a:dark-mode

Conversation

@arai-a
Copy link
Contributor

@arai-a arai-a commented Dec 27, 2025

Deploy preview home, Deploy preview profile

Fixed #2097

This patch stack implements the dark mode:

  • almost all colors and icons are moved to variables
  • the variables are defined either in the root, or as the element internal variables
  • canvas-related colors are handled in the script side, with a new dark-mode module added
home profiler

This stack doesn't cover the user documents.

@codecov
Copy link

codecov bot commented Dec 27, 2025

Codecov Report

❌ Patch coverage is 93.26923% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.71%. Comparing base (b362390) to head (28467d6).
⚠️ Report is 41 commits behind head on main.

Files with missing lines Patch % Lines
src/components/marker-chart/Canvas.tsx 85.18% 4 Missing ⚠️
src/index.tsx 0.00% 1 Missing ⚠️
src/profile-logic/graph-color.ts 0.00% 1 Missing ⚠️
src/utils/colors.ts 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5740      +/-   ##
==========================================
+ Coverage   85.69%   85.71%   +0.01%     
==========================================
  Files         316      317       +1     
  Lines       31141    31216      +75     
  Branches     8574     8595      +21     
==========================================
+ Hits        26686    26756      +70     
- Misses       4025     4030       +5     
  Partials      430      430              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@arai-a
Copy link
Contributor Author

arai-a commented Jan 3, 2026

This patch stack allows controlling the color for HCM more easily.
I'll prepare another patch stack to improve the HCM after this.
(prototype: https://github.com/arai-a/profiler/tree/hcm)

@mstange
Copy link
Contributor

mstange commented Jan 9, 2026

Very cool! Thank you!

Is there a way we could land this off-by-default? I'd like to tweak some colors but I don't want this PR to bitrot in the meantime.

Also, Nazim said he probably prefers the profiler in light mode even though he's using his operating system and browser in dark mode... I don't really agree with that idea (I think website-internal theme toggle buttons are silly) but it suggests that it might be a good idea to have a way to opt out. I'm fine with the opt-in/opt-out being rather hidden if that makes the implementation easier. For example it could be a function you call from the console, or an alternate stylesheet that you access via View -> Page Style -> ... in Firefox

@arai-a
Copy link
Contributor Author

arai-a commented Jan 9, 2026

Sure, I'll look into making it configurable.
The canvas-related things need to be made in sync with the CSS, so we need something JavaScript-initiated, or possibly the opposite way by detecting some CSS variable from JavaScript.

@arai-a arai-a requested a review from a team as a code owner January 9, 2026 17:45
@arai-a
Copy link
Contributor Author

arai-a commented Jan 9, 2026

Make it controlled by localStorage "theme" item, which sets/unsets "dark-mode" class on <html> element,
and modified each style rule to use the :root.dark-mode selector.
Some rules are moved/reordered to make stylelint happy.

Without the last patch, it's controllable by setDarkMode()/setLightMode() functions from console.

With the last patch, it's exposed to the home view, and the above functions are no longer exposed.
checkbox

@arai-a
Copy link
Contributor Author

arai-a commented Jan 9, 2026

Actually, the :root.dark-mode FOO selector interacts badly with the current HCM styling, given it has higher selectivity than the media query @media (forced-colors: active) { ... },
and now the dark mode colors overwrites the HCM rules.

I'll look into making things inside @media (forced-colors: active) have more priority.

@arai-a
Copy link
Contributor Author

arai-a commented Jan 9, 2026

Added a temporary fix for the HCM coloring.
ultimately the HCM should also use the CSS variables, but that's for another bug, which I already have prototype.
Another option is to hide the checkbox until the HCM styling gets fully fixed (so, remove the topmost 2 commits).

Copy link
Contributor

@flodolo flodolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(just for the string)

@mstange mstange self-requested a review January 17, 2026 03:01
Copy link
Contributor

@mstange mstange left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the long delay! Code-wise this looks good. Thank you for doing this work!

I noticed the following changes in the light mode theme:

  • #profileViewerTopBar is now using --base-background-color, should be using --panel-background-color instead
  • .timelineTrackRow.selected used to have a light blue background and now has a light gray background
  • The link colours have changed.

Could you revert these changes in a follow-up? Thanks!

@mstange mstange merged commit 25763b4 into firefox-devtools:main Jan 20, 2026
22 checks passed
@arai-a arai-a mentioned this pull request Jan 20, 2026
mstange added a commit that referenced this pull request Jan 21, 2026
Followup fix for #5740

This does:
  * Fix the profile viewer background color (it was different variable)
* Fix the selected track background color (wrong variable name was used
in the definition)
* Revert the link color (now it uses the system color instead of photon
colors)
@canova canova mentioned this pull request Jan 27, 2026
canova added a commit that referenced this pull request Jan 27, 2026
Lots of exciting changes 🎉:

[arai-a] Put radio buttons into labels (#5738)
[DaniPopes] Update comment for "unique-string" (#5741)
[Karan Pradhan] Hide tooltip filter button in non-sticky tooltips and
add hideFilterButton tests (#5718)
[arai-a] Add a menu to copy the Marker Table as text (#5732)
[arai-a] Make the entire list item clickable for the "Full Range"
(#5742)
[Markus Stange] Move symbol table demangling out of SymbolStore into
SymbolProvider (#5746)
[Markus Stange] Remove SVG asset imports from profile-data.ts (#5747)
[arai-a] Do not apply sticky tooltip on double click (#5754)
[arai-a] Skip the ChartCanvas redraw on the Viewport's internal default
state usage (#5744)
[Markus Stange] Stop blindly extracting uint8array.buffer after calling
compress() (#5753)
[Markus Stange] In the assembly view state, refer to the current symbol
by index (#5755)
[Markus Stange] Fix "scroll to hotspot" functionality in the source view
+ assembly view (#5759)
[Markus Stange] Keep the colorField markerSchema field when processing
profiles in the gecko format (#5760)
[Markus Stange] Implement dark mode (#5740)
[Markus Stange] Fix light-mode colors (#5765)
[Markus Stange] Tweak dark mode colours. (#5767)
[Nazım Can Altınova] Enable some basic type-aware lints (#5775)
[Markus Stange] Allow seeing different assembly code for the same
function (#5349)
[fatadel] Refine tree view a11y (#5779)
[fatadel] Align double-click behavior of stack chart with flame graph
(#5782)
[Markus Stange] Split gz.ts properly into node and browser variants
(#5764)
[Markus Stange] Simplify and optimize the computation of per-call-node
line and address timings (#5770)
[Nazım Can Altınova] Move the dark mode toggle to devtools console
(#5783)
[Nazım Can Altınova] 🔃 Sync: l10n -> main (Jan 27, 2026) (#5785)
[Nazım Can Altınova] Improve Chrome importer marker payload logic
(#5717)
[Markus Stange] Add a Focus Self transform (#5774)
[Nazım Can Altınova] Enable the Turkish locale in production (#5786)


And huge thanks to our localizers 🎉 :

be: Mikalai Udodau
de: Ger
de: Michael Köhler
el: Jim Spentzos
en-CA: chutten
en-CA: Saurabh
en-GB: Ian Neal
en-GB: Saurabh
es-CL: ravmn
fy-NL, nl: Fjoerfoks
fr: Skywarp
fr: Théo Chevalier
fur: Fabio Tomat
fy-NL: Fjoerfoks
ia: Melo46
it: Francesco Lodolo [:flod]
nl: Fjoerfoks
nl: Mark Heijl
pt-BR: Marcelo Ghelman
ru: berry
ru: Valery Ledovskoy
sv-SE: Andreas Pettersson
tr: Grk
zh-CN: Olvcpr423
zh-CN: wxie
zh-TW: Pin-guang Chen
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement a dark mode in the profiler UI

3 participants