Add tabs feature with two options
This commit is contained in:
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
66
mobile-scrollbar/index.xslt
Normal file
66
mobile-scrollbar/index.xslt
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><iai:component><iai:componentsdata><cdata-start/>
|
||||
<div class="tabs">
|
||||
<div class="tabs__container">
|
||||
|
||||
<!--Opis-->
|
||||
<iaixsl:if test="page/projector/product/vlongdescription and not(page/projector/product/vlongdescription = '')">
|
||||
<div class="tabs__item idm-active" data-tab="projector_longdescription">
|
||||
<iai:variable vid="Opis produktu" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Parametry-->
|
||||
<iaixsl:if
|
||||
test="/shop/page/projector/product/price/@srp or (count(/shop/page/projector/product/dictionary/items) > 0) or ($product_producer_label and not(/shop/page/projector/product/firm/@name = '')) or ($product_code_label and /shop/page/projector/product/@code) or ($product_series_label and /shop/page/projector/product/series) or ($product_producer_code_label and count(/shop/page/projector/product/sizes/size[@code_producer and not(@code_producer = '')]) > 0) or (count(/shop/page/projector/product/responsible_entity/producer | /shop/page/projector/product/responsible_entity/persons/person) > 0)"
|
||||
>
|
||||
<div class="tabs__item" data-tab="projector_dictionary">
|
||||
<iai:variable vid="Parametry techniczne" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Do pobrania-->
|
||||
<iaixsl:if
|
||||
test="(/shop/page/projector/product/enclosures/documents/item) or (/shop/page/projector/product/enclosures/audio/item) or (/shop/page/projector/product/enclosures/other) or (/shop/page/projector/product/enclosures/images_attachments/item) or (/shop/page/projector/product/enclosures/video/item)"
|
||||
>
|
||||
<div class="tabs__item" data-tab="projector_enclosures">
|
||||
<iai:variable vid="Do pobrania" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Gwarancja-->
|
||||
<iaixsl:if test="page/projector/product/warranty and not(page/projector/product/warranty= '')">
|
||||
<div class="tabs__item" data-tab="projector_warranty">
|
||||
<iai:variable vid="Gwarancja" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Pytania-->
|
||||
<iaixsl:if test="page/projector/product/warranty and not(page/projector/product/warranty= '')">
|
||||
<div class="tabs__item" data-tab="product_questions_list">
|
||||
<iai:variable vid="Pytania" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Opinie-->
|
||||
<div class="tabs__item" data-tab="opinions_section">
|
||||
<iai:variable vid="Opinie" />
|
||||
</div>
|
||||
|
||||
<!--Blog-->
|
||||
<iaixsl:if test="count(/shop/page/projector/blog_entries/item) > 0">
|
||||
<div class="tabs__item" data-tab="projector_blog">
|
||||
<iai:variable vid="Blog" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Rekomendacje 1-->
|
||||
<iaixsl:if test="page/projector/products_associated_zone1">
|
||||
<div class="tabs__item" data-tab="products_associated_zone1">
|
||||
<iai:variable vid="Rekomendacje 1" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<cdata-end/></iai:componentsdata></iai:component>
|
||||
26
mobile-scrollbar/src/main.js
Normal file
26
mobile-scrollbar/src/main.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const tabButtons = document.querySelectorAll('.tabs__item');
|
||||
// Leave only necessary sections id
|
||||
const sectionIds = [
|
||||
'projector_longdescription',
|
||||
'projector_dictionary',
|
||||
'projector_enclosures',
|
||||
'projector_warranty',
|
||||
'product_questions_list',
|
||||
'opinions_section',
|
||||
'projector_blog',
|
||||
'products_associated_zone1'
|
||||
];
|
||||
|
||||
const tabContents = sectionIds.map(id => document.getElementById(id));
|
||||
|
||||
tabButtons.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
tabButtons.forEach(b => b?.classList.remove('idm-active'));
|
||||
btn?.classList.add('idm-active');
|
||||
|
||||
tabContents.forEach(content => content?.classList.remove('idm-active'));
|
||||
const tabId = btn?.dataset.tab;
|
||||
|
||||
document.getElementById(tabId)?.classList.add('idm-active');
|
||||
});
|
||||
});
|
||||
112
mobile-scrollbar/src/style.less
Normal file
112
mobile-scrollbar/src/style.less
Normal file
@@ -0,0 +1,112 @@
|
||||
@keyframes slide-in {
|
||||
from {
|
||||
transform: scaleX(0);
|
||||
}
|
||||
to {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-in-opacity {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs {
|
||||
border-bottom: 3px solid #efefef;
|
||||
|
||||
@media(max-width: 978px) {
|
||||
border: none;
|
||||
}
|
||||
|
||||
&__container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #efefef;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: black;
|
||||
min-width: 30%;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #2e8b57;
|
||||
}
|
||||
|
||||
@media(max-width: 978px) {
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&__item {
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
transition: color .3s ease;
|
||||
color: #888;
|
||||
font-weight: 600;
|
||||
|
||||
&:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
&.idm-active {
|
||||
color: #000;
|
||||
|
||||
&::after {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 2.5px;
|
||||
background-color: black;
|
||||
border-radius: 2px;
|
||||
animation: slide-in .3s ease;
|
||||
@media(max-width: 978px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Leave only necessary sections id
|
||||
#projector_longdescription,
|
||||
#projector_dictionary,
|
||||
#projector_enclosures,
|
||||
#projector_warranty,
|
||||
#product_questions_list,
|
||||
#opinions_section,
|
||||
#projector_blog,
|
||||
#products_associated_zone1 {
|
||||
display: none;
|
||||
animation: slide-in-opacity .3s ease;
|
||||
padding-top: 5rem;
|
||||
&.idm-active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
66
mobile-tabs /index.xslt
Normal file
66
mobile-tabs /index.xslt
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><iai:component><iai:componentsdata><cdata-start/>
|
||||
<div class="tabs">
|
||||
<div class="tabs__container">
|
||||
|
||||
<!--Opis-->
|
||||
<iaixsl:if test="page/projector/product/vlongdescription and not(page/projector/product/vlongdescription = '')">
|
||||
<div class="tabs__item idm-active" data-tab="projector_longdescription">
|
||||
<iai:variable vid="Opis produktu" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Parametry-->
|
||||
<iaixsl:if
|
||||
test="/shop/page/projector/product/price/@srp or (count(/shop/page/projector/product/dictionary/items) > 0) or ($product_producer_label and not(/shop/page/projector/product/firm/@name = '')) or ($product_code_label and /shop/page/projector/product/@code) or ($product_series_label and /shop/page/projector/product/series) or ($product_producer_code_label and count(/shop/page/projector/product/sizes/size[@code_producer and not(@code_producer = '')]) > 0) or (count(/shop/page/projector/product/responsible_entity/producer | /shop/page/projector/product/responsible_entity/persons/person) > 0)"
|
||||
>
|
||||
<div class="tabs__item" data-tab="projector_dictionary">
|
||||
<iai:variable vid="Parametry techniczne" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Do pobrania-->
|
||||
<iaixsl:if
|
||||
test="(/shop/page/projector/product/enclosures/documents/item) or (/shop/page/projector/product/enclosures/audio/item) or (/shop/page/projector/product/enclosures/other) or (/shop/page/projector/product/enclosures/images_attachments/item) or (/shop/page/projector/product/enclosures/video/item)"
|
||||
>
|
||||
<div class="tabs__item" data-tab="projector_enclosures">
|
||||
<iai:variable vid="Do pobrania" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Gwarancja-->
|
||||
<iaixsl:if test="page/projector/product/warranty and not(page/projector/product/warranty= '')">
|
||||
<div class="tabs__item" data-tab="projector_warranty">
|
||||
<iai:variable vid="Gwarancja" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Pytania-->
|
||||
<iaixsl:if test="page/projector/product/warranty and not(page/projector/product/warranty= '')">
|
||||
<div class="tabs__item" data-tab="product_questions_list">
|
||||
<iai:variable vid="Pytania" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Opinie-->
|
||||
<div class="tabs__item" data-tab="opinions_section">
|
||||
<iai:variable vid="Opinie" />
|
||||
</div>
|
||||
|
||||
<!--Blog-->
|
||||
<iaixsl:if test="count(/shop/page/projector/blog_entries/item) > 0">
|
||||
<div class="tabs__item" data-tab="projector_blog">
|
||||
<iai:variable vid="Blog" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
<!--Rekomendacje 1-->
|
||||
<iaixsl:if test="page/projector/products_associated_zone1">
|
||||
<div class="tabs__item" data-tab="products_associated_zone1">
|
||||
<iai:variable vid="Rekomendacje 1" />
|
||||
</div>
|
||||
</iaixsl:if>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<cdata-end/></iai:componentsdata></iai:component>
|
||||
106
mobile-tabs /src/main.js
Normal file
106
mobile-tabs /src/main.js
Normal file
@@ -0,0 +1,106 @@
|
||||
// Leave only necessary sections id
|
||||
const sectionIds = [
|
||||
'projector_longdescription',
|
||||
'projector_dictionary',
|
||||
'projector_enclosures',
|
||||
'projector_warranty',
|
||||
'product_questions_list',
|
||||
'opinions_section',
|
||||
'projector_blog',
|
||||
'products_associated_zone1'
|
||||
];
|
||||
const tabContents = sectionIds.map(id => document.getElementById(id));
|
||||
const tabButtons = document.querySelectorAll('.tabs__item');
|
||||
let isMobileView = false;
|
||||
|
||||
// Engine
|
||||
(() => {
|
||||
let resizeTimeout
|
||||
let prevView = app_shop.vars.view
|
||||
const container = document.querySelector('#container')
|
||||
|
||||
const VIEW_PHONE = [1, 2]
|
||||
const VIEW_TABLET_DESKTOP = [3, 4]
|
||||
|
||||
const handleResize = () => {
|
||||
if (!container?.classList.contains('projector_page')) return
|
||||
|
||||
clearTimeout(resizeTimeout)
|
||||
resizeTimeout = setTimeout(() => {
|
||||
const currentView = app_shop.vars.view
|
||||
|
||||
if (VIEW_PHONE.includes(currentView)) {
|
||||
isMobileView = true
|
||||
placeContentsInBetween()
|
||||
} else if (VIEW_TABLET_DESKTOP.includes(currentView)) {
|
||||
isMobileView = false
|
||||
}
|
||||
|
||||
if (VIEW_TABLET_DESKTOP.includes(prevView) && VIEW_PHONE.includes(currentView)) {
|
||||
placeContentsInBetween()
|
||||
} else if (VIEW_PHONE.includes(prevView) && VIEW_TABLET_DESKTOP.includes(currentView)) {
|
||||
placeContentsDefault()
|
||||
}
|
||||
|
||||
prevView = currentView
|
||||
|
||||
initTabs()
|
||||
}, 200)
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
handleResize()
|
||||
})
|
||||
|
||||
window.addEventListener('resize', handleResize)
|
||||
})()
|
||||
|
||||
// Utils
|
||||
function handleTabClick(e) {
|
||||
const btn = e.currentTarget
|
||||
|
||||
if (isMobileView) {
|
||||
tabButtons.forEach(b => {
|
||||
if (b !== btn) b?.classList.remove('idm-active')
|
||||
})
|
||||
btn?.classList.toggle('idm-active')
|
||||
} else {
|
||||
tabButtons.forEach(b => b?.classList.remove('idm-active'))
|
||||
btn?.classList.add('idm-active')
|
||||
}
|
||||
|
||||
const tabId = btn?.dataset.tab
|
||||
if (isMobileView) {
|
||||
tabContents.forEach(content => {
|
||||
if(content.id !== tabId) content?.classList.remove('idm-active')
|
||||
})
|
||||
document.getElementById(tabId)?.classList.toggle('idm-active')
|
||||
} else {
|
||||
tabContents.forEach(content => content?.classList.remove('idm-active'))
|
||||
document.getElementById(tabId)?.classList.add('idm-active')
|
||||
}
|
||||
}
|
||||
|
||||
function initTabs() {
|
||||
tabButtons.forEach(btn => {
|
||||
btn.removeEventListener('click', handleTabClick)
|
||||
btn.addEventListener('click', handleTabClick)
|
||||
})
|
||||
}
|
||||
|
||||
function placeContentsInBetween() {
|
||||
tabButtons.forEach(btn => {
|
||||
const tabId = btn?.dataset.tab
|
||||
const relevantTab = document.getElementById(tabId)
|
||||
btn.insertAdjacentElement('afterend', relevantTab)
|
||||
})
|
||||
}
|
||||
|
||||
function placeContentsDefault() {
|
||||
const tabs = document.querySelector('.tabs')
|
||||
tabButtons.forEach(btn => {
|
||||
const tabId = btn?.dataset.tab
|
||||
const relevantTab = document.getElementById(tabId)
|
||||
tabs.insertAdjacentElement('afterend', relevantTab)
|
||||
})
|
||||
}
|
||||
113
mobile-tabs /src/style.less
Normal file
113
mobile-tabs /src/style.less
Normal file
@@ -0,0 +1,113 @@
|
||||
@keyframes slide-in-opacity {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs {
|
||||
border-bottom: 3px solid #efefef;
|
||||
|
||||
@media (max-width: 978px) {
|
||||
border: none;
|
||||
}
|
||||
|
||||
&__container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
|
||||
@media (max-width: 978px) {
|
||||
gap: 2rem;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&__item {
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
transition: color .3s ease;
|
||||
color: #888;
|
||||
font-weight: 600;
|
||||
|
||||
&:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
&.idm-active {
|
||||
color: #000;
|
||||
|
||||
&::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 978px) {
|
||||
&::before {
|
||||
opacity: 0;
|
||||
transform: translateY(50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 978px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&::after, &::before {
|
||||
content: "";
|
||||
display: block;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 2.5px;
|
||||
background-color: black;
|
||||
border-radius: 2px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
// Mobile plus&minus
|
||||
@media (max-width: 978px) {
|
||||
padding: 0;
|
||||
|
||||
&::after, &::before {
|
||||
opacity: 1;
|
||||
width: 2rem;
|
||||
left: calc(100% - 2rem);
|
||||
bottom: 50%;
|
||||
transform: translateY(50%);
|
||||
}
|
||||
|
||||
&::before {
|
||||
opacity: 1;
|
||||
transform: rotate(90deg) translateY(0) translateX(5%);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Leave only necessary sections id
|
||||
#projector_longdescription,
|
||||
#projector_dictionary,
|
||||
#projector_enclosures,
|
||||
#projector_warranty,
|
||||
#product_questions_list,
|
||||
#opinions_section,
|
||||
#projector_blog,
|
||||
#products_associated_zone1 {
|
||||
display: none;
|
||||
animation: slide-in-opacity .3s ease;
|
||||
padding-top: 5rem;
|
||||
|
||||
&.idm-active {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user