aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/molecules/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/molecules/layout')
-rw-r--r--src/components/molecules/layout/branding.module.scss32
-rw-r--r--src/components/molecules/layout/branding.stories.tsx26
-rw-r--r--src/components/molecules/layout/branding.test.tsx75
-rw-r--r--src/components/molecules/layout/branding.tsx54
4 files changed, 132 insertions, 55 deletions
diff --git a/src/components/molecules/layout/branding.module.scss b/src/components/molecules/layout/branding.module.scss
index 4d9e32c..bacf381 100644
--- a/src/components/molecules/layout/branding.module.scss
+++ b/src/components/molecules/layout/branding.module.scss
@@ -42,7 +42,7 @@
@include mix.media("screen") {
@include mix.dimensions("2xs") {
grid-template-columns:
- var(--logo-size, fun.convert-px(100))
+ var(--logo-size)
minmax(0, 1fr);
grid-template-rows: 1fr min-content;
align-items: center;
@@ -55,6 +55,8 @@
.logo {
grid-row: span 2;
margin-bottom: var(--spacing-sm);
+ border-radius: 50%;
+ animation: flip-logo 9s ease-in 0s 1;
@include mix.media("screen") {
@include mix.dimensions("2xs") {
@@ -103,3 +105,31 @@
}
}
}
+
+.flip {
+ width: var(--logo-size);
+ height: var(--logo-size);
+ border: fun.convert-px(2) solid var(--color-primary-dark);
+ border-radius: 50%;
+ box-shadow:
+ fun.convert-px(1) fun.convert-px(2) fun.convert-px(1) 0
+ var(--color-shadow-light),
+ fun.convert-px(2) fun.convert-px(3) fun.convert-px(3) 0
+ var(--color-shadow-light);
+
+ > * {
+ padding: fun.convert-px(2);
+ border-radius: 50%;
+ }
+}
+
+@keyframes flip-logo {
+ 0%,
+ 90% {
+ transform: rotateY(180deg);
+ }
+
+ 100% {
+ transform: rotateY(0deg);
+ }
+}
diff --git a/src/components/molecules/layout/branding.stories.tsx b/src/components/molecules/layout/branding.stories.tsx
index 04844e2..7ff88c9 100644
--- a/src/components/molecules/layout/branding.stories.tsx
+++ b/src/components/molecules/layout/branding.stories.tsx
@@ -1,4 +1,6 @@
-import { ComponentMeta, ComponentStory } from '@storybook/react';
+import type { ComponentMeta, ComponentStory } from '@storybook/react';
+import NextImage from 'next/image';
+import { Logo } from '../../atoms';
import { Branding } from './branding';
/**
@@ -82,8 +84,16 @@ const Template: ComponentStory<typeof Branding> = (args) => (
*/
export const Default = Template.bind({});
Default.args = {
+ logo: <Logo heading="A logo example" />,
+ photo: (
+ <NextImage
+ alt="A photo example"
+ height={200}
+ src="https://picsum.photos/200"
+ width={200}
+ />
+ ),
title: 'Website title',
- photo: 'http://placeimg.com/640/480',
};
/**
@@ -91,7 +101,15 @@ Default.args = {
*/
export const WithBaseline = Template.bind({});
WithBaseline.args = {
- title: 'Website title',
baseline: 'Maiores corporis qui',
- photo: 'http://placeimg.com/640/480',
+ logo: <Logo heading="A logo example" />,
+ photo: (
+ <NextImage
+ alt="A photo example"
+ height={200}
+ src="https://picsum.photos/200"
+ width={200}
+ />
+ ),
+ title: 'Website title',
};
diff --git a/src/components/molecules/layout/branding.test.tsx b/src/components/molecules/layout/branding.test.tsx
index 4b76446..cfb55c5 100644
--- a/src/components/molecules/layout/branding.test.tsx
+++ b/src/components/molecules/layout/branding.test.tsx
@@ -1,62 +1,109 @@
import { describe, expect, it } from '@jest/globals';
-import { render, screen } from '../../../../tests/utils';
+import NextImage from 'next/image';
+import { render, screen as rtlScreen } from '../../../../tests/utils';
+import { Logo } from '../../atoms';
import { Branding } from './branding';
describe('Branding', () => {
it('renders a photo', () => {
+ const altText = 'A photo example';
+
render(
<Branding
- photo="http://placeimg.com/640/480/city"
+ logo={<Logo />}
+ photo={
+ <NextImage
+ alt="A photo example"
+ height={200}
+ src="https://picsum.photos/200"
+ width={200}
+ />
+ }
title="Website title"
/>
);
- expect(
- screen.getByRole('img', { name: 'Website title picture' })
- ).toBeInTheDocument();
+ expect(rtlScreen.getByRole('img', { name: altText })).toBeInTheDocument();
});
it('renders a logo', () => {
+ const logoHeading = 'sed enim voluptatem';
+
render(
- <Branding photo="http://placeimg.com/640/480/city" title="Website name" />
+ <Branding
+ logo={<Logo heading={logoHeading} />}
+ photo={
+ <NextImage
+ alt="A photo example"
+ height={200}
+ src="https://picsum.photos/200"
+ width={200}
+ />
+ }
+ title="Website name"
+ />
);
- expect(screen.getByTitle('Website name logo')).toBeInTheDocument();
+ expect(rtlScreen.getByTitle(logoHeading)).toBeInTheDocument();
});
it('renders a baseline', () => {
render(
<Branding
- photo="http://placeimg.com/640/480"
+ logo={<Logo />}
+ photo={
+ <NextImage
+ alt="A photo example"
+ height={200}
+ src="https://picsum.photos/200"
+ width={200}
+ />
+ }
title="Website title"
baseline="Website baseline"
/>
);
- expect(screen.getByText('Website baseline')).toBeInTheDocument();
+ expect(rtlScreen.getByText('Website baseline')).toBeInTheDocument();
});
it('renders a title wrapped with h1 element', () => {
render(
<Branding
- photo="http://placeimg.com/640/480"
+ logo={<Logo />}
+ photo={
+ <NextImage
+ alt="A photo example"
+ height={200}
+ src="https://picsum.photos/200"
+ width={200}
+ />
+ }
title="Website title"
isHome={true}
/>
);
expect(
- screen.getByRole('heading', { level: 1, name: 'Website title' })
+ rtlScreen.getByRole('heading', { level: 1, name: 'Website title' })
).toBeInTheDocument();
});
it('renders a title with h1 styles', () => {
render(
<Branding
- photo="http://placeimg.com/640/480"
+ logo={<Logo />}
+ photo={
+ <NextImage
+ alt="A photo example"
+ height={200}
+ src="https://picsum.photos/200"
+ width={200}
+ />
+ }
title="Website title"
isHome={false}
/>
);
expect(
- screen.queryByRole('heading', { level: 1, name: 'Website title' })
+ rtlScreen.queryByRole('heading', { level: 1, name: 'Website title' })
).not.toBeInTheDocument();
- expect(screen.getByText('Website title')).toHaveClass('heading--1');
+ expect(rtlScreen.getByText('Website title')).toHaveClass('heading--1');
});
});
diff --git a/src/components/molecules/layout/branding.tsx b/src/components/molecules/layout/branding.tsx
index dceee5e..c3d3b7c 100644
--- a/src/components/molecules/layout/branding.tsx
+++ b/src/components/molecules/layout/branding.tsx
@@ -1,11 +1,9 @@
-import { type FC, useRef } from 'react';
-import { useIntl } from 'react-intl';
+import { type FC, useRef, type ReactNode } from 'react';
import { useStyles } from '../../../utils/hooks';
-import { Heading, Link } from '../../atoms';
-import { FlippingLogo, type FlippingLogoProps } from '../images';
+import { Flip, FlipSide, Heading, Link } from '../../atoms';
import styles from './branding.module.scss';
-export type BrandingProps = Pick<FlippingLogoProps, 'photo'> & {
+export type BrandingProps = {
/**
* The Branding baseline.
*/
@@ -15,6 +13,14 @@ export type BrandingProps = Pick<FlippingLogoProps, 'photo'> & {
*/
isHome?: boolean;
/**
+ * The website logo.
+ */
+ logo: ReactNode;
+ /**
+ * Your photo.
+ */
+ photo: ReactNode;
+ /**
* The Branding title;
*/
title: string;
@@ -32,31 +38,14 @@ export type BrandingProps = Pick<FlippingLogoProps, 'photo'> & {
export const Branding: FC<BrandingProps> = ({
baseline,
isHome = false,
+ logo,
photo,
title,
withLink = false,
...props
}) => {
const baselineRef = useRef<HTMLParagraphElement>(null);
- const logoRef = useRef<HTMLDivElement>(null);
const titleRef = useRef<HTMLHeadingElement | HTMLParagraphElement>(null);
- const intl = useIntl();
- const altText = intl.formatMessage(
- {
- defaultMessage: '{website} picture',
- description: 'Branding: photo alternative text',
- id: 'dDK5oc',
- },
- { website: title }
- );
- const logoTitle = intl.formatMessage(
- {
- defaultMessage: '{website} logo',
- description: 'Branding: logo title',
- id: 'x55qsD',
- },
- { website: title }
- );
useStyles({
property: '--typing-animation',
@@ -69,22 +58,15 @@ export const Branding: FC<BrandingProps> = ({
'hide-text 4.25s linear 0s 1, blink 0.8s ease-in-out 4.25s 2, typing 3.8s linear 4.25s 1',
target: baselineRef,
});
- useStyles({
- property: 'animation',
- styles: 'flip-logo 9s ease-in 0s 1',
- target: logoRef,
- });
return (
<div className={styles.wrapper}>
- <FlippingLogo
- {...props}
- altText={altText}
- className={styles.logo}
- logoTitle={logoTitle}
- photo={photo}
- ref={logoRef}
- />
+ <Flip {...props} className={styles.logo}>
+ <FlipSide className={styles.flip}>{photo}</FlipSide>
+ <FlipSide className={styles.flip} isBack>
+ {logo}
+ </FlipSide>
+ </Flip>
<Heading
className={styles.title}
isFake={!isHome}