Skip to content

Commit 3eb3a9b

Browse files
committed
feat: implement light mode theme for osv.dev web frontend
1 parent 02dd3b3 commit 3eb3a9b

11 files changed

Lines changed: 481 additions & 85 deletions

File tree

2.22 KB
Loading
1023 Bytes
Loading
11.1 KB
Loading

gcp/website/frontend3/img/logo.png

1.12 KB
Loading
-1.87 KB
Binary file not shown.
10.2 KB
Loading
28.1 KB
Loading
23.6 KB
Loading

gcp/website/frontend3/src/base.html

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
{% if disable_turbo_cache %}
1010
<meta name="turbo-cache-control" content="no-cache">
1111
{% endif %}
12+
<script>
13+
// Early inline script element here is necessary to prevent the "flash of
14+
// unstyled content" problem where the dark default theme is first rendered
15+
// followed by a sudden flash to light mode.
16+
// See https://en.wikipedia.org/wiki/Flash_of_unstyled_content.
17+
const theme = localStorage.getItem('theme') || 'dark';
18+
document.documentElement.setAttribute('data-theme', theme);
19+
</script>
1220
<link rel="icon" type="image/png" href="/static/img/favicon-32x32.png" sizes="32x32">
1321
<link rel="icon" type="image/png" href="/static/img/favicon-16x16.png" sizes="16x16">
1422
<link rel="preconnect" href="https://fonts.googleapis.com">
@@ -40,7 +48,9 @@
4048
<header class="top-bar">
4149
<div class="logo">
4250
<a href="{{ url_for('frontend_handlers.index') }}" aria-label="Home page">
43-
<img alt="OSV logo" src="/static/img/logo.png" srcset="/static/img/logo.png, /static/img/logo@2x.png 2x"
51+
<img alt="OSV logo" class="logo-img-light" src="/static/img/logo.png" srcset="/static/img/logo.png, /static/img/logo@4x.png 4x"
52+
width="54" height="20">
53+
<img alt="OSV logo" class="logo-img-dark" src="/static/img/logo-dark.png" srcset="/static/img/logo-dark.png, /static/img/logo-dark@4x.png 4x"
4454
width="54" height="20">
4555
</a>
4656
</div>
@@ -92,7 +102,13 @@
92102
</a>
93103
</li>
94104
{% endif %}
95-
<li>
105+
<li class="theme-toggle-container">
106+
<button id="theme-toggle" class="theme-toggle-btn" aria-label="Toggle theme">
107+
<span class="material-icons icon-light-mode">light_mode</span>
108+
<span class="material-icons icon-dark-mode">dark_mode</span>
109+
</button>
110+
</li>
111+
<li class="github-container">
96112
<a class="logo-img" href="https://github.com/google/osv.dev" target="_blank"
97113
aria-label="Go to our github page">
98114
<img class="logo-link" src="/static/img/github-mark-white.svg" alt="Github Logo" width="24" height="24">

gcp/website/frontend3/src/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,20 @@ function initializeSearch() {
5656
searchInstance = new ExpandableSearch();
5757
}
5858

59+
function initializeThemeToggle() {
60+
const toggle = document.getElementById('theme-toggle');
61+
// Ensure the event handler is attached only once.
62+
if (toggle && !toggle.dataset.themeInitialized) {
63+
toggle.dataset.themeInitialized = 'true';
64+
toggle.addEventListener('click', () => {
65+
const currentTheme = localStorage.getItem("theme") || 'dark';
66+
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
67+
localStorage.setItem('theme', newTheme);
68+
document.documentElement.setAttribute('data-theme', newTheme);
69+
});
70+
}
71+
}
72+
5973
// Ensure initialization happens after all dependencies are loaded
6074
function ensureInitialization() {
6175
if (!customElements) {
@@ -65,6 +79,7 @@ function ensureInitialization() {
6579

6680
if (customElements.get('md-filled-text-field')) {
6781
initializeSearch();
82+
initializeThemeToggle();
6883
} else {
6984
// wait a bit longer for components to load
7085
setTimeout(ensureInitialization, 50);

0 commit comments

Comments
 (0)