Selaa lähdekoodia

Patch `:focus-visible`.

NaotoshiFujita 3 vuotta sitten
vanhempi
commit
226a034192

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/css/splide.min.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/css/themes/splide-default.min.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/css/themes/splide-sea-green.min.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/css/themes/splide-skyblue.min.css


+ 19 - 7
dist/js/splide.js

@@ -712,7 +712,8 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   var CLASS_NEXT = "is-next";
   var CLASS_VISIBLE = "is-visible";
   var CLASS_LOADING = "is-loading";
-  var STATUS_CLASSES = [CLASS_ACTIVE, CLASS_VISIBLE, CLASS_PREV, CLASS_NEXT, CLASS_LOADING];
+  var CLASS_FOCUS_VISIBLE = "has-focus-visible";
+  var STATUS_CLASSES = [CLASS_ACTIVE, CLASS_VISIBLE, CLASS_PREV, CLASS_NEXT, CLASS_LOADING, CLASS_FOCUS_VISIBLE];
   var CLASSES = {
     slide: CLASS_SLIDE,
     clone: CLASS_CLONE,
@@ -743,9 +744,16 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     return elm;
   }
 
+  var FRICTION = 5;
+  var LOG_INTERVAL = 200;
+  var POINTER_DOWN_EVENTS = "touchstart mousedown";
+  var POINTER_MOVE_EVENTS = "touchmove mousemove";
+  var POINTER_UP_EVENTS = "touchend touchcancel mouseup";
+
   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;
@@ -756,6 +764,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var rootRole;
     var track;
     var list;
+    var isUsingKey;
 
     function setup() {
       collect();
@@ -767,6 +776,14 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       on(EVENT_REFRESH, destroy);
       on(EVENT_REFRESH, setup);
       on(EVENT_UPDATED, update);
+      bind(document, POINTER_DOWN_EVENTS + " keydown", function (e) {
+        isUsingKey = e.type === "keydown";
+      }, {
+        capture: true
+      });
+      bind(root, "focusin", function () {
+        toggleClass(root, CLASS_FOCUS_VISIBLE, !!isUsingKey);
+      });
     }
 
     function destroy() {
@@ -2067,11 +2084,6 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     passive: false,
     capture: true
   };
-  var FRICTION = 5;
-  var LOG_INTERVAL = 200;
-  var POINTER_DOWN_EVENTS = "touchstart mousedown";
-  var POINTER_MOVE_EVENTS = "touchmove mousemove";
-  var POINTER_UP_EVENTS = "touchend touchcancel mouseup";
 
   function Drag(Splide2, Components2, options) {
     var _EventInterface10 = EventInterface(Splide2),

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/js/splide.min.js


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


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/js/splide.min.js.map


+ 16 - 3
src/css/template/default/foundation/mixins.scss

@@ -4,12 +4,25 @@ $outline: colors.$focus 3px solid !default;
 $outline-offset: 3px !default;
 $outline-offset-inset: -3px !default;
 
+@mixin ie-only {
+  @media screen and ( -ms-high-contrast: none ) {
+    @content;
+  }
+}
+
 @mixin focus-outline {
   outline: $outline;
   outline-offset: $outline-offset;
 }
 
 @mixin focus-outline-inset {
-  @include focus-outline;
-  outline-offset: $outline-offset-inset;
-}
+  @supports ( outline-offset: $outline-offset-inset ) {
+    @include focus-outline;
+    outline-offset: $outline-offset-inset;
+  }
+
+  /* IE does not support outline-offset */
+  @include ie-only {
+    border: $outline;
+  }
+}

+ 0 - 4
src/css/template/default/object/modifiers/nav.scss

@@ -31,10 +31,6 @@ $opacity-active: false !default;
             opacity: $opacity-active;
           }
         }
-
-        &:focus-visible {
-          @include mixins.focus-outline-inset;
-        }
       }
     }
   }

+ 24 - 0
src/css/template/default/object/objects/slide.scss

@@ -5,13 +5,37 @@ $border-radius: false !default;
 $outline-offset: -2px !default;
 
 .splide {
+  $root: &;
+
   &__slide {
+    -webkit-tap-highlight-color: transparent;
+
     @if $border-radius {
       border-radius: $border-radius;
     }
 
+    &:focus {
+      outline: 0;
+    }
+
     &:focus-visible {
       @include mixins.focus-outline-inset;
     }
   }
+
+  &.has-focus-visible {
+    #{ $root }__slide:focus {
+      @include mixins.focus-outline-inset;
+    }
+
+    #{ $root }__track {
+      > #{ $root }__list {
+        > #{ $root }__slide:focus {
+          @include mixins.ie-only {
+            border-color: colors.$focus;
+          }
+        }
+      }
+    }
+  }
 }

+ 17 - 3
src/js/components/Elements/Elements.ts

@@ -4,7 +4,7 @@ import {
   CLASS_ARROW_NEXT,
   CLASS_ARROW_PREV,
   CLASS_ARROWS,
-  CLASS_CLONE,
+  CLASS_CLONE, CLASS_FOCUS_VISIBLE,
   CLASS_LIST,
   CLASS_PAGINATION,
   CLASS_PROGRESS_BAR,
@@ -31,10 +31,11 @@ import {
   query,
   removeAttribute,
   removeClass,
-  setAttribute,
+  setAttribute, toggleClass,
   uniqueId,
 } from '../../utils';
 import { closest } from '../../utils/dom/closest/closest';
+import { POINTER_DOWN_EVENTS } from '../Drag/constants';
 
 
 /**
@@ -75,7 +76,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;
@@ -110,6 +111,11 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
    */
   let list: HTMLElement;
 
+  /**
+   * Turns into `true` when detecting keydown, and `false` when detecting pointerdown.
+   */
+  let isUsingKey: boolean;
+
   /**
    * Called when the component is constructed.
    */
@@ -126,6 +132,14 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
     on( EVENT_REFRESH, destroy );
     on( EVENT_REFRESH, setup );
     on( EVENT_UPDATED, update );
+
+    bind( document, `${ POINTER_DOWN_EVENTS } keydown`, e => {
+      isUsingKey = e.type === 'keydown';
+    }, { capture: true } );
+
+    bind( root, 'focusin', () => {
+      toggleClass( root, CLASS_FOCUS_VISIBLE, !! isUsingKey );
+    } );
   }
 
   /**

+ 37 - 0
src/js/components/Elements/test/focus.test.ts

@@ -0,0 +1,37 @@
+import { CLASS_FOCUS_VISIBLE } from '../../../constants/classes';
+import { fire, init } from '../../../test';
+
+
+describe( 'Focus', () => {
+  test( 'can add the status class to the root when focus comes into it by a key.', () => {
+    const splide = init( {}, { arrows: true } );
+
+    fire( document, 'keydown' );
+    fire( splide.root, 'focusin' );
+
+    expect( splide.root.classList.contains( CLASS_FOCUS_VISIBLE ) ).toBe( true );
+  } );
+
+  test( 'can remove the status class from the root when detecting pointerdown.', () => {
+    const splide = init( {}, { arrows: true } );
+
+    fire( document, 'keydown' );
+    fire( splide.root, 'focusin' );
+
+    expect( splide.root.classList.contains( CLASS_FOCUS_VISIBLE ) ).toBe( true );
+
+    fire( splide.root, 'mousedown' );
+    fire( splide.root, 'focusin' );
+
+    expect( splide.root.classList.contains( CLASS_FOCUS_VISIBLE ) ).toBe( false );
+  } );
+
+  test( 'should not add the status class when focus comes into the root by pointing devices.', () => {
+    const splide = init( {}, { arrows: true } );
+
+    fire( document, 'mousedown' );
+    fire( splide.root, 'focusin' );
+
+    expect( splide.root.classList.contains( CLASS_FOCUS_VISIBLE ) ).toBe( false );
+  } );
+} );

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

@@ -26,6 +26,7 @@ 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_VISIBLE   = 'has-focus-visible';
 
 
 /**
@@ -33,7 +34,14 @@ export const CLASS_LOADING         = 'is-loading';
  *
  * @since 3.0.0
  */
-export const STATUS_CLASSES = [ CLASS_ACTIVE, CLASS_VISIBLE, CLASS_PREV, CLASS_NEXT, CLASS_LOADING ];
+export const STATUS_CLASSES = [
+  CLASS_ACTIVE,
+  CLASS_VISIBLE,
+  CLASS_PREV,
+  CLASS_NEXT,
+  CLASS_LOADING,
+  CLASS_FOCUS_VISIBLE,
+];
 
 /**
  * The collection of classes for elements that Splide dynamically creates.

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä