diff --git a/packages/components/biome.jsonc b/packages/components/biome.jsonc index 00be302c..0dd365d7 100644 --- a/packages/components/biome.jsonc +++ b/packages/components/biome.jsonc @@ -1,6 +1,10 @@ { "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", "extends": ["ultracite/biome/core", "ultracite/biome/react"], + "plugins": [ + "./plugins/no-universal-has.grit", + "./plugins/no-universal-has-css.grit" + ], "css": { "parser": { "tailwindDirectives": true diff --git a/packages/components/plugins/no-universal-has-css.grit b/packages/components/plugins/no-universal-has-css.grit new file mode 100644 index 00000000..d5c738d4 --- /dev/null +++ b/packages/components/plugins/no-universal-has-css.grit @@ -0,0 +1,6 @@ +language css + +`$sel { $decls }` where { + $sel <: r"(?s)(?:.*,)?\s*:has\(.*", + register_diagnostic(span=$sel, message="universal-subject :has selector is banned; anchor :has to a specific element") +} diff --git a/packages/components/plugins/no-universal-has.grit b/packages/components/plugins/no-universal-has.grit new file mode 100644 index 00000000..373cbca4 --- /dev/null +++ b/packages/components/plugins/no-universal-has.grit @@ -0,0 +1,11 @@ +language js + +// group-has-* compiles to a :has() selector with a universal subject, which +// forces whole-document style recalc on every dom mutation in consumers. +// anchor the variant to a stable ancestor instead, e.g. +// [[role=listitem]:has([data-component-part=step-content]:empty)_&]:hidden +`$s` where { + $s <: string(), + $s <: includes "group-has-", + register_diagnostic(span=$s, message="universal-subject :has variant (group-has-*) is banned; anchor :has to a stable ancestor") +} diff --git a/packages/components/src/code.css b/packages/components/src/code.css index 2baf77f1..185fd32e 100644 --- a/packages/components/src/code.css +++ b/packages/components/src/code.css @@ -83,17 +83,14 @@ html.dark [data-fade-overlay] { ); } -:has([data-floating-buttons]) +[data-has-floating-buttons] > [data-component-part="code-block-root"] pre > code { padding-right: var(--code-padding-right, 0px) !important; } -:has([data-component-part="code-block-header"]) - > [data-component-part="code-block-root"] - pre - > code { +[data-has-header] > [data-component-part="code-block-root"] pre > code { padding-right: var(--code-padding-right, 48px) !important; } diff --git a/packages/components/src/components/code-block/code-block.tsx b/packages/components/src/components/code-block/code-block.tsx index 047d1e0c..31f12ced 100644 --- a/packages/components/src/components/code-block/code-block.tsx +++ b/packages/components/src/components/code-block/code-block.tsx @@ -117,6 +117,9 @@ const CodeBlock = function CodeBlock(params: CodeBlockProps) { className )} ref={anchorRef} + {...(hasGrayBackgroundContainer + ? { "data-has-header": "" } + : { "data-has-floating-buttons": "" })} > {hasGrayBackgroundContainer ? (