Skip to content

Commit 17712bd

Browse files
committed
fix: ui in carousels
1 parent a3bd94f commit 17712bd

12 files changed

Lines changed: 142 additions & 86 deletions

File tree

10.5 KB
Binary file not shown.
5.88 KB
Binary file not shown.
19 KB
Binary file not shown.
41.5 KB
Binary file not shown.

apps/herbatika/src/components/blog/inline-products-carousel.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ function InlineProductsSlides({
4444
{hasOverflow ? (
4545
<>
4646
<Carousel.Previous
47-
className="-translate-y-1/2 absolute top-1/2 left-100 rounded-full aspect-square text-lg shadow-md"
47+
className="-translate-y-1/2 absolute top-1/2 left-100 rounded-full aspect-square text-lg shadow-carousel-trigger active:text-carousel-trigger-fg-active"
4848
/>
4949
<Carousel.Next
50-
className="-translate-y-1/2 absolute top-1/2 right-100 rounded-full aspect-square text-lg shadow-md"
50+
className="-translate-y-1/2 absolute top-1/2 right-100 rounded-full aspect-square text-lg shadow-carousel-trigger active:text-carousel-trigger-fg-active"
5151
/>
5252
</>
5353
) : null}

apps/herbatika/src/components/homepage/homepage.data.types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import type { IconType } from "@techsio/ui-kit/atoms/icon";
22

33
export type HeroBannerItem = {
44
id: string;
5-
title: string;
6-
subtitle: string;
7-
badge: string;
5+
title?: string;
6+
subtitle?: string;
7+
badge?: string;
88
href: string;
99
imageSrc: string;
1010
};

apps/herbatika/src/components/homepage/homepage.hero.data.ts

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,39 @@
11
import type { HeroBannerItem } from "./homepage.data.types";
2+
import firstCarouselSlide from "@/assets/homepage-carousel/first.avif";
3+
import secondCarouselSlide from "@/assets/homepage-carousel/second.avif";
4+
import thirdCarouselSlide from "@/assets/homepage-carousel/third.avif";
5+
import fourthCarouselSlide from "@/assets/homepage-carousel/fourth.avif";
6+
27

38
export const HERO_BANNERS: HeroBannerItem[] = [
49
{
5-
id: "hero-immune",
6-
title: "Silná imunita počas celého roka",
7-
subtitle: "Bylinné extrakty, vitamíny a minerály pre každý deň.",
8-
badge: "Imunita",
10+
id: "rychle-dodanie",
11+
title: "Rýchle doručenie 24h!",
12+
subtitle: "Rýchle dodanie a balenie",
13+
badge: "Rýchle dodanie",
914
href: "/c/trapi-ma",
10-
imageSrc:
11-
"https://images.unsplash.com/photo-1505751172876-fa1923c5c528?auto=format&fit=crop&w=900&q=80",
15+
imageSrc: firstCarouselSlide.src,
1216
},
1317
{
14-
id: "hero-cosmetics",
15-
title: "Prírodná kozmetika bez kompromisov",
16-
subtitle: "Objavte jemnú starostlivosť o pleť a telo.",
18+
id: "black-friday",
1719
badge: "Kozmetika",
18-
href: "/c/prirodna-kozmetika",
19-
imageSrc:
20-
"https://images.unsplash.com/photo-1571875257727-256c39da42af?auto=format&fit=crop&w=900&q=80",
20+
href: "/c/vypredaj-zlavy-a-akcie",
21+
imageSrc: secondCarouselSlide.src,
2122
},
2223
{
23-
id: "hero-tea",
24-
title: "Bylinky a čaje pre pokojný deň",
25-
subtitle: "Vyberte si z overených kombinácií od Herbatica.",
26-
badge: "Bylinky",
27-
href: "/c/potraviny-a-napoje",
28-
imageSrc:
29-
"https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?auto=format&fit=crop&w=900&q=80",
24+
id: "nova-prevadzka",
25+
title: "Otvárame pre vás novú prevádzku",
26+
badge: "Nová prevádzka",
27+
href: "/c/novinky",
28+
imageSrc: thirdCarouselSlide.src,
3029
},
3130
{
32-
id: "hero-supplements",
33-
title: "Doplnky výživy pre vitalitu",
34-
subtitle: "Kapsuly, tinktúry aj funkčné zmesi na mieru.",
35-
badge: "Doplnky",
36-
href: "/c/doplnky-vyzivy",
37-
imageSrc:
38-
"https://images.unsplash.com/photo-1506126613408-eca07ce68773?auto=format&fit=crop&w=900&q=80",
31+
id: "rychle-dodanie-2",
32+
title: "Rýchle doručenie 24h!",
33+
subtitle: "Rýchle dodanie a balenie",
34+
badge: "Rýchle dodanie",
35+
href: "/c/trapi-ma",
36+
imageSrc: fourthCarouselSlide.src,
3937
},
4038
{
4139
id: "hero-home",
Lines changed: 99 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,50 @@
11
import Image from "next/image";
2-
import { Badge } from "@techsio/ui-kit/atoms/badge";
3-
import { Link } from "@techsio/ui-kit/atoms/link";
42
import {
53
Carousel,
64
type CarouselSlide,
75
} from "@techsio/ui-kit/molecules/carousel";
86
import NextLink from "next/link";
97
import { useMemo } from "react";
10-
import { HERO_PAGE_SIZE, type HeroBannerItem } from "@/components/homepage/homepage.data";
8+
import {
9+
HERO_PAGE_SIZE,
10+
type HeroBannerItem,
11+
} from "@/components/homepage/homepage.data";
12+
import { Button } from "@techsio/ui-kit/atoms/button";
13+
14+
const HERO_CTA_LABEL = "Zistiť viac";
15+
const HERO_DESKTOP_SLIDES_PER_PAGE = 4.1;
16+
const HERO_DESKTOP_SLIDE_SPACING = "var(--spacing-400)";
17+
18+
function HeroBannerCard({ banner }: { banner: HeroBannerItem }) {
19+
return (
20+
<NextLink
21+
aria-label={`${banner.title} - ${HERO_CTA_LABEL}`}
22+
className="group relative h-full overflow-hidden rounded-lg bg-fg-primary shadow-sm font-open-sans"
23+
href={banner.href}
24+
>
25+
<Image
26+
alt={banner.id}
27+
className="object-cover transition-transform duration-500 group-hover:scale-105"
28+
fill
29+
src={banner.imageSrc}
30+
/>
31+
<div className="absolute inset-0 bg-gradient-to-t from-fg-primary/85 via-fg-primary/35 to-transparent" />
32+
{ banner.title && <div className="absolute inset-x-0 bottom-0 flex flex-col items-start p-600 text-fg-reverse">
33+
<p className="line-clamp-2 text-2xl leading-[26px] font-bold">
34+
{banner.title}
35+
</p>
36+
{banner.subtitle && (
37+
<p className="line-clamp-2 text-md leading-snug font-semibold text-fg-reverse">
38+
{banner.subtitle}
39+
</p>
40+
)}
41+
<Button size="md" className="mt-350 rounded-xl py-250 px-450 text-md">
42+
{HERO_CTA_LABEL}
43+
</Button>
44+
</div>}
45+
</NextLink>
46+
);
47+
}
1148

1249
const buildHeroSlides = (banners: HeroBannerItem[]): CarouselSlide[] => {
1350
const slides: CarouselSlide[] = [];
@@ -19,35 +56,9 @@ const buildHeroSlides = (banners: HeroBannerItem[]): CarouselSlide[] => {
1956
slides.push({
2057
id: `hero-page-${pageIndex}`,
2158
content: (
22-
<div className="grid h-full w-full grid-cols-2 gap-300 lg:grid-cols-4">
59+
<div className="grid h-full w-full grid-cols-2 gap-400 lg:grid-cols-4">
2360
{page.map((banner) => (
24-
<NextLink
25-
className="group relative h-full overflow-hidden rounded-2xl border border-border-secondary"
26-
href={banner.href}
27-
key={banner.id}
28-
>
29-
<Image
30-
alt={banner.title}
31-
fill
32-
className="object-cover transition-transform duration-300 group-hover:scale-105"
33-
src={banner.imageSrc}
34-
/>
35-
<div className="absolute inset-0 bg-gradient-to-t from-fg-primary/70 via-fg-primary/20 to-transparent" />
36-
<div className="absolute inset-x-0 bottom-0 p-300 text-fg-reverse">
37-
<Badge
38-
className="mb-100 rounded-full px-200 py-50 text-2xs font-semibold uppercase"
39-
variant="secondary"
40-
>
41-
{banner.badge}
42-
</Badge>
43-
<p className="line-clamp-2 text-sm leading-tight font-bold">
44-
{banner.title}
45-
</p>
46-
<p className="line-clamp-2 text-xs text-fg-reverse/85">
47-
{banner.subtitle}
48-
</p>
49-
</div>
50-
</NextLink>
61+
<HeroBannerCard banner={banner} key={banner.id} />
5162
))}
5263
</div>
5364
),
@@ -57,28 +68,74 @@ const buildHeroSlides = (banners: HeroBannerItem[]): CarouselSlide[] => {
5768
return slides;
5869
};
5970

71+
const buildHeroDesktopSlides = (
72+
banners: HeroBannerItem[],
73+
): CarouselSlide[] =>
74+
banners.map((banner) => ({
75+
id: banner.id,
76+
content: <HeroBannerCard banner={banner} />,
77+
}));
78+
6079
type HomepageHeroCarouselSectionProps = {
6180
banners: HeroBannerItem[];
6281
};
6382

83+
type HeroCarouselProps = {
84+
slides: CarouselSlide[];
85+
slidesPerPage?: number;
86+
spacing?: string;
87+
};
88+
89+
function HeroCarousel({
90+
slides,
91+
slidesPerPage = 1,
92+
spacing = "0px",
93+
}: HeroCarouselProps) {
94+
const hasOverflow = slides.length > slidesPerPage;
95+
96+
return (
97+
<Carousel.Root
98+
aspectRatio="none"
99+
className="w-full"
100+
loop={hasOverflow}
101+
size="full"
102+
slideCount={slides.length}
103+
slidesPerMove={1}
104+
slidesPerPage={slidesPerPage}
105+
spacing={spacing}
106+
>
107+
<Carousel.Slides className="h-homepage-hero-carousel" slides={slides} />
108+
{hasOverflow ? (
109+
<>
110+
<Carousel.Previous className="-translate-y-1/2 absolute top-1/2 left-200 rounded-full aspect-square shadow-carousel-trigger active:text-carousel-trigger-fg-active" />
111+
<Carousel.Next className="-translate-y-1/2 absolute top-1/2 right-200 rounded-full aspect-square shadow-carousel-trigger active:text-carousel-trigger-fg-active" />
112+
</>
113+
) : null}
114+
</Carousel.Root>
115+
);
116+
}
117+
64118
export function HomepageHeroCarouselSection({
65119
banners,
66120
}: HomepageHeroCarouselSectionProps) {
67121
const slides = useMemo(() => buildHeroSlides(banners), [banners]);
122+
const desktopSlides = useMemo(
123+
() => buildHeroDesktopSlides(banners),
124+
[banners],
125+
);
68126

69127
return (
70128
<section>
71-
<Carousel.Root
72-
aspectRatio="none"
73-
className="w-full"
74-
loop
75-
slideCount={slides.length}
76-
size="full"
77-
>
78-
<Carousel.Slides className="h-120" slides={slides} />
79-
<Carousel.Previous className="-translate-y-1/2 absolute top-1/2 left-200 rounded-full border border-surface/80 aspect-square font-bold" />
80-
<Carousel.Next className="-translate-y-1/2 absolute top-1/2 right-200 rounded-full border border-surface/80 aspect-square font-bold" />
81-
</Carousel.Root>
129+
<div className="xl:hidden">
130+
<HeroCarousel slides={slides} />
131+
</div>
132+
<div className="hidden xl:block">
133+
<HeroCarousel
134+
slides={desktopSlides}
135+
slidesPerPage={HERO_DESKTOP_SLIDES_PER_PAGE}
136+
spacing={HERO_DESKTOP_SLIDE_SPACING}
137+
/>
138+
</div>
82139
</section>
83140
);
84141
}

apps/herbatika/src/components/homepage/sections/purpose-carousel.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@ function PurposeCarouselSlides({
112112
{hasOverflow ? (
113113
<>
114114
<Carousel.Previous
115-
className="-translate-y-1/2 absolute top-1/2 left-100 rounded-full aspect-square text-lg shadow-md"
115+
className="-translate-y-1/2 absolute top-1/2 left-100 rounded-full aspect-square text-lg shadow-carousel-trigger active:text-carousel-trigger-fg-active"
116116
icon="token-icon-chevron-left"
117117
/>
118118
<Carousel.Next
119-
className="-translate-y-1/2 absolute top-1/2 right-100 rounded-full aspect-square text-lg shadow-md"
119+
className="-translate-y-1/2 absolute top-1/2 right-100 rounded-full aspect-square text-lg shadow-carousel-trigger active:text-carousel-trigger-fg-active"
120120
icon="token-icon-chevron-right"
121121
/>
122122
</>
@@ -158,13 +158,13 @@ export function PurposeCarousel({
158158

159159
<div className="space-y-200">
160160
<div className="md:hidden">
161-
<PurposeCarouselSlides slides={slides} slidesPerPage={3} />
161+
<PurposeCarouselSlides slides={slides} slidesPerPage={3.2} />
162162
</div>
163163
<div className="hidden md:block xl:hidden">
164-
<PurposeCarouselSlides slides={slides} slidesPerPage={5} />
164+
<PurposeCarouselSlides slides={slides} slidesPerPage={5.2} />
165165
</div>
166166
<div className="hidden xl:block">
167-
<PurposeCarouselSlides slides={slides} slidesPerPage={7} />
167+
<PurposeCarouselSlides slides={slides} slidesPerPage={7.2} />
168168
</div>
169169
</div>
170170
</section>

apps/herbatika/src/styles/tokens/_herbatika-icons.css

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
}
2121

2222
@utility token-icon-chevron-right {
23-
@apply icon-[solar--alt-arrow-right-line-duotone];
23+
/* @apply icon-[solar--alt-arrow-right-line-duotone]; */
24+
@apply icon-[fluent--chevron-right-12-filled];
2425
}
2526

2627
@utility token-icon-chevron-left {
27-
@apply icon-[solar--alt-arrow-left-line-duotone];
28+
/* @apply icon-[solar--alt-arrow-left-line-duotone]; */
29+
@apply icon-[fluent--chevron-left-12-filled];
2830
}
2931

3032
@utility token-icon-chevron-up {

0 commit comments

Comments
 (0)