diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index f67837c764..b743f8be51 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -40,6 +40,9 @@ import { import { SelectPopoverOption, } from './components/select-popover/select-popover'; +import { + SwiperOptions, +} from './components/slides/vendor/swiper'; import { ActionSheetController as IonActionSheetController @@ -2626,20 +2629,8 @@ declare global { } namespace JSXElements { export interface IonSlidesAttributes extends HTMLAttributes { - autoplay?: number; - control?: any; - direction?: 'horizontal' | 'vertical'; - effect?: string; - initialSlide?: number; - keyboardControl?: boolean; - loop?: boolean; + options?: SwiperOptions; pager?: boolean; - paginationType?: string; - parallax?: boolean; - slidesPerView?: number | 'auto'; - spaceBetween?: number; - speed?: number; - zoom?: boolean; } } } diff --git a/packages/core/src/components/popover/popover.tsx b/packages/core/src/components/popover/popover.tsx index 2dc23a8197..395a17154c 100644 --- a/packages/core/src/components/popover/popover.tsx +++ b/packages/core/src/components/popover/popover.tsx @@ -116,7 +116,7 @@ export class Popover { .then((mountingData) => { this.usersComponentElement = mountingData.element; return domControllerAsync(this.dom.raf, () => { }) - .then(() => this.animationCtrl.create(animationBuilder, this.el, this.ev)) + .then(() => this.animationCtrl.create(animationBuilder, this.el, this.ev)); }) .then((animation) => { this.animation = animation; diff --git a/packages/core/src/components/slides/readme.md b/packages/core/src/components/slides/readme.md index 39d05df961..0e99de4d75 100644 --- a/packages/core/src/components/slides/readme.md +++ b/packages/core/src/components/slides/readme.md @@ -24,146 +24,36 @@ Licensed under MIT ## Properties -#### autoplay - -number - - -#### control +#### options any - -#### direction - -any - - -#### effect - -string - - -#### initialSlide - -number - - -#### keyboardControl - -boolean - - -#### loop - -boolean +Options to pass to the swiper instance. +See http://idangero.us/swiper/api/ for valid options #### pager boolean - -#### paginationType - -string - - -#### parallax - -boolean - - -#### slidesPerView - -any - - -#### spaceBetween - -number - - -#### speed - -number - - -#### zoom - -boolean +Show or hide the pager ## Attributes -#### autoplay - -number - - -#### control +#### options any - -#### direction - -any - - -#### effect - -string - - -#### initialSlide - -number - - -#### keyboardControl - -boolean - - -#### loop - -boolean +Options to pass to the swiper instance. +See http://idangero.us/swiper/api/ for valid options #### pager boolean - -#### paginationType - -string - - -#### parallax - -boolean - - -#### slidesPerView - -any - - -#### spaceBetween - -number - - -#### speed - -number - - -#### zoom - -boolean +Show or hide the pager ## Events @@ -207,6 +97,79 @@ boolean #### ionSlideWillChange +## Methods + +#### getActiveIndex() + +Get the index of the active slide. + + +#### getPreviousIndex() + +Get the index of the previous slide. + + +#### isBeginning() + +Get whether or not the current slide is the first slide. + + +#### isEnd() + +Get whether or not the current slide is the last slide. + + +#### length() + +Get the total number of slides. + + +#### lockSwipeToNext() + +Lock or unlock the ability to slide to the next slides. + + +#### lockSwipeToPrev() + +Lock or unlock the ability to slide to the previous slides. + + +#### lockSwipes() + +Lock or unlock the ability to slide to change slides. + + +#### slideNext() + +Transition to the next slide. + + +#### slidePrev() + +Transition to the previous slide. + + +#### slideTo() + +Transition to the specified slide. + + +#### startAutoplay() + +Start auto play. + + +#### stopAutoplay() + +Stop auto play. + + +#### update() + +Update the underlying slider implementation. Call this if you've added or removed +child slides. + + ---------------------------------------------- diff --git a/packages/core/src/components/slides/slides.tsx b/packages/core/src/components/slides/slides.tsx index f7238151e9..179d30c608 100644 --- a/packages/core/src/components/slides/slides.tsx +++ b/packages/core/src/components/slides/slides.tsx @@ -1,6 +1,6 @@ -import { Component, Element, Event, EventEmitter, Prop } from '@stencil/core'; +import { Component, Element, Event, EventEmitter, Method, Prop, PropDidChange } from '@stencil/core'; import { Swiper } from './vendor/swiper.js'; - +import { SwiperOptions } from './vendor/swiper'; @Component({ tag: 'ion-slides', @@ -8,9 +8,16 @@ import { Swiper } from './vendor/swiper.js'; assetsDir: 'vendor' }) export class Slides { - swiper: any; - @Element() private el: HTMLElement; + private container: HTMLElement; + private init: boolean; + private tmr: number; + private swiper: any; + private finalOptions: any; + private slidesId: number; + private slideId: string; + + @Element() private el: HTMLElement; /** * @output {Event} Emitted before the active slide has changed. @@ -78,178 +85,78 @@ export class Slides { @Event() ionSlideTouchEnd: EventEmitter; /** - * @input {string} The animation effect of the slides. - * Possible values are: `slide`, `fade`, `cube`, `coverflow` or `flip`. - * Default: `slide`. + * Options to pass to the swiper instance. + * See http://idangero.us/swiper/api/ for valid options */ - @Prop() effect: string = 'slide'; + @Prop() options: SwiperOptions; + + @PropDidChange('options') + updateSwiperOptions() { + let newOptions = this.normalizeOptions(); + this.swiper.params = Object.assign({}, this.swiper.params, newOptions); + this.update(); + } /** - * @input {number} Delay between transitions (in milliseconds). If this - * parameter is not passed, autoplay is disabled. Default does - * not have a value and does not autoplay. - * Default: `null`. + * Show or hide the pager */ - @Prop() autoplay: number; - - /** - * @input {Slides} Pass another Slides instance or array of Slides instances - * that should be controlled by this Slides instance. - * Default: `null`. - */ - @Prop() control: any = null; - - /** - * @input {string} Swipe direction: 'horizontal' or 'vertical'. - * Default: `horizontal`. - */ - @Prop() direction: 'horizontal' | 'vertical' = 'horizontal'; - - /** - * @input {number} Index number of initial slide. Default: `0`. - */ - @Prop() initialSlide: number = 0; - - /** - * @input {boolean} If true, continuously loop from the last slide to the - * first slide. - */ - @Prop() loop: boolean = false; - - /** - * @input {boolean} If true, show the pager. - */ - @Prop() pager: boolean; - - /** - * @input {string} Type of pagination. Possible values are: - * `bullets`, `fraction`, `progress`. Default: `bullets`. - * (Note that the pager will not show unless `pager` input - * is set to true). - */ - @Prop() paginationType: string = 'bullets'; - - - /** - * @input {boolean} If true, allows you to use "parallaxed" elements inside of - * slider. - */ - @Prop() parallax: boolean = false; - - /** - * @input {number} Slides per view. Slides visible at the same time. Default: `1`. - */ - @Prop() slidesPerView: number | 'auto' = 1; - - /** - * @input {number} Distance between slides in px. Default: `0`. - */ - @Prop() spaceBetween: number = 0; - - /** - * @input {number} Duration of transition between slides - * (in milliseconds). Default: `300`. - */ - @Prop() speed: number = 300; - - - /** - * @input {boolean} If true, enables zooming functionality. - */ - @Prop() zoom: boolean; - - /** - * @input {boolean} If true, enables keyboard control - */ - @Prop() keyboardControl: boolean; - + @Prop() pager: boolean = true; render() { return (
- +
-
+
); } - /** - * Height of container. - */ - private height: number; - - /** - * Width of container. - */ - private width: number; - - /** - * Enabled this option and swiper will be operated as usual except it will - * not move, real translate values on wrapper will not be set. Useful when - * you may need to create custom slide transition. - */ - private virtualTranslate = false; - - /** - * Set to true to round values of slides width and height to prevent blurry - * texts on usual resolution screens (if you have such) - */ - private roundLengths = false; - - // Slides grid - - private originalEvent: any; - - /** - * Private properties only useful to this class. - * ------------------------------------ - */ - private _init: boolean; - private _tmr: number; - - /** - * Properties that are exposed publicly but no docs. - * ------------------------------------ - */ - private container: HTMLElement; - private slidesId: number; - private slideId: string; - - - constructor( - ) { + constructor() { this.slidesId = ++slidesId; this.slideId = 'slides-' + this.slidesId; } - private _initSlides() { - if (!this._init) { + private initSlides() { + if (!this.init) { console.debug(`ion-slides, init`); this.container = this.el.children[0] as HTMLElement; + // init swiper core + this.swiper = new Swiper(this.container, this.normalizeOptions()); + + if (this.options.keyboardControl) { + // init keyboard event listeners + this.enableKeyboardControl(true); + } + + this.init = true; + } + } + + normalizeOptions() { + // Base options, can be changed var swiperOptions = { - height: this.height, - width: this.width, - virtualTranslate: this.virtualTranslate, - roundLengths: this.roundLengths, - originalEvent: this.originalEvent, - autoplay: this.autoplay, - direction: this.direction, - initialSlide: this.initialSlide, - loop: this.loop, - pager: this.pager, - paginationType: this.paginationType, - parallax: this.parallax, - slidesPerView: this.slidesPerView, - spaceBetween: this.spaceBetween, - speed: this.speed, - zoom: this.zoom, + effect: 'slide', + autoplay: 0, + direction: 'horizontal', + initialSlide: 0, + loop: false, + pager: false, + pagination: '.swiper-pagination', + paginationType: 'bullets', + parallax: false, + slidesPerView: 1, + spaceBetween: 0, + speed: 300, + zoom: false, slidesPerColumn: 1, slidesPerColumnFill: 'column', slidesPerGroup: 1, @@ -324,7 +231,12 @@ export class Slides { prevSlideMessage: 'Previous slide', nextSlideMessage: 'Next slide', firstSlideMessage: 'This is the first slide', - lastSlideMessage: 'This is the last slide', + lastSlideMessage: 'This is the last slide' + }; + + // Keep the event options separate, we dont want users + // overwriting these + var eventOptions = { onSlideChangeStart: this.ionSlideWillChange.emit, onSlideChangeEnd: this.ionSlideDidChange.emit, onSlideNextStart: this.ionSlideNextStart.emit, @@ -337,19 +249,17 @@ export class Slides { onReachBeginning: this.ionSlideReachStart.emit, onReachEnd: this.ionSlideReachEnd.emit, onTouchStart: this.ionSlideTouchStart.emit, - onTouchEnd: this.ionSlideTouchEnd.emit, + onTouchEnd: this.ionSlideTouchEnd.emit }; - // init swiper core - this.swiper = new Swiper(this.container, swiperOptions); + // Merge the base, user options, and events together then pas to swiper + return Object.assign( + {}, + swiperOptions, + this.options, + eventOptions + ); - if (this.keyboardControl) { - // init keyboard event listeners - this.enableKeyboardControl(true); - } - - this._init = true; - } } componentDidLoad() { @@ -358,7 +268,7 @@ export class Slides { * child components are ready. */ setTimeout(() => { - this._initSlides(); + this.initSlides(); }, 10); } @@ -366,18 +276,20 @@ export class Slides { * Update the underlying slider implementation. Call this if you've added or removed * child slides. */ + @Method() update(debounce = 300) { - if (this._init) { - window.clearTimeout(this._tmr); - this._tmr = window.setTimeout(() => { - this.swiper.update(); - - // Don't allow pager to show with > 10 slides - if (this.length() > 10) { - this.paginationType = undefined; - } - }, debounce); - } + this.swiper.update(); + // if (this.init) { + // window.clearTimeout(this.tmr); + // this.tmr = window.setTimeout(() => { + // this.swiper.update(); + // + // // Don't allow pager to show with > 10 slides + // if (this.length() > 10) { + // this.options.paginationType = undefined; + // } + // }, debounce); + // } } /** @@ -387,6 +299,7 @@ export class Slides { * @param {number} [speed] Transition duration (in ms). * @param {boolean} [runCallbacks] Whether or not to emit the `ionSlideWillChange`/`ionSlideDidChange` events. Default true. */ + @Method() slideTo(index: number, speed?: number, runCallbacks?: boolean) { this.swiper.slideTo(index, speed, runCallbacks); } @@ -397,6 +310,7 @@ export class Slides { * @param {number} [speed] Transition duration (in ms). * @param {boolean} [runCallbacks] Whether or not to emit the `ionSlideWillChange`/`ionSlideDidChange` events. Default true. */ + @Method() slideNext(speed?: number, runCallbacks?: boolean) { this.swiper.slideNext(runCallbacks, speed); } @@ -407,6 +321,7 @@ export class Slides { * @param {number} [speed] Transition duration (in ms). * @param {boolean} [runCallbacks] Whether or not to emit the `ionSlideWillChange`/`ionSlideDidChange` events. Default true. */ + @Method() slidePrev(speed?: number, runCallbacks?: boolean) { this.swiper.slidePrev(runCallbacks, speed); } @@ -416,6 +331,7 @@ export class Slides { * * @returns {number} The index number of the current slide. */ + @Method() getActiveIndex(): number { return this.swiper.activeIndex; } @@ -425,6 +341,7 @@ export class Slides { * * @returns {number} The index number of the previous slide. */ + @Method() getPreviousIndex(): number { return this.swiper.previousIndex; } @@ -434,6 +351,7 @@ export class Slides { * * @returns {number} The total number of slides. */ + @Method() length(): number { return this.swiper.slides.length; } @@ -443,8 +361,9 @@ export class Slides { * * @returns {boolean} If the slide is the last slide or not. */ + @Method() isEnd(): boolean { - return this.isEnd(); + return this.swiper.isEnd; } /** @@ -452,27 +371,31 @@ export class Slides { * * @returns {boolean} If the slide is the first slide or not. */ + @Method() isBeginning(): boolean { - return this.isBeginning(); + return this.swiper.isBeginning; } /** * Start auto play. */ - startAutoplay() { + @Method() + startAutoplay(speed?: number): void { this.swiper.startAutoplay(); } /** * Stop auto play. */ - stopAutoplay() { + @Method() + stopAutoplay(): void { this.swiper.stopAutoplay(); } /** * Lock or unlock the ability to slide to the next slides. */ + @Method() lockSwipeToNext(shouldLockSwipeToNext: boolean) { if (shouldLockSwipeToNext) { return this.swiper.lockSwipeToNext(); @@ -483,6 +406,7 @@ export class Slides { /** * Lock or unlock the ability to slide to the previous slides. */ + @Method() lockSwipeToPrev(shouldLockSwipeToPrev: boolean) { if (shouldLockSwipeToPrev) { return this.swiper.lockSwipeToPrev(); @@ -493,6 +417,7 @@ export class Slides { /** * Lock or unlock the ability to slide to change slides. */ + @Method() lockSwipes(shouldLockSwipes: boolean) { if (shouldLockSwipes) { return this.swiper.lockSwipes(); @@ -510,8 +435,11 @@ export class Slides { this.swiper.disableKeyboardControl(); } + /** + * @hidden + */ componentDidUnload() { - this._init = false; + this.init = false; this.swiper.destroy(true, true); this.enableKeyboardControl(false); diff --git a/packages/core/src/components/slides/test/app-intro/index.html b/packages/core/src/components/slides/test/app-intro/index.html new file mode 100644 index 0000000000..b8f7efe38e --- /dev/null +++ b/packages/core/src/components/slides/test/app-intro/index.html @@ -0,0 +1,102 @@ + + + + + + Slides - App Intro + + + + + + + + + + + + + + Prev + + + Next + + + + + + + + +
+

+ Welcome to ICA +

+

+ The ionic conference app is a practical preview of the ionic framework in action, and a demonstration of proper code use. +

+
+
+ + + +
+

What is Ionic?

+

Ionic Framework is an open source SDK that enables developers to build high quality mobile apps with web technologies like HTML, CSS, and JavaScript.

+
+
+ + + +
+

What is Ionic Pro?

+

Ionic Pro is a powerful set of services and features built on top of Ionic Framework that brings a totally new level of app development agility to mobile dev teams.

+
+
+ + + + + Back to the start + + +
+
+
+
+ + + + diff --git a/packages/core/src/components/slides/test/basic/index.html b/packages/core/src/components/slides/test/basic/index.html index 5ac5ea175b..5ab885a700 100644 --- a/packages/core/src/components/slides/test/basic/index.html +++ b/packages/core/src/components/slides/test/basic/index.html @@ -1,9 +1,11 @@ + Slides - Basic - + + @@ -11,7 +13,7 @@ - +

Slide 1

@@ -22,8 +24,113 @@

Slide 3

+ Slide Prev + Slide Next + Get Active Index + Get Previous Index + + Is the End? + Is the beginning? + + Slide to slide index 2 + Get slide length + Start auto play + Stop auto play + Set options
+ + diff --git a/packages/core/src/components/slides/test/standalone/index.html b/packages/core/src/components/slides/test/standalone/index.html index c863d9a5d8..431072192f 100644 --- a/packages/core/src/components/slides/test/standalone/index.html +++ b/packages/core/src/components/slides/test/standalone/index.html @@ -9,7 +9,7 @@ - +

Slide 1

@@ -24,5 +24,12 @@
+ + diff --git a/packages/core/src/components/slides/vendor/swiper.d.ts b/packages/core/src/components/slides/vendor/swiper.d.ts index e10fab4bef..9678067efe 100644 --- a/packages/core/src/components/slides/vendor/swiper.d.ts +++ b/packages/core/src/components/slides/vendor/swiper.d.ts @@ -3,7 +3,7 @@ // Definitions by: Sebastián Galiano , Luca Trazzi // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -interface SwiperOptions { +export interface SwiperOptions { initialSlide?: number; direction?: string; speed?: number;