123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /**
- * The component for handling pagination
- *
- * @author Naotoshi Fujita
- * @copyright Naotoshi Fujita. All rights reserved.
- */
- import { create, addClass, removeClass } from '../../utils/dom';
- import { subscribe } from '../../utils/dom';
- import { STATUS_CLASSES } from '../../constants/classes';
- /**
- * The event name for updating some attributes of pagination nodes.
- *
- * @type {string}
- */
- const ATTRIBUTES_UPDATE_EVENT = 'move.page';
- /**
- * The event name for "update".
- *
- * @type {string}
- */
- const UPDATE_EVENT = 'updated.page';
- /**
- * The component for handling pagination
- *
- * @param {Splide} Splide - A Splide instance.
- * @param {Object} Components - An object containing components.
- * @param {string} name - A component name as a lowercase string.
- *
- * @return {Object} - The component object.
- */
- export default ( Splide, Components, name ) => {
- /**
- * Store all data for pagination.
- * - list: A list element.
- * - items: An array that contains objects(li, button, index, page).
- *
- * @type {Object}
- */
- let data = {};
- /**
- * Pagination component object.
- *
- * @type {Object}
- */
- const Pagination = {
- /**
- * Required only when the pagination option is true.
- *
- * @type {boolean}
- */
- required: Splide.options.pagination,
- /**
- * Called when the component is mounted.
- */
- mount() {
- data = createPagination();
- const root = Splide.root;
- if ( Splide.options.pagination === 'top' ) {
- root.insertBefore( data.list, Components.Elements.track );
- } else {
- root.appendChild( data.list );
- }
- bind();
- },
- /**
- * Called after all components are mounted.
- */
- mounted() {
- const index = Splide.index;
- Splide.emit( `${ name }:mounted`, data, this.getItem( index ) );
- update( index, -1 );
- },
- /**
- * Destroy the pagination.
- * Be aware that node.remove() is not supported by IE.
- */
- destroy() {
- if ( data && data.list ) {
- Splide.root.removeChild( data.list );
- }
- Splide.off( ATTRIBUTES_UPDATE_EVENT ).off( UPDATE_EVENT );
- data = null;
- },
- /**
- * Return an item by index.
- *
- * @param {number} index - A slide index.
- *
- * @return {Object|undefined} - An item object on success or undefined on failure.
- */
- getItem( index ) {
- return data.items[ Components.Controller.indexToPage( index ) ];
- },
- /**
- * Return object containing pagination data.
- *
- * @return {Object} - Pagination data including list and items.
- */
- get data() {
- return data;
- },
- };
- /**
- * Listen some events.
- */
- function bind() {
- Splide
- .on( ATTRIBUTES_UPDATE_EVENT, update )
- .on( UPDATE_EVENT, () => {
- Pagination.destroy();
- if ( Splide.options.pagination ) {
- Pagination.mount();
- Pagination.mounted();
- }
- } );
- }
- /**
- * Update attributes.
- *
- * @param {number} index - Active index.
- * @param {number} prevIndex - Prev index.
- */
- function update( index, prevIndex ) {
- const prev = Pagination.getItem( prevIndex );
- const curr = Pagination.getItem( index );
- if ( prev ) {
- removeClass( prev.button, STATUS_CLASSES.active );
- }
- if ( curr ) {
- addClass( curr.button, STATUS_CLASSES.active );
- }
- Splide.emit( `${ name }:updated`, data, prev, curr );
- }
- /**
- * Create a wrapper and button elements.
- *
- * @return {Object} - An object contains all data.
- */
- function createPagination() {
- const options = Splide.options;
- const classes = Splide.classes;
- const list = create( 'ul', { class: classes.pagination } );
- const Slides = Components.Slides;
- const items = Slides.getSlides( false, true )
- .filter( Slide => options.focus || Slide.index % options.perView === 0 )
- .map( ( Slide, page ) => {
- const li = create( 'li', {} );
- const button = create( 'button', { class: classes.page } );
- li.appendChild( button );
- list.appendChild( li );
- subscribe( button, 'click', () => { Splide.go( `>${ page }` ) } );
- return { li, button, page, Slides: Slides.getSlidesByPage( page ) };
- } );
- return { list, items };
- }
- return Pagination;
- }
|