Last active
June 13, 2019 14:37
-
-
Save stewartknapman/6596812a4122ec92d686f943c9bcf2a2 to your computer and use it in GitHub Desktop.
Tabs for use with Debut
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="description-tabs" data-tabs> | |
<!-- Tab header and content. Repeat for each tab. --> | |
<div class="description-tab__header"> | |
<h4> | |
<a href="#tab1" data-tab-target="#tab1" data-tab-active> <!-- Only add data-tab-active to the one active tab you want to show first --> | |
<span>Tab 1 title</span> | |
</a> | |
</h4> | |
</div> | |
<div class="description-tab__content-wrapper" id="tab1"> | |
<div class="description-tab__content"> | |
Tab 1 content | |
</div> | |
</div> | |
<!-- end tab header and content --> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
if (!document.querySelector && !window.addEventListener && !("classList" in document.createElement("p"))) return; | |
var ready = function (callback, ctx) { | |
if (typeof callback !== 'function') return; | |
if (document.readyState !== "loading") { | |
callback.apply(ctx); | |
} else { | |
document.addEventListener("DOMContentLoaded", function () { | |
callback.apply(ctx); | |
}); | |
} | |
}; | |
var each = function (arr, callback, ctx) { | |
var r; | |
for (var i = 0; i < arr.length; i++) { | |
ctx = ctx || arr[i]; | |
r = callback.apply(ctx, [arr[i], i]); | |
if (r == false) break; | |
} | |
}; | |
/* Description Tab */ | |
var Tabs = function (ele) { | |
this.ele = ele; | |
this.selectors = { | |
actions: '[data-tab-target]', | |
active: '[data-tab-active]' | |
}; | |
this.classes = { | |
hasTabs: 'has-tabs' | |
}; | |
this.attributes = { | |
active: 'data-tab-active', | |
target: 'data-tab-target' | |
}; | |
this.hasHistoryState = false; | |
this.allowOpenTabToBeClosed = false; // Like an accordion | |
}; | |
Tabs.prototype.init = function () { | |
if (!this.ele) return; | |
this.actions = this.ele.querySelectorAll(this.selectors.actions); | |
if (this.actions.length) { | |
var active = this.ele.querySelector(this.selectors.active) || this.actions[0]; | |
document.documentElement.classList.add(this.classes.hasTabs); | |
this._addEventListeners(); | |
this.closeAllTabs(); | |
this.openTab(active); | |
this.scrollToActive(); | |
} | |
}; | |
Tabs.prototype.openTab = function (ele) { | |
this.active = ele; | |
ele.setAttribute(this.attributes.active, ''); | |
var targetStr = ele.getAttribute(this.attributes.target); | |
var targets = this.ele.querySelectorAll(targetStr); | |
each(targets, function (target) { | |
target.style.display = 'block'; | |
}); | |
}; | |
Tabs.prototype.closeTab = function (ele) { | |
ele.removeAttribute(this.attributes.active); | |
var targetStr = ele.getAttribute(this.attributes.target); | |
var targets = this.ele.querySelectorAll(targetStr); | |
each(targets, function (target) { | |
target.style.display = 'none'; | |
}); | |
}; | |
Tabs.prototype.closeAllTabs = function (currentTarget) { | |
var target, | |
targetStr, | |
_this = this; | |
this._eachAction(function (tabAction) { | |
if (_this.allowOpenTabToBeClosed) { | |
_this.closeTab(tabAction); | |
} else if (currentTarget != tabAction) { | |
_this.closeTab(tabAction); | |
} | |
}); | |
if (this.allowOpenTabToBeClosed) { | |
this.active = false; | |
} | |
}; | |
Tabs.prototype.scrollToActive = function () { | |
if (!!location.hash) { | |
active = this.ele.querySelector('[href="'+location.hash+'"]'); | |
} | |
}; | |
Tabs.prototype._updateHash = function (hash) { | |
if (history.pushState) { | |
history.pushState(null, null, hash); | |
} else { | |
location.hash = hash; | |
} | |
}; | |
Tabs.prototype._addEventListeners = function () { | |
var _this = this; | |
this._eachAction(function (tabAction) { | |
tabAction.addEventListener('click', function (e) { | |
e.preventDefault(); | |
_this._onClick(e.currentTarget); | |
}); | |
}); | |
}; | |
Tabs.prototype._onClick = function (currentTarget) { | |
var lastActive = this.active; | |
this.closeAllTabs(currentTarget); | |
if (currentTarget !== lastActive) { | |
// only open the tab if it wasn't already open | |
this.openTab(currentTarget); | |
} | |
if (this.hasHistoryState) { | |
this._updateHash(currentTarget.getAttribute('href')); | |
} | |
currentTarget.blur(); | |
}; | |
Tabs.prototype._eachAction = function (callback) { | |
for (var i = 0; i < this.actions.length; i++) { | |
callback(this.actions[i]); | |
} | |
}; | |
/* Description Tabs */ | |
var TabGroups = function () { | |
this.selectors = { | |
ele: '[data-tabs]' | |
}; | |
this.init(); | |
}; | |
TabGroups.prototype.init = function () { | |
var tab, | |
_this = this; | |
this.eles = document.querySelectorAll(this.selectors.ele); | |
each(this.eles, function (ele) { | |
tab = new Tabs(ele); | |
tab.init(); | |
}); | |
} | |
// Run everything | |
ready(function () { | |
new TabGroups(); | |
}); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.description-tab__header { | |
padding-top: 1.5em; | |
.no-js &:first-child { | |
padding-top: 0; | |
} | |
} | |
.has-tabs { | |
.description-tabs { | |
position: relative; | |
@include display-flexbox(); | |
@include flex-direction(row); | |
@include flex-wrap(wrap); | |
margin: 1.5em 0; | |
} | |
.description-tab__header { | |
@include flex(1 1 100%); | |
width: 100%; | |
padding: 0; | |
@media (min-width: 60em) { | |
@include flex(1 1 6em); | |
order: 0; | |
width: auto; | |
text-align: center; | |
&:first-child { | |
text-align: left; | |
} | |
&:nth-last-child(2) { | |
text-align: right; | |
} | |
} | |
h4 { | |
height: 100%; | |
margin-bottom: 0; | |
font-size: 1.25em; | |
} | |
a { | |
display: block; | |
height: 100%; | |
padding: 0.5em 0; | |
border-bottom: none; | |
color: $color-body-text--light; | |
&:hover, | |
&[data-tab-active] { | |
color: $color-body-text; | |
} | |
} | |
a > span { | |
display: block; | |
position: relative; | |
top: 50%; | |
-moz-transform: translateY(-50%); | |
-ms-transform: translateY(-50%); | |
transform: translateY(-50%); | |
} | |
} | |
.description-tab__content-wrapper { | |
width: 100%; | |
padding-bottom: 1.5em; | |
@media (min-width: 60em) { | |
order: 1; | |
padding-bottom: 0; | |
} | |
} | |
.description-tab__content { | |
@extend .rte; | |
max-width: 40em; | |
} | |
.description-tab__content--wide { | |
max-width: none; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment