add more breakpoints to carousel

This commit is contained in:
jeffvli
2025-11-22 14:22:05 -08:00
parent 2b70adc1f6
commit 958ded6988
3 changed files with 87 additions and 64 deletions
@@ -16,14 +16,12 @@
min-height: 400px;
padding: var(--theme-spacing-xl);
overflow: hidden;
--items-per-row: 1;
}
.carousel-item {
position: relative;
width: 100%;
min-height: 400px;
min-height: 440px;
overflow: hidden;
border-radius: var(--theme-radius-md);
isolation: isolate;
@@ -51,7 +49,7 @@
justify-content: flex-start;
width: 100%;
height: 100%;
min-height: 400px;
min-height: 440px;
padding: var(--theme-spacing-xl);
}
@@ -73,9 +71,9 @@
align-items: center;
justify-content: center;
width: 100%;
height: 200px;
min-height: 200px;
max-height: 200px;
height: 250px;
min-height: 250px;
max-height: 250px;
}
.metadata-section {
@@ -170,25 +168,49 @@
transform: translateY(-50%) scale(0.95);
}
@container (min-width: 640px) {
.carousel {
--items-per-row: 1;
@container (min-width: $mantine-breakpoint-xs) {
.carousel-item {
min-height: 480px;
}
.content {
min-height: 480px;
}
.title-section {
height: 60px;
min-height: 60px;
max-height: 60px;
}
.image-section {
height: 300px;
min-height: 300px;
max-height: 300px;
}
.metadata-section {
height: 80px;
min-height: 80px;
max-height: 80px;
}
.album-image {
max-width: 160px;
}
}
@container (min-width: $mantine-breakpoint-sm) {
.carousel {
--items-per-row: 3;
gap: var(--theme-spacing-lg);
}
.carousel-item {
min-height: 450px;
min-height: 500px;
}
.content {
min-height: 450px;
min-height: 500px;
}
.title-section {
@@ -198,9 +220,9 @@
}
.image-section {
height: 220px;
min-height: 220px;
max-height: 220px;
height: 280px;
min-height: 280px;
max-height: 280px;
}
.metadata-section {
@@ -215,16 +237,12 @@
}
@container (min-width: $mantine-breakpoint-md) {
.carousel {
--items-per-row: 4;
}
.carousel-item {
min-height: 500px;
min-height: 550px;
}
.content {
min-height: 500px;
min-height: 550px;
}
.title-section {
@@ -234,9 +252,9 @@
}
.image-section {
height: 250px;
min-height: 250px;
max-height: 250px;
height: 320px;
min-height: 320px;
max-height: 320px;
}
.metadata-section {
@@ -251,16 +269,12 @@
}
@container (min-width: $mantine-breakpoint-xl) {
.carousel {
--items-per-row: 5;
}
.carousel-item {
min-height: 550px;
min-height: 600px;
}
.content {
min-height: 550px;
min-height: 600px;
}
.title-section {
@@ -270,9 +284,9 @@
}
.image-section {
height: 280px;
min-height: 280px;
max-height: 280px;
height: 360px;
min-height: 360px;
max-height: 360px;
}
.metadata-section {
@@ -45,16 +45,19 @@ interface FeatureCarouselProps {
const getItemsPerRow = (breakpoints: {
is2xl: boolean;
is3xl: boolean;
isLg: boolean;
isMd: boolean;
isSm: boolean;
isXl: boolean;
}) => {
if (breakpoints.is3xl) return 6;
if (breakpoints.is2xl) return 5;
if (breakpoints.isXl) return 5;
if (breakpoints.isLg) return 4;
if (breakpoints.isMd) return 3;
return 1;
if (breakpoints.isSm) return 2;
return 2;
};
interface CarouselItemProps {
@@ -143,6 +146,7 @@ export const FeatureCarousel = ({ data }: FeatureCarouselProps) => {
const [startIndex, setStartIndex] = useState(0);
const {
is2xl,
is3xl,
isLg,
isMd,
isSm,
@@ -150,6 +154,7 @@ export const FeatureCarousel = ({ data }: FeatureCarouselProps) => {
ref: containerRef,
} = useContainerQuery({
'2xl': 1920,
'3xl': 2560,
lg: 1024,
md: 768,
sm: 640,
@@ -157,8 +162,8 @@ export const FeatureCarousel = ({ data }: FeatureCarouselProps) => {
});
const itemsPerRow = useMemo(
() => getItemsPerRow({ is2xl, isLg, isMd, isSm, isXl }),
[is2xl, isLg, isMd, isSm, isXl],
() => getItemsPerRow({ is2xl, is3xl, isLg, isMd, isSm, isXl }),
[is2xl, is3xl, isLg, isMd, isSm, isXl],
);
const visibleItems = useMemo(() => {
@@ -198,6 +203,7 @@ export const FeatureCarousel = ({ data }: FeatureCarouselProps) => {
exit="exit"
initial="enter"
key={`carousel-${startIndex}`}
style={{ '--items-per-row': itemsPerRow } as React.CSSProperties}
variants={fadeVariants}
>
{visibleItems.map((album) => (
@@ -7,6 +7,7 @@ import { NativeScrollArea } from '/@/renderer/components/native-scroll-area/nati
import { albumQueries } from '/@/renderer/features/albums/api/album-api';
import { AlbumInfiniteCarousel } from '/@/renderer/features/albums/components/album-infinite-carousel';
import { AnimatedPage } from '/@/renderer/features/shared/components/animated-page';
import { LibraryContainer } from '/@/renderer/features/shared/components/library-container';
import { LibraryHeaderBar } from '/@/renderer/features/shared/components/library-header-bar';
import {
HomeItem,
@@ -115,34 +116,36 @@ const HomeRoute = () => {
}}
ref={scrollAreaRef}
>
<Stack
gap="lg"
mb="5rem"
pt={windowBarStyle === Platform.WEB ? '5rem' : '3rem'}
px="2rem"
>
{homeFeature && <FeatureCarousel data={featureItemsWithImage} />}
{sortedCarousel.map((carousel) => {
if (carousel.itemType === LibraryItem.ALBUM) {
return (
<AlbumInfiniteCarousel
key={`carousel-${carousel.uniqueId}`}
rowCount={1}
sortBy={carousel.sortBy}
sortOrder={carousel.sortOrder}
title={carousel.title}
/>
);
}
<LibraryContainer>
<Stack
gap="lg"
mb="5rem"
pt={windowBarStyle === Platform.WEB ? '5rem' : '3rem'}
px="2rem"
>
{homeFeature && <FeatureCarousel data={featureItemsWithImage} />}
{sortedCarousel.map((carousel) => {
if (carousel.itemType === LibraryItem.ALBUM) {
return (
<AlbumInfiniteCarousel
key={`carousel-${carousel.uniqueId}`}
rowCount={1}
sortBy={carousel.sortBy}
sortOrder={carousel.sortOrder}
title={carousel.title}
/>
);
}
if ('data' in carousel && 'query' in carousel) {
// TODO: Create SongInfiniteCarousel
return null;
}
if ('data' in carousel && 'query' in carousel) {
// TODO: Create SongInfiniteCarousel
return null;
}
return null;
})}
</Stack>
})}
</Stack>
</LibraryContainer>
</NativeScrollArea>
</AnimatedPage>
);