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 = `