mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 12:24:18 +00:00
🔨 refactor: carouselcommn
:%s
This commit is contained in:
parent
861b1b9fb5
commit
3b27d38a59
3
next-env.d.ts
vendored
3
next-env.d.ts
vendored
@ -1,3 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
|
@ -44,6 +44,7 @@
|
||||
"react-dom": "^17.0.2",
|
||||
"react-fast-marquee": "^1.1.4",
|
||||
"react-merge-refs": "^1.1.0",
|
||||
"react-multi-carousel": "^2.6.5",
|
||||
"react-player": "^2.9.0",
|
||||
"react-use-measure": "^2.0.4",
|
||||
"sass": "^1.38.0",
|
||||
|
132
pages/test.tsx
132
pages/test.tsx
@ -1,74 +1,12 @@
|
||||
import { CartDrawer, Layout } from 'src/components/common'
|
||||
import MenuNavigationProductList from 'src/components/common/MenuNavigationProductList/MenuNavigationProductList'
|
||||
import { CarouselCommon, ProductCard, Layout } from 'src/components/common'
|
||||
// import { RecipeListPage } from 'src/components/modules/recipes';
|
||||
import { OPTION_ALL, QUERY_KEY, ROUTE } from 'src/utils/constanst.utils'
|
||||
import { useModalCommon } from 'src/components/hooks'
|
||||
import {
|
||||
CollectionCarcousel,
|
||||
HomeCollection,
|
||||
} from 'src/components/modules/home'
|
||||
import { PRODUCT_DATA_TEST } from 'src/utils/demo-data'
|
||||
import { useKeenSlider } from 'keen-slider/react'
|
||||
import { CSSProperties } from 'react'
|
||||
const CATEGORY = [
|
||||
{
|
||||
name: 'All',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=${OPTION_ALL}`,
|
||||
},
|
||||
{
|
||||
name: 'Veggie',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=veggie`,
|
||||
},
|
||||
{
|
||||
name: 'Seafood',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=seafood`,
|
||||
},
|
||||
{
|
||||
name: 'Frozen',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=frozen`,
|
||||
},
|
||||
{
|
||||
name: 'Coffee Bean',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=coffee-bean`,
|
||||
},
|
||||
{
|
||||
name: 'Sauce',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=sauce`,
|
||||
},
|
||||
]
|
||||
const BRAND = [
|
||||
{
|
||||
name: 'Maggi',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=veggie`,
|
||||
},
|
||||
{
|
||||
name: 'Cholimes',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=seafood`,
|
||||
},
|
||||
{
|
||||
name: 'Chinsu',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=frozen`,
|
||||
},
|
||||
]
|
||||
|
||||
const FEATURED = [
|
||||
{
|
||||
name: 'Best Sellers',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=veggie`,
|
||||
},
|
||||
{
|
||||
name: 'Sales',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=seafood`,
|
||||
},
|
||||
{
|
||||
name: 'New Item',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=frozen`,
|
||||
},
|
||||
{
|
||||
name: 'Viewed',
|
||||
link: `${ROUTE.PRODUCTS}/?${QUERY_KEY.BRAND}=viewed`,
|
||||
},
|
||||
]
|
||||
import { ProductCardProps } from 'src/components/common/ProductCard/ProductCard'
|
||||
import ColectionCarcousel from 'src/components/modules/home/CollectionCarcousel/CollectionCarcousel'
|
||||
import { HomeCollection } from 'src/components/modules/home'
|
||||
export default function Test() {
|
||||
const {
|
||||
visible: visibleMenuFilter,
|
||||
@ -95,51 +33,27 @@ export default function Test() {
|
||||
maxHeight: '100vh',
|
||||
}
|
||||
const [sliderRef] = useKeenSlider<HTMLDivElement>({ slidesPerView: 2 })
|
||||
|
||||
const RESPONSIVE = {
|
||||
desktop: {
|
||||
breakpoint: { max: 3000, min: 1024 },
|
||||
items: 5.5,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 1024, min: 464 },
|
||||
items: 2,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 464, min: 0 },
|
||||
items: 1,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
}
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{/* <HomeCollection /> */}
|
||||
{/* <CollectionCarcousel
|
||||
data={PRODUCT_DATA_TEST}
|
||||
itemKey="tesst"
|
||||
category="test"
|
||||
title="test"
|
||||
subtitle=""
|
||||
/> */}
|
||||
<div ref={sliderRef} className="keen-slider">
|
||||
{/* {[...Array(10).keys()].map(() => {
|
||||
return (
|
||||
<div className="keen-slider__slide number-slide1" style={style}>
|
||||
1
|
||||
</div>
|
||||
)
|
||||
})} */}
|
||||
<div className="keen-slider__slide number-slide1" style={style}>
|
||||
1
|
||||
</div>
|
||||
<div className="keen-slider__slide number-slide1" style={style}>
|
||||
1
|
||||
</div>
|
||||
<div className="keen-slider__slide number-slide1" style={style}>
|
||||
1
|
||||
</div>
|
||||
<div className="keen-slider__slide number-slide1" style={style}>
|
||||
1
|
||||
</div>
|
||||
<div className="keen-slider__slide number-slide1" style={style}>
|
||||
1
|
||||
</div>
|
||||
<div className="keen-slider__slide number-slide1" style={style}>
|
||||
1
|
||||
</div>
|
||||
<div className="keen-slider__slide number-slide1" style={style}>
|
||||
1
|
||||
</div>
|
||||
<div className="keen-slider__slide number-slide1" style={style}>
|
||||
1
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<HomeCollection />
|
||||
{/* <CarouselCommon<ProductCardProps> showDots={true} draggable={true} infinite={true} data={PRODUCT_DATA_TEST} Component={ProductCard} responsive={RESPONSIVE} itemKey="tets"/> */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { TOptionsEvents } from 'keen-slider'
|
||||
import React, { memo } from 'react'
|
||||
import { ResponsiveType } from 'react-multi-carousel'
|
||||
import CarouselCommon from '../CarouselCommon/CarouselCommon'
|
||||
import BannerItem, { BannerItemProps } from './BannerItem/BannerItem'
|
||||
|
||||
@ -7,10 +8,13 @@ interface Props {
|
||||
data: BannerItemProps[],
|
||||
}
|
||||
|
||||
const option: TOptionsEvents = {
|
||||
slidesPerView: 1,
|
||||
mode: 'free',
|
||||
}
|
||||
const RESPONSIVE:ResponsiveType = {
|
||||
desktop: {
|
||||
breakpoint: { max: 9999, min: 0 },
|
||||
items: 1,
|
||||
},
|
||||
};
|
||||
|
||||
const Banner = memo(({ data }: Props) => {
|
||||
if (data.length === 1) {
|
||||
const item = data[0]
|
||||
@ -28,8 +32,8 @@ const Banner = memo(({ data }: Props) => {
|
||||
data={data}
|
||||
itemKey="banner"
|
||||
Component={BannerItem}
|
||||
option={option}
|
||||
isDot={true}
|
||||
responsive={RESPONSIVE}
|
||||
showDots={true}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
@ -3,57 +3,72 @@
|
||||
@apply relative;
|
||||
min-height: theme('caroucel.arrow-height');
|
||||
.isPadding {
|
||||
@apply spacing-horizontal;
|
||||
// @apply spacing-horizontal;
|
||||
}
|
||||
.showDots {
|
||||
padding-bottom: 2.4rem;
|
||||
}
|
||||
:global {
|
||||
.react-multi-carousel-dot-list {
|
||||
li {
|
||||
button{
|
||||
outline: none;
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:global(.customArrow) {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: .8rem;
|
||||
backdrop-filter: saturate(180%) blur(10px);
|
||||
border-radius: 0.8rem;
|
||||
backdrop-filter: saturate(180%) blur(10px);
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
@apply absolute top-1/2 bg-background-arrow transform -translate-y-1/2 flex justify-center items-center transition duration-100;
|
||||
&:global(.leftArrow) {
|
||||
@apply hidden left-0;
|
||||
@screen md {
|
||||
@apply flex
|
||||
}
|
||||
@apply hidden left-0;
|
||||
@screen md {
|
||||
@apply flex;
|
||||
}
|
||||
}
|
||||
&:global(.rightArrow) {
|
||||
@apply hidden right-0;
|
||||
@screen md {
|
||||
@apply flex;
|
||||
}
|
||||
@apply hidden right-0;
|
||||
@screen md {
|
||||
@apply flex;
|
||||
}
|
||||
}
|
||||
&:global(.isDisabledArrow) {
|
||||
@apply hidden;
|
||||
}
|
||||
}
|
||||
:global {
|
||||
.dots {
|
||||
display: flex;
|
||||
padding: 1rem 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dot {
|
||||
border: none;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
background: #c5c5c5;
|
||||
border-radius: 50%;
|
||||
margin: 0 0.5rem;
|
||||
padding: 0.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dot:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.dot.active {
|
||||
background: #000;
|
||||
}
|
||||
}
|
||||
:global {
|
||||
.dots {
|
||||
display: flex;
|
||||
padding: 1rem 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dot {
|
||||
border: none;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
background: #c5c5c5;
|
||||
border-radius: 50%;
|
||||
margin: 0 0.5rem;
|
||||
padding: 0.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dot:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.dot.active {
|
||||
background: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,85 +1,88 @@
|
||||
import { useKeenSlider } from 'keen-slider/react'
|
||||
import React, { useEffect } from 'react'
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
import 'keen-slider/keen-slider.min.css'
|
||||
import { CustomCarouselArrow } from './CustomArrow/CustomCarouselArrow'
|
||||
import s from './CarouselCommon.module.scss'
|
||||
import { TOptionsEvents } from 'keen-slider'
|
||||
import classNames from 'classnames'
|
||||
import CustomDot from './CustomDot/CustomDot'
|
||||
export interface CarouselCommonProps<T> {
|
||||
import Carousel from 'react-multi-carousel'
|
||||
import 'react-multi-carousel/lib/styles.css'
|
||||
import {
|
||||
ResponsiveType,
|
||||
CarouselProps,
|
||||
ButtonGroupProps,
|
||||
} from 'react-multi-carousel/lib/types'
|
||||
export interface CarouselCommonProps<T>
|
||||
extends Omit<CarouselProps, 'children' | 'responsive'> {
|
||||
data: T[]
|
||||
Component: React.ComponentType<T>
|
||||
isArrow?: Boolean
|
||||
isDot?: Boolean
|
||||
itemKey: String
|
||||
option: TOptionsEvents
|
||||
keenClassname?: string
|
||||
isPadding?: boolean
|
||||
defaultComponentProps?: object
|
||||
responsive?: ResponsiveType
|
||||
}
|
||||
const RESPONSIVE = {
|
||||
desktop: {
|
||||
breakpoint: { max: 3000, min: 1024 },
|
||||
items: 3,
|
||||
slidesToSlide: 3, // optional, default to 1.
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 1024, min: 464 },
|
||||
items: 2,
|
||||
slidesToSlide: 2, // optional, default to 1.
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 464, min: 0 },
|
||||
items: 1,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
}
|
||||
|
||||
const CarouselCommon = <T,>({
|
||||
data=[],
|
||||
data = [],
|
||||
Component,
|
||||
itemKey,
|
||||
keenClassname,
|
||||
isPadding = false,
|
||||
isArrow = true,
|
||||
isDot = false,
|
||||
defaultComponentProps,
|
||||
option: { slideChanged,slidesPerView, ...sliderOption },
|
||||
responsive = RESPONSIVE,
|
||||
showDots,
|
||||
isPadding,
|
||||
arrows,
|
||||
...props
|
||||
}: CarouselCommonProps<T>) => {
|
||||
const [currentSlide, setCurrentSlide] = React.useState(0)
|
||||
const [dotArr, setDotArr] = React.useState<number[]>([])
|
||||
const [sliderRef, slider] = useKeenSlider<HTMLDivElement>({
|
||||
...sliderOption,
|
||||
slidesPerView,
|
||||
slideChanged(s) {
|
||||
setCurrentSlide(s.details().relativeSlide)
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if(isDot && slider && data){
|
||||
let array:number[]
|
||||
let number = data.length - Math.floor(slider.details().slidesPerView - 1)
|
||||
if(number<1){
|
||||
number = 1
|
||||
}
|
||||
array = [...Array(number).keys()]
|
||||
setDotArr(array)
|
||||
}
|
||||
}, [isDot,slider,data])
|
||||
|
||||
const carousel = useRef<Carousel>(null)
|
||||
const handleRightArrowClick = () => {
|
||||
slider.next()
|
||||
carousel.current?.next(carousel.current.props.slidesToSlide||1)
|
||||
}
|
||||
|
||||
const handleLeftArrowClick = () => {
|
||||
slider.prev()
|
||||
}
|
||||
|
||||
const onDotClick = (index:number) => {
|
||||
slider.moveToSlideRelative(index)
|
||||
carousel.current?.previous(carousel.current.props.slidesToSlide||1)
|
||||
}
|
||||
return (
|
||||
<div className={s.navigationWrapper}>
|
||||
<div
|
||||
ref={sliderRef}
|
||||
className={classNames('keen-slider', keenClassname, {
|
||||
<Carousel
|
||||
{...props}
|
||||
ref={carousel}
|
||||
showDots={showDots}
|
||||
customButtonGroup={<CarouselButtonGroup />}
|
||||
renderButtonGroupOutside
|
||||
sliderClass={''}
|
||||
containerClass={classNames({
|
||||
[s.showDots]: showDots,
|
||||
[s.isPadding]: isPadding,
|
||||
})}
|
||||
responsive={responsive}
|
||||
arrows={false}
|
||||
renderDotsOutside={true}
|
||||
// customLeftArrow={<CustomCarouselArrow side="left" />}
|
||||
// customRightArrow={<CustomCarouselArrow side="right" />}
|
||||
>
|
||||
{data?.map((props, index) => {
|
||||
const allProps = defaultComponentProps ? { ...props, ...defaultComponentProps } : props
|
||||
return (
|
||||
<div className="keen-slider__slide" key={`${itemKey}-${index}`}>
|
||||
<Component {...allProps} />
|
||||
</div>
|
||||
)
|
||||
const allProps = defaultComponentProps
|
||||
? { ...props, ...defaultComponentProps }
|
||||
: props
|
||||
return <Component {...allProps} key={`${itemKey}-${index}`} />
|
||||
})}
|
||||
</div>
|
||||
{slider && isArrow && (
|
||||
</Carousel>
|
||||
{carousel && arrows && (
|
||||
<>
|
||||
<CustomCarouselArrow
|
||||
side="right"
|
||||
@ -91,7 +94,7 @@ const CarouselCommon = <T,>({
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{slider && isDot && (
|
||||
{/* {slider && isDot && (
|
||||
<div className="dots">
|
||||
{dotArr.map((index) => {
|
||||
return (
|
||||
@ -99,9 +102,16 @@ const CarouselCommon = <T,>({
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const CarouselButtonGroup = ({ next, previous }: ButtonGroupProps) => {
|
||||
return (
|
||||
<>
|
||||
<CustomCarouselArrow side="left" onClick={previous} />
|
||||
<CustomCarouselArrow side="right" onClick={next} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default CarouselCommon
|
||||
|
@ -2,24 +2,30 @@ import classNames from 'classnames'
|
||||
import React from 'react'
|
||||
import ArrowLeft from 'src/components/icons/ArrowLeft'
|
||||
import ArrowRight from 'src/components/icons/ArrowRight'
|
||||
import "./CustomCarouselArrow.module.scss"
|
||||
|
||||
interface CustomCarouselArrowProps
|
||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
import './CustomCarouselArrow.module.scss'
|
||||
import { ArrowProps } from 'react-multi-carousel/lib/types'
|
||||
interface CustomCarouselArrowProps extends ArrowProps {
|
||||
side: 'left' | 'right'
|
||||
isDisabled?:Boolean
|
||||
isDisabled?: Boolean
|
||||
}
|
||||
|
||||
export const CustomCarouselArrow = ({
|
||||
side,isDisabled,
|
||||
...props
|
||||
side,
|
||||
isDisabled,
|
||||
onClick,
|
||||
}: CustomCarouselArrowProps) => {
|
||||
const handleClick = () => {
|
||||
onClick && onClick()
|
||||
}
|
||||
return (
|
||||
<button
|
||||
{...props}
|
||||
className={classNames("customArrow", { [`${side}Arrow`]: side,"isDisabledArrow":isDisabled})}
|
||||
onClick={handleClick}
|
||||
className={classNames('customArrow', {
|
||||
[`${side}Arrow`]: side,
|
||||
isDisabledArrow: isDisabled,
|
||||
})}
|
||||
>
|
||||
{side==='left'?(<ArrowLeft/>):(<ArrowRight/>)}
|
||||
</button>
|
||||
{side === 'left' ? <ArrowLeft /> : <ArrowRight />}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
@ -1,29 +1,31 @@
|
||||
import { TOptionsEvents } from 'keen-slider';
|
||||
import React from 'react';
|
||||
import { ResponsiveType } from 'react-multi-carousel';
|
||||
import { CarouselCommon, ViewAllItem } from 'src/components/common';
|
||||
import ProductCard, { ProductCardProps } from 'src/components/common/ProductCard/ProductCard';
|
||||
import { ROUTE } from 'src/utils/constanst.utils';
|
||||
import { PRODUCT_DATA_TEST } from 'src/utils/demo-data';
|
||||
import s from './CartRecommendation.module.scss';
|
||||
|
||||
const option: TOptionsEvents = {
|
||||
slidesPerView: 1.5,
|
||||
mode: 'free',
|
||||
breakpoints: {
|
||||
'(min-width: 640px)': {
|
||||
slidesPerView: 1.5,
|
||||
},
|
||||
'(min-width: 768px)': {
|
||||
slidesPerView: 2.5,
|
||||
},
|
||||
'(min-width: 1008px)': {
|
||||
slidesPerView: 2.2,
|
||||
},
|
||||
'(min-width: 1440px)': {
|
||||
slidesPerView: 2.5,
|
||||
}
|
||||
const RESPONSIVE:ResponsiveType = {
|
||||
desktop: {
|
||||
breakpoint: { max: 99999, min: 1440 },
|
||||
items: 2.5,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
},
|
||||
}
|
||||
lap: {
|
||||
breakpoint: { max: 1440, min: 1008 },
|
||||
items: 2.2,
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 1008, min: 768 },
|
||||
items: 2.5,
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 768, min: 0 },
|
||||
items: 1.5,
|
||||
}
|
||||
};
|
||||
|
||||
const CartRecommendation = () => {
|
||||
return (
|
||||
@ -39,7 +41,7 @@ const CartRecommendation = () => {
|
||||
data={PRODUCT_DATA_TEST}
|
||||
Component={ProductCard}
|
||||
itemKey="cart-recommendation"
|
||||
option={option}
|
||||
responsive={RESPONSIVE}
|
||||
defaultComponentProps={{ isSingleButton: true }}
|
||||
/>
|
||||
</div>
|
||||
|
@ -17,6 +17,7 @@ const ImgWithLink = ({ src, alt, blurDataURL = BLUR_DATA_IMG }: ImgWithLinkProps
|
||||
className={s.imgWithLink}
|
||||
placeholder="blur"
|
||||
blurDataURL={blurDataURL}
|
||||
draggable='false'
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,6 +1,7 @@
|
||||
import classNames from 'classnames';
|
||||
import { TOptionsEvents } from 'keen-slider';
|
||||
import React from 'react';
|
||||
import { ResponsiveType } from 'react-multi-carousel';
|
||||
import CarouselCommon from '../CarouselCommon/CarouselCommon';
|
||||
import ProductCard, { ProductCardProps } from '../ProductCard/ProductCard';
|
||||
import InfoProducts from './InfoProducts/InfoProducts';
|
||||
@ -36,7 +37,35 @@ const OPTION_DEFAULT: TOptionsEvents = {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const RESPONSIVE:ResponsiveType = {
|
||||
xxl: {
|
||||
breakpoint: { max: 9999, min: 1440 },
|
||||
items: 4.5,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
},
|
||||
lg: {
|
||||
breakpoint: { max: 1440, min: 1280 },
|
||||
items: 3.5,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
},
|
||||
desktop: {
|
||||
breakpoint: { max: 1280, min: 1024 },
|
||||
items: 2.5,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
},
|
||||
lap: {
|
||||
breakpoint: { max: 1024, min: 1008 },
|
||||
items: 3.5,
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 1008, min: 640 },
|
||||
items: 3,
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 640, min: 0 },
|
||||
items: 2,
|
||||
}
|
||||
};
|
||||
const ListProductWithInfo = ({ data, title, subtitle, hasBorderBottomMobile }: Props) => {
|
||||
return (
|
||||
<div className={classNames({
|
||||
@ -52,7 +81,7 @@ const ListProductWithInfo = ({ data, title, subtitle, hasBorderBottomMobile }: P
|
||||
data={data}
|
||||
Component={ProductCard}
|
||||
itemKey={title}
|
||||
option={OPTION_DEFAULT}
|
||||
responsive={RESPONSIVE}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { TOptionsEvents } from 'keen-slider'
|
||||
// import { TOptionsEvents } from 'keen-slider'
|
||||
import React from 'react'
|
||||
import CarouselCommon, {
|
||||
CarouselCommonProps,
|
||||
@ -8,38 +8,42 @@ import s from "./ProductCarousel.module.scss"
|
||||
|
||||
interface ProductCarouselProps
|
||||
extends Omit<CarouselCommonProps<ProductCardProps>, 'Component' | "option"> {
|
||||
option?: TOptionsEvents
|
||||
}
|
||||
|
||||
const OPTION_DEFAULT: TOptionsEvents = {
|
||||
slidesPerView: 2,
|
||||
mode: 'free',
|
||||
breakpoints: {
|
||||
'(min-width: 640px)': {
|
||||
slidesPerView: 3,
|
||||
},
|
||||
'(min-width: 768px)': {
|
||||
slidesPerView: 3,
|
||||
},
|
||||
'(min-width: 1008px)': {
|
||||
slidesPerView: 3.5,
|
||||
},
|
||||
'(min-width: 1280px)': {
|
||||
slidesPerView: 4.5,
|
||||
},
|
||||
'(min-width: 1440px)': {
|
||||
slidesPerView: 5.5,
|
||||
},
|
||||
const RESPONSIVE = {
|
||||
lgScreen: {
|
||||
breakpoint: { max:9999, min: 1440 },
|
||||
items: 5.5,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
},
|
||||
}
|
||||
const ProductCarousel = ({ option, data, ...props }: ProductCarouselProps) => {
|
||||
desktop: {
|
||||
breakpoint: { max: 1440, min: 1280 },
|
||||
items: 4.5,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
},
|
||||
lap: {
|
||||
breakpoint: { max: 1280, min: 1008 },
|
||||
items: 3.5,
|
||||
slidesToSlide: 1 // optional, default to 1.
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 1008, min: 640 },
|
||||
items: 3,
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 640, min: 0 },
|
||||
items: 2,
|
||||
}
|
||||
};
|
||||
const ProductCarousel = ({ data, responsive= RESPONSIVE, ...props }: ProductCarouselProps) => {
|
||||
return (
|
||||
<div className={s.productCardWarpper}>
|
||||
<CarouselCommon<ProductCardProps>
|
||||
data={data}
|
||||
Component={ProductCard}
|
||||
draggable={true} infinite={true}
|
||||
responsive={responsive}
|
||||
isPadding
|
||||
{...props}
|
||||
option={{ ...OPTION_DEFAULT, ...option }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,20 +1,19 @@
|
||||
import { TOptionsEvents } from 'keen-slider'
|
||||
import React from 'react'
|
||||
import { ResponsiveType } from 'react-multi-carousel'
|
||||
import CarouselCommon, {
|
||||
CarouselCommonProps,
|
||||
} from '../CarouselCommon/CarouselCommon'
|
||||
import RecipeCard, { RecipeCardProps } from '../RecipeCard/RecipeCard'
|
||||
import s from "./RecipeCarousel.module.scss"
|
||||
import s from './RecipeCarousel.module.scss'
|
||||
|
||||
interface RecipeCarouselProps
|
||||
extends Omit<CarouselCommonProps<RecipeCardProps>, 'Component'|"option"> {
|
||||
option?:TOptionsEvents
|
||||
}
|
||||
extends Omit<CarouselCommonProps<RecipeCardProps>, 'Component' | 'option'> {}
|
||||
|
||||
const OPTION_DEFAULT: TOptionsEvents = {
|
||||
slidesPerView: 1.25,
|
||||
mode: 'free',
|
||||
spacing:24,
|
||||
spacing: 24,
|
||||
breakpoints: {
|
||||
'(min-width: 640px)': {
|
||||
slidesPerView: 2,
|
||||
@ -30,14 +29,39 @@ const OPTION_DEFAULT: TOptionsEvents = {
|
||||
},
|
||||
},
|
||||
}
|
||||
const RecipeCarousel = ({ option, data, ...props }: RecipeCarouselProps) => {
|
||||
const RESPONSIVE: ResponsiveType = {
|
||||
largeDesktop: {
|
||||
breakpoint: { max: 9999, min: 1536 },
|
||||
items: 3.5,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
desktop: {
|
||||
breakpoint: { max: 1536, min: 1440 },
|
||||
items: 3,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
lap: {
|
||||
breakpoint: { max: 1440, min: 1024 },
|
||||
items: 2.5,
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 1024, min: 640 },
|
||||
items: 2,
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 640, min: 0 },
|
||||
items: 1.25,
|
||||
},
|
||||
}
|
||||
const RecipeCarousel = ({ data, ...props }: RecipeCarouselProps) => {
|
||||
return (
|
||||
<div className={s.recipeCardWarpper}>
|
||||
<CarouselCommon<RecipeCardProps>
|
||||
data={data}
|
||||
Component={RecipeCard}
|
||||
{...props}
|
||||
option={{ ...OPTION_DEFAULT, ...option }}
|
||||
// option={{ ...OPTION_DEFAULT, ...option }}
|
||||
responsive={RESPONSIVE}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,30 +1,35 @@
|
||||
import { TOptionsEvents } from 'keen-slider';
|
||||
import React from 'react';
|
||||
import { ResponsiveType } from 'react-multi-carousel';
|
||||
import { CarouselCommon, HeadingCommon, RecipeCard, ViewAllItem } from 'src/components/common';
|
||||
import { RecipeCardProps } from 'src/components/common/RecipeCard/RecipeCard';
|
||||
import { ROUTE } from 'src/utils/constanst.utils';
|
||||
import s from './RecommendedRecipes.module.scss';
|
||||
|
||||
const OPTION_DEFAULT: TOptionsEvents = {
|
||||
slidesPerView: 1.25,
|
||||
mode: 'free',
|
||||
spacing: 24,
|
||||
breakpoints: {
|
||||
'(min-width: 640px)': {
|
||||
slidesPerView: 2,
|
||||
},
|
||||
'(min-width: 1024px)': {
|
||||
slidesPerView: 2.5,
|
||||
},
|
||||
'(min-width: 1440px)': {
|
||||
slidesPerView: 3,
|
||||
},
|
||||
'(min-width: 1536px)': {
|
||||
slidesPerView: 3.5,
|
||||
},
|
||||
const RESPONSIVE: ResponsiveType = {
|
||||
largeDesktop: {
|
||||
breakpoint: { max: 9999, min: 1536 },
|
||||
items: 3.5,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
}
|
||||
|
||||
desktop: {
|
||||
breakpoint: { max: 1536, min: 1440 },
|
||||
items: 3,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
lap: {
|
||||
breakpoint: { max: 1440, min: 1024 },
|
||||
items: 2.5,
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 1024, min: 640 },
|
||||
items: 2,
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 640, min: 0 },
|
||||
items: 1.25,
|
||||
},
|
||||
}
|
||||
interface Props {
|
||||
data: RecipeCardProps[],
|
||||
}
|
||||
@ -41,7 +46,7 @@ const RecommendedRecipes = ({ data }: Props) => {
|
||||
data={data}
|
||||
Component={RecipeCard}
|
||||
itemKey="Recommended Recipes"
|
||||
option={OPTION_DEFAULT}
|
||||
responsive={RESPONSIVE}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,39 +5,44 @@ import CarouselCommon, {
|
||||
} from '../../CarouselCommon/CarouselCommon'
|
||||
import BlogCard, { BlogCardProps } from 'src/components/common/CardBlog/CardBlog'
|
||||
import s from "./BlogPostCarousel.module.scss"
|
||||
import { ResponsiveType } from 'react-multi-carousel'
|
||||
|
||||
interface BlogPostCarouselProps
|
||||
extends Omit<CarouselCommonProps<BlogCardProps>, 'Component'|"option"> {
|
||||
option?:TOptionsEvents
|
||||
}
|
||||
|
||||
const OPTION_DEFAULT: TOptionsEvents = {
|
||||
slidesPerView: 1.25,
|
||||
mode: 'free',
|
||||
spacing:24,
|
||||
breakpoints: {
|
||||
'(min-width: 640px)': {
|
||||
slidesPerView: 2,
|
||||
},
|
||||
'(min-width: 1024px)': {
|
||||
slidesPerView: 2.5,
|
||||
},
|
||||
'(min-width: 1440px)': {
|
||||
slidesPerView: 3,
|
||||
},
|
||||
'(min-width: 1536px)': {
|
||||
slidesPerView: 3.5,
|
||||
},
|
||||
|
||||
const RESPONSIVE: ResponsiveType = {
|
||||
largeDesktop: {
|
||||
breakpoint: { max: 9999, min: 1536 },
|
||||
items: 3.5,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
desktop: {
|
||||
breakpoint: { max: 1536, min: 1440 },
|
||||
items: 3,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
lap: {
|
||||
breakpoint: { max: 1440, min: 1024 },
|
||||
items: 2.5,
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 1024, min: 640 },
|
||||
items: 2,
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 640, min: 0 },
|
||||
items: 1.25,
|
||||
},
|
||||
}
|
||||
const BlogPostCarousel = ({ option, data, ...props }: BlogPostCarouselProps) => {
|
||||
const BlogPostCarousel = ({ data, ...props }: BlogPostCarouselProps) => {
|
||||
return (
|
||||
<div className={s.blogCardWarpper}>
|
||||
<CarouselCommon<BlogCardProps>
|
||||
data={data}
|
||||
Component={BlogCard}
|
||||
{...props}
|
||||
option={{ ...OPTION_DEFAULT, ...option }}
|
||||
responsive={RESPONSIVE}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { TOptionsEvents } from 'keen-slider'
|
||||
import React from 'react'
|
||||
import { ResponsiveType } from 'react-multi-carousel'
|
||||
import { CarouselCommon, FeaturedProductCard } from 'src/components/common'
|
||||
import { FeaturedProductCardProps } from 'src/components/common/FeaturedProductCard/FeaturedProductCard'
|
||||
import s from "./FeaturedProductsCarousel.module.scss"
|
||||
@ -57,11 +58,57 @@ const OPTION_DEFAULT: TOptionsEvents = {
|
||||
},
|
||||
},
|
||||
}
|
||||
const RESPONSIVE: ResponsiveType = {
|
||||
largeScreen: {
|
||||
breakpoint: { max: 9999, min: 1440 },
|
||||
items: 2.075,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
largeDesktop: {
|
||||
breakpoint: { max: 1440, min: 1280 },
|
||||
items: 1.75,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
desktop: {
|
||||
breakpoint: { max: 1280, min: 1148 },
|
||||
items: 1.5,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
smallDesktop: {
|
||||
breakpoint: { max: 1148, min: 1024 },
|
||||
items: 1.375,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
lap: {
|
||||
breakpoint: { max: 1024, min: 968 },
|
||||
items: 1.75,
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 968, min: 768 },
|
||||
items: 1.075,
|
||||
},
|
||||
smallTablet: {
|
||||
breakpoint: { max: 768, min: 640 },
|
||||
items: 1.25,
|
||||
},
|
||||
largeMobile: {
|
||||
breakpoint: { max: 640, min: 400 },
|
||||
items: 2,
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 400, min: 300 },
|
||||
items: 1.5,
|
||||
},
|
||||
smallMobile: {
|
||||
breakpoint: { max: 300, min: 0 },
|
||||
items: 1,
|
||||
},
|
||||
}
|
||||
|
||||
const FeaturedProductsCarousel = ({}: FeaturedProductsCarouselProps) => {
|
||||
return (
|
||||
<div className={s.warpper}>
|
||||
<CarouselCommon<FeaturedProductCardProps> data={dataDemo} Component={FeaturedProductCard} itemKey="featured-products" option={OPTION_DEFAULT}/>
|
||||
<CarouselCommon<FeaturedProductCardProps> data={dataDemo} Component={FeaturedProductCard} itemKey="featured-products" responsive={RESPONSIVE}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ import { TOptionsEvents } from 'keen-slider'
|
||||
|
||||
import HomeFeatureItem, {HomeFeatureItemProps} from '../HomeFeatureItem/HomeFeatureItem'
|
||||
import CarouselCommon, {CarouselCommonProps} from '../../../../../common/CarouselCommon/CarouselCommon'
|
||||
import { ResponsiveType } from 'react-multi-carousel'
|
||||
|
||||
interface HomeFeatureCarouselProps
|
||||
extends Omit<CarouselCommonProps<HomeFeatureItemProps>, 'Component' | "option"> {
|
||||
option?: TOptionsEvents
|
||||
}
|
||||
|
||||
const OPTION_DEFAULT: TOptionsEvents = {
|
||||
@ -30,15 +30,43 @@ const OPTION_DEFAULT: TOptionsEvents = {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const HomeFeatureCarousel = ({option, data, ...props} : HomeFeatureCarouselProps) => {
|
||||
const RESPONSIVE: ResponsiveType = {
|
||||
largeDesktop: {
|
||||
breakpoint: { max: 9999, min: 1440 },
|
||||
items: 3,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
desktop: {
|
||||
breakpoint: { max: 1440, min: 1280 },
|
||||
items: 2.8,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
smallDesktop: {
|
||||
breakpoint: { max: 1280, min: 1008 },
|
||||
items: 2.3,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
lap: {
|
||||
breakpoint: { max: 1008, min: 768 },
|
||||
items: 2.1,
|
||||
},
|
||||
tablet: {
|
||||
breakpoint: { max: 768, min: 640 },
|
||||
items: 1.8,
|
||||
},
|
||||
mobile: {
|
||||
breakpoint: { max: 640, min: 0 },
|
||||
items: 1.2,
|
||||
},
|
||||
}
|
||||
const HomeFeatureCarousel = ({data, ...props} : HomeFeatureCarouselProps) => {
|
||||
return (
|
||||
<div>
|
||||
<CarouselCommon<HomeFeatureItemProps>
|
||||
data={data}
|
||||
Component={HomeFeatureItem}
|
||||
{...props}
|
||||
option={{ ...OPTION_DEFAULT, ...option }}
|
||||
responsive={RESPONSIVE}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react'
|
||||
import { ResponsiveType } from 'react-multi-carousel'
|
||||
import { CarouselCommon } from 'src/components/common'
|
||||
import ProductImgItem, { ProductImgItemProps } from '../ProductImgItem/ProductImgItem'
|
||||
import s from './ProductImgs.module.scss'
|
||||
@ -23,10 +24,13 @@ const DATA = [
|
||||
}
|
||||
]
|
||||
|
||||
const option = {
|
||||
slidesPerView: 1,
|
||||
}
|
||||
|
||||
const RESPONSIVE: ResponsiveType = {
|
||||
desktop: {
|
||||
breakpoint: { max: 999, min: 0 },
|
||||
items: 1,
|
||||
slidesToSlide: 1, // optional, default to 1.
|
||||
},
|
||||
}
|
||||
const ProductImgs = ({ }: Props) => {
|
||||
return (
|
||||
<section className={s.productImgs}>
|
||||
@ -34,8 +38,8 @@ const ProductImgs = ({ }: Props) => {
|
||||
data={DATA}
|
||||
itemKey="product-detail-img"
|
||||
Component={ProductImgItem}
|
||||
option={option}
|
||||
isDot={true}
|
||||
responsive={RESPONSIVE}
|
||||
showDots={true}
|
||||
/>
|
||||
</section >
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user