8000 fix(custom-element): ensure child component styles are injected in correct order before parent styles by edison1105 · Pull Request #13374 · vuejs/core · GitHub
[go: up one dir, main page]

Skip to content

fix(custom-element): ensure child component styles are injected in correct order before parent styles #13374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

edison1105
Copy link
Member
@edison1105 edison1105 commented May 23, 2025

close #13029

Summary by CodeRabbit

  • New Features

    • Improved style injection for custom elements: Child component styles are now injected before parent styles in the shadow DOM, ensuring correct style order even in deeply nested or wrapped component structures.
  • Bug Fixes

    • Ensured consistent and predictable CSS order for nested custom elements, preventing style overrides due to incorrect injection sequence.
  • Tests

    • Added new test cases to verify correct style injection order for nested and wrapped custom elements.

Copy link
coderabbitai bot commented May 23, 2025

Walkthrough

The changes update the custom element style injection mechanism to ensure child component styles are injected before parent styles within the shadow DOM. This is achieved by modifying method signatures and logic for style insertion, and by adding comprehensive tests to verify the correct style order in nested component scenarios.

Changes

File(s) Change Summary
packages/runtime-core/src/component.ts Updated the ComponentCustomElementInterface interface: the _injectChildStyle method now accepts an additional optional parent parameter of type ConcreteComponent.
packages/runtime-dom/src/apiCustomElement.ts Introduced a private _styleAnchors WeakMap in VueElement to track style anchors. Modified _applyStyles and _injectChildStyle to accept an optional parentComp parameter, adjusting logic so child styles are injected before parent styles by managing insertion anchors in the shadow DOM.
packages/runtime-core/src/renderer.ts Updated the call to _injectChildStyle in setupRenderEffect to pass both the component's type and its parent's type (if available), providing context for hierarchical style injection.
packages/runtime-dom/__tests__/customElement.spec.ts Added three new tests to the styles suite to verify that child component styles (including nested and wrapped child components) are injected before parent styles in custom elements, covering various nesting and parent-style scenarios.

Sequence Diagram(s)

sequenceDiagram
    participant Parent as Parent Custom Element
    participant Child as Child Component
    participant Wrapper as Wrapper Component
    participant ShadowDOM as Shadow DOM

    Parent->>Child: Mount child component
    Child->>Wrapper: Mount wrapper component (optional)
    Wrapper->>ShadowDOM: Inject child/wrapper styles (_injectChildStyle with parent)
    ShadowDOM->>ShadowDOM: Insert child/wrapper styles before parent styles
    Parent->>ShadowDOM: Inject parent styles (_injectChildStyle)
    ShadowDOM->>ShadowDOM: Insert parent styles after child styles
Loading

Assessment against linked issues

Objective Addressed Explanation
Ensure child component styles are injected before parent styles in custom element mode (#13029)
Match style injection order in custom element mode to standard Vue app behavior (#13029)
Add tests verifying correct style order for nested and wrapped child components in custom elements (#13029)

Suggested labels

ready to merge, :hammer: p3-minor-bug, scope: custom elements

Poem

In the garden of styles, a rabbit did see,
That children should dress before parents, with glee.
Now colors cascade in the proper array,
From greenest of leaves to the roots of the day.
With anchors and order, the bug hops away—
Hooray for the fix, and a much brighter display! 🐇🌈


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fa787c and 41379c4.

📒 Files selected for processing (4)
  • packages/runtime-core/src/component.ts (1 hunks)
  • packages/runtime-core/src/renderer.ts (1 hunks)
  • packages/runtime-dom/__tests__/customElement.spec.ts (1 hunks)
  • packages/runtime-dom/src/apiCustomElement.ts (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Redirect rules
  • GitHub Check: Header rules
  • GitHub Check: Pages changed
🔇 Additional comments (9)
packages/runtime-core/src/renderer.ts (1)

1352-1353: Enhances style ordering in custom elements.

The change adds parent component context to style injection in custom elements, ensuring child component styles are injected before parent styles. This fixes style precedence issues in nested component hierarchies.

packages/runtime-core/src/component.ts (1)

1259-1259: Extends ComponentCustomElementInterface to support proper style ordering.

The method signature update adds an optional parent parameter to _injectChildStyle, aligning with the implementation in the renderer that now passes parent context. This is essential for maintaining correct CSS cascade behavior in custom elements with nested components.

packages/runtime-dom/__tests__/customElement.spec.ts (3)

919-950: Well-designed test for child component style injection order.

This test effectively verifies that child component styles are correctly injected before parent styles, even with wrapper components in the hierarchy. The test case properly validates the style injection ordering by checking that the styles appear in the correct sequence: child (green) → wrapper (blue) → parent (red).


952-978: Good edge case coverage for parent components without styles.

This test handles an important edge case where the parent component doesn't have styles but its children do. It ensures that even without parent styles, the child component styles are still properly injected into the shadow DOM in the correct order.


980-1021: Thorough test for deeply nested component style inheritance.

This test comprehensively validates style injection in a complex component hierarchy with multiple nesting levels. It correctly asserts that styles are injected in proper order from innermost to outermost components (greenyellowblueblackred), which is essential for maintaining correct CSS cascade priority.

packages/runtime-dom/src/apiCustomElement.ts (4)

235-236: Good use of WeakMap for tracking style anchor elements.

Using a WeakMap is appropriate here as it allows garbage collection of component references when they're no longer needed, preventing memory leaks.


599-610: Clear implementation for handling parents without styles.

This code correctly handles the case where a parent component has no styles but its children do. It creates a text node as an anchor point and inserts it in the appropriate position in the shadow DOM, ensuring that child styles can be injected before parent styles even when the parent initially has no styles.


613-634: Well-structured style injection logic with proper ordering.

The implementation ensures styles are inserted in the correct order by:

  1. Iterating through styles in reverse order
  2. Using a tracked "last" element to maintain insertion sequence
  3. Using different insertion strategies based on whether a parent component exists
  4. Setting appropriate style anchors for future reference

This approach guarantees child component styles are injected before parent styles, maintaining proper CSS cascade priority.


702-705: API signature update that maintains backward compatibility.

The updated method signature for _injectChildStyle correctly adds an optional parentComp parameter, which maintains backward compatibility while enabling the new style injection ordering functionality.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
github-actions bot commented May 23, 2025

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 101 kB (+454 B) 38.4 kB (+107 B) 34.7 kB (+199 B)
vue.global.prod.js 159 kB (+454 B) 58.6 kB (+112 B) 52.1 kB (+130 B)

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.6 kB (+41 B) 18.2 kB (+14 B) 16.7 kB (+4 B)
createApp 54.6 kB (+41 B) 21.2 kB (+15 B) 19.4 kB (+11 B)
createSSRApp 58.8 kB (+41 B) 23 kB (+11 B) 21 kB (+24 B)
defineCustomElement 59.9 kB (+454 B) 22.9 kB (+142 B) 20.9 kB (+114 B)
overall 68.7 kB (+41 B) 26.4 kB (+15 B) 24.1 kB (-14 B)

Copy link
pkg-pr-new bot commented May 23, 2025

Open in StackBlitz

@vue/compiler-core

npm i https://pkg.pr.new/@vue/compiler-core@13374

@vue/compiler-dom

npm i https://pkg.pr.new/@vue/compiler-dom@13374

@vue/compiler-sfc

npm i https://pkg.pr.new/@vue/compiler-sfc@13374

@vue/compiler-ssr

npm i https://pkg.pr.new/@vue/compiler-ssr@13374

@vue/reactivity

npm i https://pkg.pr.new/@vue/reactivity@13374

@vue/runtime-core

npm i https://pkg.pr.new/@vue/runtime-core@13374

@vue/runtime-dom

npm i https://pkg.pr.new/@vue/runtime-dom@13374

@vue/server-renderer

npm i https://pkg.pr.new/@vue/server-renderer@13374

@vue/shared

npm i https://pkg.pr.new/@vue/shared@13374

vue

npm i https://pkg.pr.new/vue@13374

@vue/compat

npm i https://pkg.pr.new/@vue/compat@13374

commit: 41379c4

@edison1105 edison1105 force-pushed the edison/fix/13029 branch 5 times, most recently from 468260b to 8b6b732 Compare May 23, 2025 07:38
@edison1105 edison1105 force-pushed the edison/fix/13029 branch 2 times, most recently from 5b13a9e to 84a0439 Compare May 23, 2025 13:11
@edison1105 edison1105 changed the title fix(custom-element): inject child style before parent component's style fix(custom-element): ensure child component styles are injected in correct order before parent styles May 23, 2025
@edison1105
Copy link
Member Author

/ecosystem-ci run

@vuejs vuejs deleted a comment from edison1105 May 23, 2025
@vue-bot
Copy link
Contributor
vue-bot commented May 23, 2025

📝 Ran ecosystem CI: Open

suite result latest scheduled
nuxt success success
vant success success
test-utils success success
language-tools success success
router success success
radix-vue success success
primevue success success
pinia success success
quasar success success
vitepress success success
vue-macros success success
vite-plugin-vue success success
vue-i18n success success
vue-simple-compiler success success
vueuse success success
vuetify success success

@edison1105 edison1105 marked this pull request as ready for review May 23, 2025 13:33
@edison1105 edison1105 added ready to merge The PR is ready to be merged. 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. scope: custom elements labels May 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. ready to merge The PR is ready to be merged. scope: custom elements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Custom Element Mode - Styles applied in wrong order
2 participants
0