From 34502bd004c2522a8f2a217da3adf51586d1dec3 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Thu, 21 Apr 2022 17:03:45 +0200 Subject: chore: add a PageHeader component --- .../molecules/layout/page-header.module.scss | 63 +++++++++++++ .../molecules/layout/page-header.stories.tsx | 103 +++++++++++++++++++++ .../molecules/layout/page-header.test.tsx | 18 ++++ src/components/molecules/layout/page-header.tsx | 49 ++++++++++ 4 files changed, 233 insertions(+) create mode 100644 src/components/molecules/layout/page-header.module.scss create mode 100644 src/components/molecules/layout/page-header.stories.tsx create mode 100644 src/components/molecules/layout/page-header.test.tsx create mode 100644 src/components/molecules/layout/page-header.tsx (limited to 'src') diff --git a/src/components/molecules/layout/page-header.module.scss b/src/components/molecules/layout/page-header.module.scss new file mode 100644 index 0000000..93f7595 --- /dev/null +++ b/src/components/molecules/layout/page-header.module.scss @@ -0,0 +1,63 @@ +@use "@styles/abstracts/functions" as fun; +@use "@styles/abstracts/mixins" as mix; +@use "@styles/abstracts/placeholders"; + +.wrapper { + @extend %grid; + + &::before, + &::after { + content: ""; + width: 100%; + height: 100%; + background: var(--color-bg-secondary); + border-top: fun.convert-px(3) solid var(--color-border-light); + border-bottom: fun.convert-px(3) solid var(--color-border-light); + } + + &::before { + grid-column: 1; + justify-self: start; + border-right: fun.convert-px(3) solid var(--color-border-light); + } + + &::after { + grid-column: 3; + justify-self: end; + border-left: fun.convert-px(3) solid var(--color-border-light); + } +} + +.body { + grid-column: 2; + display: flex; + flex-flow: column wrap; + row-gap: var(--spacing-sm); +} + +.title { + display: flex; + flex-flow: row wrap; + align-items: center; + position: relative; + + &::before, + &::after { + content: ""; + width: 100%; + height: fun.convert-px(4); + background: radial-gradient( + ellipse at center, + var(--color-primary-light), + var(--color-primary-dark) + ); + } +} + +.meta { + @include mix.media("screen") { + @include mix.dimensions("xs") { + font-size: var(--font-size-sm); + } + } +} diff --git a/src/components/molecules/layout/page-header.stories.tsx b/src/components/molecules/layout/page-header.stories.tsx new file mode 100644 index 0000000..6054845 --- /dev/null +++ b/src/components/molecules/layout/page-header.stories.tsx @@ -0,0 +1,103 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import PageHeader from './page-header'; + +/** + * Page Header - Storybook Meta + */ +export default { + title: 'Molecules/Layout/PageHeader', + component: PageHeader, + argTypes: { + intro: { + control: { + type: 'text', + }, + description: 'The page introduction.', + table: { + category: 'Options', + }, + type: { + name: 'string', + required: false, + }, + }, + meta: { + description: 'The page metadata.', + table: { + category: 'Options', + }, + type: { + name: 'object', + required: false, + value: {}, + }, + }, + title: { + control: { + type: 'text', + }, + description: 'The page title.', + type: { + name: 'string', + required: true, + }, + }, + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ( + +); + +const meta = { + publication: { name: 'Published on:', value: 'April 9th 2022' }, + categories: { + name: 'Categories:', + value: [ + + Category 1 + , + + Category 2 + , + ], + }, +}; + +/** + * Page Header Stories - Default + */ +export const Default = Template.bind({}); +Default.args = { + title: 'Excepturi nesciunt illum', +}; + +/** + * Page Header Stories - With introduction + */ +export const WithIntro = Template.bind({}); +WithIntro.args = { + intro: + 'Minima dolor nihil. Velit atque odit totam enim. Quisquam reprehenderit ut et inventore et nihil libero exercitationem. Cumque similique magni placeat et. Et sed est cumque labore. Et quia similique.', + title: 'Excepturi nesciunt illum', +}; + +/** + * Page Header Stories - With meta + */ +export const WithMeta = Template.bind({}); +WithMeta.args = { + meta, + title: 'Excepturi nesciunt illum', +}; + +/** + * Page Header Stories - With introduction and meta + */ +export const WithIntroAndMeta = Template.bind({}); +WithIntroAndMeta.args = { + intro: + 'Minima dolor nihil. Velit atque odit totam enim. Quisquam reprehenderit ut et inventore et nihil libero exercitationem. Cumque similique magni placeat et. Et sed est cumque labore. Et quia similique.', + meta, + title: 'Excepturi nesciunt illum', +}; diff --git a/src/components/molecules/layout/page-header.test.tsx b/src/components/molecules/layout/page-header.test.tsx new file mode 100644 index 0000000..329b54c --- /dev/null +++ b/src/components/molecules/layout/page-header.test.tsx @@ -0,0 +1,18 @@ +import { render, screen } from '@test-utils'; +import PageHeader from './page-header'; + +const title = 'Non nemo amet'; +const intro = + 'Suscipit omnis minima doloribus commodi. Laudantium similique ut enim voluptatem soluta maxime autem et.'; + +describe('PageHeader', () => { + it('renders a title', () => { + render(); + expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(title); + }); + + it('renders an introduction', () => { + render(); + expect(screen.getByText(intro)).toBeInTheDocument(); + }); +}); diff --git a/src/components/molecules/layout/page-header.tsx b/src/components/molecules/layout/page-header.tsx new file mode 100644 index 0000000..174e246 --- /dev/null +++ b/src/components/molecules/layout/page-header.tsx @@ -0,0 +1,49 @@ +import Heading from '@components/atoms/headings/heading'; +import styles from './page-header.module.scss'; +import Meta, { type MetaMap } from './meta'; +import { FC } from 'react'; + +export type PageHeaderProps = { + /** + * Set additional classnames to the header element. + */ + className?: string; + /** + * The page introduction. + */ + intro?: string; + /** + * The page metadata. + */ + meta?: MetaMap; + /** + * The page title. + */ + title: string; +}; + +/** + * PageHeader component + * + * Render a header element with page title, meta and intro. + */ +const PageHeader: FC = ({ + className = '', + intro, + meta, + title, +}) => { + return ( +
+
+ + {title} + + {meta && } + {intro &&
{intro}
} +
+
+ ); +}; + +export default PageHeader; -- cgit v1.2.3