diff --git a/core/src/css/float-elements.scss b/core/src/css/float-elements.scss index 0e543e3404e..78147a3798a 100644 --- a/core/src/css/float-elements.scss +++ b/core/src/css/float-elements.scss @@ -1,3 +1,6 @@ +// Global stylesheet: `:host-context()` never matches outside a shadow root +$rtl-use-host-context: false; + @import "../themes/ionic.globals"; @import "../themes/ionic.mixins"; diff --git a/core/src/css/test/global-stylesheets.spec.ts b/core/src/css/test/global-stylesheets.spec.ts new file mode 100644 index 00000000000..430e3702de1 --- /dev/null +++ b/core/src/css/test/global-stylesheets.spec.ts @@ -0,0 +1,38 @@ +import { execFileSync } from 'child_process'; +import { readdirSync } from 'fs'; +import { dirname, join } from 'path'; + +const cssDir = join(__dirname, '..'); +const sassCli = join(dirname(require.resolve('sass')), 'sass.js'); + +/** + * Compiles through the sass CLI, the same way `npm run css.sass` builds + * the published stylesheets. The sass JS API can't be imported here + * because it detects the spec window and never populates its exports. + */ +const compileStylesheet = (file: string) => + execFileSync(process.execPath, [sassCli, '--style=compressed', '--no-source-map', join(cssDir, file)], { + encoding: 'utf8', + }); + +const globalStylesheets = ['.', 'palettes'].flatMap((dir) => + readdirSync(join(cssDir, dir)) + .filter((file) => file.endsWith('.scss')) + .map((file) => join(dir, file)) +); + +describe('global stylesheets', () => { + // https://github.com/ionic-team/ionic-framework/issues/30024 + it.each(globalStylesheets)('%s should not contain :host-context', (file) => { + expect(compileStylesheet(file)).not.toContain(':host-context'); + }); + + it('float-elements.scss should flip start and end floats for an ancestor dir=rtl', () => { + const css = compileStylesheet('float-elements.scss'); + + expect(css).toContain('[dir=rtl] .ion-float-start{float:right !important}'); + expect(css).toContain('[dir=rtl] .ion-float-end{float:left !important}'); + expect(css).toContain('.ion-float-start:dir(rtl){float:right !important}'); + expect(css).toContain('.ion-float-end:dir(rtl){float:left !important}'); + }); +}); diff --git a/core/src/themes/ionic.mixins.scss b/core/src/themes/ionic.mixins.scss index da174046be7..aa25b62abe6 100644 --- a/core/src/themes/ionic.mixins.scss +++ b/core/src/themes/ionic.mixins.scss @@ -226,6 +226,11 @@ // } } +// Whether `rtl()` emits `:host-context()` selectors. Global stylesheets +// set this to false: they apply to the document, where `:host-context()` +// never matches, and Lightning CSS warns about every occurrence. +$rtl-use-host-context: true !default; + @mixin rtl() { $root: #{&}; @@ -254,7 +259,7 @@ } // Supported by Chrome. - @if length($hostContextSelectors) > 0 { + @if $rtl-use-host-context and length($hostContextSelectors) > 0 { @at-root #{$hostContextSelectors} { @content; }