design-system icon indicating copy to clipboard operation
design-system copied to clipboard

[WIP-04] [Project Solar / Phase 1 / Showcase] Add support for theming and theme-switching to the showcase

Open didoo opened this issue 3 months ago • 1 comments

[!NOTE] This PR is quite large, we may consider splitting it up in multiple PRs

:pushpin: Summary

This PR contains multiple pieces of the "theming" puzzle:

  • the implementation of an hdsTheming service and a (temporary) HdsThemeSwitcher component
  • the implementation of a shwTheming service and set of showcase controls to switch theming (and theming options) plus the CSS file linked in the application
  • the implementation of a "Foundations > Theming" showcase page, plus a frameless demo page (with theme switcher) to demonstrate how theming applies to different HDS components and a mock application in general

This is based on top of https://github.com/hashicorp/design-system/pull/3259

:hammer_and_wrench: Detailed description

The first commits are a direct porting of previous showcase theming explorations (squashed):

  • https://github.com/hashicorp/design-system/pull/2589
  • https://github.com/hashicorp/design-system/pull/2611
  • https://github.com/hashicorp/design-system/pull/2608/

After the initial cherry picking of code, there's been a lot of back and forth / refactorings, with different attempts in reaching an implementation that could (hopefully) withstand how different teams may want to adopt theming in their codebases. For this reason, the bulk of the work has been around finding the right "location" for the different pieces of logic, the different concerns: what goes into the HDS theming service vs the SHW theming service; how theming preferences are expressed in the UI and controlled by the user; how consumers decisions are reflected and stored and passed over between HDS/SHW services and components; how a user would use the theming controls (including a showcase user/developer/designer) and how a consumer would allow that user to interact with the application.

It's impossible to describe in detail all the code changes and implementations introduced in this PR, you have to look at diff in code, the showcase application, the "how to review" and "how to test" sections below, and try to get a general picture of what went into this PR.

👉 👉 👉 Preview: theming page

🔎 How to review

This is a quite large PR (we may consider splitting it). I would suggest to look at a piece of code/logic (eg. HDS theming service), see how this interacts with the rest of the code (in HDS and/or in the showcase), and in parallel I would try to see in the showcase application how this logic is reflected in the UI, and try to interact with it to see what happens.

The "logical" order in which I would look at things is this:

  • start to look at the hdsTheming service and HdsThemeSwitcher component under packages/components
  • move on to the shwTheming service under showCase and see how it's an extension of the hdsTheming (something we may undo, if we remove the globalOnSetTheme callback, see below)
  • look at the ShwThemeSwitcher controls (component and sub-components) and see how they're using internally both the hdsTheming and shwTheming services, how the "current" theming options are reflected in the services and in the controls values/states, what happens when a control value is updated/applied, etc
  • see how the showcase has now a small set of themed CSS variables for its colors, so it can respond to the theming changes in the controls/switchers (and how the "static" color values have been replaced across the existing pages/components)
  • look at the foundations/theming showcase page, and its sections
    • the first one is a showcase of the HdsThemSwitcher component
    • the second section is used to test how "contextual theming" (applying a theme at "local" level via a class or data attribute) works, even when nested
    • the third section shows how the HDS "themed" components work (at the moment we have not decided yet how they will be handled in a themed application, but for now at least we have them collected in a single place)
    • the last section is a frameless demo of a mock application with a collection of the most common HDS components
  • see how some of the "Mock" components and pages had to be updated, to accomodate for changes to the AppSideNav (where we've added a theme switcher) and to add even more "mock" UI elements to test with theming
  • look at the temporary files in the public/assets/styles/@hashicorp/ folder, in particular the CSS selectors, and see if they make sense

🛠️ How to test

Launch the showcase application locally, then visit the "Foundations > Theming" page. Here play with the controls in the top right of the page, and see how changing them impacts the page:

  • try to change the theming (you have multiple option groups and options, corresponding to the different way the consumers may want to adopt/use the HDS theming
  • try to change theming via the HDS theme switcher and see how this is reflected in the SHW controls
  • open the advanced options settings and see how setting/applying them see
  • look at the local storage in the devtools, and see how the values get updated when the different options are chose/set
  • look at the different sections of the theming page and see how theming and theming options apply (or don't) to them
  • try to apply different themes to other showcase page (in this case, since the theming tokens are only partially defined, don't expect proper theming switch, the component will look broken)

If you want to double check how the tokens and their values are applied depending on the chosen theme/options, you can update the colors in the temporary/testing CSS files under the public/assets/styles/@hashicorp/ folder (see the CSS variables under the added these to test theming in the showcase comment)

💬 To discuss/decide

  • [ ] do we want to swap only CSS files for the tokens, leaving the component one always the same (see https://github.com/hashicorp/design-system/pull/3259)
  • [ ] is the way in which we're defining the CSS selectors correct, what we expect to be using in production? (this relates to https://github.com/hashicorp/design-system/pull/3239, where we set/write the CSS selectors in the actual themed token files)
  • [ ] do we want to add hds-theme-system or data-hds-theme="system" when the user-selected option is system?
    • pros: it's clearer what theme is applied, by looking at the HTML
    • cons: it required some work to have the selector work with the :not() selectors (see below)
  • [ ] should the _currentStylesheet be stored in local storage or in URL as query param (same for the other shw preferences)?
  • [ ] do we want to keep the globalOnSetTheme callback? which use cases do we foresee?

🗒️ TODOs

  • [ ] write tests for the hdsTheming service
  • [ ] write tests for the HdsTheming component
  • [ ] check if we need to update/fix the CSS selector :root:not([class*="hds-theme-"],[data-hds-theme]) (it may not work, if we use hds-theme-system or data-hds-theme="system")
  • [ ] remove the temporary CSS files under the public/assets/styles/@hashicorp/ folder and replace them with a proper implementation based on the Ember build process
    • if we decide to use only the CSS token files for the swapping, we will have to update the code accordingly
  • [ ] see if there is something we can get from these:
    • https://github.com/IBM/carbon-components-ember/blob/main/docs-app/app/docs-support/theme-support.gts
    • https://github.com/IBM/carbon-components-ember/blob/main/docs-app/app/docs-support/theme-switcher.gts
    • https://github.com/universal-ember/ember-primitives/blob/main/ember-primitives/src/color-scheme.ts
  • [ ] open ticket for the designers to finalize the theme switcher + engineers to implement it (maybe even more than one task, because we have to understand/decide how we will provide a way for the end-users to express their theming choice/preferences)

:camera_flash: Screenshots

https://github.com/user-attachments/assets/6eed6e7a-d469-4950-abfd-9391ab4ca115

:link: External links

Jira tickets:

  • https://hashicorp.atlassian.net/browse/HDS-5518
  • https://hashicorp.atlassian.net/browse/HDS-5532

:eyes: Component checklist

  • [x] Percy was checked for any visual regression
  • [ ] ~~A changelog entry was added via Changesets if needed (see templates here)~~
    • changelogs will be added in the main feature branch

:speech_balloon: Please consider using conventional comments when reviewing this PR.

:clipboard: PCI review checklist
  • [ ] If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.
  • [ ] If applicable, I've worked with GRC to document the impact of any changes to security controls. Examples of changes to controls include access controls, encryption, logging, etc.
  • [ ] If applicable, I've worked with GRC to ensure compliance due to a significant change to the in-scope PCI environment. Examples include changes to operating systems, ports, protocols, services, cryptography-related components, PII processing code, etc.

didoo avatar Sep 25 '25 20:09 didoo

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
hds-showcase Ready Ready Preview Nov 27, 2025 2:56pm
hds-website Ready Ready Preview Nov 27, 2025 2:56pm

vercel[bot] avatar Sep 25 '25 20:09 vercel[bot]

@dchyun @KristinLBradley unfortunately a wrong origin definition in my local Git client made so that I pushed to the wrong branch (the parent) instead of this one, which made GitHub see 0 commits in this branch and close the PR, and now it can't be re-opened. I had to create a new PR https://github.com/hashicorp/design-system/pull/3390 and we'll continue the code review there, while at the same time I'll reply to your review comments in this one. Hopefully it should not be major changes, so I think it's doable. Sorry for the extra work in having to review in one and comment in another.

didoo avatar Nov 27 '25 15:11 didoo