Skip to content

Commit

Permalink
Extends virtual module astro:transitions/client to export swapFunctio…
Browse files Browse the repository at this point in the history
…ns (#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>
  • Loading branch information
3 people committed Aug 28, 2024
1 parent cce0894 commit 62b0d20
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 20 deletions.
32 changes: 32 additions & 0 deletions .changeset/new-monkeys-sit.md
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 0 deletions packages/astro/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/e2e/view-transitions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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; }');
});
Expand Down
8 changes: 8 additions & 0 deletions packages/astro/src/transitions/swap-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/transitions/vite-plugin-transitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
`;
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../transitions/swap-functions.js';

0 comments on commit 62b0d20

Please sign in to comment.