Skip to content

Commit

Permalink
Bug/tabs bad markup (#262)
Browse files Browse the repository at this point in the history
* Make tabs more defensive against bad / missing markup

* Checks for complete panel markup before initialising tabset

* Update warning message
  • Loading branch information
sarah-storm authored Sep 20, 2024
1 parent de4775d commit 652b329
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 6 deletions.
23 changes: 22 additions & 1 deletion packages/tabs/__tests__/integrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ const init = (mode) => {
describe(`Tabs > Initialisation`, () => {

beforeAll(() => {init()});
console.log(TabSet)

it('should return array of length 1', async () => {
it('should return array of length 2', async () => {
expect(TabSet.length).toEqual(2);
});

Expand All @@ -66,6 +67,26 @@ describe(`Tabs > Initialisation`, () => {
});

});

describe(`Tabs > Initialisation no panel markup`, () => {

beforeAll(() => {
document.body.innerHTML = `
<div role="tablist">
<nav class="tabs__nav">
<a id="tab-4" class="tabs__nav-link js-tabs__link" href="#panel-4" role="tab">Tab 4</a>
</nav>
</div>`;

TabSet = tabs('[role=tablist]');
});

it('should return array of length 0', async () => {
expect(TabSet.length).toEqual(0);
});
});



describe(`Tabs > Accessibility > ARIA`, () => {

Expand Down
15 changes: 11 additions & 4 deletions packages/tabs/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@ export default (selector, options) => {
//return array of Objects, one for each DOM node found
//each Object has a prototype consisting of the node (HTMLElement),
//and a settings property composed from defaults, data-attributes on the node, and options passed to init
return nodes.map(node => Object.create(factory({
settings: { ...defaults, ...node.dataset, ...options },
node
})));
return nodes.map(node => {
const instance = factory({
settings: { ...defaults, ...node.dataset, ...options },
node
});
if(instance) {
return Object.create(instance);
} else {
console.warn("Tabset not initialised, required markup not found");
}
}).filter((instance) => typeof instance !== "undefined");
};
2 changes: 1 addition & 1 deletion packages/tabs/src/lib/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { KEYCODES, MODES } from './constants';
*/
export const findTabsAndPanels = (node, settings) => {
const tabs = [].slice.call(node.querySelectorAll(settings.tabSelector));
const panels = tabs.map(tab => document.getElementById(tab.getAttribute('href').substr(1)) || console.warn(`Tab panel for ${tab}`));
const panels = tabs.map(tab => document.getElementById(tab.getAttribute('href').substr(1)) || console.warn(`Tab panel not found for ${tab}`));
return { tabs, panels };
};

Expand Down
3 changes: 3 additions & 0 deletions packages/tabs/src/lib/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { getActiveIndexOnLoad } from './utils';
export default ({ node, settings }) => {
const Store = createStore();
const { tabs, panels } = findTabsAndPanels(node, settings);

if(!tabs.length || !panels.length || panels.includes(undefined)) return false;

const activeIndex = getActiveIndexOnLoad(panels, node);
Store.dispatch({
settings,
Expand Down

0 comments on commit 652b329

Please sign in to comment.