From 093f93d905f54731fc45cfda8fb43968c64c40d6 Mon Sep 17 00:00:00 2001 From: Qb Date: Sat, 18 Jan 2025 16:40:44 +0100 Subject: [PATCH] Implement system theme option --- app/assets/javascripts/theme.js | 11 ++++---- .../frontend/base/_breadcrumb.scss | 2 +- .../stylesheets/frontend/base/_theme.scss | 26 ++++++++++++++++--- .../stylesheets/frontend/pages/_browse.scss | 19 +++++++------- .../stylesheets/frontend/pages/_show.scss | 5 ++-- app/views/frontend/shared/_navbar.haml | 16 +++++++++--- 6 files changed, 52 insertions(+), 27 deletions(-) diff --git a/app/assets/javascripts/theme.js b/app/assets/javascripts/theme.js index 972484cf..983afa76 100644 --- a/app/assets/javascripts/theme.js +++ b/app/assets/javascripts/theme.js @@ -1,10 +1,9 @@ -let currentTheme = localStorage.getItem('theme') || 'light'; +let currentTheme = localStorage.getItem('color-theme') || 'system'; -function toggleTheme(theme) { - const newTheme = theme || (currentTheme === 'light' ? 'dark' : 'light'); - localStorage.setItem('theme', newTheme); +function toggleTheme(newTheme) { + localStorage.setItem('color-theme', newTheme); document.documentElement.classList.toggle('dark', newTheme === 'dark'); + document.documentElement.classList.toggle('light', newTheme === 'light'); currentTheme = newTheme; } - -toggleTheme(currentTheme); \ No newline at end of file +toggleTheme(currentTheme); diff --git a/app/assets/stylesheets/frontend/base/_breadcrumb.scss b/app/assets/stylesheets/frontend/base/_breadcrumb.scss index fddc0732..7aaed924 100644 --- a/app/assets/stylesheets/frontend/base/_breadcrumb.scss +++ b/app/assets/stylesheets/frontend/base/_breadcrumb.scss @@ -26,6 +26,6 @@ } > .active { - color: white; + color: var(--text-primary); } } diff --git a/app/assets/stylesheets/frontend/base/_theme.scss b/app/assets/stylesheets/frontend/base/_theme.scss index 279d3357..725ea0cb 100644 --- a/app/assets/stylesheets/frontend/base/_theme.scss +++ b/app/assets/stylesheets/frontend/base/_theme.scss @@ -19,8 +19,8 @@ --indigo-500: #6366f1; --indigo-400: #818cf8; } - -html { + +@mixin light-variables { --primary-100: var(--indigo-700); --primary-200: var(--indigo-600); --primary-300: var(--indigo-500); @@ -40,6 +40,7 @@ html { --text-link: var(--primary-400); --text-visited: var(--primary-300); --text-heading: var(--text-secondary); + --text-inverted: white; --border-50: var(--surface-50); --border-100: var(--surface-100); @@ -50,7 +51,7 @@ html { --border-divider: var(--text-secondary); } -.dark { +@mixin dark-variables { --primary-100: var(--indigo-700); --primary-200: var(--indigo-600); --primary-300: var(--indigo-500); @@ -68,6 +69,23 @@ html { --text-muted: rgba(255, 255, 255, 0.65); } +html { + @include light-variables; +} + +@media (prefers-color-scheme: dark) { + html { + @include dark-variables; + } +} + +.light { + @include light-variables; +} +.dark { + @include dark-variables; +} + body { background-color: var(--surface-50); color: var(--text-primary); @@ -85,5 +103,5 @@ a.btn { color: var(--text-primary); } .btn.btn-primary, .btn.btn-secondary { - color: white; + color: var(--text-inverted); } diff --git a/app/assets/stylesheets/frontend/pages/_browse.scss b/app/assets/stylesheets/frontend/pages/_browse.scss index 2ed004dd..5fe8c88f 100644 --- a/app/assets/stylesheets/frontend/pages/_browse.scss +++ b/app/assets/stylesheets/frontend/pages/_browse.scss @@ -12,13 +12,17 @@ body.page-browse { text-align: left; } + .caption { + color: var(--text-inverted); + } + &:hover, &:focus, &:active { text-decoration: none; } &.folder { background-color: var(--primary-200); - color: var(--text-primary); + color: var(--text-inverted); .header { margin-bottom: $padding-large-vertical; @@ -32,14 +36,10 @@ body.page-browse { &:hover, &:focus, &:active { background-color: var(--primary-100); } - - .caption { - color: white; - } } &.conference { - color: $gray-dark; + color: var(--neutral-800); img { height: 64px; @@ -47,17 +47,16 @@ body.page-browse { } .caption { - color: white; - background-color: $gray-dark; + background-color: var(--neutral-800); -webkit-transition: all 0.2s ease-in-out; -o-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; } &:hover, &:focus, &:active { - color: $brand-primary; + color: var(--primary-200); .caption { - background-color: $brand-primary; + background-color: var(--primary-200); } } } diff --git a/app/assets/stylesheets/frontend/pages/_show.scss b/app/assets/stylesheets/frontend/pages/_show.scss index 21e5b7ae..ce9e7336 100644 --- a/app/assets/stylesheets/frontend/pages/_show.scss +++ b/app/assets/stylesheets/frontend/pages/_show.scss @@ -84,9 +84,10 @@ body.page-show { a, button { display: block; - color: white; - + background-color: var(--neutral-500); + color: var(--text-inverted); + text-decoration: none; &:hover { diff --git a/app/views/frontend/shared/_navbar.haml b/app/views/frontend/shared/_navbar.haml index b1cd08a7..d460af03 100644 --- a/app/views/frontend/shared/_navbar.haml +++ b/app/views/frontend/shared/_navbar.haml @@ -14,14 +14,22 @@ %a.form-control.btn.btn-default{href: '/about.html'} %span.icon.icon-info - .nav.navbar-form.navbar-right.compact.button-wrapper.script-only - %a.form-control.btn.btn-default{onclick: 'toggleTheme()'} + .nav.navbar-form.navbar-right.compact.dropdown.script-only + %button#theme-menu.form-control.btn.btn-default.dropdown-toggle{"aria-expanded" => "true", "aria-haspopup" => "true", "data-toggle" => "dropdown"} %span.icon.icon-moon-o + .dropdown-menu.themes-dropdown{"aria-labelledby" => "theme-menu"} + %li + %a{href: '#', onclick: 'toggleTheme(\'system\')', role: 'button', data: { turbolinks: 'false' }} System + %li + %a{href: '#', onclick: 'toggleTheme(\'light\')', role: 'button', data: { turbolinks: 'false' }} Light + %li + %a{href: '#', onclick: 'toggleTheme(\'dark\')', role: 'button', data: { turbolinks: 'false' }} Dark + .nav.navbar-form.navbar-right.compact.dropdown.script-only - %button#feedMenu.btn.btn-default.dropdown-toggle{"aria-expanded" => "true", "aria-haspopup" => "true", "data-toggle" => "dropdown", :type => "button"} + %button#feed-menu.btn.btn-default.dropdown-toggle{"aria-expanded" => "true", "aria-haspopup" => "true", "data-toggle" => "dropdown"} %span.icon.icon-rss - %div.dropdown-menu.feeds_dropdown{"aria-labelledby" => "feedMenu"} + .dropdown-menu.feeds_dropdown{"aria-labelledby" => "feed-menu"} = render 'frontend/shared/navbar_feeds', locals: { conference: @conference } %form.navbar-form.navbar-right{role: 'search', action: '/search/', method: 'get', id: 'media-search'}