From bd5a4135ce0633e33d02cce77344b3e7d50adc77 Mon Sep 17 00:00:00 2001 From: Sarah Richards Date: Thu, 9 May 2024 13:06:12 +0100 Subject: [PATCH 1/2] Initial code updates --- packages/tabs/README.md | 8 ++++++++ packages/tabs/src/lib/factory.js | 4 ++-- packages/tabs/src/lib/utils.js | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/tabs/README.md b/packages/tabs/README.md index 051369b6..edc69032 100644 --- a/packages/tabs/README.md +++ b/packages/tabs/README.md @@ -64,6 +64,14 @@ const [ instance ] = tabs(elements); } ``` +## Setting the active tab +``` +On page load the active tab will be set by (in order of precedence): +1. The page hash. If the page hash in the address bar matches the ID of a panel, it will be activated on page load +2. The active class. If a panel element is found to have the active class on page load, it will be activated automatically +3. The tab specified by the activeIndex in the settings +4. The first tab in the set. + ## API tabs() returns an array of instances. Each instance exposes the interface diff --git a/packages/tabs/src/lib/factory.js b/packages/tabs/src/lib/factory.js index 346cdd6e..a724acaf 100644 --- a/packages/tabs/src/lib/factory.js +++ b/packages/tabs/src/lib/factory.js @@ -1,6 +1,6 @@ import { createStore } from './store'; import { findTabsAndPanels, initUI, open } from './dom'; -import { getActiveIndexByHash } from './utils'; +import { getActiveIndexOnLoad } from './utils'; /* * @param settings, Object, merged defaults + options passed in as instantiation config to module default @@ -11,7 +11,7 @@ import { getActiveIndexByHash } from './utils'; export default ({ node, settings }) => { const Store = createStore(); const { tabs, panels } = findTabsAndPanels(node, settings); - const activeIndex = getActiveIndexByHash(panels); + const activeIndex = getActiveIndexOnLoad(panels, settings); Store.dispatch({ settings, node, diff --git a/packages/tabs/src/lib/utils.js b/packages/tabs/src/lib/utils.js index 7fc06546..997d380c 100644 --- a/packages/tabs/src/lib/utils.js +++ b/packages/tabs/src/lib/utils.js @@ -8,6 +8,21 @@ export const getActiveIndexByHash = panels => { }, undefined); }; +export const getActiveIndexByClass = (panels, settings) => { + let activeIndex; + for(let i = 0; i <= panels.length-1; i++) { + if (panels[i].classList.contains(settings.activeClass)) { + activeIndex = i; + break; + } + } + return activeIndex; +}; + +export const getActiveIndexOnLoad = (panels, settings) => { + return (location.hash) ? getActiveIndexByHash(panels) : getActiveIndexByClass(panels, settings); +}; + /* * Converts a passed selector which can be of varying types into an array of DOM Objects * From 4dc9f511fca84ebdbe3c19d7a217457a7ff83fc5 Mon Sep 17 00:00:00 2001 From: Sarah Richards Date: Wed, 12 Jun 2024 14:28:06 +0100 Subject: [PATCH 2/2] Update to allow setting default tab based on data attribute --- packages/tabs/README.md | 4 +- packages/tabs/__tests__/unit/utils.js | 68 ++++++++++++++++++++++++++- packages/tabs/example/src/index.html | 6 +-- packages/tabs/src/lib/factory.js | 4 +- packages/tabs/src/lib/utils.js | 15 +----- 5 files changed, 76 insertions(+), 21 deletions(-) diff --git a/packages/tabs/README.md b/packages/tabs/README.md index edc69032..34ab453b 100644 --- a/packages/tabs/README.md +++ b/packages/tabs/README.md @@ -68,8 +68,8 @@ const [ instance ] = tabs(elements); ``` On page load the active tab will be set by (in order of precedence): 1. The page hash. If the page hash in the address bar matches the ID of a panel, it will be activated on page load -2. The active class. If a panel element is found to have the active class on page load, it will be activated automatically -3. The tab specified by the activeIndex in the settings +2. The data-active-index attribute. If the tabs node found to have a
data-active-index
attribute, that tab will be activated on page load. This is a zero-based index. +3. The tab specified by the activeIndex in the settings. This is a zero-based index. 4. The first tab in the set. ## API diff --git a/packages/tabs/__tests__/unit/utils.js b/packages/tabs/__tests__/unit/utils.js index 21fb38a8..8e783255 100644 --- a/packages/tabs/__tests__/unit/utils.js +++ b/packages/tabs/__tests__/unit/utils.js @@ -1,4 +1,4 @@ -import { getActiveIndexByHash } from '../../src/lib/utils'; +import { getActiveIndexByHash, getActiveIndexOnLoad } from '../../src/lib/utils'; const init = () => { document.body.innerHTML = `
@@ -63,3 +63,69 @@ describe(`Tabs > utils > getActiveIndexByHash`, () => { }); }); + +const initWithAttribute = () => { + document.body.innerHTML = `
+ +
Panel 1
+
+

Panel 2

+

Test link

+

Test link

+
+
+

Panel 3

+

Test link

+

Test link

+
+
`; +}; + + +describe(`Tabs > utils > getActiveIndexOnLoad`, () => { + beforeAll(initWithAttribute); + + it('should use the data attribute if no hash is available', async () => { + delete global.window.location; + global.window = Object.create(window); + global.window.location = { + port: '123', + protocol: 'http:', + hostname: 'localhost', + hash: '' + }; + const node = document.querySelector('[role="tablist"]'); + const panels = [].slice.call(document.querySelectorAll('[role=tabpanel]')); + expect(getActiveIndexOnLoad(panels, node)).toEqual(2); + }); + + it('should return undefined if neither hash or attribute', async () => { + const node = document.querySelector('[role="tablist"]'); + node.removeAttribute('data-active-index'); + const panels = [].slice.call(document.querySelectorAll('[role=tabpanel]')); + expect(getActiveIndexOnLoad(panels, node)).toEqual(undefined); + }); + + it('should use the hash as priority if available', async () => { + const node = document.querySelector('[role="tablist"]'); + node.setAttribute('data-active-index', "1"); + + delete global.window.location; + global.window = Object.create(window); + global.window.location = { + port: '123', + protocol: 'http:', + hostname: 'localhost', + hash: '#panel-3' + }; + + const panels = [].slice.call(document.querySelectorAll('[role=tabpanel]')); + expect(getActiveIndexOnLoad(panels, node)).toEqual(2); + }); + +}); + diff --git a/packages/tabs/example/src/index.html b/packages/tabs/example/src/index.html index 0e8b8047..86be9fbf 100644 --- a/packages/tabs/example/src/index.html +++ b/packages/tabs/example/src/index.html @@ -78,13 +78,13 @@ -
-
+
+ -
Panel 1
+
diff --git a/packages/tabs/src/lib/factory.js b/packages/tabs/src/lib/factory.js index a724acaf..69485e79 100644 --- a/packages/tabs/src/lib/factory.js +++ b/packages/tabs/src/lib/factory.js @@ -11,11 +11,11 @@ import { getActiveIndexOnLoad } from './utils'; export default ({ node, settings }) => { const Store = createStore(); const { tabs, panels } = findTabsAndPanels(node, settings); - const activeIndex = getActiveIndexOnLoad(panels, settings); + const activeIndex = getActiveIndexOnLoad(panels, node); Store.dispatch({ settings, node, - activeIndex: activeIndex !== undefined ? +activeIndex : +settings.activeIndex, + activeIndex: activeIndex !== undefined ? +activeIndex : +settings.activeIndex, activeTabIndex: activeIndex !== undefined ? +activeIndex : +settings.activeIndex, tabs, panels, diff --git a/packages/tabs/src/lib/utils.js b/packages/tabs/src/lib/utils.js index 997d380c..79b7470a 100644 --- a/packages/tabs/src/lib/utils.js +++ b/packages/tabs/src/lib/utils.js @@ -8,19 +8,8 @@ export const getActiveIndexByHash = panels => { }, undefined); }; -export const getActiveIndexByClass = (panels, settings) => { - let activeIndex; - for(let i = 0; i <= panels.length-1; i++) { - if (panels[i].classList.contains(settings.activeClass)) { - activeIndex = i; - break; - } - } - return activeIndex; -}; - -export const getActiveIndexOnLoad = (panels, settings) => { - return (location.hash) ? getActiveIndexByHash(panels) : getActiveIndexByClass(panels, settings); +export const getActiveIndexOnLoad = (panels, node) => { + return (location.hash) ? getActiveIndexByHash(panels) : (node.getAttribute("data-active-index")) ? parseInt(node.getAttribute("data-active-index")) : undefined; }; /*