mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
New Release (#371)
* Custom Checkout Progress * Updates to Checkout * Custom Checkout Progress * Adding tabs * Adding Collapse * Adding Collapse * Improving Sidebar Scroll * Modif footer * Changes * More design updates * sidebar cart * More design updates * More design updates * More design updates * More design updates * Types * Types * Design Updates * More changes * More changes * More changes * Changes * Changes * Changes * New tailwind required changes * Sidebar Styling issues with Mobile * Latest changes - Normalizing cart * Styling Fixes * New changes * Changes * latest * Refactor and Renaming some UI Props * Adding Quantity Component * Adding Rating Component * Rating Component * More updates * User Select disabled, plus hidding horizontal scroll bars * Changes * Adding ProductOptions Component and more helpers * Styling updates * Styling updates * Fix for slim tags * Missmatch with RightArrow * Footer updates and some styles * Latest Updates * Latest Updates * Latest Updates * Removing Portal, since it's not needed. We might add it later I'd rather not to. * Removing Portal, since it's not needed. We might add it later I'd rather not to. * Sam backdrop filter * General UI Improvements * General UI Improvements * Search now with Geist Colors * Now with Geist Colors * Changes * Scroll for Mobile on IOs devises * LoadingDots Working (: * Changes * More Changes * Perf changes * More perf changes * Fade to the Nametags in the ProductCard * changes * Search issue ui * Search issue ui * Make sure to only refresh navbar and modals when required * Index revalidate * Fixed image issue * hide album scroll on windows * Fix scrollbar * Changing * Adding 404 with Layout * Removing Toast * Adding Assets * Adding Assets * Progress with LocalProvider * New productTag * Only images for the drop * changes * Empty SWRhooks * Adding Local Provider * Working local * Working view of a LocalProvider * More updates * Changes * Removed react-ticker * default to local if no env available * default to local if no env available * add missing `@` to css import * rewrite search rewrites to multiple pages * allow requests in getStaticProps to execute in parallel * make type import explicit * add a tsconfig.js file * use local provider in tsconfig.js * avoid a circular dependency * Saleor was not in the providers list * avoid circular dependency in bigcommerce * Adding more to the Local Provider (#366) * Adding more data * Adding more data * optimize assets (#370) * Optimize assets (#372) * optimize assets * remove assets * remove assets * cart enabled * Adding saleor * Changes with Webpack * Changes Co-authored-by: Luis Alvarez <luis@vercel.com> Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com> Co-authored-by: Shu Ding <g@shud.in>
This commit is contained in:
@@ -1,82 +1,64 @@
|
||||
.root {
|
||||
@apply relative w-full h-full;
|
||||
@apply relative w-full h-full select-none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.slider {
|
||||
@apply relative h-full transition-opacity duration-150;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slider.show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.thumb {
|
||||
@apply transition-transform transition-colors
|
||||
ease-linear duration-75 overflow-hidden inline-block
|
||||
cursor-pointer h-full;
|
||||
width: 125px;
|
||||
width: calc(100% / 3);
|
||||
}
|
||||
|
||||
.thumb.selected {
|
||||
@apply bg-white;
|
||||
}
|
||||
|
||||
.thumb img {
|
||||
height: 85% !important;
|
||||
}
|
||||
|
||||
.album {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@apply bg-violet-dark;
|
||||
box-sizing: content-box;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
height: 125px;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.leftControl,
|
||||
.rightControl {
|
||||
@apply absolute top-1/2 -translate-x-1/2 z-20 w-16 h-16 flex items-center justify-center bg-hover-1 rounded-full;
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.album::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leftControl:hover,
|
||||
.rightControl:hover {
|
||||
@apply bg-hover-2;
|
||||
}
|
||||
@screen md {
|
||||
.thumb:hover {
|
||||
transform: scale(1.02);
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.leftControl:hover,
|
||||
.rightControl:hover {
|
||||
@apply outline-none shadow-outline-normal;
|
||||
}
|
||||
.thumb.selected {
|
||||
@apply bg-white;
|
||||
}
|
||||
|
||||
.leftControl {
|
||||
@apply bg-cover left-10;
|
||||
background-image: url('public/cursor-left.png');
|
||||
|
||||
@screen md {
|
||||
@apply left-6;
|
||||
.album {
|
||||
height: 182px;
|
||||
}
|
||||
.thumb {
|
||||
width: 235px;
|
||||
}
|
||||
}
|
||||
|
||||
.rightControl {
|
||||
@apply bg-cover right-10;
|
||||
background-image: url('public/cursor-right.png');
|
||||
|
||||
@screen md {
|
||||
@apply right-6;
|
||||
}
|
||||
}
|
||||
|
||||
.control {
|
||||
@apply opacity-0 transition duration-150;
|
||||
}
|
||||
|
||||
.root:hover .control {
|
||||
@apply opacity-100;
|
||||
}
|
||||
|
||||
.positionIndicatorsContainer {
|
||||
@apply hidden;
|
||||
|
||||
@screen sm {
|
||||
@apply block absolute bottom-6 left-1/2;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.positionIndicator {
|
||||
@apply rounded-full p-2;
|
||||
}
|
||||
|
||||
.dot {
|
||||
@apply bg-hover-1 transition w-3 h-3 rounded-full;
|
||||
}
|
||||
|
||||
.positionIndicator:hover .dot {
|
||||
@apply bg-hover-2;
|
||||
}
|
||||
|
||||
.positionIndicator:focus {
|
||||
@apply outline-none;
|
||||
}
|
||||
|
||||
.positionIndicator:focus .dot {
|
||||
@apply shadow-outline-normal;
|
||||
}
|
||||
|
||||
.positionIndicatorActive .dot {
|
||||
@apply bg-white;
|
||||
}
|
||||
|
||||
.positionIndicatorActive:hover .dot {
|
||||
@apply bg-white;
|
||||
}
|
||||
|
@@ -8,20 +8,42 @@ import React, {
|
||||
useEffect,
|
||||
} from 'react'
|
||||
import cn from 'classnames'
|
||||
|
||||
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)
|
||||
const thumbsContainerRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const [ref, slider] = useKeenSlider<HTMLDivElement>({
|
||||
loop: true,
|
||||
slidesPerView: 1,
|
||||
mounted: () => setIsMounted(true),
|
||||
slideChanged(s) {
|
||||
setCurrentSlide(s.details().relativeSlide)
|
||||
const slideNumber = s.details().relativeSlide
|
||||
setCurrentSlide(slideNumber)
|
||||
|
||||
if (thumbsContainerRef.current) {
|
||||
const $el = document.getElementById(
|
||||
`thumb-${s.details().relativeSlide}`
|
||||
)
|
||||
if (slideNumber >= 3) {
|
||||
thumbsContainerRef.current.scrollLeft = $el!.offsetLeft
|
||||
} else {
|
||||
thumbsContainerRef.current.scrollLeft = 0
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -59,23 +81,16 @@ const ProductSlider: FC = ({ children }) => {
|
||||
}
|
||||
}, [])
|
||||
|
||||
const onPrev = React.useCallback(() => slider.prev(), [slider])
|
||||
const onNext = React.useCallback(() => slider.next(), [slider])
|
||||
|
||||
return (
|
||||
<div className={s.root} ref={sliderContainerRef}>
|
||||
<button
|
||||
className={cn(s.leftControl, s.control)}
|
||||
onClick={slider?.prev}
|
||||
aria-label="Previous Product Image"
|
||||
/>
|
||||
<button
|
||||
className={cn(s.rightControl, s.control)}
|
||||
onClick={slider?.next}
|
||||
aria-label="Next Product Image"
|
||||
/>
|
||||
<div className={cn(s.root, className)} ref={sliderContainerRef}>
|
||||
<div
|
||||
ref={ref}
|
||||
className="keen-slider h-full transition-opacity duration-150"
|
||||
style={{ opacity: isMounted ? 1 : 0 }}
|
||||
className={cn(s.slider, { [s.show]: isMounted }, 'keen-slider')}
|
||||
>
|
||||
{slider && <ProductSliderControl onPrev={onPrev} onNext={onNext} />}
|
||||
{Children.map(children, (child) => {
|
||||
// Add the keen-slider__slide className to children
|
||||
if (isValidElement(child)) {
|
||||
@@ -92,26 +107,28 @@ const ProductSlider: FC = ({ children }) => {
|
||||
return child
|
||||
})}
|
||||
</div>
|
||||
{slider && (
|
||||
<div className={cn(s.positionIndicatorsContainer)}>
|
||||
{[...Array(slider.details().size).keys()].map((idx) => {
|
||||
return (
|
||||
<button
|
||||
aria-label="Position indicator"
|
||||
key={idx}
|
||||
className={cn(s.positionIndicator, {
|
||||
[s.positionIndicatorActive]: currentSlide === idx,
|
||||
})}
|
||||
onClick={() => {
|
||||
slider.moveToSlideRelative(idx)
|
||||
}}
|
||||
>
|
||||
<div className={s.dot} />
|
||||
</button>
|
||||
)
|
||||
|
||||
<a.div className={s.album} ref={thumbsContainerRef}>
|
||||
{slider &&
|
||||
Children.map(children, (child, idx) => {
|
||||
if (isValidElement(child)) {
|
||||
return {
|
||||
...child,
|
||||
props: {
|
||||
...child.props,
|
||||
className: cn(child.props.className, s.thumb, {
|
||||
[s.selected]: currentSlide === idx,
|
||||
}),
|
||||
id: `thumb-${idx}`,
|
||||
onClick: () => {
|
||||
slider.moveToSlideRelative(idx)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return child
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</a.div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user