From 782a5a1e794a9a8ef6b0b892cd3f386ed583c680 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 22 Apr 2022 18:56:32 +0200 Subject: chore: add a SectionedLayout component --- .../templates/sectioned/sectioned-layout.test.tsx | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/components/templates/sectioned/sectioned-layout.test.tsx (limited to 'src/components/templates/sectioned/sectioned-layout.test.tsx') diff --git a/src/components/templates/sectioned/sectioned-layout.test.tsx b/src/components/templates/sectioned/sectioned-layout.test.tsx new file mode 100644 index 0000000..334d1cc --- /dev/null +++ b/src/components/templates/sectioned/sectioned-layout.test.tsx @@ -0,0 +1,34 @@ +import { render, screen } from '@test-utils'; +import SectionedLayout from './sectioned-layout'; + +const sections = [ + { + title: 'Section 1', + content: + 'Qui suscipit ea et aut dicta. Quia ut dignissimos. Sapiente beatae voluptatem quis et. Nemo vitae magni. Nihil iste officia est sed esse molestiae doloribus. Quia temporibus nobis ea fuga quis incidunt doloribus eaque.', + }, + { + title: 'Section 2', + content: + 'Reprehenderit aut magnam ut quos. Voluptatibus beatae et. Earum non atque voluptatum illum rem distinctio repellat.', + }, + { + title: 'Section 3', + content: + 'Placeat rem dolores dolore illum earum officia dolore. Ut est ducimus. Officia eveniet pariatur ut laboriosam voluptatibus aut doloremque natus quis.', + }, + { + title: 'Section 4', + content: + 'Vitae facere ipsa eum sunt debitis veritatis dolorem labore qui. Dolores recusandae omnis aut. Repudiandae quia neque porro in blanditiis. A atque minima fugit. Totam quidem voluptas natus velit at.', + }, +]; + +describe('SectionedLayout', () => { + it('renders the correct number of section', () => { + render(); + expect(screen.getAllByRole('heading', { name: /^Section/ })).toHaveLength( + sections.length + ); + }); +}); -- cgit v1.2.3 From 2155550fa36a3bc3c8f66e0926530123b4018cd4 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Mon, 16 May 2022 12:46:38 +0200 Subject: refactor: use custom hook for breadcrumb items and schema --- src/components/templates/layout/layout.stories.tsx | 54 ++++++++--- src/components/templates/layout/layout.test.tsx | 12 ++- src/components/templates/layout/layout.tsx | 26 ++++- .../templates/page/page-layout.stories.tsx | 12 +++ src/components/templates/page/page-layout.test.tsx | 41 ++++++-- src/components/templates/page/page-layout.tsx | 11 ++- .../sectioned/sectioned-layout.stories.tsx | 24 +++-- .../templates/sectioned/sectioned-layout.test.tsx | 9 +- .../templates/sectioned/sectioned-layout.tsx | 8 +- src/pages/404.tsx | 16 ++-- src/pages/article/[slug].tsx | 24 ++--- src/pages/blog/index.tsx | 16 ++-- src/pages/contact.tsx | 22 ++--- src/pages/cv.tsx | 22 ++--- src/pages/index.tsx | 9 +- src/pages/mentions-legales.tsx | 22 ++--- src/pages/projets/[slug].tsx | 27 ++---- src/pages/projets/index.tsx | 22 ++--- src/pages/recherche/index.tsx | 22 ++--- src/pages/sujet/[slug].tsx | 22 ++--- src/pages/thematique/[slug].tsx | 22 ++--- src/utils/hooks/use-breadcrumb.tsx | 106 +++++++++++++++++++++ 22 files changed, 343 insertions(+), 206 deletions(-) create mode 100644 src/utils/hooks/use-breadcrumb.tsx (limited to 'src/components/templates/sectioned/sectioned-layout.test.tsx') diff --git a/src/components/templates/layout/layout.stories.tsx b/src/components/templates/layout/layout.stories.tsx index 2415412..105e808 100644 --- a/src/components/templates/layout/layout.stories.tsx +++ b/src/components/templates/layout/layout.stories.tsx @@ -1,5 +1,4 @@ import { ComponentMeta, ComponentStory } from '@storybook/react'; -import { IntlProvider } from 'react-intl'; import LayoutComponent from './layout'; /** @@ -8,6 +7,10 @@ import LayoutComponent from './layout'; export default { title: 'Templates/LayoutBase', component: LayoutComponent, + args: { + breadcrumbSchema: [], + isHome: false, + }, argTypes: { children: { control: { @@ -19,6 +22,31 @@ export default { required: true, }, }, + breadcrumbSchema: { + control: { + type: 'null', + }, + description: 'The JSON schema for breadcrumb items.', + type: { + name: 'object', + required: true, + value: {}, + }, + }, + isHome: { + control: { + type: 'boolean', + }, + description: 'Determine if it is the homepage.', + table: { + category: 'Options', + defaultValue: { summary: false }, + }, + type: { + name: 'boolean', + required: false, + }, + }, className: { control: { type: 'text', @@ -35,19 +63,17 @@ export default { }, decorators: [ (Story) => ( - -
- -
-
+
+ +
), ], parameters: { diff --git a/src/components/templates/layout/layout.test.tsx b/src/components/templates/layout/layout.test.tsx index 914e1cd..94145ec 100644 --- a/src/components/templates/layout/layout.test.tsx +++ b/src/components/templates/layout/layout.test.tsx @@ -1,34 +1,36 @@ import { render, screen } from '@test-utils'; +import { BreadcrumbList } from 'schema-dts'; import Layout from './layout'; const body = 'Sit dolorem eveniet. Sit sit odio nemo vitae corrupti modi sint est rerum. Pariatur quidem maiores distinctio. Quia et illum aspernatur est cum.'; +const breadcrumbSchema: BreadcrumbList['itemListElement'][] = []; describe('Layout', () => { it('renders the website header', () => { - render({body}); + render({body}); expect(screen.getByRole('banner')).toBeInTheDocument(); }); it('renders the website main content', () => { - render({body}); + render({body}); expect(screen.getByRole('main')).toBeInTheDocument(); }); it('renders the website footer', () => { - render({body}); + render({body}); expect(screen.getByRole('contentinfo')).toBeInTheDocument(); }); it('renders a skip to content link', () => { - render({body}); + render({body}); expect( screen.getByRole('link', { name: 'Skip to content' }) ).toBeInTheDocument(); }); it('renders an article', () => { - render({body}); + render({body}); expect(screen.getByRole('article')).toHaveTextContent(body); }); }); diff --git a/src/components/templates/layout/layout.tsx b/src/components/templates/layout/layout.tsx index bfb918b..9e9282b 100644 --- a/src/components/templates/layout/layout.tsx +++ b/src/components/templates/layout/layout.tsx @@ -13,7 +13,13 @@ import useSettings from '@utils/hooks/use-settings'; import Script from 'next/script'; import { FC, ReactNode } from 'react'; import { useIntl } from 'react-intl'; -import { Person, SearchAction, WebSite, WithContext } from 'schema-dts'; +import { + BreadcrumbList, + Person, + SearchAction, + WebSite, + WithContext, +} from 'schema-dts'; import styles from './layout.module.scss'; export type QueryAction = SearchAction & { @@ -21,6 +27,10 @@ export type QueryAction = SearchAction & { }; export type LayoutProps = Pick & { + /** + * The breadcrumb JSON schema. + */ + breadcrumbSchema: BreadcrumbList['itemListElement'][]; /** * The layout main content. */ @@ -36,7 +46,12 @@ export type LayoutProps = Pick & { * * Render the base layout used by all pages. */ -const Layout: FC = ({ children, isHome, ...props }) => { +const Layout: FC = ({ + breadcrumbSchema, + children, + isHome, + ...props +}) => { const intl = useIntl(); const { website } = useSettings(); const { baseline, copyright, locales, name, picture, url } = website; @@ -153,12 +168,17 @@ const Layout: FC = ({ children, isHome, ...props }) => { id="schema-layout" type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }} - > + />