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

refactor(web-components): use adopted style sheets to set theme tokens #31713

Merged
merged 30 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1e99fb8
use adopted style sheets to set theme tokens
marchbox Jun 13, 2024
10cd692
Merge branch 'master' of github.com:marchbox/fluentui into set-theme-…
marchbox Jun 13, 2024
0b7871e
add change file
marchbox Jun 13, 2024
f8e01ae
update comment for clarify
marchbox Jun 13, 2024
129a62f
update code format
marchbox Jun 14, 2024
b346702
Merge branch 'master' of github.com:marchbox/fluentui into set-theme-…
marchbox Jun 18, 2024
2ef4629
remove ref to high contrast theme
marchbox Jun 18, 2024
d5e0717
correct comment
marchbox Jun 18, 2024
4c4673a
allow empty catch in eslint
marchbox Jun 18, 2024
c60fac5
add perf test
marchbox Jun 18, 2024
2dd836b
Merge branch 'microsoft:master' into set-theme-improvements
marchbox Jun 18, 2024
52fc933
Merge branch 'microsoft:master' into set-theme-improvements
marchbox Jun 21, 2024
3a22a09
fix formatting
marchbox Jun 21, 2024
f44ce08
Merge branch 'microsoft:master' into set-theme-improvements
marchbox Jun 21, 2024
0440cc2
apply token custom properties to root element instead of body
marchbox Jun 21, 2024
91ea3b9
Merge branch 'microsoft:master' into set-theme-improvements
marchbox Jun 24, 2024
c03dd6a
Merge branch 'master' into set-theme-improvements
marchbox Jun 25, 2024
863dc7d
update deps
marchbox Jun 25, 2024
22074bd
Merge branch 'set-theme-improvements' of github.com:marchbox/fluentui…
marchbox Jun 25, 2024
970a01a
Merge branch 'microsoft:master' into set-theme-improvements
marchbox Jun 25, 2024
f44f0a5
reenable ts check
marchbox Jun 25, 2024
577d4cd
move tensile-perf deps to root
marchbox Jun 25, 2024
2821ca9
update dependencies
marchbox Jun 26, 2024
7c389dc
Merge branch 'microsoft:master' into set-theme-improvements
marchbox Jun 26, 2024
69b320b
attempt to fix deps dedupe
marchbox Jun 26, 2024
bf01f4c
Merge branch 'master' into set-theme-improvements
marchbox Jun 26, 2024
7c8f644
Merge branch 'master' into set-theme-improvements
marchbox Jun 26, 2024
b853d21
Merge branch 'master' into set-theme-improvements
marchbox Jun 27, 2024
8fe0382
Merge branch 'master' into set-theme-improvements
chrisdholt Jun 27, 2024
946f5c4
Merge branch 'master' into set-theme-improvements
marchbox Jun 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
marchbox marked this conversation as resolved.
Show resolved Hide resolved
marchbox marked this conversation as resolved.
Show resolved Hide resolved
marchbox marked this conversation as resolved.
Show resolved Hide resolved
"type": "prerelease",
"comment": "refactor setTheme() to use adoptedStyleSheets",
"packageName": "@fluentui/web-components",
"email": "[email protected]",
"dependentChangeType": "patch"
}
6 changes: 6 additions & 0 deletions packages/web-components/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
}
},
"rules": {
"no-empty": [
"error",
{
"allowEmptyCatch": true
}
],
"no-extra-boolean-cast": "off",
"no-prototype-builtins": "off",
"no-fallthrough": "off",
Expand Down
4 changes: 4 additions & 0 deletions packages/web-components/docs/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

```ts

/// <reference types="web" />

import type { Constructable } from '@microsoft/fast-element';
import { CSSDirective } from '@microsoft/fast-element';
import { Direction } from '@microsoft/fast-web-utilities';
Expand Down Expand Up @@ -3152,6 +3154,8 @@ class Text_2 extends FASTElement {
block: boolean;
// (undocumented)
connectedCallback(): void;
// (undocumented)
disconnectedCallback(): void;
// @internal
elementInternals: ElementInternals;
font?: TextFont;
Expand Down
2 changes: 1 addition & 1 deletion packages/web-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,9 @@
},
"devDependencies": {
"@microsoft/fast-element": "2.0.0-beta.26",
"@tensile-perf/web-components": "~0.2.0",
"@types/web": "^0.0.142",
"@storybook/html": "6.5.15",
"@tensile-perf/web-components": "~0.1.15",
"chromedriver": "^125.0.0"
},
"dependencies": {
Expand Down
30 changes: 30 additions & 0 deletions packages/web-components/src/theme/set-theme.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { measurePerformance, type TestRenderFunction } from '@tensile-perf/web-components';
import { teamsDarkTheme, teamsLightTheme, webDarkTheme, webLightTheme } from '@fluentui/tokens';

import { setTheme } from './set-theme.js';

const tests: Record<string, TestRenderFunction> = {
mount: ({ onComplete }) => {
const { startMeasure, endMeasure } = measurePerformance();

startMeasure();

// Newly set themes
setTheme(webLightTheme);
setTheme(webDarkTheme);
setTheme(teamsDarkTheme);
setTheme(teamsLightTheme);

// Cached themes
setTheme(webLightTheme);
setTheme(webDarkTheme);
setTheme(teamsDarkTheme);
setTheme(teamsLightTheme);

endMeasure();

onComplete();
},
};

export { tests };
16 changes: 16 additions & 0 deletions packages/web-components/src/theme/set-theme.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { html } from '@microsoft/fast-element';
import { teamsDarkTheme, teamsLightTheme, webDarkTheme, webLightTheme } from '@fluentui/tokens';

import { renderComponent } from '../helpers.stories.js';
import { setTheme } from './set-theme.js';

export default {
title: 'Theme/SetTheme',
};

export const SetTheme = renderComponent(html`
<fluent-button @click="${() => setTheme(webLightTheme)}">webLightTheme</fluent-button>
<fluent-button @click="${() => setTheme(webDarkTheme)}">webDarkTheme</fluent-button>
<fluent-button @click="${() => setTheme(teamsLightTheme)}">teamsLightTheme</fluent-button>
<fluent-button @click="${() => setTheme(teamsDarkTheme)}">teamsDarkTheme</fluent-button>
`);
56 changes: 37 additions & 19 deletions packages/web-components/src/theme/set-theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,52 @@ import * as tokens from './design-tokens.js';

const tokenNames = Object.keys(tokens) as (keyof Theme)[];

const SUPPORTS_REGISTER_PROPERTY = 'registerProperty' in CSS;
const SUPPORTS_ADOPTED_STYLE_SHEETS = 'adoptedStyleSheets' in document;
const themeStyleSheet = new CSSStyleSheet();
const themeStyleTextMap = new Map<Theme, string>();

/**
* Sets the theme tokens on defaultNode.
* @param theme - Flat object of theme token values.
* @internal
*/
export const setTheme = (theme: Theme) => {
for (const t of tokenNames) {
let registered = false;

if ('registerProperty' in CSS) {
try {
CSS.registerProperty({
name: `--${t}`,
inherits: true,
initialValue: theme[t] as string,
});
registered = true;
} catch {
// Do nothing.
// Fallback to setting token custom properties on `<html>` element’s `style`
// attribute, only checking the support of `document.adoptedStyleSheets`
// here because it has broader support than `CSS.registerProperty()`, which
// is checked later.
if (!SUPPORTS_ADOPTED_STYLE_SHEETS) {
setThemeFor(document.documentElement, theme);
return;
}

if (!themeStyleTextMap.has(theme)) {
const tokenDeclarations: string[] = [];

for (const t of tokenNames) {
if (SUPPORTS_REGISTER_PROPERTY) {
marchbox marked this conversation as resolved.
Show resolved Hide resolved
try {
CSS.registerProperty({
name: `--${t}`,
inherits: true,
initialValue: theme[t] as string,
});
} catch {}
}
tokenDeclarations.push(`--${t}: ${theme[t] as string};`);
}

if (!registered) {
// TODO: Find a better way to update the values. Current approach adds
// lots of code to the `style` attribute on `<body>`. Maybe look into
// `document.adoptedStyleSheets`.
setThemeFor(document.body, theme);
}
themeStyleTextMap.set(theme, `html{${tokenDeclarations.join('')}}`);
}

if (!document.adoptedStyleSheets.includes(themeStyleSheet)) {
document.adoptedStyleSheets.push(themeStyleSheet);
} else {
// The very first call to `setTheme()` within a document doesn’t need to
// call `replaceSync()`, because `CSS.registerProperty()` above is
// sufficient to set the tokens.
themeStyleSheet.replaceSync(themeStyleTextMap.get(theme)!);
}
};

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4640,10 +4640,10 @@
dependencies:
"@tensile-perf/tools" "0.1.7"

"@tensile-perf/web-components@~0.1.15":
version "0.1.15"
resolved "https://registry.yarnpkg.com/@tensile-perf/web-components/-/web-components-0.1.15.tgz#95587b220d0b09b79b339da4e4f8694772fab91a"
integrity sha512-gawc20t7uvZyWUZOqBCA6/2Z7wEGECy2ytxe2/FMplDOuUj/CLXKoDY9mtS1dlo+6HjERuL8iP4IjdqURXo2UA==
"@tensile-perf/web-components@~0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@tensile-perf/web-components/-/web-components-0.2.0.tgz#355ac463a121656e68c0567f9c15accf19b61734"
integrity sha512-NEKH6d/2HrOJgW60E/oZ/O2D4vjzBv9xgSQmAz1cQnrEyQ/Odz/l3OWDwfEobcg8VHm6iODVoNAyvYAr4ESTKQ==
dependencies:
"@tensile-perf/runner" "0.4.0"
"@tensile-perf/tools" "0.1.7"
Expand Down
Loading