UI: Implement Web Assets' theme system, and add 'dark' theme #103972

Merged
Márton Lente merged 23 commits from ui/theme-system into main 2024-09-30 15:03:39 +02:00
13 changed files with 116 additions and 18 deletions

@ -1 +1 @@
Subproject commit 52a05c428631d617fee9f50ced9adfeef19ce3d9 Subproject commit 0cdfbd54f695493a549f87162a6a43f29b7f053f

View File

@ -269,7 +269,7 @@ PIPELINE = {
'output_filename': 'js/festival-finals.js', 'output_filename': 'js/festival-finals.js',
}, },
'web-assets': { 'web-assets': {
'source_filenames': ('tutti/10_navbar.js',), 'source_filenames': ('tutti/10_navbar.js', 'tutti/20_theme.js',),
'output_filename': 'js/web-assets.js', 'output_filename': 'js/web-assets.js',
'extra_context': {'async': True, 'defer': True}, 'extra_context': {'async': True, 'defer': True},
}, },

View File

@ -1,3 +1,71 @@
/* Theme-system mixins to make dynamic location colours contrast work with dark
* and light themes. */
=theme-dark-schedule
--event-detail-location-color-l: 65%
--schedule-container-location-color-l: 65%
--schedule-filters-container-location-bg-color-l: 20%
--schedule-filters-container-location-color-l: 60%
.schedule-container
&.horizontal
Review

Any reason to limit this to the horizontal layout? The same concept could be used in the vertical schedule.

Any reason to limit this to the horizontal layout? The same concept could be used in the vertical schedule.
Review

Sorry for the late reponse, just noticed the new comments.

I like the idea to display followed/assisting items in the vertical schedule more remarkably, but I think here it should look different, as the vertical layout doesn't have the coloured rows by location. Maybe we should just apply a slightly different tone of grey to highlighted items' backgrounds? Or shall we try to go for location-based colouring here as well, possibly with less saturated tones?

Based on this, I think the existing rule is correct, and we could extend vertical layout styles with additional rules.

Sorry for the late reponse, just noticed the new comments. I like the idea to display followed/assisting items in the vertical schedule more remarkably, but I think here it should look different, as the vertical layout doesn't have the coloured rows by location. Maybe we should just apply a slightly different tone of grey to highlighted items' backgrounds? Or shall we try to go for location-based colouring here as well, possibly with less saturated tones? Based on this, I think the existing rule is correct, and we could extend vertical layout styles with additional rules.
.event
backdrop-filter: brightness(75%)
&:hover
backdrop-filter: brightness(80%)
/* Event favourited styles */
&:has(button[data-is-checked])
backdrop-filter: brightness(125%) saturate(200%)
color: var(--color-text-primary)
&:hover
backdrop-filter: brightness(130%) saturate(200%)
.event-header,
.event-speakers
// TODO: @web-assets consider adding variables colours grey shades
color: hsl(0, 0%, 75%)
=theme-light-schedule
--event-detail-location-color-l: 35%
--schedule-container-location-color-l: 35%
--schedule-filters-container-location-bg-color-l: 10%
--schedule-filters-container-location-color-l: 50%
.schedule-container
&.horizontal
.event
backdrop-filter: brightness(110%)
&:hover
backdrop-filter: brightness(115%)
&:has(button[data-is-checked="data-is-checked"])
backdrop-filter: brightness(90%) saturate(400%)
color: var(--color-text-primary)
&:hover
backdrop-filter: brightness(95%) saturate(400%)
.event-header,
.event-speakers
color: hsl(0, 0%, 50%)
\:root,
[data-theme="light"]
+theme-light-schedule
[data-theme="dark"]
+theme-dark-schedule
@media (prefers-color-scheme: dark)
\:root
+theme-dark-schedule
[data-theme="light"]
+theme-light-schedule
$col-time-width: 8% $col-time-width: 8%
.schedule-container .schedule-container
@ -68,7 +136,7 @@ $col-time-width: 8%
&.toggle &.toggle
i i
border-radius: var(--spacer) border-radius: var(--spacer)
background-color: white background-color: currentColor
color: currentColor color: currentColor
height: var(--spacer) height: var(--spacer)
+margin(1, right) +margin(1, right)
@ -223,18 +291,18 @@ body.is-scrolled
@include media-breakpoint-down(md) @include media-breakpoint-down(md)
padding-top: 0.5 * $spacer padding-top: 0.5 * $spacer
padding-bottom: 0.5 * $spacer padding-bottom: 0.5 * $spacer
border-bottom: var(--border-width) solid rgba(black, .05) border-bottom: var(--border-width) solid var(--border-color)
.row-rulers-lg .row-rulers-lg
@include media-breakpoint-up(lg) @include media-breakpoint-up(lg)
border-top: var(--border-width) solid rgba(black, .05) border-top: var(--border-width) solid var(--border-color)
+padding(3, y) +padding(3, y)
.col-rulers .col-rulers
+padding(3, x) +padding(3, x)
@include media-breakpoint-up(lg) @include media-breakpoint-up(lg)
border-left: var(--border-width) solid rgba(black, .05) border-left: var(--border-width) solid var(--border-color)
.col-time .col-time
@include media-breakpoint-up(lg) @include media-breakpoint-up(lg)
@ -412,6 +480,7 @@ body.is-scrolled
.event .event
+box-card +box-card
display: flex display: flex
flex-direction: column flex-direction: column
+margin(3, bottom) +margin(3, bottom)
@ -419,7 +488,7 @@ body.is-scrolled
transition: background-color var(--transition-speed) ease-in-out, opacity 250ms ease-in-out transition: background-color var(--transition-speed) ease-in-out, opacity 250ms ease-in-out
&:hover &:hover
background-color: white !important background-color: var(--box-bg-color-hover)
text-decoration: none text-decoration: none
&[data-filtered] &[data-filtered]
@ -636,6 +705,10 @@ body.is-scrolled
position: absolute position: absolute
right: 0 right: 0
.event
background-color: transparent
transition: backdrop-filter var(--transition-speed)
.schedule-filters-container .schedule-filters-container
+padding(2, y) +padding(2, y)

View File

@ -2,6 +2,7 @@ $font-path: '/static/assets/fonts'
// Import Web Assets. // Import Web Assets.
@import "../../../../assets_shared/src/styles/main.sass" @import "../../../../assets_shared/src/styles/main.sass"
@import "../../../../assets_shared/src/styles/_theme_system.sass"
@import "_albums.sass" @import "_albums.sass"
@import "_attendee.sass" @import "_attendee.sass"
@ -17,11 +18,15 @@ $font-path: '/static/assets/fonts'
@import "_sponsors.sass" @import "_sponsors.sass"
@import "_utils.sass" @import "_utils.sass"
\:root \:root,
html[data-theme="light"]
--body-color-bg: #e9ecef --body-color-bg: #e9ecef
--color-bg: var(--body-color-bg) --color-bg: var(--body-color-bg)
--navbar-bg: #1e1e1e
--box-bg-color-hover: white
\:root
// TODO: check if component variables table colours are needed
--table-border-color: var(--color-bg-tertiary) --table-border-color: var(--color-bg-tertiary)
--table-row-bg-color: var(--color-bg-secondary) --table-row-bg-color: var(--color-bg-secondary)
@ -38,6 +43,9 @@ $font-path: '/static/assets/fonts'
+media-sm +media-sm
--page-with-header-content-offset: calc(var(--spacer) * 8) --page-with-header-content-offset: calc(var(--spacer) * 8)
html[data-theme="dark"]
--box-bg-color-hover: var(--btn-color-bg-hover)
body.is-scrolled body.is-scrolled
.navbar .navbar
box-shadow: none box-shadow: none
@ -252,6 +260,13 @@ button.going-star
/* Web Assets overrides. */ /* Web Assets overrides. */
// TODO: check component forms in Web Assets v2 // TODO: check component forms in Web Assets v2
.form-control
&:disabled,
&[readonly]
background-color: var(--input-color-bg)
color: var(--color-text-secondary)
pointer-events: none
.form-group .form-group
display: block display: block

View File

@ -3,7 +3,7 @@
| {% block head_extra %} | {% block head_extra %}
style. style.
:root { :root {
--bg-color-container: hsla(0, 0%, 100%, 0.9); --bg-color-container: var(--box-bg-color);
--bg-stripes-color-1: #5F1BED; --bg-stripes-color-1: #5F1BED;
--bg-stripes-color-2: #84BBDC; --bg-stripes-color-2: #84BBDC;
--bg-stripes-width: 75px; --bg-stripes-width: 75px;

View File

@ -3,7 +3,7 @@
| {% block head_extra %} | {% block head_extra %}
style. style.
:root { :root {
--bg-color-container: hsla(0, 0%, 100%, 0.9); --bg-color-container: var(--box-bg-color);
--bg-color: #5F1BED; --bg-color: #5F1BED;
--bg-dots-color: #EFAA2A; --bg-dots-color: #EFAA2A;
--bg-dots-width: 300px; --bg-dots-width: 300px;

View File

@ -37,6 +37,10 @@ nav.nav-global(role='navigation')
| {% endif %} | {% endif %}
| {% endif %} | {% endif %}
li
button.js-toggle-theme-btn
i.i-adjust.js-toggle-theme-btn-icon
| {% include "conference_main/_navbar_menu_user.pug" %} | {% include "conference_main/_navbar_menu_user.pug" %}
li li

View File

@ -2,6 +2,13 @@
| {% load pipeline %} | {% load pipeline %}
| {% load static %} | {% load static %}
| {% block head_extra %}
| {% verbatim %}
script.
!function(){{const rootElement=document.documentElement;let themeValue;function getThemeValue(){themeValue=localStorage.getItem("dataTheme")}var data;getThemeValue(),themeValue&&(data=themeValue,getThemeValue(),rootElement.setAttribute("data-theme",data))}}();
| {% endverbatim %}
| {% endblock head_extra %}
| {% block header %} | {% block header %}
| {% block jumbotron %} | {% block jumbotron %}
| {% include "conference_main/components/hero.pug" with show_logo=True show_date=True show_location=True show_overlay=True %} | {% include "conference_main/components/hero.pug" with show_logo=True show_date=True show_location=True show_overlay=True %}

View File

@ -7,7 +7,7 @@
| {% if object.status == 'accepted' %} | {% if object.status == 'accepted' %}
div.ml-4 div.ml-4
small.text-muted.d-block Location small.text-muted.d-block Location
span(style="color: hsl(var(--location-hue-{{ object.location.slug }}), 50%, 50%);") span(style="color: hsl(var(--location-hue-{{ object.location.slug }}), 80%, var(--event-detail-location-color-l));")
| {% if object.location.slug %} | {% if object.location.slug %}
| {{ object.location.slug | title }} | {{ object.location.slug | title }}
| {% else %} | {% else %}

View File

@ -1,7 +1,7 @@
| {% load static %} | {% load static %}
| {% load pipeline %} | {% load pipeline %}
!!! 5 !!! 5
html(lang="en") html(data-theme="light", lang="en")
head head
meta(charset='utf-8') meta(charset='utf-8')
meta(name='viewport', content='width=device-width, initial-scale=1.0') meta(name='viewport', content='width=device-width, initial-scale=1.0')

View File

@ -78,7 +78,7 @@ meta(name='twitter:image', content='{{request.scheme}}://{{request.META.HTTP_HOS
ul.event-description ul.event-description
| {% if object.location.slug %} | {% if object.location.slug %}
li.event-location( li.event-location(
style="color: hsl(var(--location-hue-{{ object.location.slug }}), 80%, 35%);") style="color: hsl(var(--location-hue-{{ object.location.slug }}), 80%, var(--event-detail-location-color-l));")
| {{ object.location.slug | upper }} | {{ object.location.slug | upper }}
| {% endif %} | {% endif %}

View File

@ -63,7 +63,6 @@
| {% for event in events %} | {% for event in events %}
a.event.js-time-slot( a.event.js-time-slot(
style=" style="
background-color: hsl(var(--location-hue-{{ location }}), 60%, 97%);
left: calc(calc({{ event.start_time_in_minutes}} - {{ events_per_day_per_location_with_range.range_minutes.start }}) * 10px); left: calc(calc({{ event.start_time_in_minutes}} - {{ events_per_day_per_location_with_range.range_minutes.start }}) * 10px);
width: calc({{ event.duration_minutes}}px * {{ events_per_day_per_location_with_range.minute_to_pixel_multiplier }})" width: calc({{ event.duration_minutes}}px * {{ events_per_day_per_location_with_range.minute_to_pixel_multiplier }})"
id="#event-{{ event.id }}", id="#event-{{ event.id }}",

View File

@ -54,9 +54,9 @@
} }
.event-location-{{ location.slug }} input:checked ~ label { .event-location-{{ location.slug }} input:checked ~ label {
background-color: hsla(var(--location-hue-{{ location.slug }}), 50%, 50%, 10%); background-color: hsla(var(--location-hue-{{ location.slug }}), 50%, 50%, var(--schedule-filters-container-location-bg-color-l));
border-color: hsla(var(--location-hue-{{ location.slug }}), 50%, 50%, 20%); border-color: hsla(var(--location-hue-{{ location.slug }}), 50%, 50%, 20%);
color: hsl(var(--location-hue-{{ location.slug }}), 50%, 50%); color: hsl(var(--location-hue-{{ location.slug }}), 50%, var(--schedule-filters-container-location-color-l));
} }
.event-location-{{ location.slug }} input:checked ~ label:hover { .event-location-{{ location.slug }} input:checked ~ label:hover {
@ -195,7 +195,7 @@
| {% if event.location.slug %} | {% if event.location.slug %}
li.event-location( li.event-location(
style="color: hsl(var(--location-hue-{{ event.location.slug }}), 80%, 35%);") style="color: hsl(var(--location-hue-{{ event.location.slug }}), 80%, var(--schedule-container-location-color-l));")
| {{ event.location.slug | upper }} | {{ event.location.slug | upper }}
| {% endif %} | {% endif %}