Skip to content

Commit

Permalink
Merge pull request #66 from shamalijadhav/feature/component-creation
Browse files Browse the repository at this point in the history
 tab added
  • Loading branch information
Sm1pleScr1pt authored Jun 20, 2024
2 parents 0234582 + 2ac9079 commit 8292148
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 7 deletions.
Empty file added blocks/tabs/tabs.css
Empty file.
116 changes: 116 additions & 0 deletions blocks/tabs/tabs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// import { createTag } from '../../scripts/scripts.js';

/**
* Helper function to create DOM elements
* @param {string} tag DOM element to be created
* @param {array} attributes attributes to be added
*/
function createTag(tag, attributes, html) {
const el = document.createElement(tag);
if (html) {
if (html instanceof HTMLElement || html instanceof SVGElement) {
el.append(html);
} else {
el.insertAdjacentHTML('beforeend', html);
}
}
if (attributes) {
Object.entries(attributes).forEach(([key, val]) => {
el.setAttribute(key, val);
});
}
return el;
}

function changeTabs(e) {
const { target } = e;
const tabMenu = target.parentNode;
const tabContent = tabMenu.nextElementSibling;

tabMenu.querySelectorAll('[aria-selected="true"]').forEach((t) => t.setAttribute('aria-selected', false));

target.setAttribute('aria-selected', true);

tabContent.querySelectorAll('[role="tabpanel"]').forEach((p) => p.classList.remove('active'));

tabContent.parentNode.querySelector(`#${target.getAttribute('aria-controls')}`).classList.add('active');
}

function initTabs(block) {
const tabs = block.querySelectorAll('[role="tab"]');

tabs.forEach((tab) => {
tab.addEventListener('click', changeTabs);
});
}

let initCount = 0;
export default function decorate(block) {
const tabList = createTag('div', { class: 'tab-list', role: 'tablist' });
const tabContent = createTag('div', { class: 'tab-content' });

const tabNames = [];
const tabContents = [];
// list of Universal Editor instrumented 'tab content' divs
const tabInstrumentedDiv = [];

[...block.children].forEach((child) => {
// keep the div that has been instrumented for UE
tabInstrumentedDiv.push(child);

[...child.children].forEach((el, index) => {
if (index === 0) {
tabNames.push(el.textContent.trim());
} else {
tabContents.push(el.childNodes);
}
});
});

tabNames.forEach((name, i) => {
const tabBtnAttributes = {
role: 'tab',
class: 'tab-title',
id: `tab-${initCount}-${i}`,
tabindex: i > 0 ? '0' : '-1',
'aria-selected': i === 0 ? 'true' : 'false',
'aria-controls': `tab-panel-${initCount}-${i}`,
'aria-label': name,
'data-tab-id': i,
};

const tabNameDiv = createTag('button', tabBtnAttributes);
tabNameDiv.textContent = name;
tabList.appendChild(tabNameDiv);
});

tabContents.forEach((content, i) => {
const tabContentAttributes = {
id: `tab-panel-${initCount}-${i}`,
role: 'tabpanel',
class: 'tabpanel',
tabindex: '0',
'aria-labelledby': `tab-${initCount}-${i}`,
};

// get the instrumented div
const tabContentDiv = tabInstrumentedDiv[i];
// add all additional attributes
Object.entries(tabContentAttributes).forEach(([key, val]) => {
tabContentDiv.setAttribute(key, val);
});

// default first tab is active
if (i === 0) tabContentDiv.classList.add('active');
tabContentDiv.replaceChildren(...Array.from(content));
tabContent.appendChild(tabContentDiv);
});

// Replace the existing content with the new tab list and tab content
block.innerHTML = ''; // Clear the existing content
block.appendChild(tabList);
block.appendChild(tabContent);

initTabs(block);
initCount += 1;
}
40 changes: 40 additions & 0 deletions component-definition.json
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,46 @@
}
}
}
},
{
"title": "Tabs",
"id": "tabs",
"plugins": {
"xwalk": {
"page": {
"resourceType": "core/franklin/components/block/v1/block",
"template": {
"name": "Tabs",
"model": "tabs",
"filter": "tab",
"item1": {
"sling:resourceType": "core/franklin/components/block/v1/block/item",
"name": "Tab",
"model": "tab",
"title": "Tab",
"content": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."
}
}
}
}
}
},
{
"title": "Tab",
"id": "tab",
"plugins": {
"xwalk": {
"page": {
"resourceType": "core/franklin/components/block/v1/block/item",
"template": {
"name": "Tab",
"model": "tab",
"title": "Tab",
"content": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."
}
}
}
}
}
]
}
Expand Down
15 changes: 8 additions & 7 deletions component-filters.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"rte",
"imgwithlink",
"carousel",
"teaser"
"teaser",
"tabs"
]
},
{
Expand All @@ -39,7 +40,8 @@
"rte",
"imgwithlink",
"carousel",
"teaser"
"teaser",
"tabs"
]
},
{
Expand All @@ -56,12 +58,11 @@
"button",
"title",
"hero",
"cards",
"columns",
"rte",
"imgwithlink",
"carousel",
"teaser"
]
},
{
"id": "tab",
"components": ["tab"]
}
]
23 changes: 23 additions & 0 deletions component-models.json
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@
"id": "carousel",
"fields": []
},
{
"id": "tabs",
"fields": []
},
{
"id": "teaser",
"fields": [
Expand Down Expand Up @@ -498,5 +502,24 @@
"description": "What link to open when clicking the button."
}
]
},
{
"id": "tab",
"fields": [
{
"component": "text",
"valueType": "string",
"name": "title",
"value": "",
"label": "Heading"
},
{
"component": "richtext",
"valueType": "string",
"name": "content",
"value": "",
"label": "Body"
}
]
}
]

0 comments on commit 8292148

Please sign in to comment.