Skip to content

Commit

Permalink
feat: minimal example of a page transition
Browse files Browse the repository at this point in the history
  • Loading branch information
pmelab committed Sep 15, 2023
1 parent a83a6a3 commit fe3cbf8
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 29 deletions.
33 changes: 33 additions & 0 deletions packages/ui/src/components/Molecules/PageTransition.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { motion, useReducedMotion } from 'framer-motion';
import React, { PropsWithChildren, useEffect } from 'react';

import { Messages, readMessages } from './Messages';

export function PageTransition({ children }: PropsWithChildren) {
const [messages, setMessages] = React.useState<Array<string>>([]);
useEffect(() => {
setMessages(readMessages());
}, []);
return useReducedMotion() ? (
<main id="main-content">
<Messages messages={messages} />
{children}
</main>
) : (
<motion.main
id="main-content"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{
type: 'spring',
mass: 0.35,
stiffness: 75,
duration: 0.3,
}}
>
<Messages messages={messages} />
{children}
</motion.main>
);
}
7 changes: 6 additions & 1 deletion packages/ui/src/components/Routes/ContentHub.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import React from 'react';

import { PageTransition } from '../Molecules/PageTransition';
import { ContentHub as ContentHubOrganism } from '../Organisms/ContentHub';

export function ContentHub(props: { pageSize: number }) {
return <ContentHubOrganism pageSize={props.pageSize} />;
return (
<PageTransition>
<ContentHubOrganism pageSize={props.pageSize} />
</PageTransition>
);
}
17 changes: 9 additions & 8 deletions packages/ui/src/components/Routes/Frame.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { ComponentProps, PropsWithChildren, useEffect } from 'react';
import { AnimatePresence, useReducedMotion } from 'framer-motion';
import React, { ComponentProps, PropsWithChildren } from 'react';

import { Messages, readMessages } from '../Molecules/Messages';
import { Footer } from '../Organisms/Footer';
import Header from '../Organisms/Header';

Expand All @@ -10,16 +10,17 @@ export function Frame(
footer: ComponentProps<typeof Footer>;
}>,
) {
const [messages, setMessages] = React.useState<Array<string>>([]);
useEffect(() => {
setMessages(readMessages());
}, []);
return (
<div>
<Header {...props.header} />
<main>
<Messages messages={messages} />
{props.children}
{useReducedMotion() ? (
<>{props.children}</>
) : (
<AnimatePresence mode="wait" initial={false}>
{props.children}
</AnimatePresence>
)}
</main>
<Footer {...props.footer} />
</div>
Expand Down
39 changes: 21 additions & 18 deletions packages/ui/src/components/Routes/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,36 @@ import React from 'react';

import { isTruthy } from '../../utils/isTruthy';
import { UnreachableCaseError } from '../../utils/unreachable-case-error';
import { PageTransition } from '../Molecules/PageTransition';
import { BlockForm } from '../Organisms/PageContent/BlockForm';
import { BlockMarkup } from '../Organisms/PageContent/BlockMarkup';
import { BlockMedia } from '../Organisms/PageContent/BlockMedia';
import { PageHero } from '../Organisms/PageHero';

export function Page(props: { page: PageFragment }) {
return (
<div>
{props.page.hero ? <PageHero {...props.page.hero} /> : null}
<div className="bg-white py-12 px-6 lg:px-8">
<div className="mx-auto max-w-3xl text-base leading-7 text-gray-700">
<div className="mt-10">
{props.page?.content?.filter(isTruthy).map((block, index) => {
switch (block.__typename) {
case 'BlockMedia':
return <BlockMedia key={index} {...block} />;
case 'BlockMarkup':
return <BlockMarkup key={index} {...block} />;
case 'BlockForm':
return <BlockForm key={index} {...block} />;
default:
throw new UnreachableCaseError(block);
}
})}
<PageTransition>
<div>
{props.page.hero ? <PageHero {...props.page.hero} /> : null}
<div className="bg-white py-12 px-6 lg:px-8">
<div className="mx-auto max-w-3xl text-base leading-7 text-gray-700">
<div className="mt-10">
{props.page?.content?.filter(isTruthy).map((block, index) => {
switch (block.__typename) {
case 'BlockMedia':
return <BlockMedia key={index} {...block} />;
case 'BlockMarkup':
return <BlockMarkup key={index} {...block} />;
case 'BlockForm':
return <BlockForm key={index} {...block} />;
default:
throw new UnreachableCaseError(block);
}
})}
</div>
</div>
</div>
</div>
</div>
</PageTransition>
);
}
6 changes: 4 additions & 2 deletions tests/e2e/specs/links.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ test.describe('links', () => {
await page.getByRole('link', { name: 'link to page' }).click();
await page.waitForURL(websiteUrl('/en/privacy'));

await page.goBack();
await page.goto(websiteUrl('/en/page-links'));

const downloadPromise = page.waitForEvent('download');
await page.getByRole('link', { name: 'link to file' }).click();
await page
.getByRole('link', { name: 'link to file', includeHidden: true })
.click();
const download = await downloadPromise;
expect(download.url()).toBe(
websiteUrl('/sites/default/files/2023-04/document_docx.docx'),
Expand Down

0 comments on commit fe3cbf8

Please sign in to comment.