From 767c0cdc5eaf6bd56020d64fd7718b1379c09390 Mon Sep 17 00:00:00 2001 From: Fanny Chien Date: Fri, 3 Jun 2022 14:27:57 -0300 Subject: [PATCH] feat(UI): Add Hero component (#1336) * Adds base code for Hero component * Adds Hero components * Adds base styles to example * Updates styles * Renames `HeroContent` to `HeroHeading` * Updates styles * Adds missing flie * Fixes typo * Removes `HeroLink` component * Update packages/ui/src/organisms/Hero/Hero.test.tsx Co-authored-by: Eduardo Formiga * Update packages/ui/src/organisms/Hero/HeroHeading.tsx Co-authored-by: Filipe W. Lima * Removing children prop Co-authored-by: Eduardo Formiga Co-authored-by: Filipe W. Lima --- packages/styles/src/organisms/hero.css | 51 ++++++++++++++++ packages/styles/src/organisms/index.css | 1 + packages/ui/src/index.ts | 7 +++ packages/ui/src/organisms/Hero/Hero.test.tsx | 60 +++++++++++++++++++ packages/ui/src/organisms/Hero/Hero.tsx | 23 +++++++ .../ui/src/organisms/Hero/HeroHeading.tsx | 24 ++++++++ packages/ui/src/organisms/Hero/HeroImage.tsx | 22 +++++++ packages/ui/src/organisms/Hero/index.tsx | 8 +++ .../ui/src/organisms/Hero/stories/Hero.mdx | 48 +++++++++++++++ .../organisms/Hero/stories/Hero.stories.tsx | 56 +++++++++++++++++ 10 files changed, 300 insertions(+) create mode 100644 packages/styles/src/organisms/hero.css create mode 100644 packages/ui/src/organisms/Hero/Hero.test.tsx create mode 100644 packages/ui/src/organisms/Hero/Hero.tsx create mode 100644 packages/ui/src/organisms/Hero/HeroHeading.tsx create mode 100644 packages/ui/src/organisms/Hero/HeroImage.tsx create mode 100644 packages/ui/src/organisms/Hero/index.tsx create mode 100644 packages/ui/src/organisms/Hero/stories/Hero.mdx create mode 100644 packages/ui/src/organisms/Hero/stories/Hero.stories.tsx diff --git a/packages/styles/src/organisms/hero.css b/packages/styles/src/organisms/hero.css new file mode 100644 index 0000000000..8718304329 --- /dev/null +++ b/packages/styles/src/organisms/hero.css @@ -0,0 +1,51 @@ +[data-store-hero] { + display: flex; + flex-direction: column; + width: 100%; + min-height: 20rem; + background-color: #001947; + color: #fff; +} + +[data-hero-heading] { + display: flex; + flex-direction: column; + justify-content: center; + padding: 2rem; +} + +[data-hero-heading] h1 { + font-size: 1.81rem; + font-weight: bold; + margin-bottom: 1.5rem; +} + +[data-hero-heading] a { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem; + margin-top: 2rem; + min-width: 11.25rem; + width: fit-content; + color: #001947; + border: 1px solid #171a1c; + background-color: #fff; +} + +[data-hero-image] { + height: 100%; + overflow: hidden; +} + +@media only screen and (min-width: 769px) { + [data-store-hero] { + flex-direction: row-reverse; + } + [data-hero-heading] { + padding: 0 4rem; + } + [data-hero-heading] h1 { + font-size: 3rem; + } +} diff --git a/packages/styles/src/organisms/index.css b/packages/styles/src/organisms/index.css index 013d69524b..e9b832a08e 100644 --- a/packages/styles/src/organisms/index.css +++ b/packages/styles/src/organisms/index.css @@ -1 +1,2 @@ +@import './hero.css'; @import './out-of-stock.css'; diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 2df99693ff..86f217e9b1 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -187,6 +187,13 @@ export type { OutOfStockTitleProps, } from './organisms/OutOfStock' +export { default as Hero, HeroHeading, HeroImage } from './organisms/Hero' +export type { + HeroProps, + HeroHeadingProps, + HeroImageProps, +} from './organisms/Hero' + // Hooks export { default as useSlider } from './hooks/useSlider' export type { diff --git a/packages/ui/src/organisms/Hero/Hero.test.tsx b/packages/ui/src/organisms/Hero/Hero.test.tsx new file mode 100644 index 0000000000..358860dbda --- /dev/null +++ b/packages/ui/src/organisms/Hero/Hero.test.tsx @@ -0,0 +1,60 @@ +import { render } from '@testing-library/react' +import { axe } from 'jest-axe' +import React from 'react' + +import Hero from './Hero' +import HeroImage from './HeroImage' +import HeroHeading from './HeroHeading' + +const HeroTest = () => { + return ( + + + Quest 2 Controller on a table + + +

Get yo know our next release

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

+ Shop Now +
+
+ ) +} + +describe('Hero', () => { + describe('Data attributes', () => { + const { getByTestId } = render() + + const hero = getByTestId('store-hero') + const heroImage = getByTestId('store-hero-image') + const heroHeading = getByTestId('store-hero-heading') + + it('`Hero` component should have `data-store-hero` attribute', () => { + expect(hero).toHaveAttribute('data-store-hero') + }) + + it('`Hero` component should have custom data attribute `data-custom-attribute`', () => { + expect(hero).toHaveAttribute('data-custom-attribute') + }) + + it('`HeroImage` component should have `data-hero-image` attribute', () => { + expect(heroImage).toHaveAttribute('data-hero-image') + }) + + it('`HeroHeading` component should have `data-hero-heading` attribute', () => { + expect(heroHeading).toHaveAttribute('data-hero-heading') + }) + }) + + describe('Accessibility', () => { + it('should have no violations', async () => { + const { getByTestId } = render() + + expect(await axe(getByTestId('store-hero'))).toHaveNoViolations() + expect(await axe(getByTestId('store-hero'))).toHaveNoIncompletes() + }) + }) +}) diff --git a/packages/ui/src/organisms/Hero/Hero.tsx b/packages/ui/src/organisms/Hero/Hero.tsx new file mode 100644 index 0000000000..2eb14ce722 --- /dev/null +++ b/packages/ui/src/organisms/Hero/Hero.tsx @@ -0,0 +1,23 @@ +import React, { forwardRef } from 'react' +import type { HTMLAttributes } from 'react' + +export interface HeroProps extends HTMLAttributes { + /** + * ID to find this component in testing tools (e.g.: cypress, + * testing-library, and jest). + */ + testId?: string +} + +const Hero = forwardRef(function Hero( + { testId = 'store-hero', children, ...otherProps }, + ref +) { + return ( +
+ {children} +
+ ) +}) + +export default Hero diff --git a/packages/ui/src/organisms/Hero/HeroHeading.tsx b/packages/ui/src/organisms/Hero/HeroHeading.tsx new file mode 100644 index 0000000000..31ed1966dd --- /dev/null +++ b/packages/ui/src/organisms/Hero/HeroHeading.tsx @@ -0,0 +1,24 @@ +import type { HTMLAttributes } from 'react' +import React, { forwardRef } from 'react' + +export interface HeroHeadingProps extends HTMLAttributes { + /** + * ID to find this component in testing tools (e.g.: cypress, testing library, and jest). + */ + testId?: string +} + +const HeroHeading = forwardRef( + function HeroHeading( + { testId = 'store-hero-heading', children, ...otherProps }, + ref + ) { + return ( +
+ {children} +
+ ) + } +) + +export default HeroHeading diff --git a/packages/ui/src/organisms/Hero/HeroImage.tsx b/packages/ui/src/organisms/Hero/HeroImage.tsx new file mode 100644 index 0000000000..9323330e27 --- /dev/null +++ b/packages/ui/src/organisms/Hero/HeroImage.tsx @@ -0,0 +1,22 @@ +import type { HTMLAttributes } from 'react' +import React, { forwardRef } from 'react' + +export interface HeroImageProps extends HTMLAttributes { + /** + * ID to find this component in testing tools (e.g.: cypress, testing library, and jest). + */ + testId?: string +} + +const HeroImage = forwardRef(function HeroImage( + { testId = 'store-hero-image', children, ...otherProps }, + ref +) { + return ( +
+ {children} +
+ ) +}) + +export default HeroImage diff --git a/packages/ui/src/organisms/Hero/index.tsx b/packages/ui/src/organisms/Hero/index.tsx new file mode 100644 index 0000000000..782bdd8260 --- /dev/null +++ b/packages/ui/src/organisms/Hero/index.tsx @@ -0,0 +1,8 @@ +export { default } from './Hero' +export type { HeroProps } from './Hero' + +export { default as HeroImage } from './HeroImage' +export type { HeroImageProps } from './HeroImage' + +export { default as HeroHeading } from './HeroHeading' +export type { HeroHeadingProps } from './HeroHeading' diff --git a/packages/ui/src/organisms/Hero/stories/Hero.mdx b/packages/ui/src/organisms/Hero/stories/Hero.mdx new file mode 100644 index 0000000000..315421411f --- /dev/null +++ b/packages/ui/src/organisms/Hero/stories/Hero.mdx @@ -0,0 +1,48 @@ +import { Canvas, Props, Story, ArgsTable } from '@storybook/addon-docs' + +import Hero from '../Hero' +import HeroImage from '../HeroImage' +import HeroHeading from '../HeroHeading' + +# Hero + + + + + +## Components + +The `Hero` uses the [Compound Component](https://kentcdodds.com/blog/compound-components-with-react-hooks) pattern, its components are: + +- `Hero`: the wrapper component. +- `HeroImage`: the component that wraps the image displayed in the component. +- `HeroHeading`: the component should have a title, description, and a call to action link. + +## Props + +All hero-related components support all attributes also supported by the `
` tag. + +Besides those attributes, the following props are also supported: + +### `Hero` + + + +### `HeroImage` + + + +### `HeroHeading` + + + +## CSS Selectors + +```css +[data-store-hero] { +} +[data-hero-image] { +} +[data-hero-heading] { +} +``` diff --git a/packages/ui/src/organisms/Hero/stories/Hero.stories.tsx b/packages/ui/src/organisms/Hero/stories/Hero.stories.tsx new file mode 100644 index 0000000000..abda706a19 --- /dev/null +++ b/packages/ui/src/organisms/Hero/stories/Hero.stories.tsx @@ -0,0 +1,56 @@ +import type { Story, Meta } from '@storybook/react' +import React from 'react' + +import HeroComponent from '../Hero' +import HeroImage from '../HeroImage' +import HeroHeading from '../HeroHeading' +import type { HeroProps } from '../Hero' +import { Icon } from '../../..' +import mdx from './Hero.mdx' + +const RightArrow = () => ( + + + +) + +const HeroTemplate: Story = ({ testId }) => ( + + + Quest 2 Controller on a table + + +

New Products Available

+

+ At BaseStore you can shop the best tech of 2022. Enjoy and get 10% off + on your first purchase. +

+ + See all } /> + +
+
+) + +export const Hero = HeroTemplate.bind({}) +Hero.storyName = 'Hero' + +export default { + title: 'Organisms/Hero', + parameters: { + docs: { + page: mdx, + }, + }, +} as Meta