@rtstic.dev/pulse 0.0.55 → 0.0.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/form/book-a-demo.js +679 -2
- package/dist/form/index.js +962 -2
- package/dist/form/index.js.map +2 -2
- package/dist/form/pricing.css +2 -0
- package/dist/form/pricing.js +790 -2
- package/dist/form/styles.css +140 -1
- package/dist/global/accordions-v2.js +262 -1
- package/dist/global/accordions.js +237 -1
- package/dist/global/faqs.js +116 -1
- package/dist/global/loader.js +76 -1
- package/dist/global/styles.css +252 -1
- package/dist/home/depth.js +243 -3
- package/dist/home/hero-animation/loader.js +67810 -1397
- package/dist/home/hero-animation/scroll.js +401 -1
- package/dist/home/hero-animation/styles.css +233 -1
- package/dist/home/hero-animation/torch.js +62 -1
- package/dist/home/horizontal-scroll.css +49 -1
- package/dist/home/horizontal-scroll.js +140 -1
- package/dist/home/tabs-v2.js +134 -1
- package/dist/home/tabs.js +163 -1
- package/dist/lever/styles.css +31 -1
- package/dist/marquee/index.js +557 -2
- package/dist/marquee/styles.css +26 -1
- package/dist/slider/freescroll-cards.js +51 -1
- package/dist/slider/freescroll-slider.js +31 -1
- package/dist/slider/testimonial.js +30 -1
- package/package.json +3 -3
|
@@ -1 +1,62 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
// src/home/hero-animation/torch.ts
|
|
4
|
+
var config = { darkness: 0.5, torchSize: 520, clear: 300 };
|
|
5
|
+
var section = document.getElementById("gallery");
|
|
6
|
+
var triggerSection = document.getElementById("trigger-gallery");
|
|
7
|
+
var grid = document.getElementById("grid");
|
|
8
|
+
var torch = section?.querySelector(".torch");
|
|
9
|
+
section.style.setProperty("--darkness", String(config.darkness));
|
|
10
|
+
section.style.setProperty("--torch-size", `${config.torchSize}px`);
|
|
11
|
+
section.style.setProperty("--clear", `${config.clear}px`);
|
|
12
|
+
var clamp01 = (v) => Math.max(0, Math.min(1, v));
|
|
13
|
+
var setFromTriggerPoint = (clientX, clientY) => {
|
|
14
|
+
const tRect = triggerSection.getBoundingClientRect();
|
|
15
|
+
const gRect = section.getBoundingClientRect();
|
|
16
|
+
const rx = clamp01((clientX - tRect.left) / tRect.width);
|
|
17
|
+
const ry = clamp01((clientY - tRect.top) / tRect.height);
|
|
18
|
+
const gx = rx * gRect.width;
|
|
19
|
+
const gy = ry * gRect.height;
|
|
20
|
+
section.style.setProperty("--x", `${gx}px`);
|
|
21
|
+
section.style.setProperty("--y", `${gy}px`);
|
|
22
|
+
};
|
|
23
|
+
var centerTorch = () => {
|
|
24
|
+
const gRect = section.getBoundingClientRect();
|
|
25
|
+
section.style.setProperty("--x", `${gRect.width / 2}px`);
|
|
26
|
+
section.style.setProperty("--y", `${gRect.height / 2}px`);
|
|
27
|
+
};
|
|
28
|
+
centerTorch();
|
|
29
|
+
var showTorch = () => {
|
|
30
|
+
if (torch) torch.style.opacity = "1";
|
|
31
|
+
};
|
|
32
|
+
var hideTorch = () => {
|
|
33
|
+
if (torch) torch.style.opacity = "0";
|
|
34
|
+
centerTorch();
|
|
35
|
+
};
|
|
36
|
+
if (triggerSection) {
|
|
37
|
+
triggerSection.addEventListener("mousemove", (e) => {
|
|
38
|
+
showTorch();
|
|
39
|
+
setFromTriggerPoint(e.clientX, e.clientY);
|
|
40
|
+
});
|
|
41
|
+
triggerSection.addEventListener("mouseenter", showTorch);
|
|
42
|
+
triggerSection.addEventListener("mouseleave", hideTorch);
|
|
43
|
+
}
|
|
44
|
+
var moveTouch = (touch) => setFromTriggerPoint(touch.clientX, touch.clientY);
|
|
45
|
+
triggerSection?.addEventListener("touchstart", (e) => {
|
|
46
|
+
showTorch();
|
|
47
|
+
moveTouch(e.touches[0]);
|
|
48
|
+
}, { passive: true });
|
|
49
|
+
triggerSection?.addEventListener("touchmove", (e) => moveTouch(e.touches[0]), { passive: true });
|
|
50
|
+
triggerSection?.addEventListener("touchend", hideTorch);
|
|
51
|
+
if (!triggerSection) {
|
|
52
|
+
section.addEventListener("mousemove", (e) => {
|
|
53
|
+
const r = section.getBoundingClientRect();
|
|
54
|
+
section.style.setProperty("--x", `${e.clientX - r.left}px`);
|
|
55
|
+
section.style.setProperty("--y", `${e.clientY - r.top}px`);
|
|
56
|
+
showTorch();
|
|
57
|
+
});
|
|
58
|
+
section.addEventListener("mouseleave", hideTorch);
|
|
59
|
+
section.addEventListener("mouseenter", showTorch);
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
//# sourceMappingURL=torch.js.map
|
|
@@ -1 +1,49 @@
|
|
|
1
|
-
|
|
1
|
+
/* src/home/horizontal-scroll.css */
|
|
2
|
+
[horizontal-scroll-section] {
|
|
3
|
+
height: 100vh;
|
|
4
|
+
overflow: hidden;
|
|
5
|
+
background: #000;
|
|
6
|
+
position: relative;
|
|
7
|
+
justify-content: flex-start;
|
|
8
|
+
}
|
|
9
|
+
[horizontal-scroll-wrapper] {
|
|
10
|
+
display: flex;
|
|
11
|
+
height: 100%;
|
|
12
|
+
will-change: transform;
|
|
13
|
+
gap: 40px;
|
|
14
|
+
}
|
|
15
|
+
.panel {
|
|
16
|
+
min-width: 100vw;
|
|
17
|
+
width: 100vw;
|
|
18
|
+
height: 100vh;
|
|
19
|
+
position: relative;
|
|
20
|
+
z-index: 1;
|
|
21
|
+
}
|
|
22
|
+
.panel.is-title {
|
|
23
|
+
min-width: 60vw;
|
|
24
|
+
width: 60vw;
|
|
25
|
+
position: relative;
|
|
26
|
+
z-index: 1;
|
|
27
|
+
}
|
|
28
|
+
@media (max-width: 991px) {
|
|
29
|
+
[horizontal-scroll-section] {
|
|
30
|
+
height: auto;
|
|
31
|
+
overflow: visible;
|
|
32
|
+
display: block;
|
|
33
|
+
padding: 0;
|
|
34
|
+
}
|
|
35
|
+
[horizontal-scroll-wrapper] {
|
|
36
|
+
display: block;
|
|
37
|
+
height: auto;
|
|
38
|
+
width: 100%;
|
|
39
|
+
}
|
|
40
|
+
.panel {
|
|
41
|
+
min-width: 100%;
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 100vh;
|
|
44
|
+
position: sticky;
|
|
45
|
+
top: 0;
|
|
46
|
+
box-shadow: 0 -5px 20px rgba(0, 0, 0, 0.5);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/*# sourceMappingURL=horizontal-scroll.css.map */
|
|
@@ -1 +1,140 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
// src/home/horizontal-scroll.ts
|
|
4
|
+
function waitForGSAPAndScrollTrigger() {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
const maxAttempts = 50;
|
|
7
|
+
let attempts = 0;
|
|
8
|
+
const check = () => {
|
|
9
|
+
attempts++;
|
|
10
|
+
const gsap = window.gsap;
|
|
11
|
+
const ScrollTrigger = window.ScrollTrigger;
|
|
12
|
+
if (gsap && ScrollTrigger) {
|
|
13
|
+
resolve({ gsap, ScrollTrigger });
|
|
14
|
+
} else if (attempts >= maxAttempts) {
|
|
15
|
+
reject(
|
|
16
|
+
new Error(
|
|
17
|
+
"GSAP or ScrollTrigger failed to load. Ensure they are loaded as <script> tags before this module."
|
|
18
|
+
)
|
|
19
|
+
);
|
|
20
|
+
} else {
|
|
21
|
+
setTimeout(check, 100);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
check();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async function ensureScrollTriggerRegistered() {
|
|
28
|
+
if (typeof window === "undefined") return false;
|
|
29
|
+
try {
|
|
30
|
+
const { gsap, ScrollTrigger } = await waitForGSAPAndScrollTrigger();
|
|
31
|
+
const isAlreadyRegistered = gsap.plugins?.scrollTrigger !== void 0;
|
|
32
|
+
if (!isAlreadyRegistered) {
|
|
33
|
+
gsap.registerPlugin(ScrollTrigger);
|
|
34
|
+
} else {
|
|
35
|
+
console.log("\u2713 ScrollTrigger already registered");
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.error("Failed to register ScrollTrigger:", err);
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function initHorizontalScroll() {
|
|
44
|
+
const registered = await ensureScrollTriggerRegistered();
|
|
45
|
+
if (!registered) return;
|
|
46
|
+
const gsap = window.gsap;
|
|
47
|
+
const mm = gsap.matchMedia?.();
|
|
48
|
+
if (!mm) {
|
|
49
|
+
console.error("GSAP matchMedia() is unavailable.");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
mm.add("(min-width: 992px)", () => {
|
|
53
|
+
const sections = document.querySelectorAll(
|
|
54
|
+
"[horizontal-scroll-section]"
|
|
55
|
+
);
|
|
56
|
+
if (sections.length === 0) {
|
|
57
|
+
console.warn("No elements found with [horizontal-scroll-section]");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
sections.forEach((section) => {
|
|
61
|
+
const wrapper = section.querySelector(
|
|
62
|
+
"[horizontal-scroll-wrapper]"
|
|
63
|
+
);
|
|
64
|
+
if (!wrapper) {
|
|
65
|
+
console.warn("Missing [horizontal-scroll-wrapper] inside:", section);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const endDistance = () => {
|
|
69
|
+
const dist = wrapper.scrollWidth - window.innerWidth;
|
|
70
|
+
return Math.max(dist, 0);
|
|
71
|
+
};
|
|
72
|
+
if (endDistance() <= 0) {
|
|
73
|
+
console.warn(
|
|
74
|
+
"Wrapper content is not wider than viewport. No scroll needed.",
|
|
75
|
+
wrapper
|
|
76
|
+
);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const triggerId = `hs-${wrapper.dataset.stId || Math.random().toString(16).slice(2)}`;
|
|
80
|
+
const existing = gsap.getById?.(triggerId);
|
|
81
|
+
if (existing) {
|
|
82
|
+
existing.kill();
|
|
83
|
+
}
|
|
84
|
+
wrapper.dataset.stId = triggerId;
|
|
85
|
+
gsap.to(wrapper, {
|
|
86
|
+
x: () => -endDistance(),
|
|
87
|
+
ease: "none",
|
|
88
|
+
scrollTrigger: {
|
|
89
|
+
id: triggerId,
|
|
90
|
+
trigger: section,
|
|
91
|
+
start: "top top",
|
|
92
|
+
end: () => `+=${endDistance()}`,
|
|
93
|
+
pin: true,
|
|
94
|
+
scrub: 1,
|
|
95
|
+
invalidateOnRefresh: true,
|
|
96
|
+
markers: false,
|
|
97
|
+
// Set to true for debugging
|
|
98
|
+
onUpdate: (self) => {
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
return () => {
|
|
104
|
+
try {
|
|
105
|
+
gsap.getChildren?.().forEach((trigger) => {
|
|
106
|
+
if (trigger.id?.startsWith("hs-")) {
|
|
107
|
+
trigger.kill();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
} catch {
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
if (typeof window !== "undefined") {
|
|
116
|
+
if (document.readyState === "loading") {
|
|
117
|
+
document.addEventListener("DOMContentLoaded", async () => {
|
|
118
|
+
try {
|
|
119
|
+
await initHorizontalScroll();
|
|
120
|
+
} catch (err) {
|
|
121
|
+
console.error("Error initializing horizontal scroll:", err);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
} else {
|
|
125
|
+
initHorizontalScroll().catch((err) => {
|
|
126
|
+
console.error("Error initializing horizontal scroll:", err);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
window.addEventListener("load", () => {
|
|
130
|
+
try {
|
|
131
|
+
if (window.ScrollTrigger?.refresh) {
|
|
132
|
+
window.ScrollTrigger.refresh();
|
|
133
|
+
}
|
|
134
|
+
} catch (err) {
|
|
135
|
+
console.error("Error refreshing ScrollTrigger:", err);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
})();
|
|
140
|
+
//# sourceMappingURL=horizontal-scroll.js.map
|
package/dist/home/tabs-v2.js
CHANGED
|
@@ -1 +1,134 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
// src/home/tabs-v2.ts
|
|
4
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
5
|
+
const mediaQuery = window.matchMedia("(min-width: 992px)");
|
|
6
|
+
let cleanup = null;
|
|
7
|
+
function initPulseTabs() {
|
|
8
|
+
const tabConfigs = [
|
|
9
|
+
{ identifier: "1", autoplayDuration: "22000ms" },
|
|
10
|
+
{ identifier: "2", autoplayDuration: "12000ms" },
|
|
11
|
+
{ identifier: "3", autoplayDuration: "18000ms" }
|
|
12
|
+
];
|
|
13
|
+
function parseDuration(duration) {
|
|
14
|
+
if (duration.endsWith("ms")) {
|
|
15
|
+
return parseInt(duration.replace("ms", ""), 10);
|
|
16
|
+
}
|
|
17
|
+
if (duration.endsWith("s")) {
|
|
18
|
+
return parseFloat(duration.replace("s", "")) * 1e3;
|
|
19
|
+
}
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
function activateTab(identifier) {
|
|
23
|
+
const tabContents = document.querySelectorAll("[pulse-tab-content]");
|
|
24
|
+
tabContents.forEach((el) => {
|
|
25
|
+
const value = el.getAttribute("pulse-tab-content");
|
|
26
|
+
el.setAttribute("active-tabcontent", value === identifier ? "true" : "false");
|
|
27
|
+
});
|
|
28
|
+
const tabLinks2 = document.querySelectorAll("[pulse-tab-link]");
|
|
29
|
+
tabLinks2.forEach((el) => {
|
|
30
|
+
const value = el.getAttribute("pulse-tab-link");
|
|
31
|
+
el.setAttribute("active-tablink", value === identifier ? "true" : "false");
|
|
32
|
+
});
|
|
33
|
+
handleTabVideos(identifier);
|
|
34
|
+
}
|
|
35
|
+
function handleTabVideos(activeIdentifier) {
|
|
36
|
+
const tabContents = document.querySelectorAll("[pulse-tab-content]");
|
|
37
|
+
tabContents.forEach((tab) => {
|
|
38
|
+
const identifier = tab.getAttribute("pulse-tab-content");
|
|
39
|
+
const video = tab.querySelector("video");
|
|
40
|
+
if (!video) return;
|
|
41
|
+
if (identifier === activeIdentifier) {
|
|
42
|
+
video.loop = true;
|
|
43
|
+
video.play().catch(() => {
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
video.pause();
|
|
47
|
+
video.currentTime = 0;
|
|
48
|
+
video.loop = false;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function getDurationForIdentifier(identifier) {
|
|
53
|
+
const config = tabConfigs.find((tab) => tab.identifier === identifier);
|
|
54
|
+
return config ? parseDuration(config.autoplayDuration) : 0;
|
|
55
|
+
}
|
|
56
|
+
function getIndexForIdentifier(identifier) {
|
|
57
|
+
return tabConfigs.findIndex((tab) => tab.identifier === identifier);
|
|
58
|
+
}
|
|
59
|
+
let autoplayTimeout = null;
|
|
60
|
+
let currentIndex = 0;
|
|
61
|
+
function autoplayNext() {
|
|
62
|
+
const config = tabConfigs[currentIndex];
|
|
63
|
+
const delay = parseDuration(config.autoplayDuration);
|
|
64
|
+
activateTab(config.identifier);
|
|
65
|
+
handleTabLinkPathAnimation(config.identifier, delay);
|
|
66
|
+
currentIndex = (currentIndex + 1) % tabConfigs.length;
|
|
67
|
+
autoplayTimeout = window.setTimeout(autoplayNext, delay);
|
|
68
|
+
}
|
|
69
|
+
function startAutoplay() {
|
|
70
|
+
stopAutoplay();
|
|
71
|
+
currentIndex = 0;
|
|
72
|
+
autoplayNext();
|
|
73
|
+
}
|
|
74
|
+
function stopAutoplay() {
|
|
75
|
+
if (autoplayTimeout !== null) {
|
|
76
|
+
clearTimeout(autoplayTimeout);
|
|
77
|
+
autoplayTimeout = null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function handleTabLinkPathAnimation(activeIdentifier, durationMs) {
|
|
81
|
+
const tabLinks2 = document.querySelectorAll("[pulse-tab-link]");
|
|
82
|
+
tabLinks2.forEach((link) => {
|
|
83
|
+
const identifier = link.getAttribute("pulse-tab-link");
|
|
84
|
+
const path = link.querySelector("[tablink-path]");
|
|
85
|
+
if (!path) return;
|
|
86
|
+
path.style.transition = "none";
|
|
87
|
+
path.style.width = "0%";
|
|
88
|
+
if (identifier === activeIdentifier) {
|
|
89
|
+
path.getBoundingClientRect();
|
|
90
|
+
path.style.transition = `width ${durationMs}ms linear`;
|
|
91
|
+
path.style.width = "100%";
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const tabLinks = document.querySelectorAll("[pulse-tab-link]");
|
|
96
|
+
tabLinks.forEach((link) => {
|
|
97
|
+
link.addEventListener("click", () => {
|
|
98
|
+
const identifier = link.getAttribute("pulse-tab-link");
|
|
99
|
+
if (!identifier) return;
|
|
100
|
+
stopAutoplay();
|
|
101
|
+
activateTab(identifier);
|
|
102
|
+
const duration = getDurationForIdentifier(identifier);
|
|
103
|
+
handleTabLinkPathAnimation(identifier, duration);
|
|
104
|
+
const index = getIndexForIdentifier(identifier);
|
|
105
|
+
if (index !== -1) {
|
|
106
|
+
currentIndex = (index + 1) % tabConfigs.length;
|
|
107
|
+
}
|
|
108
|
+
autoplayTimeout = window.setTimeout(autoplayNext, duration);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
activateTab(tabConfigs[0].identifier);
|
|
112
|
+
startAutoplay();
|
|
113
|
+
window.activateTab = activateTab;
|
|
114
|
+
window.startTabAutoplay = startAutoplay;
|
|
115
|
+
window.stopTabAutoplay = stopAutoplay;
|
|
116
|
+
return stopAutoplay;
|
|
117
|
+
}
|
|
118
|
+
function handleBreakpoint(e) {
|
|
119
|
+
if (e.matches) {
|
|
120
|
+
if (!cleanup) {
|
|
121
|
+
cleanup = initPulseTabs();
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
if (cleanup) {
|
|
125
|
+
cleanup();
|
|
126
|
+
cleanup = null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
handleBreakpoint(mediaQuery);
|
|
131
|
+
mediaQuery.addEventListener("change", handleBreakpoint);
|
|
132
|
+
});
|
|
133
|
+
})();
|
|
134
|
+
//# sourceMappingURL=tabs-v2.js.map
|
package/dist/home/tabs.js
CHANGED
|
@@ -1 +1,163 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
// src/home/tabs.ts
|
|
4
|
+
var TABLINK_ATTR = "influur-tablink";
|
|
5
|
+
var TABCONTENT_ATTR = "influur-tabcontent";
|
|
6
|
+
var ACTIVE_ATTR = "influur-tablink-active";
|
|
7
|
+
var FILL_ATTR = "influur-tablink-fill";
|
|
8
|
+
var TAB_AUTOPLAY_INTERVAL = 4e3;
|
|
9
|
+
function isHTMLElement(node) {
|
|
10
|
+
return !!node && node.nodeType === Node.ELEMENT_NODE;
|
|
11
|
+
}
|
|
12
|
+
function getAttr(el, attr) {
|
|
13
|
+
const val = el.getAttribute(attr);
|
|
14
|
+
if (val === null) return null;
|
|
15
|
+
const trimmed = val.trim();
|
|
16
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
17
|
+
}
|
|
18
|
+
function queryAllHTMLElements(selector, root = document) {
|
|
19
|
+
return Array.from(root.querySelectorAll(selector)).filter(isHTMLElement);
|
|
20
|
+
}
|
|
21
|
+
function hideAllContents(contents) {
|
|
22
|
+
for (const c of contents) {
|
|
23
|
+
c.style.display = "none";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function deactivateAllLinks(tablinks) {
|
|
27
|
+
for (const l of tablinks) {
|
|
28
|
+
l.setAttribute(ACTIVE_ATTR, "false");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function showContent(el) {
|
|
32
|
+
el.style.display = "block";
|
|
33
|
+
}
|
|
34
|
+
function findContentByValue(value, contents) {
|
|
35
|
+
for (const c of contents) {
|
|
36
|
+
const v = getAttr(c, TABCONTENT_ATTR);
|
|
37
|
+
if (v !== null && v === value) return c;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
function findLinkByValue(value, tablinks) {
|
|
42
|
+
for (const l of tablinks) {
|
|
43
|
+
const v = getAttr(l, TABLINK_ATTR);
|
|
44
|
+
if (v !== null && v === value) return l;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
function getFillEl(link) {
|
|
49
|
+
const el = link.querySelector(`[${FILL_ATTR}]`);
|
|
50
|
+
return el ?? null;
|
|
51
|
+
}
|
|
52
|
+
function resetAllFills(tablinks) {
|
|
53
|
+
for (const l of tablinks) {
|
|
54
|
+
const fill = getFillEl(l);
|
|
55
|
+
if (fill) fill.style.width = "0%";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
59
|
+
const tablinks = queryAllHTMLElements(`[${TABLINK_ATTR}]`);
|
|
60
|
+
const contents = queryAllHTMLElements(`[${TABCONTENT_ATTR}]`);
|
|
61
|
+
if (contents.length === 0) {
|
|
62
|
+
console.warn("No tab contents found.");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (tablinks.length === 0) {
|
|
66
|
+
console.warn("No tab links found. Hiding all tab contents.");
|
|
67
|
+
hideAllContents(contents);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
let currentIndex = 0;
|
|
71
|
+
let autoplayTimer = null;
|
|
72
|
+
let rafId = null;
|
|
73
|
+
function cancelFillAnimation() {
|
|
74
|
+
if (rafId !== null) {
|
|
75
|
+
cancelAnimationFrame(rafId);
|
|
76
|
+
rafId = null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function startFillAnimation(activeLink) {
|
|
80
|
+
cancelFillAnimation();
|
|
81
|
+
resetAllFills(tablinks);
|
|
82
|
+
const fill = getFillEl(activeLink);
|
|
83
|
+
if (!fill) {
|
|
84
|
+
console.warn(`Active tablink is missing ${FILL_ATTR} child`, activeLink);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const duration = Math.max(0, TAB_AUTOPLAY_INTERVAL);
|
|
88
|
+
const start = performance.now();
|
|
89
|
+
const tick = (now) => {
|
|
90
|
+
const elapsed = now - start;
|
|
91
|
+
const progress = duration === 0 ? 1 : Math.min(1, elapsed / duration);
|
|
92
|
+
fill.style.width = `${(progress * 100).toFixed(4)}%`;
|
|
93
|
+
if (activeLink.getAttribute(ACTIVE_ATTR) === "true" && progress < 1) {
|
|
94
|
+
rafId = requestAnimationFrame(tick);
|
|
95
|
+
} else {
|
|
96
|
+
rafId = null;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
fill.style.width = "0%";
|
|
100
|
+
rafId = requestAnimationFrame(tick);
|
|
101
|
+
}
|
|
102
|
+
const changeTab = (attributeValue) => {
|
|
103
|
+
if (typeof attributeValue !== "string" || attributeValue.trim().length === 0) {
|
|
104
|
+
console.warn("changeTab called with invalid attributeValue:", attributeValue);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
hideAllContents(contents);
|
|
108
|
+
deactivateAllLinks(tablinks);
|
|
109
|
+
const matchContent = findContentByValue(attributeValue, contents);
|
|
110
|
+
const matchLink = findLinkByValue(attributeValue, tablinks);
|
|
111
|
+
if (!matchContent || !matchLink) {
|
|
112
|
+
console.warn(`No matching pair found for value "${attributeValue}"`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
showContent(matchContent);
|
|
116
|
+
matchLink.setAttribute(ACTIVE_ATTR, "true");
|
|
117
|
+
const index = tablinks.indexOf(matchLink);
|
|
118
|
+
if (index >= 0) currentIndex = index;
|
|
119
|
+
startFillAnimation(matchLink);
|
|
120
|
+
};
|
|
121
|
+
window.changeTab = changeTab;
|
|
122
|
+
for (const link of tablinks) {
|
|
123
|
+
link.addEventListener("click", (ev) => {
|
|
124
|
+
if (ev.target?.closest("a")) ev.preventDefault();
|
|
125
|
+
const val = getAttr(link, TABLINK_ATTR);
|
|
126
|
+
if (val === null) {
|
|
127
|
+
console.warn(`Tablink missing valid ${TABLINK_ATTR} value`, link);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
changeTab(val);
|
|
131
|
+
restartAutoplay();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const firstVal = getAttr(tablinks[0], TABLINK_ATTR);
|
|
135
|
+
if (firstVal === null) {
|
|
136
|
+
console.warn(`First tablink missing ${TABLINK_ATTR} value. Hiding all tab contents.`);
|
|
137
|
+
hideAllContents(contents);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
changeTab(firstVal);
|
|
141
|
+
function autoplayStep() {
|
|
142
|
+
if (tablinks.length === 0) return;
|
|
143
|
+
currentIndex = (currentIndex + 1) % tablinks.length;
|
|
144
|
+
const val = getAttr(tablinks[currentIndex], TABLINK_ATTR);
|
|
145
|
+
if (val) changeTab(val);
|
|
146
|
+
}
|
|
147
|
+
function startAutoplay() {
|
|
148
|
+
stopAutoplayTimerOnly();
|
|
149
|
+
autoplayTimer = window.setInterval(autoplayStep, TAB_AUTOPLAY_INTERVAL);
|
|
150
|
+
}
|
|
151
|
+
function stopAutoplayTimerOnly() {
|
|
152
|
+
if (autoplayTimer !== null) {
|
|
153
|
+
clearInterval(autoplayTimer);
|
|
154
|
+
autoplayTimer = null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function restartAutoplay() {
|
|
158
|
+
startAutoplay();
|
|
159
|
+
}
|
|
160
|
+
startAutoplay();
|
|
161
|
+
});
|
|
162
|
+
})();
|
|
163
|
+
//# sourceMappingURL=tabs.js.map
|
package/dist/lever/styles.css
CHANGED
|
@@ -1 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
/* src/lever/styles.css */
|
|
2
|
+
.embed-flex {
|
|
3
|
+
margin: 0;
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
}
|
|
7
|
+
span.lever-job-tag {
|
|
8
|
+
display: inline-block;
|
|
9
|
+
background: #333232 !important;
|
|
10
|
+
border-radius: 4px !important;
|
|
11
|
+
padding: 2px 10px !important;
|
|
12
|
+
font-size: 12px !important;
|
|
13
|
+
width: max-content !important;
|
|
14
|
+
font-weight: 400 !important;
|
|
15
|
+
margin-bottom: 10px !important;
|
|
16
|
+
}
|
|
17
|
+
.lever-department-title {
|
|
18
|
+
display: none;
|
|
19
|
+
}
|
|
20
|
+
.lever-job {
|
|
21
|
+
background: #121212 !important;
|
|
22
|
+
}
|
|
23
|
+
.lever-job-title {
|
|
24
|
+
text-decoration: none !important;
|
|
25
|
+
font-family: var(--_font-family---title);
|
|
26
|
+
font-size: var(--_text-size---title--m);
|
|
27
|
+
line-height: var(--_line-height---line-height-title--m);
|
|
28
|
+
font-weight: var(--_font-weight---font-weight-title--m);
|
|
29
|
+
letter-spacing: var(--_letter-spacing---letter-spacing-title--m);
|
|
30
|
+
}
|
|
31
|
+
/*# sourceMappingURL=styles.css.map */
|