0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

fix(rendering): allow render instructions to propagate while rendering slots (#10316)

* fix(rendering): allow render instructions to propagate while rendering slots

* add test

* add changeset

* undo changes to `playwright.config.js`
This commit is contained in:
Arsh 2024-03-05 21:25:48 +05:30 committed by GitHub
parent 439155c36e
commit 507b4ac246
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 2 deletions

View file

@ -0,0 +1,5 @@
---
"astro": patch
---
Fixes an issue where slotting interactive components within a "client:only" component prevented all component code in the page from running.

View file

@ -0,0 +1,17 @@
---
import ReactCounter from '../components/react/ReactCounter.jsx';
---
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
</head>
<body>
<main>
<ReactCounter id="react-counter" client:only="react">
<Fragment><ReactCounter id="react-counter-nested" client:only="react" children/></Fragment>
</ReactCounter>
</main>
</body>
</html>

View file

@ -114,4 +114,14 @@ test.describe('Nested Frameworks in React', () => {
await expect(count, 'count incremented by 1').toHaveText('1');
});
test('React counter nested in client:only component', async ({ astro, page }) => {
await page.goto(astro.resolveUrl('/nested-in-only'));
const counter = page.locator('#react-counter');
await expect(counter, 'component is visible').toBeVisible();
const count = counter.locator('#react-counter-count');
await expect(count).toBeVisible();
});
});

View file

@ -52,8 +52,16 @@ export async function renderSlotToString(
let instructions: null | RenderInstruction[] = null;
const temporaryDestination: RenderDestination = {
write(chunk) {
if (chunk instanceof Response) return;
if (typeof chunk === 'object' && 'type' in chunk && typeof chunk.type === 'string') {
// if the chunk is already a SlotString, we concatenate
if (chunk instanceof SlotString) {
content += chunk
if (chunk.instructions) {
instructions ??= []
instructions.push(...chunk.instructions)
}
}
else if (chunk instanceof Response) return;
else if (typeof chunk === 'object' && 'type' in chunk && typeof chunk.type === 'string') {
if (instructions === null) {
instructions = [];
}