biofriction-wp-theme/node_modules/foundation-sites/js/foundation.toggler.js

164 lines
4.4 KiB
JavaScript
Raw Normal View History

2021-10-26 14:18:09 +02:00
'use strict';
import $ from 'jquery';
import { Motion } from './foundation.util.motion';
import { Plugin } from './foundation.core.plugin';
import { RegExpEscape } from './foundation.core.utils';
import { Triggers } from './foundation.util.triggers';
/**
* Toggler module.
* @module foundation.toggler
* @requires foundation.util.motion
* @requires foundation.util.triggers
*/
class Toggler extends Plugin {
/**
* Creates a new instance of Toggler.
* @class
* @name Toggler
* @fires Toggler#init
* @param {Object} element - jQuery object to add the trigger to.
* @param {Object} options - Overrides to the default plugin settings.
*/
_setup(element, options) {
this.$element = element;
this.options = $.extend({}, Toggler.defaults, element.data(), options);
this.className = '';
this.className = 'Toggler'; // ie9 back compat
// Triggers init is idempotent, just need to make sure it is initialized
Triggers.init($);
this._init();
this._events();
}
/**
* Initializes the Toggler plugin by parsing the toggle class from data-toggler, or animation classes from data-animate.
* @function
* @private
*/
_init() {
var input;
// Parse animation classes if they were set
if (this.options.animate) {
input = this.options.animate.split(' ');
this.animationIn = input[0];
this.animationOut = input[1] || null;
}
// Otherwise, parse toggle class
else {
input = this.$element.data('toggler');
// Allow for a . at the beginning of the string
this.className = input[0] === '.' ? input.slice(1) : input;
}
// Add ARIA attributes to triggers:
var id = this.$element[0].id,
$triggers = $(`[data-open~="${id}"], [data-close~="${id}"], [data-toggle~="${id}"]`);
// - aria-expanded: according to the element visibility.
$triggers.attr('aria-expanded', !this.$element.is(':hidden'));
// - aria-controls: adding the element id to it if not already in it.
$triggers.each((index, trigger) => {
const $trigger = $(trigger);
const controls = $trigger.attr('aria-controls') || '';
const containsId = new RegExp(`\\b${RegExpEscape(id)}\\b`).test(controls);
if (!containsId) $trigger.attr('aria-controls', controls ? `${controls} ${id}` : id);
});
}
/**
* Initializes events for the toggle trigger.
* @function
* @private
*/
_events() {
this.$element.off('toggle.zf.trigger').on('toggle.zf.trigger', this.toggle.bind(this));
}
/**
* Toggles the target class on the target element. An event is fired from the original trigger depending on if the resultant state was "on" or "off".
* @function
* @fires Toggler#on
* @fires Toggler#off
*/
toggle() {
this[ this.options.animate ? '_toggleAnimate' : '_toggleClass']();
}
_toggleClass() {
this.$element.toggleClass(this.className);
var isOn = this.$element.hasClass(this.className);
if (isOn) {
/**
* Fires if the target element has the class after a toggle.
* @event Toggler#on
*/
this.$element.trigger('on.zf.toggler');
}
else {
/**
* Fires if the target element does not have the class after a toggle.
* @event Toggler#off
*/
this.$element.trigger('off.zf.toggler');
}
this._updateARIA(isOn);
this.$element.find('[data-mutate]').trigger('mutateme.zf.trigger');
}
_toggleAnimate() {
var _this = this;
if (this.$element.is(':hidden')) {
Motion.animateIn(this.$element, this.animationIn, function() {
_this._updateARIA(true);
this.trigger('on.zf.toggler');
this.find('[data-mutate]').trigger('mutateme.zf.trigger');
});
}
else {
Motion.animateOut(this.$element, this.animationOut, function() {
_this._updateARIA(false);
this.trigger('off.zf.toggler');
this.find('[data-mutate]').trigger('mutateme.zf.trigger');
});
}
}
_updateARIA(isOn) {
var id = this.$element[0].id;
$(`[data-open="${id}"], [data-close="${id}"], [data-toggle="${id}"]`)
.attr({
'aria-expanded': isOn ? true : false
});
}
/**
* Destroys the instance of Toggler on the element.
* @function
*/
_destroy() {
this.$element.off('.zf.toggler');
}
}
Toggler.defaults = {
/**
* Tells the plugin if the element should animated when toggled.
* @option
* @type {boolean}
* @default false
*/
animate: false
};
export {Toggler};