Skip to content
This repository has been archived by the owner on Jun 2, 2022. It is now read-only.

feat: sections #371

Merged
merged 5 commits into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Removed fit-in property from image component
- Sections are now self-contained
- Moves icons to `/static/icons` folder
- Replaces page type redirects, a.k.a. `/account`, `/login` to a corresponding file in `/pages` folder
- Replaces `let` declarations for `useRef` for better React compatibility
Expand Down
32 changes: 18 additions & 14 deletions src/components/sections/BannerText/BannerText.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Banner, BannerContent, BannerLink } from '@faststore/ui'
import type { InputHTMLAttributes } from 'react'
import React from 'react'
import { LinkButton } from 'src/components/ui/Button'
import type { InputHTMLAttributes } from 'react'

import Section from '../Section'

import './banner-text.scss'

Expand Down Expand Up @@ -34,19 +36,21 @@ function BannerText({
actionLabel,
}: BannerTextProps) {
return (
<Banner>
<BannerContent className="grid-content">
<div className="title-display-big">
<h2>{title}</h2>
<p>{caption}</p>
</div>
<BannerLink>
<LinkButton to={actionPath} inverse>
{actionLabel}
</LinkButton>
</BannerLink>
</BannerContent>
</Banner>
<Section className="grid-section">
<Banner>
<BannerContent className="grid-content">
<div className="title-display-big">
<h2>{title}</h2>
<p>{caption}</p>
</div>
<BannerLink>
<LinkButton to={actionPath} inverse>
{actionLabel}
</LinkButton>
</BannerLink>
</BannerContent>
</Banner>
</Section>
)
}

Expand Down
12 changes: 10 additions & 2 deletions src/components/sections/Breadcrumb/Breadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import React, { memo } from 'react'
import type { BreadcrumbProps } from 'src/components/ui/Breadcrumb'
import UIBreadcrumb from 'src/components/ui/Breadcrumb'
import type { BreadcrumbProps } from 'src/components/ui/Breadcrumb'

import Section from '../Section'

import './breadcrumb.scss'

interface BreadcrumbWrapperProps
extends Partial<Pick<BreadcrumbProps, 'breadcrumbList'>> {
Expand All @@ -11,7 +15,11 @@ function Breadcrumb({ breadcrumbList, name }: BreadcrumbWrapperProps) {
const fallback = [{ item: '/', name, position: 1 }]
const list = breadcrumbList ?? fallback

return <UIBreadcrumb breadcrumbList={list} />
return (
<Section className="breadcrumb / grid-content">
<UIBreadcrumb breadcrumbList={list} />
</Section>
)
}

export default memo(Breadcrumb)
6 changes: 6 additions & 0 deletions src/components/sections/Breadcrumb/breadcrumb.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@import "src/styles/scaffold";

.breadcrumb {
padding-top: var(--space-3);
padding-bottom: var(--space-3);
}
63 changes: 33 additions & 30 deletions src/components/sections/Hero/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react'
import type { ReactNode } from 'react'
import UIHero, {
HeroContent,
HeroImage,
Expand All @@ -9,6 +8,8 @@ import Image from 'src/components/ui/Image/Image'
import { LinkButton } from 'src/components/ui/Button'
import IconSVG from 'src/components/common/IconSVG'

import Section from '../Section'

type Variant = 'default' | 'small'

interface HeroProps {
Expand All @@ -17,7 +18,7 @@ interface HeroProps {
variant?: Variant
linkText?: string
link?: string
icon?: ReactNode
icon?: JSX.Element
imageSrc: string
imageAlt: string
}
Expand All @@ -42,36 +43,38 @@ const Hero = ({
imageSrc,
}: HeroProps) => {
return (
<UIHero data-hero-variant={variant}>
<HeroContent aria-labelledby="hero-heading">
<div className="hero-content-wrapper / grid-content">
<div className="hero-content-info">
<h1
id="hero-heading"
className={
variant === 'default' ? 'title-hero' : 'title-hero-small'
}
>
{title}
</h1>
<Section>
<UIHero data-hero-variant={variant}>
<HeroContent aria-labelledby="hero-heading">
<div className="hero-content-wrapper / grid-content">
<div className="hero-content-info">
<h1
id="hero-heading"
className={
variant === 'default' ? 'title-hero' : 'title-hero-small'
}
>
{title}
</h1>

<p className="text-body-big">{subtitle}</p>
{!!link && (
<HeroLink>
<LinkButton to={link} inverse>
{linkText}{' '}
<IconSVG name="ArrowRight" width={24} height={24} />
</LinkButton>
</HeroLink>
)}
<p className="text-body-big">{subtitle}</p>
{!!link && (
<HeroLink>
<LinkButton to={link} inverse>
{linkText}{' '}
<IconSVG name="ArrowRight" width={24} height={24} />
</LinkButton>
</HeroLink>
)}
</div>
{!!icon && <div className="hero-content-icon">{icon}</div>}
</div>
{!!icon && <div className="hero-content-icon">{icon}</div>}
</div>
</HeroContent>
<HeroImage>
<Image baseUrl={imageSrc} alt={imageAlt} {...imgProps} />
</HeroImage>
</UIHero>
</HeroContent>
<HeroImage>
<Image baseUrl={imageSrc} alt={imageAlt} {...imgProps} />
</HeroImage>
</UIHero>
</Section>
)
}

Expand Down
7 changes: 6 additions & 1 deletion src/components/sections/Incentives/IncentivesHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'
import IconSVG from 'src/components/common/IconSVG'

import Incentives from './Incentives'
import Section from '../Section'

const incentives = [
{
Expand Down Expand Up @@ -32,7 +33,11 @@ const incentives = [
]

function IncentivesHeader() {
return <Incentives incentives={incentives} classes="incentives--colored" />
return (
<Section>
<Incentives incentives={incentives} classes="incentives--colored" />
</Section>
)
}

export default IncentivesHeader
5 changes: 3 additions & 2 deletions src/components/sections/ProductDetails/ProductDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type { CurrencyCode, ViewItemEvent } from '@faststore/sdk'
import type { AnalyticsItem } from 'src/sdk/analytics/types'

import './product-details.scss'
import Section from '../Section'

interface Props {
product: ProductDetailsFragment_ProductFragment
Expand Down Expand Up @@ -115,7 +116,7 @@ function ProductDetails({ product: staleProduct }: Props) {
])

return (
<div className="product-details / grid-content grid-section">
<Section className="product-details / grid-content grid-section">
<Breadcrumb breadcrumbList={breadcrumbs.itemListElement} />

<section className="product-details__body">
Expand Down Expand Up @@ -183,7 +184,7 @@ function ProductDetails({ product: staleProduct }: Props) {
</article>
</section>
</section>
</div>
</Section>
)
}

Expand Down
9 changes: 5 additions & 4 deletions src/components/sections/ProductGallery/ProductGallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import FilterSkeleton from 'src/components/skeletons/FilterSkeleton'
import ProductGrid from 'src/components/product/ProductGrid'
import IconSVG from 'src/components/common/IconSVG'

import Section from '../Section'
import GalleryPage from './ProductGalleryPage'
import EmptyGallery from './EmptyGallery'
import { useGalleryQuery } from './useGalleryQuery'
Expand All @@ -30,14 +31,14 @@ function ProductGallery({ title }: Props) {

if (data && totalCount === 0) {
return (
<div className="product-listing / grid-content">
<Section className="product-listing / grid-content">
<EmptyGallery />
</div>
</Section>
)
}

return (
<div className="product-listing / grid-content-full">
<Section className="product-listing / grid-content-full">
<div className="product-listing__content-grid / grid-content">
<div className="product-listing__filters">
<FilterSkeleton loading={orderedFacets?.length === 0}>
Expand Down Expand Up @@ -167,7 +168,7 @@ function ProductGallery({ title }: Props) {
)}
</div>
</div>
</div>
</Section>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,13 @@ function GalleryPage({
/>
<div className="product-listing__results-sponsored">
<h3>Sponsored</h3>
<ProductTiles products={productsSponsored.slice(0, 2)} />
{/*
TODO: Refactor this bit of code

Sections should be self contained and should not import other sections.
We should remove/refactor this section from here
*/}
<ProductTiles products={productsSponsored.slice(0, 2)} title="" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make the title prop optional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure. This component is weird because it's using another section. Sections should be self contained and not depend on other sections. This should be refactored on another PR. I'll add a TODO for this. Thanks!

</div>
<ProductGrid
products={products.slice(middleItemIndex, itemsPerPage)}
Expand Down
36 changes: 26 additions & 10 deletions src/components/sections/ProductShelf/ProductShelf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,40 @@ import type { ProductSummary_ProductFragment } from '@generated/graphql'
import ProductShelfSkeleton from 'src/components/skeletons/ProductShelfSkeleton'

import ProductCard from '../../product/ProductCard'
import Section from '../Section'

import './product-shelf.scss'

interface ProductShelfProps {
products: ProductSummary_ProductFragment[]
title: string | JSX.Element
withDivisor?: boolean
}

function ProductShelf({ products }: ProductShelfProps) {
function ProductShelf({
products,
title,
withDivisor = false,
}: ProductShelfProps) {
return (
<ProductShelfSkeleton loading={products.length === 0}>
<ul data-product-shelf className="grid-content">
{products.map((product, idx) => (
<li key={`${product.id}`}>
<ProductCard product={product} index={idx + 1} />
</li>
))}
</ul>
</ProductShelfSkeleton>
<Section
className={`page__section-shelf / grid-section ${
withDivisor ? 'page__section-divisor' : ''
}`}
>
<h2 className="title-section / grid-content">{title}</h2>
<div className="page__section-content">
<ProductShelfSkeleton loading={products.length === 0}>
<ul data-product-shelf className="grid-content">
{products.map((product, idx) => (
<li key={`${product.id}`}>
<ProductCard product={product} index={idx + 1} />
</li>
))}
</ul>
</ProductShelfSkeleton>
</div>
</Section>
)
}

Expand Down
45 changes: 28 additions & 17 deletions src/components/sections/ProductTiles/ProductTiles.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import React from 'react'
import Tiles, { Tile } from 'src/components/ui/Tiles'
import ProductCard from 'src/components/product/ProductCard'
import type { ProductSummary_ProductFragment } from '@generated/graphql'
import ProductTilesSkeleton from 'src/components/skeletons/ProductTilesSkeleton'
import type { ProductSummary_ProductFragment } from '@generated/graphql'

import Section from '../Section'

interface TilesProps {
products: ProductSummary_ProductFragment[]
title: string | JSX.Element
}

const NUMBER_ITEMS_TO_EXPAND_FIRST = 3
Expand All @@ -25,23 +28,31 @@ const getRatio = (products: number, idx: number) => {
return 3 / 4
}

const ProductTiles = ({ products }: TilesProps) => {
const ProductTiles = ({ products, title }: TilesProps) => {
return (
<ProductTilesSkeleton variant="horizontal" loading={products.length === 0}>
<Tiles>
{products.map((product, idx) => (
<Tile key={product.id}>
<ProductCard
data-testid="tile-card"
product={product}
index={idx + 1}
variant="horizontal"
aspectRatio={getRatio(products.length, idx)}
/>
</Tile>
))}
</Tiles>
</ProductTilesSkeleton>
<Section className="grid-section grid-content">
<h2 className="title-section">{title}</h2>
<div className="page__section-content">
<ProductTilesSkeleton
variant="horizontal"
loading={products.length === 0}
>
<Tiles>
{products.map((product, idx) => (
<Tile key={product.id}>
<ProductCard
data-testid="tile-card"
product={product}
index={idx + 1}
variant="horizontal"
aspectRatio={getRatio(products.length, idx)}
/>
</Tile>
))}
</Tiles>
</ProductTilesSkeleton>
</div>
</Section>
)
}

Expand Down
Loading