Skip to content

Commit c93f986

Browse files
committed
[WebProfilerBundle] Improved the light/dark theme switching
1 parent 9b89b2e commit c93f986

File tree

2 files changed

+45
-22
lines changed

2 files changed

+45
-22
lines changed

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base.html.twig

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@
1515
</head>
1616
<body>
1717
<script>
18-
document.body.classList.add(
19-
localStorage.getItem('symfony/profiler/theme') || (matchMedia('(prefers-color-scheme: dark)').matches ? 'theme-dark' : 'theme-light'),
20-
localStorage.getItem('symfony/profiler/width') || 'width-normal'
21-
);
18+
if (null === localStorage.getItem('symfony/profiler/theme') || 'theme-auto' === localStorage.getItem('symfony/profiler/theme')) {
19+
document.body.classList.add((matchMedia('(prefers-color-scheme: dark)').matches ? 'theme-dark' : 'theme-light'));
20+
} else {
21+
document.body.classList.add(localStorage.getItem('symfony/profiler/theme'));
22+
}
23+
// needed to respond dynamically to OS changes without having to refresh the page
24+
window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
25+
document.body.classList.remove(e.matches ? 'theme-light' : 'theme-dark');
26+
document.body.classList.add(e.matches ? 'theme-dark' : 'theme-light');
27+
});
28+
29+
document.body.classList.add(localStorage.getItem('symfony/profiler/width') || 'width-normal');
2230
</script>
2331

2432
{% block body '' %}

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/settings.html.twig

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -116,21 +116,25 @@
116116
<div class="modal-content">
117117
<h4>Theme</h4>
118118

119+
<input class="config-option" type="radio" name="theme" value="auto" id="settings-theme-auto">
120+
<label for="settings-theme-auto">Auto</label>
121+
<p class="form-help"><strong>Default theme</strong>. It switches between Light and Dark automatically to match the operating system theme.</p>
122+
119123
<input class="config-option" type="radio" name="theme" value="light" id="settings-theme-light">
120124
<label for="settings-theme-light">Light</label>
121-
<p class="form-help">Default theme. Improves readability.</p>
125+
<p class="form-help">Provides greatest readability, but requires a well-lit environment.</p>
122126

123127
<input class="config-option" type="radio" name="theme" value="dark" id="settings-theme-dark">
124128
<label for="settings-theme-dark">Dark</label>
125-
<p class="form-help">Reduces eye fatigue. Ideal for low light conditions.</p>
129+
<p class="form-help">Reduces eye fatigue. Ideal for low light environments.</p>
126130

127131
<h4>Page Width</h4>
128132

129-
<input class="config-option" type="radio" name="width" value="light" id="settings-width-normal">
133+
<input class="config-option" type="radio" name="width" value="normal" id="settings-width-normal">
130134
<label for="settings-width-normal">Normal</label>
131135
<p class="form-help">Fixed page width. Improves readability.</p>
132136

133-
<input class="config-option" type="radio" name="width" value="dark" id="settings-width-full">
137+
<input class="config-option" type="radio" name="width" value="full" id="settings-width-full">
134138
<label for="settings-width-full">Full-page</label>
135139
<p class="form-help">Dynamic page width. As wide as the browser window.</p>
136140
</div>
@@ -139,27 +143,38 @@
139143

140144
<script>
141145
(function() {
142-
let configOptions = document.querySelectorAll('.config-option');
143-
let oppositeValues = { 'light': 'dark', 'dark': 'light', 'normal': 'full', 'full': 'normal' };
146+
const configOptions = document.querySelectorAll('.config-option');
147+
const allSettingValues = ['theme-auto', 'theme-ligh', 'theme-dark', 'width-normal', 'width-full'];
144148
[...configOptions].forEach(option => {
145149
option.addEventListener('click', function (event) {
146-
let optionParts = option.id.split('-');
147-
let optionName = optionParts[1];
148-
let optionValue = optionParts[2];
149-
150-
document.body.classList.remove(optionName + '-' + oppositeValues[optionValue]);
151-
document.body.classList.add(optionName + '-' + optionValue);
152-
localStorage.setItem('symfony/profiler/' + optionName, optionName + '-' + optionValue);
150+
const optionName = option.name;
151+
const optionValue = option.value;
152+
const settingName = 'symfony/profiler/' + optionName;
153+
const settingValue = optionName + '-' + optionValue;
154+
155+
localStorage.setItem(settingName, settingValue);
156+
157+
document.body.classList.forEach((cssClass) => {
158+
if (cssClass.startsWith(optionName)) {
159+
document.body.classList.remove(cssClass);
160+
}
161+
});
162+
163+
if ('theme-auto' === settingValue) {
164+
document.body.classList.add((matchMedia('(prefers-color-scheme: dark)').matches ? 'theme-dark' : 'theme-light'));
165+
} else {
166+
document.body.classList.add(settingValue);
167+
}
153168
});
154169
});
155170
156-
let openModalButton = document.getElementById('open-settings');
157-
let modalWindow = document.getElementById('profiler-settings');
158-
let closeModalButton = document.getElementsByClassName('close-modal')[0];
159-
let modalWrapper = document.getElementsByClassName('modal-wrap')[0]
171+
const openModalButton = document.getElementById('open-settings');
172+
const modalWindow = document.getElementById('profiler-settings');
173+
const closeModalButton = document.getElementsByClassName('close-modal')[0];
174+
const modalWrapper = document.getElementsByClassName('modal-wrap')[0]
160175
161176
openModalButton.addEventListener('click', function(event) {
162-
document.getElementById('settings-' + (localStorage.getItem('symfony/profiler/theme') || 'theme-light')).checked = 'checked';
177+
document.getElementById('settings-' + (localStorage.getItem('symfony/profiler/theme') || 'theme-auto')).checked = 'checked';
163178
document.getElementById('settings-' + (localStorage.getItem('symfony/profiler/width') || 'width-normal')).checked = 'checked';
164179
165180
modalWindow.classList.toggle('visible');

0 commit comments

Comments
 (0)