diff options
Diffstat (limited to 'src/components/molecules/layout')
4 files changed, 185 insertions, 0 deletions
| diff --git a/src/components/molecules/layout/flipping-logo.module.scss b/src/components/molecules/layout/flipping-logo.module.scss new file mode 100644 index 0000000..89b9499 --- /dev/null +++ b/src/components/molecules/layout/flipping-logo.module.scss @@ -0,0 +1,59 @@ +@use "@styles/abstracts/functions" as fun; + +.logo { +  width: var(--logo-size, fun.convert-px(100)); +  height: var(--logo-size, fun.convert-px(100)); +  position: relative; +  border-radius: 50%; +  transform-style: preserve-3d; +  transition: all 0.6s linear 0s; + +  &__front, +  &__back { +    width: 100%; +    height: 100%; +    position: absolute; +    top: 0; +    left: 0; +    backface-visibility: hidden; +    background: var(--color-bg); +    border: fun.convert-px(2) solid var(--color-primary-dark); +    border-radius: 50%; +    transition: all 0.6s linear 0s; + +    svg, +    img { +      // !important is required to override next/image styles... +      padding: fun.convert-px(2) !important; +      border-radius: 50%; +    } +  } + +  &__front { +    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); +  } + +  &__back { +    transform: rotateY(180deg); +  } + +  &:hover { +    transform: rotateY(180deg); +  } + +  &:hover & { +    &__front { +      box-shadow: none; +    } + +    &__back { +      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); +    } +  } +} diff --git a/src/components/molecules/layout/flipping-logo.stories.tsx b/src/components/molecules/layout/flipping-logo.stories.tsx new file mode 100644 index 0000000..1508269 --- /dev/null +++ b/src/components/molecules/layout/flipping-logo.stories.tsx @@ -0,0 +1,53 @@ +import { ComponentMeta, ComponentStory } from '@storybook/react'; +import FlippingLogoComponent from './flipping-logo'; + +export default { +  title: 'Molecules/Layout', +  component: FlippingLogoComponent, +  argTypes: { +    additionalClasses: { +      control: { +        type: 'text', +      }, +      description: 'Adds additional classes to the logo wrapper.', +      table: { +        category: 'Options', +      }, +      type: { +        name: 'string', +        required: false, +      }, +    }, +    altText: { +      control: { +        type: 'text', +      }, +      description: 'Photo alternative text.', +      type: { +        name: 'string', +        required: true, +      }, +    }, +    photo: { +      control: { +        type: 'text', +      }, +      description: 'Photo url.', +      type: { +        name: 'string', +        required: true, +      }, +    }, +  }, +} as ComponentMeta<typeof FlippingLogoComponent>; + +const Template: ComponentStory<typeof FlippingLogoComponent> = (args) => ( +  <FlippingLogoComponent {...args} /> +); + +export const FlippingLogo = Template.bind({}); +FlippingLogo.args = { +  altText: 'Website picture', +  logoTitle: 'Website logo', +  photo: 'http://placeimg.com/640/480', +}; diff --git a/src/components/molecules/layout/flipping-logo.test.tsx b/src/components/molecules/layout/flipping-logo.test.tsx new file mode 100644 index 0000000..806fdbe --- /dev/null +++ b/src/components/molecules/layout/flipping-logo.test.tsx @@ -0,0 +1,25 @@ +import { render, screen } from '@test-utils'; +import FlippingLogo from './flipping-logo'; + +describe('FlippingLogo', () => { +  it('renders a photo', () => { +    render( +      <FlippingLogo +        altText="Alternative text" +        photo="http://placeimg.com/640/480" +      /> +    ); +    expect(screen.getByAltText('Alternative text')).toBeInTheDocument(); +  }); + +  it('renders a logo', () => { +    render( +      <FlippingLogo +        altText="Alternative text" +        logoTitle="A logo title" +        photo="http://placeimg.com/640/480" +      /> +    ); +    expect(screen.getByTitle('A logo title')).toBeInTheDocument(); +  }); +}); diff --git a/src/components/molecules/layout/flipping-logo.tsx b/src/components/molecules/layout/flipping-logo.tsx new file mode 100644 index 0000000..7bb7afc --- /dev/null +++ b/src/components/molecules/layout/flipping-logo.tsx @@ -0,0 +1,48 @@ +import Logo from '@components/atoms/images/logo'; +import Image from 'next/image'; +import { FC } from 'react'; +import styles from './flipping-logo.module.scss'; + +type FlippingLogoProps = { +  /** +   * Adds additional classes to the logo wrapper. +   */ +  additionalClasses?: string; +  /** +   * Photo alternative text. +   */ +  altText: string; +  /** +   * Logo image title. +   */ +  logoTitle?: string; +  /** +   * Photo url. +   */ +  photo: string; +}; + +/** + * FlippingLogo component + * + * Render a logo and a photo with a flipping effect. + */ +const FlippingLogo: FC<FlippingLogoProps> = ({ +  additionalClasses, +  altText, +  logoTitle, +  photo, +}) => { +  return ( +    <div className={`${styles.logo} ${additionalClasses}`}> +      <div className={styles.logo__front}> +        <Image src={photo} alt={altText} layout="fill" objectFit="cover" /> +      </div> +      <div className={styles.logo__back}> +        <Logo title={logoTitle} /> +      </div> +    </div> +  ); +}; + +export default FlippingLogo; | 
