0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-30 22:03:56 -05:00

Rename the ViewTransitions component to ClientRouter (#11980)

* Rename the ViewTransitions component to ClientRouter

* oops, move

* Move it
This commit is contained in:
Matthew Phillips 2024-09-13 10:53:52 -04:00 committed by GitHub
parent 3e70853b76
commit a604a0ca9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 96 additions and 72 deletions

View file

@ -0,0 +1,11 @@
---
'astro': minor
---
ViewTransitions component renamed to ClientRouter
The `<ViewTransitions />` component has been renamed to `<ClientRouter />`. There are no other changes than the name. The old name will continue to work in Astro 5.x, but will be removed in 6.0.
This change was done to clarify the role of the component within Astro's View Transitions support. Astro supports View Transitions APIs in a few different ways, and renaming the component makes it more clear that the features you get from the ClientRouter component are slightly different from what you get using the native CSS-based MPA router.
We still intend to maintain the ClientRouter as before, and it's still important for use-cases that the native support doesn't cover, such as persisting state between pages.

View file

@ -1,5 +1,5 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
import SEO, { type Props as SEOProps } from './SEO.astro';
import { SiteTitle, SiteDescription } from '../consts';
@ -17,4 +17,4 @@ const { title = SiteTitle, name = SiteTitle, description = SiteDescription, ...s
rel="stylesheet"
/>
<ViewTransitions />
<ClientRouter />

View file

@ -1,6 +1,6 @@
---
import '../styles/styles.css';
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
import Footer from '../components/Footer.astro';
import Nav from '../components/Nav.astro';
@ -20,7 +20,7 @@ const { title } = Astro.props as Props;
<meta name="generator" content={Astro.generator} />
<meta name="view-transition" content="same-origin" />
<title>{title}</title>
<ViewTransitions />
<ClientRouter />
</head>
<body class="font-sans bg-gray-900 text-white">
<div class="h-screen overflow-hidden flex flex-col">

View file

@ -116,8 +116,12 @@ declare module 'astro:transitions' {
export const fade: TransitionModule['fade'];
export const createAnimationScope: TransitionModule['createAnimationScope'];
type ViewTransitionsModule = typeof import('./components/ViewTransitions.astro');
export const ViewTransitions: ViewTransitionsModule['default'];
type ClientRouterModule = typeof import('./components/ClientRouter.astro');
/**
* @deprecated The ViewTransitions component has been renamed to ClientRouter
*/
export const ViewTransitions: ClientRouterModule['default'];
export const ClientRouter: ClientRouterModule['default'];
}
declare module 'astro:transitions/client' {

View file

@ -1,10 +1,10 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
---
<html lang="en">
<head>
<title>View Transition Test</title>
<ViewTransitions />
<ClientRouter />
<script is:inline>
// let playwright know when navigate() is done
document.addEventListener('astro:before-swap', (e) => {

View file

@ -1,5 +1,5 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
import { HTMLAttributes } from 'astro/types';
interface Props extends HTMLAttributes<'html'> {}
@ -7,7 +7,7 @@ interface Props extends HTMLAttributes<'html'> {}
<html {...Astro.props}>
<head>
<title>Testing</title>
<ViewTransitions />
<ClientRouter />
</head>
<body>
<main transition:animate="slide">

View file

@ -1,5 +1,5 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
import DarkMode from './DarkMode.astro';
interface Props {
@ -8,25 +8,27 @@ interface Props {
const { link } = Astro.props as Props;
---
<html>
<head>
<title>Testing</title>
{link ? <link rel="stylesheet" href={link} > : ''}
{link ? <link rel="stylesheet" href={link} /> : ''}
<style>
main {
max-width: 900px;
margin: auto;
}
</style>
<link rel="stylesheet" href="/styles.css">
<ViewTransitions handleForms />
<link rel="stylesheet" href="/styles.css" />
<ClientRouter handleForms />
<DarkMode />
<meta name="script-executions" content="0">
<meta charset="utf-8">
<meta name="script-executions" content="0" />
<meta charset="utf-8" />
<script is:inline defer>
{
// Increment a global to see if this is running more than once
globalThis.scriptExecutions = globalThis.scriptExecutions == null ? -1 : globalThis.scriptExecutions;
globalThis.scriptExecutions =
globalThis.scriptExecutions == null ? -1 : globalThis.scriptExecutions;
globalThis.scriptExecutions++;
const el = document.querySelector('[name="script-executions"]');
el.setAttribute('content', globalThis.scriptExecutions);

View file

@ -1,21 +1,21 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
---
<html>
<head>
<ViewTransitions/>
<ClientRouter />
</head>
<body>
<p>Local transitions</p>
<slot/>
<slot />
<script>
document.addEventListener("astro:after-swap", () => {
document.documentElement.setAttribute("class", "blue");
document.documentElement.setAttribute("animations", "" + document.getAnimations().length);
document.addEventListener('astro:after-swap', () => {
document.documentElement.setAttribute('class', 'blue');
document.documentElement.setAttribute('animations', '' + document.getAnimations().length);
});
</script>
</body>
<style>
</body><style>
p {
transition: color 1s;
}

View file

@ -1,29 +1,30 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
---
<html>
<head>
<ViewTransitions />
<ClientRouter />
</head>
<body>
<h1>Abort</h1>
</body>
</html>
<script>
import {navigate } from 'astro:transitions/client';
import { navigate } from 'astro:transitions/client';
document.addEventListener('astro:before-preparation', (e) => {
const originalLoader = e.loader;
e.loader = async () => {
const result = await originalLoader();
if (e.to.href.endsWith("/two")) {
if (e.to.href.endsWith('/two')) {
// delay loading of /two
await new Promise((resolve) => setTimeout(resolve, 1100));
}
}
};
});
// starts later, but is faster and overtakes the slower navigation
setTimeout(()=>navigate("/one"), 400);
setTimeout(() => navigate('/one'), 400);
// starts now, but is to slow to keep its lead
navigate("/two");
navigate('/two');
</script>

View file

@ -1,9 +1,9 @@
---
import { ViewTransitions, fade } from 'astro:transitions';
import { ClientRouter, fade } from 'astro:transitions';
---
<html transition:animate="none">
<head>
<ViewTransitions />
<ClientRouter />
</head>
<body>
<h1 transition:name="h1" transition:animate={fade({duration:500})}>Abort</h1>

View file

@ -1,12 +1,13 @@
---
import { ViewTransitions } from "astro:transitions";
import ClickToNavigate from "../components/ClickToNavigate.jsx"
import { ClientRouter } from 'astro:transitions';
import ClickToNavigate from '../components/ClickToNavigate.jsx';
---
<html>
<head>
<ViewTransitions />
<ClientRouter />
</head>
<body>
<ClickToNavigate id="react-client-load-navigate-button" to="/two" client:load/>
<ClickToNavigate id="react-client-load-navigate-button" to="/two" client:load />
</body>
</html>

View file

@ -1,9 +1,10 @@
---
import { ViewTransitions } from "astro:transitions";
import { ClientRouter } from 'astro:transitions';
---
<html>
<head>
<ViewTransitions />
<ClientRouter />
</head>
<body>
<button id="open" onclick="modal.showModal()">Open Modal</button>

View file

@ -1,10 +1,10 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
---
<html>
<head>
<ViewTransitions handleForms/>
<ClientRouter handleForms />
<meta charset="UTF-8" />
</head>
<body>

View file

@ -1,7 +1,7 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
// For the test fixture, we import the script but we don't use the <ViewTransitions /> component
// For the test fixture, we import the script but we don't use the <ClientRouter /> component
// While this seems to be some strange mistake,
// it might be realistic, e.g. in a configurable CommonHead component
@ -10,10 +10,11 @@ interface Props {
}
const { transitions } = Astro.props;
---
<html>
<head>
<title>Half-Baked</title>
{transitions && <ViewTransitions />}
{transitions && <ClientRouter />}
</head>
<body>
<main>

View file

@ -1,11 +1,11 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
---
<html>
<head>
<title>Testing</title>
<ViewTransitions />
<ClientRouter />
</head>
<body>
<p id="one">One</p>

View file

@ -1,11 +1,11 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
---
<html>
<head>
<title>Testing</title>
<ViewTransitions />
<ClientRouter />
</head>
<body>
<p id="two">Two</p>

View file

@ -114,7 +114,7 @@ test.describe('View Transitions', () => {
expect(loads.length, 'There should only be 1 page load').toEqual(1);
});
test('Moving to a page without ViewTransitions triggers a full page navigation', async ({
test('Moving to a page without ClientRouter triggers a full page navigation', async ({
page,
astro,
}) => {
@ -125,7 +125,7 @@ test.describe('View Transitions', () => {
let p = page.locator('#one');
await expect(p, 'should have content').toHaveText('Page 1');
// Go to page 3 which does *not* have ViewTransitions enabled
// Go to page 3 which does *not* have ClientRouter enabled
await page.click('#click-three');
p = page.locator('#three');
await expect(p, 'should have content').toHaveText('Page 3');
@ -136,7 +136,7 @@ test.describe('View Transitions', () => {
).toEqual(2);
});
test('Moving within a page without ViewTransitions does not trigger a full page navigation', async ({
test('Moving within a page without ClientRouter does not trigger a full page navigation', async ({
page,
astro,
}) => {
@ -146,7 +146,7 @@ test.describe('View Transitions', () => {
let p = page.locator('#one');
await expect(p, 'should have content').toHaveText('Page 1');
// Go to page 3 which does *not* have ViewTransitions enabled
// Go to page 3 which does *not* have ClientRouter enabled
await page.click('#click-three');
p = page.locator('#three');
await expect(p, 'should have content').toHaveText('Page 3');
@ -167,14 +167,14 @@ test.describe('View Transitions', () => {
).toEqual(2);
});
test('Moving from a page without ViewTransitions w/ back button', async ({ page, astro }) => {
test('Moving from a page without ClientRouter w/ back button', async ({ page, astro }) => {
const loads = collectLoads(page);
// Go to page 1
await page.goto(astro.resolveUrl('/one'));
let p = page.locator('#one');
await expect(p, 'should have content').toHaveText('Page 1');
// Go to page 3 which does *not* have ViewTransitions enabled
// Go to page 3 which does *not* have ClientRouter enabled
await page.click('#click-three');
p = page.locator('#three');
await expect(p, 'should have content').toHaveText('Page 3');
@ -606,7 +606,7 @@ test.describe('View Transitions', () => {
await expect(loads.length, 'There should only be 1 page load').toEqual(1);
});
test('Importing ViewTransitions w/o using the component must not mess with history', async ({
test('Importing ClientRouter w/o using the component must not mess with history', async ({
page,
astro,
}) => {
@ -706,7 +706,7 @@ test.describe('View Transitions', () => {
expect(loads.length, 'There should be 2 page load').toEqual(2);
});
test('Scroll position is restored on back navigation from page w/o ViewTransitions', async ({
test('Scroll position is restored on back navigation from page w/o ClientRouter', async ({
page,
astro,
}) => {
@ -716,7 +716,7 @@ test.describe('View Transitions', () => {
let locator = page.locator('#click-external');
await expect(locator).toBeInViewport();
// Go to a page that has not enabled ViewTransitions
// Go to a page that has not enabled ClientRouter
await page.click('#click-external');
locator = page.locator('#three');
await expect(locator).toHaveText('Page 3');

View file

@ -428,7 +428,7 @@ async function transition(
// see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
preparationEvent.newDocument.querySelectorAll('noscript').forEach((el) => el.remove());
// If ViewTransitions is not enabled on the incoming page, do a full page load to it.
// If ClientRouter is not enabled on the incoming page, do a full page load to it.
// Unless this was a form submission, in which case we do not want to trigger another mutation.
if (
!preparationEvent.newDocument.querySelector('[name="astro-view-transitions-enabled"]') &&

View file

@ -29,7 +29,10 @@ export default function astroTransitions({ settings }: { settings: AstroSettings
if (id === resolvedVirtualModuleId) {
return `
export * from "astro/virtual-modules/transitions.js";
export { default as ViewTransitions } from "astro/components/ViewTransitions.astro";
export {
default as ViewTransitions,
default as ClientRouter
} from "astro/components/ClientRouter.astro";
`;
}
if (id === resolvedVirtualClientModuleId) {
@ -47,7 +50,7 @@ export default function astroTransitions({ settings }: { settings: AstroSettings
}
},
transform(code, id) {
if (id.includes('ViewTransitions.astro') && id.endsWith('.ts')) {
if (id.includes('ClientRouter.astro') && id.endsWith('.ts')) {
const prefetchDisabled = settings.config.prefetch === false;
return code.replace('__PREFETCH_DISABLED__', JSON.stringify(prefetchDisabled));
}

View file

@ -835,7 +835,7 @@ export interface AstroUserConfig {
* @type {boolean | object}
* @description
* Enable prefetching for links on your site to provide faster page transitions.
* (Enabled by default on pages using the `<ViewTransitions />` router. Set `prefetch: false` to opt out of this behaviour.)
* (Enabled by default on pages using the `<ClientRouter />` router. Set `prefetch: false` to opt out of this behaviour.)
*
* This configuration automatically adds a prefetch script to every page in the project
* giving you access to the `data-astro-prefetch` attribute.
@ -857,7 +857,7 @@ export interface AstroUserConfig {
* @type {boolean}
* @description
* Enable prefetching for all links, including those without the `data-astro-prefetch` attribute.
* This value defaults to `true` when using the `<ViewTransitions />` router. Otherwise, the default value is `false`.
* This value defaults to `true` when using the `<ClientRouter />` router. Otherwise, the default value is `false`.
*
* ```js
* prefetch: {

View file

@ -1,5 +1,5 @@
---
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
import 'open-props/normalize';
import 'open-props/style';
@ -19,7 +19,7 @@ const { title } = Astro.props;
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<ViewTransitions handleForms />
<ClientRouter handleForms />
</head>
<body>
<slot />