mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
Extends virtual module astro:transitions/client to export swapFunctions (#11708)
* extend virtual module astro:transitions/client to exports swapFunctions * use virtual module in e2e tests * Update .changeset/new-monkeys-sit.md * Update .changeset/new-monkeys-sit.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Update new-monkeys-sit.md * Update swap-functions.ts restoreFocus() bindings are now returned by saveFocus() and do not make sense anymore as a member of the swapFunctions object * take over suggestion Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * Update .changeset/new-monkeys-sit.md Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> --------- Co-authored-by: Emanuele Stoppa <my.burning@gmail.com> Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
cce0894534
commit
62b0d20b97
9 changed files with 64 additions and 20 deletions
32
.changeset/new-monkeys-sit.md
Normal file
32
.changeset/new-monkeys-sit.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
'astro': minor
|
||||
---
|
||||
|
||||
Adds a new object `swapFunctions` to expose the necessary utility functions on `astro:transitions/client` that allow you to build custom swap functions to be used with view transitions.
|
||||
|
||||
The example below uses these functions to replace Astro's built-in default `swap` function with one that only swaps the `<main>` part of the page:
|
||||
|
||||
```astro
|
||||
<script>
|
||||
import { swapFunctions } from 'astro:transitions/client';
|
||||
|
||||
document.addEventListener('astro:before-swap', (e) => { e.swap = () => swapMainOnly(e.newDocument) });
|
||||
|
||||
function swapMainOnly(doc: Document) {
|
||||
swapFunctions.deselectScripts(doc);
|
||||
swapFunctions.swapRootAttributes(doc);
|
||||
swapFunctions.swapHeadElements(doc);
|
||||
const restoreFocusFunction = swapFunctions.saveFocus();
|
||||
const newMain = doc.querySelector('main');
|
||||
const oldMain = document.querySelector('main');
|
||||
if (newMain && oldMain) {
|
||||
swapFunctions.swapBodyElement(newMain, oldMain);
|
||||
} else {
|
||||
swapFunctions.swapBodyElement(doc.body, document.body);
|
||||
}
|
||||
restoreFocusFunction();
|
||||
};
|
||||
<script>
|
||||
```
|
||||
|
||||
See the [view transitions guide](https://docs.astro.build/en/guides/view-transitions/#astrobefore-swap) for more information about hooking into the `astro:before-swap` lifecycle event and adding a custom swap implementation.
|
2
packages/astro/client.d.ts
vendored
2
packages/astro/client.d.ts
vendored
|
@ -150,6 +150,8 @@ declare module 'astro:transitions/client' {
|
|||
import('./dist/virtual-modules/transitions-events.js').TransitionBeforeSwapEvent;
|
||||
export const isTransitionBeforePreparationEvent: EventModule['isTransitionBeforePreparationEvent'];
|
||||
export const isTransitionBeforeSwapEvent: EventModule['isTransitionBeforeSwapEvent'];
|
||||
type TransitionSwapFunctionModule = typeof import('./dist/virtual-modules/transitions-swap-functions.js');
|
||||
export const swapFunctions: TransitionSwapFunctionModule['swapFunctions']
|
||||
}
|
||||
|
||||
declare module 'astro:prefetch' {
|
||||
|
|
|
@ -7,22 +7,22 @@ import Layout from '../components/Layout.astro';
|
|||
</Layout>
|
||||
<script>
|
||||
|
||||
import { deselectScripts, saveFocus, swapBodyElement, swapHeadElements, swapRootAttributes } from '../../node_modules/astro/dist/transitions/swap-functions'
|
||||
import { swapFunctions } from 'astro:transitions/client';
|
||||
|
||||
document.addEventListener('astro:before-swap', (e) => {
|
||||
e.swap = () => keepStyle(e.newDocument)
|
||||
});
|
||||
|
||||
function keepStyle(doc: Document) {
|
||||
deselectScripts(doc);
|
||||
swapRootAttributes(doc);
|
||||
swapFunctions.deselectScripts(doc);
|
||||
swapFunctions.swapRootAttributes(doc);
|
||||
{
|
||||
const dynamicStyle = document.head.querySelector('style:not(:empty)');
|
||||
swapHeadElements(doc);
|
||||
swapFunctions.swapHeadElements(doc);
|
||||
dynamicStyle && document.head.insertAdjacentElement('afterbegin', dynamicStyle);
|
||||
}
|
||||
const restoreFocusFunction = saveFocus();
|
||||
swapBodyElement(doc.body, document.body)
|
||||
const restoreFocusFunction = swapFunctions.saveFocus();
|
||||
swapFunctions.swapBodyElement(doc.body, document.body)
|
||||
restoreFocusFunction();
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -6,18 +6,18 @@ import Layout from '../components/Layout.astro';
|
|||
<a id="click" href="/keep-two">go to next page</a>
|
||||
</Layout>
|
||||
<script>
|
||||
import { deselectScripts, saveFocus, swapBodyElement, swapHeadElements, swapRootAttributes } from '../../node_modules/astro/dist/transitions/swap-functions'
|
||||
import { swapFunctions } from 'astro:transitions/client';
|
||||
|
||||
function keepTheme(doc:Document) {
|
||||
deselectScripts(doc);
|
||||
swapFunctions.deselectScripts(doc);
|
||||
{
|
||||
const theme = document.documentElement.getAttribute('data-theme')!;
|
||||
swapRootAttributes(doc);
|
||||
swapFunctions.swapRootAttributes(doc);
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
}
|
||||
swapHeadElements(doc);
|
||||
const restoreFocusFunction = saveFocus();
|
||||
swapBodyElement(doc.body, document.body)
|
||||
swapFunctions.swapHeadElements(doc);
|
||||
const restoreFocusFunction = swapFunctions.saveFocus();
|
||||
swapFunctions.swapBodyElement(doc.body, document.body)
|
||||
restoreFocusFunction();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,24 +9,24 @@ import Layout from '../components/Layout.astro';
|
|||
<a id="click" href="/keep-two">go to next page</a>
|
||||
</Layout>
|
||||
<script>
|
||||
import { deselectScripts, saveFocus, swapBodyElement, swapHeadElements, swapRootAttributes } from "../../node_modules/astro/dist/transitions/swap-functions"
|
||||
import { swapFunctions } from 'astro:transitions/client';
|
||||
|
||||
document.addEventListener('astro:before-swap', (e) => {
|
||||
e.swap = () => replaceMain(e.newDocument)
|
||||
});
|
||||
|
||||
function replaceMain(doc:Document){
|
||||
deselectScripts(doc);
|
||||
swapRootAttributes(doc);
|
||||
swapHeadElements(doc);
|
||||
const restoreFocusFunction = saveFocus();
|
||||
swapFunctions.deselectScripts(doc);
|
||||
swapFunctions.swapRootAttributes(doc);
|
||||
swapFunctions.swapHeadElements(doc);
|
||||
const restoreFocusFunction = swapFunctions.saveFocus();
|
||||
{
|
||||
const newMain = doc.body.querySelector('main section');
|
||||
const oldMain = document.body.querySelector('main section');
|
||||
if (newMain && oldMain) {
|
||||
swapBodyElement(newMain, oldMain);
|
||||
swapFunctions.swapBodyElement(newMain, oldMain);
|
||||
} else {
|
||||
swapBodyElement(doc.body, document.body);
|
||||
swapFunctions.swapBodyElement(doc.body, document.body);
|
||||
}
|
||||
}
|
||||
restoreFocusFunction();
|
||||
|
|
|
@ -1447,7 +1447,7 @@ test.describe('View Transitions', () => {
|
|||
await page.click('#click');
|
||||
await expect(page.locator('#name'), 'should have content').toHaveText('Keep 2');
|
||||
|
||||
const styleElement = await page.$('head > style');
|
||||
const styleElement = await page.$('head > style:nth-child(1)');
|
||||
const styleContent = await page.evaluate((style) => style.innerHTML, styleElement);
|
||||
expect(styleContent).toBe('body { background-color: purple; }');
|
||||
});
|
||||
|
|
|
@ -133,6 +133,14 @@ const shouldCopyProps = (el: HTMLElement): boolean => {
|
|||
return persistProps == null || persistProps === 'false';
|
||||
};
|
||||
|
||||
export const swapFunctions = {
|
||||
deselectScripts,
|
||||
swapRootAttributes,
|
||||
swapHeadElements,
|
||||
swapBodyElement,
|
||||
saveFocus,
|
||||
};
|
||||
|
||||
export const swap = (doc: Document) => {
|
||||
deselectScripts(doc);
|
||||
swapRootAttributes(doc);
|
||||
|
|
|
@ -42,6 +42,7 @@ export default function astroTransitions({ settings }: { settings: AstroSettings
|
|||
TRANSITION_BEFORE_SWAP, isTransitionBeforeSwapEvent, TransitionBeforeSwapEvent,
|
||||
TRANSITION_AFTER_SWAP, TRANSITION_PAGE_LOAD
|
||||
} from "astro/virtual-modules/transitions-events.js";
|
||||
export { swapFunctions } from "astro/virtual-modules/transitions-swap-functions.js";
|
||||
`;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export * from '../transitions/swap-functions.js';
|
Loading…
Reference in a new issue