diff --git a/component/build/scopeStylesToRoot.test.ts b/component/build/scopeStylesToRoot.test.ts index ae42062c3..adb483226 100644 --- a/component/build/scopeStylesToRoot.test.ts +++ b/component/build/scopeStylesToRoot.test.ts @@ -109,4 +109,12 @@ describe("scopeStylesToRoot", () => { ".a .b_abc12:hover { border: 0 }", ); }); + + it("leaves an excluded stylesheet as it is", async () => { + const css = "body { margin: 0 } .menu { color: red }"; + const result = await postcss([ + scopeStylesToRoot({ exclude: [/host\.css$/] }), + ]).process(css, { from: "/app/host.css" }); + expect(result.css).toBe(css); + }); }); diff --git a/component/build/scopeStylesToRoot.ts b/component/build/scopeStylesToRoot.ts index e7d9e1d62..9f35e85b3 100644 --- a/component/build/scopeStylesToRoot.ts +++ b/component/build/scopeStylesToRoot.ts @@ -60,12 +60,18 @@ const IS_ROOT = `:where(${ROOT_SELECTOR})`; * tokens, the component styles, the fonts — is not in this build at all: the * host supplies it, unscoped, along with its copy of Compound. */ -export function scopeStylesToRoot(): Plugin { +interface Options { + /** Stylesheets left as they are: a host's own, which it doesn't scope. */ + exclude?: RegExp[]; +} + +export function scopeStylesToRoot({ exclude = [] }: Options = {}): Plugin { return { postcssPlugin: "element-call-scope-styles-to-root", Once(root) { - const isModule = - root.source?.input.file?.endsWith(".module.css") ?? false; + const file = root.source?.input.file ?? ""; + if (exclude.some((pattern) => pattern.test(file))) return; + const isModule = file.endsWith(".module.css"); root.walkRules((rule) => { if (isRelative(rule)) return; rule.selector = (isModule ? scopeBare : scopeAll).processSync( diff --git a/package.json b/package.json index b30f57ce3..041c91c04 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "@typescript-eslint/utils": "^8.61.0", "@use-gesture/react": "^10.2.11", "@vector-im/compound-design-tokens": "^11.0.0", - "@vector-im/compound-web": "^10.0.0", + "@vector-im/compound-web": "^10.3.0", "@vitejs/plugin-react": "^6.0.2", "@vitest/browser-playwright": "^4.1.5", "@vitest/coverage-v8": "^4.0.18", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 23e2eaa3a..bbd1e2260 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -134,8 +134,8 @@ importers: specifier: ^11.0.0 version: 11.1.0(@types/react@19.2.18)(react@19.2.8) '@vector-im/compound-web': - specifier: ^10.0.0 - version: 10.1.0(@fontsource/inconsolata@5.3.0)(@fontsource/inter@5.3.0)(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(@vector-im/compound-design-tokens@11.1.0(@types/react@19.2.18)(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + specifier: ^10.3.0 + version: 10.3.0(@fontsource/inconsolata@5.3.0)(@fontsource/inter@5.3.0)(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(@vector-im/compound-design-tokens@11.1.0(@types/react@19.2.18)(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@vitejs/plugin-react': specifier: ^6.0.2 version: 6.1.1(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7(supports-color@7.2.0))(@babel/runtime@8.0.0)(rolldown@1.2.7)(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.103.1)(terser@5.46.1)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(sass@1.103.1)(terser@5.46.1)(yaml@2.9.0)) @@ -3240,13 +3240,13 @@ packages: react: optional: true - '@vector-im/compound-web@10.1.0': - resolution: {integrity: sha512-Lhw9Q+RZo1GtDYjF5PXWTD0zdfbrz/vnSVBYFHC8Hq+YeDule2QfGbTRo8IVHeV7jK6ZzsLc8zb6553eeIRLYg==} + '@vector-im/compound-web@10.3.0': + resolution: {integrity: sha512-tce5hsNpdvYXfB5nYQgTK7WjTDqjdxpV1BeGsw67gYAWSFKJr9p6X5gzE79o+Tp/q5uykLuO4ozTBdjLsmUWMw==} peerDependencies: '@fontsource/inconsolata': ^5 '@fontsource/inter': ^5 '@types/react': '*' - '@vector-im/compound-design-tokens': '>=1.6.1 <11.0.0' + '@vector-im/compound-design-tokens': '>=1.6.1 <12.0.0' react: ^18 || ^19.0.0 peerDependenciesMeta: '@types/react': @@ -8672,7 +8672,7 @@ snapshots: '@types/react': 19.2.18 react: 19.2.8 - '@vector-im/compound-web@10.1.0(@fontsource/inconsolata@5.3.0)(@fontsource/inter@5.3.0)(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(@vector-im/compound-design-tokens@11.1.0(@types/react@19.2.18)(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + '@vector-im/compound-web@10.3.0(@fontsource/inconsolata@5.3.0)(@fontsource/inter@5.3.0)(@types/react-dom@19.2.5(@types/react@19.2.18))(@types/react@19.2.18)(@vector-im/compound-design-tokens@11.1.0(@types/react@19.2.18)(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': dependencies: '@floating-ui/react': 0.27.20(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@floating-ui/react-dom': 2.1.9(react-dom@19.2.8(react@19.2.8))(react@19.2.8) diff --git a/src/__snapshots__/AppBar.test.tsx.snap b/src/__snapshots__/AppBar.test.tsx.snap index 99b322ac3..93f11e96c 100644 --- a/src/__snapshots__/AppBar.test.tsx.snap +++ b/src/__snapshots__/AppBar.test.tsx.snap @@ -15,7 +15,7 @@ exports[`AppBar > renders 1`] = ` tabindex="0" >
+ {toggles.length > 0 &&