diff --git a/component-definition.json b/component-definition.json index 7c5b29e..ab53504 100644 --- a/component-definition.json +++ b/component-definition.json @@ -76,6 +76,23 @@ } } } + }, + { + "title": "Tab Section", + "id": "tab-section", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/section/v1/section", + "template": { + "name": "Tab Section", + "model": "tab-section", + "filter": "tab-section", + "style": "tab-section" + } + } + } + } } ] }, diff --git a/component-filters.json b/component-filters.json index 1f71d59..132a78a 100644 --- a/component-filters.json +++ b/component-filters.json @@ -26,6 +26,24 @@ "title" ] }, + { + "id": "tab-section", + "components": [ + "text", + "image", + "button", + "title", + "columns", + "icon-block", + "teaser", + "detailed-teaser", + "video-embed", + "media", + "block-quote", + "callout", + "note" + ] + }, { "id": "cards", "components": [ diff --git a/component-models.json b/component-models.json index c37101f..65b7602 100644 --- a/component-models.json +++ b/component-models.json @@ -111,6 +111,28 @@ } ] }, + { + "id": "tab-section", + "fields": [ + { + "component": "select", + "name": "style", + "value": "", + "label": "Style", + "description": "The section style", + "valueType": "string", + "hidden": true, + "options": [] + }, + { + "component": "text", + "valueType": "string", + "name": "title", + "value": "", + "label": "Tab heading" + } + ] + }, { "id": "page-metadata", "fields": [ diff --git a/models/_section.json b/models/_section.json index 1f50ad3..c4222a7 100644 --- a/models/_section.json +++ b/models/_section.json @@ -15,6 +15,23 @@ } } } + }, + { + "title": "Tab Section", + "id": "tab-section", + "plugins": { + "xwalk": { + "page": { + "resourceType": "core/franklin/components/section/v1/section", + "template": { + "name": "Tab Section", + "model": "tab-section", + "filter": "tab-section", + "style": "tab-section" + } + } + } + } } ], "models": [ @@ -33,6 +50,28 @@ ] } ] + }, + { + "id": "tab-section", + "fields": [ + { + "component": "select", + "name": "style", + "value": "", + "label": "Style", + "description": "The section style", + "valueType": "string", + "hidden": true, + "options": [] + }, + { + "component": "text", + "valueType": "string", + "name": "title", + "value": "", + "label": "Tab heading" + } + ] } ], "filters": [ @@ -56,6 +95,24 @@ "image", "title" ] + }, + { + "id": "tab-section", + "components": [ + "text", + "image", + "button", + "title", + "columns", + "icon-block", + "teaser", + "detailed-teaser", + "video-embed", + "media", + "block-quote", + "callout", + "note" + ] } ] } diff --git a/scripts/aem.js b/scripts/aem.js index de3beb1..1f69dbf 100644 --- a/scripts/aem.js +++ b/scripts/aem.js @@ -539,7 +539,7 @@ async function fetchPlaceholders(prefix = 'default') { * @param {string} blockName name of the block * @param {*} content two dimensional array or string or object of content */ -function buildBlock(blockName, content) { +export function buildBlock(blockName, content) { const table = Array.isArray(content) ? content : [[content]]; const blockEl = document.createElement('div'); // build image block nested div structure diff --git a/scripts/editor-support.js b/scripts/editor-support.js index 231fdc8..07df6da 100644 --- a/scripts/editor-support.js +++ b/scripts/editor-support.js @@ -174,17 +174,6 @@ function handleEditorSelect(event) { // click it button.click(); } - - // if a teaser in a carousel was selected - if (event.target.closest('.panel-container')) { - // switch to the selected carousel slide - const carouselItem = event.target; - carouselItem.parentElement.scrollTo({ - top: 0, - left: carouselItem.offsetLeft - carouselItem.parentNode.offsetLeft, - behavior: 'instant', - }); - } } function attachEventListeners(main) { diff --git a/scripts/scripts.js b/scripts/scripts.js index 5e1288e..5e9cc66 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -11,6 +11,7 @@ import { loadSection, loadSections, loadCSS, + buildBlock } from './aem.js'; /** @@ -59,6 +60,47 @@ async function loadFonts() { } } +/** + * Tabbed layout for Tab section + * @param {HTMLElement} main + */ +async function buildTabSection(main) { + let tabIndex = 0; + let tabContainer; + let tabFound = false; + const sections = main.querySelectorAll('main > div'); + sections.forEach((section, i) => { + const sectionMeta = section.querySelector('.section-metadata > div > div:nth-child(2)'); + if (sectionMeta?.textContent.includes('tab-section')) { + if (!tabFound) { + tabIndex += 1; + tabFound = true; + const tabs = buildBlock('tabs', []); + tabs.dataset.tabIndex = tabIndex; + tabContainer = document.createElement('div'); + tabContainer.classList.add('section'); + if ( + i > 0 && sections[i - 1] + .querySelector('.section-metadata > div > div:nth-child(2)') + ?.textContent.includes('article-content-section') + ) { + tabContainer.classList.add('article-content-section'); + } + tabContainer.append(tabs); + main.insertBefore(tabContainer, section); + } + if ( + tabFound && !sections[i + 1] + ?.querySelector('.section-metadata > div > div:nth-child(2)') + ?.textContent.includes('tab-section') + ) { + tabFound = false; + } + section.classList.add(`tab-index-${tabIndex}`); + } + }); +} + /** * Builds all synthetic blocks in a container element. * @param {Element} main The container element @@ -66,6 +108,7 @@ async function loadFonts() { function buildAutoBlocks() { try { // TODO: add auto block, if needed + buildTabSection(main); } catch (error) { // eslint-disable-next-line no-console console.error('Auto Blocking failed', error);