Merged in refactor/SW-1669-carousel-cards-shadow (pull request #1370)

Refactor(SW-1669): Carousel Cards Enhancements

* feat(SW-1669): Enhance Filters component with scroll shadows and heart icon

* feat(SW-1669): Carousel peek next card

* fix(SW-1669): carousel review comments

* feat(SW-1669): Add left scroll shadow to TabFilters component

* refactor(SW-1669): Simplify TabFilters shadow styling

* refactor(SW-1669): Adjust TabFilters shadow width

* refactor(SW-1699): Remove unused import from enter details store


Approved-by: Christian Andolf
This commit is contained in:
Chuma Mcphoy (We Ahead)
2025-02-19 12:46:22 +00:00
parent 59eefb877e
commit b6bf1b3ded
6 changed files with 80 additions and 24 deletions

View File

@@ -9,7 +9,7 @@
.container { .container {
display: grid; display: grid;
grid-auto-flow: column; grid-auto-flow: column;
grid-auto-columns: 100%; grid-auto-columns: 85%;
gap: var(--Spacing-x2); gap: var(--Spacing-x2);
} }

View File

@@ -23,8 +23,9 @@ function Carousel({
}: CarouselProps) { }: CarouselProps) {
const [carouselRef, api] = useEmblaCarousel( const [carouselRef, api] = useEmblaCarousel(
{ {
...opts, containScroll: "trimSnaps",
axis: "x", axis: "x",
...opts,
}, },
plugins plugins
) )

View File

@@ -48,9 +48,3 @@
padding: var(--Spacing-x2) var(--Spacing-x2) var(--Spacing-x2) 0; padding: var(--Spacing-x2) var(--Spacing-x2) var(--Spacing-x2) 0;
} }
} }
@media (max-width: 767px) {
.card {
min-width: 300px;
}
}

View File

@@ -5,7 +5,6 @@ import { useIntl } from "react-intl"
import { useEnterDetailsStore } from "@/stores/enter-details" import { useEnterDetailsStore } from "@/stores/enter-details"
import { import {
selectBookingProgress, selectBookingProgress,
selectNextStep,
selectRoom, selectRoom,
selectRoomStatus, selectRoomStatus,
} from "@/stores/enter-details/helpers" } from "@/stores/enter-details/helpers"

View File

@@ -1,5 +1,10 @@
"use client" "use client"
import { cx } from "class-variance-authority"
import { HeartIcon } from "@/components/Icons"
import useScrollShadows from "@/hooks/useScrollShadows"
import styles from "./tabFilters.module.css" import styles from "./tabFilters.module.css"
import type { CardGalleryFilter } from "@/types/enums/cardGallery" import type { CardGalleryFilter } from "@/types/enums/cardGallery"
@@ -21,22 +26,36 @@ export default function TabFilters({
selectedFilter, selectedFilter,
onFilterSelect, onFilterSelect,
}: TabFiltersProps) { }: TabFiltersProps) {
const { containerRef, showLeftShadow, showRightShadow } =
useScrollShadows<HTMLDivElement>()
return ( return (
<div className={styles.container}> <div
{categories.map((category) => ( className={cx(
<button styles.containerWrapper,
key={category.identifier} showLeftShadow && styles.showLeftShadow,
onClick={() => onFilterSelect(category.identifier)} showRightShadow && styles.showRightShadow
className={ )}
selectedFilter === category.identifier >
? styles.filterSelected <div className={styles.container} ref={containerRef}>
: styles.filter {categories.map((category) => (
} <button
type="button" key={category.identifier}
> onClick={() => onFilterSelect(category.identifier)}
{category.label} className={
</button> selectedFilter === category.identifier
))} ? styles.filterSelected
: styles.filter
}
type="button"
>
<HeartIcon
color={selectedFilter === category.identifier ? "white" : "black"}
/>
{category.label}
</button>
))}
</div>
</div> </div>
) )
} }

View File

@@ -1,9 +1,49 @@
.containerWrapper {
position: relative;
overflow: hidden;
}
.container { .container {
display: flex; display: flex;
gap: var(--Spacing-x1); gap: var(--Spacing-x1);
overflow-x: auto; overflow-x: auto;
scroll-snap-type: x mandatory; scroll-snap-type: x mandatory;
scrollbar-width: none; scrollbar-width: none;
position: relative;
width: 100%;
}
.containerWrapper::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
width: var(--Spacing-x3);
pointer-events: none;
z-index: 1;
opacity: 0;
transition: opacity 0.3s ease;
right: 0;
background: linear-gradient(90deg, rgba(255, 255, 255, 0.1) 6%, #fff 90%);
}
.containerWrapper::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
width: var(--Spacing-x3);
pointer-events: none;
z-index: 1;
opacity: 0;
transition: opacity 0.3s ease;
left: 0;
background: linear-gradient(-90deg, rgba(255, 255, 255, 0.1) 6%, #fff 90%);
}
.showLeftShadow::before,
.showRightShadow::after {
opacity: 1;
} }
.filter, .filter,
@@ -17,6 +57,9 @@
font-family: var(--typography-Body-Regular-fontFamily); font-family: var(--typography-Body-Regular-fontFamily);
font-weight: 400; font-weight: 400;
cursor: pointer; cursor: pointer;
display: flex;
align-items: center;
gap: var(--Spacing-x1);
} }
.filter { .filter {