@growth-angels/ds-core 1.16.3 → 1.17.1
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.
- package/dist/lib/hydrate-carousel.d.ts +2 -0
- package/dist/lib/hydrate-carousel.js +11 -4
- package/dist/organisms/Carousel/Carousel.stories.d.ts +1 -0
- package/dist/organisms/Carousel/Carousel.stories.js +24 -0
- package/dist/organisms/Carousel/CarouselSwiper.d.ts +2 -0
- package/dist/organisms/Carousel/CarouselSwiper.js +74 -0
- package/dist/organisms/Carousel/CarouselSwiper.stories.d.ts +6 -0
- package/dist/organisms/Carousel/CarouselSwiper.stories.js +31 -0
- package/package.json +3 -2
- package/src/lib/hydrate-carousel.tsx +11 -4
- package/src/organisms/Carousel/Carousel.scss +1 -0
- package/src/organisms/Carousel/Carousel.stories.tsx +25 -0
- package/src/organisms/Carousel/CarouselSwiper.stories.tsx +35 -0
- package/src/organisms/Carousel/CarouselSwiper.tsx +113 -0
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { CarouselSwiper } from "../organisms/Carousel/CarouselSwiper";
|
|
3
3
|
import { useReactAdapter } from "../hooks/useReactAdaptater";
|
|
4
4
|
import { NativeChildWrapper } from "./utils/native-child-wrapper";
|
|
5
|
-
|
|
5
|
+
import Swiper from "swiper";
|
|
6
|
+
import * as modules from "swiper/modules";
|
|
7
|
+
window.Swiper = {
|
|
8
|
+
instance: Swiper,
|
|
9
|
+
modules,
|
|
10
|
+
};
|
|
11
|
+
import "swiper/css";
|
|
12
|
+
import "swiper/css/autoplay";
|
|
13
|
+
const { createElement, createRoot } = useReactAdapter();
|
|
6
14
|
export function HydrateCarousel(islands) {
|
|
7
|
-
console.log("HydrateCarousel called with islands:", islands);
|
|
8
15
|
islands?.forEach((carousel) => {
|
|
9
|
-
const Component =
|
|
16
|
+
const Component = CarouselSwiper;
|
|
10
17
|
if (!Component)
|
|
11
18
|
return;
|
|
12
19
|
const props = carousel.getAttribute("data-props");
|
|
@@ -60,3 +60,27 @@ export const NotOverflowing = {
|
|
|
60
60
|
hasPagination: true,
|
|
61
61
|
},
|
|
62
62
|
};
|
|
63
|
+
export const SwiperCarousel = {
|
|
64
|
+
args: {
|
|
65
|
+
context: "wp-editor",
|
|
66
|
+
children: [
|
|
67
|
+
_jsx("div", { children: "Slide 1" }),
|
|
68
|
+
_jsx("div", { children: "Slide 2" }),
|
|
69
|
+
_jsx("div", { children: "Slide 3" }),
|
|
70
|
+
_jsx("div", { children: "Slide 4" }),
|
|
71
|
+
_jsx("div", { children: "Slide 5" }),
|
|
72
|
+
_jsx("div", { children: "Slide 6" }),
|
|
73
|
+
_jsx("div", { children: "Slide 7" }),
|
|
74
|
+
],
|
|
75
|
+
slidesPerView: { sm: 1, md: 2, lg: 3, xl: 4 },
|
|
76
|
+
spaceBetween: 16,
|
|
77
|
+
pagination: {
|
|
78
|
+
clickable: true,
|
|
79
|
+
},
|
|
80
|
+
navigation: {
|
|
81
|
+
positionY: "bottom",
|
|
82
|
+
},
|
|
83
|
+
hasNavigation: true,
|
|
84
|
+
hasPagination: true,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useReactAdapter } from "../../hooks/useReactAdaptater";
|
|
3
|
+
import { Button } from "../../atoms/atoms";
|
|
4
|
+
import Swiper from "swiper";
|
|
5
|
+
import { Autoplay, Navigation, Pagination } from "swiper/modules";
|
|
6
|
+
export const CarouselSwiper = (props) => {
|
|
7
|
+
const { children, slidesPerView: slidesPerViewDefault, spaceBetween = 48, navigation, pagination, hasPagination, hasNavigation, loop = false, } = props;
|
|
8
|
+
const classes = ["ga-ds-carousel"];
|
|
9
|
+
if (props.extraClassNames) {
|
|
10
|
+
if (typeof props.extraClassNames === "string") {
|
|
11
|
+
classes.push(props.extraClassNames);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
classes.push(...props.extraClassNames);
|
|
15
|
+
}
|
|
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
|
+
},
|
|
46
|
+
},
|
|
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
|
+
});
|
|
65
|
+
setSwiperInstance(swiper);
|
|
66
|
+
}
|
|
67
|
+
}, [slidesPerView, spaceBetween, navigation, pagination, hasNavigation, hasPagination, loop, trackRef, swiperInstance]);
|
|
68
|
+
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] }));
|
|
69
|
+
}
|
|
70
|
+
return _jsx("div", { children: "Swiper library is not loaded." });
|
|
71
|
+
};
|
|
72
|
+
const CarouselNavigation = () => {
|
|
73
|
+
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" })] }));
|
|
74
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { CarouselSwiper } from "./CarouselSwiper";
|
|
3
|
+
declare const meta: Meta<typeof CarouselSwiper>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof CarouselSwiper>;
|
|
6
|
+
export declare const Primary: Story;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { CarouselSwiper } from "./CarouselSwiper";
|
|
3
|
+
const meta = {
|
|
4
|
+
title: "Organisms/CarouselSwiper",
|
|
5
|
+
component: CarouselSwiper,
|
|
6
|
+
tags: ["autodocs"],
|
|
7
|
+
};
|
|
8
|
+
export default meta;
|
|
9
|
+
export const Primary = {
|
|
10
|
+
args: {
|
|
11
|
+
children: [
|
|
12
|
+
_jsx("div", { children: "Slide 1" }),
|
|
13
|
+
_jsx("div", { children: "Slide 2" }),
|
|
14
|
+
_jsx("div", { children: "Slide 3" }),
|
|
15
|
+
_jsx("div", { children: "Slide 4" }),
|
|
16
|
+
_jsx("div", { children: "Slide 5" }),
|
|
17
|
+
_jsx("div", { children: "Slide 6" }),
|
|
18
|
+
_jsx("div", { children: "Slide 7" }),
|
|
19
|
+
],
|
|
20
|
+
slidesPerView: { sm: 1, md: 2, lg: 3, xl: 4 },
|
|
21
|
+
spaceBetween: 16,
|
|
22
|
+
pagination: {
|
|
23
|
+
clickable: true,
|
|
24
|
+
},
|
|
25
|
+
navigation: {
|
|
26
|
+
positionY: "bottom",
|
|
27
|
+
},
|
|
28
|
+
hasNavigation: true,
|
|
29
|
+
hasPagination: true,
|
|
30
|
+
},
|
|
31
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@growth-angels/ds-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.1",
|
|
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": "^12.0.3"
|
|
41
42
|
},
|
|
42
43
|
"peerDependencies": {
|
|
43
44
|
"react": ">=18"
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CarouselSwiper } from "../organisms/Carousel/CarouselSwiper"
|
|
2
2
|
import { useReactAdapter } from "../hooks/useReactAdaptater"
|
|
3
3
|
import { NativeChildWrapper } from "./utils/native-child-wrapper"
|
|
4
|
-
|
|
4
|
+
import Swiper from "swiper"
|
|
5
|
+
import * as modules from "swiper/modules"
|
|
6
|
+
;(window as any).Swiper = {
|
|
7
|
+
instance: Swiper,
|
|
8
|
+
modules,
|
|
9
|
+
}
|
|
10
|
+
import "swiper/css"
|
|
11
|
+
import "swiper/css/autoplay"
|
|
12
|
+
const { createElement, createRoot } = useReactAdapter()
|
|
5
13
|
|
|
6
14
|
export function HydrateCarousel(islands: NodeListOf<Element> | null) {
|
|
7
|
-
console.log("HydrateCarousel called with islands:", islands)
|
|
8
15
|
islands?.forEach((carousel) => {
|
|
9
|
-
const Component =
|
|
16
|
+
const Component = CarouselSwiper
|
|
10
17
|
if (!Component) return
|
|
11
18
|
const props = carousel.getAttribute("data-props")
|
|
12
19
|
carousel.removeAttribute("data-props")
|
|
@@ -66,3 +66,28 @@ export const NotOverflowing: Story = {
|
|
|
66
66
|
hasPagination: true,
|
|
67
67
|
},
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
export const SwiperCarousel: Story = {
|
|
71
|
+
args: {
|
|
72
|
+
context: "wp-editor",
|
|
73
|
+
children: [
|
|
74
|
+
<div>Slide 1</div>,
|
|
75
|
+
<div>Slide 2</div>,
|
|
76
|
+
<div>Slide 3</div>,
|
|
77
|
+
<div>Slide 4</div>,
|
|
78
|
+
<div>Slide 5</div>,
|
|
79
|
+
<div>Slide 6</div>,
|
|
80
|
+
<div>Slide 7</div>,
|
|
81
|
+
],
|
|
82
|
+
slidesPerView: { sm: 1, md: 2, lg: 3, xl: 4 },
|
|
83
|
+
spaceBetween: 16,
|
|
84
|
+
pagination: {
|
|
85
|
+
clickable: true,
|
|
86
|
+
},
|
|
87
|
+
navigation: {
|
|
88
|
+
positionY: "bottom",
|
|
89
|
+
},
|
|
90
|
+
hasNavigation: true,
|
|
91
|
+
hasPagination: true,
|
|
92
|
+
},
|
|
93
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
2
|
+
import { CarouselSwiper } from "./CarouselSwiper"
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof CarouselSwiper> = {
|
|
5
|
+
title: "Organisms/CarouselSwiper",
|
|
6
|
+
component: CarouselSwiper,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default meta
|
|
11
|
+
type Story = StoryObj<typeof CarouselSwiper>
|
|
12
|
+
|
|
13
|
+
export const Primary: Story = {
|
|
14
|
+
args: {
|
|
15
|
+
children: [
|
|
16
|
+
<div>Slide 1</div>,
|
|
17
|
+
<div>Slide 2</div>,
|
|
18
|
+
<div>Slide 3</div>,
|
|
19
|
+
<div>Slide 4</div>,
|
|
20
|
+
<div>Slide 5</div>,
|
|
21
|
+
<div>Slide 6</div>,
|
|
22
|
+
<div>Slide 7</div>,
|
|
23
|
+
],
|
|
24
|
+
slidesPerView: { sm: 1, md: 2, lg: 3, xl: 4 },
|
|
25
|
+
spaceBetween: 16,
|
|
26
|
+
pagination: {
|
|
27
|
+
clickable: true,
|
|
28
|
+
},
|
|
29
|
+
navigation: {
|
|
30
|
+
positionY: "bottom",
|
|
31
|
+
},
|
|
32
|
+
hasNavigation: true,
|
|
33
|
+
hasPagination: true,
|
|
34
|
+
},
|
|
35
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { useReactAdapter } from "../../hooks/useReactAdaptater"
|
|
2
|
+
import { CarouselProps } from "./Carousel.types"
|
|
3
|
+
import { Button } from "../../atoms/atoms"
|
|
4
|
+
import Swiper from "swiper"
|
|
5
|
+
import { Autoplay, Navigation, Pagination } from "swiper/modules"
|
|
6
|
+
|
|
7
|
+
export const CarouselSwiper = (props: CarouselProps) => {
|
|
8
|
+
const {
|
|
9
|
+
children,
|
|
10
|
+
slidesPerView: slidesPerViewDefault,
|
|
11
|
+
spaceBetween = 48,
|
|
12
|
+
navigation,
|
|
13
|
+
pagination,
|
|
14
|
+
hasPagination,
|
|
15
|
+
hasNavigation,
|
|
16
|
+
loop = false,
|
|
17
|
+
} = props
|
|
18
|
+
|
|
19
|
+
const classes = ["ga-ds-carousel"]
|
|
20
|
+
|
|
21
|
+
if (props.extraClassNames) {
|
|
22
|
+
if (typeof props.extraClassNames === "string") {
|
|
23
|
+
classes.push(props.extraClassNames)
|
|
24
|
+
} else {
|
|
25
|
+
classes.push(...props.extraClassNames)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (Swiper) {
|
|
29
|
+
const slidesPerView = { xs: 1, ...slidesPerViewDefault }
|
|
30
|
+
const { useEffect, useState, useRef, Children } = useReactAdapter()
|
|
31
|
+
const trackRef = useRef<HTMLDivElement>(null)
|
|
32
|
+
const containerRef = useRef<HTMLDivElement>(null)
|
|
33
|
+
const slides = Children.toArray(children)
|
|
34
|
+
|
|
35
|
+
const [swiperInstance, setSwiperInstance] = useState<any>(null)
|
|
36
|
+
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (trackRef.current && containerRef.current && !swiperInstance) {
|
|
39
|
+
const { current } = containerRef
|
|
40
|
+
const swiper = new Swiper(trackRef.current, {
|
|
41
|
+
modules: [Autoplay, Navigation, Pagination],
|
|
42
|
+
slidesPerView: 1,
|
|
43
|
+
breakpoints: {
|
|
44
|
+
375: {
|
|
45
|
+
slidesPerView: (slidesPerView as Record<string, number>).xs ?? 1,
|
|
46
|
+
},
|
|
47
|
+
576: {
|
|
48
|
+
slidesPerView: (slidesPerView as Record<string, number>).sm ?? 1,
|
|
49
|
+
},
|
|
50
|
+
768: {
|
|
51
|
+
slidesPerView: (slidesPerView as Record<string, number>).md ?? 1,
|
|
52
|
+
},
|
|
53
|
+
992: {
|
|
54
|
+
slidesPerView: (slidesPerView as Record<string, number>).lg ?? 1,
|
|
55
|
+
},
|
|
56
|
+
1200: {
|
|
57
|
+
slidesPerView: (slidesPerView as Record<string, number>).xl ?? 1,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
spaceBetween,
|
|
61
|
+
loop,
|
|
62
|
+
mousewheel: true,
|
|
63
|
+
navigation: hasNavigation
|
|
64
|
+
? {
|
|
65
|
+
nextEl: current.querySelector(".ga-ds-carousel__button--next") as HTMLElement,
|
|
66
|
+
prevEl: current.querySelector(".ga-ds-carousel__button--prev") as HTMLElement,
|
|
67
|
+
}
|
|
68
|
+
: false,
|
|
69
|
+
pagination: hasPagination
|
|
70
|
+
? {
|
|
71
|
+
el: current.querySelector(".ga-ds-carousel__dots") as HTMLElement,
|
|
72
|
+
clickable: pagination ? pagination.clickable : false,
|
|
73
|
+
bulletClass: "ga-ds-carousel__dot",
|
|
74
|
+
bulletActiveClass: "ga-ds-carousel__dot--active",
|
|
75
|
+
}
|
|
76
|
+
: false,
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
setSwiperInstance(swiper)
|
|
80
|
+
}
|
|
81
|
+
}, [slidesPerView, spaceBetween, navigation, pagination, hasNavigation, hasPagination, loop, trackRef, swiperInstance])
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<div className={`ga-carousel-swiper ${classes.join(" ")}`} ref={containerRef}>
|
|
85
|
+
<div className="swiper" ref={trackRef}>
|
|
86
|
+
<div className="swiper-wrapper">
|
|
87
|
+
{slides.map((slide, index) => (
|
|
88
|
+
<div className="swiper-slide" key={index}>
|
|
89
|
+
{slide}
|
|
90
|
+
</div>
|
|
91
|
+
))}
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
{hasNavigation || hasPagination ? (
|
|
95
|
+
<div className="ga-ds-carousel__navigation">
|
|
96
|
+
{hasPagination && <div className="ga-ds-carousel__dots"></div>}
|
|
97
|
+
{hasNavigation && <CarouselNavigation />}
|
|
98
|
+
</div>
|
|
99
|
+
) : null}
|
|
100
|
+
</div>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
return <div>Swiper library is not loaded.</div>
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const CarouselNavigation = () => {
|
|
107
|
+
return (
|
|
108
|
+
<div className={`ga-ds-carousel__arrows`}>
|
|
109
|
+
<Button extraClassNames={["ga-ds-carousel__button", "ga-ds-carousel__button--prev"]} icon="chevron-left" />
|
|
110
|
+
<Button extraClassNames={["ga-ds-carousel__button", "ga-ds-carousel__button--next"]} icon="chevron-right" />
|
|
111
|
+
</div>
|
|
112
|
+
)
|
|
113
|
+
}
|