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',
},
'web-assets': {
'source_filenames': ('tutti/10_navbar.js',),
'source_filenames': ('tutti/10_navbar.js', 'tutti/20_theme.js',),
'output_filename': 'js/web-assets.js',
'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])
martonlente marked this conversation as resolved Outdated

Seems that when the button is pressed, it only adds the data-is-checked attribute but it doesn't assign any value. So the user has to reload the page for it to update in real time.

Perhaps we could replace the check:

From:
&:has(button[data-is-checked="data-is-checked"])

To:
&:has(button[data-is-checked])

So it updates as it is pressed.

Seems that when the button is pressed, it only adds the `data-is-checked` attribute but it doesn't assign any value. So the user has to reload the page for it to update in real time. Perhaps we could replace the check: From: `&:has(button[data-is-checked="data-is-checked"])` To: `&:has(button[data-is-checked])` So it updates as it is pressed.

Thanks, this is indeed much nicer with the less specificity, and works without page reload! 👍 I updated accordingly.

Thanks, this is indeed much nicer with the less specificity, and works without page reload! 👍 I updated accordingly.
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%
.schedule-container
@ -68,7 +136,7 @@ $col-time-width: 8%
&.toggle
i
border-radius: var(--spacer)
background-color: white
background-color: currentColor
color: currentColor
height: var(--spacer)
+margin(1, right)
@ -223,18 +291,18 @@ body.is-scrolled
@include media-breakpoint-down(md)
padding-top: 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
@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)
.col-rulers
+padding(3, x)
@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
@include media-breakpoint-up(lg)
@ -412,6 +480,7 @@ body.is-scrolled
.event
+box-card
display: flex
flex-direction: column
+margin(3, bottom)
@ -419,7 +488,7 @@ body.is-scrolled
transition: background-color var(--transition-speed) ease-in-out, opacity 250ms ease-in-out
&:hover
background-color: white !important
background-color: var(--box-bg-color-hover)
text-decoration: none
&[data-filtered]
@ -636,6 +705,10 @@ body.is-scrolled
position: absolute
right: 0
.event
background-color: transparent
transition: backdrop-filter var(--transition-speed)
.schedule-filters-container
+padding(2, y)

View File

@ -2,6 +2,7 @@ $font-path: '/static/assets/fonts'
// Import Web Assets.
@import "../../../../assets_shared/src/styles/main.sass"
@import "../../../../assets_shared/src/styles/_theme_system.sass"
@import "_albums.sass"
@import "_attendee.sass"
@ -17,11 +18,15 @@ $font-path: '/static/assets/fonts'
@import "_sponsors.sass"
@import "_utils.sass"
\:root
\:root,
html[data-theme="light"]
--body-color-bg: #e9ecef
--color-bg: var(--body-color-bg)
--navbar-bg: #1e1e1e
--box-bg-color-hover: white
martonlente marked this conversation as resolved Outdated

Left over comment

Left over comment
\:root
// TODO: check if component variables table colours are needed
--table-border-color: var(--color-bg-tertiary)
--table-row-bg-color: var(--color-bg-secondary)
@ -38,6 +43,9 @@ $font-path: '/static/assets/fonts'
+media-sm
--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
.navbar
box-shadow: none
@ -252,6 +260,13 @@ button.going-star
/* Web Assets overrides. */
// 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
display: block

View File

@ -3,7 +3,7 @@
| {% block head_extra %}
style.
: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-2: #84BBDC;
--bg-stripes-width: 75px;

View File

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

View File

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

View File

@ -2,6 +2,13 @@
| {% load pipeline %}
| {% 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 jumbotron %}
| {% 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' %}
div.ml-4
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 %}
| {{ object.location.slug | title }}
| {% else %}

View File

@ -1,7 +1,7 @@
| {% load static %}
| {% load pipeline %}
!!! 5
html(lang="en")
html(data-theme="light", lang="en")
head
meta(charset='utf-8')
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
| {% if object.location.slug %}
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 }}
| {% endif %}

View File

@ -63,7 +63,6 @@
| {% for event in events %}
a.event.js-time-slot(
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);
width: calc({{ event.duration_minutes}}px * {{ events_per_day_per_location_with_range.minute_to_pixel_multiplier }})"
id="#event-{{ event.id }}",

View File

@ -54,9 +54,9 @@
}
.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%);
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 {
@ -195,7 +195,7 @@
| {% if event.location.slug %}
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 }}
| {% endif %}