@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.
@@ -1 +1,3 @@
1
+ import "swiper/css";
2
+ import "swiper/css/autoplay";
1
3
  export declare function HydrateCarousel(islands: NodeListOf<Element> | null): void;
@@ -1,12 +1,19 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Carousel } from "../organisms/Carousel/Carousel";
2
+ import { CarouselSwiper } from "../organisms/Carousel/CarouselSwiper";
3
3
  import { useReactAdapter } from "../hooks/useReactAdaptater";
4
4
  import { NativeChildWrapper } from "./utils/native-child-wrapper";
5
- const { createElement, createRoot, useRef, useEffect } = useReactAdapter();
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 = Carousel;
16
+ const Component = CarouselSwiper;
10
17
  if (!Component)
11
18
  return;
12
19
  const props = carousel.getAttribute("data-props");
@@ -6,3 +6,4 @@ type Story = StoryObj<typeof Carousel>;
6
6
  export declare const Primary: Story;
7
7
  export declare const LoopingCarousel: Story;
8
8
  export declare const NotOverflowing: Story;
9
+ export declare const SwiperCarousel: Story;
@@ -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,2 @@
1
+ import { CarouselProps } from "./Carousel.types";
2
+ export declare const CarouselSwiper: (props: CarouselProps) => import("react/jsx-runtime").JSX.Element;
@@ -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.16.3",
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 { Carousel } from "../organisms/Carousel/Carousel"
1
+ import { CarouselSwiper } from "../organisms/Carousel/CarouselSwiper"
2
2
  import { useReactAdapter } from "../hooks/useReactAdaptater"
3
3
  import { NativeChildWrapper } from "./utils/native-child-wrapper"
4
- const { createElement, createRoot, useRef, useEffect } = useReactAdapter()
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 = Carousel
16
+ const Component = CarouselSwiper
10
17
  if (!Component) return
11
18
  const props = carousel.getAttribute("data-props")
12
19
  carousel.removeAttribute("data-props")
@@ -50,6 +50,7 @@
50
50
 
51
51
  &__arrows {
52
52
  display: flex;
53
+ gap: 0.8rem;
53
54
 
54
55
  &.left {
55
56
  justify-content: flex-start;
@@ -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
+ }