Pārlūkot izejas kodu

Make `label` and `labelledby` options responsive for destruction.

Naotoshi Fujita 3 gadi atpakaļ
vecāks
revīzija
453ae886e2

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/js/splide-renderer.min.js


+ 20 - 19
dist/js/splide.cjs.js

@@ -163,7 +163,7 @@ function assign(object) {
 }
 
 function merge(object) {
-  slice(arguments).forEach(function (source) {
+  slice(arguments, 1).forEach(function (source) {
     forOwn(source, function (value, key) {
       if (isArray(value)) {
         object[key] = value.slice();
@@ -603,20 +603,20 @@ function Media(Splide2, Components2, options) {
   }
 
   function update() {
+    var destroyed = Splide2.state.is(DESTROYED);
     var direction = options.direction;
     var merged = queries.reduce(function (merged2, entry) {
       return merge(merged2, entry[1].matches ? entry[0] : {});
     }, {});
     omit(options);
-    merge(options, merged);
+    Splide2.options = merged;
 
     if (options.destroy) {
       Splide2.destroy(options.destroy === "completely");
-    } else if (Splide2.state.is(DESTROYED)) {
+    } else if (destroyed) {
       destroy(true);
       Splide2.mount();
     } else {
-      Splide2.options = merged;
       direction !== options.direction && Splide2.refresh();
     }
   }
@@ -680,12 +680,13 @@ var ARIA_CONTROLS = ARIA_PREFIX + "controls";
 var ARIA_CURRENT = ARIA_PREFIX + "current";
 var ARIA_SELECTED = ARIA_PREFIX + "selected";
 var ARIA_LABEL = ARIA_PREFIX + "label";
+var ARIA_LABELLEDBY = ARIA_PREFIX + "labelledby";
 var ARIA_HIDDEN = ARIA_PREFIX + "hidden";
 var ARIA_ORIENTATION = ARIA_PREFIX + "orientation";
 var ARIA_ROLEDESCRIPTION = ARIA_PREFIX + "roledescription";
 var ARIA_LIVE = ARIA_PREFIX + "live";
 var ARIA_RELEVANT = ARIA_PREFIX + "relevant";
-var ALL_ATTRIBUTES = [ROLE, TAB_INDEX, DISABLED, ARIA_CONTROLS, ARIA_CURRENT, ARIA_LABEL, ARIA_HIDDEN, ARIA_ORIENTATION, ARIA_ROLEDESCRIPTION];
+var ALL_ATTRIBUTES = [ROLE, TAB_INDEX, DISABLED, ARIA_CONTROLS, ARIA_CURRENT, ARIA_LABEL, ARIA_LABELLEDBY, ARIA_HIDDEN, ARIA_ORIENTATION, ARIA_ROLEDESCRIPTION];
 var CLASS_ROOT = PROJECT_CODE;
 var CLASS_TRACK = PROJECT_CODE + "__track";
 var CLASS_LIST = PROJECT_CODE + "__list";
@@ -758,8 +759,6 @@ function Elements(Splide2, Components2, options) {
   var i18n = options.i18n;
   var elements = {};
   var slides = [];
-  var rootRole = getAttribute(root, ROLE);
-  var rootLabel = getAttribute(root, ARIA_LABEL);
   var rootClasses = [];
   var trackClasses = [];
   var track;
@@ -787,18 +786,12 @@ function Elements(Splide2, Components2, options) {
   }
 
   function destroy(completely) {
+    var attrs = ALL_ATTRIBUTES.concat("style");
     empty(slides);
     removeClass(root, rootClasses);
     removeClass(track, trackClasses);
-    removeAttribute([track, list], ALL_ATTRIBUTES.concat("style"));
-    removeAttribute(root, "style");
-
-    if (completely) {
-      removeAttribute(root, ALL_ATTRIBUTES);
-      setAttribute(root, ROLE, rootRole);
-    }
-
-    setAttribute(root, ARIA_LABEL, rootLabel);
+    removeAttribute([track, list], attrs);
+    removeAttribute(root, completely ? attrs : ["style", ARIA_ROLEDESCRIPTION]);
   }
 
   function update() {
@@ -808,6 +801,8 @@ function Elements(Splide2, Components2, options) {
     trackClasses = getClasses(CLASS_TRACK);
     addClass(root, rootClasses);
     addClass(track, trackClasses);
+    setAttribute(root, ARIA_LABEL, options.label);
+    setAttribute(root, ARIA_LABELLEDBY, options.labelledby);
   }
 
   function collect() {
@@ -835,12 +830,15 @@ function Elements(Splide2, Components2, options) {
 
   function init() {
     var id = root.id || uniqueId(PROJECT_CODE);
-    var role = rootRole || root.tagName !== "SECTION" && options.role || "";
     root.id = id;
     track.id = track.id || id + "-track";
     list.id = list.id || id + "-list";
+
+    if (!getAttribute(root, ROLE)) {
+      setAttribute(root, ROLE, root.tagName !== "SECTION" && options.role || "");
+    }
+
     setAttribute(root, ARIA_ROLEDESCRIPTION, i18n.carousel);
-    getAttribute(root, ROLE) || setAttribute(root, ROLE, role);
     setAttribute(list, ROLE, "presentation");
   }
 
@@ -2943,7 +2941,10 @@ var _Splide = /*#__PURE__*/function () {
     var root = isString(target) ? query(document, target) : target;
     assert(root, root + " is invalid.");
     this.root = root;
-    options = merge({}, DEFAULTS, _Splide.defaults, options || {});
+    options = merge({
+      label: getAttribute(root, ARIA_LABEL) || "",
+      labelledby: getAttribute(root, ARIA_LABELLEDBY) || ""
+    }, DEFAULTS, _Splide.defaults, options || {});
 
     try {
       merge(options, JSON.parse(getAttribute(root, DATA_ATTRIBUTE)));

+ 20 - 19
dist/js/splide.esm.js

@@ -158,7 +158,7 @@ function assign(object) {
 }
 
 function merge(object) {
-  slice(arguments).forEach(function (source) {
+  slice(arguments, 1).forEach(function (source) {
     forOwn(source, function (value, key) {
       if (isArray(value)) {
         object[key] = value.slice();
@@ -598,20 +598,20 @@ function Media(Splide2, Components2, options) {
   }
 
   function update() {
+    var destroyed = Splide2.state.is(DESTROYED);
     var direction = options.direction;
     var merged = queries.reduce(function (merged2, entry) {
       return merge(merged2, entry[1].matches ? entry[0] : {});
     }, {});
     omit(options);
-    merge(options, merged);
+    Splide2.options = merged;
 
     if (options.destroy) {
       Splide2.destroy(options.destroy === "completely");
-    } else if (Splide2.state.is(DESTROYED)) {
+    } else if (destroyed) {
       destroy(true);
       Splide2.mount();
     } else {
-      Splide2.options = merged;
       direction !== options.direction && Splide2.refresh();
     }
   }
@@ -675,12 +675,13 @@ var ARIA_CONTROLS = ARIA_PREFIX + "controls";
 var ARIA_CURRENT = ARIA_PREFIX + "current";
 var ARIA_SELECTED = ARIA_PREFIX + "selected";
 var ARIA_LABEL = ARIA_PREFIX + "label";
+var ARIA_LABELLEDBY = ARIA_PREFIX + "labelledby";
 var ARIA_HIDDEN = ARIA_PREFIX + "hidden";
 var ARIA_ORIENTATION = ARIA_PREFIX + "orientation";
 var ARIA_ROLEDESCRIPTION = ARIA_PREFIX + "roledescription";
 var ARIA_LIVE = ARIA_PREFIX + "live";
 var ARIA_RELEVANT = ARIA_PREFIX + "relevant";
-var ALL_ATTRIBUTES = [ROLE, TAB_INDEX, DISABLED, ARIA_CONTROLS, ARIA_CURRENT, ARIA_LABEL, ARIA_HIDDEN, ARIA_ORIENTATION, ARIA_ROLEDESCRIPTION];
+var ALL_ATTRIBUTES = [ROLE, TAB_INDEX, DISABLED, ARIA_CONTROLS, ARIA_CURRENT, ARIA_LABEL, ARIA_LABELLEDBY, ARIA_HIDDEN, ARIA_ORIENTATION, ARIA_ROLEDESCRIPTION];
 var CLASS_ROOT = PROJECT_CODE;
 var CLASS_TRACK = PROJECT_CODE + "__track";
 var CLASS_LIST = PROJECT_CODE + "__list";
@@ -753,8 +754,6 @@ function Elements(Splide2, Components2, options) {
   var i18n = options.i18n;
   var elements = {};
   var slides = [];
-  var rootRole = getAttribute(root, ROLE);
-  var rootLabel = getAttribute(root, ARIA_LABEL);
   var rootClasses = [];
   var trackClasses = [];
   var track;
@@ -782,18 +781,12 @@ function Elements(Splide2, Components2, options) {
   }
 
   function destroy(completely) {
+    var attrs = ALL_ATTRIBUTES.concat("style");
     empty(slides);
     removeClass(root, rootClasses);
     removeClass(track, trackClasses);
-    removeAttribute([track, list], ALL_ATTRIBUTES.concat("style"));
-    removeAttribute(root, "style");
-
-    if (completely) {
-      removeAttribute(root, ALL_ATTRIBUTES);
-      setAttribute(root, ROLE, rootRole);
-    }
-
-    setAttribute(root, ARIA_LABEL, rootLabel);
+    removeAttribute([track, list], attrs);
+    removeAttribute(root, completely ? attrs : ["style", ARIA_ROLEDESCRIPTION]);
   }
 
   function update() {
@@ -803,6 +796,8 @@ function Elements(Splide2, Components2, options) {
     trackClasses = getClasses(CLASS_TRACK);
     addClass(root, rootClasses);
     addClass(track, trackClasses);
+    setAttribute(root, ARIA_LABEL, options.label);
+    setAttribute(root, ARIA_LABELLEDBY, options.labelledby);
   }
 
   function collect() {
@@ -830,12 +825,15 @@ function Elements(Splide2, Components2, options) {
 
   function init() {
     var id = root.id || uniqueId(PROJECT_CODE);
-    var role = rootRole || root.tagName !== "SECTION" && options.role || "";
     root.id = id;
     track.id = track.id || id + "-track";
     list.id = list.id || id + "-list";
+
+    if (!getAttribute(root, ROLE)) {
+      setAttribute(root, ROLE, root.tagName !== "SECTION" && options.role || "");
+    }
+
     setAttribute(root, ARIA_ROLEDESCRIPTION, i18n.carousel);
-    getAttribute(root, ROLE) || setAttribute(root, ROLE, role);
     setAttribute(list, ROLE, "presentation");
   }
 
@@ -2938,7 +2936,10 @@ var _Splide = /*#__PURE__*/function () {
     var root = isString(target) ? query(document, target) : target;
     assert(root, root + " is invalid.");
     this.root = root;
-    options = merge({}, DEFAULTS, _Splide.defaults, options || {});
+    options = merge({
+      label: getAttribute(root, ARIA_LABEL) || "",
+      labelledby: getAttribute(root, ARIA_LABELLEDBY) || ""
+    }, DEFAULTS, _Splide.defaults, options || {});
 
     try {
       merge(options, JSON.parse(getAttribute(root, DATA_ATTRIBUTE)));

+ 20 - 19
dist/js/splide.js

@@ -163,7 +163,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   }
 
   function merge(object) {
-    slice(arguments).forEach(function (source) {
+    slice(arguments, 1).forEach(function (source) {
       forOwn(source, function (value, key) {
         if (isArray(value)) {
           object[key] = value.slice();
@@ -599,20 +599,20 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function update() {
+      var destroyed = Splide2.state.is(DESTROYED);
       var direction = options.direction;
       var merged = queries.reduce(function (merged2, entry) {
         return merge(merged2, entry[1].matches ? entry[0] : {});
       }, {});
       omit(options);
-      merge(options, merged);
+      Splide2.options = merged;
 
       if (options.destroy) {
         Splide2.destroy(options.destroy === "completely");
-      } else if (Splide2.state.is(DESTROYED)) {
+      } else if (destroyed) {
         destroy(true);
         Splide2.mount();
       } else {
-        Splide2.options = merged;
         direction !== options.direction && Splide2.refresh();
       }
     }
@@ -676,12 +676,13 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   var ARIA_CURRENT = ARIA_PREFIX + "current";
   var ARIA_SELECTED = ARIA_PREFIX + "selected";
   var ARIA_LABEL = ARIA_PREFIX + "label";
+  var ARIA_LABELLEDBY = ARIA_PREFIX + "labelledby";
   var ARIA_HIDDEN = ARIA_PREFIX + "hidden";
   var ARIA_ORIENTATION = ARIA_PREFIX + "orientation";
   var ARIA_ROLEDESCRIPTION = ARIA_PREFIX + "roledescription";
   var ARIA_LIVE = ARIA_PREFIX + "live";
   var ARIA_RELEVANT = ARIA_PREFIX + "relevant";
-  var ALL_ATTRIBUTES = [ROLE, TAB_INDEX, DISABLED, ARIA_CONTROLS, ARIA_CURRENT, ARIA_LABEL, ARIA_HIDDEN, ARIA_ORIENTATION, ARIA_ROLEDESCRIPTION];
+  var ALL_ATTRIBUTES = [ROLE, TAB_INDEX, DISABLED, ARIA_CONTROLS, ARIA_CURRENT, ARIA_LABEL, ARIA_LABELLEDBY, ARIA_HIDDEN, ARIA_ORIENTATION, ARIA_ROLEDESCRIPTION];
   var CLASS_ROOT = PROJECT_CODE;
   var CLASS_TRACK = PROJECT_CODE + "__track";
   var CLASS_LIST = PROJECT_CODE + "__list";
@@ -752,8 +753,6 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var i18n = options.i18n;
     var elements = {};
     var slides = [];
-    var rootRole = getAttribute(root, ROLE);
-    var rootLabel = getAttribute(root, ARIA_LABEL);
     var rootClasses = [];
     var trackClasses = [];
     var track;
@@ -781,18 +780,12 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function destroy(completely) {
+      var attrs = ALL_ATTRIBUTES.concat("style");
       empty(slides);
       removeClass(root, rootClasses);
       removeClass(track, trackClasses);
-      removeAttribute([track, list], ALL_ATTRIBUTES.concat("style"));
-      removeAttribute(root, "style");
-
-      if (completely) {
-        removeAttribute(root, ALL_ATTRIBUTES);
-        setAttribute(root, ROLE, rootRole);
-      }
-
-      setAttribute(root, ARIA_LABEL, rootLabel);
+      removeAttribute([track, list], attrs);
+      removeAttribute(root, completely ? attrs : ["style", ARIA_ROLEDESCRIPTION]);
     }
 
     function update() {
@@ -802,6 +795,8 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       trackClasses = getClasses(CLASS_TRACK);
       addClass(root, rootClasses);
       addClass(track, trackClasses);
+      setAttribute(root, ARIA_LABEL, options.label);
+      setAttribute(root, ARIA_LABELLEDBY, options.labelledby);
     }
 
     function collect() {
@@ -829,12 +824,15 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
     function init() {
       var id = root.id || uniqueId(PROJECT_CODE);
-      var role = rootRole || root.tagName !== "SECTION" && options.role || "";
       root.id = id;
       track.id = track.id || id + "-track";
       list.id = list.id || id + "-list";
+
+      if (!getAttribute(root, ROLE)) {
+        setAttribute(root, ROLE, root.tagName !== "SECTION" && options.role || "");
+      }
+
       setAttribute(root, ARIA_ROLEDESCRIPTION, i18n.carousel);
-      getAttribute(root, ROLE) || setAttribute(root, ROLE, role);
       setAttribute(list, ROLE, "presentation");
     }
 
@@ -2937,7 +2935,10 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       var root = isString(target) ? query(document, target) : target;
       assert(root, root + " is invalid.");
       this.root = root;
-      options = merge({}, DEFAULTS, _Splide.defaults, options || {});
+      options = merge({
+        label: getAttribute(root, ARIA_LABEL) || "",
+        labelledby: getAttribute(root, ARIA_LABELLEDBY) || ""
+      }, DEFAULTS, _Splide.defaults, options || {});
 
       try {
         merge(options, JSON.parse(getAttribute(root, DATA_ATTRIBUTE)));

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/js/splide.min.js


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


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
dist/js/splide.min.js.map


+ 9 - 4
dist/types/index.d.ts

@@ -282,10 +282,6 @@ interface Options extends ResponsiveOptions {
      * If the tag is `<section>`, this value will not be used. The default value is `'region'`.
      */
     role?: string;
-    /**
-     * The label for the root element.
-     */
-    label?: string;
     /**
      * Determines whether to disable any actions while the slider is transitioning.
      * Even if `false`, the slider forcibly waits for transition on the loop points.
@@ -466,6 +462,15 @@ interface ResponsiveOptions {
      * Accepts arbitrary properties for extensions, although it's not ideal typing.
      */
     [key: string]: any;
+    /**
+     * The label for the root element.
+     * Use `labelledby` instead if there is a visible label.
+     */
+    label?: string;
+    /**
+     * The ID for the element that used as the label of the carousel.
+     */
+    labelledby?: string;
     /**
      * The transition speed in milliseconds.
      */

+ 13 - 23
src/js/components/Elements/Elements.ts

@@ -1,4 +1,4 @@
-import { ALL_ATTRIBUTES, ARIA_LABEL, ARIA_ROLEDESCRIPTION, ROLE } from '../../constants/attributes';
+import { ALL_ATTRIBUTES, ARIA_LABEL, ARIA_LABELLEDBY, ARIA_ROLEDESCRIPTION, ROLE } from '../../constants/attributes';
 import {
   CLASS_ACTIVE,
   CLASS_ARROW_NEXT,
@@ -88,16 +88,6 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
    */
   const slides: HTMLElement[] = [];
 
-  /**
-   * Keeps the root role in HTML.
-   */
-  const rootRole = getAttribute( root, ROLE );
-
-  /**
-   * Keeps the root label in HTML.
-   */
-  const rootLabel = getAttribute( root, ARIA_LABEL );
-
   /**
    * Stores all root classes.
    */
@@ -155,18 +145,13 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
    * @param completely - Whether to destroy the component completely or not.
    */
   function destroy( completely?: boolean ): void {
+    const attrs = ALL_ATTRIBUTES.concat( 'style' );
+
     empty( slides );
     removeClass( root, rootClasses );
     removeClass( track, trackClasses );
-    removeAttribute( [ track, list ], ALL_ATTRIBUTES.concat( 'style' ) );
-    removeAttribute( root, 'style' );
-
-    if ( completely ) {
-      removeAttribute( root, ALL_ATTRIBUTES );
-      setAttribute( root, ROLE, rootRole );
-    }
-
-    setAttribute( root, ARIA_LABEL, rootLabel );
+    removeAttribute( [ track, list ], attrs );
+    removeAttribute( root, completely ? attrs : [ 'style', ARIA_ROLEDESCRIPTION ] );
   }
 
   /**
@@ -181,6 +166,9 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
 
     addClass( root, rootClasses );
     addClass( track, trackClasses );
+
+    setAttribute( root, ARIA_LABEL, options.label );
+    setAttribute( root, ARIA_LABELLEDBY, options.labelledby );
   }
 
   /**
@@ -213,15 +201,17 @@ export function Elements( Splide: Splide, Components: Components, options: Optio
    * which removes the region from the accessibility tree.
    */
   function init(): void {
-    const id   = root.id || uniqueId( PROJECT_CODE );
-    const role = rootRole || root.tagName !== 'SECTION' && options.role || '';
+    const id = root.id || uniqueId( PROJECT_CODE );
 
     root.id  = id;
     track.id = track.id || `${ id }-track`;
     list.id  = list.id || `${ id }-list`;
 
+    if ( ! getAttribute( root, ROLE ) ) {
+      setAttribute( root, ROLE, root.tagName !== 'SECTION' && options.role || '' );
+    }
+
     setAttribute( root, ARIA_ROLEDESCRIPTION, i18n.carousel );
-    getAttribute( root, ROLE ) || setAttribute( root, ROLE, role );
     setAttribute( list, ROLE, 'presentation' );
   }
 

+ 21 - 6
src/js/components/Elements/test/attributes.test.ts

@@ -1,12 +1,27 @@
-import { ALL_ATTRIBUTES, ARIA_ROLEDESCRIPTION, ROLE } from '../../../constants/attributes';
+import { ALL_ATTRIBUTES } from '../../../constants/attributes';
 import { buildHtml, init } from '../../../test';
 
 
 describe( 'Elements', () => {
   test( 'can assign aria attributes.', () => {
     const splide = init();
-    expect( splide.root.getAttribute( ROLE ) ).toBe( 'region' );
-    expect( splide.root.getAttribute( ARIA_ROLEDESCRIPTION ) ).toBe( 'carousel' );
+    expect( splide.root.getAttribute( 'role' ) ).toBe( 'region' );
+    expect( splide.root.getAttribute( 'aria-roledescription' ) ).toBe( 'carousel' );
+  } );
+
+  test( 'can set a role.', () => {
+    const splide = init( { role: 'navigation' } );
+    expect( splide.root.getAttribute( 'role' ) ).toBe( 'navigation' );
+  } );
+
+  test( 'can set aria-label.', () => {
+    const splide = init( { label: 'Splide carousel' } );
+    expect( splide.root.getAttribute( 'aria-label' ) ).toBe( 'Splide carousel' );
+  } );
+
+  test( 'can set aria-labelledby.', () => {
+    const splide = init( { labelledby: 'heading' } );
+    expect( splide.root.getAttribute( 'aria-labelledby' ) ).toBe( 'heading' );
   } );
 
   test( 'can remove assigned attributes.', () => {
@@ -30,14 +45,14 @@ describe( 'Elements', () => {
 
   test( 'should not assign the role if the root element is section.', () => {
     const splide = init( {}, { html: buildHtml( { tag: 'section' } ) } );
-    expect( splide.root.getAttribute( ROLE ) ).toBeNull();
+    expect( splide.root.getAttribute( 'role' ) ).toBeNull();
   } );
 
   test( 'should not remove the role attribute by soft destruction.', () => {
     const splide = init();
-    expect( splide.root.getAttribute( ROLE ) ).toBe( 'region' );
+    expect( splide.root.getAttribute( 'role' ) ).toBe( 'region' );
 
     splide.destroy( false );
-    expect( splide.root.getAttribute( ROLE ) ).toBe( 'region' );
+    expect( splide.root.getAttribute( 'role' ) ).toBe( 'region' );
   } );
 } );

+ 3 - 3
src/js/components/Media/Media.ts

@@ -80,21 +80,21 @@ export function Media( Splide: Splide, Components: Components, options: Options
    * Checks all media queries in entries and updates options.
    */
   function update(): void {
+    const destroyed = Splide.state.is( DESTROYED );
     const direction = options.direction;
     const merged = queries.reduce<Options>( ( merged, entry ) => {
       return merge( merged, entry[ 1 ].matches ? entry[ 0 ] : {} );
     }, {} );
 
     omit( options );
-    merge( options, merged );
+    Splide.options = merged;
 
     if ( options.destroy ) {
       Splide.destroy( options.destroy === 'completely' );
-    } else if ( Splide.state.is( DESTROYED ) ) {
+    } else if ( destroyed ) {
       destroy( true );
       Splide.mount();
     } else {
-      Splide.options = merged;
       direction !== options.direction && Splide.refresh();
     }
   }

+ 2 - 0
src/js/constants/attributes.ts

@@ -7,6 +7,7 @@ export const ARIA_CONTROLS        = `${ ARIA_PREFIX }controls`;
 export const ARIA_CURRENT         = `${ ARIA_PREFIX }current`;
 export const ARIA_SELECTED        = `${ ARIA_PREFIX }selected`;
 export const ARIA_LABEL           = `${ ARIA_PREFIX }label`;
+export const ARIA_LABELLEDBY      = `${ ARIA_PREFIX }labelledby`;
 export const ARIA_HIDDEN          = `${ ARIA_PREFIX }hidden`;
 export const ARIA_ORIENTATION     = `${ ARIA_PREFIX }orientation`;
 export const ARIA_ROLEDESCRIPTION = `${ ARIA_PREFIX }roledescription`;
@@ -27,6 +28,7 @@ export const ALL_ATTRIBUTES = [
   ARIA_CONTROLS,
   ARIA_CURRENT,
   ARIA_LABEL,
+  ARIA_LABELLEDBY,
   ARIA_HIDDEN,
   ARIA_ORIENTATION,
   ARIA_ROLEDESCRIPTION,

+ 5 - 1
src/js/core/Splide/Splide.ts

@@ -10,6 +10,7 @@ import { EventInterface, EventInterfaceObject, State, StateObject } from '../../
 import { Fade, Slide } from '../../transitions';
 import { AnyFunction, ComponentConstructor, Components, EventMap, Options, SyncTarget } from '../../types';
 import { addClass, assert, assign, empty, forOwn, getAttribute, isString, merge, query, slice } from '../../utils';
+import { ARIA_LABEL, ARIA_LABELLEDBY } from "../../constants/attributes";
 
 
 /**
@@ -85,7 +86,10 @@ export class Splide {
 
     this.root = root;
 
-    options = merge( {}, DEFAULTS, Splide.defaults, options || {} );
+    options = merge( {
+      label     : getAttribute( root, ARIA_LABEL ) || '',
+      labelledby: getAttribute( root, ARIA_LABELLEDBY ) || '',
+    }, DEFAULTS, Splide.defaults, options || {} );
 
     try {
       merge( options, JSON.parse( getAttribute( root, DATA_ATTRIBUTE ) ) );

+ 3 - 3
src/js/test/assets/css/planet.css

@@ -56,7 +56,7 @@ cite {
 }
 
 .splide__heading {
-  font-family: Splide Heading, sans-serif;
+  font-family: SplideHeading, sans-serif;
   color: #fff;
   margin: 0;
   padding: 1rem 1.5rem .5rem;
@@ -111,10 +111,10 @@ cite {
 }
 
 .splide__arrow:focus-visible {
-  outline: #fff dotted 3px;
+  outline: #fff dotted 3px !important;
 }
 
 .splide__slide:focus-visible {
-  outline: #fff dotted 3px;
+  outline: #fff dotted 3px !important;
 }
 

+ 28 - 33
src/js/test/php/examples/breakpoints.php

@@ -24,40 +24,35 @@ $settings = get_settings();
 
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
-			const options = {
-				perPage    : 3,
-				arrows     : false,
-				mediaQuery : 'max',
-				// destroy: true,
-				breakpoints: {
-					1200: {
-						perPage: 1,
-						gap    : '1rem',
-						arrows : true,
-						padding: 50,
-						// direction: 'ttb',
-						height: 500,
-						destroy: false,
-						// paginationDirection: 'ltr',
-					},
-					1000: {
-						// direction: 'ltr',
-						perPage   : 2,
-						gap       : 0,
-						arrows    : false,
-						padding   : 0,
-						pagination: false,
-						// destroy: false,
-						// height: undefined,
-					},
-					800 : {
-						destroy: true,
-					},
-				},
-			}
+      const options = {
+        perPage: 3,
+        arrows: false,
+        mediaQuery: 'max',
+        // destroy: true,
+        breakpoints: {
+          1200: {
+            perPage: 1,
+            gap: '1rem',
+            arrows: true,
+            padding: 50,
+            height: 500,
+            destroy: false,
+          },
+          1000: {
+            perPage: 2,
+            gap: 0,
+            arrows: false,
+            padding: 0,
+            pagination: false,
+          },
+          800: {
+            destroy: true,
+          },
+        },
+      }
 
-	    new Splide( '#splide01', options ).mount();
-	    new Splide( '#splide02', options ).mount();
+      new Splide( '#splide01', options ).mount();
+      new Splide( '#splide02', options ).mount();
     } );
   </script>
 </head>

+ 29 - 25
src/js/test/php/examples/default.php

@@ -21,33 +21,37 @@ $settings = get_settings();
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide = new Splide( '#splide01', {
-	      width       : 800,
-	      // type        : 'loop',
-	      perPage     : 3,
-	      rewind      : true,
-	      rewindByDrag: true,
-	      padding     : 40,
-	      updateOnMove: true,
-	      direction   : 'ltr',
-	      height      : undefined,
-	      paginationDirection: 'ttb',
-	      rewindSpeed : 2000,
-
-	      breakpoints: {
-					1200: {
-						direction: 'ttb',
-						height   : 500,
-						perPage  : 2,
-					},
-		      1000: {
-			      direction: 'ltr',
-		      }
-	      }
+        width: 800,
+        // type        : 'loop',
+        perPage: 3,
+        // rewind: true,
+        // rewindByDrag: true,
+        padding: { left: '3rem', right: '2rem' },
+        updateOnMove: true,
+        direction: 'ltr',
+        height: undefined,
+        paginationDirection: 'ttb',
+        rewindSpeed: 2000,
+
+        breakpoints: {
+          1200: {
+            // padding: 5,
+          },
+          1000: {
+            label: 'The destroyed carousel',
+            destroy: true,
+          },
+        },
+
+        classes: {
+          arrows: 'splide__arrows custom-arrows',
+          pagination: 'splide__pagination custom-pagination',
+        },
       } );
 
-	    // splide.on( 'move', function () {
-		  //   console.log( 'move' );
-	    // } );
+      // splide.on( 'destroy', function () {
+      //     console.log( 'destroy' );
+      // } );
 	    //
       // splide.on( 'moved', function ( index, prev, dest ) {
       //   console.log( 'moved', index, prev, dest );

+ 1 - 1
src/js/test/php/examples/live-regions.php

@@ -35,7 +35,7 @@ $settings = get_settings();
 <body>
 
 <div class="wrapper">
-	<div id="splide01" class="splide" aria-label="Planets gallery">
+	<div id="splide01" class="splide" aria-label="Planets gallery carousel">
 		<div class="splide__track">
 			<ul class="splide__list">
 				<li class="splide__slide">

+ 11 - 5
src/js/types/options.ts

@@ -21,11 +21,6 @@ export interface Options extends ResponsiveOptions {
    */
   role?: string;
 
-  /**
-   * The label for the root element.
-   */
-  label?: string;
-
   /**
    * Determines whether to disable any actions while the slider is transitioning.
    * Even if `false`, the slider forcibly waits for transition on the loop points.
@@ -239,6 +234,17 @@ export interface ResponsiveOptions {
    */
   [ key: string ]: any;
 
+  /**
+   * The label for the root element.
+   * Use `labelledby` instead if there is a visible label.
+   */
+  label?: string;
+
+  /**
+   * The ID for the element that used as the label of the carousel.
+   */
+  labelledby?: string;
+
   /**
    * The transition speed in milliseconds.
    */

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels