Add skeleton, updates to client email formatting
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { navigating, page } from '$app/stores';
|
||||
import { afterNavigate, disableScrollHandling } from '$app/navigation';
|
||||
import { initClickTracking, trackPageView } from '$lib/analytics';
|
||||
import RouteSkeleton from '$lib/components/RouteSkeleton.svelte';
|
||||
import '$lib/styles/variables.css';
|
||||
import '$lib/styles/base.css';
|
||||
import '$lib/styles/layout.css';
|
||||
@@ -13,6 +15,26 @@
|
||||
|
||||
onMount(() => initClickTracking());
|
||||
|
||||
function shouldShowSkeleton() {
|
||||
const navigation = $navigating;
|
||||
|
||||
if (!navigation?.to?.url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const fromPath = navigation.from?.url.pathname ?? $page.url.pathname;
|
||||
const toPath = navigation.to.url.pathname;
|
||||
|
||||
if (navigation.to.url.hash && toPath === fromPath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return toPath !== fromPath;
|
||||
}
|
||||
|
||||
$: loadingPath = $navigating?.to?.url.pathname ?? $page.url.pathname;
|
||||
$: showRouteSkeleton = shouldShowSkeleton();
|
||||
|
||||
afterNavigate(({ from, to }) => {
|
||||
if (!from || !to || to.url.hash) {
|
||||
return;
|
||||
@@ -38,4 +60,32 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<slot />
|
||||
<div class="layout-shell">
|
||||
<div class:layout-content-loading={showRouteSkeleton} class="layout-content" aria-hidden={showRouteSkeleton}>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
{#if showRouteSkeleton}
|
||||
<div class="layout-skeleton-layer" role="status" aria-label="Loading page" aria-live="polite">
|
||||
<RouteSkeleton pathname={loadingPath} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.layout-shell {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.layout-content-loading {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.layout-skeleton-layer {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 30;
|
||||
overflow-y: auto;
|
||||
background: rgba(251, 251, 251, 0.98);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { render } from '@testing-library/svelte';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { setMockNavigating, setMockPage } from '../test/mocks/app-stores';
|
||||
|
||||
const afterNavigate = vi.fn();
|
||||
const disableScrollHandling = vi.fn();
|
||||
@@ -49,4 +50,25 @@ describe('root layout navigation behavior', () => {
|
||||
|
||||
expect(disableScrollHandling).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('shows a route skeleton while navigating to a new page', async () => {
|
||||
setMockPage('https://www.goodwalk.co.nz/about');
|
||||
setMockNavigating('https://www.goodwalk.co.nz/contact-us', 'https://www.goodwalk.co.nz/about');
|
||||
|
||||
const { default: Layout } = await import('./+layout.svelte');
|
||||
const { getByLabelText, container } = render(Layout);
|
||||
|
||||
expect(getByLabelText('Loading page')).toBeInTheDocument();
|
||||
expect(container.querySelector('[data-skeleton-variant="contact"]')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not show the skeleton for hash-only navigation', async () => {
|
||||
setMockPage('https://www.goodwalk.co.nz/about');
|
||||
setMockNavigating('https://www.goodwalk.co.nz/about#team', 'https://www.goodwalk.co.nz/about');
|
||||
|
||||
const { default: Layout } = await import('./+layout.svelte');
|
||||
const { queryByLabelText } = render(Layout);
|
||||
|
||||
expect(queryByLabelText('Loading page')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ import { GET } from './+server';
|
||||
|
||||
describe('robots endpoint', () => {
|
||||
it('returns the crawl policy and sitemap location', async () => {
|
||||
const response = GET();
|
||||
const response = await GET({} as never);
|
||||
const body = await response.text();
|
||||
|
||||
expect(response.headers.get('content-type')).toBe('text/plain; charset=utf-8');
|
||||
|
||||
@@ -10,7 +10,7 @@ describe('sitemap endpoint', () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date('2026-05-01T09:15:00Z'));
|
||||
|
||||
const response = GET();
|
||||
const response = await GET({} as never);
|
||||
const body = await response.text();
|
||||
|
||||
expect(response.headers.get('content-type')).toBe('application/xml; charset=utf-8');
|
||||
|
||||
Reference in New Issue
Block a user