Prevent style removal of client:only components (#8472)
This commit is contained in:
parent
1ed21d10db
commit
fa77fa63d9
5 changed files with 60 additions and 0 deletions
5
.changeset/grumpy-hotels-heal.md
Normal file
5
.changeset/grumpy-hotels-heal.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Prevent client:only styles from being removed in dev (View Transitions)
|
|
@ -113,6 +113,11 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
|
||||
const parser = new DOMParser();
|
||||
|
||||
// A noop element used to prevent styles from being removed
|
||||
if(import.meta.env.DEV) {
|
||||
var noopEl: string | undefined = document.createElement('div');
|
||||
}
|
||||
|
||||
async function updateDOM(doc: Document, loc: URL, state?: State, fallback?: Fallback) {
|
||||
// Check for a head element that should persist, either because it has the data
|
||||
// attribute or is a link el.
|
||||
|
@ -139,6 +144,16 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
}
|
||||
}
|
||||
}
|
||||
// Only run this in dev. This will get stripped from production builds and is not needed.
|
||||
if(import.meta.env.DEV) {
|
||||
if(el.tagName === 'STYLE' && el.dataset.viteDevId) {
|
||||
const devId = el.dataset.viteDevId;
|
||||
// If this same style tag exists, remove it from the new page
|
||||
return doc.querySelector(`style[data-astro-dev-id="${devId}"]`)
|
||||
// Otherwise, keep it anyways. This is client:only styles.
|
||||
|| noopEl;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
import Layout from '../components/Layout.astro';
|
||||
import Island from '../components/Island';
|
||||
---
|
||||
<Layout>
|
||||
<a id="click-two" href="/client-only-two">go to page 2</a>
|
||||
<div transition:persist="island">
|
||||
<Island client:only count={5}>message here</Island>
|
||||
</div>
|
||||
</Layout>
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
import Layout from '../components/Layout.astro';
|
||||
import Island from '../components/Island';
|
||||
---
|
||||
<Layout>
|
||||
<p id="page-two">Page 2</p>
|
||||
<div transition:persist="island">
|
||||
<Island client:only count={5}>message here</Island>
|
||||
</div>
|
||||
</Layout>
|
|
@ -565,4 +565,24 @@ test.describe('View Transitions', () => {
|
|||
p = page.locator('#one');
|
||||
await expect(p, 'should have content').toHaveText('Page 1');
|
||||
});
|
||||
|
||||
test("client:only styles are retained on transition", async ({ page, astro }) => {
|
||||
const totalExpectedStyles = 8;
|
||||
|
||||
// Go to page 1
|
||||
await page.goto(astro.resolveUrl('/client-only-one'));
|
||||
let msg = page.locator('.counter-message');
|
||||
await expect(msg).toHaveText('message here');
|
||||
|
||||
let styles = await page.locator('style').all();
|
||||
expect(styles.length).toEqual(totalExpectedStyles);
|
||||
|
||||
await page.click('#click-two');
|
||||
|
||||
let pageTwo = page.locator('#page-two');
|
||||
await expect(pageTwo, 'should have content').toHaveText('Page 2');
|
||||
|
||||
styles = await page.locator('style').all();
|
||||
expect(styles.length).toEqual(totalExpectedStyles, 'style count has not changed');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue