Skip to content

Commit 87e8f84

Browse files
author
AMJones
committed
Adds tab overflow js.
1 parent 992dbc6 commit 87e8f84

File tree

5 files changed

+190
-26
lines changed

5 files changed

+190
-26
lines changed

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"layout"
1010
],
1111
"homepage": "https://www.github.com/strapless/layout",
12-
"version": "1.1.1",
12+
"version": "1.1.2",
1313
"authors": [
1414
{
1515
"name": "Aaron M Jones",
@@ -19,6 +19,7 @@
1919
"license": "MIT",
2020
"require": {
2121
"strapless/colors": "^1.0",
22-
"strapless/base": "^1.1"
22+
"strapless/base": "^1.1",
23+
"strapless/icons": "^1.0"
2324
}
2425
}

composer.lock

Lines changed: 52 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/tab-scroll.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/**
2+
* jQuery plugin to handle width overflow of bootstrap tabs in a manner similar to tab handling on Android.
3+
*
4+
* @version v1.1.2
5+
* @license https://github.com/strapless/layout/LICENSE
6+
* @author Aaron M Jones <am@jonesiscoding.com>
7+
*/
8+
(function($) {
9+
10+
$.tabScroll = function(element, options) {
11+
12+
var defaults = {
13+
cls: {
14+
'toggle': 'dropdown-toggle',
15+
'wrapper': 'dropdown',
16+
'dropdown': 'dropdown-menu',
17+
'open': 'open',
18+
'marker': 'overflow-item'
19+
}
20+
};
21+
22+
var plugin = this;
23+
24+
/**
25+
* @type object
26+
*/
27+
plugin.settings = {};
28+
29+
var $el = $(element);
30+
31+
plugin.init = function() {
32+
33+
plugin.settings = $.extend({}, defaults, options);
34+
35+
$(window).afterwards('resize', function () {
36+
plugin.toggleMarker(plugin.hasOverflow());
37+
});
38+
39+
$(document).on('show.bs.dropdown', '[data-overflow="true"]', function(e) {
40+
var $dropdown = $(e.target).find(plugin.settings.cls.dropdown);
41+
var $trigger = $dropdown.parent('.' + plugin.settings.cls.wrapper).find('.' + plugin.settings.cls.toggle);
42+
var top = $trigger.offset().top + $trigger.outerHeight();
43+
var left = $trigger.offset().left;
44+
$dropdown.appendTo('body').css({left: left + 'px', top: top + 'px', 'max-height': 'calc(90vh - ' + top + 'px)', 'overflow-y': 'scroll' });
45+
$('body').addClass(plugin.settings.cls.open);
46+
$(this).on('hidden.bs.dropdown', function () {
47+
$dropdown.appendTo(e.target).css({});
48+
$('body').removeClass(plugin.settings.cls.open);
49+
})
50+
});
51+
52+
if (!$(document).hasClass('.touch')) {
53+
$el.on('click', '.' + plugin.settings.cls.marker, function(e) { plugin.onClick(e); });
54+
}
55+
56+
plugin.toggleMarker(plugin.hasOverflow());
57+
};
58+
59+
/**
60+
* @returns {boolean}
61+
*/
62+
plugin.hasOverflow = function() {
63+
var width = $el.innerWidth();
64+
var childWidth = 0;
65+
$el.children('li').each(function() {
66+
childWidth = childWidth + $(this).innerWidth();
67+
});
68+
69+
return (width && width < childWidth);
70+
};
71+
72+
/**
73+
* @param status
74+
*/
75+
plugin.toggleMarker = function(status) {
76+
var sel = '.' + plugin.settings.cls.marker;
77+
var $marker = $el.find(sel);
78+
var hasMarker = (0 === $marker.length);
79+
if(status !== false) {
80+
if(hasMarker) {
81+
$marker = $('<span></span>');
82+
$marker.addClass(plugin.settings.cls.marker).appendTo($el);
83+
$el.on('scroll', function() {
84+
var left = $el.innerWidth() + $el.scrollLeft();
85+
$marker.css('left',left);
86+
});
87+
} else {
88+
$marker.show();
89+
}
90+
} else {
91+
if(hasMarker) {
92+
$marker.hide();
93+
}
94+
}
95+
};
96+
97+
/**
98+
* @param e The click event.
99+
*/
100+
plugin.onClick = function(e) {
101+
e.preventDefault();
102+
var leftPos = $el.scrollLeft();
103+
$el.animate({scrollLeft: leftPos + 200}, 800);
104+
};
105+
106+
plugin.init();
107+
108+
};
109+
110+
/**
111+
* @param options
112+
* @returns {*}
113+
*/
114+
$.fn.tabScroll = function(options) {
115+
return this.each(function() {
116+
if (undefined === $(this).data('tabScroll')) {
117+
var plugin = new $.tabScroll(this, options);
118+
$(this).data('tabScroll', plugin);
119+
}
120+
});
121+
};
122+
})(jQuery);

scss/_header.scss

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -206,21 +206,20 @@ header {
206206
}
207207

208208
.nav-tabs[data-overflow] {
209-
position: relative;
209+
position: relative; // Constrain the icon
210210
display: flex;
211-
flex-direction: row;
212-
flex-wrap: nowrap;
211+
flex-flow: row nowrap;
213212
flex: 1 0 auto;
214-
overflow-x: scroll;
215-
overflow-y: hidden;
216-
// Hide Scrollbar in Edge
217-
-ms-overflow-style: none !important;
218-
// Hide Scrollbar in Chrome, Safari
219-
&::-webkit-scrollbar {
220-
display: none;
213+
overflow: auto;
214+
-ms-overflow-style: none !important; // Hide Scrollbar in Edge
215+
&::-webkit-scrollbar { display: none; } // Hide Scrollbar in Chrome, Safari
216+
> .nav-item {
217+
// Each item should take all the space it needs.
218+
flex-shrink: 0 !important;
221219
}
222-
&::after {
223-
display: inline-block;
220+
> .overflow-item {
221+
// Overflow indicator
222+
display: block;
224223
content: ' ';
225224
position: absolute;
226225
width: 8px;
@@ -230,3 +229,4 @@ header {
230229
margin-top: -4px;
231230
}
232231
}
232+

scss/_layout-mixins.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
}
6161
}
6262

63-
.nav-tabs[data-overflow]::after {
63+
.nav-tabs[data-overflow] > .overflow-item {
6464
background: transparent inline-svg($indicator) center center / 8px 8px no-repeat;
6565
}
6666
}

0 commit comments

Comments
 (0)