diff options
5 files changed, 45 insertions, 2 deletions
diff --git a/.changeset/chilled-elephants-develop.md b/.changeset/chilled-elephants-develop.md new file mode 100644 index 000000000..06c1da452 --- /dev/null +++ b/.changeset/chilled-elephants-develop.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Adds an `astro:beforeload` event for the dark mode use-case diff --git a/packages/astro/components/ViewTransitions.astro b/packages/astro/components/ViewTransitions.astro index 2df794679..33cad86a2 100644 --- a/packages/astro/components/ViewTransitions.astro +++ b/packages/astro/components/ViewTransitions.astro @@ -13,6 +13,7 @@ const { fallback = 'animate' } = Astro.props as Props; <script> type Fallback = 'none' | 'animate' | 'swap'; type Direction = 'forward' | 'back'; + type Events = 'astro:load' | 'astro:beforeload'; // The History API does not tell you if navigation is forward or back, so // you can figure it using an index. On pushState the index is incremented so you @@ -25,7 +26,8 @@ const { fallback = 'animate' } = Astro.props as Props; const supportsViewTransitions = !!document.startViewTransition; const transitionEnabledOnThisPage = () => !!document.querySelector('[name="astro-view-transitions-enabled"]'); - const onload = () => document.dispatchEvent(new Event('astro:load')); + const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name)); + const onload = () => triggerEvent('astro:load'); async function getHTML(href: string) { const res = await fetch(href); @@ -65,7 +67,10 @@ const { fallback = 'animate' } = Astro.props as Props; async function updateDOM(dir: Direction, html: string, fallback?: Fallback) { const doc = parser.parseFromString(html, 'text/html'); doc.documentElement.dataset.astroTransition = dir; - const swap = () => document.documentElement.replaceWith(doc.documentElement); + const swap = () => { + document.documentElement.replaceWith(doc.documentElement); + triggerEvent('astro:beforeload') + } // Wait on links to finish, to prevent FOUC const links = Array.from(doc.querySelectorAll('head link[rel=stylesheet]')).map( diff --git a/packages/astro/e2e/fixtures/view-transitions/src/components/DarkMode.astro b/packages/astro/e2e/fixtures/view-transitions/src/components/DarkMode.astro new file mode 100644 index 000000000..b8eb585c8 --- /dev/null +++ b/packages/astro/e2e/fixtures/view-transitions/src/components/DarkMode.astro @@ -0,0 +1,18 @@ +<script> + const toggle = () => { + if(localStorage.darkMode) { + document.documentElement.dataset.dark = ''; + } + } + + toggle(); + document.addEventListener('astro:beforeload', () => { + toggle(); + }) +</script> +<style is:global> + html[data-dark] body { + background: black; + color: white; + } +</style> diff --git a/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro b/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro index e4dc54015..9d94681cd 100644 --- a/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro +++ b/packages/astro/e2e/fixtures/view-transitions/src/components/Layout.astro @@ -1,5 +1,6 @@ --- import { ViewTransitions } from 'astro:transitions'; +import DarkMode from './DarkMode.astro'; interface Props { link?: string; @@ -12,6 +13,7 @@ const { link } = Astro.props as Props; <title>Testing</title> {link ? <link rel="stylesheet" href={link} > : ''} <ViewTransitions /> + <DarkMode /> </head> <body> <header transition:animate="morph"> diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js index ee5db3f2f..2dd02afe2 100644 --- a/packages/astro/e2e/view-transitions.test.js +++ b/packages/astro/e2e/view-transitions.test.js @@ -159,6 +159,19 @@ test.describe('View Transitions', () => { await expect(article, 'should have script content').toHaveText('works'); }); + test('astro:beforeload event fires right before the swap', async ({ page, astro }) => { + // 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 2 + await page.click('#click-two'); + p = page.locator('#two'); + const h = page.locator('html'); + await expect(h, 'imported CSS updated').toHaveCSS('background-color', 'rgba(0, 0, 0, 0)'); + }) + test('click hash links does not do navigation', async ({ page, astro }) => { // Go to page 1 await page.goto(astro.resolveUrl('/one')); |