@growth-angels/ds-core 1.12.9 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  type ReactType = typeof import('react');
2
3
  type ExtendedReactType = ReactType & {
3
4
  createRoot: (container: Element | DocumentFragment) => {
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  export const useReactAdapter = () => {
2
3
  // Check if WordPress element is available (WordPress context)
3
4
  if (typeof window !== 'undefined' && window.wp?.element) {
@@ -5,5 +6,5 @@ export const useReactAdapter = () => {
5
6
  }
6
7
  // Fallback for non-WordPress environments (Storybook, tests, SSR)
7
8
  // This will bundle React only in non-WordPress builds
8
- return import('react');
9
+ return React;
9
10
  };
@@ -1,2 +1,5 @@
1
1
  import { CarouselProps } from "./Carousel.types";
2
+ import "swiper/css";
3
+ import "swiper/css/navigation";
4
+ import "swiper/css/pagination";
2
5
  export declare const Carousel: (props: CarouselProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,159 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button } from "../../atoms/atoms";
3
- import { useBreakpointObserver } from "../../hooks/useBreakPointObserver";
4
3
  import { useReactAdapter } from "../../hooks/useReactAdaptater";
4
+ import { Swiper, SwiperSlide } from "swiper/react";
5
+ import { Navigation, Pagination, A11y } from "swiper/modules";
6
+ import "swiper/css";
7
+ import "swiper/css/navigation";
8
+ import "swiper/css/pagination";
5
9
  export const Carousel = (props) => {
6
- const { children, slidesPerView = { sm: 1, md: 2, lg: 3, xl: 4 }, spaceBetween = 20, navigation, pagination, context, hasPagination, hasNavigation, loop = false, } = props;
7
- const { useEffect, useState, useRef, Children } = useReactAdapter();
8
- const trackRef = useRef(null);
9
- const isNavigatingRef = useRef(false);
10
+ const { children, slidesPerView = { xs: 1, sm: 1, md: 2, lg: 3, xl: 4 }, spaceBetween = 20, navigation, pagination, context, hasPagination, hasNavigation, loop = false, } = props;
11
+ const { useRef, Children } = useReactAdapter();
12
+ const swiperRef = useRef(null);
10
13
  const slides = Children.toArray(children);
11
- const calculatePages = (totalSlides = 0, slidesPerView = 0, step = 1) => {
12
- return Math.max(1, Math.ceil((totalSlides - slidesPerView) / step) + 1);
13
- };
14
- const [activeSlideIndex, setActiveSlideIndex] = useState(0);
15
- const [activeDOMIndex, setActiveDOMIndex] = useState(0);
16
- const [isAtEnd, setIsAtEnd] = useState(false);
17
- const [isAtStart, setIsAtStart] = useState(true);
18
- const [totalPages, setTotalPages] = useState(0);
19
- const [isOverflowing, setIsOverflowing] = useState(false);
20
- const displayNavigation = hasNavigation && (loop || isOverflowing);
21
- const displayPagination = hasPagination && (loop || isOverflowing);
22
- useEffect(() => {
23
- if (loop) {
24
- setIsAtStart(false);
25
- setIsAtEnd(false);
26
- }
27
- else {
28
- setIsAtStart(activeSlideIndex === 0);
29
- setIsAtEnd(activeSlideIndex === totalPages - 1);
30
- }
31
- }, [activeSlideIndex, totalPages, loop]);
32
- const breakpoint = useBreakpointObserver({ sm: 768, md: 992, lg: 1200, xl: 1400 });
33
- useEffect(() => {
34
- setTotalPages(calculatePages(slides.length, slidesPerView[breakpoint], 1));
35
- }, [breakpoint, slidesPerView]);
36
- useEffect(() => {
37
- const track = trackRef.current;
38
- if (!track)
39
- return;
40
- const handleScroll = () => {
41
- if (loop) {
42
- const slideWidth = track.scrollWidth / (slides.length * 3);
43
- const scrollLeft = track.scrollLeft;
44
- // Repositionnement infini (uniquement si pas en navigation)
45
- if (!isNavigatingRef.current) {
46
- if (scrollLeft <= slideWidth * slides.length) {
47
- track.scrollLeft = scrollLeft + slideWidth * slides.length;
48
- }
49
- else if (scrollLeft >= slideWidth * slides.length * 2) {
50
- track.scrollLeft = scrollLeft - slideWidth * slides.length;
51
- }
52
- }
53
- const scrollPosition = track.scrollLeft + slideWidth / 2;
54
- const domIndex = Math.floor(scrollPosition / slideWidth);
55
- const index = domIndex % slides.length;
56
- setActiveDOMIndex(domIndex);
57
- setActiveSlideIndex(index);
58
- }
59
- else {
60
- const slideWidth = track.scrollWidth / slides.length;
61
- const scrollPosition = track.scrollLeft + slideWidth / 2;
62
- const index = Math.floor(scrollPosition / slideWidth);
63
- setActiveSlideIndex(Math.min(index, slides.length - 1));
64
- setActiveDOMIndex(index);
65
- }
66
- };
67
- track.addEventListener("scroll", handleScroll);
68
- // Position initiale au milieu en mode loop
69
- if (loop) {
70
- setTimeout(() => {
71
- const slideWidth = track.scrollWidth / (slides.length * 3);
72
- track.scrollLeft = slideWidth * slides.length;
73
- }, 0);
74
- }
75
- return () => track.removeEventListener("scroll", handleScroll);
76
- }, [slides.length, loop]);
77
- // Check if the slides overflow the container
78
- useEffect(() => {
79
- const track = trackRef.current;
80
- if (!track)
81
- return;
82
- const handleResize = () => {
83
- setIsOverflowing(track.scrollWidth > track.clientWidth);
84
- };
85
- handleResize(); // Initial check
86
- window.addEventListener("resize", handleResize);
87
- return () => window.removeEventListener("resize", handleResize);
88
- }, [loop]);
89
- const style = Object.fromEntries(Object.entries(slidesPerView).map(([key, value]) => [`--ga-ds-slides-per-view-${key}`, `${value}`]));
90
- const goPrev = () => {
91
- if (!trackRef.current)
92
- return;
93
- const allSlides = trackRef.current.querySelectorAll(".ga-ds-carousel__slide");
94
- if (activeSlideIndex === 0 && !loop)
95
- return;
96
- isNavigatingRef.current = true;
97
- if (loop) {
98
- // En mode loop, on utilise l'index DOM actuel
99
- allSlides[activeDOMIndex - 1]?.scrollIntoView({
100
- behavior: "smooth",
101
- block: "nearest",
102
- inline: "start",
103
- });
104
- }
105
- else {
106
- const nextIndex = activeSlideIndex - 1;
107
- allSlides[nextIndex]?.scrollIntoView({
108
- behavior: "smooth",
109
- block: "nearest",
110
- inline: "start",
111
- });
112
- }
113
- setTimeout(() => {
114
- isNavigatingRef.current = false;
115
- }, 600);
116
- };
117
- const goNext = () => {
118
- if (!trackRef.current)
119
- return;
120
- const allSlides = trackRef.current.querySelectorAll(".ga-ds-carousel__slide");
121
- isNavigatingRef.current = true;
122
- if (loop) {
123
- // En mode loop, on utilise l'index DOM actuel
124
- allSlides[activeDOMIndex + 1]?.scrollIntoView({
125
- behavior: "smooth",
126
- block: "nearest",
127
- inline: "start",
128
- });
129
- }
130
- else {
131
- const totalSlides = allSlides.length;
132
- if (activeSlideIndex >= totalSlides - 1)
133
- return;
134
- if (isAtEnd)
135
- return;
136
- const nextIndex = activeSlideIndex + 1;
137
- allSlides[nextIndex]?.scrollIntoView({
138
- behavior: "smooth",
139
- block: "nearest",
140
- inline: "start",
141
- });
142
- }
143
- setTimeout(() => {
144
- isNavigatingRef.current = false;
145
- }, 600);
146
- };
147
- const goTo = (nextIndex) => {
148
- if (!trackRef.current)
149
- return;
150
- const slides = trackRef.current.querySelectorAll(".ga-ds-carousel__slide");
151
- slides[nextIndex]?.scrollIntoView({
152
- behavior: "smooth",
153
- block: "nearest",
154
- inline: "start",
155
- });
156
- };
14
+ const displayNavigation = hasNavigation;
15
+ const displayPagination = hasPagination;
157
16
  const classes = ["ga-ds-carousel"];
158
17
  if (props.extraClassNames) {
159
18
  if (typeof props.extraClassNames === "string") {
@@ -163,19 +22,31 @@ export const Carousel = (props) => {
163
22
  classes.push(...props.extraClassNames);
164
23
  }
165
24
  }
166
- return (_jsxs("div", { className: classes.join(" "), style: style, children: [navigation?.positionY === "top" && displayNavigation && (_jsx(CarouselNavigation, { goPrev: goPrev, goNext: goNext, isAtStart: isAtStart, isAtEnd: isAtEnd })), _jsx("div", { className: "ga-ds-carousel__track", ref: trackRef, style: {
167
- "--ga-ds-space-between": `${spaceBetween / 10}rem`,
168
- }, children: context === "wp-editor"
25
+ const breakpoints = {
26
+ 0: { slidesPerView: slidesPerView.xs || slidesPerView.sm || 1 },
27
+ 576: { slidesPerView: slidesPerView.sm || 1 },
28
+ 992: { slidesPerView: slidesPerView.md || 2 },
29
+ 1200: { slidesPerView: slidesPerView.lg || 3 },
30
+ 1440: { slidesPerView: slidesPerView.xl || 4 },
31
+ };
32
+ return (_jsxs("div", { className: classes.join(" "), children: [navigation?.positionY === "top" && displayNavigation && _jsx(CarouselNavigation, {}), _jsx(Swiper, { modules: [Navigation, Pagination, A11y], spaceBetween: spaceBetween, breakpoints: breakpoints, loop: loop, navigation: displayNavigation
33
+ ? {
34
+ prevEl: ".ga-ds-carousel__button--prev",
35
+ nextEl: ".ga-ds-carousel__button--next",
36
+ }
37
+ : false, pagination: displayPagination && pagination
38
+ ? {
39
+ clickable: pagination.clickable,
40
+ el: ".ga-ds-carousel__dots",
41
+ bulletClass: "ga-ds-carousel__dot",
42
+ bulletActiveClass: "ga-ds-carousel__dot--active",
43
+ }
44
+ : false, onSwiper: (swiper) => {
45
+ swiperRef.current = swiper;
46
+ }, className: "ga-ds-carousel__track", children: context === "wp-editor"
169
47
  ? children
170
- : slides.map((child, index) => {
171
- return (_jsx("div", { className: `ga-ds-carousel__slide ${index === activeDOMIndex ? "ga-ds-carousel__slide--active" : ""}`, children: child }, index));
172
- }) }), _jsxs("div", { className: "ga-ds-carousel__navigation", children: [pagination && displayPagination && (_jsx(CarouselPagination, { totalPages: totalPages, activeSlideIndex: activeSlideIndex, goTo: goTo, clickable: pagination.clickable })), displayNavigation && navigation?.positionY === "bottom" && (_jsx(CarouselNavigation, { goPrev: goPrev, goNext: goNext, isAtStart: isAtStart, isAtEnd: isAtEnd }))] })] }));
173
- };
174
- const CarouselNavigation = ({ goPrev, goNext, isAtStart, isAtEnd, }) => {
175
- return (_jsxs("div", { className: `ga-ds-carousel__arrows`, children: [_jsx(Button, { extraClassNames: ["ga-ds-carousel__button", "ga-ds-carousel__button--prev"], icon: "chevron-left", onClick: goPrev, disabled: isAtStart }), _jsx(Button, { extraClassNames: ["ga-ds-carousel__button", "ga-ds-carousel__button--next"], icon: "chevron-right", onClick: goNext, disabled: isAtEnd })] }));
48
+ : slides.map((child, index) => (_jsx(SwiperSlide, { className: "ga-ds-carousel__slide", children: child }, index))) }), _jsxs("div", { className: "ga-ds-carousel__navigation", children: [displayPagination && _jsx("div", { className: "ga-ds-carousel__dots" }), displayNavigation && navigation?.positionY === "bottom" && _jsx(CarouselNavigation, {})] })] }));
176
49
  };
177
- const CarouselPagination = ({ totalPages, activeSlideIndex, goTo, clickable, }) => {
178
- return (_jsx("div", { className: "ga-ds-carousel__dots", children: Array.from({ length: totalPages }, (_, index) => index).map((_, index) => (_jsx("span", { className: `ga-ds-carousel__dot ${index === activeSlideIndex ? "ga-ds-carousel__dot--active" : ""}`, onClick: () => clickable && goTo(index), style: {
179
- cursor: clickable ? "pointer" : "default",
180
- } }, index))) }));
50
+ const CarouselNavigation = () => {
51
+ return (_jsxs("div", { className: `ga-ds-carousel__arrows`, children: [_jsx(Button, { extraClassNames: ["ga-ds-carousel__button", "ga-ds-carousel__button--prev"], icon: "chevron-left" }), _jsx(Button, { extraClassNames: ["ga-ds-carousel__button", "ga-ds-carousel__button--next"], icon: "chevron-right" })] }));
181
52
  };
@@ -2,6 +2,7 @@ import { WordpressDefault } from "../../global.types";
2
2
  export type CarouselAttributes = {
3
3
  context?: 'wp-editor';
4
4
  slidesPerView?: {
5
+ xs?: number;
5
6
  sm: number;
6
7
  md: number;
7
8
  lg: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-angels/ds-core",
3
- "version": "1.12.9",
3
+ "version": "1.13.0",
4
4
  "description": "Design system by Growth Angels",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -37,7 +37,8 @@
37
37
  "build-storybook": "storybook build"
38
38
  },
39
39
  "dependencies": {
40
- "@growth-angels/foundation": "^1.4.1"
40
+ "@growth-angels/foundation": "^1.4.1",
41
+ "swiper": "^11.1.15"
41
42
  },
42
43
  "peerDependencies": {
43
44
  "react": ">=18"
@@ -1,3 +1,4 @@
1
+ import React from 'react'
1
2
  // @ts-ignore - React types from window.wp.element
2
3
  type ReactType = typeof import('react')
3
4
 
@@ -27,6 +28,6 @@ export const useReactAdapter = (): ExtendedReactType => {
27
28
 
28
29
  // Fallback for non-WordPress environments (Storybook, tests, SSR)
29
30
  // This will bundle React only in non-WordPress builds
30
- return import('react') as unknown as ExtendedReactType
31
+ return React as ExtendedReactType
31
32
  }
32
33
 
@@ -1,12 +1,17 @@
1
1
  import { Button } from "../../atoms/atoms"
2
- import { useBreakpointObserver } from "../../hooks/useBreakPointObserver"
3
2
  import { useReactAdapter } from "../../hooks/useReactAdaptater"
4
3
  import { CarouselProps } from "./Carousel.types"
4
+ import { Swiper, SwiperSlide } from "swiper/react"
5
+ import { Navigation, Pagination, A11y } from "swiper/modules"
6
+ import type { Swiper as SwiperType } from "swiper"
7
+ import "swiper/css"
8
+ import "swiper/css/navigation"
9
+ import "swiper/css/pagination"
5
10
 
6
11
  export const Carousel = (props: CarouselProps) => {
7
12
  const {
8
13
  children,
9
- slidesPerView = { sm: 1, md: 2, lg: 3, xl: 4 },
14
+ slidesPerView = { xs: 1, sm: 1, md: 2, lg: 3, xl: 4 },
10
15
  spaceBetween = 20,
11
16
  navigation,
12
17
  pagination,
@@ -15,173 +20,12 @@ export const Carousel = (props: CarouselProps) => {
15
20
  hasNavigation,
16
21
  loop = false,
17
22
  } = props
18
- const { useEffect, useState, useRef, Children } = useReactAdapter()
19
- const trackRef = useRef<HTMLDivElement>(null)
20
- const isNavigatingRef = useRef(false)
23
+ const { useRef, Children } = useReactAdapter()
24
+ const swiperRef = useRef<SwiperType | null>(null)
21
25
  const slides = Children.toArray(children)
22
26
 
23
- const calculatePages = (totalSlides = 0, slidesPerView = 0, step = 1) => {
24
- return Math.max(1, Math.ceil((totalSlides - slidesPerView) / step) + 1)
25
- }
26
-
27
- const [activeSlideIndex, setActiveSlideIndex] = useState(0)
28
- const [activeDOMIndex, setActiveDOMIndex] = useState(0)
29
- const [isAtEnd, setIsAtEnd] = useState(false)
30
- const [isAtStart, setIsAtStart] = useState(true)
31
- const [totalPages, setTotalPages] = useState(0)
32
- const [isOverflowing, setIsOverflowing] = useState(false)
33
-
34
- const displayNavigation = hasNavigation && (loop || isOverflowing)
35
- const displayPagination = hasPagination && (loop || isOverflowing)
36
-
37
- useEffect(() => {
38
- if (loop) {
39
- setIsAtStart(false)
40
- setIsAtEnd(false)
41
- } else {
42
- setIsAtStart(activeSlideIndex === 0)
43
- setIsAtEnd(activeSlideIndex === totalPages - 1)
44
- }
45
- }, [activeSlideIndex, totalPages, loop])
46
-
47
- const breakpoint = useBreakpointObserver({ sm: 768, md: 992, lg: 1200, xl: 1400 })
48
-
49
- useEffect(() => {
50
- setTotalPages(calculatePages(slides.length, slidesPerView[breakpoint], 1))
51
- }, [breakpoint, slidesPerView])
52
-
53
- useEffect(() => {
54
- const track = trackRef.current
55
- if (!track) return
56
-
57
- const handleScroll = () => {
58
- if (loop) {
59
- const slideWidth = track.scrollWidth / (slides.length * 3)
60
- const scrollLeft = track.scrollLeft
61
-
62
- // Repositionnement infini (uniquement si pas en navigation)
63
- if (!isNavigatingRef.current) {
64
- if (scrollLeft <= slideWidth * slides.length) {
65
- track.scrollLeft = scrollLeft + slideWidth * slides.length
66
- } else if (scrollLeft >= slideWidth * slides.length * 2) {
67
- track.scrollLeft = scrollLeft - slideWidth * slides.length
68
- }
69
- }
70
-
71
- const scrollPosition = track.scrollLeft + slideWidth / 2
72
- const domIndex = Math.floor(scrollPosition / slideWidth)
73
- const index = domIndex % slides.length
74
- setActiveDOMIndex(domIndex)
75
- setActiveSlideIndex(index)
76
- } else {
77
- const slideWidth = track.scrollWidth / slides.length
78
- const scrollPosition = track.scrollLeft + slideWidth / 2
79
- const index = Math.floor(scrollPosition / slideWidth)
80
- setActiveSlideIndex(Math.min(index, slides.length - 1))
81
- setActiveDOMIndex(index)
82
- }
83
- }
84
-
85
- track.addEventListener("scroll", handleScroll)
86
-
87
- // Position initiale au milieu en mode loop
88
- if (loop) {
89
- setTimeout(() => {
90
- const slideWidth = track.scrollWidth / (slides.length * 3)
91
- track.scrollLeft = slideWidth * slides.length
92
- }, 0)
93
- }
94
-
95
- return () => track.removeEventListener("scroll", handleScroll)
96
- }, [slides.length, loop])
97
-
98
- // Check if the slides overflow the container
99
- useEffect(() => {
100
- const track = trackRef.current
101
- if (!track) return
102
-
103
- const handleResize = () => {
104
- setIsOverflowing(track.scrollWidth > track.clientWidth)
105
- }
106
-
107
- handleResize() // Initial check
108
-
109
- window.addEventListener("resize", handleResize)
110
- return () => window.removeEventListener("resize", handleResize)
111
- }, [loop])
112
-
113
- const style = Object.fromEntries(
114
- Object.entries(slidesPerView).map(([key, value]) => [`--ga-ds-slides-per-view-${key}`, `${value}`])
115
- )
116
-
117
- const goPrev = () => {
118
- if (!trackRef.current) return
119
- const allSlides = trackRef.current.querySelectorAll(".ga-ds-carousel__slide")
120
- if (activeSlideIndex === 0 && !loop) return
121
-
122
- isNavigatingRef.current = true
123
-
124
- if (loop) {
125
- // En mode loop, on utilise l'index DOM actuel
126
- allSlides[activeDOMIndex - 1]?.scrollIntoView({
127
- behavior: "smooth",
128
- block: "nearest",
129
- inline: "start",
130
- })
131
- } else {
132
- const nextIndex = activeSlideIndex - 1
133
- allSlides[nextIndex]?.scrollIntoView({
134
- behavior: "smooth",
135
- block: "nearest",
136
- inline: "start",
137
- })
138
- }
139
-
140
- setTimeout(() => {
141
- isNavigatingRef.current = false
142
- }, 600)
143
- }
144
-
145
- const goNext = () => {
146
- if (!trackRef.current) return
147
- const allSlides = trackRef.current.querySelectorAll(".ga-ds-carousel__slide")
148
-
149
- isNavigatingRef.current = true
150
-
151
- if (loop) {
152
- // En mode loop, on utilise l'index DOM actuel
153
- allSlides[activeDOMIndex + 1]?.scrollIntoView({
154
- behavior: "smooth",
155
- block: "nearest",
156
- inline: "start",
157
- })
158
- } else {
159
- const totalSlides = allSlides.length
160
- if (activeSlideIndex >= totalSlides - 1) return
161
- if (isAtEnd) return
162
-
163
- const nextIndex = activeSlideIndex + 1
164
- allSlides[nextIndex]?.scrollIntoView({
165
- behavior: "smooth",
166
- block: "nearest",
167
- inline: "start",
168
- })
169
- }
170
-
171
- setTimeout(() => {
172
- isNavigatingRef.current = false
173
- }, 600)
174
- }
175
-
176
- const goTo = (nextIndex: number) => {
177
- if (!trackRef.current) return
178
- const slides = trackRef.current.querySelectorAll(".ga-ds-carousel__slide")
179
- slides[nextIndex]?.scrollIntoView({
180
- behavior: "smooth",
181
- block: "nearest",
182
- inline: "start",
183
- })
184
- }
27
+ const displayNavigation = hasNavigation
28
+ const displayPagination = hasPagination
185
29
 
186
30
  const classes = ["ga-ds-carousel"]
187
31
 
@@ -193,103 +37,68 @@ export const Carousel = (props: CarouselProps) => {
193
37
  }
194
38
  }
195
39
 
40
+ const breakpoints = {
41
+ 0: { slidesPerView: slidesPerView.xs || slidesPerView.sm || 1 },
42
+ 576: { slidesPerView: slidesPerView.sm || 1 },
43
+ 992: { slidesPerView: slidesPerView.md || 2 },
44
+ 1200: { slidesPerView: slidesPerView.lg || 3 },
45
+ 1440: { slidesPerView: slidesPerView.xl || 4 },
46
+ }
47
+
196
48
  return (
197
- <div className={classes.join(" ")} style={style}>
198
- {navigation?.positionY === "top" && displayNavigation && (
199
- <CarouselNavigation goPrev={goPrev} goNext={goNext} isAtStart={isAtStart} isAtEnd={isAtEnd} />
200
- )}
201
- <div
202
- className="ga-ds-carousel__track"
203
- ref={trackRef}
204
- style={
205
- {
206
- "--ga-ds-space-between": `${spaceBetween / 10}rem`,
207
- } as React.CSSProperties
49
+ <div className={classes.join(" ")}>
50
+ {navigation?.positionY === "top" && displayNavigation && <CarouselNavigation />}
51
+
52
+ <Swiper
53
+ modules={[Navigation, Pagination, A11y]}
54
+ spaceBetween={spaceBetween}
55
+ breakpoints={breakpoints}
56
+ loop={loop}
57
+ navigation={
58
+ displayNavigation
59
+ ? {
60
+ prevEl: ".ga-ds-carousel__button--prev",
61
+ nextEl: ".ga-ds-carousel__button--next",
62
+ }
63
+ : false
64
+ }
65
+ pagination={
66
+ displayPagination && pagination
67
+ ? {
68
+ clickable: pagination.clickable,
69
+ el: ".ga-ds-carousel__dots",
70
+ bulletClass: "ga-ds-carousel__dot",
71
+ bulletActiveClass: "ga-ds-carousel__dot--active",
72
+ }
73
+ : false
208
74
  }
75
+ onSwiper={(swiper: SwiperType) => {
76
+ swiperRef.current = swiper
77
+ }}
78
+ className="ga-ds-carousel__track"
209
79
  >
210
80
  {context === "wp-editor"
211
81
  ? children
212
- : slides.map((child, index) => {
213
- return (
214
- <div
215
- key={index}
216
- className={`ga-ds-carousel__slide ${index === activeDOMIndex ? "ga-ds-carousel__slide--active" : ""}`}
217
- >
218
- {child}
219
- </div>
220
- )
221
- })}
222
- </div>
82
+ : slides.map((child, index) => (
83
+ <SwiperSlide key={index} className="ga-ds-carousel__slide">
84
+ {child}
85
+ </SwiperSlide>
86
+ ))}
87
+ </Swiper>
223
88
 
224
89
  <div className="ga-ds-carousel__navigation">
225
- {pagination && displayPagination && (
226
- <CarouselPagination
227
- totalPages={totalPages}
228
- activeSlideIndex={activeSlideIndex}
229
- goTo={goTo}
230
- clickable={pagination.clickable}
231
- />
232
- )}
233
- {displayNavigation && navigation?.positionY === "bottom" && (
234
- <CarouselNavigation goPrev={goPrev} goNext={goNext} isAtStart={isAtStart} isAtEnd={isAtEnd} />
235
- )}
90
+ {displayPagination && <div className="ga-ds-carousel__dots"></div>}
91
+ {displayNavigation && navigation?.positionY === "bottom" && <CarouselNavigation />}
236
92
  </div>
237
93
  </div>
238
94
  )
239
95
  }
240
96
 
241
- const CarouselNavigation = ({
242
- goPrev,
243
- goNext,
244
- isAtStart,
245
- isAtEnd,
246
- }: {
247
- goPrev: () => void
248
- goNext: () => void
249
- isAtStart: boolean
250
- isAtEnd: boolean
251
- }) => {
97
+ const CarouselNavigation = () => {
252
98
  return (
253
99
  <div className={`ga-ds-carousel__arrows`}>
254
- <Button
255
- extraClassNames={["ga-ds-carousel__button", "ga-ds-carousel__button--prev"]}
256
- icon="chevron-left"
257
- onClick={goPrev}
258
- disabled={isAtStart}
259
- />
260
- <Button
261
- extraClassNames={["ga-ds-carousel__button", "ga-ds-carousel__button--next"]}
262
- icon="chevron-right"
263
- onClick={goNext}
264
- disabled={isAtEnd}
265
- />
266
- </div>
267
- )
268
- }
269
-
270
- const CarouselPagination = ({
271
- totalPages,
272
- activeSlideIndex,
273
- goTo,
274
- clickable,
275
- }: {
276
- totalPages: number
277
- activeSlideIndex: number
278
- goTo: (nextIndex: number) => void
279
- clickable: boolean
280
- }) => {
281
- return (
282
- <div className="ga-ds-carousel__dots">
283
- {Array.from({ length: totalPages }, (_, index) => index).map((_, index) => (
284
- <span
285
- key={index}
286
- className={`ga-ds-carousel__dot ${index === activeSlideIndex ? "ga-ds-carousel__dot--active" : ""}`}
287
- onClick={() => clickable && goTo(index)}
288
- style={{
289
- cursor: clickable ? "pointer" : "default",
290
- }}
291
- ></span>
292
- ))}
100
+ <Button extraClassNames={["ga-ds-carousel__button", "ga-ds-carousel__button--prev"]} icon="chevron-left" />
101
+ <Button extraClassNames={["ga-ds-carousel__button", "ga-ds-carousel__button--next"]} icon="chevron-right" />
293
102
  </div>
294
103
  )
295
104
  }
@@ -3,6 +3,7 @@ import { WordpressDefault } from "../../global.types"
3
3
  export type CarouselAttributes = {
4
4
  context?: 'wp-editor'
5
5
  slidesPerView?: {
6
+ xs?: number
6
7
  sm: number
7
8
  md: number
8
9
  lg: number