perf(slides): tree-shake dependency

This commit is contained in:
Manu Mtz.-Almeida
2018-09-14 00:27:50 +02:00
parent ea01900f99
commit 9d3a2598be
14 changed files with 262 additions and 10328 deletions

View File

@ -33,6 +33,7 @@
"@stencil/sass": "0.1.0", "@stencil/sass": "0.1.0",
"@stencil/utils": "latest", "@stencil/utils": "latest",
"@types/jest": "^23.3.1", "@types/jest": "^23.3.1",
"@types/swiper": "4.2.1",
"agadoo": "^1.0.0", "agadoo": "^1.0.0",
"autoprefixer": "^9.0.2", "autoprefixer": "^9.0.2",
"chromedriver": "^2.38.3", "chromedriver": "^2.38.3",
@ -44,6 +45,7 @@
"selenium-webdriver": "^3.6.0", "selenium-webdriver": "^3.6.0",
"stylelint": "^9.4.0", "stylelint": "^9.4.0",
"stylelint-order": "^0.8.1", "stylelint-order": "^0.8.1",
"swiper": "4.3.5",
"tslint": "^5.10.0", "tslint": "^5.10.0",
"tslint-ionic-rules": "0.0.19", "tslint-ionic-rules": "0.0.19",
"tslint-react": "^3.6.0", "tslint-react": "^3.6.0",

View File

@ -4167,7 +4167,9 @@ export namespace Components {
} }
interface IonSlide {} interface IonSlide {}
interface IonSlideAttributes extends StencilHTMLAttributes {} interface IonSlideAttributes extends StencilHTMLAttributes {
'onIonSlideChanged'?: (event: CustomEvent<void>) => void;
}
interface IonSlides { interface IonSlides {
/** /**
@ -4193,15 +4195,19 @@ export namespace Components {
/** /**
* Lock or unlock the ability to slide to the next slides. * Lock or unlock the ability to slide to the next slides.
*/ */
'lockSwipeToNext': (shouldLockSwipeToNext: boolean) => void; 'lockSwipeToNext': (shouldLockSwipeToNext: boolean) => Promise<void>;
/** /**
* Lock or unlock the ability to slide to the previous slides. * Lock or unlock the ability to slide to the previous slides.
*/ */
'lockSwipeToPrev': (shouldLockSwipeToPrev: boolean) => void; 'lockSwipeToPrev': (shouldLockSwipeToPrev: boolean) => Promise<void>;
/** /**
* Lock or unlock the ability to slide to change slides. * Lock or unlock the ability to slide to change slides.
*/ */
'lockSwipes': (shouldLockSwipes: boolean) => void; 'lockSwipes': (shouldLockSwipes: boolean) => Promise<void>;
/**
* The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`.
*/
'mode': Mode;
/** /**
* Options to pass to the swiper instance. See http://idangero.us/swiper/api/ for valid options * Options to pass to the swiper instance. See http://idangero.us/swiper/api/ for valid options
*/ */
@ -4217,93 +4223,97 @@ export namespace Components {
/** /**
* Transition to the next slide. * Transition to the next slide.
*/ */
'slideNext': (speed?: number | undefined, runCallbacks?: boolean | undefined) => void; 'slideNext': (speed: number, runCallbacks: boolean) => Promise<void>;
/** /**
* Transition to the previous slide. * Transition to the previous slide.
*/ */
'slidePrev': (speed?: number | undefined, runCallbacks?: boolean | undefined) => void; 'slidePrev': (speed?: number | undefined, runCallbacks?: boolean | undefined) => Promise<void>;
/** /**
* Transition to the specified slide. * Transition to the specified slide.
*/ */
'slideTo': (index: number, speed?: number | undefined, runCallbacks?: boolean | undefined) => void; 'slideTo': (index: number, speed?: number | undefined, runCallbacks?: boolean | undefined) => Promise<void>;
/** /**
* Start auto play. * Start auto play.
*/ */
'startAutoplay': () => void; 'startAutoplay': () => Promise<void>;
/** /**
* Stop auto play. * Stop auto play.
*/ */
'stopAutoplay': () => void; 'stopAutoplay': () => Promise<void>;
/** /**
* Update the underlying slider implementation. Call this if you've added or removed child slides. * Update the underlying slider implementation. Call this if you've added or removed child slides.
*/ */
'update': () => void; 'update': () => Promise<void>;
} }
interface IonSlidesAttributes extends StencilHTMLAttributes { interface IonSlidesAttributes extends StencilHTMLAttributes {
/**
* The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`.
*/
'mode'?: Mode;
/** /**
* Emitted after the active slide has changed. * Emitted after the active slide has changed.
*/ */
'onIonSlideDidChange'?: (event: CustomEvent) => void; 'onIonSlideDidChange'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the user double taps on the slide's container. * Emitted when the user double taps on the slide's container.
*/ */
'onIonSlideDoubleTap'?: (event: CustomEvent) => void; 'onIonSlideDoubleTap'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the slider is actively being moved. * Emitted when the slider is actively being moved.
*/ */
'onIonSlideDrag'?: (event: CustomEvent) => void; 'onIonSlideDrag'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the next slide has ended. * Emitted when the next slide has ended.
*/ */
'onIonSlideNextEnd'?: (event: CustomEvent) => void; 'onIonSlideNextEnd'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the next slide has started. * Emitted when the next slide has started.
*/ */
'onIonSlideNextStart'?: (event: CustomEvent) => void; 'onIonSlideNextStart'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the previous slide has ended. * Emitted when the previous slide has ended.
*/ */
'onIonSlidePrevEnd'?: (event: CustomEvent) => void; 'onIonSlidePrevEnd'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the previous slide has started. * Emitted when the previous slide has started.
*/ */
'onIonSlidePrevStart'?: (event: CustomEvent) => void; 'onIonSlidePrevStart'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the slider is at the last slide. * Emitted when the slider is at the last slide.
*/ */
'onIonSlideReachEnd'?: (event: CustomEvent) => void; 'onIonSlideReachEnd'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the slider is at its initial position. * Emitted when the slider is at its initial position.
*/ */
'onIonSlideReachStart'?: (event: CustomEvent) => void; 'onIonSlideReachStart'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the user taps/clicks on the slide's container. * Emitted when the user taps/clicks on the slide's container.
*/ */
'onIonSlideTap'?: (event: CustomEvent) => void; 'onIonSlideTap'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the user releases the touch. * Emitted when the user releases the touch.
*/ */
'onIonSlideTouchEnd'?: (event: CustomEvent) => void; 'onIonSlideTouchEnd'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the user first touches the slider. * Emitted when the user first touches the slider.
*/ */
'onIonSlideTouchStart'?: (event: CustomEvent) => void; 'onIonSlideTouchStart'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the slide transition has ended. * Emitted when the slide transition has ended.
*/ */
'onIonSlideTransitionEnd'?: (event: CustomEvent) => void; 'onIonSlideTransitionEnd'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted when the slide transition has started. * Emitted when the slide transition has started.
*/ */
'onIonSlideTransitionStart'?: (event: CustomEvent) => void; 'onIonSlideTransitionStart'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted before the active slide has changed. * Emitted before the active slide has changed.
*/ */
'onIonSlideWillChange'?: (event: CustomEvent) => void; 'onIonSlideWillChange'?: (event: CustomEvent<void>) => void;
/** /**
* Emitted after Swiper initialization * Emitted after Swiper initialization
*/ */
'onIonSlidesDidLoad'?: (event: CustomEvent) => void; 'onIonSlidesDidLoad'?: (event: CustomEvent<void>) => void;
/** /**
* Options to pass to the swiper instance. See http://idangero.us/swiper/api/ for valid options * Options to pass to the swiper instance. See http://idangero.us/swiper/api/ for valid options
*/ */

View File

@ -10,6 +10,13 @@ See the [Slides API Docs](../slides) for more usage information.
<!-- Auto Generated Below --> <!-- Auto Generated Below -->
## Events
| Event | Description |
| ----------------- | ----------- |
| `ionSlideChanged` | |
---------------------------------------------- ----------------------------------------------
*Built with [StencilJS](https://stenciljs.com/)* *Built with [StencilJS](https://stenciljs.com/)*

View File

@ -1,4 +1,5 @@
import { Component } from '@stencil/core'; import { Component, Event } from '@stencil/core';
import { EventEmitter } from 'ionicons/dist/types/stencil.core';
@Component({ @Component({
tag: 'ion-slide', tag: 'ion-slide',
@ -6,13 +7,21 @@ import { Component } from '@stencil/core';
}) })
export class Slide { export class Slide {
@Event() ionSlideChanged!: EventEmitter<void>;
componentDidLoad() {
this.ionSlideChanged.emit();
}
componentDidUnload() {
this.ionSlideChanged.emit();
}
hostData() { hostData() {
return { return {
class: { class: {
'slide-zoom': true,
'swiper-slide': true 'swiper-slide': true
} }
}; };
} }
} }

View File

@ -23,6 +23,7 @@ Licensed under MIT
| Property | Attribute | Description | Type | | Property | Attribute | Description | Type |
| ----------- | ----------- | -------------------------------------------------------------------------------------------- | --------- | | ----------- | ----------- | -------------------------------------------------------------------------------------------- | --------- |
| `mode` | `mode` | The mode determines which platform styles to use. Possible values are: `"ios"` or `"md"`. | `Mode` |
| `options` | -- | Options to pass to the swiper instance. See http://idangero.us/swiper/api/ for valid options | `any` | | `options` | -- | Options to pass to the swiper instance. See http://idangero.us/swiper/api/ for valid options | `any` |
| `pager` | `pager` | If true, show the pagination. Defaults to `false`. | `boolean` | | `pager` | `pager` | If true, show the pagination. Defaults to `false`. | `boolean` |
| `scrollbar` | `scrollbar` | If true, show the scrollbar. Defaults to `false`. | `boolean` | | `scrollbar` | `scrollbar` | If true, show the scrollbar. Defaults to `false`. | `boolean` |

View File

@ -1,5 +1,5 @@
/** /**
* Swiper 4.2.6 * Swiper 4.3.5
* Most modern mobile touch slider and framework with hardware accelerated transitions * Most modern mobile touch slider and framework with hardware accelerated transitions
* http://www.idangero.us/swiper/ * http://www.idangero.us/swiper/
* *
@ -7,7 +7,7 @@
* *
* Released under the MIT License * Released under the MIT License
* *
* Released on: May 1, 2018 * Released on: July 31, 2018
*/ */
.swiper-container { .swiper-container {
margin: 0 auto; margin: 0 auto;
@ -272,7 +272,8 @@
height: 8px; height: 8px;
display: inline-block; display: inline-block;
border-radius: 100%; border-radius: 100%;
background: rgba(0, 0, 0, .2); background: #000;
opacity: 0.2;
} }
button.swiper-pagination-bullet { button.swiper-pagination-bullet {
border: none; border: none;
@ -288,6 +289,7 @@ button.swiper-pagination-bullet {
cursor: pointer; cursor: pointer;
} }
.swiper-pagination-bullet-active { .swiper-pagination-bullet-active {
opacity: 1;
background: #007aff; background: #007aff;
} }
.swiper-container-vertical > .swiper-pagination-bullets { .swiper-container-vertical > .swiper-pagination-bullets {

View File

@ -4,7 +4,7 @@
// iOS Slides // iOS Slides
// -------------------------------------------------- // --------------------------------------------------
:host { .slides-ios {
--bullet-background: #{$slides-ios-bullet-background}; --bullet-background: #{$slides-ios-bullet-background};
--bullet-background-active: #{$slides-ios-bullet-background-active}; --bullet-background-active: #{$slides-ios-bullet-background-active};
--progress-bar-background: #{$slides-ios-progress-bar-background}; --progress-bar-background: #{$slides-ios-progress-bar-background};

View File

@ -4,7 +4,7 @@
// Material Design Slides // Material Design Slides
// -------------------------------------------------- // --------------------------------------------------
:host { .slides-md {
--bullet-background: #{$slides-md-bullet-background}; --bullet-background: #{$slides-md-bullet-background};
--bullet-background-active: #{$slides-md-bullet-background-active}; --bullet-background-active: #{$slides-md-bullet-background-active};
--progress-bar-background: #{$slides-md-progress-bar-background}; --progress-bar-background: #{$slides-md-progress-bar-background};

View File

@ -4,23 +4,16 @@
// Slides // Slides
// -------------------------------------------------- // --------------------------------------------------
:host { .slides {
/** /**
* @prop --bullet-background: Background of the pagination bullets * @prop --bullet-background: Background of the pagination bullets
* @prop --bullet-background-active: Background of the active pagination bullet * @prop --bullet-background-active: Background of the active pagination bullet
*/ */
// TODO: document progress and scroll bar properties once they're working
display: block; display: block;
user-select: none; user-select: none;
} }
.swiper-container {
height: 100%;
}
// Pagination Bullets // Pagination Bullets
// -------------------------------------------------- // --------------------------------------------------

View File

@ -1,109 +1,34 @@
import { Component, Element, Event, EventEmitter, Method, Prop, Watch } from '@stencil/core'; import { Component, Element, Event, EventEmitter, Method, Prop, Watch, Listen } from '@stencil/core';
import { Mode } from '../../interface.js'; import { Mode } from '../../interface';
import { rIC } from '../../utils/helpers.js';
import { createThemedClasses } from '../../utils/theme.js';
import { Swiper } from './vendor/swiper.js'; import { SwiperInterface, SwiperOptions } from './swiper/swiper-interface';
@Component({ @Component({
tag: 'ion-slides', tag: 'ion-slides',
styleUrls: { styleUrls: {
ios: 'slides.ios.scss', ios: 'slides.ios.scss',
md: 'slides.md.scss' md: 'slides.md.scss'
}, }
assetsDir: 'vendor',
shadow: true
}) })
export class Slides { export class Slides {
private container!: HTMLElement; private scrollbarEl?: HTMLElement;
private swiper: any; private paginationEl?: HTMLElement;
private didInit = false;
private readyResolve: any; private readySwiper!: (swiper: SwiperInterface) => void;
private readyPromise: Promise<boolean> = new Promise(resolve => { this.readyResolve = resolve; }); private swiper: Promise<SwiperInterface> = new Promise(resolve => { this.readySwiper = resolve; });
mode!: Mode;
@Element() el!: HTMLStencilElement; @Element() el!: HTMLStencilElement;
/** /**
* Emitted after Swiper initialization * The mode determines which platform styles to use.
* Possible values are: `"ios"` or `"md"`.
*/ */
@Event() ionSlidesDidLoad!: EventEmitter; @Prop() mode!: Mode;
/**
* Emitted when the user taps/clicks on the slide's container.
*/
@Event() ionSlideTap!: EventEmitter;
/**
* Emitted when the user double taps on the slide's container.
*/
@Event() ionSlideDoubleTap!: EventEmitter;
/**
* Emitted before the active slide has changed.
*/
@Event() ionSlideWillChange!: EventEmitter;
/**
* Emitted after the active slide has changed.
*/
@Event() ionSlideDidChange!: EventEmitter;
/**
* Emitted when the next slide has started.
*/
@Event() ionSlideNextStart!: EventEmitter;
/**
* Emitted when the previous slide has started.
*/
@Event() ionSlidePrevStart!: EventEmitter;
/**
* Emitted when the next slide has ended.
*/
@Event() ionSlideNextEnd!: EventEmitter;
/**
* Emitted when the previous slide has ended.
*/
@Event() ionSlidePrevEnd!: EventEmitter;
/**
* Emitted when the slide transition has started.
*/
@Event() ionSlideTransitionStart!: EventEmitter;
/**
* Emitted when the slide transition has ended.
*/
@Event() ionSlideTransitionEnd!: EventEmitter;
/**
* Emitted when the slider is actively being moved.
*/
@Event() ionSlideDrag!: EventEmitter;
/**
* Emitted when the slider is at its initial position.
*/
@Event() ionSlideReachStart!: EventEmitter;
/**
* Emitted when the slider is at the last slide.
*/
@Event() ionSlideReachEnd!: EventEmitter;
/**
* Emitted when the user first touches the slider.
*/
@Event() ionSlideTouchStart!: EventEmitter;
/**
* Emitted when the user releases the touch.
*/
@Event() ionSlideTouchEnd!: EventEmitter;
/** /**
* Options to pass to the swiper instance. * Options to pass to the swiper instance.
@ -112,10 +37,10 @@ export class Slides {
@Prop() options: any = {}; // SwiperOptions; // TODO @Prop() options: any = {}; // SwiperOptions; // TODO
@Watch('options') @Watch('options')
updateSwiperOptions() { async updateSwiperOptions() {
const newOptions = this.normalizeOptions(); const swiper = await this.getSwiper();
this.swiper.params = { ...this.swiper.params, ...newOptions }; swiper.params = this.normalizeOptions();
this.update(); await this.update();
} }
/** /**
@ -128,20 +53,100 @@ export class Slides {
*/ */
@Prop() scrollbar = false; @Prop() scrollbar = false;
/**
* Emitted after Swiper initialization
*/
@Event() ionSlidesDidLoad!: EventEmitter<void>;
/**
* Emitted when the user taps/clicks on the slide's container.
*/
@Event() ionSlideTap!: EventEmitter<void>;
/**
* Emitted when the user double taps on the slide's container.
*/
@Event() ionSlideDoubleTap!: EventEmitter<void>;
/**
* Emitted before the active slide has changed.
*/
@Event() ionSlideWillChange!: EventEmitter<void>;
/**
* Emitted after the active slide has changed.
*/
@Event() ionSlideDidChange!: EventEmitter<void>;
/**
* Emitted when the next slide has started.
*/
@Event() ionSlideNextStart!: EventEmitter<void>;
/**
* Emitted when the previous slide has started.
*/
@Event() ionSlidePrevStart!: EventEmitter<void>;
/**
* Emitted when the next slide has ended.
*/
@Event() ionSlideNextEnd!: EventEmitter<void>;
/**
* Emitted when the previous slide has ended.
*/
@Event() ionSlidePrevEnd!: EventEmitter<void>;
/**
* Emitted when the slide transition has started.
*/
@Event() ionSlideTransitionStart!: EventEmitter<void>;
/**
* Emitted when the slide transition has ended.
*/
@Event() ionSlideTransitionEnd!: EventEmitter<void>;
/**
* Emitted when the slider is actively being moved.
*/
@Event() ionSlideDrag!: EventEmitter<void>;
/**
* Emitted when the slider is at its initial position.
*/
@Event() ionSlideReachStart!: EventEmitter<void>;
/**
* Emitted when the slider is at the last slide.
*/
@Event() ionSlideReachEnd!: EventEmitter<void>;
/**
* Emitted when the user first touches the slider.
*/
@Event() ionSlideTouchStart!: EventEmitter<void>;
/**
* Emitted when the user releases the touch.
*/
@Event() ionSlideTouchEnd!: EventEmitter<void>;
componentDidLoad() { componentDidLoad() {
setTimeout(this.initSlides.bind(this), 10); rIC(() => this.initSwiper());
} }
componentDidUnload() { async componentDidUnload() {
this.swiper.destroy(true, true); const swiper = await this.getSwiper();
swiper.destroy(true, true);
} }
private initSlides() { @Listen('ionSlideChanged')
this.container = (this.el.shadowRoot || this.el).querySelector('.swiper-container') as HTMLElement; onSlideChanged() {
const finalOptions = this.normalizeOptions(); if (this.didInit) {
// init swiper core this.update();
this.swiper = new Swiper(this.container, finalOptions); }
this.readyResolve(true);
} }
/** /**
@ -150,8 +155,8 @@ export class Slides {
*/ */
@Method() @Method()
async update() { async update() {
await this.waitUntilReady(); const swiper = await this.getSwiper();
this.swiper.update(); swiper.update();
} }
/** /**
@ -159,17 +164,17 @@ export class Slides {
*/ */
@Method() @Method()
async slideTo(index: number, speed?: number, runCallbacks?: boolean) { async slideTo(index: number, speed?: number, runCallbacks?: boolean) {
await this.waitUntilReady(); const swiper = await this.getSwiper();
this.swiper.slideTo(index, speed, runCallbacks); swiper.slideTo(index, speed, runCallbacks);
} }
/** /**
* Transition to the next slide. * Transition to the next slide.
*/ */
@Method() @Method()
async slideNext(speed?: number, runCallbacks?: boolean) { async slideNext(speed: number, runCallbacks: boolean) {
await this.waitUntilReady(); const swiper = await this.getSwiper();
this.swiper.slideNext(speed, runCallbacks); swiper.slideNext(speed, runCallbacks);
} }
/** /**
@ -177,8 +182,8 @@ export class Slides {
*/ */
@Method() @Method()
async slidePrev(speed?: number, runCallbacks?: boolean) { async slidePrev(speed?: number, runCallbacks?: boolean) {
await this.waitUntilReady(); const swiper = await this.getSwiper();
this.swiper.slidePrev(speed, runCallbacks); swiper.slidePrev(speed, runCallbacks);
} }
/** /**
@ -186,8 +191,8 @@ export class Slides {
*/ */
@Method() @Method()
async getActiveIndex(): Promise<number> { async getActiveIndex(): Promise<number> {
await this.waitUntilReady(); const swiper = await this.getSwiper();
return Promise.resolve(this.swiper.activeIndex); return swiper.activeIndex;
} }
/** /**
@ -195,8 +200,8 @@ export class Slides {
*/ */
@Method() @Method()
async getPreviousIndex(): Promise<number> { async getPreviousIndex(): Promise<number> {
await this.waitUntilReady(); const swiper = await this.getSwiper();
return Promise.resolve(this.swiper.previousIndex); return swiper.previousIndex;
} }
/** /**
@ -204,8 +209,8 @@ export class Slides {
*/ */
@Method() @Method()
async length(): Promise<number> { async length(): Promise<number> {
await this.waitUntilReady(); const swiper = await this.getSwiper();
return Promise.resolve(this.swiper.slides.length); return swiper.slides.length;
} }
/** /**
@ -214,8 +219,8 @@ export class Slides {
*/ */
@Method() @Method()
async isEnd(): Promise<boolean> { async isEnd(): Promise<boolean> {
await this.waitUntilReady(); const swiper = await this.getSwiper();
return Promise.resolve(this.swiper.isEnd); return swiper.isEnd;
} }
/** /**
@ -223,8 +228,8 @@ export class Slides {
*/ */
@Method() @Method()
async isBeginning(): Promise<boolean> { async isBeginning(): Promise<boolean> {
await this.waitUntilReady(); const swiper = await this.getSwiper();
return Promise.resolve(this.swiper.isBeginning); return swiper.isBeginning;
} }
/** /**
@ -232,8 +237,10 @@ export class Slides {
*/ */
@Method() @Method()
async startAutoplay() { async startAutoplay() {
await this.waitUntilReady(); const swiper = await this.getSwiper();
this.swiper.autoplay.start(); if (swiper.autoplay) {
swiper.autoplay.start();
}
} }
/** /**
@ -241,8 +248,10 @@ export class Slides {
*/ */
@Method() @Method()
async stopAutoplay() { async stopAutoplay() {
await this.waitUntilReady(); const swiper = await this.getSwiper();
this.swiper.autoplay.stop(); if (swiper.autoplay) {
swiper.autoplay.stop();
}
} }
/** /**
@ -250,8 +259,8 @@ export class Slides {
*/ */
@Method() @Method()
async lockSwipeToNext(shouldLockSwipeToNext: boolean) { async lockSwipeToNext(shouldLockSwipeToNext: boolean) {
await this.waitUntilReady(); const swiper = await this.getSwiper();
this.swiper.allowSlideNext = !shouldLockSwipeToNext; swiper.allowSlideNext = !shouldLockSwipeToNext;
} }
/** /**
@ -259,8 +268,8 @@ export class Slides {
*/ */
@Method() @Method()
async lockSwipeToPrev(shouldLockSwipeToPrev: boolean) { async lockSwipeToPrev(shouldLockSwipeToPrev: boolean) {
await this.waitUntilReady(); const swiper = await this.getSwiper();
this.swiper.allowSlidePrev = !shouldLockSwipeToPrev; swiper.allowSlidePrev = !shouldLockSwipeToPrev;
} }
/** /**
@ -268,39 +277,35 @@ export class Slides {
*/ */
@Method() @Method()
async lockSwipes(shouldLockSwipes: boolean) { async lockSwipes(shouldLockSwipes: boolean) {
await this.waitUntilReady(); const swiper = await this.getSwiper();
this.swiper.allowSlideNext = !shouldLockSwipes; swiper.allowSlideNext = !shouldLockSwipes;
this.swiper.allowSlidePrev = !shouldLockSwipes; swiper.allowSlidePrev = !shouldLockSwipes;
this.swiper.allowTouchMove = !shouldLockSwipes; swiper.allowTouchMove = !shouldLockSwipes;
} }
/** private async initSwiper() {
* Calls true if the swiper core is initialized const finalOptions = this.normalizeOptions();
*/
private waitUntilReady(): Promise<boolean> { // init swiper core
return this.readyPromise; const { Swiper } = await import('./swiper/swiper');
const swiper = new Swiper(this.el, finalOptions);
this.didInit = true;
this.readySwiper(swiper);
} }
private normalizeOptions() { private getSwiper() {
return this.swiper;
}
private normalizeOptions(): SwiperOptions {
// Base options, can be changed // Base options, can be changed
// TODO Add interface SwiperOptions // TODO Add interface SwiperOptions
const swiperOptions = { const swiperOptions: SwiperOptions = {
effect: 'slide', effect: 'slide',
direction: 'horizontal', direction: 'horizontal',
initialSlide: 0, initialSlide: 0,
loop: false, loop: false,
pagination: {
el: '.swiper-pagination',
type: 'bullets',
clickable: false,
hideOnClick: false,
},
parallax: false, parallax: false,
scrollbar: {
el: this.scrollbar ? '.swiper-scrollbar' : undefined,
hide: true,
},
slidesPerView: 1, slidesPerView: 1,
spaceBetween: 0, spaceBetween: 0,
speed: 300, speed: 300,
@ -353,11 +358,6 @@ export class Slides {
loopAdditionalSlides: 0, loopAdditionalSlides: 0,
noSwiping: true, noSwiping: true,
runCallbacksOnInit: true, runCallbacksOnInit: true,
controller: {
control: this.swiper,
by: 'slide',
inverse: false,
},
coverflowEffect: { coverflowEffect: {
rotate: 50, rotate: 50,
stretch: 0, stretch: 0,
@ -376,7 +376,7 @@ export class Slides {
shadowScale: 0.94 shadowScale: 0.94
}, },
fadeEffect: { fadeEffect: {
crossFade: false crossfade: false
}, },
a11y: { a11y: {
prevSlideMessage: 'Previous slide', prevSlideMessage: 'Previous slide',
@ -386,9 +386,25 @@ export class Slides {
} }
}; };
if (this.pager) {
swiperOptions.pagination = {
el: this.paginationEl!,
type: 'bullets',
clickable: false,
hideOnClick: false,
};
}
if (this.scrollbar) {
swiperOptions.scrollbar = {
el: this.scrollbarEl!,
hide: true,
};
}
// Keep the event options separate, we dont want users // Keep the event options separate, we dont want users
// overwriting these // overwriting these
const eventOptions = { const eventOptions: SwiperOptions = {
on: { on: {
init: () => { init: () => {
setTimeout(() => { setTimeout(() => {
@ -417,15 +433,22 @@ export class Slides {
return { ...swiperOptions, ...this.options, ...eventOptions }; return { ...swiperOptions, ...this.options, ...eventOptions };
} }
hostData() {
return {
class: {
...createThemedClasses(this.mode, 'slides'),
'swiper-container': true
}
};
}
render() { render() {
return ( return [
<div class="swiper-container" ref={el => this.container = el as HTMLElement}>
<div class="swiper-wrapper"> <div class="swiper-wrapper">
<slot></slot> <slot></slot>
</div> </div>,
{this.pager ? <div class="swiper-pagination"></div> : null} this.pager && <div class="swiper-pagination" ref={el => this.paginationEl = el}></div>,
{this.scrollbar ? <div class="swiper-scrollbar"></div> : null} this.scrollbar && <div class="swiper-scrollbar" ref={el => this.scrollbarEl = el}></div>
</div> ];
);
} }
} }

View File

@ -0,0 +1 @@
export { Swiper as SwiperInterface, SwiperOptions } from 'swiper/dist/js/swiper.esm';

View File

@ -0,0 +1,4 @@
import { Pagination, Scrollbar, Swiper } from 'swiper/dist/js/swiper.esm';
Swiper.use([Pagination, Scrollbar]);
export { Swiper };

View File

@ -1,458 +0,0 @@
// Type definitions for Swiper 4.2
// Project: https://github.com/nolimits4web/Swiper
// Definitions by: Sebastián Galiano <https://github.com/sgaliano>, Luca Trazzi <https://github.com/lucax88x>, Eugene Matseruk <https://github.com/ematseruk>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.7
type CommonEvent =
| 'init'
| 'beforeDestroy'
| 'slideChange'
| 'slideChangeTransitionStart'
| 'slideChangeTransitionEnd'
| 'slideNextTransitionStart'
| 'slideNextTransitionEnd'
| 'slidePrevTransitionStart'
| 'slidePrevTransitionEnd'
| 'transitionStart'
| 'transitionEnd'
| 'touchStart'
| 'touchMove'
| 'touchMoveOpposite'
| 'sliderMove'
| 'touchEnd'
| 'click'
| 'tap'
| 'doubleTap'
| 'imagesReady'
| 'progress'
| 'reachBeginning'
| 'reachEnd'
| 'fromEdge'
| 'setTranslate'
| 'setTransition'
| 'resize';
type PaginationEvent = 'paginationRender' | 'paginationUpdate';
type AutoplayEvent = 'autoplayStart' | 'autoplayStop' | 'autoplay';
type LazyLoadingEvent = 'lazyImageLoad' | 'lazyImageReady';
type SwiperEvent = CommonEvent | PaginationEvent | AutoplayEvent | LazyLoadingEvent;
interface NavigationOptions {
nextEl?: string | HTMLElement;
prevEl?: string | HTMLElement;
hideOnClick?: boolean;
disabledClass?: string;
hiddenClass?: string;
}
interface PaginationOptions {
el?: string;
type?: 'bullets' | 'fraction' | 'progressbar' | 'custom';
bulletElement?: string;
dynamicBullets?: boolean;
dynamicMainBullets?: number;
hideOnClick?: boolean;
clickable?: boolean;
progressbarOpposite?: boolean;
bulletClass?: string;
bulletActiveClass?: string;
modifierClass?: string;
currentClass?: string;
totalClass?: string;
hiddenClass?: string;
progressbarFillClass?: string;
clickableClass?: string;
renderBullet?: (index: number, className: string) => void;
renderFraction?: (currentClass: string, totalClass: string) => void;
renderProgressbar?: (progressbarFillClass: string) => void;
renderCustom?: (swiper: Swiper, current: number, total: number) => void;
}
interface ScrollbarOptions {
el?: string | HTMLElement;
hide?: boolean;
draggable?: boolean;
snapOnRelease?: boolean;
dragSize?: 'auto' | number;
lockClass?: 'string';
dragClass?: 'string';
}
interface AutoplayOptions {
delay?: number;
stopOnLastSlide?: boolean;
disableOnInteraction?: boolean;
reverseDirection?: boolean;
waitForTransition?: boolean;
}
interface LazyLoadingOptions {
loadPrevNext?: string;
loadPrevNextAmount?: number;
loadOnTransitionStart?: boolean;
elementClass?: string;
loadingClass?: string;
loadedClass?: string;
preloaderClass?: string;
}
interface FadeEffectOptions {
crossFade: boolean;
}
interface CoverflowEffectOptions {
slideShadows?: boolean;
rotate?: number;
stretch?: number;
depth?: number;
modifier?: number;
}
interface FlipEffectOptions {
slideShadows?: boolean;
limitRotation?: boolean;
}
interface CubeEffectOptions {
slideShadows?: boolean;
shadow?: boolean;
shadowOffset: number;
shadowScale: number;
}
interface ZoomOptions {
maxRatio?: number;
minRatio?: number;
toggle?: boolean;
containerClass?: string;
zoomedSlideClass?: string;
}
interface KeyboardControlOptions {
enabled?: boolean;
onlyInViewport?: boolean;
}
interface MouseWheelControlOptions {
forceToAxis?: boolean;
releaseOnEdges?: boolean;
invert?: boolean;
sensitivity?: number;
eventsTarged?: string | HTMLElement;
}
interface VirtualSlidesRenderExternalData {
offset: number;
from: number;
to: number;
slides: any[];
}
interface VirtualSlidesOptions {
slides?: any[];
cache?: boolean;
renderSlide?: (slide: any, index: number) => void;
renderExternal?: (data: VirtualSlidesRenderExternalData) => void;
}
interface HashNavigationOptions {
watchState?: boolean;
replaceState?: boolean;
}
interface HistoryNavigationOptions {
replaceState?: boolean;
key?: string;
}
interface ControllerOptions {
control: Swiper;
inverse: boolean;
by: 'slide' | 'container';
}
interface AccessibilityOptions {
enabled?: boolean;
prevSlideMessage?: string;
nextSlideMessage?: string;
firstSlideMessage?: string;
lastSlideMessage?: string;
paginationBulletMessage?: string;
notificationClass?: string;
}
export interface SwiperOptions {
// General parameters
init?: boolean;
initialSlide?: number;
direction?: 'horizontal' | 'vertical';
speed?: number;
setWrapperSize?: boolean;
virtualTranslate?: boolean;
width?: number;
height?: number;
autoHeight?: boolean;
roundLengths?: boolean;
nested?: boolean;
uniqueNavElements?: boolean;
effect?: 'slide' | 'fade' | 'cube' | 'coverflow' | 'flip';
runCallbacksOnInit?: boolean;
watchOverflow?: boolean;
on?: {[key in SwiperEvent]?: () => void };
// Slides grid
spaceBetween?: number;
slidesPerView?: 'auto' | number;
slidesPerColumn?: number;
slidesPerColumnFill?: 'row' | 'column';
slidesPerGroup?: number;
centeredSlides?: boolean;
slidesOffsetBefore?: number;
slidesOffsetAfter?: number;
normalizeSlideIndex?: boolean;
// Grab cursor
grabCursor?: boolean;
// Touches
touchEventsTarget?: 'container' | 'wrapper';
touchRatio?: number;
touchAngle?: number;
simulateTouch?: boolean;
shortSwipes?: boolean;
longSwipes?: boolean;
longSwipesRatio?: number;
longSwipesMs?: number;
followFinger?: boolean;
allowTouchMove?: boolean;
threshold?: number;
touchMoveStopPropagation?: boolean;
iOSEdgeSwipeDetection?: boolean;
iOSEdgeSwipeThreshold?: number;
touchReleaseOnEdges?: boolean;
passiveListeners?: boolean;
// Touch Resistance
resistance?: boolean;
resistanceRatio?: number;
// Swiping / No swiping
preventIntercationOnTransition?: boolean;
allowSlidePrev?: boolean;
allowSlideNext?: boolean;
noSwiping?: boolean;
noSwipingClass?: string;
noSwipingSelector?: string;
swipeHandler?: string | HTMLElement;
// Clicks
preventClicks?: boolean;
preventClicksPropagation?: boolean;
slideToClickedSlide?: boolean;
// Freemode
freeMode?: boolean;
freeModeMomentum?: boolean;
freeModeMomentumRatio?: number;
freeModeMomentumVelocityRatio?: number;
freeModeMomentumBounce?: boolean;
freeModeMomentumBounceRatio?: number;
freeModeMinimumVelocity?: number;
freeModeSticky?: boolean;
// Progress
watchSlidesProgress?: boolean;
watchSlidesVisibility?: boolean;
// Images
preloadImages?: boolean;
updateOnImagesReady?: boolean;
// Loop
loop?: boolean;
loopAdditionalSlides?: number;
loopedSlides?: number;
loopFillGroupWithBlank?: boolean;
// Breakpoints
breakpoints?: {
// TODO: extract possible parameters for breakpoints to separate interface
[index: number]: any;
};
// Observer
observer?: boolean;
observeParents?: boolean;
// Namespace
containerModifierClass?: string;
slideClass?: string;
slideActiveClass?: string;
slideDuplicatedActiveClass?: string;
slideVisibleClass?: string;
slideDuplicateClass?: string;
slideNextClass?: string;
slideDuplicatedNextClass?: string;
slidePrevClass?: string;
slideDuplicatedPrevClass?: string;
wrapperClass?: string;
// Components
navigation?: NavigationOptions;
pagination?: PaginationOptions;
scrollbar?: ScrollbarOptions;
autoplay?: AutoplayOptions;
parallax?: boolean;
lazy?: LazyLoadingOptions | boolean;
fadeEffect?: FadeEffectOptions;
coverflowEffect?: CoverflowEffectOptions;
flipEffect?: FlipEffectOptions;
cubeEffect?: CubeEffectOptions;
zoom?: ZoomOptions | boolean;
keyboard?: KeyboardControlOptions | boolean;
mousewheel?: MouseWheelControlOptions | boolean;
virtual?: VirtualSlidesOptions;
hashNavigation?: HashNavigationOptions;
history?: HistoryNavigationOptions;
controller?: ControllerOptions;
a11y?: AccessibilityOptions;
}
interface Navigation {
nextEl: HTMLElement;
prevEl: HTMLElement;
update: () => void;
}
interface Pagination {
el: HTMLElement;
// TODO: dom7 like array
bullets: any[];
render: () => void;
update: () => void;
}
interface Scrollbar {
eL: HTMLElement;
dragEl: HTMLElement;
updateSize: () => void;
}
interface Autoplay {
running: boolean;
start: () => void;
stop: () => void;
}
interface LazyLoading {
load: () => void;
loadInSlide: (index: number) => void;
}
interface Zoom {
enabled: boolean;
scale: number;
enable: () => void;
disable: () => void;
in: () => void;
out: () => void;
toggle: () => void;
}
// Keyboard and Mousewheel control
interface Control {
enabled: boolean;
enable: () => void;
disable: () => void;
}
interface VirtualSlides {
cache: any;
from: number;
to: number;
slides: any[];
appendSlide: (slide: any) => void;
prependSlide: (slide: any) => void;
update: () => void;
}
interface Controller {
control: Swiper;
}
export declare class Swiper {
constructor(container: string | Element, parameters?: SwiperOptions);
// Properties
params: SwiperOptions;
// TODO: dom7 element
$el: any;
// TODO: dom7 element
$wrapperEl: any;
slides: HTMLElement[];
width: number;
height: number;
translate: number;
progress: number;
activeIndex: number;
realIndex: number;
previousIndex: number;
isBeginning: boolean;
isEnd: boolean;
animating: boolean;
touches: {
startX: number;
startY: number;
currentX: number;
currentY: number;
diff: number;
};
clickedIndex: number;
clickedSlide: HTMLElement;
allowSlideNext: boolean;
allowSlidePrev: boolean;
allowTouchMove: boolean;
slideNext: (speed?: number, runCallbacks?: boolean) => void;
slidePrev: (speed?: number, runCallbacks?: boolean) => void;
slideTo: (index: number, speed?: number, runCallbacks?: boolean) => void;
slideToLoop: (index: number, speed?: number, runCallbacks?: boolean) => void;
slideReset: (speed?: number, runCallbacks?: boolean) => void;
slideToClosest: (speed?: number, runCallbacks?: boolean) => void;
updateAutoHeight: (speed?: number) => void;
update: () => void;
detachEvents: () => void;
attachEvents: () => void;
destroy: (deleteInstance?: boolean, cleanStyles?: boolean) => void;
appendSlide: (slides: Array<(HTMLElement | string)> | string | HTMLElement) => void;
prependSlide: (slides: Array<(HTMLElement | string)> | string | HTMLElement) => void;
removeSlide: (index: number) => void;
removeAllSlides: () => void;
setTranslate: (translate: number) => void;
getTranslate: () => void;
on: (event: SwiperEvent, handler: () => void) => void;
once: (event: SwiperEvent, handler: () => void) => void;
off: (event: SwiperEvent, handler?: () => void) => void;
unsetGrabCursor: () => void;
setGrabCursor: () => void;
// components
navigation: Navigation;
pagination: Pagination;
scrollbar: Scrollbar;
autoplay: Autoplay;
zoom: Zoom;
keyboard: Control;
mousewheel: Control;
virtual: VirtualSlides;
controller: Controller;
}

File diff suppressed because it is too large Load Diff