astro-swiper 2.4.0 → 2.5.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/README.md +10 -6
- package/package.json +2 -2
- package/src/components/Swiper.astro +85 -46
- package/src/index.ts +41 -24
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div align="center" style="background-color: dark-grey; padding: 1rem;">
|
|
2
2
|
<a href="https://swiperjs.com" target="_blank"><img width="70" width="auto" src="images/swiper-logo.svg"></a>
|
|
3
3
|
<a href="https://astro.build/" target="_blank"><img height="68" width="auto" src="images/astro-logo.svg"></a>
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
# Astro Swiper
|
|
6
6
|
|
|
7
7
|
> Astro Swiper - native component for [Swiper](https://github.com/nolimits4web/swiper).
|
|
@@ -74,7 +74,7 @@ You can also look at how others are using `astro-swiper` in public github repo:
|
|
|
74
74
|
- the famous astro template [astroplate](https://github.com/zeon-studio/astroplate) in the
|
|
75
75
|
[testominial section](https://zeon.studio/preview?project=astroplate)
|
|
76
76
|
(cf. **_What Users Are Saying About Astroplate_**):
|
|
77
|
-
autoplay, pagination and breakpoints are used
|
|
77
|
+
autoplay, pagination and breakpoints are used.
|
|
78
78
|
- the popular astro template [pinwheel-astro](https://github.com/themefisher/pinwheel-astro)
|
|
79
79
|
is using `astro-swiper` in several places:
|
|
80
80
|
[testimonial section](https://pinwheel-astro.vercel.app/),
|
|
@@ -91,14 +91,18 @@ You can also look at how others are using `astro-swiper` in public github repo:
|
|
|
91
91
|
[main page](https://tf-bigspring-light-astro.vercel.app/) with customized pagination.
|
|
92
92
|
- [Women Techmakers organized by GDG Madrid](https://github.com/wtmgdgmadrid/wtmgdgmadrid.github.io)
|
|
93
93
|
is using pagination and autoplay at different places in their
|
|
94
|
-
[page](http://wtmgdgmadrid.github.io/)
|
|
94
|
+
[page](http://wtmgdgmadrid.github.io/).
|
|
95
95
|
- [kando-menu](https://github.com/make-42/kando-menu.github.io) is using `astro-swiper`
|
|
96
|
-
with pagination, card effect, and coverflow effect as displayed in [kando.menu](https://kando.menu/)
|
|
97
|
-
- [astroimagej](https://github.com/AstroImageJ/astroimagej) is using pagination with progress bar
|
|
96
|
+
with pagination, card effect, and coverflow effect as displayed in [kando.menu](https://kando.menu/).
|
|
97
|
+
- [astroimagej](https://github.com/AstroImageJ/astroimagej) is using pagination with progress bar.
|
|
98
|
+
- [rustdesk.com](https://github.com/rustdesk/doc.rustdesk.com) makes use of `<SwiperLazyPreloader/>`
|
|
99
|
+
to add a preloader element.
|
|
98
100
|
- ... and many others such as
|
|
99
101
|
[Cinerama](https://github.com/RaiderMr3003/Cinerama) and
|
|
100
102
|
[pfm-landing-page](https://github.com/RichardAgain/pfm-landing-page)
|
|
101
|
-
using `astro-swiper` in the hero section
|
|
103
|
+
using `astro-swiper` in the hero section,
|
|
104
|
+
[folex-lite-astro](https://github.com/getastrothemes/folex-lite-astro)
|
|
105
|
+
using it in the portfolio page,...
|
|
102
106
|
|
|
103
107
|
## Help needed?
|
|
104
108
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro-swiper",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Astro component for swiper, dedicated to slider / carousel / photo swiper / slide, including thumbnails",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"bugs": {
|
|
19
19
|
"url": "https://github.com/pascal-brand38/astro-swiper/issues"
|
|
20
20
|
},
|
|
21
|
-
"homepage": "https://github.
|
|
21
|
+
"homepage": "https://pascal-brand38.github.io/astro-dev/packages/astro-swiper/",
|
|
22
22
|
"exports": {
|
|
23
23
|
".": {
|
|
24
24
|
"types": "./index.ts",
|
|
@@ -9,20 +9,40 @@ type Props = AstroSwiperType;
|
|
|
9
9
|
|
|
10
10
|
const {
|
|
11
11
|
options = {},
|
|
12
|
-
uniqueClass
|
|
12
|
+
uniqueClass: removedUniqueClass, // remove it once deprecated uniqueClass prop is removed
|
|
13
13
|
class: className = null,
|
|
14
|
-
linkToThumbUniqueClass
|
|
14
|
+
linkToThumbUniqueClass: removedLinkToThumbUniqueClass, // remove it once deprecated uniqueClass prop is removed
|
|
15
15
|
addDefaultClass = true,
|
|
16
|
-
useCustomElement = true,
|
|
17
16
|
...props
|
|
18
17
|
} = Astro.props;
|
|
18
|
+
|
|
19
|
+
// check for deprecated useCustomElement prop and set the options.astro.useCustomElement
|
|
20
|
+
// option accordingly if not set, to keep legacy
|
|
21
|
+
if (options?.astro?.useCustomElement === undefined && Astro.props.useCustomElement === false) {
|
|
22
|
+
if (!options.astro) {
|
|
23
|
+
options.astro = {};
|
|
24
|
+
}
|
|
25
|
+
options.astro.useCustomElement = false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// once Astro.props.uniqueClass is removed, uniqueClass can be directly set to the generated unique class name
|
|
29
|
+
const uniqueClass =
|
|
30
|
+
Astro.props.uniqueClass || `astro-swiper-${Math.random().toString(36).slice(2, 11)}`;
|
|
31
|
+
|
|
32
|
+
// check for deprecated useCustomElement prop and set the options.astro.useCustomElement
|
|
33
|
+
// option accordingly if not set, to keep legacy
|
|
34
|
+
if (options?.astro?.thumbSwiperUniqueSelector === undefined && Astro.props.linkToThumbUniqueClass) {
|
|
35
|
+
if (!options.astro) {
|
|
36
|
+
options.astro = {};
|
|
37
|
+
}
|
|
38
|
+
options.astro.thumbSwiperUniqueSelector = `.${Astro.props.linkToThumbUniqueClass}`;
|
|
39
|
+
}
|
|
19
40
|
---
|
|
20
41
|
|
|
21
42
|
<!-- Slider main container -->{
|
|
22
|
-
useCustomElement ? (
|
|
43
|
+
options?.astro?.useCustomElement !== false ? (
|
|
23
44
|
<astro-swiper
|
|
24
45
|
data-options={JSON.stringify(options)}
|
|
25
|
-
data-linktothumbuniqueclass={linkToThumbUniqueClass}
|
|
26
46
|
data-uniqueclass={uniqueClass}
|
|
27
47
|
class:list={[addDefaultClass ? 'swiper' : null, uniqueClass, className]}
|
|
28
48
|
{...props}
|
|
@@ -31,11 +51,7 @@ const {
|
|
|
31
51
|
</astro-swiper>
|
|
32
52
|
) : (
|
|
33
53
|
<div class:list={[addDefaultClass ? 'swiper' : null, uniqueClass, className]} {...props}>
|
|
34
|
-
<astro-swiper
|
|
35
|
-
data-options={JSON.stringify(options)}
|
|
36
|
-
data-linktothumbuniqueclass={linkToThumbUniqueClass}
|
|
37
|
-
data-uniqueclass={uniqueClass}
|
|
38
|
-
/>
|
|
54
|
+
<astro-swiper data-options={JSON.stringify(options)} data-uniqueclass={uniqueClass} />
|
|
39
55
|
<slot />
|
|
40
56
|
</div>
|
|
41
57
|
)
|
|
@@ -43,51 +59,62 @@ const {
|
|
|
43
59
|
|
|
44
60
|
<script>
|
|
45
61
|
import Swiper from 'swiper/bundle';
|
|
46
|
-
import
|
|
62
|
+
import { getSwiperFromUniqueSelector } from '../index';
|
|
63
|
+
import type { AstroSwiperOptions, selectorStringType } from '../index';
|
|
47
64
|
|
|
48
|
-
|
|
49
|
-
|
|
65
|
+
const getSwiperFromUniqueSelectorOptions = {
|
|
66
|
+
// to avoid warning when the swiper is not initialized yet, but will be in the future
|
|
67
|
+
// (for example when using thumbnails, the main swiper is created before the thumbnail
|
|
68
|
+
// swiper, so it is normal that it is not found at this moment)
|
|
69
|
+
mayBeUndefined: true,
|
|
70
|
+
};
|
|
50
71
|
|
|
51
|
-
/** contains the option used when creating the swiper object for each
|
|
52
|
-
const _useOptions: { [
|
|
72
|
+
/** contains the option used when creating the swiper object for each uniqueSelector */
|
|
73
|
+
const _useOptions: { [uniqueSelector: string]: AstroSwiperOptions } = {};
|
|
53
74
|
|
|
54
|
-
/** contains all the
|
|
75
|
+
/** contains all the uniqueSelector that have their swiper object delayed because the
|
|
55
76
|
* related thumbnail swiper is not created yet
|
|
56
|
-
* For each
|
|
77
|
+
* For each uniqueSelector, is equal to the thumbnail slider uniqueSelector
|
|
57
78
|
*/
|
|
58
|
-
const _useDelaySwiper: { [
|
|
79
|
+
const _useDelaySwiper: { [uniqueSelector: string]: string } = {};
|
|
59
80
|
|
|
60
81
|
// Init swipers that have delayed initialization because the thumbnail swiper is not created yet
|
|
61
82
|
// If this is now the case, then it is intialized, as well as its observer if needed
|
|
62
83
|
function _initDelayedSwipers() {
|
|
63
|
-
Object.keys(_useDelaySwiper).forEach((
|
|
64
|
-
// swiper of
|
|
65
|
-
// "
|
|
66
|
-
const
|
|
67
|
-
|
|
84
|
+
Object.keys(_useDelaySwiper).forEach((delayedSelector) => {
|
|
85
|
+
// swiper of uniqueSelector "delayedSelector" is delayed because it needs the swiper of uniqueSelector
|
|
86
|
+
// "delayedThumbSelector" to be created first
|
|
87
|
+
const delayedThumbSelector = _useDelaySwiper[delayedSelector];
|
|
88
|
+
const swiper = getSwiperFromUniqueSelector(
|
|
89
|
+
delayedThumbSelector,
|
|
90
|
+
getSwiperFromUniqueSelectorOptions,
|
|
91
|
+
);
|
|
92
|
+
if (swiper) {
|
|
68
93
|
// the thumbnail swiper is created, we can create the swiper
|
|
69
|
-
delete _useDelaySwiper[
|
|
70
|
-
const delayedOptions = _useOptions[
|
|
94
|
+
delete _useDelaySwiper[delayedSelector]; // remove it from the delayed list
|
|
95
|
+
const delayedOptions = _useOptions[delayedSelector];
|
|
71
96
|
delayedOptions.thumbs = {
|
|
72
|
-
swiper:
|
|
97
|
+
swiper: swiper, // add the thumbnail swiper link to the options
|
|
73
98
|
...delayedOptions.thumbs,
|
|
74
99
|
};
|
|
75
100
|
|
|
76
101
|
_createSwiperAndObserver(
|
|
77
|
-
|
|
102
|
+
delayedSelector,
|
|
78
103
|
delayedOptions,
|
|
79
|
-
document.querySelector(
|
|
104
|
+
document.querySelector(delayedSelector) as AstroSwiper,
|
|
80
105
|
);
|
|
81
|
-
_useOptions[delayedClass] = delayedOptions; // update the options with the thumbnail link
|
|
82
106
|
}
|
|
83
107
|
});
|
|
84
108
|
}
|
|
85
109
|
|
|
86
110
|
// initialize the swiper instance
|
|
87
111
|
// the autoplay may be stopped manually if it should be started by the observer
|
|
88
|
-
function _initSwiper(
|
|
89
|
-
|
|
90
|
-
|
|
112
|
+
function _initSwiper(
|
|
113
|
+
uniqueSelector: selectorStringType,
|
|
114
|
+
options: AstroSwiperOptions,
|
|
115
|
+
element: AstroSwiper,
|
|
116
|
+
) {
|
|
117
|
+
const swiper = new Swiper(uniqueSelector, options);
|
|
91
118
|
element.astroSwiper = swiper;
|
|
92
119
|
|
|
93
120
|
// stop the autoplay if it will be started by the observer
|
|
@@ -99,12 +126,16 @@ const {
|
|
|
99
126
|
return swiper;
|
|
100
127
|
}
|
|
101
128
|
|
|
102
|
-
function _createObserver(
|
|
129
|
+
function _createObserver(
|
|
130
|
+
uniqueSelector: selectorStringType,
|
|
131
|
+
options: AstroSwiperOptions,
|
|
132
|
+
element: AstroSwiper,
|
|
133
|
+
) {
|
|
103
134
|
const observerOptions = options.astro?.intersectionObserver || {};
|
|
104
135
|
const observer = new IntersectionObserver((entries) => {
|
|
105
136
|
if (entries[0].isIntersecting) {
|
|
106
137
|
if (observerOptions?.initSwiper && !element.astroSwiper) {
|
|
107
|
-
_initSwiper(
|
|
138
|
+
_initSwiper(uniqueSelector, options, element);
|
|
108
139
|
if (observerOptions?.disconnectOnInit) {
|
|
109
140
|
observer.disconnect();
|
|
110
141
|
}
|
|
@@ -133,18 +164,18 @@ const {
|
|
|
133
164
|
// - init the swiper if it should not be done by the observer
|
|
134
165
|
// - create the observer if required
|
|
135
166
|
function _createSwiperAndObserver(
|
|
136
|
-
|
|
167
|
+
uniqueSelector: selectorStringType,
|
|
137
168
|
options: AstroSwiperOptions,
|
|
138
169
|
element: AstroSwiper,
|
|
139
170
|
) {
|
|
140
171
|
if (!options.astro?.intersectionObserver?.initSwiper) {
|
|
141
172
|
// create the swiper immediatly
|
|
142
|
-
_initSwiper(
|
|
173
|
+
_initSwiper(uniqueSelector, options, element);
|
|
143
174
|
}
|
|
144
175
|
|
|
145
176
|
// create the observer. It may init the swiper
|
|
146
177
|
if (options.astro?.intersectionObserver) {
|
|
147
|
-
_createObserver(
|
|
178
|
+
_createObserver(uniqueSelector, options, element);
|
|
148
179
|
}
|
|
149
180
|
}
|
|
150
181
|
|
|
@@ -160,24 +191,32 @@ const {
|
|
|
160
191
|
// Read the message from the data attribute.
|
|
161
192
|
const options: AstroSwiperOptions = JSON.parse(this.dataset.options || '{}');
|
|
162
193
|
// to have more than 1 swiper in a single page
|
|
163
|
-
const
|
|
164
|
-
const
|
|
194
|
+
const uniqueSelector: selectorStringType = `.${this.dataset.uniqueclass}`;
|
|
195
|
+
const thumbSwiperUniqueSelector = options.astro?.thumbSwiperUniqueSelector;
|
|
165
196
|
|
|
166
197
|
// no thumbnail link, or link to thumbnail swiper already created,
|
|
167
198
|
// the swiper can be created or not immediatly depending on the observer option
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
|
|
199
|
+
if (
|
|
200
|
+
!thumbSwiperUniqueSelector ||
|
|
201
|
+
getSwiperFromUniqueSelector(thumbSwiperUniqueSelector, getSwiperFromUniqueSelectorOptions)
|
|
202
|
+
) {
|
|
203
|
+
if (thumbSwiperUniqueSelector) {
|
|
204
|
+
options.thumbs = {
|
|
205
|
+
swiper: getSwiperFromUniqueSelector(
|
|
206
|
+
thumbSwiperUniqueSelector,
|
|
207
|
+
getSwiperFromUniqueSelectorOptions,
|
|
208
|
+
),
|
|
209
|
+
...options.thumbs,
|
|
210
|
+
};
|
|
171
211
|
}
|
|
172
212
|
// create the swiper and the observer if needed
|
|
173
|
-
_createSwiperAndObserver(
|
|
213
|
+
_createSwiperAndObserver(uniqueSelector, options, this);
|
|
174
214
|
} else {
|
|
175
215
|
// cannot create the swiper as the thumbnail swiper not created yet
|
|
176
216
|
// is delayed until the thumbnail swiper is initialized.
|
|
177
|
-
_useDelaySwiper[
|
|
217
|
+
_useDelaySwiper[uniqueSelector] = thumbSwiperUniqueSelector;
|
|
218
|
+
_useOptions[uniqueSelector] = options;
|
|
178
219
|
}
|
|
179
|
-
|
|
180
|
-
_useOptions[uniqueClass] = options;
|
|
181
220
|
}
|
|
182
221
|
}
|
|
183
222
|
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
import type { Swiper, SwiperOptions } from 'swiper/types';
|
|
5
5
|
import type { HTMLAttributes } from 'astro/types';
|
|
6
6
|
|
|
7
|
+
// type of a string that starts with a dot (class selector) or a hash (id selector), followed by any string
|
|
8
|
+
export type selectorStringType = `.${string}` | `#${string}`;
|
|
9
|
+
|
|
7
10
|
/** Swiper options for the Astro component.
|
|
8
11
|
* Basically the same as the original SwiperOptions, but extended
|
|
9
12
|
* with new capabilities
|
|
@@ -26,7 +29,23 @@ export interface AstroSwiperOptions extends SwiperOptions {
|
|
|
26
29
|
/** options for the IntersectionObserver */
|
|
27
30
|
options?: IntersectionObserverInit;
|
|
28
31
|
};
|
|
29
|
-
|
|
32
|
+
|
|
33
|
+
/** useCustomElement, if true, the component will be rendered as a custom element, otherwise as a div.
|
|
34
|
+
* This option is true by default to keep legacy.
|
|
35
|
+
* It is there to be as close as possible to the original swiper structure, that is a div with class "swiper"
|
|
36
|
+
* and not a custom element.
|
|
37
|
+
* It is also to avoid issues with some swiper modules that are looking for the "swiper" class on the parent
|
|
38
|
+
* element, and not on the custom element.
|
|
39
|
+
*/
|
|
40
|
+
useCustomElement?: boolean;
|
|
41
|
+
|
|
42
|
+
/** unique selector of the thumbnail swiper to link with, when using the thumbs module.
|
|
43
|
+
* when a thumbnail swiper is build, this parameter is provided on the main slider
|
|
44
|
+
* (the one with big slides, not the one to track the progress) and equal
|
|
45
|
+
* the unique selector of the thumbnail swiper (the one to track the progress).
|
|
46
|
+
* It is used to link the main swiper with the thumbnail swiper when using the thumbs module.
|
|
47
|
+
*/
|
|
48
|
+
thumbSwiperUniqueSelector?: selectorStringType;
|
|
30
49
|
};
|
|
31
50
|
}
|
|
32
51
|
|
|
@@ -40,28 +59,17 @@ export interface AstroSwiperType extends HTMLAttributes<'div'> {
|
|
|
40
59
|
*/
|
|
41
60
|
options?: AstroSwiperOptions;
|
|
42
61
|
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
62
|
+
/** add the default swiper class, true by default */
|
|
63
|
+
addDefaultClass?: boolean;
|
|
64
|
+
|
|
65
|
+
/** @deprecated is not really usefull anymore. If a specific unique class or id is needed,
|
|
66
|
+
* add it as an id or or a class directly */
|
|
47
67
|
uniqueClass?: string;
|
|
48
68
|
|
|
49
|
-
/**
|
|
50
|
-
* (the one with big slides, not the one to track the progress) and equal
|
|
51
|
-
* the unique class of the thumbnail slider
|
|
52
|
-
*/
|
|
69
|
+
/** @deprecated use astro.options.astro.thumbsSwiperUniqueSelector instead */
|
|
53
70
|
linkToThumbUniqueClass?: string;
|
|
54
71
|
|
|
55
|
-
/**
|
|
56
|
-
addDefaultClass?: boolean;
|
|
57
|
-
|
|
58
|
-
/** useCustomElement, if true, the component will be rendered as a custom element, otherwise as a div.
|
|
59
|
-
* This option is true by default to keep legacy.
|
|
60
|
-
* It is there to be as close as possible to the original swiper structure, that is a div with class "swiper"
|
|
61
|
-
* and not a custom element.
|
|
62
|
-
* It is also to avoid issues with some swiper modules that are looking for the "swiper" class on the parent
|
|
63
|
-
* element, and not on the custom element.
|
|
64
|
-
*/
|
|
72
|
+
/** @deprecated use astro.useCustomElement instead */
|
|
65
73
|
useCustomElement?: boolean;
|
|
66
74
|
}
|
|
67
75
|
|
|
@@ -91,7 +99,10 @@ export function getSwiperFromUniqueClass(uniqueClass: string): Swiper | undefine
|
|
|
91
99
|
* @example const swiper = getSwiperFromUniqueSelector('.my-unique-class')
|
|
92
100
|
* const swiper = getSwiperFromUniqueSelector('#my-unique-id')
|
|
93
101
|
*/
|
|
94
|
-
export function getSwiperFromUniqueSelector(
|
|
102
|
+
export function getSwiperFromUniqueSelector(
|
|
103
|
+
uniqueSelector: selectorStringType,
|
|
104
|
+
options?: { mayBeUndefined?: boolean },
|
|
105
|
+
): Swiper | undefined {
|
|
95
106
|
if (!/^[.#]/.test(uniqueSelector)) {
|
|
96
107
|
console.warn("Used selector doesn't contain class or ID selector sign");
|
|
97
108
|
}
|
|
@@ -111,10 +122,16 @@ export function getSwiperFromUniqueSelector(uniqueSelector: string): Swiper | un
|
|
|
111
122
|
const childElement = element.firstElementChild as AstroSwiper;
|
|
112
123
|
if (childElement?.astroSwiper) return childElement.astroSwiper;
|
|
113
124
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
125
|
+
if (!options?.mayBeUndefined) {
|
|
126
|
+
// set options.mayBeUndefined to true to avoid this warning when the swiper is not initialized yet,
|
|
127
|
+
// but will be in the future:
|
|
128
|
+
// for example when using thumbnails, the main swiper is created before the thumbnail swiper,
|
|
129
|
+
// so it is normal that it is not found at this moment)
|
|
130
|
+
console.warn(
|
|
131
|
+
`astro-swiper: element found with selector "${uniqueSelector}" but no swiper instance found. ` +
|
|
132
|
+
`Expected either a custom element with astroSwiper property or a <div/> containing such an element.`,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
118
135
|
|
|
119
136
|
return undefined;
|
|
120
137
|
}
|