Skip to content

feat(rrweb-snapshot): support more user-action pseudo-classes for rebuild#1897

Open
hi-ogawa wants to merge 4 commits into
rrweb-io:mainfrom
hi-ogawa:feat/hack-css-pseudo-classes
Open

feat(rrweb-snapshot): support more user-action pseudo-classes for rebuild#1897
hi-ogawa wants to merge 4 commits into
rrweb-io:mainfrom
hi-ogawa:feat/hack-css-pseudo-classes

Conversation

@hi-ogawa

@hi-ogawa hi-ogawa commented Jul 2, 2026

Copy link
Copy Markdown

This PR adds hackCssPseudoClasses option to rebuild so snapshots can mirror :active, :focus, :focus-visible and :focus-within (not just :hover) as escaped classes for replay. Defaults to [':hover'], so existing behavior is unchanged.

This is a suggested change for #1896. Happy to iterate or close depending on the maintainers' decision. I wanted to open a PR first so there's a concrete scope of changes to discuss. Thanks for the review!

hi-ogawa and others added 2 commits July 2, 2026 13:21
…ebuilding

`pseudoClassPlugin` only mirrored `:hover` to an escaped class. Add a
`hackCssPseudoClasses` rebuild option (default `[':hover']`, unchanged) so
consumers that rebuild snapshots without the event replayer can also mirror
`:active`, `:focus`, `:focus-visible` and `:focus-within` for replay.

The selected set is threaded through `rebuild` -> `adaptCssForReplay` and folded
into its cache key. Each pseudo-class regex ends with a `(?![-\w])` boundary so
`:focus` is not rewritten inside `:focus-visible` / `:focus-within`.

Co-authored-by: OpenCode (claude-opus-4-8) <noreply@opencode.ai>
Co-authored-by: OpenCode (claude-opus-4-8) <noreply@opencode.ai>
@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f7431c4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
rrweb-snapshot Patch
rrweb Patch
rrdom Patch
rrdom-nodejs Patch
rrweb-player Patch
@rrweb/all Patch
@rrweb/replay Patch
@rrweb/record Patch
@rrweb/types Patch
@rrweb/packer Patch
@rrweb/utils Patch
@rrweb/browser-client Patch
@rrweb/web-extension Patch
rrvideo Patch
@rrweb/rrweb-plugin-console-record Patch
@rrweb/rrweb-plugin-console-replay Patch
@rrweb/rrweb-plugin-sequential-id-record Patch
@rrweb/rrweb-plugin-sequential-id-replay Patch
@rrweb/rrweb-plugin-canvas-webrtc-record Patch
@rrweb/rrweb-plugin-canvas-webrtc-replay Patch
@rrweb/rrweb-plugin-network-record Patch
@rrweb/rrweb-plugin-network-replay Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Comment on lines +127 to +132
/**
* User-action pseudo-classes to mirror as escaped classes when `hackCss` is
* enabled, e.g. `foo:focus` becomes `foo:focus, foo.\:focus`.
* Defaults to `[':hover']`.
*/
hackCssPseudoClasses?: HackCssPseudoClass[];

@hi-ogawa hi-ogawa Jul 2, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative API may be to extend hackCss option like:

hackCss: boolean | { pseudoClasses: HackCssPseudoClass[] }

Please let me know if you have any API preference 🙏

hi-ogawa and others added 2 commits July 2, 2026 14:10
Backs the `(?![-\w])` boundary: `:focus` must not be rewritten inside
`:focus-visible` / `:focus-within`.

Co-authored-by: OpenCode (claude-opus-4-8) <noreply@opencode.ai>
Co-authored-by: OpenCode (claude-opus-4-8) <noreply@opencode.ai>
@hi-ogawa
hi-ogawa marked this pull request as ready for review July 2, 2026 05:26
Copilot AI review requested due to automatic review settings July 2, 2026 05:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in mechanism in rrweb-snapshot’s rebuild pipeline to mirror additional “user-action” CSS pseudo-classes (beyond :hover) as escaped class selectors, enabling snapshot consumers (e.g. static viewers) to paint interaction states by toggling classes on rebuilt nodes.

Changes:

  • Add hackCssPseudoClasses to rebuild/rebuildIntoSandboxedIframe to control which pseudo-classes are mirrored (default remains [':hover']).
  • Generalize the CSS rewriting plugin to mirror :active, :focus, :focus-visible, and :focus-within, with tests covering correct boundary handling.
  • Extend integration coverage to validate that rebuilt snapshots paint the mirrored pseudo-class styles when the corresponding escaped classes are added.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/rrweb-snapshot/src/css.ts Generalizes the PostCSS selector rewrite to mirror a configurable set of supported pseudo-classes.
packages/rrweb-snapshot/src/rebuild.ts Threads hackCssPseudoClasses through rebuild + updates CSS rewrite caching to include the selected pseudo-class set.
packages/rrweb-snapshot/test/css.test.ts Updates and extends unit tests to cover new pseudo-class mirroring and boundary correctness.
packages/rrweb-snapshot/test/integration.test.ts Adds integration tests proving rebuilt snapshots can paint mirrored pseudo-class styles and that default remains hover-only.
.changeset/hack-css-pseudo-classes.md Documents the new option as a patch-level change for rrweb-snapshot.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request]: Ability to reproduce more user-action pseudo-classes (:active, :focus, :focus-visible, etc.) in replay

2 participants