foundation-rails 6.2.4.0 → 6.3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/Rakefile +2 -0
  4. data/bower.json +2 -2
  5. data/lib/foundation/rails/version.rb +1 -1
  6. data/lib/generators/foundation/templates/_settings.scss +117 -70
  7. data/lib/generators/foundation/templates/foundation_and_overrides.scss +2 -1
  8. data/vendor/assets/_vendor/normalize-scss/sass/_normalize.scss +3 -0
  9. data/vendor/assets/_vendor/normalize-scss/sass/normalize/_import-now.scss +11 -0
  10. data/vendor/assets/_vendor/normalize-scss/sass/normalize/_normalize-mixin.scss +676 -0
  11. data/vendor/assets/_vendor/normalize-scss/sass/normalize/_variables.scss +36 -0
  12. data/vendor/assets/_vendor/normalize-scss/sass/normalize/_vertical-rhythm.scss +61 -0
  13. data/vendor/assets/_vendor/sassy-lists/stylesheets/functions/_purge.scss +38 -0
  14. data/vendor/assets/_vendor/sassy-lists/stylesheets/functions/_remove.scss +31 -0
  15. data/vendor/assets/_vendor/sassy-lists/stylesheets/functions/_replace.scss +46 -0
  16. data/vendor/assets/_vendor/sassy-lists/stylesheets/functions/_to-list.scss +27 -0
  17. data/vendor/assets/_vendor/sassy-lists/stylesheets/helpers/_missing-dependencies.scss +25 -0
  18. data/vendor/assets/_vendor/sassy-lists/stylesheets/helpers/_true.scss +13 -0
  19. data/vendor/assets/js/foundation.abide.js.es6 +28 -0
  20. data/vendor/assets/js/foundation.accordion.js.es6 +1 -1
  21. data/vendor/assets/js/foundation.accordionMenu.js.es6 +9 -1
  22. data/vendor/assets/js/foundation.core.js.es6 +4 -4
  23. data/vendor/assets/js/foundation.drilldown.js.es6 +128 -14
  24. data/vendor/assets/js/foundation.dropdown.js.es6 +48 -42
  25. data/vendor/assets/js/foundation.dropdownMenu.js.es6 +20 -18
  26. data/vendor/assets/js/foundation.equalizer.js.es6 +12 -6
  27. data/vendor/assets/js/foundation.interchange.js.es6 +3 -2
  28. data/vendor/assets/js/foundation.js.es6 +2 -1
  29. data/vendor/assets/js/foundation.magellan.js.es6 +28 -9
  30. data/vendor/assets/js/foundation.offcanvas.js.es6 +90 -123
  31. data/vendor/assets/js/foundation.orbit.js.es6 +61 -10
  32. data/vendor/assets/js/foundation.responsiveMenu.js.es6 +2 -0
  33. data/vendor/assets/js/foundation.responsiveToggle.js.es6 +52 -12
  34. data/vendor/assets/js/foundation.reveal.js.es6 +48 -48
  35. data/vendor/assets/js/foundation.slider.js.es6 +124 -42
  36. data/vendor/assets/js/foundation.sticky.js.es6 +11 -9
  37. data/vendor/assets/js/foundation.tabs.js.es6 +164 -35
  38. data/vendor/assets/js/foundation.toggler.js.es6 +3 -0
  39. data/vendor/assets/js/foundation.tooltip.js.es6 +20 -10
  40. data/vendor/assets/js/foundation.util.box.js.es6 +2 -2
  41. data/vendor/assets/js/foundation.util.keyboard.js.es6 +37 -0
  42. data/vendor/assets/js/foundation.util.mediaQuery.js.es6 +16 -0
  43. data/vendor/assets/js/foundation.util.motion.js.es6 +7 -1
  44. data/vendor/assets/js/foundation.util.nest.js.es6 +10 -5
  45. data/vendor/assets/js/foundation.util.timerAndImageLoader.js.es6 +6 -4
  46. data/vendor/assets/js/foundation.util.triggers.js.es6 +54 -36
  47. data/vendor/assets/js/foundation.zf.responsiveAccordionTabs.js.es6 +240 -0
  48. data/vendor/assets/scss/_global.scss +25 -450
  49. data/vendor/assets/scss/components/_accordion-menu.scss +8 -4
  50. data/vendor/assets/scss/components/_accordion.scss +43 -22
  51. data/vendor/assets/scss/components/_badge.scss +17 -9
  52. data/vendor/assets/scss/components/_breadcrumbs.scss +7 -5
  53. data/vendor/assets/scss/components/_button-group.scss +54 -6
  54. data/vendor/assets/scss/components/_button.scss +27 -16
  55. data/vendor/assets/scss/components/_callout.scss +3 -2
  56. data/vendor/assets/scss/components/_card.scss +121 -0
  57. data/vendor/assets/scss/components/_close-button.scss +54 -13
  58. data/vendor/assets/scss/components/_drilldown.scss +19 -5
  59. data/vendor/assets/scss/components/_dropdown-menu.scss +23 -18
  60. data/vendor/assets/scss/components/_dropdown.scss +14 -7
  61. data/vendor/assets/scss/components/_flex-video.scss +1 -63
  62. data/vendor/assets/scss/components/_float.scss +1 -1
  63. data/vendor/assets/scss/components/_label.scss +16 -8
  64. data/vendor/assets/scss/components/_media-object.scss +2 -3
  65. data/vendor/assets/scss/components/_menu.scss +68 -33
  66. data/vendor/assets/scss/components/_off-canvas.scss +231 -80
  67. data/vendor/assets/scss/components/_orbit.scss +8 -6
  68. data/vendor/assets/scss/components/_pagination.scss +42 -22
  69. data/vendor/assets/scss/components/_progress-bar.scss +1 -1
  70. data/vendor/assets/scss/components/_responsive-embed.scss +66 -0
  71. data/vendor/assets/scss/components/_reveal.scss +17 -11
  72. data/vendor/assets/scss/components/_slider.scss +6 -1
  73. data/vendor/assets/scss/components/_sticky.scss +3 -3
  74. data/vendor/assets/scss/components/_switch.scss +47 -36
  75. data/vendor/assets/scss/components/_table.scss +83 -23
  76. data/vendor/assets/scss/components/_tabs.scss +54 -23
  77. data/vendor/assets/scss/components/_thumbnail.scss +17 -4
  78. data/vendor/assets/scss/components/_title-bar.scss +5 -6
  79. data/vendor/assets/scss/components/_tooltip.scss +15 -12
  80. data/vendor/assets/scss/components/_top-bar.scss +11 -8
  81. data/vendor/assets/scss/forms/_checkbox.scss +2 -1
  82. data/vendor/assets/scss/forms/_error.scss +10 -6
  83. data/vendor/assets/scss/forms/_fieldset.scss +7 -7
  84. data/vendor/assets/scss/forms/_input-group.scss +17 -11
  85. data/vendor/assets/scss/forms/_label.scss +2 -0
  86. data/vendor/assets/scss/forms/_meter.scss +9 -10
  87. data/vendor/assets/scss/forms/_progress.scss +9 -9
  88. data/vendor/assets/scss/forms/_range.scss +20 -15
  89. data/vendor/assets/scss/forms/_select.scss +26 -8
  90. data/vendor/assets/scss/forms/_text.scss +19 -16
  91. data/vendor/assets/scss/foundation.scss +19 -3
  92. data/vendor/assets/scss/grid/_classes.scss +31 -14
  93. data/vendor/assets/scss/grid/_column.scss +10 -24
  94. data/vendor/assets/scss/grid/_flex-grid.scss +84 -76
  95. data/vendor/assets/scss/grid/_grid.scss +0 -16
  96. data/vendor/assets/scss/grid/_gutter.scss +53 -5
  97. data/vendor/assets/scss/grid/_layout.scss +3 -3
  98. data/vendor/assets/scss/grid/_position.scss +3 -3
  99. data/vendor/assets/scss/grid/_row.scss +24 -19
  100. data/vendor/assets/scss/settings/_settings.scss +117 -70
  101. data/vendor/assets/scss/typography/_base.scss +110 -44
  102. data/vendor/assets/scss/typography/_helpers.scss +1 -0
  103. data/vendor/assets/scss/typography/_print.scss +7 -3
  104. data/vendor/assets/scss/typography/_typography.scss +0 -2
  105. data/vendor/assets/scss/util/_breakpoint.scss +28 -19
  106. data/vendor/assets/scss/util/_color.scss +69 -16
  107. data/vendor/assets/scss/util/_flex.scss +20 -3
  108. data/vendor/assets/scss/util/_math.scss +72 -0
  109. data/vendor/assets/scss/util/_mixins.scss +63 -26
  110. data/vendor/assets/scss/util/_selector.scss +3 -2
  111. data/vendor/assets/scss/util/_unit.scss +61 -4
  112. data/vendor/assets/scss/util/_util.scss +1 -0
  113. data/vendor/assets/scss/util/_value.scss +33 -0
  114. metadata +17 -2
@@ -0,0 +1,36 @@
1
+ //
2
+ // Variables
3
+ //
4
+ // You can override the default values by setting the variables in your Sass
5
+ // before importing the normalize-scss library.
6
+
7
+ // The font size set on the root html element.
8
+ $base-font-size: 16px !default;
9
+
10
+ // The base line height determines the basic unit of vertical rhythm.
11
+ $base-line-height: 24px !default;
12
+
13
+ // The length unit in which to output vertical rhythm values.
14
+ // Supported values: px, em, rem.
15
+ $base-unit: 'em' !default;
16
+
17
+ // The default font family.
18
+ $base-font-family: sans-serif !default;
19
+
20
+ // The font sizes for h1-h6.
21
+ $h1-font-size: 2 * $base-font-size !default;
22
+ $h2-font-size: 1.5 * $base-font-size !default;
23
+ $h3-font-size: 1.17 * $base-font-size !default;
24
+ $h4-font-size: 1 * $base-font-size !default;
25
+ $h5-font-size: 0.83 * $base-font-size !default;
26
+ $h6-font-size: 0.67 * $base-font-size !default;
27
+
28
+ // The amount lists and blockquotes are indented.
29
+ $indent-amount: 40px !default;
30
+
31
+ // The following variable controls whether normalize-scss will output
32
+ // font-sizes, line-heights and block-level top/bottom margins that form a basic
33
+ // vertical rhythm on the page, which differs from the original Normalize.css.
34
+ // However, changing any of the variables above will cause
35
+ // $normalize-vertical-rhythm to be automatically set to true.
36
+ $normalize-vertical-rhythm: false !default;
@@ -0,0 +1,61 @@
1
+ //
2
+ // Vertical Rhythm
3
+ //
4
+ // This is the minimal amount of code needed to create vertical rhythm in our
5
+ // CSS. If you are looking for a robust solution, look at the excellent Typey
6
+ // library. @see https://github.com/jptaranto/typey
7
+
8
+ @function normalize-rhythm($value, $relative-to: $base-font-size, $unit: $base-unit) {
9
+ @if unit($value) != px {
10
+ @error "The normalize vertical-rhythm module only supports px inputs. The typey library is better.";
11
+ }
12
+ @if $unit == rem {
13
+ @return ($value / $base-font-size) * 1rem;
14
+ }
15
+ @else if $unit == em {
16
+ @return ($value / $relative-to) * 1em;
17
+ }
18
+ @else { // $unit == px
19
+ @return $value;
20
+ }
21
+ }
22
+
23
+ @mixin normalize-font-size($value, $relative-to: $base-font-size) {
24
+ @if unit($value) != 'px' {
25
+ @error "normalize-font-size() only supports px inputs. The typey library is better.";
26
+ }
27
+ font-size: normalize-rhythm($value, $relative-to);
28
+ }
29
+
30
+ @mixin normalize-rhythm($property, $values, $relative-to: $base-font-size) {
31
+ $value-list: $values;
32
+ $sep: space;
33
+ @if type-of($values) == 'list' {
34
+ $sep: list-separator($values);
35
+ }
36
+ @else {
37
+ $value-list: append((), $values);
38
+ }
39
+
40
+ $normalized-values: ();
41
+ @each $value in $value-list {
42
+ @if unitless($value) and $value != 0 {
43
+ $value: $value * normalize-rhythm($base-line-height, $relative-to);
44
+ }
45
+ $normalized-values: append($normalized-values, $value, $sep);
46
+ }
47
+ #{$property}: $normalized-values;
48
+ }
49
+
50
+ @mixin normalize-margin($values, $relative-to: $base-font-size) {
51
+ @include normalize-rhythm(margin, $values, $relative-to);
52
+ }
53
+
54
+ @mixin normalize-line-height($font-size, $min-line-padding: 2px) {
55
+ $lines: ceil($font-size / $base-line-height);
56
+ // If lines are cramped include some extra leading.
57
+ @if ($lines * $base-line-height - $font-size) < ($min-line-padding * 2) {
58
+ $lines: $lines + 1;
59
+ }
60
+ @include normalize-rhythm(line-height, $lines, $font-size);
61
+ }
@@ -0,0 +1,38 @@
1
+ /// Removes all false and null values from `$list`.
2
+ ///
3
+ /// @ignore Documentation: http://at-import.github.io/SassyLists/documentation/#function-sl-purge
4
+ ///
5
+ /// @requires sl-is-true
6
+ /// @requires sl-to-list
7
+ ///
8
+ /// @param {List} $list - list to purge
9
+ ///
10
+ /// @example
11
+ /// sl-purge(null a false b)
12
+ /// // a b
13
+ ///
14
+ /// @return {List}
15
+ ///
16
+
17
+ @function sl-purge($list) {
18
+ $_: sl-missing-dependencies('sl-is-true', 'sl-to-list');
19
+
20
+ $result: ();
21
+
22
+ @each $item in $list {
23
+ @if sl-is-true($item) {
24
+ $result: append($result, $item, list-separator($list));
25
+ }
26
+ }
27
+
28
+ @return sl-to-list($result);
29
+ }
30
+
31
+ ///
32
+ /// @requires sl-purge
33
+ /// @alias sl-purge
34
+ ///
35
+
36
+ @function sl-clean($list) {
37
+ @return sl-purge($list);
38
+ }
@@ -0,0 +1,31 @@
1
+ ///
2
+ /// Removes value(s) `$value` from `$list`.
3
+ ///
4
+ /// @ignore Documentation: http://at-import.github.io/SassyLists/documentation/#function-sl-remove
5
+ ///
6
+ /// @requires sl-replace
7
+ ///
8
+ /// @param {List} $list - list to update
9
+ /// @param {*} $value - value to remove
10
+ ///
11
+ /// @example
12
+ /// sl-remove(a b c, a)
13
+ /// // b c
14
+ ///
15
+ /// @return {List}
16
+ ///
17
+
18
+ @function sl-remove($list, $value) {
19
+ $_: sl-missing-dependencies('sl-replace');
20
+
21
+ @return sl-replace($list, $value, null);
22
+ }
23
+
24
+ ///
25
+ /// @requires sl-remove
26
+ /// @alias sl-remove
27
+ ///
28
+
29
+ @function sl-without($list, $value) {
30
+ @return sl-remove($list, $value);
31
+ }
@@ -0,0 +1,46 @@
1
+ ///
2
+ /// Replaces `$old` by `$new` in `$list`.
3
+ ///
4
+ /// @ignore Documentation: http://at-import.github.io/SassyLists/documentation/#function-sl-replace
5
+ ///
6
+ /// @requires sl-is-true
7
+ /// @requires sl-purge
8
+ /// @requires sl-to-list
9
+ ///
10
+ /// @param {List} $list - list to update
11
+ /// @param {*} $old - value to replace
12
+ /// @param {*} $value - new value for $old
13
+ ///
14
+ /// @example
15
+ /// sl-replace(a b c, b, z)
16
+ /// // a z c
17
+ ///
18
+ /// @example
19
+ /// sl-replace(a b c, y, z)
20
+ /// // a b c
21
+ ///
22
+ /// @return {List}
23
+ ///
24
+
25
+ @function sl-replace($list, $old, $value) {
26
+ $_: sl-missing-dependencies('sl-is-true', 'sl-purge', 'sl-to-list');
27
+
28
+ $running: true;
29
+
30
+ @while $running {
31
+ $index: index($list, $old);
32
+
33
+ @if not $index {
34
+ $running: false;
35
+ }
36
+
37
+ @else {
38
+ $list: set-nth($list, $index, $value);
39
+ }
40
+
41
+ }
42
+
43
+ $list: if(sl-is-true($value), $list, sl-purge($list));
44
+
45
+ @return sl-to-list($list);
46
+ }
@@ -0,0 +1,27 @@
1
+ ///
2
+ /// Casts `$value` into a list.
3
+ ///
4
+ /// @ignore Documentation: http://at-import.github.io/SassyLists/documentation/#function-sl-to-list
5
+ ///
6
+ /// @param {*} $value - value to cast to list
7
+ /// @param {String} $separator [space] - separator to use
8
+ ///
9
+ /// @example
10
+ /// sl-to-list(a b c, comma)
11
+ /// // a, b, c
12
+ ///
13
+ /// @return {List}
14
+ ///
15
+
16
+ @function sl-to-list($value, $separator: list-separator($value)) {
17
+ @return join((), $value, $separator);
18
+ }
19
+
20
+ ///
21
+ /// @requires sl-to-list
22
+ /// @alias sl-to-list
23
+ ///
24
+
25
+ @function sl-listify($value) {
26
+ @return sl-to-list($value);
27
+ }
@@ -0,0 +1,25 @@
1
+ ///
2
+ /// Checks whether `$functions` exist in global scope.
3
+ ///
4
+ /// @access private
5
+ ///
6
+ /// @param {ArgList} $functions - list of functions to check for
7
+ ///
8
+ /// @return {Bool} Whether or not there are missing dependencies
9
+ ///
10
+
11
+ @function sl-missing-dependencies($functions...) {
12
+ $missing-dependencies: ();
13
+
14
+ @each $function in $functions {
15
+ @if not function-exists($function) {
16
+ $missing-dependencies: append($missing-dependencies, $function, comma);
17
+ }
18
+ }
19
+
20
+ @if length($missing-dependencies) > 0 {
21
+ @error 'Unmet dependencies! The following functions are required: #{$missing-dependencies}.';
22
+ }
23
+
24
+ @return length($missing-dependencies) > 0;
25
+ }
@@ -0,0 +1,13 @@
1
+ ///
2
+ /// Returns truthiness of `$value`.
3
+ ///
4
+ /// @access private
5
+ ///
6
+ /// @param {*} $value - value to check
7
+ ///
8
+ /// @return {Bool}
9
+ ///
10
+
11
+ @function sl-is-true($value) {
12
+ @return if($value == null, false, $value and $value != null and $value != '' and $value != ());
13
+ }
@@ -62,6 +62,14 @@ class Abide {
62
62
  this.validateInput($(e.target));
63
63
  });
64
64
  }
65
+
66
+ if (this.options.validateOnBlur) {
67
+ this.$inputs
68
+ .off('blur.zf.abide')
69
+ .on('blur.zf.abide', (e) => {
70
+ this.validateInput($(e.target));
71
+ });
72
+ }
65
73
  }
66
74
 
67
75
  /**
@@ -278,6 +286,19 @@ class Abide {
278
286
  var goodToGo = [clearRequire, validated, customValidator, equalTo].indexOf(false) === -1;
279
287
  var message = (goodToGo ? 'valid' : 'invalid') + '.zf.abide';
280
288
 
289
+ if (goodToGo) {
290
+ // Re-validate inputs that depend on this one with equalto
291
+ const dependentElements = this.$element.find(`[data-equalto="${$el.attr('id')}"]`);
292
+ if (dependentElements.length) {
293
+ let _this = this;
294
+ dependentElements.each(function() {
295
+ if ($(this).val()) {
296
+ _this.validateInput($(this));
297
+ }
298
+ });
299
+ }
300
+ }
301
+
281
302
  this[goodToGo ? 'removeErrorClasses' : 'addErrorClasses']($el);
282
303
 
283
304
  /**
@@ -490,6 +511,13 @@ Abide.defaults = {
490
511
  */
491
512
  liveValidate: false,
492
513
 
514
+ /**
515
+ * Set to true to validate inputs on blur.
516
+ * @option
517
+ * @example false
518
+ */
519
+ validateOnBlur: false,
520
+
493
521
  patterns: {
494
522
  alpha : /^[a-zA-Z]+$/,
495
523
  alpha_numeric : /^[a-zA-Z0-9]+$/,
@@ -38,7 +38,7 @@ class Accordion {
38
38
  */
39
39
  _init() {
40
40
  this.$element.attr('role', 'tablist');
41
- this.$tabs = this.$element.children('li, [data-accordion-item]');
41
+ this.$tabs = this.$element.children('[data-accordion-item]');
42
42
 
43
43
  this.$tabs.each(function(idx, el) {
44
44
  var $el = $(el),
@@ -172,7 +172,15 @@ class AccordionMenu {
172
172
  * @function
173
173
  */
174
174
  hideAll() {
175
- this.$element.find('[data-submenu]').slideUp(this.options.slideSpeed);
175
+ this.up(this.$element.find('[data-submenu]'));
176
+ }
177
+
178
+ /**
179
+ * Opens all panes of the menu.
180
+ * @function
181
+ */
182
+ showAll() {
183
+ this.down(this.$element.find('[data-submenu]'));
176
184
  }
177
185
 
178
186
  /**
@@ -2,7 +2,7 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- var FOUNDATION_VERSION = '6.2.4';
5
+ var FOUNDATION_VERSION = '6.3.0';
6
6
 
7
7
  // Global Foundation object
8
8
  // This is attached to the window, or used as a module for AMD/Browserify
@@ -364,9 +364,9 @@ function functionName(fn) {
364
364
  }
365
365
  }
366
366
  function parseValue(str){
367
- if(/true/.test(str)) return true;
368
- else if(/false/.test(str)) return false;
369
- else if(!isNaN(str * 1)) return parseFloat(str);
367
+ if ('true' === str) return true;
368
+ else if ('false' === str) return false;
369
+ else if (!isNaN(str * 1)) return parseFloat(str);
370
370
  return str;
371
371
  }
372
372
  // Convert PascalCase to kebab-case
@@ -47,8 +47,10 @@ class Drilldown {
47
47
  this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent').children('a');
48
48
  this.$submenus = this.$submenuAnchors.parent('li').children('[data-submenu]');
49
49
  this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'menuitem').find('a');
50
+ this.$element.attr('data-mutate', (this.$element.attr('data-drilldown') || Foundation.GetYoDigits(6, 'drilldown')));
50
51
 
51
52
  this._prepareMenu();
53
+ this._registerEvents();
52
54
 
53
55
  this._keyboardEvents();
54
56
  }
@@ -84,16 +86,37 @@ class Drilldown {
84
86
  var $menu = $(this),
85
87
  $back = $menu.find('.js-drilldown-back');
86
88
  if(!$back.length){
87
- $menu.prepend(_this.options.backButton);
89
+ switch (_this.options.backButtonPosition) {
90
+ case "bottom":
91
+ $menu.append(_this.options.backButton);
92
+ break;
93
+ case "top":
94
+ $menu.prepend(_this.options.backButton);
95
+ break;
96
+ default:
97
+ console.error("Unsupported backButtonPosition value '" + _this.options.backButtonPosition + "'");
98
+ }
88
99
  }
89
100
  _this._back($menu);
90
101
  });
102
+
103
+ if(!this.options.autoHeight) {
104
+ this.$submenus.addClass('drilldown-submenu-cover-previous');
105
+ }
106
+
91
107
  if(!this.$element.parent().hasClass('is-drilldown')){
92
108
  this.$wrapper = $(this.options.wrapper).addClass('is-drilldown');
109
+ if(this.options.animateHeight) this.$wrapper.addClass('animate-height');
93
110
  this.$wrapper = this.$element.wrap(this.$wrapper).parent().css(this._getMaxDims());
94
111
  }
95
112
  }
96
113
 
114
+ _resize() {
115
+ this.$wrapper.css({'max-width': 'none', 'min-height': 'none'});
116
+ // _getMaxDims has side effects (boo) but calling it should update all other necessary heights & widths
117
+ this.$wrapper.css(this._getMaxDims());
118
+ }
119
+
97
120
  /**
98
121
  * Adds event handlers to elements in the menu.
99
122
  * @function
@@ -124,6 +147,37 @@ class Drilldown {
124
147
  $body.off('.zf.drilldown');
125
148
  });
126
149
  }
150
+ });
151
+ this.$element.on('mutateme.zf.trigger', this._resize.bind(this));
152
+ }
153
+
154
+ /**
155
+ * Adds event handlers to the menu element.
156
+ * @function
157
+ * @private
158
+ */
159
+ _registerEvents() {
160
+ if(this.options.scrollTop){
161
+ this._bindHandler = this._scrollTop.bind(this);
162
+ this.$element.on('open.zf.drilldown hide.zf.drilldown closed.zf.drilldown',this._bindHandler);
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Scroll to Top of Element or data-scroll-top-element
168
+ * @function
169
+ * @fires Drilldown#scrollme
170
+ */
171
+ _scrollTop() {
172
+ var _this = this;
173
+ var $scrollTopElement = _this.options.scrollTopElement!=''?$(_this.options.scrollTopElement):_this.$element,
174
+ scrollPos = parseInt($scrollTopElement.offset().top+_this.options.scrollTopOffset);
175
+ $('html, body').stop(true).animate({ scrollTop: scrollPos }, _this.options.animationDuration, _this.options.animationEasing,function(){
176
+ /**
177
+ * Fires after the menu has scrolled
178
+ * @event Drilldown#scrollme
179
+ */
180
+ if(this===$('html')[0])_this.$element.trigger('scrollme.zf.drilldown');
127
181
  });
128
182
  }
129
183
 
@@ -134,8 +188,7 @@ class Drilldown {
134
188
  _keyboardEvents() {
135
189
  var _this = this;
136
190
 
137
- this.$menuItems.add(this.$element.find('.js-drilldown-back > a')).on('keydown.zf.drilldown', function(e){
138
-
191
+ this.$menuItems.add(this.$element.find('.js-drilldown-back > a, .is-submenu-parent-item > a')).on('keydown.zf.drilldown', function(e){
139
192
  var $element = $(this),
140
193
  $elements = $element.parent('li').parent('ul').children('li').children('a'),
141
194
  $prevElement,
@@ -188,7 +241,7 @@ class Drilldown {
188
241
  $element.parent('li').parent('ul').parent('li').children('a').first().focus();
189
242
  }, 1);
190
243
  });
191
- return true;
244
+ return true;
192
245
  } else if ($element.is(_this.$submenuAnchors)) {
193
246
  _this._show($element.parent('li'));
194
247
  $element.parent('li').one(Foundation.transitionend($element), function(){
@@ -214,6 +267,7 @@ class Drilldown {
214
267
  */
215
268
  _hideAll() {
216
269
  var $elem = this.$element.find('.is-drilldown-submenu.is-active').addClass('is-closing');
270
+ if(this.options.autoHeight) this.$wrapper.css({height:$elem.parent().closest('ul').data('calcHeight')});
217
271
  $elem.one(Foundation.transitionend($elem), function(e){
218
272
  $elem.removeClass('is-active is-closing');
219
273
  });
@@ -241,7 +295,7 @@ class Drilldown {
241
295
 
242
296
  // If there is a parent submenu, call show
243
297
  let parentSubMenu = $elem.parent('li').parent('ul').parent('li');
244
- if (parentSubMenu.length) {
298
+ if (parentSubMenu.length) {
245
299
  _this._show(parentSubMenu);
246
300
  }
247
301
  });
@@ -271,6 +325,7 @@ class Drilldown {
271
325
  * @param {jQuery} $elem - the current element with a submenu to open, i.e. the `li` tag.
272
326
  */
273
327
  _show($elem) {
328
+ if(this.options.autoHeight) this.$wrapper.css({height:$elem.children('[data-submenu]').data('calcHeight')});
274
329
  $elem.attr('aria-expanded', true);
275
330
  $elem.children('[data-submenu]').addClass('is-active').attr('aria-hidden', false);
276
331
  /**
@@ -287,9 +342,11 @@ class Drilldown {
287
342
  * @param {jQuery} $elem - the current sub-menu to hide, i.e. the `ul` tag.
288
343
  */
289
344
  _hide($elem) {
345
+ if(this.options.autoHeight) this.$wrapper.css({height:$elem.parent().closest('ul').data('calcHeight')});
290
346
  var _this = this;
291
347
  $elem.parent('li').attr('aria-expanded', false);
292
348
  $elem.attr('aria-hidden', true).addClass('is-closing')
349
+ $elem.addClass('is-closing')
293
350
  .one(Foundation.transitionend($elem), function(){
294
351
  $elem.removeClass('is-active is-closing');
295
352
  $elem.blur();
@@ -308,15 +365,19 @@ class Drilldown {
308
365
  * @private
309
366
  */
310
367
  _getMaxDims() {
311
- var biggest = 0
312
- var result = {};
313
-
314
- this.$submenus.add(this.$element).each((i, elem) => {
315
- var height = elem.getBoundingClientRect().height;
316
- if (height > biggest) biggest = height;
368
+ var maxHeight = 0, result = {}, _this = this;
369
+ this.$submenus.add(this.$element).each(function(){
370
+ var numOfElems = $(this).children('li').length;
371
+ var height = Foundation.Box.GetDimensions(this).height;
372
+ maxHeight = height > maxHeight ? height : maxHeight;
373
+ if(_this.options.autoHeight) {
374
+ $(this).data('calcHeight',height);
375
+ if (!$(this).hasClass('is-drilldown-submenu')) result['height'] = height;
376
+ }
317
377
  });
318
378
 
319
- result['min-height'] = `${biggest}px`;
379
+ if(!this.options.autoHeight) result['min-height'] = `${maxHeight}px`;
380
+
320
381
  result['max-width'] = `${this.$element[0].getBoundingClientRect().width}px`;
321
382
 
322
383
  return result;
@@ -327,7 +388,9 @@ class Drilldown {
327
388
  * @function
328
389
  */
329
390
  destroy() {
391
+ if(this.options.scrollTop) this.$element.off('.zf.drilldown',this._bindHandler);
330
392
  this._hideAll();
393
+ this.$element.off('mutateme.zf.trigger');
331
394
  Foundation.Nest.Burn(this.$element, 'drilldown');
332
395
  this.$element.unwrap()
333
396
  .find('.js-drilldown-back, .is-submenu-parent-item').remove()
@@ -336,6 +399,9 @@ class Drilldown {
336
399
  this.$submenuAnchors.each(function() {
337
400
  $(this).off('.zf.drilldown');
338
401
  });
402
+
403
+ this.$submenus.removeClass('drilldown-submenu-cover-previous');
404
+
339
405
  this.$element.find('a').each(function(){
340
406
  var $link = $(this);
341
407
  $link.removeAttr('tabindex');
@@ -349,11 +415,17 @@ class Drilldown {
349
415
 
350
416
  Drilldown.defaults = {
351
417
  /**
352
- * Markup used for JS generated back button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting.
418
+ * Markup used for JS generated back button. Prepended or appended (see backButtonPosition) to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting.
353
419
  * @option
354
420
  * @example '<\li><\a>Back<\/a><\/li>'
355
421
  */
356
422
  backButton: '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>',
423
+ /**
424
+ * Position the back button either at the top or bottom of drilldown submenus.
425
+ * @option
426
+ * @example bottom
427
+ */
428
+ backButtonPosition: 'top',
357
429
  /**
358
430
  * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
359
431
  * @option
@@ -371,7 +443,49 @@ Drilldown.defaults = {
371
443
  * @option
372
444
  * @example false
373
445
  */
374
- closeOnClick: false
446
+ closeOnClick: false,
447
+ /**
448
+ * Allow the menu to auto adjust height.
449
+ * @option
450
+ * @example false
451
+ */
452
+ autoHeight: false,
453
+ /**
454
+ * Animate the auto adjust height.
455
+ * @option
456
+ * @example false
457
+ */
458
+ animateHeight: false,
459
+ /**
460
+ * Scroll to the top of the menu after opening a submenu or navigating back using the menu back button
461
+ * @option
462
+ * @example false
463
+ */
464
+ scrollTop: false,
465
+ /**
466
+ * String jquery selector (for example 'body') of element to take offset().top from, if empty string the drilldown menu offset().top is taken
467
+ * @option
468
+ * @example ''
469
+ */
470
+ scrollTopElement: '',
471
+ /**
472
+ * ScrollTop offset
473
+ * @option
474
+ * @example 100
475
+ */
476
+ scrollTopOffset: 0,
477
+ /**
478
+ * Scroll animation duration
479
+ * @option
480
+ * @example 500
481
+ */
482
+ animationDuration: 500,
483
+ /**
484
+ * Scroll animation easing
485
+ * @option
486
+ * @example 'swing'
487
+ */
488
+ animationEasing: 'swing'
375
489
  // holdOpen: false
376
490
  };
377
491