vendor/assets/js/foundation.tabs.js.es6 in foundation-rails-6.2.4.0 vs vendor/assets/js/foundation.tabs.js.es6 in foundation-rails-6.3.0.0
- old
+ new
@@ -40,17 +40,18 @@
* @private
*/
_init() {
var _this = this;
+ this.$element.attr({'role': 'tablist'});
this.$tabTitles = this.$element.find(`.${this.options.linkClass}`);
this.$tabContent = $(`[data-tabs-content="${this.$element[0].id}"]`);
this.$tabTitles.each(function(){
var $elem = $(this),
$link = $elem.find('a'),
- isActive = $elem.hasClass('is-active'),
+ isActive = $elem.hasClass(`${_this.options.linkActiveClass}`),
hash = $link[0].hash.slice(1),
linkId = $link[0].id ? $link[0].id : `${hash}-label`,
$tabContent = $(`#${hash}`);
$elem.attr({'role': 'presentation'});
@@ -67,12 +68,42 @@
'aria-hidden': !isActive,
'aria-labelledby': linkId
});
if(isActive && _this.options.autoFocus){
- $link.focus();
+ $(window).load(function() {
+ $('html, body').animate({ scrollTop: $elem.offset().top }, _this.options.deepLinkSmudgeDelay, () => {
+ $link.focus();
+ });
+ });
}
+
+ //use browser to open a tab, if it exists in this tabset
+ if (_this.options.deepLink) {
+ var anchor = window.location.hash;
+ //need a hash and a relevant anchor in this tabset
+ if(anchor.length) {
+ var $link = $elem.find('[href="'+anchor+'"]');
+ if ($link.length) {
+ _this.selectTab($(anchor));
+
+ //roll up a little to show the titles
+ if (_this.options.deepLinkSmudge) {
+ $(window).load(function() {
+ var offset = $elem.offset();
+ $('html, body').animate({ scrollTop: offset.top }, _this.options.deepLinkSmudgeDelay);
+ });
+ }
+
+ /**
+ * Fires when the zplugin has deeplinked at pageload
+ * @event Tabs#deeplink
+ */
+ $elem.trigger('deeplink.zf.tabs', [$link, $(anchor)]);
+ }
+ }
+ }
});
if(this.options.matchHeight) {
var $images = this.$tabContent.find('img');
@@ -92,14 +123,14 @@
*/
_events() {
this._addKeyHandler();
this._addClickHandler();
this._setHeightMqHandler = null;
-
+
if (this.options.matchHeight) {
this._setHeightMqHandler = this._setHeight.bind(this);
-
+
$(window).on('changed.zf.mediaquery', this._setHeightMqHandler);
}
}
/**
@@ -112,30 +143,25 @@
this.$element
.off('click.zf.tabs')
.on('click.zf.tabs', `.${this.options.linkClass}`, function(e){
e.preventDefault();
e.stopPropagation();
- if ($(this).hasClass('is-active')) {
- return;
- }
_this._handleTabChange($(this));
});
}
/**
* Adds keyboard event handlers for items within the tabs.
* @private
*/
_addKeyHandler() {
var _this = this;
- var $firstTab = _this.$element.find('li:first-of-type');
- var $lastTab = _this.$element.find('li:last-of-type');
this.$tabTitles.off('keydown.zf.tabs').on('keydown.zf.tabs', function(e){
if (e.which === 9) return;
-
+
var $element = $(this),
$elements = $element.parent('ul').children('li'),
$prevElement,
$nextElement;
@@ -173,45 +199,102 @@
});
});
}
/**
- * Opens the tab `$targetContent` defined by `$target`.
+ * Opens the tab `$targetContent` defined by `$target`. Collapses active tab.
* @param {jQuery} $target - Tab to open.
* @fires Tabs#change
* @function
*/
_handleTabChange($target) {
- var $tabLink = $target.find('[role="tab"]'),
- hash = $tabLink[0].hash,
- $targetContent = this.$tabContent.find(hash),
- $oldTab = this.$element.
- find(`.${this.options.linkClass}.is-active`)
- .removeClass('is-active')
- .find('[role="tab"]')
- .attr({ 'aria-selected': 'false' });
- $(`#${$oldTab.attr('aria-controls')}`)
- .removeClass('is-active')
- .attr({ 'aria-hidden': 'true' });
+ /**
+ * Check for active class on target. Collapse if exists.
+ */
+ if ($target.hasClass(`${this.options.linkActiveClass}`)) {
+ if(this.options.activeCollapse) {
+ this._collapseTab($target);
- $target.addClass('is-active');
+ /**
+ * Fires when the zplugin has successfully collapsed tabs.
+ * @event Tabs#collapse
+ */
+ this.$element.trigger('collapse.zf.tabs', [$target]);
+ }
+ return;
+ }
- $tabLink.attr({'aria-selected': 'true'});
+ var $oldTab = this.$element.
+ find(`.${this.options.linkClass}.${this.options.linkActiveClass}`),
+ $tabLink = $target.find('[role="tab"]'),
+ hash = $tabLink[0].hash,
+ $targetContent = this.$tabContent.find(hash);
- $targetContent
- .addClass('is-active')
- .attr({'aria-hidden': 'false'});
+ //close old tab
+ this._collapseTab($oldTab);
+ //open new tab
+ this._openTab($target);
+
+ //either replace or update browser history
+ if (this.options.deepLink) {
+ var anchor = $target.find('a').attr('href');
+
+ if (this.options.updateHistory) {
+ history.pushState({}, '', anchor);
+ } else {
+ history.replaceState({}, '', anchor);
+ }
+ }
+
/**
* Fires when the plugin has successfully changed tabs.
* @event Tabs#change
*/
- this.$element.trigger('change.zf.tabs', [$target]);
+ this.$element.trigger('change.zf.tabs', [$target, $targetContent]);
+
+ //fire to children a mutation event
+ $targetContent.find("[data-mutate]").trigger("mutateme.zf.trigger");
}
/**
+ * Opens the tab `$targetContent` defined by `$target`.
+ * @param {jQuery} $target - Tab to Open.
+ * @function
+ */
+ _openTab($target) {
+ var $tabLink = $target.find('[role="tab"]'),
+ hash = $tabLink[0].hash,
+ $targetContent = this.$tabContent.find(hash);
+
+ $target.addClass(`${this.options.linkActiveClass}`);
+
+ $tabLink.attr({'aria-selected': 'true'});
+
+ $targetContent
+ .addClass(`${this.options.panelActiveClass}`)
+ .attr({'aria-hidden': 'false'});
+ }
+
+ /**
+ * Collapses `$targetContent` defined by `$target`.
+ * @param {jQuery} $target - Tab to Open.
+ * @function
+ */
+ _collapseTab($target) {
+ var $target_anchor = $target
+ .removeClass(`${this.options.linkActiveClass}`)
+ .find('[role="tab"]')
+ .attr({ 'aria-selected': 'false' });
+
+ $(`#${$target_anchor.attr('aria-controls')}`)
+ .removeClass(`${this.options.panelActiveClass}`)
+ .attr({ 'aria-hidden': 'true' });
+ }
+
+ /**
* Public method for selecting a content pane to display.
* @param {jQuery | String} elem - jQuery object or string of the id of the pane to display.
* @function
*/
selectTab(elem) {
@@ -243,11 +326,11 @@
this.$tabContent
.find(`.${this.options.panelClass}`)
.css('height', '')
.each(function() {
var panel = $(this),
- isActive = panel.hasClass('is-active');
+ isActive = panel.hasClass(`${this.options.panelActiveClass}`);
if (!isActive) {
panel.css({'visibility': 'hidden', 'display': 'block'});
}
@@ -286,11 +369,40 @@
}
}
Tabs.defaults = {
/**
+ * Allows the window to scroll to content of pane specified by hash anchor
+ * @option
+ * @example false
+ */
+ deepLink: false,
+
+ /**
+ * Adjust the deep link scroll to make sure the top of the tab panel is visible
+ * @option
+ * @example false
+ */
+ deepLinkSmudge: false,
+
+ /**
+ * Animation time (ms) for the deep link adjustment
+ * @option
+ * @example 300
+ */
+ deepLinkSmudgeDelay: 300,
+
+ /**
+ * Update the browser history with the open tab
+ * @option
+ * @example false
+ */
+ updateHistory: false,
+
+ /**
* Allows the window to scroll to content of active pane on load if set to true.
+ * Not recommended if more than one tab panel per page.
* @option
* @example false
*/
autoFocus: false,
@@ -307,26 +419,43 @@
* @example false
*/
matchHeight: false,
/**
+ * Allows active tabs to collapse when clicked.
+ * @option
+ * @example false
+ */
+ activeCollapse: false,
+
+ /**
* Class applied to `li`'s in tab link list.
* @option
* @example 'tabs-title'
*/
linkClass: 'tabs-title',
/**
+ * Class applied to the active `li` in tab link list.
+ * @option
+ * @example 'is-active'
+ */
+ linkActiveClass: 'is-active',
+
+ /**
* Class applied to the content containers.
* @option
* @example 'tabs-panel'
*/
- panelClass: 'tabs-panel'
-};
+ panelClass: 'tabs-panel',
-function checkClass($elem){
- return $elem.hasClass('is-active');
-}
+ /**
+ * Class applied to the active content container.
+ * @option
+ * @example 'is-active'
+ */
+ panelActiveClass: 'is-active'
+};
// Window exports
Foundation.plugin(Tabs, 'Tabs');
}(jQuery);