123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- import { ArrowsComponent, Components, Options } from '@splidejs/splide';
- import { ALL_ATTRIBUTES, ARIA_CONTROLS, ARIA_LABEL } from '../../constants/attributes';
- import {
- EVENT_ARROWS_MOUNTED,
- EVENT_ARROWS_UPDATED,
- EVENT_MOUNTED,
- EVENT_MOVE,
- EVENT_REFRESH,
- EVENT_SCROLLED,
- EVENT_UPDATED,
- } from '../../constants/events';
- import { EventInterface } from '../../constructors';
- import { Splide } from '../../core/Splide/Splide';
- import { append, before, child, create, display, parseHtml, remove, removeAttribute, setAttribute } from '../../utils';
- import { PATH, SIZE, XML_NAME_SPACE } from './path';
- /**
- * The component for handling previous and next arrows.
- *
- * @since 3.0.0
- *
- * @param Splide - A Splide instance.
- * @param Components - A collection of components.
- * @param options - Options.
- *
- * @return An Arrows component object.
- */
- export function Arrows( Splide: Splide, Components: Components, options: Options ): ArrowsComponent {
- const { on, bind, emit } = EventInterface( Splide );
- const { classes, i18n } = options;
- const { Elements, Controller } = Components;
- const { slider, track } = Elements;
- /**
- * The wrapper element.
- */
- let wrapper = Elements.arrows;
- /**
- * The previous arrow element.
- */
- let prev = Elements.prev;
- /**
- * The next arrow element.
- */
- let next = Elements.next;
- /**
- * Indicates whether the component creates arrows or retrieved from the DOM.
- */
- let created: boolean;
- /**
- * An object with previous and next arrows.
- */
- const arrows: ArrowsComponent[ 'arrows' ] = {};
- /**
- * Called when the component is mounted.
- */
- function mount(): void {
- init();
- on( EVENT_UPDATED, init );
- }
- /**
- * Initializes the component.
- */
- function init(): void {
- if ( options.arrows ) {
- if ( ! prev || ! next ) {
- createArrows();
- }
- }
- if ( prev && next ) {
- if ( ! arrows.prev ) {
- setAttribute( prev, ARIA_CONTROLS, track.id );
- setAttribute( next, ARIA_CONTROLS, track.id );
- arrows.prev = prev;
- arrows.next = next;
- listen();
- emit( EVENT_ARROWS_MOUNTED, prev, next );
- } else {
- display( wrapper, options.arrows === false ? 'none' : '' );
- }
- }
- }
- /**
- * Destroys the component.
- */
- function destroy(): void {
- if ( created ) {
- remove( wrapper );
- } else {
- removeAttribute( prev, ALL_ATTRIBUTES );
- removeAttribute( next, ALL_ATTRIBUTES );
- }
- }
- /**
- * Listens to some events.
- */
- function listen(): void {
- const { go } = Controller;
- on( [ EVENT_MOUNTED, EVENT_MOVE, EVENT_UPDATED, EVENT_REFRESH, EVENT_SCROLLED ], update );
- bind( next, 'click', () => { go( '>' ) } );
- bind( prev, 'click', () => { go( '<' ) } );
- }
- /**
- * Create arrows and append them to the slider.
- */
- function createArrows(): void {
- const parent = options.arrows === 'slider' && slider ? slider : Splide.root;
- wrapper = create( 'div', classes.arrows );
- prev = createArrow( true );
- next = createArrow( false );
- created = true;
- append( wrapper, [ prev, next ] );
- before( wrapper, child( parent ) );
- }
- /**
- * Creates an arrow button.
- *
- * @param prev - Determines whether to create a previous or next arrow.
- *
- * @return A created button element.
- */
- function createArrow( prev: boolean ): HTMLButtonElement {
- const arrow = `<button class="${ classes.arrow } ${ prev ? classes.prev : classes.next }" type="button">`
- + `<svg xmlns="${ XML_NAME_SPACE }" viewBox="0 0 ${ SIZE } ${ SIZE }" width="${ SIZE }" height="${ SIZE }">`
- + `<path d="${ options.arrowPath || PATH }" />`;
- return parseHtml<HTMLButtonElement>( arrow );
- }
- /**
- * Updates status of arrows, such as `disabled` and `aria-label`.
- */
- function update(): void {
- const index = Splide.index;
- const prevIndex = Controller.getPrev();
- const nextIndex = Controller.getNext();
- const prevLabel = prevIndex > -1 && index < prevIndex ? i18n.last : i18n.prev;
- const nextLabel = nextIndex > -1 && index > nextIndex ? i18n.first : i18n.next;
- prev.disabled = prevIndex < 0;
- next.disabled = nextIndex < 0;
- setAttribute( prev, ARIA_LABEL, prevLabel );
- setAttribute( next, ARIA_LABEL, nextLabel );
- emit( EVENT_ARROWS_UPDATED, prev, next, prevIndex, nextIndex );
- }
- return {
- arrows,
- mount,
- destroy,
- };
- }
|