diff --git a/libs/blocks/tabs/tabs.css b/libs/blocks/tabs/tabs.css index 0efb1d762f..889f517e9f 100644 --- a/libs/blocks/tabs/tabs.css +++ b/libs/blocks/tabs/tabs.css @@ -493,3 +493,46 @@ top: 24px; } } + +@media screen and (max-width: 599px) { + .tabs.stacked-mobile div[role="tablist"] { + margin: 0; + } + + .tabs.stacked-mobile div[role="tablist"] .tab-list-container { + flex-direction: column; + margin: 30px auto; + } + + .tabs.stacked-mobile div[role="tablist"] button { + font-size: 20px; + white-space: unset; + word-wrap: break-word; + line-height: 25px; + padding: 8px; + border-radius: 0; + border: 0; + margin-bottom: 8px; + } + + .tabs.stacked-mobile div[role="tablist"] button:last-of-type { + margin-bottom: 0; + } + + .tabs.stacked-mobile div[role="tablist"] button[aria-selected="true"] { + background-color: #dadada; + } + + .tabs.stacked-mobile.dark div[role="tablist"] button[aria-selected="true"] { + background-color: #393939; + } + + .tabs.stacked-mobile.center div[role="tablist"] .tab-list-container { + width: 100%; + margin: 0 30px 30px; + } + + .tabs.stacked-mobile.quiet div[role="tablist"] button { + margin-inline-start: 0; + } +} diff --git a/libs/blocks/tabs/tabs.js b/libs/blocks/tabs/tabs.js index db4a367235..b32e5bcbbe 100644 --- a/libs/blocks/tabs/tabs.js +++ b/libs/blocks/tabs/tabs.js @@ -34,10 +34,19 @@ const removeAttributes = (el, attrsKeys) => { attrsKeys.forEach((key) => el.removeAttribute(key)); }; +const scrollStackedMobile = (content) => { + if (!window.matchMedia('(max-width: 600px)').matches) return; + const rects = content.getBoundingClientRect(); + const navHeight = document.querySelector('.global-navigation, .gnav')?.scrollHeight || 0; + const topOffset = rects.top + window.scrollY - navHeight - 1; + window.scrollTo({ top: topOffset, behavior: 'smooth' }); +}; + function changeTabs(e) { const { target } = e; const parent = target.parentNode; const content = parent.parentNode.parentNode.lastElementChild; + const targetContent = content.querySelector(`#${target.getAttribute('aria-controls')}`); const blockId = target.closest('.tabs').id; parent .querySelectorAll(`[aria-selected="true"][data-block-id="${blockId}"]`) @@ -47,9 +56,8 @@ function changeTabs(e) { content .querySelectorAll(`[role="tabpanel"][data-block-id="${blockId}"]`) .forEach((p) => p.setAttribute('hidden', true)); - content - .querySelector(`#${target.getAttribute('aria-controls')}`) - .removeAttribute('hidden'); + targetContent.removeAttribute('hidden'); + scrollStackedMobile(targetContent); } function getStringKeyName(str) { diff --git a/test/blocks/tabs/mocks/body.html b/test/blocks/tabs/mocks/body.html index 2763172d12..9eb9c3f599 100644 --- a/test/blocks/tabs/mocks/body.html +++ b/test/blocks/tabs/mocks/body.html @@ -306,3 +306,36 @@

Tab by index label free

+ +
+

Stacked Mobile Tabs

+
+
+
+
    +
  • Tab, stacked-1
  • +
  • Tab, stacked-2
  • +
+
+
+
+
+
+

Here is Tab 1

+
+
+
tab
+
Tab, stacked-1
+
+
+
+
+

Here is Tab 2

+
+
+
tab
+
Tab, stacked-2
+
+
+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur posuere dignissim leo quis rhoncus. Suspendisse potenti. Nulla ac dolor dui. Vivamus posuere porttitor lectus, et vestibulum nisi varius cursus. Phasellus bibendum non lectus sit amet bibendum. Vivamus dapibus ultrices nisi. Praesent consequat lorem vitae gravida suscipit. Sed facilisis lacinia neque, ac tincidunt ex placerat a. Vivamus ultrices arcu sed laoreet tincidunt.

diff --git a/test/blocks/tabs/tabs.test.js b/test/blocks/tabs/tabs.test.js index 541db35ba5..d01de3cb9c 100644 --- a/test/blocks/tabs/tabs.test.js +++ b/test/blocks/tabs/tabs.test.js @@ -94,4 +94,16 @@ describe('tabs', () => { expect(tabList.scrollLeft).to.equal(0); }); + + describe('stacked mobile variant', () => { + it('scrolls the window to the selected tab content', async () => { + setViewport({ width: MOBILE_WIDTH, height: HEIGHT }); + window.dispatchEvent(new Event('resize')); + const oldPosition = window.scrollY; + document.querySelector('#stacked-mobile .tabs button').click(); + await delay(50); + const newPosition = window.scrollY; + expect(newPosition).to.be.above(oldPosition); + }); + }); });