astro-swiper 2.2.1 → 2.3.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.
- package/package.json +9 -3
- package/src/components/Swiper.astro +99 -37
- package/src/index.ts +27 -1
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-swiper",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Astro component for swiper, dedicated to slider / carousel / photo swiper / slide, including thumbnails",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "index.js",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"format": "biome format --write && prettier -w \"**/*.astro\"",
|
|
@@ -18,14 +19,19 @@
|
|
|
18
19
|
"url": "https://github.com/pascal-brand38/astro-swiper/issues"
|
|
19
20
|
},
|
|
20
21
|
"homepage": "https://github.com/pascal-brand38/astro-swiper",
|
|
21
|
-
"exports":
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./index.ts",
|
|
25
|
+
"default": "./index.ts"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
22
28
|
"files": [
|
|
23
29
|
"index.ts",
|
|
24
30
|
"src/**"
|
|
25
31
|
],
|
|
26
32
|
"engines": {
|
|
27
33
|
"pnpm": ">=10.30.3",
|
|
28
|
-
"node": ">=
|
|
34
|
+
"node": ">=20"
|
|
29
35
|
},
|
|
30
36
|
"packageManager": "pnpm@10.30.3",
|
|
31
37
|
"devDependencies": {
|
|
@@ -43,13 +43,13 @@ const {
|
|
|
43
43
|
|
|
44
44
|
<script>
|
|
45
45
|
import Swiper from 'swiper/bundle';
|
|
46
|
-
import type {
|
|
46
|
+
import type { AstroSwiperOptions } from 'astro-swiper';
|
|
47
47
|
|
|
48
48
|
/** contains the swiper json object once created, for each uniqueClass */
|
|
49
49
|
const _useSwiper: { [uniqueClass: string]: Swiper } = {};
|
|
50
50
|
|
|
51
51
|
/** contains the option used when creating the swiper object for each uniqueClass */
|
|
52
|
-
const _useOptions: { [uniqueClass: string]:
|
|
52
|
+
const _useOptions: { [uniqueClass: string]: AstroSwiperOptions } = {};
|
|
53
53
|
|
|
54
54
|
/** contains all the uniqueClass that have their swiper object delayed because the
|
|
55
55
|
* related thumbnail swiper is not created yet
|
|
@@ -57,6 +57,92 @@ const {
|
|
|
57
57
|
*/
|
|
58
58
|
const _useDelaySwiper: { [uniqueClass: string]: string } = {};
|
|
59
59
|
|
|
60
|
+
// Init swipers that have delayed initialization because the thumbnail swiper is not created yet
|
|
61
|
+
// If this is now the case, then it is intialized, as well as its observer if needed
|
|
62
|
+
function _initDelayedSwipers() {
|
|
63
|
+
Object.keys(_useDelaySwiper).forEach((delayedClass) => {
|
|
64
|
+
// swiper of uniqueClass "delayedClass" is delayed because it needs the swiper of uniqueClass
|
|
65
|
+
// "delayedThumbClass" to be created first
|
|
66
|
+
const delayedThumbClass = _useDelaySwiper[delayedClass];
|
|
67
|
+
if (_useSwiper[delayedThumbClass]) {
|
|
68
|
+
// the thumbnail swiper is created, we can create the swiper
|
|
69
|
+
delete _useDelaySwiper[delayedClass]; // remove it from the delayed list
|
|
70
|
+
const delayedOptions = _useOptions[delayedClass];
|
|
71
|
+
delayedOptions.thumbs = {
|
|
72
|
+
swiper: _useSwiper[delayedThumbClass], // add the thumbnail swiper link to the options
|
|
73
|
+
...delayedOptions.thumbs,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
_createSwiperAndObserver(delayedClass, delayedOptions, (document.querySelector(`.${delayedClass}`) as AstroSwiper));
|
|
77
|
+
_useOptions[delayedClass] = delayedOptions; // update the options with the thumbnail link
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// initialize the swiper instance
|
|
83
|
+
// the autoplay may be stopped manually if it should be started by the observer
|
|
84
|
+
function _initSwiper(uniqueClass: string, options: AstroSwiperOptions, element: AstroSwiper) {
|
|
85
|
+
const swiper = new Swiper(`.${uniqueClass}`, options);
|
|
86
|
+
_useSwiper[uniqueClass] = swiper;
|
|
87
|
+
element.astroSwiper = swiper;
|
|
88
|
+
|
|
89
|
+
// stop the autoplay if it will be started by the observer
|
|
90
|
+
if (options.astro?.intersectionObserver?.controlAutoplay && options.autoplay) {
|
|
91
|
+
swiper.autoplay.stop();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
_initDelayedSwipers();
|
|
95
|
+
return swiper;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function _createObserver(uniqueClass: string, options: AstroSwiperOptions, element: AstroSwiper) {
|
|
99
|
+
const observerOptions = options.astro?.intersectionObserver || {};
|
|
100
|
+
const observer = new IntersectionObserver(
|
|
101
|
+
(entries) => {
|
|
102
|
+
if (entries[0].isIntersecting) {
|
|
103
|
+
if (observerOptions?.initSwiper && !element.astroSwiper) {
|
|
104
|
+
_initSwiper(uniqueClass, options, element);
|
|
105
|
+
if (observerOptions?.disconnectOnInit) {
|
|
106
|
+
observer.disconnect();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const swiper = element?.astroSwiper
|
|
112
|
+
if (!swiper) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (observerOptions?.controlAutoplay && options.autoplay) {
|
|
117
|
+
if (entries[0].isIntersecting) {
|
|
118
|
+
swiper.autoplay.start();
|
|
119
|
+
} else {
|
|
120
|
+
swiper.autoplay.stop();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
observerOptions.options,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
observer.observe(element);
|
|
128
|
+
window.addEventListener("unload", observer.disconnect);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// create the swiper and the observer
|
|
132
|
+
// - init the swiper if it should not be done by the observer
|
|
133
|
+
// - create the observer if required
|
|
134
|
+
function _createSwiperAndObserver(uniqueClass: string, options: AstroSwiperOptions, element: AstroSwiper) {
|
|
135
|
+
if (!(options.astro?.intersectionObserver?.initSwiper)) {
|
|
136
|
+
// create the swiper immediatly
|
|
137
|
+
_initSwiper(uniqueClass, options, element);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// create the observer. It may init the swiper
|
|
141
|
+
if (options.astro?.intersectionObserver) {
|
|
142
|
+
_createObserver(uniqueClass, options, element);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
60
146
|
class AstroSwiper extends HTMLElement {
|
|
61
147
|
/** pointer to the swiper structure that was created using "new",
|
|
62
148
|
* even when not initialized */
|
|
@@ -67,50 +153,26 @@ const {
|
|
|
67
153
|
this.astroSwiper = undefined;
|
|
68
154
|
|
|
69
155
|
// Read the message from the data attribute.
|
|
70
|
-
const options = JSON.parse(this.dataset.options || '{}');
|
|
156
|
+
const options: AstroSwiperOptions = JSON.parse(this.dataset.options || '{}');
|
|
71
157
|
// to have more than 1 swiper in a single page
|
|
72
158
|
const uniqueClass = this.dataset.uniqueclass || '';
|
|
73
159
|
const linkToThumbUniqueClass = this.dataset.linktothumbuniqueclass || '';
|
|
74
160
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this.astroSwiper = swiper;
|
|
80
|
-
} else {
|
|
81
|
-
// a thumbnail link is provided
|
|
82
|
-
// if the thumbnail swiper is already created, the main slider can be created also
|
|
83
|
-
// otherwise, it will be added in the delayed swiper list
|
|
84
|
-
if (_useSwiper[linkToThumbUniqueClass] !== undefined) {
|
|
161
|
+
// no thumbnail link, or link to thumbnail swiper already created,
|
|
162
|
+
// the swiper can be created or not immediatly depending on the observer option
|
|
163
|
+
if (!linkToThumbUniqueClass || _useSwiper[linkToThumbUniqueClass]) {
|
|
164
|
+
if (linkToThumbUniqueClass) {
|
|
85
165
|
options.thumbs = { swiper: _useSwiper[linkToThumbUniqueClass], ...options.thumbs };
|
|
86
|
-
const swiper = new Swiper(`.${uniqueClass}`, options);
|
|
87
|
-
_useSwiper[uniqueClass] = swiper;
|
|
88
|
-
this.astroSwiper = swiper;
|
|
89
|
-
} else {
|
|
90
|
-
// cannot create the swiper as the thumbnail swiper not created yet
|
|
91
|
-
// will be done later
|
|
92
|
-
_useDelaySwiper[uniqueClass] = linkToThumbUniqueClass;
|
|
93
166
|
}
|
|
167
|
+
// create the swiper and the observer if needed
|
|
168
|
+
_createSwiperAndObserver(uniqueClass, options, this);
|
|
169
|
+
} else {
|
|
170
|
+
// cannot create the swiper as the thumbnail swiper not created yet
|
|
171
|
+
// is delayed until the thumbnail swiper is initialized.
|
|
172
|
+
_useDelaySwiper[uniqueClass] = linkToThumbUniqueClass;
|
|
94
173
|
}
|
|
95
174
|
|
|
96
175
|
_useOptions[uniqueClass] = options;
|
|
97
|
-
|
|
98
|
-
// look if any delayed swiper can be created, that is its related thumbnail swiper is now created
|
|
99
|
-
Object.keys(_useDelaySwiper).forEach((delayedClass) => {
|
|
100
|
-
const delayedThumbClass = _useDelaySwiper[delayedClass];
|
|
101
|
-
if (_useSwiper[delayedThumbClass] !== undefined) {
|
|
102
|
-
const delayedOptions = _useOptions[delayedClass];
|
|
103
|
-
delayedOptions.thumbs = {
|
|
104
|
-
swiper: _useSwiper[delayedThumbClass],
|
|
105
|
-
...delayedOptions.thumbs,
|
|
106
|
-
};
|
|
107
|
-
const swiper = new Swiper(`.${delayedClass}`, delayedOptions);
|
|
108
|
-
_useSwiper[delayedClass] = swiper;
|
|
109
|
-
(document.querySelector(`.${delayedClass}`) as AstroSwiper).astroSwiper = swiper;
|
|
110
|
-
_useOptions[delayedClass] = delayedOptions;
|
|
111
|
-
delete _useDelaySwiper[delayedClass];
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
176
|
}
|
|
115
177
|
}
|
|
116
178
|
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,32 @@
|
|
|
4
4
|
import type { Swiper, SwiperOptions } from 'swiper/types';
|
|
5
5
|
import type { HTMLAttributes } from 'astro/types';
|
|
6
6
|
|
|
7
|
+
/** Swiper options for the Astro component.
|
|
8
|
+
* Basically the same as the original SwiperOptions, but extended
|
|
9
|
+
* with new capabilities
|
|
10
|
+
*/
|
|
11
|
+
export interface AstroSwiperOptions extends SwiperOptions {
|
|
12
|
+
/** options specific to astro-swiper component */
|
|
13
|
+
astro?: {
|
|
14
|
+
/** intersection observer options: an observer can be added to control the swiper when it appears / disappears in the screen.
|
|
15
|
+
* The observer is created using IntersectionObserver
|
|
16
|
+
* The behavior of the observer is controlled by the following properties
|
|
17
|
+
* When observer is not provided, no observer is created.
|
|
18
|
+
*/
|
|
19
|
+
intersectionObserver?: {
|
|
20
|
+
/** true to initialize the swiper when the element appears in the screen */
|
|
21
|
+
initSwiper?: boolean;
|
|
22
|
+
/** true to disconnect the observer once the swiper is initialized */
|
|
23
|
+
disconnectOnInit?: boolean;
|
|
24
|
+
/** true to start and stop the autoplay when the swiper appears and disappears from the screen, respectively. */
|
|
25
|
+
controlAutoplay?: boolean;
|
|
26
|
+
/** options for the IntersectionObserver */
|
|
27
|
+
options?: IntersectionObserverInit;
|
|
28
|
+
}
|
|
29
|
+
/** TODO: uniqueClass and linkToThumbUniqueClass may be part of it */
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
7
33
|
/** properties passed to the <Swiper> component
|
|
8
34
|
* It extends a div (that is may have class, style,...), plus other attributes
|
|
9
35
|
* Note that all other components (<SwiperSlide>, <SwiperButtonNext>...) extends a div only
|
|
@@ -12,7 +38,7 @@ export interface AstroSwiperType extends HTMLAttributes<'div'> {
|
|
|
12
38
|
/** swiper options, to set autoplay, navigation, thumbnails,...
|
|
13
39
|
* check fullset of options: https://swiperjs.com/swiper-api#parameters
|
|
14
40
|
*/
|
|
15
|
-
options?:
|
|
41
|
+
options?: AstroSwiperOptions;
|
|
16
42
|
|
|
17
43
|
/** unique class to be able to retrieve the swiper instance, if required
|
|
18
44
|
* Mandatory on thumbnail for example
|