Skip to content

Commit e609ee6

Browse files
committed
refactor: explode ui/swiper into compossible parts
migrates global.css styling into component
1 parent 202b11d commit e609ee6

File tree

2 files changed

+98
-72
lines changed

2 files changed

+98
-72
lines changed

src/components/ui/swiper.tsx

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { ChevronNext, ChevronPrev } from "@/components/Chevron"
1212

1313
import { cn } from "@/lib/utils/cn"
1414

15+
import { Button, type ButtonProps } from "./buttons/Button"
16+
1517
import "swiper/css"
1618
import "swiper/css/navigation"
1719
import "swiper/css/pagination"
@@ -25,24 +27,100 @@ const SwiperContainer = React.forwardRef<
2527
))
2628
SwiperContainer.displayName = "SwiperContainer"
2729

30+
const SwiperNavButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
31+
({ children, className, ...props }, ref) => (
32+
<Button
33+
ref={ref}
34+
variant="ghost"
35+
className={cn("px-2", className)}
36+
{...props}
37+
>
38+
{children}
39+
</Button>
40+
)
41+
)
42+
SwiperNavButton.displayName = "SwiperNavButton"
43+
44+
const SwiperNextButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
45+
({ children, className, ...props }, ref) => (
46+
<SwiperNavButton
47+
ref={ref}
48+
className={cn("ui-swiper-button-next", className)}
49+
{...props}
50+
>
51+
{children || <ChevronNext />}
52+
</SwiperNavButton>
53+
)
54+
)
55+
SwiperNextButton.displayName = "SwiperNextButton"
56+
57+
const SwiperPrevButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
58+
({ children, className, ...props }, ref) => (
59+
<SwiperNavButton
60+
ref={ref}
61+
className={cn("ui-swiper-button-prev", className)}
62+
{...props}
63+
>
64+
{children || <ChevronPrev />}
65+
</SwiperNavButton>
66+
)
67+
)
68+
SwiperPrevButton.displayName = "SwiperPrevButton"
69+
70+
const SwiperPaginationDots = React.forwardRef<
71+
HTMLDivElement,
72+
React.HTMLAttributes<HTMLDivElement>
73+
>(({ className, ...props }, ref) => (
74+
<div
75+
ref={ref}
76+
className={cn(
77+
"ui-swiper-pagination flex w-fit flex-row",
78+
"[&_.swiper-pagination-bullet]:bg-primary-high-contrast",
79+
"[&_.swiper-pagination-bullet-active]:bg-primary-hover",
80+
className
81+
)}
82+
{...props}
83+
/>
84+
))
85+
SwiperPaginationDots.displayName = "SwiperPaginationDots"
86+
87+
const SwiperNavContainer = React.forwardRef<
88+
HTMLDivElement,
89+
React.HTMLAttributes<HTMLDivElement>
90+
>(({ className, ...props }, ref) => (
91+
<div
92+
ref={ref}
93+
className={cn(
94+
"mx-auto mt-6 flex h-6 w-fit items-center gap-4 rounded-full bg-background-highlight",
95+
className
96+
)}
97+
{...props}
98+
/>
99+
))
100+
SwiperNavContainer.displayName = "SwiperNavContainer"
101+
28102
type SwiperProps = SwiperReactProps & {
103+
navigation?: React.ReactNode
29104
children: React.ReactNode[]
30105
}
31106
const Swiper = React.forwardRef<SwiperRef, SwiperProps>(
32-
({ children, ...props }, ref) => {
107+
({ children, navigation, ...props }, ref) => {
33108
const { t } = useTranslation("common")
34109
return (
35110
<SwiperReact
36111
ref={ref}
37112
navigation={{
38-
nextEl: ".swiper-button-next",
39-
prevEl: ".swiper-button-prev",
113+
nextEl: ".ui-swiper-button-next",
114+
prevEl: ".ui-swiper-button-prev",
40115
}}
41116
a11y={{
42117
prevSlideMessage: t("previous"),
43118
nextSlideMessage: t("next"),
44119
}}
45-
pagination={{ clickable: true, el: ".swiper-pagination" }}
120+
pagination={{
121+
clickable: true,
122+
el: ".ui-swiper-pagination",
123+
}}
46124
keyboard
47125
modules={[Navigation, Pagination, Keyboard, EffectCards]}
48126
slidesPerView={1}
@@ -54,14 +132,25 @@ const Swiper = React.forwardRef<SwiperRef, SwiperProps>(
54132
{children.map((child, index) => (
55133
<SwiperSlide key={index}>{child}</SwiperSlide>
56134
))}
57-
58-
<ChevronPrev className="swiper-button-prev" />
59-
<div className="swiper-pagination" />
60-
<ChevronNext className="swiper-button-next" />
135+
{navigation || (
136+
<SwiperNavContainer>
137+
<SwiperPrevButton />
138+
<SwiperPaginationDots />
139+
<SwiperNextButton />
140+
</SwiperNavContainer>
141+
)}
61142
</SwiperReact>
62143
)
63144
}
64145
)
65146
Swiper.displayName = "Swiper"
66147

67-
export { Swiper, SwiperContainer }
148+
export {
149+
Swiper,
150+
SwiperContainer,
151+
SwiperNavButton,
152+
SwiperNavContainer,
153+
SwiperNextButton,
154+
SwiperPaginationDots,
155+
SwiperPrevButton,
156+
}

src/styles/global.css

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -167,69 +167,6 @@
167167
}
168168
}
169169

170-
@layer components {
171-
.swiper-horizontal > .swiper-pagination-bullets,
172-
.swiper-pagination-bullets.swiper-pagination-horizontal {
173-
@apply bg-background-highlight;
174-
}
175-
176-
.swiper-pagination.swiper-pagination-clickable.swiper-pagination-bullets.swiper-pagination-horizontal {
177-
@apply !relative;
178-
}
179-
180-
.swiper-pagination {
181-
@apply relative mx-auto mt-8 flex h-[26px] max-w-48 items-center justify-center rounded-full bg-background-highlight;
182-
}
183-
184-
.css-posts-swiper .swiper-pagination {
185-
@apply max-w-52 sm:max-w-40 lg:max-w-36;
186-
}
187-
188-
.swiper-pagination .swiper-pagination-bullet {
189-
@apply bg-primary-high-contrast;
190-
}
191-
192-
.swiper-pagination.swiper-pagination-clickable.swiper-pagination-bullets.swiper-pagination-horizontal
193-
.swiper-pagination-bullet-active {
194-
@apply bg-primary-hover;
195-
}
196-
197-
.swiper-button-prev,
198-
.swiper-button-next {
199-
@apply !h-6 !w-fit fill-primary px-2;
200-
}
201-
}
202-
203-
.swiper-button-prev,
204-
.swiper-button-next {
205-
top: calc(100% - 11px) !important;
206-
--nav-inset: calc(50% - 6.5rem);
207-
}
208-
209-
@media (min-width: theme("screens.sm")) {
210-
.swiper-button-prev,
211-
.swiper-button-next {
212-
--nav-inset: calc(50% - 5rem);
213-
}
214-
}
215-
216-
@media (min-width: theme("screens.lg")) {
217-
.swiper-button-prev,
218-
.swiper-button-next {
219-
--nav-inset: calc(50% - 4.5rem);
220-
}
221-
}
222-
223-
.swiper-button-next {
224-
inset-inline-end: var(--nav-inset) !important;
225-
inset-inline-start: auto !important;
226-
}
227-
228-
.swiper-button-prev {
229-
inset-inline-end: auto !important;
230-
inset-inline-start: var(--nav-inset) !important;
231-
}
232-
233170
.swiper-slide-shadow {
234171
background: transparent !important;
235172
}

0 commit comments

Comments
 (0)