@growth-angels/ds-core 1.25.5 → 2.0.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.
@@ -0,0 +1,4 @@
1
+ export declare function useWindowSize(): {
2
+ width: number | null;
3
+ height: number | null;
4
+ };
@@ -0,0 +1,22 @@
1
+ import { useReactAdapter } from "./useReactAdaptater";
2
+ export function useWindowSize() {
3
+ const React = useReactAdapter();
4
+ const [size, setSize] = React.useState({
5
+ width: null,
6
+ height: null,
7
+ });
8
+ React.useLayoutEffect(() => {
9
+ const handleResize = () => {
10
+ setSize({
11
+ width: window.innerWidth,
12
+ height: window.innerHeight,
13
+ });
14
+ };
15
+ handleResize();
16
+ window.addEventListener("resize", handleResize);
17
+ return () => {
18
+ window.removeEventListener("resize", handleResize);
19
+ };
20
+ }, []);
21
+ return size;
22
+ }
@@ -23,6 +23,7 @@ export type CarouselAttributes = {
23
23
  disableOnInteraction?: boolean;
24
24
  };
25
25
  speed?: number;
26
+ loopOnMobile?: boolean;
26
27
  };
27
28
  export interface CarouselProps extends CarouselAttributes, WordpressDefault {
28
29
  children: React.ReactNode | React.ReactNode[];
@@ -4,7 +4,7 @@ import { Button } from "../../atoms/atoms";
4
4
  import Swiper from "swiper";
5
5
  import { Autoplay, Navigation, Pagination } from "swiper/modules";
6
6
  export const CarouselSwiper = (props) => {
7
- const { children, slidesPerView: slidesPerViewDefault, spaceBetween = 48, navigation, pagination, hasPagination, hasNavigation, loop = false, autoplay, speed, } = props;
7
+ const { children, slidesPerView: slidesPerViewDefault, spaceBetween = 48, navigation, pagination, hasPagination, hasNavigation, loop = false, autoplay, speed, loopOnMobile = false, } = props;
8
8
  const classes = ["ga-ds-carousel"];
9
9
  if (props.extraClassNames) {
10
10
  if (typeof props.extraClassNames === "string") {
@@ -14,64 +14,102 @@ export const CarouselSwiper = (props) => {
14
14
  classes.push(...props.extraClassNames);
15
15
  }
16
16
  }
17
- if (Swiper) {
18
- const slidesPerView = { xs: 1, ...slidesPerViewDefault };
19
- const { useEffect, useState, useRef, Children } = useReactAdapter();
20
- const trackRef = useRef(null);
21
- const containerRef = useRef(null);
22
- const slides = Children.toArray(children);
23
- const [swiperInstance, setSwiperInstance] = useState(null);
24
- useEffect(() => {
25
- if (trackRef.current && containerRef.current && !swiperInstance) {
26
- const { current } = containerRef;
27
- const swiper = new Swiper(trackRef.current, {
28
- modules: [Autoplay, Navigation, Pagination],
29
- slidesPerView: 1,
30
- breakpoints: {
31
- 375: {
32
- slidesPerView: slidesPerView.xs ?? 1,
33
- },
34
- 576: {
35
- slidesPerView: slidesPerView.sm ?? 1,
36
- },
37
- 768: {
38
- slidesPerView: slidesPerView.md ?? 1,
39
- },
40
- 992: {
41
- slidesPerView: slidesPerView.lg ?? 1,
42
- },
43
- 1200: {
44
- slidesPerView: slidesPerView.xl ?? 1,
45
- },
17
+ const slidesPerView = { xs: 1, ...slidesPerViewDefault };
18
+ const { useLayoutEffect, useRef, Children } = useReactAdapter();
19
+ const trackRef = useRef(null);
20
+ const containerRef = useRef(null);
21
+ const slides = Children.toArray(children);
22
+ const initSwiper = (current, track, windowWidth) => {
23
+ if (!current || !track) {
24
+ return null;
25
+ }
26
+ return new Swiper(track, loopOnMobile && windowWidth && windowWidth < 768
27
+ ? {
28
+ modules: [Autoplay],
29
+ slidesPerView: "auto",
30
+ spaceBetween: 80,
31
+ loop: true,
32
+ speed: 5000,
33
+ allowTouchMove: false,
34
+ autoplay: {
35
+ delay: 1,
36
+ disableOnInteraction: false,
37
+ },
38
+ }
39
+ : {
40
+ modules: [Autoplay, Navigation, Pagination],
41
+ slidesPerView: 1,
42
+ breakpoints: {
43
+ 375: {
44
+ slidesPerView: slidesPerView.xs ?? 1,
45
+ },
46
+ 576: {
47
+ slidesPerView: slidesPerView.sm ?? 1,
48
+ },
49
+ 768: {
50
+ slidesPerView: slidesPerView.md ?? 1,
46
51
  },
47
- spaceBetween,
48
- loop,
49
- mousewheel: true,
50
- navigation: hasNavigation
51
- ? {
52
- nextEl: current.querySelector(".ga-ds-carousel__button--next"),
53
- prevEl: current.querySelector(".ga-ds-carousel__button--prev"),
54
- }
55
- : false,
56
- pagination: hasPagination
57
- ? {
58
- el: current.querySelector(".ga-ds-carousel__dots"),
59
- clickable: pagination ? pagination.clickable : false,
60
- bulletClass: "ga-ds-carousel__dot",
61
- bulletActiveClass: "ga-ds-carousel__dot--active",
62
- }
63
- : false,
64
- autoplay: autoplay
65
- ? { delay: autoplay.delay || 5000, disableOnInteraction: autoplay.disableOnInteraction ?? false }
66
- : false,
67
- speed: speed || 300,
68
- });
69
- setSwiperInstance(swiper);
52
+ 992: {
53
+ slidesPerView: slidesPerView.lg ?? 1,
54
+ },
55
+ 1200: {
56
+ slidesPerView: slidesPerView.xl ?? 1,
57
+ },
58
+ },
59
+ spaceBetween,
60
+ loop,
61
+ mousewheel: true,
62
+ navigation: hasNavigation
63
+ ? {
64
+ nextEl: current.querySelector(".ga-ds-carousel__button--next"),
65
+ prevEl: current.querySelector(".ga-ds-carousel__button--prev"),
66
+ }
67
+ : false,
68
+ pagination: hasPagination
69
+ ? {
70
+ el: current.querySelector(".ga-ds-carousel__dots"),
71
+ clickable: pagination ? pagination.clickable : false,
72
+ bulletClass: "ga-ds-carousel__dot",
73
+ bulletActiveClass: "ga-ds-carousel__dot--active",
74
+ }
75
+ : false,
76
+ autoplay: autoplay
77
+ ? {
78
+ delay: autoplay.delay || 5000,
79
+ disableOnInteraction: autoplay.disableOnInteraction ?? false,
80
+ }
81
+ : false,
82
+ speed: speed || 300,
83
+ });
84
+ };
85
+ useLayoutEffect(() => {
86
+ if (!trackRef.current || !containerRef.current) {
87
+ return;
88
+ }
89
+ const container = containerRef.current;
90
+ let swiper = initSwiper(container, trackRef.current, window.innerWidth);
91
+ let wasMobile = window.innerWidth < 768;
92
+ if (!loopOnMobile) {
93
+ return () => swiper?.destroy(true, true);
94
+ }
95
+ const handleResize = () => {
96
+ const isMobile = window.innerWidth < 768;
97
+ if (isMobile !== wasMobile) {
98
+ swiper?.destroy(true, true);
99
+ swiper = initSwiper(container, trackRef.current, window.innerWidth);
100
+ wasMobile = isMobile;
70
101
  }
71
- }, [slidesPerView, spaceBetween, navigation, pagination, hasNavigation, hasPagination, loop, trackRef, swiperInstance]);
72
- return (_jsxs("div", { className: `ga-carousel-swiper ${classes.join(" ")}`, ref: containerRef, children: [_jsx("div", { className: "swiper", ref: trackRef, children: _jsx("div", { className: "swiper-wrapper", children: slides.map((slide, index) => (_jsx("div", { className: "swiper-slide", children: slide }, index))) }) }), hasNavigation || hasPagination ? (_jsxs("div", { className: "ga-ds-carousel__navigation", children: [hasPagination && _jsx("div", { className: "ga-ds-carousel__dots" }), hasNavigation && _jsx(CarouselNavigation, {})] })) : null] }));
102
+ };
103
+ window.addEventListener("resize", handleResize);
104
+ return () => {
105
+ window.removeEventListener("resize", handleResize);
106
+ swiper?.destroy(true, true);
107
+ };
108
+ }, []);
109
+ if (!Swiper) {
110
+ return _jsx("div", { children: "Swiper library is not loaded." });
73
111
  }
74
- return _jsx("div", { children: "Swiper library is not loaded." });
112
+ return (_jsxs("div", { className: `ga-carousel-swiper ${loopOnMobile ? "ga-carousel-swiper--loop-on-mobile" : ""} ${classes.join(" ")}`, ref: containerRef, children: [_jsx("div", { className: "swiper", ref: trackRef, children: _jsx("div", { className: "swiper-wrapper", children: slides.map((slide, index) => (_jsx("div", { className: "swiper-slide", children: slide }, index))) }) }), hasNavigation || hasPagination ? (_jsxs("div", { className: "ga-ds-carousel__navigation", children: [hasPagination && _jsx("div", { className: "ga-ds-carousel__dots" }), hasNavigation && _jsx(CarouselNavigation, {})] })) : null] }));
75
113
  };
76
114
  const CarouselNavigation = () => {
77
115
  return (_jsxs("div", { className: `ga-ds-carousel__arrows`, children: [_jsx(Button, { extraClassNames: ["ga-ds-carousel__button", "ga-ds-carousel__button--prev"], icon: "chevron-left", ariaLabel: "Slide pr\u00E9c\u00E9dente" }), _jsx(Button, { extraClassNames: ["ga-ds-carousel__button", "ga-ds-carousel__button--next"], icon: "chevron-right", ariaLabel: "Slide suivante" })] }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-angels/ds-core",
3
- "version": "1.25.5",
3
+ "version": "2.0.0",
4
4
  "description": "Design system by Growth Angels",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -24,6 +24,7 @@ export type CarouselAttributes = {
24
24
  disableOnInteraction?: boolean;
25
25
  }
26
26
  speed?: number;
27
+ loopOnMobile?: boolean
27
28
  }
28
29
  export interface CarouselProps extends CarouselAttributes, WordpressDefault {
29
30
  children: React.ReactNode | React.ReactNode[]
@@ -16,6 +16,7 @@ export const CarouselSwiper = (props: CarouselProps) => {
16
16
  loop = false,
17
17
  autoplay,
18
18
  speed,
19
+ loopOnMobile = false,
19
20
  } = props
20
21
 
21
22
  const classes = ["ga-ds-carousel"]
@@ -27,86 +28,134 @@ export const CarouselSwiper = (props: CarouselProps) => {
27
28
  classes.push(...props.extraClassNames)
28
29
  }
29
30
  }
30
- if (Swiper) {
31
- const slidesPerView = { xs: 1, ...slidesPerViewDefault }
32
- const { useEffect, useState, useRef, Children } = useReactAdapter()
33
- const trackRef = useRef<HTMLDivElement>(null)
34
- const containerRef = useRef<HTMLDivElement>(null)
35
- const slides = Children.toArray(children)
36
31
 
37
- const [swiperInstance, setSwiperInstance] = useState<any>(null)
32
+ const slidesPerView = { xs: 1, ...slidesPerViewDefault }
33
+ const { useLayoutEffect, useRef, Children } = useReactAdapter()
34
+ const trackRef = useRef<HTMLDivElement>(null)
35
+ const containerRef = useRef<HTMLDivElement>(null)
36
+ const slides = Children.toArray(children)
38
37
 
39
- useEffect(() => {
40
- if (trackRef.current && containerRef.current && !swiperInstance) {
41
- const { current } = containerRef
42
- const swiper = new Swiper(trackRef.current, {
43
- modules: [Autoplay, Navigation, Pagination],
44
- slidesPerView: 1,
45
- breakpoints: {
46
- 375: {
47
- slidesPerView: (slidesPerView as Record<string, number>).xs ?? 1,
48
- },
49
- 576: {
50
- slidesPerView: (slidesPerView as Record<string, number>).sm ?? 1,
51
- },
52
- 768: {
53
- slidesPerView: (slidesPerView as Record<string, number>).md ?? 1,
54
- },
55
- 992: {
56
- slidesPerView: (slidesPerView as Record<string, number>).lg ?? 1,
38
+ const initSwiper = (current: HTMLElement | null, track: HTMLElement | null, windowWidth: number | null) => {
39
+ if (!current || !track) {
40
+ return null
41
+ }
42
+ return new Swiper(
43
+ track,
44
+ loopOnMobile && windowWidth && windowWidth < 768
45
+ ? {
46
+ modules: [Autoplay],
47
+ slidesPerView: "auto",
48
+ spaceBetween: 80,
49
+ loop: true,
50
+ speed: 5000,
51
+ allowTouchMove: false,
52
+ autoplay: {
53
+ delay: 1,
54
+ disableOnInteraction: false,
57
55
  },
58
- 1200: {
59
- slidesPerView: (slidesPerView as Record<string, number>).xl ?? 1,
56
+ }
57
+ : {
58
+ modules: [Autoplay, Navigation, Pagination],
59
+ slidesPerView: 1,
60
+ breakpoints: {
61
+ 375: {
62
+ slidesPerView: (slidesPerView as Record<string, number>).xs ?? 1,
63
+ },
64
+ 576: {
65
+ slidesPerView: (slidesPerView as Record<string, number>).sm ?? 1,
66
+ },
67
+ 768: {
68
+ slidesPerView: (slidesPerView as Record<string, number>).md ?? 1,
69
+ },
70
+ 992: {
71
+ slidesPerView: (slidesPerView as Record<string, number>).lg ?? 1,
72
+ },
73
+ 1200: {
74
+ slidesPerView: (slidesPerView as Record<string, number>).xl ?? 1,
75
+ },
60
76
  },
77
+ spaceBetween,
78
+ loop,
79
+ mousewheel: true,
80
+ navigation: hasNavigation
81
+ ? {
82
+ nextEl: current.querySelector(".ga-ds-carousel__button--next") as HTMLElement,
83
+ prevEl: current.querySelector(".ga-ds-carousel__button--prev") as HTMLElement,
84
+ }
85
+ : false,
86
+ pagination: hasPagination
87
+ ? {
88
+ el: current.querySelector(".ga-ds-carousel__dots") as HTMLElement,
89
+ clickable: pagination ? pagination.clickable : false,
90
+ bulletClass: "ga-ds-carousel__dot",
91
+ bulletActiveClass: "ga-ds-carousel__dot--active",
92
+ }
93
+ : false,
94
+ autoplay: autoplay
95
+ ? {
96
+ delay: autoplay.delay || 5000,
97
+ disableOnInteraction: autoplay.disableOnInteraction ?? false,
98
+ }
99
+ : false,
100
+ speed: speed || 300,
61
101
  },
62
- spaceBetween,
63
- loop,
64
- mousewheel: true,
65
- navigation: hasNavigation
66
- ? {
67
- nextEl: current.querySelector(".ga-ds-carousel__button--next") as HTMLElement,
68
- prevEl: current.querySelector(".ga-ds-carousel__button--prev") as HTMLElement,
69
- }
70
- : false,
71
- pagination: hasPagination
72
- ? {
73
- el: current.querySelector(".ga-ds-carousel__dots") as HTMLElement,
74
- clickable: pagination ? pagination.clickable : false,
75
- bulletClass: "ga-ds-carousel__dot",
76
- bulletActiveClass: "ga-ds-carousel__dot--active",
77
- }
78
- : false,
79
- autoplay: autoplay
80
- ? { delay: autoplay.delay || 5000, disableOnInteraction: autoplay.disableOnInteraction ?? false }
81
- : false,
82
- speed: speed || 300,
83
- })
102
+ )
103
+ }
104
+ useLayoutEffect(() => {
105
+ if (!trackRef.current || !containerRef.current) {
106
+ return
107
+ }
108
+ const container = containerRef.current
109
+ let swiper = initSwiper(container, trackRef.current, window.innerWidth)
110
+ let wasMobile = window.innerWidth < 768
111
+
112
+ if (!loopOnMobile) {
113
+ return () => swiper?.destroy(true, true)
114
+ }
84
115
 
85
- setSwiperInstance(swiper)
116
+ const handleResize = () => {
117
+ const isMobile = window.innerWidth < 768
118
+ if (isMobile !== wasMobile) {
119
+ swiper?.destroy(true, true)
120
+ swiper = initSwiper(container, trackRef.current, window.innerWidth)
121
+ wasMobile = isMobile
86
122
  }
87
- }, [slidesPerView, spaceBetween, navigation, pagination, hasNavigation, hasPagination, loop, trackRef, swiperInstance])
123
+ }
124
+
125
+ window.addEventListener("resize", handleResize)
88
126
 
89
- return (
90
- <div className={`ga-carousel-swiper ${classes.join(" ")}`} ref={containerRef}>
91
- <div className="swiper" ref={trackRef}>
92
- <div className="swiper-wrapper">
93
- {slides.map((slide, index) => (
94
- <div className="swiper-slide" key={index}>
95
- {slide}
96
- </div>
97
- ))}
98
- </div>
127
+ return () => {
128
+ window.removeEventListener("resize", handleResize)
129
+ swiper?.destroy(true, true)
130
+ }
131
+ }, [])
132
+
133
+ if (!Swiper) {
134
+ return <div>Swiper library is not loaded.</div>
135
+ }
136
+
137
+ return (
138
+ <div
139
+ className={`ga-carousel-swiper ${loopOnMobile ? "ga-carousel-swiper--loop-on-mobile" : ""} ${classes.join(" ")}`}
140
+ ref={containerRef}
141
+ >
142
+ <div className="swiper" ref={trackRef}>
143
+ <div className="swiper-wrapper">
144
+ {slides.map((slide, index) => (
145
+ <div className="swiper-slide" key={index}>
146
+ {slide}
147
+ </div>
148
+ ))}
99
149
  </div>
100
- {hasNavigation || hasPagination ? (
101
- <div className="ga-ds-carousel__navigation">
102
- {hasPagination && <div className="ga-ds-carousel__dots"></div>}
103
- {hasNavigation && <CarouselNavigation />}
104
- </div>
105
- ) : null}
106
150
  </div>
107
- )
108
- }
109
- return <div>Swiper library is not loaded.</div>
151
+ {hasNavigation || hasPagination ? (
152
+ <div className="ga-ds-carousel__navigation">
153
+ {hasPagination && <div className="ga-ds-carousel__dots"></div>}
154
+ {hasNavigation && <CarouselNavigation />}
155
+ </div>
156
+ ) : null}
157
+ </div>
158
+ )
110
159
  }
111
160
 
112
161
  const CarouselNavigation = () => {