Skip to content

Addon-Pseudo-States: Fix pseudo-states rewriting for nested functional selectors - #34318

Merged
Sidnioulz merged 4 commits into
storybookjs:nextfrom
filipw01:fix/pseudo-states-has-rewrite
Aug 3, 2026
Merged

Sidnioulz merged 4 commits into
storybookjs:nextfrom
filipw01:fix/pseudo-states-has-rewrite

Conversation

@filipw01

@filipw01 filipw01 commented Mar 25, 2026 •

Copy link
Copy Markdown
Contributor

What I did

Fixed storybook-addon-pseudo-states rewriting for pseudo states nested inside functional selectors like :has(span + :hover).
Previously it would try to insert :has(span > ) which is an invalid selector

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Manual testing not performed in a Storybook sandbox.

  1. Enable storybook-addon-pseudo-states in a Storybook instance.
  2. Add a component with CSS that includes a selector like :has(span > :hover) and enable hover pseudo state.
  3. Open the story
  4. Confirm no insertRule() error is thrown and the rewritten selector behaves as expected.

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Bug Fixes
    • Improved pseudo-state selector rewriting for cases where combinators appear inside functional pseudo-class parameters (e.g., :has()).
    • Prevented selector corruption when pseudo-state conditions are removed or rewritten by repairing the selector structure.
    • Preserved the original pseudo-state entry while generating the expected alternative selector rules for both direct matches and ancestor targeting.
  • Tests
    • Added a new test case covering pseudo-state rewriting within complex :has() selectors containing combinators.

@coderabbitai

coderabbitai Bot commented Mar 25, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5952762c-8ae3-4d06-83c2-82074f1de5f2

📥 Commits

Reviewing files that changed from the base of the PR and between 9db9a6c and e6f5fc1.

📒 Files selected for processing (1)
  • code/addons/pseudo-states/src/preview/rewriteStyleSheet.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • code/addons/pseudo-states/src/preview/rewriteStyleSheet.ts

📝 Walkthrough

Walkthrough

extractPseudoStates() now inserts universal selectors before removing pseudo-states that follow combinators or opening parentheses. A new test verifies rewriting of :has(span > :hover) into direct and ancestor-targeting alternatives.

Changes

Pseudo-state selector rewriting

Layer / File(s) Summary
Nested pseudo-state selector rewriting
code/addons/pseudo-states/src/preview/rewriteStyleSheet.ts, code/addons/pseudo-states/src/preview/rewriteStyleSheet.test.ts
Adds selectorStartPattern, changes selector repair in extractPseudoStates(), and tests nested :has(...) selectors containing combinators.

Estimated code review effort: 2 (Simple) | ~10 minutes

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@filipw01 filipw01 changed the title Fix pseudo-states rewriting for :has selectors Fix pseudo-states rewriting for nested functional selectors Mar 26, 2026
@valentinpalkovic valentinpalkovic moved this to Empathy Queue (prioritized) in Core Team Projects Mar 30, 2026
@valentinpalkovic valentinpalkovic changed the title Fix pseudo-states rewriting for nested functional selectors Addon-Pseudo-States: Fix pseudo-states rewriting for nested functional selectors Mar 30, 2026
@valentinpalkovic

Copy link
Copy Markdown
Contributor

Hi @filipw01,

Thank you for your contribution. Due to the high volume of incoming PRs, we are gently requesting that you either link a GitHub issue to the PR or provide a simple reproduction, ideally with a video or image showing the issue and its resolution! Thank you very much!

@valentinpalkovic valentinpalkovic added addon: pseudo-states ci:normal Run our default set of CI jobs (choose this for most PRs). labels Mar 30, 2026
@storybook-app-bot

storybook-app-bot Bot commented Mar 30, 2026 •

Copy link
Copy Markdown
Contributor

Package Benchmarks

Commit: 1a48807, ran on 28 August 2026 at 10:19:22 UTC

The following packages have significant changes to their size or dependencies:

@storybook/addon-mcp

Before After Difference
Dependency count 11 13 🚨 +2 🚨
Self size 107 KB 191 KB 🚨 +84 KB 🚨
Dependency size 2.74 MB 2.89 MB 🚨 +146 KB 🚨
Bundle Size Analyzer Link Link

storybook-addon-pseudo-states

Before After Difference
Dependency count 0 0 0
Self size 24 KB 21 KB 🎉 -3 KB 🎉
Dependency size 686 B 689 B 🚨 +3 B 🚨
Bundle Size Analyzer Link Link

@storybook/addon-vitest

Before After Difference
Dependency count 2 2 0
Self size 466 KB 429 KB 🎉 -36 KB 🎉
Dependency size 350 KB 350 KB 🚨 +3 B 🚨
Bundle Size Analyzer Link Link

@storybook/builder-vite

Before After Difference
Dependency count 1 11 🚨 +10 🚨
Self size 136 KB 136 KB 🎉 -364 B 🎉
Dependency size 28 KB 1.33 MB 🚨 +1.30 MB 🚨
Bundle Size Analyzer Link Link

@storybook/builder-webpack5

Before After Difference
Dependency count 182 182 0
Self size 92 KB 79 KB 🎉 -13 KB 🎉
Dependency size 37.43 MB 37.43 MB 🚨 +9 B 🚨
Bundle Size Analyzer Link Link

storybook

Before After Difference
Dependency count 73 73 0
Self size 22.04 MB 21.39 MB 🎉 -650 KB 🎉
Dependency size 31.20 MB 30.98 MB 🎉 -218 KB 🎉
Bundle Size Analyzer Link Link

@storybook/angular

Before After Difference
Dependency count 185 185 0
Self size 267 KB 160 KB 🎉 -107 KB 🎉
Dependency size 30.29 MB 30.28 MB 🎉 -13 KB 🎉
Bundle Size Analyzer Link Link

@storybook/angular-vite

Before After Difference
Dependency count 20 29 🚨 +9 🚨
Self size 23.08 MB 22.83 MB 🎉 -247 KB 🎉
Dependency size 11.49 MB 12.69 MB 🚨 +1.21 MB 🚨
Bundle Size Analyzer Link Link

@storybook/ember

Before After Difference
Dependency count 181 181 0
Self size 13 KB 13 KB 🎉 -15 B 🎉
Dependency size 32.79 MB 32.77 MB 🎉 -13 KB 🎉
Bundle Size Analyzer Link Link

@storybook/html-vite

Before After Difference
Dependency count 4 14 🚨 +10 🚨
Self size 22 KB 22 KB 🚨 +4 B 🚨
Dependency size 199 KB 1.50 MB 🚨 +1.30 MB 🚨
Bundle Size Analyzer Link Link

@storybook/nextjs

Before After Difference
Dependency count 536 527 🎉 -9 🎉
Self size 641 KB 641 KB 🎉 -174 B 🎉
Dependency size 64.69 MB 64.14 MB 🎉 -549 KB 🎉
Bundle Size Analyzer Link Link

@storybook/nextjs-vite

Before After Difference
Dependency count 101 94 🎉 -7 🎉
Self size 1.42 MB 1.42 MB 🎉 -922 B 🎉
Dependency size 23.32 MB 23.90 MB 🚨 +580 KB 🚨
Bundle Size Analyzer Link Link

@storybook/preact-vite

Before After Difference
Dependency count 4 14 🚨 +10 🚨
Self size 12 KB 12 KB 🚨 +4 B 🚨
Dependency size 217 KB 1.52 MB 🚨 +1.30 MB 🚨
Bundle Size Analyzer Link Link

@storybook/react-native-web-vite

Before After Difference
Dependency count 122 125 🚨 +3 🚨
Self size 29 KB 29 KB 🎉 -13 B 🎉
Dependency size 25.71 MB 25.91 MB 🚨 +204 KB 🚨
Bundle Size Analyzer Link Link

@storybook/react-vite

Before After Difference
Dependency count 79 83 🚨 +4 🚨
Self size 32 KB 32 KB 🎉 -245 B 🎉
Dependency size 20.44 MB 21.21 MB 🚨 +770 KB 🚨
Bundle Size Analyzer Link Link

@storybook/server-webpack5

Before After Difference
Dependency count 194 194 0
Self size 15 KB 15 KB 🚨 +17 B 🚨
Dependency size 38.70 MB 38.69 MB 🎉 -13 KB 🎉
Bundle Size Analyzer Link Link

@storybook/svelte-vite

Before After Difference
Dependency count 11 20 🚨 +9 🚨
Self size 54 KB 54 KB 🚨 +16 B 🚨
Dependency size 25.47 MB 26.67 MB 🚨 +1.20 MB 🚨
Bundle Size Analyzer Link Link

@storybook/sveltekit

Before After Difference
Dependency count 12 21 🚨 +9 🚨
Self size 56 KB 56 KB 🚨 +5 B 🚨
Dependency size 25.52 MB 26.73 MB 🚨 +1.20 MB 🚨
Bundle Size Analyzer Link Link

@storybook/tanstack-react

Before After Difference
Dependency count 80 84 🚨 +4 🚨
Self size 132 KB 113 KB 🎉 -19 KB 🎉
Dependency size 20.47 MB 21.24 MB 🚨 +769 KB 🚨
Bundle Size Analyzer Link Link

@storybook/vue3-vite

Before After Difference
Dependency count 94 103 🚨 +9 🚨
Self size 32 KB 34 KB 🚨 +3 KB 🚨
Dependency size 18.54 MB 43.15 MB 🚨 +24.62 MB 🚨
Bundle Size Analyzer Link Link

@storybook/web-components-vite

Before After Difference
Dependency count 5 15 🚨 +10 🚨
Self size 19 KB 19 KB 🚨 +16 B 🚨
Dependency size 266 KB 1.56 MB 🚨 +1.30 MB 🚨
Bundle Size Analyzer Link Link

@storybook/cli

Before After Difference
Dependency count 205 205 0
Self size 869 KB 829 KB 🎉 -40 KB 🎉
Dependency size 87.61 MB 86.73 MB 🎉 -879 KB 🎉
Bundle Size Analyzer Link Link

@storybook/codemod

Before After Difference
Dependency count 198 198 0
Self size 44 KB 32 KB 🎉 -12 KB 🎉
Dependency size 86.08 MB 85.21 MB 🎉 -869 KB 🎉
Bundle Size Analyzer Link Link

create-storybook

Before After Difference
Dependency count 74 74 0
Self size 1.09 MB 1.09 MB 🚨 +1 KB 🚨
Dependency size 53.24 MB 52.38 MB 🎉 -869 KB 🎉
Bundle Size Analyzer node node

@storybook/csf-plugin

Before After Difference
Dependency count 0 9 🚨 +9 🚨
Self size 0 B 7 KB 🚨 +7 KB 🚨
Dependency size 0 B 1.29 MB 🚨 +1.29 MB 🚨
Bundle Size Analyzer Link Link

@storybook/mcp

Before After Difference
Dependency count 11 11 0
Self size 151 KB 107 KB 🎉 -43 KB 🎉
Dependency size 2.74 MB 2.74 MB 🚨 +896 B 🚨
Bundle Size Analyzer Link Link

@storybook/react

Before After Difference
Dependency count 59 59 0
Self size 1.46 MB 1.48 MB 🚨 +16 KB 🚨
Dependency size 12.28 MB 12.28 MB 🚨 +13 B 🚨
Bundle Size Analyzer Link Link

@storybook/vue3

Before After Difference
Dependency count 90 4 🎉 -86 🎉
Self size 184 KB 68 KB 🎉 -116 KB 🎉
Dependency size 18.11 MB 584 KB 🎉 -17.53 MB 🎉
Bundle Size Analyzer Link Link

@filipw01

Copy link
Copy Markdown
Contributor Author

@valentinpalkovic this is an error I'm getting in storybook, the best reproduction is the test I added in the PR. It's failing without my changes
CleanShot 2026-03-30 at 10 07 25@2x

@github-actions github-actions Bot added the Stale label Apr 10, 2026
@Sidnioulz
Sidnioulz self-requested a review June 18, 2026 09:05
@Sidnioulz Sidnioulz self-assigned this Jun 18, 2026
@Sidnioulz

Copy link
Copy Markdown
Contributor

Sorry for the delay in reviewing this PR, @filipw01! We had a similar one come in and I thought I had merged yours.

Could you please look at the conflicts? The other PR also handles *, with a slightly different approach than yours as it was investigating selector specificity, IIRC.

@valentinpalkovic valentinpalkovic added the sev:S3 Medium priority. Fix within months if possible. label Jul 14, 2026
@filipw01
filipw01 force-pushed the fix/pseudo-states-has-rewrite branch from cab8034 to ddbccf6 Compare July 18, 2026 17:50
filipw01 added 2 commits July 18, 2026 19:52
…as-rewrite

# Conflicts:
#	code/addons/pseudo-states/src/preview/rewriteStyleSheet.ts
@filipw01

Copy link
Copy Markdown
Contributor Author

@Sidnioulz Done, I think that should be good

@valentinpalkovic valentinpalkovic added the qa:needed Pull Requests that will need manual QA prior to release. label Jul 31, 2026
@valentinpalkovic
valentinpalkovic requested a review from a team July 31, 2026 20:41
@Sidnioulz
Sidnioulz enabled auto-merge August 3, 2026 07:02
@Sidnioulz
Sidnioulz merged commit c67c544 into storybookjs:next Aug 3, 2026
131 checks passed
@github-actions github-actions Bot mentioned this pull request Aug 3, 2026
2 tasks done
@ndelangen ndelangen added the patch:yes Bugfix & documentation PR that need to be picked to main branch label Aug 17, 2026
@github-actions

github-actions Bot commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor
Fails
🚫

node failed.

Log

Details
Error:  Error: Could not find the Dangerfile at scripts/dangerfile.ts - if it is local, perhaps you have a typo? If it's using a remote file, it doesn't have a repo reference.
    at /usr/src/danger/dist/platforms/GitHub.js:161:27
    at step (/usr/src/danger/dist/platforms/GitHub.js:44:23)
    at Object.next (/usr/src/danger/dist/platforms/GitHub.js:25:53)
    at /usr/src/danger/dist/platforms/GitHub.js:19:71
    at new Promise (<anonymous>)
    at __awaiter (/usr/src/danger/dist/platforms/GitHub.js:15:12)
    at Object.executeRuntimeEnvironment (/usr/src/danger/dist/platforms/GitHub.js:144:88)
    at /usr/src/danger/dist/commands/danger-runner.js:101:47
    at step (/usr/src/danger/dist/commands/danger-runner.js:34:23)
    at Object.next (/usr/src/danger/dist/commands/danger-runner.js:15:53)
danger-results://tmp/danger-results-a2b90b43.json

Generated by 🚫 dangerJS against 1a48807

@github-actions github-actions Bot mentioned this pull request Aug 17, 2026
5 tasks done
@ndelangen ndelangen added the patch:done Patch/release PRs already cherry-picked to main/release branch label Aug 18, 2026
@yannbf yannbf added qa:success Pull Requests that were successfully QA'ed by the release team. and removed qa:needed Pull Requests that will need manual QA prior to release. labels Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

addon: pseudo-states bug ci:normal Run our default set of CI jobs (choose this for most PRs). patch:done Patch/release PRs already cherry-picked to main/release branch patch:yes Bugfix & documentation PR that need to be picked to main branch qa:success Pull Requests that were successfully QA'ed by the release team. sev:S3 Medium priority. Fix within months if possible.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants