Skip to content

Commit 9961063

Browse files
authored
refactor: support Lumo/Aura switching in examples (internal) (#4858)
* feat: example theme switcher * clean up * Apply suggestion from @vursen
1 parent a96cc19 commit 9961063

File tree

6 files changed

+62
-19
lines changed

6 files changed

+62
-19
lines changed

dspublisher/theme/global.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ html {
9090
--docs-before-background-color: var(--red-50);
9191
--docs-after-background-color: var(--green-100);
9292
--docs-before-after-border-color: var(--gray-300);
93+
94+
/* Example frame styles currently use hardcoded values from the Lumo theme */
95+
--docs-example-render-font-family:
96+
-apple-system, BlinkMacSystemFont, 'Roboto', 'Segoe UI', Helvetica, Arial, sans-serif,
97+
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
98+
--docs-example-render-color: light-dark(hsla(214, 40%, 16%, 0.94), hsla(214, 96%, 96%, 0.9));
99+
--docs-example-render-background-color: light-dark(#fff, hsl(214, 35%, 21%));
93100
}
94101

95102
::-moz-selection {

frontend/demo/foundation/lumo-tokens.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import propsStyles from '@vaadin/vaadin-lumo-styles/src/props/index.css?inline';
21
import colorScheme from '@vaadin/vaadin-lumo-styles/src/global/color-scheme.css?inline';
2+
import propsStyles from '@vaadin/vaadin-lumo-styles/src/props/index.css?inline';
33
import utilityStyles from '@vaadin/vaadin-lumo-styles/utility.css?inline';
44
import { addStylesheet } from 'Frontend/demo/theme';
55

frontend/demo/init.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ import '../generated/vaadin-featureflags';
66
import { applyTheme } from 'Frontend/demo/theme';
77
import client from 'Frontend/generated/connect-client.default';
88

9-
// Apply the theme to the document, so that notification styles work as expected,
10-
// as the notification container is added to the document body.
11-
applyTheme(document);
9+
// Some Vaadin components add elements to document.body that require theme styles
10+
// (e.g. Notification). Such components are embedded via iframes, but the same examples
11+
// can also be opened as standalone pages. To support both cases, apply the theme
12+
// to the document when the example runs in an iframe or standalone. This is safe
13+
// because in those modes the styles are isolated from the rest of the site.
14+
if (window.location.pathname.endsWith('/example')) {
15+
applyTheme(document);
16+
}
1217

1318
// @ts-expect-error Inserted by DS Publisher
1419
client.prefix = __VAADIN_CONNECT_PREFIX__; // eslint-disable-line no-undef
1520

16-
document.body.style.setProperty('--docs-example-render-font-family', 'var(--lumo-font-family)');
17-
document.body.style.setProperty('--docs-example-render-color', 'var(--lumo-body-text-color)');
18-
document.body.style.setProperty('--docs-example-render-background-color', 'var(--lumo-base-color)');
19-
2021
// Ensures standalone UI sample pags have a lang attribute
2122
document.documentElement.setAttribute('lang', 'en');
2223

frontend/demo/theme.ts

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import '@vaadin/vaadin-lumo-styles/src/props/icons.css';
12
import type { CSSResultGroup } from 'lit';
3+
import auraCss from '@vaadin/aura/aura.css?inline';
4+
import lumoCss from '@vaadin/vaadin-lumo-styles/lumo.css?inline';
25
import docsCss from 'Frontend/themes/docs/styles.css?inline';
36

47
function createStylesheet(css: CSSResultGroup | string): CSSStyleSheet {
@@ -11,14 +14,44 @@ function createStylesheet(css: CSSResultGroup | string): CSSStyleSheet {
1114
return stylesheet;
1215
}
1316

14-
const docsStylesheet = createStylesheet(docsCss);
17+
const lumoStyleSheet = createStylesheet(lumoCss);
18+
const auraStyleSheet = createStylesheet(auraCss);
19+
const docsStyleSheet = createStylesheet(docsCss);
20+
21+
function getRootHost(root: DocumentOrShadowRoot) {
22+
let host: Element;
23+
if (root instanceof ShadowRoot) {
24+
host = root.host;
25+
} else {
26+
host = (root as Document).documentElement;
27+
}
28+
return host;
29+
}
1530

1631
export function applyTheme(root: DocumentFragment | DocumentOrShadowRoot | HTMLElement) {
17-
// The root parameter type is very broad to handle the default return type of
18-
// LitElement.createRenderRoot. In general, we expect this to either be a document or a shadow
19-
// root. The adoptedStyleSheets check below makes Typescript accept the parameter type.
20-
if ('adoptedStyleSheets' in root && !root.adoptedStyleSheets.includes(docsStylesheet)) {
21-
root.adoptedStyleSheets = [...root.adoptedStyleSheets, docsStylesheet];
32+
if (root instanceof ShadowRoot || root instanceof Document) {
33+
const host = getRootHost(root);
34+
35+
const updateTheme = () => {
36+
const adoptedStyleSheets = root.adoptedStyleSheets.filter(
37+
(styleSheet) => ![lumoStyleSheet, auraStyleSheet, docsStyleSheet].includes(styleSheet)
38+
);
39+
40+
if (host.matches('[theme~="aura"]')) {
41+
adoptedStyleSheets.push(auraStyleSheet);
42+
} else {
43+
adoptedStyleSheets.push(lumoStyleSheet);
44+
}
45+
46+
root.adoptedStyleSheets = [...adoptedStyleSheets, docsStyleSheet];
47+
};
48+
49+
new MutationObserver(updateTheme).observe(host, {
50+
attributes: true,
51+
attributeFilter: ['theme'],
52+
});
53+
54+
updateTheme();
2255
}
2356
}
2457

frontend/themes/docs/styles.css

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
/* Import Lumo theme and utility classes */
2-
@import '@vaadin/vaadin-lumo-styles/lumo.css';
3-
@import '@vaadin/vaadin-lumo-styles/utility.css';
4-
51
/* Import custom styles used in examples */
62
@import './app-layout.css';
73
@import './basic-layouts.css';

vite.config.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const customConfig: UserConfigFn = (env) => ({
2626
},
2727
{
2828
name: 'apply-docs-theme',
29-
transform(_code, id) {
29+
transform(code, id) {
3030
// This module is imported by web components exported from Flow to inject styles into their
3131
// shadow root. Instead of importing the docs styles from the Flow bundle again, for example
3232
// by adding @CssImport to DemoExporter, we provide a global from the docs
@@ -36,6 +36,12 @@ const customConfig: UserConfigFn = (env) => ({
3636
if (id.endsWith('generated/css.generated.js')) {
3737
return 'export const applyCss = window.__applyTheme.applyTheme;';
3838
}
39+
40+
// Remove applyCss(document) from `generated/vaadin-web-component.ts` because the global theme
41+
// styles injection is handled by `init.ts` in the docs project.
42+
if (id.endsWith('generated/vaadin-web-component.ts')) {
43+
return code.replace('applyCss(document);', '');
44+
}
3945
},
4046
},
4147
],

0 commit comments

Comments
 (0)