Skip to content

Commit 7271cac

Browse files
Dark mode support (#1913)
1 parent c1463a5 commit 7271cac

File tree

8 files changed

+242
-46
lines changed

8 files changed

+242
-46
lines changed

debug_toolbar/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"TOOLBAR_LANGUAGE": None,
4646
"IS_RUNNING_TESTS": "test" in sys.argv,
4747
"UPDATE_ON_FETCH": False,
48+
"DEFAULT_THEME": "auto",
4849
}
4950

5051

debug_toolbar/static/debug_toolbar/css/toolbar.css

Lines changed: 121 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* Variable definitions */
2-
:root {
2+
:root,
3+
#djDebug[data-theme="light"] {
34
/* Font families are the same as in Django admin/css/base.css */
45
--djdt-font-family-primary: "Segoe UI", system-ui, Roboto, "Helvetica Neue",
56
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
@@ -9,12 +10,79 @@
910
"Source Code Pro", "Fira Mono", "Droid Sans Mono", "Courier New",
1011
monospace, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
1112
"Noto Color Emoji";
13+
14+
color-scheme: light;
15+
--djdt-font-color: black;
16+
--djdt-background-color: white;
17+
--djdt-panel-content-background-color: #eee;
18+
--djdt-panel-content-table-background-color: var(--djdt-background-color);
19+
--djdt-panel-title-background-color: #ffc;
20+
--djdt-djdt-panel-content-table-strip-background-color: #f5f5f5;
21+
--djdt--highlighted-background-color: lightgrey;
22+
--djdt-toggle-template-background-color: #bbb;
23+
24+
--djdt-sql-font-color: #333;
25+
--djdt-pre-text-color: #555;
26+
--djdt-path-and-locals: #777;
27+
--djdt-stack-span-color: black;
28+
--djdt-template-highlight-color: #333;
29+
30+
--djdt-table-border-color: #ccc;
31+
--djdt-button-border-color: var(--djdt-table-border-color);
32+
--djdt-pre-border-color: var(--djdt-table-border-color);
33+
--djdt-raw-border-color: var(--djdt-table-border-color);
34+
}
35+
36+
@media (prefers-color-scheme: dark) {
37+
:root {
38+
color-scheme: dark;
39+
--djdt-font-color: #8393a7;
40+
--djdt-background-color: #1e293bff;
41+
--djdt-panel-content-background-color: #0f1729ff;
42+
--djdt-panel-title-background-color: #242432;
43+
--djdt-djdt-panel-content-table-strip-background-color: #324154ff;
44+
--djdt--highlighted-background-color: #2c2a7dff;
45+
--djdt-toggle-template-background-color: #282755;
46+
47+
--djdt-sql-font-color: var(--djdt-font-color);
48+
--djdt-pre-text-color: var(--djdt-font-color);
49+
--djdt-path-and-locals: #65758cff;
50+
--djdt-stack-span-color: #7c8fa4;
51+
--djdt-template-highlight-color: var(--djdt-stack-span-color);
52+
53+
--djdt-table-border-color: #324154ff;
54+
--djdt-button-border-color: var(--djdt-table-border-color);
55+
--djdt-pre-border-color: var(--djdt-table-border-color);
56+
--djdt-raw-border-color: var(--djdt-table-border-color);
57+
}
58+
}
59+
60+
#djDebug[data-theme="dark"] {
61+
color-scheme: dark;
62+
--djdt-font-color: #8393a7;
63+
--djdt-background-color: #1e293bff;
64+
--djdt-panel-content-background-color: #0f1729ff;
65+
--djdt-panel-title-background-color: #242432;
66+
--djdt-djdt-panel-content-table-strip-background-color: #324154ff;
67+
--djdt--highlighted-background-color: #2c2a7dff;
68+
--djdt-toggle-template-background-color: #282755;
69+
70+
--djdt-sql-font-color: var(--djdt-font-color);
71+
--djdt-pre-text-color: var(--djdt-font-color);
72+
--djdt-path-and-locals: #65758cff;
73+
--djdt-stack-span-color: #7c8fa4;
74+
--djdt-template-highlight-color: var(--djdt-stack-span-color);
75+
76+
--djdt-table-border-color: #324154ff;
77+
--djdt-button-border-color: var(--djdt-table-border-color);
78+
--djdt-pre-border-color: var(--djdt-table-border-color);
79+
--djdt-raw-border-color: var(--djdt-table-border-color);
1280
}
1381

1482
/* Debug Toolbar CSS Reset, adapted from Eric Meyer's CSS Reset */
1583
#djDebug {
16-
color: #000;
17-
background: #fff;
84+
color: var(--djdt-font-color);
85+
background: var(--djdt-background-color);
1886
}
1987
#djDebug,
2088
#djDebug div,
@@ -87,7 +155,7 @@
87155
outline: 0;
88156
font-size: 12px;
89157
line-height: 1.5em;
90-
color: #000;
158+
color: var(--djdt-font-color);
91159
vertical-align: baseline;
92160
background-color: transparent;
93161
font-family: var(--djdt-font-family-primary);
@@ -100,7 +168,7 @@
100168
#djDebug button {
101169
background-color: #eee;
102170
background-image: linear-gradient(to bottom, #eee, #cccccc);
103-
border: 1px solid #ccc;
171+
border: 1px solid var(--djdt-button-border-color);
104172
border-bottom: 1px solid #bbb;
105173
border-radius: 3px;
106174
color: #333;
@@ -268,10 +336,10 @@
268336

269337
#djDebug pre {
270338
white-space: pre-wrap;
271-
color: #555;
272-
border: 1px solid #ccc;
339+
color: var(--djdt-pre-text-color);
340+
border: 1px solid var(--djdt-pre-border-color);
273341
border-collapse: collapse;
274-
background-color: #fff;
342+
background-color: var(--djdt-background-color);
275343
padding: 2px 3px;
276344
margin-bottom: 3px;
277345
}
@@ -283,7 +351,7 @@
283351
right: 220px;
284352
bottom: 0;
285353
left: 0px;
286-
background-color: #eee;
354+
background-color: var(--djdt-panel-content-background-color);
287355
color: #666;
288356
z-index: 100000000;
289357
}
@@ -294,7 +362,7 @@
294362

295363
#djDebug .djDebugPanelTitle {
296364
position: absolute;
297-
background-color: #ffc;
365+
background-color: var(--djdt-panel-title-background-color);
298366
color: #666;
299367
padding-left: 20px;
300368
top: 0;
@@ -357,16 +425,16 @@
357425
}
358426

359427
#djDebug .djdt-panelContent table {
360-
border: 1px solid #ccc;
428+
border: 1px solid var(--djdt-table-border-color);
361429
border-collapse: collapse;
362430
width: 100%;
363-
background-color: #fff;
431+
background-color: var(--djdt-panel-content-table-background-color);
364432
display: table;
365433
margin-top: 0.8em;
366434
overflow: auto;
367435
}
368436
#djDebug .djdt-panelContent tbody > tr:nth-child(odd):not(.djdt-highlighted) {
369-
background-color: #f5f5f5;
437+
background-color: var(--djdt-panel-content-table-strip-background-color);
370438
}
371439
#djDebug .djdt-panelContent tbody td,
372440
#djDebug .djdt-panelContent tbody th {
@@ -392,7 +460,7 @@
392460
}
393461

394462
#djDebug .djTemplateContext {
395-
background-color: #fff;
463+
background-color: var(--djdt-background-color);
396464
}
397465

398466
#djDebug .djdt-panelContent .djDebugClose {
@@ -433,7 +501,7 @@
433501

434502
#djDebug a.toggleTemplate {
435503
padding: 4px;
436-
background-color: #bbb;
504+
background-color: var(--djdt-toggle-template-background-color);
437505
border-radius: 3px;
438506
}
439507

@@ -445,11 +513,11 @@
445513
}
446514

447515
#djDebug .djDebugCollapsed {
448-
color: #333;
516+
color: var(--djdt-sql-font-color);
449517
}
450518

451519
#djDebug .djDebugUncollapsed {
452-
color: #333;
520+
color: var(--djdt-sql-font-color);
453521
}
454522

455523
#djDebug .djUnselected {
@@ -483,66 +551,66 @@
483551
}
484552

485553
#djDebug .highlight {
486-
color: #000;
554+
color: var(--djdt-font-color);
487555
}
488556
#djDebug .highlight .err {
489-
color: #000;
557+
color: var(--djdt-font-color);
490558
} /* Error */
491559
#djDebug .highlight .g {
492-
color: #000;
560+
color: var(--djdt-font-color);
493561
} /* Generic */
494562
#djDebug .highlight .k {
495-
color: #000;
563+
color: var(--djdt-font-color);
496564
font-weight: bold;
497565
} /* Keyword */
498566
#djDebug .highlight .o {
499-
color: #000;
567+
color: var(--djdt-font-color);
500568
} /* Operator */
501569
#djDebug .highlight .n {
502-
color: #000;
570+
color: var(--djdt-font-color);
503571
} /* Name */
504572
#djDebug .highlight .mi {
505-
color: #000;
573+
color: var(--djdt-font-color);
506574
font-weight: bold;
507575
} /* Literal.Number.Integer */
508576
#djDebug .highlight .l {
509-
color: #000;
577+
color: var(--djdt-font-color);
510578
} /* Literal */
511579
#djDebug .highlight .x {
512-
color: #000;
580+
color: var(--djdt-font-color);
513581
} /* Other */
514582
#djDebug .highlight .p {
515-
color: #000;
583+
color: var(--djdt-font-color);
516584
} /* Punctuation */
517585
#djDebug .highlight .m {
518-
color: #000;
586+
color: var(--djdt-font-color);
519587
font-weight: bold;
520588
} /* Literal.Number */
521589
#djDebug .highlight .s {
522-
color: #333;
590+
color: var(--djdt-template-highlight-color);
523591
} /* Literal.String */
524592
#djDebug .highlight .w {
525593
color: #888888;
526594
} /* Text.Whitespace */
527595
#djDebug .highlight .il {
528-
color: #000;
596+
color: var(--djdt-font-color);
529597
font-weight: bold;
530598
} /* Literal.Number.Integer.Long */
531599
#djDebug .highlight .na {
532-
color: #333;
600+
color: var(--djdt-template-highlight-color);
533601
} /* Name.Attribute */
534602
#djDebug .highlight .nt {
535-
color: #000;
603+
color: var(--djdt-font-color);
536604
font-weight: bold;
537605
} /* Name.Tag */
538606
#djDebug .highlight .nv {
539-
color: #333;
607+
color: var(--djdt-template-highlight-color);
540608
} /* Name.Variable */
541609
#djDebug .highlight .s2 {
542-
color: #333;
610+
color: var(--djdt-template-highlight-color);
543611
} /* Literal.String.Double */
544612
#djDebug .highlight .cp {
545-
color: #333;
613+
color: var(--djdt-template-highlight-color);
546614
} /* Comment.Preproc */
547615

548616
#djDebug svg.djDebugLineChart {
@@ -595,13 +663,13 @@
595663
}
596664

597665
#djDebug .djdt-stack span {
598-
color: #000;
666+
color: var(--djdt-stack-span-color);
599667
font-weight: bold;
600668
}
601669
#djDebug .djdt-stack span.djdt-path,
602670
#djDebug .djdt-stack pre.djdt-locals,
603671
#djDebug .djdt-stack pre.djdt-locals span {
604-
color: #777;
672+
color: var(--djdt-path-and-locals);
605673
font-weight: normal;
606674
}
607675
#djDebug .djdt-stack span.djdt-code {
@@ -612,7 +680,7 @@
612680
}
613681
#djDebug .djdt-raw {
614682
background-color: #fff;
615-
border: 1px solid #ccc;
683+
border: 1px solid var(--djdt-raw-border-color);
616684
margin-top: 0.8em;
617685
padding: 5px;
618686
white-space: pre-wrap;
@@ -631,7 +699,7 @@
631699
max-height: 100%;
632700
}
633701
#djDebug .djdt-highlighted {
634-
background-color: lightgrey;
702+
background-color: var(--djdt--highlighted-background-color);
635703
}
636704
#djDebug tr.djdt-highlighted.djdt-profile-row {
637705
background-color: #ffc;
@@ -654,3 +722,17 @@
654722
.djdt-hidden {
655723
display: none;
656724
}
725+
726+
#djDebug #djDebugToolbar a#djToggleThemeButton {
727+
display: flex;
728+
align-items: center;
729+
cursor: pointer;
730+
}
731+
#djToggleThemeButton > svg {
732+
margin-left: auto;
733+
}
734+
#djDebug[data-theme="light"] #djToggleThemeButton svg.theme-light,
735+
#djDebug[data-theme="dark"] #djToggleThemeButton svg.theme-dark,
736+
#djDebug[data-theme="auto"] #djToggleThemeButton svg.theme-auto {
737+
display: block;
738+
}

debug_toolbar/static/debug_toolbar/js/toolbar.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { $$, ajax, replaceToolbarState, debounce } from "./utils.js";
1+
import { $$, ajax, debounce, replaceToolbarState } from "./utils.js";
22

33
function onKeyDown(event) {
44
if (event.keyCode === 27) {
@@ -213,6 +213,29 @@ const djdt = {
213213
if (djDebug.dataset.sidebarUrl !== undefined) {
214214
djdt.updateOnAjax();
215215
}
216+
217+
// Updates the theme using user settings
218+
const userTheme = localStorage.getItem("djdt.user-theme");
219+
if (userTheme !== null) {
220+
djDebug.setAttribute("data-theme", userTheme);
221+
}
222+
// Adds the listener to the Theme Toggle Button
223+
$$.on(djDebug, "click", "#djToggleThemeButton", function () {
224+
switch (djDebug.getAttribute("data-theme")) {
225+
case "auto":
226+
djDebug.setAttribute("data-theme", "light");
227+
localStorage.setItem("djdt.user-theme", "light");
228+
break;
229+
case "light":
230+
djDebug.setAttribute("data-theme", "dark");
231+
localStorage.setItem("djdt.user-theme", "dark");
232+
break;
233+
default: /* dark is the default */
234+
djDebug.setAttribute("data-theme", "auto");
235+
localStorage.setItem("djdt.user-theme", "auto");
236+
break;
237+
}
238+
});
216239
},
217240
hidePanels() {
218241
const djDebug = getDebugElement();
@@ -276,7 +299,7 @@ const djdt = {
276299
storeId = encodeURIComponent(storeId);
277300
const dest = `${sidebarUrl}?store_id=${storeId}`;
278301
slowjax(dest).then(function (data) {
279-
if (djdt.needUpdateOnFetch){
302+
if (djdt.needUpdateOnFetch) {
280303
replaceToolbarState(storeId, data);
281304
}
282305
});

debug_toolbar/templates/debug_toolbar/base.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,16 @@
1616
data-sidebar-url="{{ history_url }}"
1717
{% endif %}
1818
data-default-show="{% if toolbar.config.SHOW_COLLAPSED %}false{% else %}true{% endif %}"
19-
{{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }} data-update-on-fetch="{{ toolbar.config.UPDATE_ON_FETCH }}">
19+
{{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }} data-update-on-fetch="{{ toolbar.config.UPDATE_ON_FETCH }}"
20+
data-theme="{{ toolbar.config.DEFAULT_THEME }}">
2021
<div class="djdt-hidden" id="djDebugToolbar">
2122
<ul id="djDebugPanelList">
2223
<li><a id="djHideToolBarButton" href="#" title="{% trans 'Hide toolbar' %}">{% trans "Hide" %} »</a></li>
24+
<li>
25+
<a id="djToggleThemeButton" href="#" title="{% trans 'Toggle Theme' %}">
26+
{% trans "Toggle Theme" %} {% include "debug_toolbar/includes/theme_selector.html" %}
27+
</a>
28+
</li>
2329
{% for panel in toolbar.panels %}
2430
{% include "debug_toolbar/includes/panel_button.html" %}
2531
{% endfor %}

0 commit comments

Comments
 (0)