PageSourceSearch

https://www.narscosmetics.com/on/demandware.static/Sites-nars_us-S…/v1790845648508/lib/foundation.accordion.js

js narscosmetics.com collected 2026-10-02 07:03:18 UTC 7,725 bytes, 256 lines download raw bytes

1/**
2 * Accordion module.
3 * @module foundation.accordion
4 * @requires foundation.util.keyboard
5 * @requires foundation.util.motion
6 */
7!function($, Foundation) {
8  'use strict';
9
10  /**
11   * Creates a new instance of an accordion.
12   * @class
13   * @fires Accordion#init
14   * @param {jQuery} element - jQuery object to make into an accordion.
15   */
16  function Accordion(element, options){
17    this.$element = element;
18    this.options = $.extend({}, Accordion.defaults, this.$element.data(), options);
19
20    this._init();
21
22    Foundation.registerPlugin(this, 'Accordion');
23    Foundation.Keyboard.register('Accordion', {
24      'ENTER': 'toggle',
25      'SPACE': 'toggle',
26      'ARROW_DOWN': 'next',
27      'ARROW_UP': 'previous'
28    });
29  }
30
31  Accordion.defaults = {
32    /**
33     * Amount of time to animate the opening of an accordion pane.
34     * @option
35     * @example 250
36     */
37    slideSpeed: 250,
38    /**
39     * Allow the accordion to have multiple open panes.
40     * @option
41     * @example false
42     */
43    multiExpand: false,
44    /**
45     * Allow the accordion to close all panes.
46     * @option
47     * @example false
48     */
49    allowAllClosed: false
50  };
51
52  /**
53   * Initializes the accordion by animating the preset active pane(s).
54   * @private
55   */
56  Accordion.prototype._init = function() {
57    if (!this.$element.hasClass('accordion')) {
58      this.$element.attr('role', 'tablist');
59    }
60    this.$tabs = this.$element.children('li');
61    if (this.$tabs.length == 0) {
62      this.$tabs = this.$element.children('[data-accordion-item]');
63    }
64    if (this.$element.hasClass('accordion')) {
65      this.$tabs.each(function(idx, el){
66
67        var $el = $(el),
68            $content = $el.find('[data-tab-content]'),
69            id = $content[0].id || Foundation.GetYoDigits(6, 'accordion'),
70            linkId = el.id || id + '-label';
71  
72        $el.find('a:first').attr({
73          'aria-controls': id,
74          'role': 'button',
75          'id': linkId,
76          'aria-expanded': false
77        });
78        if ($el.hasClass('is-active')) {
79          $el.find('a:first').attr({
80            'aria-controls': id,
81            'role': 'button',
82            'id': linkId,
83            'aria-expanded': true
84          });
85        }
86        $content.attr({'role': 'region', 'aria-labelledby': linkId, 'aria-hidden': true, 'id': id});
87      });
88    } else {
89      this.$tabs.each(function(idx, el){
90        var $el = $(el),
91            $content = $el.find('[data-tab-content]'),
92            id = $content[0].id || Foundation.GetYoDigits(6, 'accordion'),
93            linkId = el.id || id + '-label';
94  
95        $el.find('a:first').attr({
96          'aria-controls': id,
97          'role': 'tab',
98          'id': linkId,
99          'aria-expanded': false,
100          'aria-selected': false
101        });
102        $content.attr({'role': 'tabpanel', 'aria-labelledby': linkId, 'aria-hidden': true, 'id': id});
103      });
104    }
105    var $initActive = this.$element.find('.is-active').children('[data-tab-content]');
106    if($initActive.length){
107      this.down($initActive, true);
108    }
109    this._events();
110  };
111
112  /**
113   * Adds event handlers for items within the accordion.
114   * @private
115   */
116  Accordion.prototype._events = function() {
117    var _this = this;
118
119    this.$tabs.each(function(){
120      var $elem = $(this);
121      var $tabContent = $elem.children('[data-tab-content]');
122      if ($tabContent.length) {
123        $elem.children('a').off('click.zf.accordion keydown.zf.accordion')
124               .on('click.zf.accordion', function(e){
125        // $(this).children('a').on('click.zf.accordion', function(e) {
126          e.preventDefault();
127          if ($elem.hasClass('is-active')) {
128            if(_this.options.allowAllClosed || $elem.siblings().hasClass('is-active')){
129              _this.up($tabContent);
130            }
131          }
132          else {
133            _this.down($tabContent);
134          }
135        }).on('keydown.zf.accordion', function(e){
136          Foundation.Keyboard.handleKey(e, 'Accordion', {
137            toggle: function() {
138              _this.toggle($tabContent);
139            },
140            next: function() {
141              $elem.next().find('a').focus().trigger('click.zf.accordion');
142            },
143            previous: function() {
144              $elem.prev().find('a').focus().trigger('click.zf.accordion');
145            },
146            handled: function() {
147              e.preventDefault();
148              e.stopPropagation();
149            }
150          });
151        });
152      }
153    });
154  };
155  /**
156   * Toggles the selected content pane's open/close state.
157   * @param {jQuery} $target - jQuery object of the pane to toggle.
158   * @function
159   */
160  Accordion.prototype.toggle = function($target){
161    if($target.parent().hasClass('is-active')){
162      if(this.options.allowAllClosed || $target.parent().siblings().hasClass('is-active')){
163        this.up($target);
164      }else{ return; }
165    }else{
166      this.down($target);
167    }
168  };
169  /**
170   * Opens the accordion tab defined by `$target`.
171   * @param {jQuery} $target - Accordion pane to open.
172   * @param {Boolean} firstTime - flag to determine if reflow should happen.
173   * @fires Accordion#down
174   * @function
175   */
176  Accordion.prototype.down = function($target, firstTime) {
177    var _this = this;
178    if(!this.options.multiExpand && !firstTime){
179      var $currentActive = this.$element.find('.is-active').children('[data-tab-content]');
180      if($currentActive.length){
181        this.up($currentActive);
182      }
183    }
184
185    $target
186      .attr('aria-hidden', false)
187      .parent('[data-tab-content]')
188      .addBack()
189      .parent().addClass('is-active');
190
191    // Foundation.Move(_this.options.slideSpeed, $target, function(){
192      $target.slideDown(_this.options.slideSpeed);
193    // });
194
195    // if(!firstTime){
196    //   Foundation._reflow(this.$element.attr('data-accordion'));
197    // }
198    $('#' + $target.attr('aria-labelledby')).attr({
199      'aria-expanded': true,
200      'aria-selected': true
201    });
202    /**
203     * Fires when the tab is done opening.
204     * @event Accordion#down
205     */
206    this.$element.trigger('down.zf.accordion', [$target]);
207  };
208
209  /**
210   * Closes the tab defined by `$target`.
211   * @param {jQuery} $target - Accordion tab to close.
212   * @fires Accordion#up
213   * @function
214   */
215  Accordion.prototype.up = function($target) {
216    var $aunts = $target.parent().siblings(),
217        _this = this;
218    var canClose = this.options.multiExpand ? $aunts.hasClass('is-active') : $target.parent().hasClass('is-active');
219
220    if(!this.options.allowAllClosed && !canClose){
221      return;
222    }
223
224    // Foundation.Move(this.options.slideSpeed, $target, function(){
225      $target.slideUp(_this.options.slideSpeed);
226    // });
227
228    $target.attr('aria-hidden', true)
229           .parent().removeClass('is-active');
230
231    $('#' + $target.attr('aria-labelledby')).attr({
232     'aria-expanded': false,
233     'aria-selected': false
234   });
235
236    /**
237     * Fires when the tab is done collapsing up.
238     * @event Accordion#up
239     */
240    this.$element.trigger('up.zf.accordion', [$target]);
241  };
242
243  /**
244   * Destroys an instance of an accordion.
245   * @fires Accordion#destroyed
246   * @function
247   */
248  Accordion.prototype.destroy = function() {
249    this.$element.find('[data-tab-content]').slideUp(0).css('display', '');
250    this.$element.find('a').off('.zf.accordion');
251
252    Foundation.unregisterPlugin(this);
253  };
254
255  Foundation.plugin(Accordion, 'Accordion');
256}(jQuery, window.Foundation);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.