0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-06 22:10:10 -05:00

Add astro:beforeload event (#7823)

* Add astro:beforeload event

* Adding a changeset

* Update .changeset/chilled-elephants-develop.md

Co-authored-by: Yan Thomas <61414485+Yan-Thomas@users.noreply.github.com>

---------

Co-authored-by: Yan Thomas <61414485+Yan-Thomas@users.noreply.github.com>
This commit is contained in:
Matthew Phillips 2023-07-27 08:57:37 -04:00 committed by GitHub
parent 30336bab94
commit 5161cf919c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 2 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Adds an `astro:beforeload` event for the dark mode use-case

View file

@ -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(

View file

@ -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>

View file

@ -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">

View file

@ -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'));