@dontgoplastic/tab-nav
Advanced tools
Comparing version 0.0.2 to 0.0.3
@@ -1,2 +0,2 @@ | ||
function t(t,e){t.setAttribute("tabindex",e)}function e(t,e){t.setAttribute("aria-selected",e)}function i(t,e){t.setAttribute("role",e)}var s=0;function n(t){var e=t.getAttribute("id");if(e)return e;var i="auto-id-"+(new Date).getTime()+"-"+(s+=1);return t.setAttribute("id",i),i}function o(t){return t instanceof Element?t:document.querySelector(t)}var a={RETURN:13,SPACE_BAR:32,LEFT:37,RIGHT:39,UP:38,DOWN:40},c=function(t,e){var i=this;void 0===e&&(e={}),t=o(t),this.options=Object.assign({},{activeClass:"active",onItemClick:null},e);var s=this.options,n=s.activeClass,c=s.onItemClick;this.el=t,this.items=Array.from(t.children);var r=this.items.find(function(t){return t.classList.contains(n)})||this.items[0];this.el.addEventListener("keydown",function(t){var e=t.target;switch(t.keyCode){case a.LEFT:case a.UP:i.focusPrevious(e);break;case a.RIGHT:case a.DOWN:i.focusNext(e);break;case a.RETURN:case a.SPACE_BAR:e.click()}}),this.items.forEach(function(t){t.addEventListener("blur",function(t){var e=t.relatedTarget;i.el.contains(e)||i.updateTabIndexes()}),t.addEventListener("click",function(){i.setActiveItem(t),c&&c(t,i)})}),this.setActiveItem(r)};c.prototype.getItems=function(){return this.items},c.prototype.getActiveItem=function(){return this.items[this.activeIndex]},c.prototype.focusPrevious=function(t){var e=this.items.indexOf(t),i=0===e?this.items.length-1:e-1;this.focusItem(this.items[i])},c.prototype.focusNext=function(t){var e=this.items.indexOf(t),i=e===this.items.length-1?0:e+1;this.focusItem(this.items[i])},c.prototype.focusItem=function(i){this.items.forEach(function(s){e(s,s===i),t(s,-1)}),i.focus()},c.prototype.setActiveItem=function(t){var e=this.items.indexOf(t);this.setActiveIndex(e)},c.prototype.setActiveIndex=function(t){t!==this.activeIndex&&(this.activeIndex=t,this.updateTabIndexes())},c.prototype.updateTabIndexes=function(){var i=this.activeIndex,s=this.options.activeClass;this.items.forEach(function(n,o){var a=o===i;n.classList.toggle(s,a),e(n,a),t(n,a?0:-1)})};var r=function(e,s){var a=this;void 0===s&&(s={}),i(e=o(e),"tablist");var r=new c(e,{onItemClick:this.onTabClick.bind(this)});this.contentsByTab=new Map,r.getItems().forEach(function(e){var s=n(e),o=e.dataset.tabContentId,c=document.querySelector("#"+o);e.setAttribute("aria-controls",o),i(e,"tab"),c.setAttribute("aria-labelledby",s),i(c,"tabpanel"),t(c,0),a.contentsByTab.set(e,c)}),this.onTabClick(r.getActiveItem())};r.prototype.onTabClick=function(t){this.contentsByTab.forEach(function(e,i){var s=i===t;i.setAttribute("aria-expanded",s),e.style.display=s?"":"none"})};export default r; | ||
function t(t,e){t.setAttribute("tabindex",e)}function e(t,e){t.setAttribute("aria-selected",e)}function i(t,e){t.setAttribute("role",e)}var n=0;function s(t){var e=t.getAttribute("id");if(e)return e;var i="auto-id-"+(new Date).getTime()+"-"+(n+=1);return t.setAttribute("id",i),i}function a(t){return t instanceof Element?t:document.querySelector(t)}var o={RETURN:13,SPACE_BAR:32,LEFT:37,RIGHT:39,UP:38,DOWN:40},r={activeClass:"active",onChange:null},c=function(t,e){var i=this;void 0===e&&(e={});var s=a(t);this.options=Object.assign({},r,e),this.el=s,this.items=Array.from(s.children),this.el.addEventListener("keydown",function(t){var e=t.target;switch(t.keyCode){case o.LEFT:case o.UP:i.focusPrevious(e);break;case o.RIGHT:case o.DOWN:i.focusNext(e);break;case o.RETURN:case o.SPACE_BAR:e.click()}}),this.items.forEach(function(t){t.addEventListener("blur",function(t){var e=t.relatedTarget;i.el.contains(e)||i.updateTabIndexes()}),t.addEventListener("click",function(){i.setActiveItem(t)})})};c.prototype.trigger=function(){var t=this.options.activeClass,e=this.items.find(function(e){return e.classList.contains(t)})||this.items[0];this.setActiveItem(e)},c.prototype.getItems=function(){return this.items},c.prototype.getActiveItem=function(){return this.items[this.activeIndex]},c.prototype.focusPrevious=function(t){var e=this.items.indexOf(t),i=0===e?this.items.length-1:e-1;this.focusItem(this.items[i])},c.prototype.focusNext=function(t){var e=this.items.indexOf(t),i=e===this.items.length-1?0:e+1;this.focusItem(this.items[i])},c.prototype.focusItem=function(i){this.items.forEach(function(s){e(s,s===i),t(s,-1)}),i.focus()},c.prototype.setActiveItem=function(t){var e=this.items.indexOf(t);this.setActiveIndex(e)},c.prototype.setActiveIndex=function(t){if(t!==this.activeIndex){this.activeIndex=t,this.updateTabIndexes();var e=this.options.onChange;e&&e(this.getActiveItem())}},c.prototype.updateTabIndexes=function(){var i=this.activeIndex,s=this.options.activeClass;this.items.forEach(function(n,a){var o=a===i;n.classList.toggle(s,o),e(n,o),t(n,o?0:-1)})};var u={activeClass:"active",onChange:null},h=function(e,n){var o=this;void 0===n&&(n={}),this.options=Object.assign({},u,n);var r=this.options.activeClass,h=a(e);i(h,"tablist");var f=new c(h,{activeClass:r,onChange:this.onTabChange.bind(this)});this.contentsByTab=new Map,f.getItems().forEach(function(e){var n=s(e),a=e.dataset.tabContentId,r=document.querySelector("#"+a);e.setAttribute("aria-controls",a),i(e,"tab"),r.setAttribute("aria-labelledby",n),i(r,"tabpanel"),t(r,0),o.contentsByTab.set(e,r)}),f.trigger()};h.prototype.onTabChange=function(t){var e=this.options.onChange,i=null;this.contentsByTab.forEach(function(e,s){var n=s===t;n&&(i=e),s.setAttribute("aria-expanded",n),e.style.setProperty("display",n?"":"none")}),e&&e(t,i)};export default h; | ||
//# sourceMappingURL=tab-nav.es.js.map |
@@ -1,2 +0,2 @@ | ||
function t(t,e){t.setAttribute("tabindex",e)}function e(t,e){t.setAttribute("aria-selected",e)}function i(t,e){t.setAttribute("role",e)}var s=0;function n(t){var e=t.getAttribute("id");if(e)return e;var i="auto-id-"+(new Date).getTime()+"-"+(s+=1);return t.setAttribute("id",i),i}function o(t){return t instanceof Element?t:document.querySelector(t)}var a={RETURN:13,SPACE_BAR:32,LEFT:37,RIGHT:39,UP:38,DOWN:40},c=function(t,e){var i=this;void 0===e&&(e={}),t=o(t),this.options=Object.assign({},{activeClass:"active",onItemClick:null},e);var s=this.options,n=s.activeClass,c=s.onItemClick;this.el=t,this.items=Array.from(t.children);var r=this.items.find(function(t){return t.classList.contains(n)})||this.items[0];this.el.addEventListener("keydown",function(t){var e=t.target;switch(t.keyCode){case a.LEFT:case a.UP:i.focusPrevious(e);break;case a.RIGHT:case a.DOWN:i.focusNext(e);break;case a.RETURN:case a.SPACE_BAR:e.click()}}),this.items.forEach(function(t){t.addEventListener("blur",function(t){var e=t.relatedTarget;i.el.contains(e)||i.updateTabIndexes()}),t.addEventListener("click",function(){i.setActiveItem(t),c&&c(t,i)})}),this.setActiveItem(r)};c.prototype.getItems=function(){return this.items},c.prototype.getActiveItem=function(){return this.items[this.activeIndex]},c.prototype.focusPrevious=function(t){var e=this.items.indexOf(t),i=0===e?this.items.length-1:e-1;this.focusItem(this.items[i])},c.prototype.focusNext=function(t){var e=this.items.indexOf(t),i=e===this.items.length-1?0:e+1;this.focusItem(this.items[i])},c.prototype.focusItem=function(i){this.items.forEach(function(s){e(s,s===i),t(s,-1)}),i.focus()},c.prototype.setActiveItem=function(t){var e=this.items.indexOf(t);this.setActiveIndex(e)},c.prototype.setActiveIndex=function(t){t!==this.activeIndex&&(this.activeIndex=t,this.updateTabIndexes())},c.prototype.updateTabIndexes=function(){var i=this.activeIndex,s=this.options.activeClass;this.items.forEach(function(n,o){var a=o===i;n.classList.toggle(s,a),e(n,a),t(n,a?0:-1)})};var r=function(e,s){var a=this;void 0===s&&(s={}),i(e=o(e),"tablist");var r=new c(e,{onItemClick:this.onTabClick.bind(this)});this.contentsByTab=new Map,r.getItems().forEach(function(e){var s=n(e),o=e.dataset.tabContentId,c=document.querySelector("#"+o);e.setAttribute("aria-controls",o),i(e,"tab"),c.setAttribute("aria-labelledby",s),i(c,"tabpanel"),t(c,0),a.contentsByTab.set(e,c)}),this.onTabClick(r.getActiveItem())};r.prototype.onTabClick=function(t){this.contentsByTab.forEach(function(e,i){var s=i===t;i.setAttribute("aria-expanded",s),e.style.display=s?"":"none"})},module.exports=r; | ||
function t(t,e){t.setAttribute("tabindex",e)}function e(t,e){t.setAttribute("aria-selected",e)}function i(t,e){t.setAttribute("role",e)}var s=0;function n(t){var e=t.getAttribute("id");if(e)return e;var i="auto-id-"+(new Date).getTime()+"-"+(s+=1);return t.setAttribute("id",i),i}function a(t){return t instanceof Element?t:document.querySelector(t)}var o={RETURN:13,SPACE_BAR:32,LEFT:37,RIGHT:39,UP:38,DOWN:40},r={activeClass:"active",onChange:null},c=function(t,e){var i=this;void 0===e&&(e={});var s=a(t);this.options=Object.assign({},r,e),this.el=s,this.items=Array.from(s.children),this.el.addEventListener("keydown",function(t){var e=t.target;switch(t.keyCode){case o.LEFT:case o.UP:i.focusPrevious(e);break;case o.RIGHT:case o.DOWN:i.focusNext(e);break;case o.RETURN:case o.SPACE_BAR:e.click()}}),this.items.forEach(function(t){t.addEventListener("blur",function(t){var e=t.relatedTarget;i.el.contains(e)||i.updateTabIndexes()}),t.addEventListener("click",function(){i.setActiveItem(t)})})};c.prototype.trigger=function(){var t=this.options.activeClass,e=this.items.find(function(e){return e.classList.contains(t)})||this.items[0];this.setActiveItem(e)},c.prototype.getItems=function(){return this.items},c.prototype.getActiveItem=function(){return this.items[this.activeIndex]},c.prototype.focusPrevious=function(t){var e=this.items.indexOf(t),i=0===e?this.items.length-1:e-1;this.focusItem(this.items[i])},c.prototype.focusNext=function(t){var e=this.items.indexOf(t),i=e===this.items.length-1?0:e+1;this.focusItem(this.items[i])},c.prototype.focusItem=function(i){this.items.forEach(function(s){e(s,s===i),t(s,-1)}),i.focus()},c.prototype.setActiveItem=function(t){var e=this.items.indexOf(t);this.setActiveIndex(e)},c.prototype.setActiveIndex=function(t){if(t!==this.activeIndex){this.activeIndex=t,this.updateTabIndexes();var e=this.options.onChange;e&&e(this.getActiveItem())}},c.prototype.updateTabIndexes=function(){var i=this.activeIndex,s=this.options.activeClass;this.items.forEach(function(n,a){var o=a===i;n.classList.toggle(s,o),e(n,o),t(n,o?0:-1)})};var u={activeClass:"active",onChange:null},h=function(e,s){var o=this;void 0===s&&(s={}),this.options=Object.assign({},u,s);var r=this.options.activeClass,h=a(e);i(h,"tablist");var v=new c(h,{activeClass:r,onChange:this.onTabChange.bind(this)});this.contentsByTab=new Map,v.getItems().forEach(function(e){var s=n(e),a=e.dataset.tabContentId,r=document.querySelector("#"+a);e.setAttribute("aria-controls",a),i(e,"tab"),r.setAttribute("aria-labelledby",s),i(r,"tabpanel"),t(r,0),o.contentsByTab.set(e,r)}),v.trigger()};h.prototype.onTabChange=function(t){var e=this.options.onChange,i=null;this.contentsByTab.forEach(function(e,s){var n=s===t;n&&(i=e),s.setAttribute("aria-expanded",n),e.style.setProperty("display",n?"":"none")}),e&&e(t,i)},module.exports=h; | ||
//# sourceMappingURL=tab-nav.js.map |
@@ -1,2 +0,2 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.TabNav=e()}(this,function(){function t(t,e){t.setAttribute("tabindex",e)}function e(t,e){t.setAttribute("aria-selected",e)}function i(t,e){t.setAttribute("role",e)}var n=0;function s(t){return t instanceof Element?t:document.querySelector(t)}var o=13,a=32,c=37,r=39,u=38,f=40,d=function(t,e){var i=this;void 0===e&&(e={}),t=s(t),this.options=Object.assign({},{activeClass:"active",onItemClick:null},e);var n=this.options,d=n.activeClass,h=n.onItemClick;this.el=t,this.items=Array.from(t.children);var v=this.items.find(function(t){return t.classList.contains(d)})||this.items[0];this.el.addEventListener("keydown",function(t){var e=t.target;switch(t.keyCode){case c:case u:i.focusPrevious(e);break;case r:case f:i.focusNext(e);break;case o:case a:e.click()}}),this.items.forEach(function(t){t.addEventListener("blur",function(t){var e=t.relatedTarget;i.el.contains(e)||i.updateTabIndexes()}),t.addEventListener("click",function(){i.setActiveItem(t),h&&h(t,i)})}),this.setActiveItem(v)};d.prototype.getItems=function(){return this.items},d.prototype.getActiveItem=function(){return this.items[this.activeIndex]},d.prototype.focusPrevious=function(t){var e=this.items.indexOf(t),i=0===e?this.items.length-1:e-1;this.focusItem(this.items[i])},d.prototype.focusNext=function(t){var e=this.items.indexOf(t),i=e===this.items.length-1?0:e+1;this.focusItem(this.items[i])},d.prototype.focusItem=function(i){this.items.forEach(function(n){e(n,n===i),t(n,-1)}),i.focus()},d.prototype.setActiveItem=function(t){var e=this.items.indexOf(t);this.setActiveIndex(e)},d.prototype.setActiveIndex=function(t){t!==this.activeIndex&&(this.activeIndex=t,this.updateTabIndexes())},d.prototype.updateTabIndexes=function(){var i=this.activeIndex,n=this.options.activeClass;this.items.forEach(function(s,o){var a=o===i;s.classList.toggle(n,a),e(s,a),t(s,a?0:-1)})};var h=function(e,o){var a=this;void 0===o&&(o={}),i(e=s(e),"tablist");var c=new d(e,{onItemClick:this.onTabClick.bind(this)});this.contentsByTab=new Map,c.getItems().forEach(function(e){var s=function(t){var e=t.getAttribute("id");if(e)return e;var i="auto-id-"+(new Date).getTime()+"-"+(n+=1);return t.setAttribute("id",i),i}(e),o=e.dataset.tabContentId,c=document.querySelector("#"+o);e.setAttribute("aria-controls",o),i(e,"tab"),c.setAttribute("aria-labelledby",s),i(c,"tabpanel"),t(c,0),a.contentsByTab.set(e,c)}),this.onTabClick(c.getActiveItem())};return h.prototype.onTabClick=function(t){this.contentsByTab.forEach(function(e,i){var n=i===t;i.setAttribute("aria-expanded",n),e.style.display=n?"":"none"})},h}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.TabNav=e()}(this,function(){function t(t,e){t.setAttribute("tabindex",e)}function e(t,e){t.setAttribute("aria-selected",e)}function i(t,e){t.setAttribute("role",e)}var n=0;function s(t){return t instanceof Element?t:document.querySelector(t)}var o=13,a=32,r=37,c=39,u=38,f=40,h={activeClass:"active",onChange:null},d=function(t,e){var i=this;void 0===e&&(e={});var n=s(t);this.options=Object.assign({},h,e),this.el=n,this.items=Array.from(n.children),this.el.addEventListener("keydown",function(t){var e=t.target;switch(t.keyCode){case r:case u:i.focusPrevious(e);break;case c:case f:i.focusNext(e);break;case o:case a:e.click()}}),this.items.forEach(function(t){t.addEventListener("blur",function(t){var e=t.relatedTarget;i.el.contains(e)||i.updateTabIndexes()}),t.addEventListener("click",function(){i.setActiveItem(t)})})};d.prototype.trigger=function(){var t=this.options.activeClass,e=this.items.find(function(e){return e.classList.contains(t)})||this.items[0];this.setActiveItem(e)},d.prototype.getItems=function(){return this.items},d.prototype.getActiveItem=function(){return this.items[this.activeIndex]},d.prototype.focusPrevious=function(t){var e=this.items.indexOf(t),i=0===e?this.items.length-1:e-1;this.focusItem(this.items[i])},d.prototype.focusNext=function(t){var e=this.items.indexOf(t),i=e===this.items.length-1?0:e+1;this.focusItem(this.items[i])},d.prototype.focusItem=function(i){this.items.forEach(function(n){e(n,n===i),t(n,-1)}),i.focus()},d.prototype.setActiveItem=function(t){var e=this.items.indexOf(t);this.setActiveIndex(e)},d.prototype.setActiveIndex=function(t){if(t!==this.activeIndex){this.activeIndex=t,this.updateTabIndexes();var e=this.options.onChange;e&&e(this.getActiveItem())}},d.prototype.updateTabIndexes=function(){var i=this.activeIndex,n=this.options.activeClass;this.items.forEach(function(s,o){var a=o===i;s.classList.toggle(n,a),e(s,a),t(s,a?0:-1)})};var v={activeClass:"active",onChange:null},l=function(e,o){var a=this;void 0===o&&(o={}),this.options=Object.assign({},v,o);var r=this.options.activeClass,c=s(e);i(c,"tablist");var u=new d(c,{activeClass:r,onChange:this.onTabChange.bind(this)});this.contentsByTab=new Map,u.getItems().forEach(function(e){var s=function(t){var e=t.getAttribute("id");if(e)return e;var i="auto-id-"+(new Date).getTime()+"-"+(n+=1);return t.setAttribute("id",i),i}(e),o=e.dataset.tabContentId,r=document.querySelector("#"+o);e.setAttribute("aria-controls",o),i(e,"tab"),r.setAttribute("aria-labelledby",s),i(r,"tabpanel"),t(r,0),a.contentsByTab.set(e,r)}),u.trigger()};return l.prototype.onTabChange=function(t){var e=this.options.onChange,i=null;this.contentsByTab.forEach(function(e,n){var s=n===t;s&&(i=e),n.setAttribute("aria-expanded",s),e.style.setProperty("display",s?"":"none")}),e&&e(t,i)},l}); | ||
//# sourceMappingURL=tab-nav.umd.js.map |
{ | ||
"name": "@dontgoplastic/tab-nav", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "An accessible tab navigation component", | ||
@@ -22,2 +22,7 @@ "repository": "github:dontgoplastic/tab-nav", | ||
"devDependencies": { | ||
"eslint": "^4.16.0", | ||
"eslint-config-airbnb": "^16.1.0", | ||
"eslint-plugin-import": "^2.8.0", | ||
"eslint-plugin-jsx-a11y": "^6.0.3", | ||
"eslint-plugin-react": "^7.6.0", | ||
"microbundle": "^0.4.2" | ||
@@ -24,0 +29,0 @@ }, |
@@ -5,2 +5,55 @@ # tab-nav | ||
[Demo](https://dontgoplastic.github.io/tab-nav/demo) | ||
[Demo](https://dontgoplastic.github.io/tab-nav/demo) | ||
## How to use | ||
Create a list with corresponding content targets: | ||
```html | ||
<ul id="repo-nav"> | ||
<li data-tab-content-id="all">All</li> | ||
<li data-tab-content-id="public">Public</li> | ||
<li data-tab-content-id="private">Private</li> | ||
</ul> | ||
<section id="all"> ... </section> | ||
<section id="public"> ... </section> | ||
<section id="private"> ... </section> | ||
``` | ||
Kick off a TabNav: | ||
```js | ||
new TabNav('#repo-nav'); | ||
``` | ||
Instances can be configured with a few options: | ||
```js | ||
new TabNav('#repo-nav', { | ||
activeClass: 'active', | ||
onChange: (tabElement, contentElement) => { | ||
// ... | ||
} | ||
}); | ||
``` | ||
| Name | Default Value | Description | | ||
| --- | --- | --- | | ||
| activeClass | `'active'` | Class applied to expanded tabs | | ||
| onChange | `null` | Callback for when expaned tabs change. Provides the tab and revealed content target elements as arguments | | ||
## Styles | ||
Bring your own! | ||
## What it does | ||
* `role` attribute values `tablist`, `tab`, and `tabpanel` will be added to the list, list items, and content targets. | ||
* `tabindex="0"` added to the expanded tab and all content targets. | ||
* With a tab focused, <kbd>↑</kbd> or <kbd>←</kbd> will focus the previous tab, <kbd>↓</kbd> or <kbd>→</kbd> the next. | ||
* Tabs will be expanded on mouse click. Focused tabs will can be expanded by pressing either <kbd>Enter</kbd> or <kbd>Space</kbd>. | ||
* A tab with the `activeClass` (or the first tab if not present) will be auto-expanded. | ||
* All non-expanded content targets will be hidden via `display: none;`. | ||
* If ids aren't already present, unique ids are auto-assigned to all tabs and content targets to facilitate `aria-labelledby` and `aria-controls` hook-up. |
import { | ||
setTabIndex, | ||
setAriaSelected, | ||
identify, | ||
getElement, | ||
@@ -17,19 +16,17 @@ } from './utils'; | ||
const defaults = { | ||
activeClass: 'active', | ||
onChange: null, | ||
}; | ||
class FocusGroup { | ||
constructor(el, options = {}) { | ||
el = getElement(el); | ||
constructor(elOrSelector, options = {}) { | ||
const el = getElement(elOrSelector); | ||
this.options = Object.assign({}, { | ||
activeClass: 'active', | ||
onItemClick: null, | ||
}, options); | ||
const { activeClass, onItemClick } = this.options; | ||
this.options = Object.assign({}, defaults, options); | ||
this.el = el; | ||
this.items = Array.from(el.children); | ||
const activeItem = this.items.find(item => item.classList.contains(activeClass)) || this.items[0]; | ||
this.el.addEventListener('keydown', ({target, keyCode}) => { | ||
switch(keyCode) { | ||
this.el.addEventListener('keydown', ({ target, keyCode }) => { | ||
switch (keyCode) { | ||
case Key.LEFT: | ||
@@ -47,7 +44,9 @@ case Key.UP: | ||
break; | ||
default: | ||
break; | ||
} | ||
}); | ||
this.items.forEach(item => { | ||
item.addEventListener('blur', ({relatedTarget}) => { | ||
this.items.forEach((item) => { | ||
item.addEventListener('blur', ({ relatedTarget }) => { | ||
if (!this.el.contains(relatedTarget)) { | ||
@@ -57,11 +56,14 @@ this.updateTabIndexes(); | ||
}); | ||
item.addEventListener('click', () => { | ||
this.setActiveItem(item); | ||
if (onItemClick) { | ||
onItemClick(item, this); | ||
} | ||
}); | ||
}); | ||
} | ||
trigger() { | ||
const { activeClass } = this.options; | ||
const findActiveByClass = item => item.classList.contains(activeClass); | ||
const activeItem = this.items.find(findActiveByClass) || this.items[0]; | ||
this.setActiveItem(activeItem); | ||
@@ -99,3 +101,3 @@ } | ||
focusItem(item) { | ||
this.items.forEach(el => { | ||
this.items.forEach((el) => { | ||
setAriaSelected(el, el === item); | ||
@@ -120,2 +122,7 @@ setTabIndex(el, -1); | ||
this.updateTabIndexes(); | ||
const { onChange } = this.options; | ||
if (onChange) { | ||
onChange(this.getActiveItem()); | ||
} | ||
} | ||
@@ -135,6 +142,4 @@ | ||
} | ||
} | ||
export default FocusGroup; | ||
export default FocusGroup; |
@@ -9,10 +9,19 @@ import FocusGroup from './FocusGroup'; | ||
const defaults = { | ||
activeClass: 'active', | ||
onChange: null, | ||
}; | ||
class TabNav { | ||
constructor(el, options = {}) { | ||
el = getElement(el); | ||
constructor(elOrSelector, options = {}) { | ||
this.options = Object.assign({}, defaults, options); | ||
const { activeClass } = this.options; | ||
const el = getElement(elOrSelector); | ||
setRole(el, 'tablist'); | ||
const focusGroup = new FocusGroup(el, { | ||
onItemClick: this.onTabClick.bind(this) | ||
activeClass, | ||
onChange: this.onTabChange.bind(this), | ||
}); | ||
@@ -22,6 +31,6 @@ | ||
focusGroup.getItems().forEach(tab => { | ||
focusGroup.getItems().forEach((tab) => { | ||
const tabId = identify(tab); | ||
const contentId = tab.dataset.tabContentId; | ||
const content = document.querySelector('#' + contentId); | ||
const content = document.querySelector(`#${contentId}`); | ||
@@ -38,16 +47,26 @@ tab.setAttribute('aria-controls', contentId); | ||
this.onTabClick(focusGroup.getActiveItem()); | ||
focusGroup.trigger(); | ||
} | ||
onTabClick(item) { | ||
onTabChange(activeTab) { | ||
const { onChange } = this.options; | ||
let activeContent = null; | ||
this.contentsByTab.forEach((content, tab) => { | ||
const isActive = tab === item; | ||
const isActive = tab === activeTab; | ||
if (isActive) { | ||
activeContent = content; | ||
} | ||
tab.setAttribute('aria-expanded', isActive); | ||
content.style.display = isActive ? '' : 'none'; | ||
}) | ||
content.style.setProperty('display', isActive ? '' : 'none'); | ||
}); | ||
if (onChange) { | ||
onChange(activeTab, activeContent); | ||
} | ||
} | ||
} | ||
export default TabNav; | ||
export default TabNav; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
54524
232
58
6