Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dark mode #2223

Merged
merged 71 commits into from
Jan 2, 2024
Merged

Dark mode #2223

merged 71 commits into from
Jan 2, 2024

Conversation

julien-deramond
Copy link
Contributor

@julien-deramond julien-deramond commented Sep 11, 2023

Description

Grab a cup of coffee or tea, and take your time.

This PR finally introduces the dark mode in Boosted. It's a huge PR that has been developed over the course of 3 months. It's the result of a lot of prototyping, discussions, and iterations with the ODS web core team, but also with the Bootstrap team.

The entire solution relies on the data-bs-theme attribute that has been introduced in Bootstrap 5.3.0. It allows to switch between light and dark mode, and to switch between different themes (light, dark, etc.) in the same page.

Live previews

Usage

The exact usage of the dark mode for Orange websites and web apps is not defined precisely yet. It's a work in progress. The goal of this PR is to provide the technical solution to implement the dark mode in Boosted and to provide a first version of the documentation to help developers to use it. Here are the remaining tasks to do to define the usage of the dark mode at Orange:

  • Define in the DSM what is the dark mode and why it's important for Orange.
  • Define the usage of the dark mode at Orange. Must it be present on all websites, web apps, etc.? If not, in which cases should it be used?
    • Update the DSM to explain this rule
    • When the rule is defined, update the Boosted documentation to explain this rule, or at least link to the DSM

Switching from light to dark mode

The switch from light to dark mode is not defined precisely yet. It's a work in progress. The goal of this PR is to provide the technical solution to implement the dark mode in Boosted and to provide a first version of the documentation to help developers to use it. Here are the remaining tasks to do to define the switch from light to dark mode at Orange:

  • Define how to switch from light to dark mode in web interfaces. Is it always the same selector? Always in the header? Always a dropdown? Always with the light/dark/auto options?
    • Update the DSM to define this rule
    • When the rule is defined, update the Boosted documentation to explain this rule, or at least link to the DSM
    • Do we insert this switch to all Boosted/UI Kit/DSM navbars and examples?
    • Do we create a reusable component for this switch?
    • Do we need to update the new Navbar mode selector example page we created?

In the meantime, this PR provides a new "With mode selector" Orange navbar variant that relies on:

  • a new optional markup for the Orange navbar to render the mode selector
    • this mode selector relies on a color-modes.js JavaScript file that has been added to the documentation to allow to switch between light and dark mode manually
    • this mode selector relies on 4 Solaris icons that have been added to the documentation to allow to switch between light and dark mode manually

The new Navbar mode selector example page we created allows users to find a real world example of this new variant to copy and paste in their code.

Mode selector rendering

The mode selector rendering was defined with the designers. It's a dropdown with 3 options:

  • light with a sun icon to force the light mode
  • dark with a moon icon to force the dark mode
  • auto with a sun and a moon icon to let the browser decide which mode to use based on the user's preferences
    • This auto icon is probably not the final one. Designers suggested to create a new Solaris icon for this use case.

User preferences are stored in the local storage of the browser.

In terms of rendering, all the dropdowns in a navbar are rendered differently compared to the dropdowns in the rest of the page. Right now, there's a specific CSS code for these dropdowns in _navbar.scss that changes the alignments, the sizes of the SVGs when there are icons, the space between the caret and the text, etc. It's not ideal because it's not generic, but it's a topic identified to be tackled later in #2242.

Dark variant vs. dark mode

The color modes can be contextual or not. It means that the color mode can be applied to the whole page or to a specific component. It's the case for the dark mode. It can be applied to the whole page or to a specific component.

That's why we decided to drop all of our components' dark variants and replace them by contextual dark mode rendering.
It's a big change but is the easiest way to implement the dark mode in Boosted for now.

It implies the following modifications:

  • Dropped the root CSS rule that allowed to switch main colors: [class*="bg-black"], [class*="-dark"]:not(.border-dark):not(.text-dark):not(.btn-dark):not(.focus-ring-dark):not(.link-underline-dark):not(.link-dark), [class*="bg-secondary"]
  • Replace in the documentation all the dark variant examples by a deprecation message (without example)
  • Remove almost all .{component}-dark classes.
    • Some of them have been kept for retro-compatibility with external libraries (Orange user using an external library based on Bootstrap 5.3.3 but with our CSS): .navbar-dark, .btn-close-white, and .dropdown-menu-dark
  • Remove all $*-inverted and ${component}-dark-* Sass variables

There's a specific use case: the Orange navbar and footer. They are always rendered on a black background in light and dark mode. It means that they must always be used with data-bs-theme="dark".
This use case also implies that _variables-dark.scss must always be embedded in the Sass compilation.
Another consequence is that the dark mode background color by default is #141414 and the Orange navbar and footer one is black. So the inputs (for instance) in the Orange navbar and footer stay with a #141414 background color instead of black previously.

Dark mode at the highest level in Boosted

  • Dark mode is enabled by default and $enable-dark-mode can be set to false to disable it.

Color palette

A new color palette page has been created to explain the new color palette and the new color names.

  • A new scss/_color-palette.scss file has been created to define the color palette based on the one defined for Orange Design System: https://github.com/Orange-OpenSource/Orange-Boosted-Bootstrap/blob/8ba87681fad206eb88cdab3c7d7b23cf9e5e70e5/scss/_color-palette.scss. This color palette adds various Sass variables named after the color names defined in the Orange Design System (e.g. $ods-orange-200 or $ods-forest-100). Their values are set to hex values.

    • _color-palette.scss is imported by _variables.scss to avoid Sass compilation breaking changes.
    • It implies that _variables.scss and _variables-dark.scss now use these new variables instead of the hex values directly.
  • The Bootstrap color palette for blues, indigos, purples, etc. has been mapped to the new Orange Design System color palette for the values from ${color}-100 to ${color}-600. From ${color}-700 to ${color}-900, shade-color() from 20% to 60% of the ${color}-600 value is used.

  • Introduced $theme-colors-dark and $theme-colors-rgb-dark (RGB values from $theme-colors-dark)

    • It allowed to update --bs-{color} and --bs{color}-rgb CSS variables values for dark mode

Note that #141414 is a new color introduced in the gray palette as $gray-950 (and $ods-gray-900) and used for $body-bg-dark, var(--bs-body-bg*) corresponding to .bg-body.

Also note that some light mode colors have been revamped by the designers to provide a better contrast for accessibility: info, danger, and success.

Colors and semantics

Some CSS variables have been added in _root.scss to allow to switch some colors from light to dark mode. You can find the entire list of reusable CSS variables and their associated colors in our new color theme page.

Core, functional and grays have different values in light and dark mode. It's not the case for the supporting colors.

  • Note that primary now switch between our light and dark oranges. But also that there's a new supporting orange.

New CSS variables:

  • --bs-tertiary-active-bg is new
  • --bs-disabled-color is new
  • --bs-form-color-disabled-filter is new
  • --bs-form-check-input-disabled-color is new
  • --bs-form-switch-square-bg is new
  • --bs-form-check-filter is new
  • --breadcrumb-divider-filter is new
  • --bs-form-select-disabled-indicator is new
  • --bs-form-select-indicator is new

New --bs-border-color-subtle and $border-color-subtle to be used instead of --bs-border-color-translucent because our colors are never translucent. The translucent variable is kept for backward compatibility.

  • All the usages of --bs-border-color-translucent have been changed to --bs-border-color-subtle except when it wasn't used as a border color. In this case, it has been replaced with --bs-tertiary-color.

Then,

  • --bs-highlight-bg is replaced with --secondary, --bs-border-color or --bs-body-color given the context
  • --bs-link-hover-color is replaced with --bs-primary for the cases where it's not used as a link

Success, warning, info, danger

For these 4 concepts, there's only one color used in light mode, and another in dark mode:

  • Light mode: darker color
  • Dark mode: lighter color

Warning color is an exception since it remains the same in both modes

It's not to be used to write on it (except for the buttons), users should prefer the supporting colors for that such as .bg-supporting-green in Boosted

Orange color

By default, our primary color in Boosted is used for texts, icons, borders, and backgrounds without text in it:

  • Light mode: darker orange
  • Dark mode: lighter orange
    Even if we will configure the corresponding foreground color to be accessible, we have to explain in the documentation that it's not to be used to display text on it. In light mode, the foreground color is black.

Whenever someone wants to write text on an orange surface, the lighter orange color must be used, and the corresponding foreground color is black. This combination doesn't change in light and dark mode.
All components such as buttons, stickers, stepped processes, etc. use this rule because there is text in it.
It also has been decided that this concept matches the concept of supporting colors in Boosted where the surface color doesn't change, and its corresponding foreground color neither.
So .bg-supporting-orange will be created for that matter.

  • $brand-orange is replaced with $supporting-orange
  • $accessible-orange is replaced with $primary

Functional colors

  • Functional colors have the same color for text, background, and borders.
  • .text-bg-* utilities apply automatically the right corresponding foreground color. So users should use .text-bg-{color} instead of .bg-{color} + forcing .text-{color} when available for automatic contrast.

Syntax highlighting (code blocks)

Syntax highlighting has been updated to match the new color palette. It's based on the Prism.js library.

Technical zoom on data-bs-theme

data-bs-theme can be used on the whole page or contextually on an HTML element (a <div> but also directly on a component).

These themes can be nested.

  • color-scheme light was forced on :root, [data-bs-theme="light"] to have the right rendering for light basic browser form UI elements. It's not done on Bootstrap side (see [PROTO]: handle data-bs-theme differently twbs/bootstrap#39295).
  • color and background-color are now linked to [data-bs-theme] attribute and automatically set. So when you create a <div data-bs-theme="dark"> the content will be automatically rendered with a dark background and a white text in Boosted.

Based on this modification, this PR also sets the Sass and/or CSS variables of components handling color and/or bg color to null by default, or inherit, and also sometimes sets the background to transparent.

More info

We decided to make big components (components with multiple layers) to inherit the color because it seemed more logical. Some components escape this logic such as spinners. It's because it's not really the color that is redefined but the use of currentColor.
All this is due to a technical issue we have when the theme is set directly on the component.

If the component sets color at the top level, it overrides the color coming from the data-bs-theme so if it's set to null or inherit, it will inherit the color above and avoid data-bs-theme color. On multiple-layer components it's easier to handle since we only need to avoid declaring color at the top level of this component.

There's a weird behavior for titles. For example h1 redefines the color but .h1 inherits when the data theme is placed on them directly.

For basic elements, form elements and input labels, we decided to keep the behavior as-is. Most likely the theme won't be applied to "basic" elements themselves. And the users could override this behavior if they are using this edge case.

  • We got rid of text-body classes in dark mode page for basic elements introduced by Dark mode: basic elements #2355 to really test the impact of this PR in this context.

Basic concepts

Screenshot 2023-11-07 at 07 39 49

Forms

Components

Note: detailed descriptions can be found directly in the corresponding PR and are not necessarily copied here when it's only about Sass/CSS variables changes. They will be mentioned directly into the migration guide anyway.

Helpers

Utilities

A first PR tackled the changes around the orange color used within the framework: #2362.

  • Background
    • $primary value has changed to should be mentioned in the migration guide (impact)
    • Doc: explain the rules between .bg-primary|success|etc. and .bg-supporting-* (how to use them)
  • Borders
  • Colors
    • Rework docs/5.3/utilities/colors/#oranges-colors to explain it clearly
  • Link
  • Shadows

Examples

Documentation

  • Global rendering
  • Header
  • Footer
  • Homepage
  • Search (Dark mode: Algolia modal #2338)
  • Cookies banner (Dark mode: Tarteaucitron #2339)
  • Design guidelines page
  • Boosted callouts
  • Bootstrap callouts
  • Code blocks (Dark mode: Proposals to handle dark mode code highlights #2378)
  • ToC
  • Sidebar
  • /docsref page
  • /versions page
  • Check the rendering of all pages in detail
  • Color modes
    • _color-modes.md should explain in detail the impact and the usage of data-bs-theme (color, background-color, contextual, container contextual vs component contextual, the difference with dark variant, etc.)
  • Color modes page has been updated to:
    • Drop the design callout
    • Adapt the dropdown example description
    • Add a warning callout about the impact of deactivating entirely the dark mode
  • New color palette page
  • New color theme page
  • Deletion of color page

Final steps

After the PR

  • Remove main-jd-dark-mode from Netlify.
  • Question to design: It was initially only a question about the accordions but could be a more generic question for all components. Do we want to have a transparent background on hover. I mean, on an orange background, instead of having a gray background (var(--bs-secondary-bg)) on hover, we could have something like (rgba(var(--bs-body-color-rgb), .15)). It could help to make components blend with their environment.
  • Create an issue to list what could change if data-bs-theme="inverted" is implemented in Bootstrap
  • Check directly in Bootstrap if we need a data-bs-theme="body" somehow for modals, popovers, offcanvases, etc.
  • Check directly in Bootstrap if we could use for pagination a CSS variable or $component-active-color|bg instead of things like var(--#{$prefix}highlight-color) and var(--#{$prefix}highlight-bg). We should have this intermediate layer of semantics with the notion of active component.
  • Create an issue in Boosted: Would integrating a .bg-solid utility useful? By default, most of our components are transparent, but on some background we might want them either solid or transparent.
    • Tags are solid? They shouldn't probably
  • Create an issue in Boosted: Check if we could introduce a new .border-tertiary utility. Its color should be the same as .text-tertiary and use the current color defined in --bs-border-color-translucent.
    • It could be used for layouts borders, or even inside footer (light mode is awful atm)
  • On Boostrap side, when the dark theme variables will be introduced (in a map of not), .text-bg-* would need some new variables to work correctly something like --bs-on-*.

References

Related Boosted issues

Closes #1776
Closes #2140
Closes #511
Closes #117
Closes #2243

Related Bootstrap issues

Related Bootstrap PRs


Storybook

A new dev dependency named @storybook/addon-themes has been added to have a theme switcher within the Storybook interface which allows to switch between data-bs-theme values manually (see #2376).

@netlify
Copy link

netlify bot commented Sep 11, 2023

Deploy Preview for boosted ready!

Name Link
🔨 Latest commit 6f8e992
🔍 Latest deploy log https://app.netlify.com/sites/boosted/deploys/65941980f98037000894bfe2
😎 Deploy Preview https://deploy-preview-2223--boosted.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@julien-deramond julien-deramond added the color mode Temporary label to highlight color mode issues label Sep 11, 2023
@julien-deramond julien-deramond changed the title feat: dark mode Dark mode Sep 11, 2023
This was referenced Sep 26, 2023
@julien-deramond julien-deramond force-pushed the main-jd-dark-mode branch 2 times, most recently from bbf1afd to fc169fa Compare October 26, 2023 12:23
@julien-deramond julien-deramond force-pushed the main-jd-dark-mode branch 7 times, most recently from af61298 to 85428a8 Compare November 10, 2023 05:44
@julien-deramond julien-deramond force-pushed the main-jd-dark-mode branch 2 times, most recently from 449b31f to 8d5980c Compare November 15, 2023 06:20
louismaximepiton and others added 13 commits January 2, 2024 07:57
Co-authored-by: Julien Déramond <julien.deramond@orange.com>
Co-authored-by: Julien Déramond <julien.deramond@orange.com>
Co-authored-by: Julien Déramond <julien.deramond@orange.com>
Co-authored-by: Julien Déramond <julien.deramond@orange.com>
Co-authored-by: Julien Déramond <julien.deramond@orange.com>
…m examples (#2427)

Co-authored-by: louismaxime.piton <louismaxime.piton@orange.com>
Co-authored-by: louismaxime.piton <louismaxime.piton@orange.com>
Co-authored-by: louismaxime.piton <louismaxime.piton@orange.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
brand color mode Temporary label to highlight color mode issues css feature passed design review v5
Projects
5 participants