diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-10-09 14:33:29 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-11 18:14:41 +0100 |
| commit | f11a906420975e833f278a08470d8f9783c76f73 (patch) | |
| tree | cd98eb0c73e07d08fbbe3006a2f7d5a34b0464b3 /src/components/molecules | |
| parent | d75b9a1e150ab211c1052fb49bede9bd16320aca (diff) | |
refactor(components): extract FlippingLogo from Branding component
Diffstat (limited to 'src/components/molecules')
8 files changed, 143 insertions, 33 deletions
diff --git a/src/components/molecules/images/flipping-logo/flipping-logo.module.scss b/src/components/molecules/images/flipping-logo/flipping-logo.module.scss new file mode 100644 index 0000000..d93b6e9 --- /dev/null +++ b/src/components/molecules/images/flipping-logo/flipping-logo.module.scss @@ -0,0 +1,24 @@ +@use "../../../../styles/abstracts/functions" as fun; + +.wrapper { + border-radius: 50%; + width: fit-content; +} + +.side { + width: var(--logo-size, fun.convert-px(100)); + height: var(--logo-size, fun.convert-px(100)); + 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); + background: var(--color-bg); + border-radius: 50%; + } +} diff --git a/src/components/molecules/images/flipping-logo/flipping-logo.stories.tsx b/src/components/molecules/images/flipping-logo/flipping-logo.stories.tsx new file mode 100644 index 0000000..43ef150 --- /dev/null +++ b/src/components/molecules/images/flipping-logo/flipping-logo.stories.tsx @@ -0,0 +1,34 @@ +import type { ComponentMeta, ComponentStory } from '@storybook/react'; +import NextImage from 'next/image'; +import { Logo } from '../../../atoms'; +import { FlippingLogo as FlippingLogoComponent } from './flipping-logo'; + +/** + * FlippingLogo - Storybook Meta + */ +export default { + title: 'Molecules/Images/Flipping Logo', + component: FlippingLogoComponent, + args: {}, + argTypes: {}, +} as ComponentMeta<typeof FlippingLogoComponent>; + +const Template: ComponentStory<typeof FlippingLogoComponent> = (args) => ( + <FlippingLogoComponent {...args} /> +); + +/** + * FlippingLogo Story + */ +export const FlippingLogo = Template.bind({}); +FlippingLogo.args = { + back: <Logo heading="A logo example" />, + front: ( + <NextImage + alt="A photo example" + height={200} + src="https://picsum.photos/200" + width={200} + /> + ), +}; diff --git a/src/components/molecules/images/flipping-logo/flipping-logo.test.tsx b/src/components/molecules/images/flipping-logo/flipping-logo.test.tsx new file mode 100644 index 0000000..5409262 --- /dev/null +++ b/src/components/molecules/images/flipping-logo/flipping-logo.test.tsx @@ -0,0 +1,39 @@ +import { describe, expect, it } from '@jest/globals'; +import { render, screen as rtlScreen } from '@testing-library/react'; +import NextImage from 'next/image'; +import { FlippingLogo } from './flipping-logo'; + +describe('FlippingLogo', () => { + it('renders both sides of the logo', () => { + const frontAltTxt = 'aliquam officia et'; + const backAltTxt = 'voluptas nesciunt itaque'; + + render( + <FlippingLogo + back={ + <NextImage + alt={backAltTxt} + height={100} + src="https://picsum.photos/100" + width={100} + /> + } + front={ + <NextImage + alt={frontAltTxt} + height={100} + src="https://picsum.photos/100" + width={100} + /> + } + /> + ); + + expect( + rtlScreen.getByRole('img', { name: frontAltTxt }) + ).toBeInTheDocument(); + expect( + rtlScreen.getByRole('img', { name: backAltTxt }) + ).toBeInTheDocument(); + }); +}); diff --git a/src/components/molecules/images/flipping-logo/flipping-logo.tsx b/src/components/molecules/images/flipping-logo/flipping-logo.tsx new file mode 100644 index 0000000..e22feae --- /dev/null +++ b/src/components/molecules/images/flipping-logo/flipping-logo.tsx @@ -0,0 +1,41 @@ +import { + forwardRef, + type ReactNode, + type ForwardRefRenderFunction, +} from 'react'; +import { Flip, type FlipProps, FlipSide } from '../../../atoms'; +import styles from './flipping-logo.module.scss'; + +type FlippingLogoProps = Omit<FlipProps, 'children'> & { + /** + * The back face. + */ + back: ReactNode; + /** + * The front face. + */ + front: ReactNode; +}; + +const FlippingLogoWithRef: ForwardRefRenderFunction< + HTMLDivElement, + FlippingLogoProps +> = ({ back, className = '', front, ...props }, ref) => { + const wrapperClass = `${styles.wrapper} ${className}`; + + return ( + <Flip {...props} className={wrapperClass} ref={ref}> + <FlipSide className={styles.side}>{front}</FlipSide> + <FlipSide className={styles.side} isBack> + {back} + </FlipSide> + </Flip> + ); +}; + +/** + * FlippingLogo component + * + * Renders a website logo with two faces. + */ +export const FlippingLogo = forwardRef(FlippingLogoWithRef); diff --git a/src/components/molecules/images/flipping-logo/index.ts b/src/components/molecules/images/flipping-logo/index.ts new file mode 100644 index 0000000..318a6af --- /dev/null +++ b/src/components/molecules/images/flipping-logo/index.ts @@ -0,0 +1 @@ +export * from './flipping-logo'; diff --git a/src/components/molecules/images/index.ts b/src/components/molecules/images/index.ts index a00c6c2..33ec886 100644 --- a/src/components/molecules/images/index.ts +++ b/src/components/molecules/images/index.ts @@ -1 +1,2 @@ +export * from './flipping-logo'; export * from './responsive-image'; diff --git a/src/components/molecules/layout/branding.module.scss b/src/components/molecules/layout/branding.module.scss index bacf381..6f67c8b 100644 --- a/src/components/molecules/layout/branding.module.scss +++ b/src/components/molecules/layout/branding.module.scss @@ -54,15 +54,7 @@ .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") { - margin-bottom: 0; - } - } } .title { @@ -106,23 +98,6 @@ } } -.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% { diff --git a/src/components/molecules/layout/branding.tsx b/src/components/molecules/layout/branding.tsx index c3d3b7c..9f8e6ce 100644 --- a/src/components/molecules/layout/branding.tsx +++ b/src/components/molecules/layout/branding.tsx @@ -1,6 +1,7 @@ import { type FC, useRef, type ReactNode } from 'react'; import { useStyles } from '../../../utils/hooks'; -import { Flip, FlipSide, Heading, Link } from '../../atoms'; +import { Heading, Link } from '../../atoms'; +import { FlippingLogo } from '../images'; import styles from './branding.module.scss'; export type BrandingProps = { @@ -42,7 +43,6 @@ export const Branding: FC<BrandingProps> = ({ photo, title, withLink = false, - ...props }) => { const baselineRef = useRef<HTMLParagraphElement>(null); const titleRef = useRef<HTMLHeadingElement | HTMLParagraphElement>(null); @@ -61,12 +61,7 @@ export const Branding: FC<BrandingProps> = ({ return ( <div className={styles.wrapper}> - <Flip {...props} className={styles.logo}> - <FlipSide className={styles.flip}>{photo}</FlipSide> - <FlipSide className={styles.flip} isBack> - {logo} - </FlipSide> - </Flip> + <FlippingLogo back={logo} className={styles.logo} front={photo} /> <Heading className={styles.title} isFake={!isHome} |
