swiper and clean
This commit is contained in:
39
src/App.jsx
39
src/App.jsx
@@ -1,16 +1,13 @@
|
||||
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'
|
||||
import { lazy, Suspense } from 'react'
|
||||
import Layout from './components/Layout'
|
||||
import Loading from './components/Loading'
|
||||
import ErrorBoundary from './components/ErrorBoundary'
|
||||
import { BRAND_PRIMARY } from './config'
|
||||
|
||||
const Home = lazy(() => import('./pages/Home'))
|
||||
const About = lazy(() => import('./pages/About'))
|
||||
const Services = lazy(() => import('./pages/Services'))
|
||||
const ServiceDetail = lazy(() => import('./pages/ServiceDetail'))
|
||||
const Project = lazy(() => import('./pages/Project'))
|
||||
const Contact = lazy(() => import('./pages/Contact'))
|
||||
import Home from './pages/Home'
|
||||
import About from './pages/About'
|
||||
import Services from './pages/Services'
|
||||
import ServiceDetail from './pages/ServiceDetail'
|
||||
import Project from './pages/Project'
|
||||
import Contact from './pages/Contact'
|
||||
|
||||
function NotFound() {
|
||||
return (
|
||||
@@ -26,19 +23,17 @@ export default function App() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<ErrorBoundary>
|
||||
<Suspense fallback={<Loading />}>
|
||||
<Routes>
|
||||
<Route element={<Layout />}>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/about" element={<About />} />
|
||||
<Route path="/service" element={<Services />} />
|
||||
<Route path="/service/:slug" element={<ServiceDetail />} />
|
||||
<Route path="/project" element={<Project />} />
|
||||
<Route path="/contact" element={<Contact />} />
|
||||
<Route path="*" element={<NotFound />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</Suspense>
|
||||
<Routes>
|
||||
<Route element={<Layout />}>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/about" element={<About />} />
|
||||
<Route path="/service" element={<Services />} />
|
||||
<Route path="/service/:slug" element={<ServiceDetail />} />
|
||||
<Route path="/project" element={<Project />} />
|
||||
<Route path="/contact" element={<Contact />} />
|
||||
<Route path="*" element={<NotFound />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</ErrorBoundary>
|
||||
</BrowserRouter>
|
||||
)
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { Outlet, useLocation } from 'react-router-dom'
|
||||
import Header from './sections/Header'
|
||||
import Footer from './sections/Footer'
|
||||
import WhatsAppButton from './WhatsAppButton'
|
||||
import useThemeAssets from '../hooks/useThemeAssets'
|
||||
import useLayoutInit from '../hooks/useLayoutInit'
|
||||
import useSwiper from '../hooks/useSwiper'
|
||||
import useBackgroundAttrs from "../hooks/useBackgroundAttrs"
|
||||
import useAnimations from "../hooks/useAnimations"
|
||||
import { PAGE_IDS } from '../config'
|
||||
|
||||
export default function Layout() {
|
||||
@@ -12,6 +15,10 @@ export default function Layout() {
|
||||
|
||||
useThemeAssets()
|
||||
useLayoutInit()
|
||||
const contentRef = useRef(null)
|
||||
useBackgroundAttrs(contentRef)
|
||||
useSwiper(contentRef)
|
||||
useAnimations(contentRef)
|
||||
|
||||
useEffect(() => {
|
||||
let removed = false
|
||||
@@ -68,7 +75,7 @@ export default function Layout() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<Outlet />
|
||||
<div ref={contentRef}><Outlet /></div>
|
||||
<Footer />
|
||||
<WhatsAppButton />
|
||||
</>
|
||||
|
||||
10
src/css/fontawesome.css
vendored
10
src/css/fontawesome.css
vendored
File diff suppressed because one or more lines are too long
@@ -2399,65 +2399,6 @@ textarea.is-invalid {
|
||||
width: 45px;
|
||||
}
|
||||
|
||||
.scroll-top {
|
||||
position: fixed;
|
||||
right: 30px;
|
||||
bottom: 30px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
border-radius: 50px;
|
||||
z-index: 10000;
|
||||
opacity: 1;
|
||||
visibility: hidden;
|
||||
-webkit-transform: translateY(45px);
|
||||
transform: translateY(45px);
|
||||
-webkit-transition: all 300ms linear;
|
||||
transition: all 300ms linear;
|
||||
}
|
||||
.scroll-top:after {
|
||||
content: "\f062";
|
||||
font-family: var(--icon-font);
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
font-size: 20px;
|
||||
color: var(--theme-color);
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
z-index: 1;
|
||||
border: 2px solid var(--theme-color);
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.scroll-top svg {
|
||||
color: var(--theme-color);
|
||||
border-radius: 50%;
|
||||
background: var(--white-color);
|
||||
}
|
||||
.scroll-top svg path {
|
||||
fill: none;
|
||||
}
|
||||
.scroll-top .progress-circle path {
|
||||
stroke: var(--theme-color);
|
||||
stroke-width: 20px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-transition: all 400ms linear;
|
||||
transition: all 400ms linear;
|
||||
}
|
||||
.scroll-top.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/*------------------- 3.3. Titles -------------------*/
|
||||
.sec-title {
|
||||
@@ -6649,12 +6590,6 @@ ol.wp-block-rss {
|
||||
padding-bottom: 48px;
|
||||
}
|
||||
|
||||
.sticky-footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.footer-links ul {
|
||||
padding: 0;
|
||||
@@ -12792,109 +12727,6 @@ span.select2-selection.select2-selection--single:focus {
|
||||
}
|
||||
|
||||
/* About 2 ---------------------------------- */
|
||||
.comparison-img {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
.comparison-img p {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
background-color: var(--theme-color);
|
||||
color: var(--title-color);
|
||||
padding: 5px 15px;
|
||||
z-index: 3;
|
||||
font-weight: 500;
|
||||
}
|
||||
.comparison-img .before {
|
||||
left: 40px;
|
||||
}
|
||||
.comparison-img .after {
|
||||
right: 40px;
|
||||
}
|
||||
.comparison-img .img {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left center;
|
||||
/* Extra small devices */
|
||||
}
|
||||
@media (max-width: 375px) {
|
||||
.comparison-img .img {
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
.comparison-img .foreground-img {
|
||||
width: 50%;
|
||||
}
|
||||
.comparison-img .compslider {
|
||||
position: absolute;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
-webkit-transition: all 0.2s;
|
||||
transition: all 0.2s;
|
||||
text-align: center;
|
||||
}
|
||||
.comparison-img .compslider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 3px;
|
||||
height: 800px;
|
||||
background: var(--white-color);
|
||||
cursor: pointer;
|
||||
-webkit-transform: translateX(3px);
|
||||
transform: translateX(3px);
|
||||
}
|
||||
.comparison-img .compslider::-moz-range-thumb {
|
||||
width: 3px;
|
||||
height: 800px;
|
||||
background: var(--white-color);
|
||||
cursor: pointer;
|
||||
transform: translateX(3px);
|
||||
}
|
||||
.comparison-img .slider-button {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 50%;
|
||||
padding: 8px;
|
||||
background-color: var(--theme-color);
|
||||
left: calc(50% - 32px);
|
||||
top: calc(50% - 28px);
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
.comparison-img .slider-button:after {
|
||||
content: "";
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
border: solid var(--white-color);
|
||||
border-width: 0 1px 1px 0;
|
||||
-webkit-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
.comparison-img .slider-button:before {
|
||||
content: "";
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
border: solid var(--white-color);
|
||||
border-width: 0 1px 1px 0;
|
||||
-webkit-transform: rotate(135deg);
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
|
||||
.img-box4 {
|
||||
position: relative;
|
||||
@@ -15922,476 +15754,6 @@ span.select2-selection.select2-selection--single:focus {
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
/* overlay-direction */
|
||||
.overlay-direction .filter-item {
|
||||
-webkit-perspective: 0;
|
||||
-webkit-backface-visibility: hidden;
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
visibility: visible;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
.overlay-direction .filter-item {
|
||||
-webkit-perspective: 540px;
|
||||
perspective: 540px;
|
||||
}
|
||||
|
||||
.in-top .box-content {
|
||||
-webkit-transform-origin: 50% 0%;
|
||||
transform-origin: 50% 0%;
|
||||
-webkit-animation: in-top 500ms ease 0ms 1 forwards;
|
||||
animation: in-top 500ms ease 0ms 1 forwards;
|
||||
}
|
||||
|
||||
.in-right .box-content {
|
||||
-webkit-transform-origin: 100% 0%;
|
||||
transform-origin: 100% 0%;
|
||||
-webkit-animation: in-right 500ms ease 0ms 1 forwards;
|
||||
animation: in-right 500ms ease 0ms 1 forwards;
|
||||
}
|
||||
|
||||
.in-bottom .box-content {
|
||||
-webkit-transform-origin: 50% 100%;
|
||||
transform-origin: 50% 100%;
|
||||
-webkit-animation: in-bottom 500ms ease 0ms 1 forwards;
|
||||
animation: in-bottom 500ms ease 0ms 1 forwards;
|
||||
}
|
||||
|
||||
.in-left .box-content {
|
||||
-webkit-transform-origin: 0% 0%;
|
||||
transform-origin: 0% 0%;
|
||||
-webkit-animation: in-left 500ms ease 0ms 1 forwards;
|
||||
animation: in-left 500ms ease 0ms 1 forwards;
|
||||
}
|
||||
|
||||
.out-top .box-content {
|
||||
-webkit-transform-origin: 50% 0%;
|
||||
transform-origin: 50% 0%;
|
||||
-webkit-animation: out-top 500ms ease 0ms 1 forwards;
|
||||
animation: out-top 500ms ease 0ms 1 forwards;
|
||||
}
|
||||
|
||||
.out-right .box-content {
|
||||
-webkit-transform-origin: 100% 50%;
|
||||
transform-origin: 100% 50%;
|
||||
-webkit-animation: out-right 500ms ease 0ms 1 forwards;
|
||||
animation: out-right 500ms ease 0ms 1 forwards;
|
||||
}
|
||||
|
||||
.out-bottom .box-content {
|
||||
-webkit-transform-origin: 50% 100%;
|
||||
transform-origin: 50% 100%;
|
||||
-webkit-animation: out-bottom 500ms ease 0ms 1 forwards;
|
||||
animation: out-bottom 500ms ease 0ms 1 forwards;
|
||||
}
|
||||
|
||||
.out-left .box-content {
|
||||
-webkit-transform-origin: 0% 0%;
|
||||
transform-origin: 0% 0%;
|
||||
-webkit-animation: out-left 500ms ease 0ms 1 forwards;
|
||||
animation: out-left 500ms ease 0ms 1 forwards;
|
||||
}
|
||||
|
||||
@-webkit-keyframes in-top {
|
||||
from {
|
||||
-webkit-transform: rotate3d(-1, 0, 0, 90deg);
|
||||
transform: rotate3d(-1, 0, 0, 90deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
}
|
||||
@keyframes in-top {
|
||||
from {
|
||||
-webkit-transform: rotate3d(-1, 0, 0, 90deg);
|
||||
transform: rotate3d(-1, 0, 0, 90deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes in-right {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, -1, 0, 90deg);
|
||||
transform: rotate3d(0, -1, 0, 90deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
}
|
||||
@keyframes in-right {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, -1, 0, 90deg);
|
||||
transform: rotate3d(0, -1, 0, 90deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes in-bottom {
|
||||
from {
|
||||
-webkit-transform: rotate3d(1, 0, 0, 90deg);
|
||||
transform: rotate3d(1, 0, 0, 90deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
}
|
||||
@keyframes in-bottom {
|
||||
from {
|
||||
-webkit-transform: rotate3d(1, 0, 0, 90deg);
|
||||
transform: rotate3d(1, 0, 0, 90deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes in-left {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 1, 0, 90deg);
|
||||
transform: rotate3d(0, 1, 0, 90deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
}
|
||||
@keyframes in-left {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 1, 0, 90deg);
|
||||
transform: rotate3d(0, 1, 0, 90deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes out-top {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(-1, 0, 0, 104deg);
|
||||
transform: rotate3d(-1, 0, 0, 104deg);
|
||||
}
|
||||
}
|
||||
@keyframes out-top {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(-1, 0, 0, 104deg);
|
||||
transform: rotate3d(-1, 0, 0, 104deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes out-right {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, -1, 0, 104deg);
|
||||
transform: rotate3d(0, -1, 0, 104deg);
|
||||
}
|
||||
}
|
||||
@keyframes out-right {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, -1, 0, 104deg);
|
||||
transform: rotate3d(0, -1, 0, 104deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes out-bottom {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(1, 0, 0, 104deg);
|
||||
transform: rotate3d(1, 0, 0, 104deg);
|
||||
}
|
||||
}
|
||||
@keyframes out-bottom {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(1, 0, 0, 104deg);
|
||||
transform: rotate3d(1, 0, 0, 104deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes out-left {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 1, 0, 104deg);
|
||||
transform: rotate3d(0, 1, 0, 104deg);
|
||||
}
|
||||
}
|
||||
@keyframes out-left {
|
||||
from {
|
||||
-webkit-transform: rotate3d(0, 0, 0, 0deg);
|
||||
transform: rotate3d(0, 0, 0, 0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate3d(0, 1, 0, 104deg);
|
||||
transform: rotate3d(0, 1, 0, 104deg);
|
||||
}
|
||||
}
|
||||
/*------------------- 4.00. CTA -------------------*/
|
||||
.cta-img1 img {
|
||||
height: 100%;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
-o-object-position: right center;
|
||||
object-position: right center;
|
||||
/* Medium devices */
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
.cta-img1 img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.cta-sec1 {
|
||||
background-size: auto;
|
||||
background-position: center right;
|
||||
background-color: var(--theme-color);
|
||||
max-width: 1620px;
|
||||
margin: -45px auto auto;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
/* Large devices */
|
||||
/* Medium devices */
|
||||
}
|
||||
@media (max-width: 1199px) {
|
||||
.cta-sec1 {
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
.cta-sec1 {
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
}
|
||||
.cta-sec1 .sec-title {
|
||||
max-width: 600px;
|
||||
}
|
||||
.cta-sec1 .call-btn .box-label {
|
||||
font-weight: 400;
|
||||
}
|
||||
.cta-sec1 .call-btn .box-link {
|
||||
font-weight: 600;
|
||||
}
|
||||
.cta-sec1 .call-btn a:hover {
|
||||
color: var(--title-color) !important;
|
||||
}
|
||||
.cta-sec1 .play-btn:before, .cta-sec1 .play-btn:after {
|
||||
background-color: var(--white-color);
|
||||
}
|
||||
.cta-sec1 .play-btn > i {
|
||||
background-color: var(--white-color);
|
||||
color: var(--title-color);
|
||||
}
|
||||
.cta-sec1 .cta-content {
|
||||
padding: 40px 12px;
|
||||
-ms-flex-item-align: center;
|
||||
align-self: center;
|
||||
/* Medium devices */
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
.cta-sec1 .cta-content {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.video-content1 {
|
||||
padding: 220px 0;
|
||||
width: 100%;
|
||||
max-width: 550px;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
/* Medium Large devices */
|
||||
/* Medium devices */
|
||||
}
|
||||
.video-content1 .sec-title {
|
||||
margin: 40px 0 -0.22em 0;
|
||||
}
|
||||
.video-content1 .play-btn {
|
||||
--icon-size: 80px;
|
||||
font-size: 20px;
|
||||
}
|
||||
@media (max-width: 1299px) {
|
||||
.video-content1 {
|
||||
padding: 160px 0;
|
||||
}
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
.video-content1 {
|
||||
padding: 120px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.link-btn2 {
|
||||
font-family: var(--title-font);
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--white-color);
|
||||
}
|
||||
.link-btn2 i {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
border: 1px solid var(--white-color);
|
||||
border-radius: 8px;
|
||||
color: var(--theme-color);
|
||||
margin-right: 12px;
|
||||
}
|
||||
.link-btn2:hover {
|
||||
color: var(--theme-color);
|
||||
}
|
||||
|
||||
.video-content2 {
|
||||
padding: 160px 0 110px 0;
|
||||
width: 100%;
|
||||
max-width: 840px;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
/* Medium devices */
|
||||
}
|
||||
.video-content2 .sec-title {
|
||||
margin: 60px 0 26px 0;
|
||||
}
|
||||
.video-content2 .sec-text {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.video-content2 .play-btn {
|
||||
--icon-size: 80px;
|
||||
font-size: 20px;
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
.video-content2 {
|
||||
padding: 100px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.video-sec2 .counter-card-wrap {
|
||||
border-radius: 40px 40px 0 0;
|
||||
/* Medium devices */
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
.video-sec2 .counter-card-wrap {
|
||||
border-radius: 20px 20px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.video-sec3 .play-btn {
|
||||
--icon-size: 80px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.video-content3 .sec-title {
|
||||
margin-bottom: 26px;
|
||||
/* Large devices */
|
||||
}
|
||||
@media (max-width: 1199px) {
|
||||
.video-content3 .sec-title {
|
||||
margin-top: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------- 4.00. Tab Menu -------------------*/
|
||||
/* Tab Menu 1 ------------------------------------*/
|
||||
.tab-menu1 {
|
||||
position: relative;
|
||||
display: -webkit-inline-box;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
border: 1px solid var(--body-color);
|
||||
border-radius: 35px;
|
||||
padding: 8px;
|
||||
/* Large devices */
|
||||
}
|
||||
@media (max-width: 1199px) {
|
||||
.tab-menu1 {
|
||||
margin-top: -15px;
|
||||
}
|
||||
}
|
||||
.tab-menu1 .tab-btn {
|
||||
font-family: var(--title-font);
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 44px;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
padding: 0 28px;
|
||||
color: var(--title-color);
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
overflow: hidden;
|
||||
/* Small devices */
|
||||
}
|
||||
.tab-menu1 .tab-btn.active {
|
||||
color: var(--white-color);
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.tab-menu1 .tab-btn {
|
||||
padding: 0 18px;
|
||||
}
|
||||
}
|
||||
.tab-menu1 .indicator {
|
||||
position: absolute;
|
||||
top: var(--pos-y);
|
||||
left: var(--pos-x);
|
||||
height: var(--height-set);
|
||||
width: var(--width-set);
|
||||
-webkit-transition: 0.4s ease-in-out;
|
||||
transition: 0.4s ease-in-out;
|
||||
background-color: var(--theme-color);
|
||||
border-radius: 35px;
|
||||
}
|
||||
|
||||
/* Tab Menu 2 ------------------------------------*/
|
||||
.tab-menu2 {
|
||||
position: relative;
|
||||
display: -webkit-inline-box;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
z-index: 2;
|
||||
margin-bottom: 60px;
|
||||
margin-top: -20px;
|
||||
/* Large devices */
|
||||
}
|
||||
@media (max-width: 1199px) {
|
||||
.tab-menu2 {
|
||||
margin-top: -15px;
|
||||
@@ -18511,4 +17873,4 @@ span.select2-selection.select2-selection--single:focus {
|
||||
.space-extra2-bottom {
|
||||
padding-bottom: 70px;
|
||||
}
|
||||
}/*# sourceMappingURL=style.css.map */
|
||||
}
|
||||
@@ -94,7 +94,7 @@
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-2e21688 elementor-widget elementor-widget-rakargallery" data-id="2e21688" data-element_type="widget" data-e-type="widget" data-widget_type="rakargallery.default">
|
||||
<div class="elementor-widget-container">
|
||||
<div class="row gy-30 filter-active overlay-direction"><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_1.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_1.jpg" alt="gallery_1_1" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i> </span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_2.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_2.jpg" alt="gallery_1_2" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-6 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_3.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_3.jpg" alt="gallery_1_3" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-6 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_4.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_4.jpg" alt="gallery_1_4" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_5.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_5.jpg" alt="gallery_1_5" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_6.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_6.jpg" alt="gallery_1_6" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_7.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_7.jpg" alt="gallery_1_7" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-6 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_8.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_8.jpg" alt="gallery_1_8" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_9.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_9.jpg" alt="gallery_1_9" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div></div> </div>
|
||||
<div class="row gy-30 filter-active"><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_1.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_1.jpg" alt="gallery_1_1" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i> </span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_2.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_2.jpg" alt="gallery_1_2" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-6 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_3.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_3.jpg" alt="gallery_1_3" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-6 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_4.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_4.jpg" alt="gallery_1_4" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_5.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_5.jpg" alt="gallery_1_5" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_6.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_6.jpg" alt="gallery_1_6" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_7.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_7.jpg" alt="gallery_1_7" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-6 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_8.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_8.jpg" alt="gallery_1_8" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div><div class="cat2 col-xl-3 col-md-6 filter-item th-gallery-loop"><div class="gallery-card"><a class="box-img popup-image" href="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_9.jpg"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/gallery_1_9.jpg" alt="gallery_1_9" /><div class="box-content"><span class="box-btn"><i class="fas fa-plus"></i></span></div></a></div></div></div> </div>
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-be52d56 elementor-widget elementor-widget-rakarbutton" data-id="be52d56" data-element_type="widget" data-e-type="widget" data-widget_type="rakarbutton.default">
|
||||
<div class="elementor-widget-container">
|
||||
@@ -113,25 +113,25 @@
|
||||
</div>
|
||||
<div class="elementor-element elementor-element-96922c6 elementor-widget elementor-widget-rakarprice" data-id="96922c6" data-element_type="widget" data-e-type="widget" data-widget_type="rakarprice.default">
|
||||
<div class="elementor-widget-container">
|
||||
<div class="row gy-4"><div class="hover-item col-xl-3 col-md-6"><div class="price-card"><div class="box-shape"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/lines_3.png" alt="lines_3" /></div><h3 class="box-title">Basic Plan</h3><p class="box-price">$99.00<span class="duration">/Monthly</span></p><div class="box-list"><ul>
|
||||
<div class="row gy-4"><div class="col-xl-3 col-md-6"><div class="price-card"><div class="box-shape"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/lines_3.png" alt="lines_3" /></div><h3 class="box-title">Basic Plan</h3><p class="box-price">$99.00<span class="duration">/Monthly</span></p><div class="box-list"><ul>
|
||||
<li>Monthly Inspection</li>
|
||||
<li>General Repair</li>
|
||||
<li class="unavailable">Maintenance</li>
|
||||
<li class="unavailable">Fixing of Faulty Wiring</li>
|
||||
<li class="unavailable">Ac Condition Repair</li>
|
||||
</ul></div><div class="box-footer"><a href="/contact" class="th-btn">Get Started<i class="far fa-arrow-right ms-2"></i></a></div></div></div><div class="hover-item item-active col-xl-3 col-md-6"><div class="price-card"><div class="box-shape"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/lines_3.png" alt="lines_3" /></div><span class="tag">Popular Plan</span><h3 class="box-title">Standard</h3><p class="box-price">$129.00<span class="duration">/Monthly</span></p><div class="box-list"><ul>
|
||||
</ul></div><div class="box-footer"><a href="/contact" class="th-btn">Get Started<i class="far fa-arrow-right ms-2"></i></a></div></div></div><div class="col-xl-3 col-md-6"><div class="price-card"><div class="box-shape"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/lines_3.png" alt="lines_3" /></div><span class="tag">Popular Plan</span><h3 class="box-title">Standard</h3><p class="box-price">$129.00<span class="duration">/Monthly</span></p><div class="box-list"><ul>
|
||||
<li>Monthly Inspection</li>
|
||||
<li>General Repair</li>
|
||||
<li>Maintenance</li>
|
||||
<li class="unavailable">Fixing of Faulty Wiring</li>
|
||||
<li class="unavailable">Ac Condition Repair</li>
|
||||
</ul></div><div class="box-footer"><a href="/contact" class="th-btn">Get Started<i class="far fa-arrow-right ms-2"></i></a></div></div></div><div class="hover-item col-xl-3 col-md-6"><div class="price-card"><div class="box-shape"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/lines_3.png" alt="lines_3" /></div><h3 class="box-title">Premium</h3><p class="box-price">$199.00<span class="duration">/Monthly</span></p><div class="box-list"><ul>
|
||||
</ul></div><div class="box-footer"><a href="/contact" class="th-btn">Get Started<i class="far fa-arrow-right ms-2"></i></a></div></div></div><div class="col-xl-3 col-md-6"><div class="price-card"><div class="box-shape"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/lines_3.png" alt="lines_3" /></div><h3 class="box-title">Premium</h3><p class="box-price">$199.00<span class="duration">/Monthly</span></p><div class="box-list"><ul>
|
||||
<li>Monthly Inspection</li>
|
||||
<li>General Repair</li>
|
||||
<li>Maintenance</li>
|
||||
<li>Fixing of Faulty Wiring</li>
|
||||
<li class="unavailable">Ac Condition Repair</li>
|
||||
</ul></div><div class="box-footer"><a href="/contact" class="th-btn">Get Started<i class="far fa-arrow-right ms-2"></i></a></div></div></div><div class="hover-item col-xl-3 col-md-6"><div class="price-card"><div class="box-shape"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/lines_3.png" alt="lines_3" /></div><h3 class="box-title">Dedicated Plan</h3><p class="box-price">$299.00<span class="duration">/Monthly</span></p><div class="box-list"><ul>
|
||||
</ul></div><div class="box-footer"><a href="/contact" class="th-btn">Get Started<i class="far fa-arrow-right ms-2"></i></a></div></div></div><div class="col-xl-3 col-md-6"><div class="price-card"><div class="box-shape"><img decoding="async" src="https://wordpress.themeholy.com/rakar/assets/images/lines_3.png" alt="lines_3" /></div><h3 class="box-title">Dedicated Plan</h3><p class="box-price">$299.00<span class="duration">/Monthly</span></p><div class="box-list"><ul>
|
||||
<li>Monthly Inspection</li>
|
||||
<li>General Repair</li>
|
||||
<li>Maintenance</li>
|
||||
|
||||
18
src/hooks/useAnimations.js
Normal file
18
src/hooks/useAnimations.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
export default function useAnimations(containerRef) {
|
||||
const { pathname } = useLocation()
|
||||
useEffect(() => {
|
||||
const el = containerRef.current
|
||||
if (!el) return
|
||||
|
||||
el.querySelectorAll('[data-ani]').forEach(el => {
|
||||
el.classList.add(el.dataset.ani)
|
||||
})
|
||||
|
||||
el.querySelectorAll('[data-ani-delay]').forEach(el => {
|
||||
el.style.animationDelay = el.dataset.aniDelay
|
||||
})
|
||||
}, [containerRef, pathname])
|
||||
}
|
||||
36
src/hooks/useBackgroundAttrs.js
Normal file
36
src/hooks/useBackgroundAttrs.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
export default function useBackgroundAttrs(containerRef) {
|
||||
const { pathname } = useLocation()
|
||||
useEffect(() => {
|
||||
const el = containerRef.current
|
||||
if (!el) return
|
||||
|
||||
// data-bg-src → background-image
|
||||
el.querySelectorAll('[data-bg-src]').forEach(el => {
|
||||
el.style.backgroundImage = 'url(' + el.dataset.bgSrc + ')'
|
||||
el.removeAttribute('data-bg-src')
|
||||
el.classList.add('background-image')
|
||||
})
|
||||
|
||||
// data-bg-color → background-color
|
||||
el.querySelectorAll('[data-bg-color]').forEach(el => {
|
||||
el.style.backgroundColor = el.dataset.bgColor
|
||||
el.removeAttribute('data-bg-color')
|
||||
})
|
||||
|
||||
// data-border → CSS var
|
||||
el.querySelectorAll('[data-border]').forEach(el => {
|
||||
el.style.setProperty('--th-border-color', el.dataset.border)
|
||||
})
|
||||
|
||||
// data-mask-src → mask-image
|
||||
el.querySelectorAll('[data-mask-src]').forEach(el => {
|
||||
el.style.maskImage = 'url(' + el.dataset.maskSrc + ')'
|
||||
el.style.webkitMaskImage = 'url(' + el.dataset.maskSrc + ')'
|
||||
el.classList.add('bg-mask')
|
||||
el.removeAttribute('data-mask-src')
|
||||
})
|
||||
}, [containerRef, pathname])
|
||||
}
|
||||
133
src/hooks/useSwiper.js
Normal file
133
src/hooks/useSwiper.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import Swiper from 'swiper'
|
||||
import { Navigation, Pagination, Autoplay, EffectFade } from 'swiper/modules'
|
||||
|
||||
export default function useSwiper(containerRef) {
|
||||
const { pathname } = useLocation()
|
||||
const instances = useRef([])
|
||||
|
||||
useEffect(() => {
|
||||
const container = containerRef.current
|
||||
if (!container) return
|
||||
|
||||
// Destroy previous instances
|
||||
instances.current.forEach(s => s.destroy(true, true))
|
||||
instances.current = []
|
||||
|
||||
// Init all .th-slider elements
|
||||
container.querySelectorAll('.th-slider').forEach(el => {
|
||||
try {
|
||||
const userOptions = JSON.parse(el.dataset.sliderOptions || '{}')
|
||||
|
||||
// Find pagination element — inside slider or sibling .slider-controller
|
||||
let paginationEl = el.querySelector('.slider-pagination')
|
||||
if (!paginationEl) {
|
||||
const controller = el.closest('.th-slider')?.parentElement?.querySelector('.slider-controller')
|
||||
if (controller) paginationEl = controller.querySelector('.slider-pagination')
|
||||
}
|
||||
|
||||
const hasNumberPagi = el.querySelector('.slider-pagination.pagi-number')
|
||||
const paginationType = userOptions.paginationType || 'bullets'
|
||||
|
||||
const swiper = new Swiper(el, {
|
||||
modules: [Navigation, Pagination, Autoplay, EffectFade],
|
||||
slidesPerView: userOptions.slidesPerView || 1,
|
||||
spaceBetween: userOptions.spaceBetween !== undefined ? userOptions.spaceBetween : 24,
|
||||
loop: userOptions.loop !== false,
|
||||
speed: userOptions.speed || 1000,
|
||||
autoplay: userOptions.autoplay || { delay: 6000, disableOnInteraction: false },
|
||||
effect: userOptions.effect || 'slide',
|
||||
centeredSlides: userOptions.centeredSlides || false,
|
||||
slidesPerGroup: userOptions.slidesPerGroup || 1,
|
||||
breakpoints: userOptions.breakpoints || {},
|
||||
navigation: {
|
||||
nextEl: el.querySelector('.slider-next'),
|
||||
prevEl: el.querySelector('.slider-prev'),
|
||||
},
|
||||
pagination: paginationEl ? {
|
||||
el: paginationEl,
|
||||
type: paginationType,
|
||||
clickable: true,
|
||||
renderBullet: hasNumberPagi ? function (index, className) {
|
||||
const num = index + 1
|
||||
return '<span class="' + className + ' number">' + (num < 10 ? '0' + num : num) + '</span>'
|
||||
} : undefined,
|
||||
formatFractionCurrent: function (n) { return n < 10 ? '0' + n : n },
|
||||
formatFractionTotal: function (n) { return n < 10 ? '0' + n : n },
|
||||
} : false,
|
||||
|
||||
on: {
|
||||
slideChange: function () {
|
||||
setTimeout(function () {
|
||||
if (swiper.params.mousewheel) swiper.params.mousewheel.releaseOnEdges = false
|
||||
}, 500)
|
||||
},
|
||||
reachEnd: function () {
|
||||
setTimeout(function () {
|
||||
if (swiper.params.mousewheel) swiper.params.mousewheel.releaseOnEdges = true
|
||||
}, 750)
|
||||
},
|
||||
...(userOptions.on || {}),
|
||||
},
|
||||
})
|
||||
|
||||
instances.current.push(swiper)
|
||||
} catch (e) {
|
||||
console.warn('useSwiper: failed to init', el.id || el.className, e)
|
||||
}
|
||||
})
|
||||
|
||||
// External controls: [data-slider-prev] and [data-slider-next]
|
||||
const handleClick = (e) => {
|
||||
const btn = e.target.closest('[data-slider-prev], [data-slider-next]')
|
||||
if (!btn) return
|
||||
const selector = btn.dataset.sliderPrev || btn.dataset.sliderNext
|
||||
const sliderEl = document.querySelector(selector)
|
||||
if (!sliderEl || !sliderEl.swiper) return
|
||||
if (btn.dataset.sliderPrev) sliderEl.swiper.slidePrev()
|
||||
else sliderEl.swiper.slideNext()
|
||||
}
|
||||
container.addEventListener('click', handleClick)
|
||||
|
||||
// Slider tabs: [data-slider-tab]
|
||||
const tabContainers = container.querySelectorAll('[data-slider-tab]')
|
||||
tabContainers.forEach(tc => {
|
||||
const tabButtons = tc.querySelectorAll('.tab-btn')
|
||||
const sliderSelector = tc.dataset.sliderTab
|
||||
const sliderEl = document.querySelector(sliderSelector)
|
||||
if (!sliderEl || !sliderEl.swiper || !tabButtons.length) return
|
||||
|
||||
const swiper = sliderEl.swiper
|
||||
|
||||
const setActive = (btn) => {
|
||||
tabButtons.forEach(b => b.classList.remove('active'))
|
||||
btn.classList.add('active')
|
||||
}
|
||||
|
||||
tabButtons.forEach((btn, i) => {
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
setActive(btn)
|
||||
swiper.slideTo(i)
|
||||
})
|
||||
})
|
||||
|
||||
swiper.on('slideChange', () => {
|
||||
const idx = swiper.realIndex
|
||||
if (tabButtons[idx]) setActive(tabButtons[idx])
|
||||
})
|
||||
|
||||
// Set initial active
|
||||
if (tabButtons[swiper.activeIndex]) {
|
||||
tabButtons[swiper.activeIndex].classList.add('active')
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
instances.current.forEach(s => s.destroy(true, true))
|
||||
instances.current = []
|
||||
container.removeEventListener('click', handleClick)
|
||||
}
|
||||
}, [containerRef, pathname])
|
||||
}
|
||||
@@ -3,6 +3,9 @@ import { createRoot } from 'react-dom/client'
|
||||
import App from './App.jsx'
|
||||
|
||||
// Vendors
|
||||
import "swiper/css"
|
||||
import "swiper/css/navigation"
|
||||
import "swiper/css/pagination"
|
||||
import './css/bootstrap.css'
|
||||
import './css/swiper-bundle.css'
|
||||
import './css/magnific-popup.css'
|
||||
|
||||
Reference in New Issue
Block a user