Kaynağa Gözat

Forwards focus to the active slide on loop or rewind. Remove the focus class.

NaotoshiFujita 3 yıl önce
ebeveyn
işleme
823990ea04

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/js/splide-renderer.min.js


+ 24 - 23
dist/js/splide.js

@@ -301,7 +301,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   }
 
   function queryAll(parent, selector) {
-    return slice(parent.querySelectorAll(selector));
+    return selector ? slice(parent.querySelectorAll(selector)) : [];
   }
 
   function removeClass(elm, classes) {
@@ -719,8 +719,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   var CLASS_NEXT = "is-next";
   var CLASS_VISIBLE = "is-visible";
   var CLASS_LOADING = "is-loading";
-  var CLASS_FOCUS = "has-focus";
-  var STATUS_CLASSES = [CLASS_ACTIVE, CLASS_VISIBLE, CLASS_PREV, CLASS_NEXT, CLASS_LOADING, CLASS_FOCUS];
+  var STATUS_CLASSES = [CLASS_ACTIVE, CLASS_VISIBLE, CLASS_PREV, CLASS_NEXT, CLASS_LOADING];
   var CLASSES = {
     slide: CLASS_SLIDE,
     clone: CLASS_CLONE,
@@ -735,7 +734,8 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
   function Elements(Splide2, Components2, options) {
     var _EventInterface = EventInterface(Splide2),
-        on = _EventInterface.on;
+        on = _EventInterface.on,
+        bind = _EventInterface.bind;
 
     var root = Splide2.root;
     var i18n = options.i18n;
@@ -811,15 +811,10 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       return [CLASS_ROOT + "--" + options.type, CLASS_ROOT + "--" + options.direction, options.drag && CLASS_ROOT + "--draggable", options.isNavigation && CLASS_ROOT + "--nav", CLASS_ACTIVE];
     }
 
-    function isTab() {
-      return !!options.pagination;
-    }
-
     return assign(elements, {
       setup: setup,
       mount: mount,
-      destroy: destroy,
-      isTab: isTab
+      destroy: destroy
     });
   }
 
@@ -840,18 +835,17 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var isNavigation = options.isNavigation,
         updateOnMove = options.updateOnMove,
         i18n = options.i18n;
-    var isTab = Components.Elements.isTab;
     var resolve = Components.Direction.resolve;
     var styles = getAttribute(slide, "style");
     var isClone = slideIndex > -1;
     var container = child(slide, "." + CLASS_CONTAINER);
-    var focusableNodes = options.focusableNodes && queryAll(slide, options.focusableNodes);
+    var focusableNodes = queryAll(slide, options.focusableNodes || "");
     var destroyed;
 
     function mount() {
       if (!isClone) {
         slide.id = root.id + "-slide" + pad(index + 1);
-        setAttribute(slide, ROLE, isTab() ? "tabpanel" : "group");
+        setAttribute(slide, ROLE, options.pagination ? "tabpanel" : "group");
         setAttribute(slide, ARIA_ROLEDESCRIPTION, i18n.slide);
         setAttribute(slide, ARIA_LABEL, format(i18n.slideLabel, [index + 1, Splide2.length]));
       }
@@ -897,28 +891,29 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
     function update() {
       if (!destroyed) {
-        var currIndex = Splide2.index;
+        var curr = Splide2.index;
         updateActivity(isActive());
         updateVisibility(isVisible());
-        toggleClass(slide, CLASS_PREV, index === currIndex - 1);
-        toggleClass(slide, CLASS_NEXT, index === currIndex + 1);
+        toggleClass(slide, CLASS_PREV, index === curr - 1);
+        toggleClass(slide, CLASS_NEXT, index === curr + 1);
       }
     }
 
     function updateActivity(active) {
       if (active !== hasClass(slide, CLASS_ACTIVE)) {
         toggleClass(slide, CLASS_ACTIVE, active);
-
-        if (isNavigation) {
-          setAttribute(slide, ARIA_SELECTED, active || "");
-        }
-
+        setAttribute(slide, ARIA_CURRENT, isNavigation && active || "");
         emit(active ? EVENT_ACTIVE : EVENT_INACTIVE, self);
       }
     }
 
     function updateVisibility(visible) {
       var hidden = !visible && (!isActive() || isClone);
+
+      if (document.activeElement === slide && hidden) {
+        nextTick(forwardFocus);
+      }
+
       setAttribute(slide, ARIA_HIDDEN, hidden || "");
       setAttribute(slide, TAB_INDEX, !hidden && options.slideFocus ? 0 : "");
       setAttribute(focusableNodes || [], TAB_INDEX, hidden ? -1 : "");
@@ -929,6 +924,14 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       }
     }
 
+    function forwardFocus() {
+      var Slide2 = Components.Slides.getAt(Splide2.index);
+
+      if (Slide2) {
+        focus(Slide2.slide);
+      }
+    }
+
     function style$1(prop, value, useContainer) {
       style(useContainer && container || slide, prop, value);
     }
@@ -2492,8 +2495,6 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       var parent = options.pagination === "slider" && Elements.slider || Elements.root;
       var max = hasFocus() ? length : ceil(length / perPage);
       list = create("ul", classes.pagination, parent);
-      bind(list, "focusin", apply(addClass, list, CLASS_FOCUS));
-      bind(list, "focusout", apply(removeClass, list, CLASS_FOCUS));
       setAttribute(list, ROLE, "tablist");
       setAttribute(list, ARIA_LABEL, i18n.select);
 

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/js/splide.min.js


BIN
dist/js/splide.min.js.gz


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
dist/js/splide.min.js.map


+ 1 - 14
src/js/components/Elements/Elements.ts

@@ -63,7 +63,6 @@ export interface ElementCollection {
  * @since 3.0.0
  */
 export interface ElementsComponent extends BaseComponent, ElementCollection {
-  isTab(): boolean;
 }
 
 /**
@@ -78,7 +77,7 @@ export interface ElementsComponent extends BaseComponent, ElementCollection {
  * @return An Elements component object.
  */
 export function Elements( Splide: Splide, Components: Components, options: Options ): ElementsComponent {
-  const { on } = EventInterface( Splide );
+  const { on, bind } = EventInterface( Splide );
   const { root } = Splide;
   const { i18n } = options;
   const elements: ElementCollection = {} as ElementCollection;
@@ -212,21 +211,9 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
     ];
   }
 
-  /**
-   * Indicates whether the slide should be implemented as "Tabbed Carousel" or not.
-   *
-   * @todo remove this
-   *
-   * @return `true` if the slider should be tabbed, or otherwise `false`.
-   */
-  function isTab(): boolean {
-    return !! options.pagination;
-  }
-
   return assign( elements, {
     setup,
     mount,
     destroy,
-    isTab,
   } );
 }

+ 1 - 3
src/js/components/Pagination/Pagination.ts

@@ -1,5 +1,5 @@
 import { ARIA_CONTROLS, ARIA_LABEL, ARIA_SELECTED, ROLE, TAB_INDEX } from '../../constants/attributes';
-import { CLASS_ACTIVE, CLASS_FOCUS } from '../../constants/classes';
+import { CLASS_ACTIVE } from '../../constants/classes';
 import {
   EVENT_MOVE,
   EVENT_PAGINATION_MOUNTED,
@@ -133,8 +133,6 @@ export function Pagination( Splide: Splide, Components: Components, options: Opt
 
     list = create( 'ul', classes.pagination, parent );
 
-    bind( list, 'focusin', apply( addClass, list, CLASS_FOCUS ) );
-    bind( list, 'focusout', apply( removeClass, list, CLASS_FOCUS ) );
     setAttribute( list, ROLE, 'tablist' );
     setAttribute( list, ARIA_LABEL, i18n.select );
 

+ 25 - 15
src/js/components/Slides/Slide.ts

@@ -1,10 +1,9 @@
 import {
   ALL_ATTRIBUTES,
-  ARIA_CONTROLS,
+  ARIA_CONTROLS, ARIA_CURRENT,
   ARIA_HIDDEN,
   ARIA_LABEL,
   ARIA_ROLEDESCRIPTION,
-  ARIA_SELECTED,
   ROLE,
   TAB_INDEX,
 } from '../../constants/attributes';
@@ -40,10 +39,12 @@ import {
   ceil,
   child,
   floor,
+  focus,
   format,
   getAttribute,
   hasClass,
   min,
+  nextTick,
   pad,
   queryAll,
   rect,
@@ -87,12 +88,11 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
   const { on, emit, bind, destroy: destroyEvents } = EventInterface( Splide );
   const { Components, root, options } = Splide;
   const { isNavigation, updateOnMove, i18n } = options;
-  const { isTab } = Components.Elements;
   const { resolve } = Components.Direction;
   const styles         = getAttribute( slide, 'style' );
   const isClone        = slideIndex > -1;
   const container      = child( slide, `.${ CLASS_CONTAINER }` );
-  const focusableNodes = options.focusableNodes && queryAll( slide, options.focusableNodes );
+  const focusableNodes = queryAll( slide, options.focusableNodes || '' );
 
   /**
    * Turns into `true` when the component is destroyed.
@@ -105,8 +105,7 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
   function mount( this: SlideComponent ): void {
     if ( ! isClone ) {
       slide.id = `${ root.id }-slide${ pad( index + 1 ) }`;
-
-      setAttribute( slide, ROLE, isTab() ? 'tabpanel' : 'group' );
+      setAttribute( slide, ROLE, options.pagination ? 'tabpanel' : 'group' );
       setAttribute( slide, ARIA_ROLEDESCRIPTION, i18n.slide );
       setAttribute( slide, ARIA_LABEL, format( i18n.slideLabel, [ index + 1, Splide.length ] ) );
     }
@@ -152,7 +151,6 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
 
     setAttribute( slide, ARIA_LABEL, format( i18n.slideX, ( isClone ? slideIndex : index ) + 1 ) );
     setAttribute( slide, ARIA_CONTROLS, controls );
-
     updateActivity( isActive() );
   }
 
@@ -170,13 +168,13 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
    */
   function update(): void {
     if ( ! destroyed ) {
-      const { index: currIndex } = Splide;
+      const { index: curr } = Splide;
 
       updateActivity( isActive() );
       updateVisibility( isVisible() );
 
-      toggleClass( slide, CLASS_PREV, index === currIndex - 1 );
-      toggleClass( slide, CLASS_NEXT, index === currIndex + 1 );
+      toggleClass( slide, CLASS_PREV, index === curr - 1 );
+      toggleClass( slide, CLASS_NEXT, index === curr + 1 );
     }
   }
 
@@ -188,11 +186,7 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
   function updateActivity( active: boolean ): void {
     if ( active !== hasClass( slide, CLASS_ACTIVE ) ) {
       toggleClass( slide, CLASS_ACTIVE, active );
-
-      if ( isNavigation ) {
-        setAttribute( slide, ARIA_SELECTED, active || '' );
-      }
-
+      setAttribute( slide, ARIA_CURRENT, isNavigation && active || '' );
       emit( active ? EVENT_ACTIVE : EVENT_INACTIVE, self );
     }
   }
@@ -205,6 +199,10 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
   function updateVisibility( visible: boolean ): void {
     const hidden = ! visible && ( ! isActive() || isClone );
 
+    if ( document.activeElement === slide && hidden ) {
+      nextTick( forwardFocus );
+    }
+
     setAttribute( slide, ARIA_HIDDEN, hidden || '' );
     setAttribute( slide, TAB_INDEX, ! hidden && options.slideFocus ? 0 : '' );
     setAttribute( focusableNodes || [], TAB_INDEX, hidden ? -1 : '' );
@@ -215,6 +213,18 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
     }
   }
 
+  /**
+   * Forwards the focus to the active element.
+   * Avoid losing focus from the slider when the focused slide gets hidden by slider move.
+   */
+  function forwardFocus(): void {
+    const Slide = Components.Slides.getAt( Splide.index );
+
+    if ( Slide ) {
+      focus( Slide.slide );
+    }
+  }
+
   /**
    * Adds a CSS rule to the slider or the container.
    *

+ 1 - 2
src/js/constants/classes.ts

@@ -26,14 +26,13 @@ export const CLASS_PREV            = 'is-prev';
 export const CLASS_NEXT            = 'is-next';
 export const CLASS_VISIBLE         = 'is-visible';
 export const CLASS_LOADING         = 'is-loading';
-export const CLASS_FOCUS           = 'has-focus';
 
 /**
  * The array with all status classes.
  *
  * @since 3.0.0
  */
-export const STATUS_CLASSES = [ CLASS_ACTIVE, CLASS_VISIBLE, CLASS_PREV, CLASS_NEXT, CLASS_LOADING, CLASS_FOCUS ];
+export const STATUS_CLASSES = [ CLASS_ACTIVE, CLASS_VISIBLE, CLASS_PREV, CLASS_NEXT, CLASS_LOADING ];
 
 /**
  * The collection of classes for elements that Splide dynamically creates.

+ 1 - 1
src/js/utils/dom/queryAll/queryAll.ts

@@ -10,5 +10,5 @@ import { slice } from '../../arrayLike';
  * @return An array with matched elements.
  */
 export function queryAll<E extends Element = Element>( parent: Element | Document, selector: string ): E[] {
-  return slice<E>( parent.querySelectorAll( selector ) );
+  return selector ? slice<E>( parent.querySelectorAll( selector ) ) : [];
 }

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor