mirror of
https://github.com/vercel/commerce.git
synced 2025-05-17 23:16:59 +00:00
New productTag
This commit is contained in:
parent
e752555e02
commit
9c647b856f
@ -6,7 +6,7 @@ import s from './ProductCard.module.css'
|
||||
import Image, { ImageProps } from 'next/image'
|
||||
import WishlistButton from '@components/wishlist/WishlistButton'
|
||||
import usePrice from '@framework/product/use-price'
|
||||
|
||||
import ProductTag from '../ProductTag'
|
||||
interface Props {
|
||||
className?: string
|
||||
product: Product
|
||||
@ -104,14 +104,10 @@ const ProductCard: FC<Props> = ({
|
||||
variant={product.variants[0] as any}
|
||||
/>
|
||||
)}
|
||||
<div className={s.header}>
|
||||
<h3 className={s.name}>
|
||||
<span>{product.name}</span>
|
||||
</h3>
|
||||
<div className={s.price}>
|
||||
{`${price} ${product.price?.currencyCode}`}
|
||||
</div>
|
||||
</div>
|
||||
<ProductTag
|
||||
name={product.name}
|
||||
price={`${price} ${product.price?.currencyCode}`}
|
||||
/>
|
||||
<div className={s.imageContainer}>
|
||||
{product?.images && (
|
||||
<Image
|
||||
|
@ -12,7 +12,15 @@ import { a } from '@react-spring/web'
|
||||
import s from './ProductSlider.module.css'
|
||||
import ProductSliderControl from '../ProductSliderControl'
|
||||
|
||||
const ProductSlider: FC = ({ children }) => {
|
||||
interface ProductSliderProps {
|
||||
children: React.ReactNode[]
|
||||
className?: string
|
||||
}
|
||||
|
||||
const ProductSlider: React.FC<ProductSliderProps> = ({
|
||||
children,
|
||||
className = '',
|
||||
}) => {
|
||||
const [currentSlide, setCurrentSlide] = useState(0)
|
||||
const [isMounted, setIsMounted] = useState(false)
|
||||
const sliderContainerRef = useRef<HTMLDivElement>(null)
|
||||
@ -77,7 +85,7 @@ const ProductSlider: FC = ({ children }) => {
|
||||
const onNext = React.useCallback(() => slider.next(), [slider])
|
||||
|
||||
return (
|
||||
<div className={s.root} ref={sliderContainerRef}>
|
||||
<div className={cn(s.root, className)} ref={sliderContainerRef}>
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(s.slider, { [s.show]: isMounted }, 'keen-slider')}
|
||||
|
30
components/product/ProductTag/ProductTag.module.css
Normal file
30
components/product/ProductTag/ProductTag.module.css
Normal file
@ -0,0 +1,30 @@
|
||||
.root {
|
||||
@apply transition-colors ease-in-out duration-500
|
||||
absolute top-0 left-0 z-20 pr-16;
|
||||
}
|
||||
|
||||
.root .name {
|
||||
@apply pt-0 max-w-full w-full leading-extra-loose;
|
||||
font-size: 2rem;
|
||||
letter-spacing: 0.4px;
|
||||
line-height: 2.2em;
|
||||
}
|
||||
|
||||
.root .name span {
|
||||
@apply py-4 px-6 bg-primary text-primary font-bold;
|
||||
min-height: 70px;
|
||||
font-size: inherit;
|
||||
letter-spacing: inherit;
|
||||
box-decoration-break: clone;
|
||||
-webkit-box-decoration-break: clone;
|
||||
}
|
||||
|
||||
.root .name span.fontsizing {
|
||||
display: flex;
|
||||
padding-top: 1.5rem;
|
||||
}
|
||||
|
||||
.root .price {
|
||||
@apply pt-2 px-6 pb-4 text-sm bg-primary text-accent-9
|
||||
font-semibold inline-block tracking-wide;
|
||||
}
|
36
components/product/ProductTag/ProductTag.tsx
Normal file
36
components/product/ProductTag/ProductTag.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import cn from 'classnames'
|
||||
import { inherits } from 'util'
|
||||
import s from './ProductTag.module.css'
|
||||
|
||||
interface ProductTagProps {
|
||||
className?: string
|
||||
name: string
|
||||
price: string
|
||||
fontSize?: number
|
||||
}
|
||||
|
||||
const ProductTag: React.FC<ProductTagProps> = ({
|
||||
name,
|
||||
price,
|
||||
className = '',
|
||||
fontSize = 32,
|
||||
}) => {
|
||||
return (
|
||||
<div className={cn(s.root, className)}>
|
||||
<h3 className={s.name}>
|
||||
<span
|
||||
className={cn({ [s.fontsizing]: fontSize < 32 })}
|
||||
style={{
|
||||
fontSize: `${fontSize}px`,
|
||||
lineHeight: `${fontSize}px`,
|
||||
}}
|
||||
>
|
||||
{name}
|
||||
</span>
|
||||
</h3>
|
||||
<div className={s.price}>{price}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ProductTag
|
1
components/product/ProductTag/index.ts
Normal file
1
components/product/ProductTag/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './ProductTag'
|
@ -8,30 +8,6 @@
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
.header {
|
||||
@apply transition-colors ease-in-out duration-500
|
||||
absolute top-0 left-0 z-20 pr-16;
|
||||
}
|
||||
|
||||
.header .name {
|
||||
@apply pt-0 max-w-full w-full leading-extra-loose;
|
||||
font-size: 2rem;
|
||||
letter-spacing: 0.4px;
|
||||
}
|
||||
|
||||
.header .name span {
|
||||
@apply py-4 px-6 bg-primary text-primary font-bold;
|
||||
font-size: inherit;
|
||||
letter-spacing: inherit;
|
||||
box-decoration-break: clone;
|
||||
-webkit-box-decoration-break: clone;
|
||||
}
|
||||
|
||||
.header .price {
|
||||
@apply pt-2 px-6 pb-4 text-sm bg-primary text-accent-9
|
||||
font-semibold inline-block tracking-wide;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
@apply flex flex-col col-span-1 mx-auto max-w-8xl px-6 py-6 w-full h-full;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import { WishlistButton } from '@components/wishlist'
|
||||
import { ProductSlider, ProductCard } from '@components/product'
|
||||
import { Container, Text } from '@components/ui'
|
||||
import ProductSidebar from '../ProductSidebar'
|
||||
import ProductTag from '../ProductTag'
|
||||
interface ProductViewProps {
|
||||
product: Product
|
||||
relatedProducts: Product[]
|
||||
@ -23,35 +24,14 @@ const ProductView: FC<ProductViewProps> = ({ product, relatedProducts }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<NextSeo
|
||||
title={product.name}
|
||||
description={product.description}
|
||||
openGraph={{
|
||||
type: 'website',
|
||||
title: product.name,
|
||||
description: product.description,
|
||||
images: [
|
||||
{
|
||||
url: product.images[0]?.url!,
|
||||
width: 800,
|
||||
height: 600,
|
||||
alt: product.name,
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
<Container className="max-w-none w-full" clean>
|
||||
<div className={cn(s.root, 'fit')}>
|
||||
<div className={cn(s.main, 'fit')}>
|
||||
<div className={s.header}>
|
||||
<h3 className={s.name}>
|
||||
<span>{product.name}</span>
|
||||
</h3>
|
||||
<div className={s.price}>
|
||||
{`${price} ${product.price?.currencyCode}`}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ProductTag
|
||||
name={product.name}
|
||||
price={`${price} ${product.price?.currencyCode}`}
|
||||
fontSize={32}
|
||||
/>
|
||||
<div className={s.sliderContainer}>
|
||||
<ProductSlider key={product.id}>
|
||||
{product.images.map((image, i) => (
|
||||
@ -105,6 +85,23 @@ const ProductView: FC<ProductViewProps> = ({ product, relatedProducts }) => {
|
||||
</div>
|
||||
</section>
|
||||
</Container>
|
||||
<NextSeo
|
||||
title={product.name}
|
||||
description={product.description}
|
||||
openGraph={{
|
||||
type: 'website',
|
||||
title: product.name,
|
||||
description: product.description,
|
||||
images: [
|
||||
{
|
||||
url: product.images[0]?.url!,
|
||||
width: 800,
|
||||
height: 600,
|
||||
alt: product.name,
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user