Skip to content

Conversation

@Artur-
Copy link
Member

@Artur- Artur- commented Nov 12, 2025

Adds a ColorScheme API for controlling light and dark theme variants in Vaadin applications. Includes an @colorscheme annotation for initial configuration and Page.setColorScheme() for runtime switching. Uses the HTML theme attribute approach for CSS compatibility.

Initial Configuration

  • @colorscheme annotation for AppShell to set the initial color scheme
  • Applied as inline style on element during bootstrap

Runtime Control

  • Page.setColorScheme(ColorScheme.Value) / Page.getColorScheme() for dynamic switching
  • ColorScheme.Value enum: LIGHT, DARK, LIGHT_DARK, DARK_LIGHT, NORMAL
  • Server-side state synchronized via ExtendedClientDetails

Implementation Details

  • Sets theme attribute on element (e.g., )
  • Clears inline style.colorScheme to allow theme CSS to set the property
  • Enables CSS selectors: html[theme~="dark"] { color-scheme: dark; }
  • Client sends color scheme to server via v-cs parameter in Flow.ts
  • Automatic string-to-enum conversion via ColorScheme.Value.fromString()

Backward Compatibility

  • Deprecated @theme(variant) attribute in favor of @colorscheme
  • Existing variant usage continues to work

Fixes #15354

@vaadin vaadin deleted a comment from github-actions bot Nov 12, 2025
@github-actions
Copy link

github-actions bot commented Nov 12, 2025

Test Results

1 296 files  + 4  1 296 suites  +4   1h 16m 49s ⏱️ + 1m 11s
9 077 tests +31  9 009 ✅ +31  68 💤 ±0  0 ❌ ±0 
9 533 runs  +26  9 457 ✅ +26  76 💤 ±0  0 ❌ ±0 

Results for commit 7ce5642. ± Comparison against base commit 8a177ec.

♻️ This comment has been updated with latest results.

@jouni
Copy link
Member

jouni commented Nov 12, 2025

Rather than making it work differently with Lumo and Aura, we should align the themes to work the same way. Either both offer a theme="dark|light" attribute or both support the color-scheme property on the html element.

@Artur-
Copy link
Member Author

Artur- commented Nov 12, 2025

Please do

@Artur-
Copy link
Member Author

Artur- commented Nov 12, 2025

Adds Page.setThemeVariant() and Page.getThemeVariant() methods
to enable runtime switching between theme variants without requiring
manual JavaScript execution. The theme variant is automatically synced
from the browser on page load if set in index.html.

The implementation supports both Lumo and Aura themes:
- Lumo: Sets/removes the 'theme' attribute on the HTML element
- Aura: Sets/removes the '--aura-color-scheme' CSS custom property

Key changes:
- Page API: setThemeVariant() and getThemeVariant() methods
- UIInternals: cache theme variant for quick access (returns "" not null)
- ExtendedClientDetails: include theme variant from browser
- FlowBootstrap.js: sync theme attribute and Aura color scheme on page load
- Comprehensive unit and integration tests

Fixes #15354
@Artur- Artur- marked this pull request as ready for review November 17, 2025 14:31
@github-actions github-actions bot added +0.1.0 and removed +1.0.0 labels Nov 17, 2025
@vaadin-bot vaadin-bot added +1.0.0 and removed +0.1.0 labels Nov 17, 2025
Copy link
Member

@jouni jouni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change request concerning the use of --aura-color-scheme which no longer exists.

Why do we need the theme name? It’ll be an empty string for any custom theme not built on top of Lumo or Aura. I feel this feature should be a simple theme-agnostic way of setting attribute values on the <html> document element.

Given the discussion about possibly moving away from the theme attribute in future major versions (correct me if I remember wrong, @rolfsmeds and @web-padawan), I’m unsure if we should build more API explicitly for that.

The themeVariant field in ExtendedClientDetails is null until first
initialized, consistent with other fields like windowName. Added null
check in Page.getThemeVariant() to ensure it always returns an empty
string instead of null when the theme variant hasn't been set yet.
@Artur-
Copy link
Member Author

Artur- commented Nov 18, 2025

Given the discussion about possibly moving away from the theme attribute in future major versions (correct me if I remember wrong, @rolfsmeds and @web-padawan), I’m unsure if we should build more API explicitly for that.

What does this refer to? The API added is for getting the variant: dark or light. It can be set using an attribute or using magic fairy dust and this API stays the same

@Artur-
Copy link
Member Author

Artur- commented Nov 18, 2025

Why do we need the theme name? It’ll be an empty string for any custom theme not built on top of Lumo or Aura.

Depends on who "we" are. Some add-on authors will presumably use it to customize some behavior to better match Aura or Lumo defaults, and use either one as the fallback if you have a completely custom theme.

The --aura-color-scheme CSS custom property has been replaced with the
native color-scheme property in Aura theme. Updated the fallback logic
to check for the standard color-scheme property when the theme attribute
is not present.
@Artur- Artur- changed the title feat: add ColorScheme (light/dark) API for runtime theme switching feat: add ColorScheme API for light/dark theme support Nov 20, 2025
@Artur-
Copy link
Member Author

Artur- commented Nov 20, 2025

Changed the whole API to be based on ColorScheme instead of ThemeVariant

@Artur-
Copy link
Member Author

Artur- commented Nov 20, 2025

Component level API in #22799

@vaadin vaadin deleted a comment from github-actions bot Nov 20, 2025
- IndexHtmlRequestHandler now sets theme attribute instead of inline style
- Updated PageTest to check for theme attribute and style clearing
- Both @colorscheme and @theme(variant) now set theme attribute consistently
- All tests pass
@Artur- Artur- requested review from caalador and jouni November 21, 2025 07:39
@jouni
Copy link
Member

jouni commented Nov 21, 2025

But what is SYSTEM? Do you mean NORMAL which is a valid CSS value?

"System" is sometimes/often used to indicate light dark, aka "auto", aka "operating system preference". It’s different from normal, which is the default/initial value of the browser, which allows the color scheme to be defined by the meta tag. If there’s no meta tag, then normal results in light mode.

The color-scheme CSS property is essentially a way to override the meta tag value.

NORMAL doesn't force browser default behavior - it just means no
color scheme is set via this API. The actual behavior depends on
other factors like browser defaults, system preferences, or meta tags.
Addresses review feedback - sets both theme attribute and color-scheme
property to support custom themes that don't define their own CSS rules.

The theme attribute enables CSS targeting (html[theme~='dark']), while
the inline color-scheme property ensures browser UI adaptation works
universally, even for custom themes.

- Updated Page.java to set property instead of clearing it
- Updated documentation to explain dual-setting approach
- Updated all tests to verify both attribute and property
- All integration tests passing (6/6)
@vaadin vaadin deleted a comment from github-actions bot Nov 21, 2025
For multi-value color schemes like LIGHT_DARK, the theme attribute now
uses hyphens (e.g., "light-dark") while the CSS color-scheme property
uses spaces (e.g., "light dark").

- Added getThemeValue() method to ColorScheme.Value enum
- Updated Page.setColorScheme() to pass separate values for theme attribute and CSS property
- Updated IndexHtmlRequestHandler to use getThemeValue()
- Added ColorSchemeTest to verify enum behavior
- Updated PageTest with test for LIGHT_DARK handling
- All unit and integration tests passing
@Artur-
Copy link
Member Author

Artur- commented Nov 21, 2025

Let's wait for @jouni then

@sonarqubecloud
Copy link

@jouni jouni self-requested a review November 24, 2025 07:32
@Artur- Artur- merged commit ad035c3 into main Nov 24, 2025
34 checks passed
@Artur- Artur- deleted the flow-change-dark branch November 24, 2025 07:50
@vaadin-bot
Copy link
Collaborator

This ticket/PR has been released with Vaadin 25.0.0-beta8.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Java API for changing the variant of the theme (light / dark)

7 participants