well-petal 0.0.19 → 0.0.21

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/petal.js CHANGED
@@ -50,13 +50,33 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
50
50
 
51
51
  /***/ }),
52
52
 
53
+ /***/ "./src/animation.ts":
54
+ /*!**************************!*\
55
+ !*** ./src/animation.ts ***!
56
+ \**************************/
57
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
58
+
59
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ animateMaskClosed: () => (/* binding */ animateMaskClosed),\n/* harmony export */ animateMaskOpen: () => (/* binding */ animateMaskOpen),\n/* harmony export */ getAnimation: () => (/* binding */ getAnimation),\n/* harmony export */ getAnimationNew: () => (/* binding */ getAnimationNew),\n/* harmony export */ isPopupAnimation: () => (/* binding */ isPopupAnimation)\n/* harmony export */ });\nconst validAnimations = [\"scale-up\", \"scale-down\", \"slide-up\", \"slide-down\", \"slide-left\", \"slide-right\"];\nconst animationMap = {\n \"scale-up\": [animateScaleUp, animateScaleDown],\n \"scale-down\": [animateScaleDown, animateScaleUp],\n \"slide-up\": [animateSlideUp, animateSlideDown],\n \"slide-down\": [animateSlideDown, animateSlideUp],\n \"slide-left\": [animateSlideLeft, animateSlideRight],\n \"slide-right\": [animateSlideRight, animateSlideLeft],\n};\nfunction getAnimationNew(popup) {\n // Popup Settings\n const animationDesktop = getPopupAnimation(popup.getAttribute(\"petal-anim\"));\n const animationMobile = getPopupAnimation(popup.getAttribute(\"petal-anim-mobile\")) || animationDesktop;\n const duration = parseFloat(popup.getAttribute(\"petal-duration\") || \"0.5\");\n const open = getComputedStyle(popup).display !== \"none\";\n const animation = isMobile() ? animationMobile : animationDesktop;\n const [normal, reverse] = animationMap[animation];\n const gsapAnim = open ? reverse(false) : normal(true);\n gsapAnim.to.duration = duration;\n return gsapAnim;\n}\n// Animation selection\nfunction getAnimation(animation, open) {\n const [normal, reverse] = animationMap[animation];\n return open ? reverse(false) : normal(true);\n}\n// Individual animations\nfunction animateScaleUp(show) {\n return {\n from: { scale: 0 },\n to: { scale: 1, opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateScaleDown(show) {\n return {\n from: { scale: 1 },\n to: { scale: 0, opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateSlideUp(show) {\n return {\n from: { y: \"100%\", x: \"0%\" },\n to: { y: \"0%\", opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateSlideDown(show) {\n return {\n from: { y: \"0%\", x: \"0%\" },\n to: { y: \"100%\", opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateSlideRight(show) {\n return {\n from: { x: \"0%\", y: \"0%\" },\n to: { x: \"100%\", opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateSlideLeft(show) {\n return {\n from: { x: \"100%\", y: \"0%\" },\n to: { x: \"0%\", opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\n// Reusable mask animations\nfunction animateMaskOpen(opacity) {\n return {\n from: { opacity: 0 },\n to: { opacity: opacity, duration: 0.5 },\n };\n}\nfunction animateMaskClosed(opacity) {\n return {\n from: { opacity: opacity },\n to: { opacity: 0, duration: 0.5 },\n };\n}\n// Device check\nfunction isMobile() {\n return window.innerWidth <= 768;\n}\n// Validate popup animation string\nfunction isPopupAnimation(value) {\n return validAnimations.includes(value);\n}\n// Safe parser with fallback\nfunction getPopupAnimation(raw) {\n return isPopupAnimation(raw !== null && raw !== void 0 ? raw : \"\") ? raw : \"slide-up\";\n}\n\n\n//# sourceURL=webpack://petal/./src/animation.ts?");
60
+
61
+ /***/ }),
62
+
53
63
  /***/ "./src/petal.ts":
54
64
  /*!**********************!*\
55
65
  !*** ./src/petal.ts ***!
56
66
  \**********************/
57
67
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
58
68
 
59
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ \"./node_modules/gsap/index.js\");\n\nconst validAnimations = [\"scale-up\", \"scale-down\", \"slide-up\", \"slide-down\", \"slide-left\", \"slide-right\"];\nconst animationMap = {\n \"scale-up\": [animateScaleUp, animateScaleDown],\n \"scale-down\": [animateScaleDown, animateScaleUp],\n \"slide-up\": [animateSlideUp, animateSlideDown],\n \"slide-down\": [animateSlideDown, animateSlideUp],\n \"slide-left\": [animateSlideLeft, animateSlideRight],\n \"slide-right\": [animateSlideRight, animateSlideLeft],\n};\n// Initialize popup triggers\ndocument.querySelectorAll(\"[petal-el='trigger'], [petal-el='mask']\").forEach((trigger) => {\n const popupName = trigger.getAttribute(\"petal\");\n if (!popupName) {\n logError(\"NO_NAME\", \"\", trigger);\n return;\n }\n const popup = document.querySelector(`[petal='${popupName}'][petal-el='popup']`);\n if (!popup) {\n logError(\"NO_POPUP\", popupName, trigger);\n return;\n }\n // Popup Elements\n const mask = popup.querySelector(\"[petal-el='mask']\");\n const slot = popup.querySelector(\"[petal-el='slot']\");\n // Mask Settings\n const maskOpacity = parseFloat((mask === null || mask === void 0 ? void 0 : mask.getAttribute(\"petal-mask-opacity\")) || \"0.15\");\n // Popup Settings\n const animation = getPopupAnimation(popup.getAttribute(\"petal-anim\"));\n const animationMobile = getPopupAnimation(popup.getAttribute(\"petal-anim-mobile\")) || animation;\n const duration = parseFloat(popup.getAttribute(\"petal-duration\") || \"1\");\n // Initialize GSAP timeline\n const tl = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].timeline();\n // Initialize Popup\n gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].set(slot, { opacity: 0 });\n trigger.addEventListener(\"click\", () => animate(popup));\n // Animate open/close\n function animate(popup) {\n // Check if the popup is open or closed\n const open = getComputedStyle(popup).display !== \"none\";\n if (!slot)\n console.warn(\"A slot was not found for this popup.\");\n console.log(`[Petal Popup]`, {\n popupName,\n animationDesktop: animation,\n animationMobile,\n duration,\n maskOpacity,\n isMobile: isMobile(),\n open,\n });\n // If the popup is closed, open it\n if (!open) {\n // Animate Popup\n tl.set(popup, { display: \"flex\" });\n // Animate Mask\n if (mask) {\n tl.fromTo(mask, animateMaskOpen(maskOpacity).from, animateMaskOpen(maskOpacity).to, \"<\");\n }\n // Animate the popup\n const anim = isMobile() ? getAnimation(animationMobile, open) : getAnimation(animation, open);\n anim.to.duration = duration;\n tl.fromTo(slot, anim.from, anim.to);\n }\n // If the popup is open, close it\n if (open) {\n // Pause all <video> elements inside the popup before hiding it\n popup.querySelectorAll(\"video\").forEach((video) => {\n console.log(\"[Petal Popup] Pausing video:\", video);\n if (!video.paused)\n video.pause();\n });\n // Animate the popup\n const anim = isMobile() ? getAnimation(animationMobile, open) : getAnimation(animation, open);\n anim.to.duration = duration;\n tl.fromTo(slot, anim.from, anim.to);\n // Animate Mask Closed\n if (mask) {\n tl.fromTo(mask, animateMaskClosed(maskOpacity).from, animateMaskClosed(maskOpacity).to, \"<\");\n }\n tl.set(popup, { display: \"none\" });\n }\n }\n});\n// Reusable mask animations\nfunction animateMaskOpen(opacity) {\n return {\n from: { opacity: 0 },\n to: { opacity: opacity, duration: 0.5 },\n };\n}\nfunction animateMaskClosed(opacity) {\n return {\n from: { opacity: opacity },\n to: { opacity: 0, duration: 0.5 },\n };\n}\n// Animation selection\nfunction getAnimation(animation, open) {\n const [normal, reverse] = animationMap[animation];\n return open ? reverse(false) : normal(true);\n}\n// Individual animations\nfunction animateScaleUp(show) {\n return {\n from: { scale: 0 },\n to: { scale: 1, opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateScaleDown(show) {\n return {\n from: { scale: 1 },\n to: { scale: 0, opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateSlideUp(show) {\n return {\n from: { y: \"100%\", x: \"0%\" },\n to: { y: \"0%\", opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateSlideDown(show) {\n return {\n from: { y: \"0%\", x: \"0%\" },\n to: { y: \"100%\", opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateSlideRight(show) {\n return {\n from: { x: \"0%\", y: \"0%\" },\n to: { x: \"100%\", opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\nfunction animateSlideLeft(show) {\n return {\n from: { x: \"100%\", y: \"0%\" },\n to: { x: \"0%\", opacity: show ? 1 : 0, ease: \"power3.inOut\" },\n };\n}\n// Device check\nfunction isMobile() {\n return window.innerWidth <= 768;\n}\n// Validate popup animation string\nfunction isPopupAnimation(value) {\n return validAnimations.includes(value);\n}\n// Safe parser with fallback\nfunction getPopupAnimation(raw) {\n return isPopupAnimation(raw !== null && raw !== void 0 ? raw : \"\") ? raw : \"slide-up\";\n}\n// Centralized error logging\nfunction logError(error, popupName, trigger) {\n switch (error) {\n case \"NO_NAME\":\n console.error(`Trigger is missing the \"petal\" attribute:`, trigger);\n break;\n case \"NO_POPUP\":\n console.error(`Popup with name \"${popupName}\" not found for trigger:`, trigger);\n break;\n default:\n console.error(`Popup error [${error}] for \"${popupName}\":`, trigger);\n }\n}\n\n\n//# sourceURL=webpack://petal/./src/petal.ts?");
69
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! gsap */ \"./node_modules/gsap/index.js\");\n/* harmony import */ var _animation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./animation */ \"./src/animation.ts\");\n/* harmony import */ var _video__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./video */ \"./src/video.ts\");\n\n\n\n// Initialize popup triggers\ndocument.querySelectorAll(\"[petal-el='trigger'], [petal-el='mask']\").forEach((trigger) => {\n const popupName = trigger.getAttribute(\"petal\");\n if (!popupName) {\n logError(\"NO_NAME\", \"\", trigger);\n return;\n }\n const popup = document.querySelector(`[petal='${popupName}'][petal-el='popup']`);\n if (!popup) {\n logError(\"NO_POPUP\", popupName, trigger);\n return;\n }\n // Popup Elements\n const mask = popup.querySelector(\"[petal-el='mask']\");\n const slot = popup.querySelector(\"[petal-el='slot']\");\n // Mask Settings\n const maskOpacity = parseFloat((mask === null || mask === void 0 ? void 0 : mask.getAttribute(\"petal-mask-opacity\")) || \"0.15\");\n // Initialize GSAP timeline\n const tl = gsap__WEBPACK_IMPORTED_MODULE_2__[\"default\"].timeline();\n // Initialize Popup\n gsap__WEBPACK_IMPORTED_MODULE_2__[\"default\"].set(slot, { opacity: 0 });\n trigger.addEventListener(\"click\", () => animate(popup));\n // Animate open/close\n function animate(popup) {\n if (!slot)\n console.warn(\"A slot was not found for this popup.\");\n console.log(`[Petal Popup]`, {\n popupName,\n popup,\n slot,\n maskOpacity,\n open,\n });\n // If the popup is closed, open it\n if (!open) {\n // Animate Popup\n tl.set(popup, { display: \"flex\" });\n // Animate Mask\n if (mask) {\n tl.fromTo(mask, (0,_animation__WEBPACK_IMPORTED_MODULE_0__.animateMaskOpen)(maskOpacity).from, (0,_animation__WEBPACK_IMPORTED_MODULE_0__.animateMaskOpen)(maskOpacity).to, \"<\");\n }\n // Animate the popup\n const anim = (0,_animation__WEBPACK_IMPORTED_MODULE_0__.getAnimationNew)(popup);\n console.log(anim);\n tl.fromTo(slot, anim.from, anim.to);\n }\n // If the popup is open, close it\n else {\n // Pause any videos in the popup\n (0,_video__WEBPACK_IMPORTED_MODULE_1__.pauseVideo)(popup);\n // Animate the popup\n const anim = (0,_animation__WEBPACK_IMPORTED_MODULE_0__.getAnimationNew)(popup);\n console.log(anim);\n tl.fromTo(slot, anim.from, anim.to);\n // Animate Mask Closed\n if (mask) {\n tl.fromTo(mask, (0,_animation__WEBPACK_IMPORTED_MODULE_0__.animateMaskClosed)(maskOpacity).from, (0,_animation__WEBPACK_IMPORTED_MODULE_0__.animateMaskClosed)(maskOpacity).to, \"<\");\n }\n tl.set(popup, { display: \"none\" });\n }\n }\n});\n// Centralized error logging\nfunction logError(error, popupName, trigger) {\n switch (error) {\n case \"NO_NAME\":\n console.error(`Trigger is missing the \"petal\" attribute:`, trigger);\n break;\n case \"NO_POPUP\":\n console.error(`Popup with name \"${popupName}\" not found for trigger:`, trigger);\n break;\n default:\n console.error(`Popup error [${error}] for \"${popupName}\":`, trigger);\n }\n}\n\n\n//# sourceURL=webpack://petal/./src/petal.ts?");
70
+
71
+ /***/ }),
72
+
73
+ /***/ "./src/video.ts":
74
+ /*!**********************!*\
75
+ !*** ./src/video.ts ***!
76
+ \**********************/
77
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
78
+
79
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ pauseVideo: () => (/* binding */ pauseVideo)\n/* harmony export */ });\nfunction pauseVideo(popup) {\n // Pause all <video> elements inside the popup before hiding it\n popup.querySelectorAll(\"video\").forEach((video) => {\n if (!video.paused)\n video.pause();\n });\n}\n\n\n//# sourceURL=webpack://petal/./src/video.ts?");
60
80
 
61
81
  /***/ })
62
82
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "well-petal",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "description": "Webflow Popups powered by attributes",
5
5
  "main": "petal.js",
6
6
  "scripts": {
@@ -0,0 +1,107 @@
1
+ // Popup animation types
2
+ export type PopupAnimation = "scale-up" | "scale-down" | "slide-up" | "slide-down" | "slide-left" | "slide-right";
3
+
4
+ const validAnimations: PopupAnimation[] = ["scale-up", "scale-down", "slide-up", "slide-down", "slide-left", "slide-right"];
5
+
6
+ const animationMap: Record<PopupAnimation, [(show: boolean) => GSAPTweenVars, (show: boolean) => GSAPTweenVars]> = {
7
+ "scale-up": [animateScaleUp, animateScaleDown],
8
+ "scale-down": [animateScaleDown, animateScaleUp],
9
+ "slide-up": [animateSlideUp, animateSlideDown],
10
+ "slide-down": [animateSlideDown, animateSlideUp],
11
+ "slide-left": [animateSlideLeft, animateSlideRight],
12
+ "slide-right": [animateSlideRight, animateSlideLeft],
13
+ };
14
+
15
+ export function getAnimationNew(popup: HTMLElement): GSAPTweenVars {
16
+ // Popup Settings
17
+ const animationDesktop = getPopupAnimation(popup.getAttribute("petal-anim"));
18
+ const animationMobile = getPopupAnimation(popup.getAttribute("petal-anim-mobile")) || animationDesktop;
19
+ const duration = parseFloat(popup.getAttribute("petal-duration") || "0.5");
20
+ const open = getComputedStyle(popup).display !== "none";
21
+
22
+ const animation = isMobile() ? animationMobile : animationDesktop;
23
+
24
+ const [normal, reverse] = animationMap[animation];
25
+ const gsapAnim = open ? reverse(false) : normal(true);
26
+ gsapAnim.to.duration = duration;
27
+ return gsapAnim;
28
+ }
29
+
30
+ // Animation selection
31
+ export function getAnimation(animation: PopupAnimation, open: boolean): GSAPTweenVars {
32
+ const [normal, reverse] = animationMap[animation];
33
+ return open ? reverse(false) : normal(true);
34
+ }
35
+
36
+ // Individual animations
37
+ function animateScaleUp(show: boolean): GSAPTweenVars {
38
+ return {
39
+ from: { scale: 0 },
40
+ to: { scale: 1, opacity: show ? 1 : 0, ease: "power3.inOut" },
41
+ };
42
+ }
43
+
44
+ function animateScaleDown(show: boolean): GSAPTweenVars {
45
+ return {
46
+ from: { scale: 1 },
47
+ to: { scale: 0, opacity: show ? 1 : 0, ease: "power3.inOut" },
48
+ };
49
+ }
50
+
51
+ function animateSlideUp(show: boolean): GSAPTweenVars {
52
+ return {
53
+ from: { y: "100%", x: "0%" },
54
+ to: { y: "0%", opacity: show ? 1 : 0, ease: "power3.inOut" },
55
+ };
56
+ }
57
+
58
+ function animateSlideDown(show: boolean): GSAPTweenVars {
59
+ return {
60
+ from: { y: "0%", x: "0%" },
61
+ to: { y: "100%", opacity: show ? 1 : 0, ease: "power3.inOut" },
62
+ };
63
+ }
64
+
65
+ function animateSlideRight(show: boolean): GSAPTweenVars {
66
+ return {
67
+ from: { x: "0%", y: "0%" },
68
+ to: { x: "100%", opacity: show ? 1 : 0, ease: "power3.inOut" },
69
+ };
70
+ }
71
+
72
+ function animateSlideLeft(show: boolean): GSAPTweenVars {
73
+ return {
74
+ from: { x: "100%", y: "0%" },
75
+ to: { x: "0%", opacity: show ? 1 : 0, ease: "power3.inOut" },
76
+ };
77
+ }
78
+
79
+ // Reusable mask animations
80
+ export function animateMaskOpen(opacity: number): GSAPTweenVars {
81
+ return {
82
+ from: { opacity: 0 },
83
+ to: { opacity: opacity, duration: 0.5 },
84
+ };
85
+ }
86
+
87
+ export function animateMaskClosed(opacity: number): GSAPTweenVars {
88
+ return {
89
+ from: { opacity: opacity },
90
+ to: { opacity: 0, duration: 0.5 },
91
+ };
92
+ }
93
+
94
+ // Device check
95
+ function isMobile(): boolean {
96
+ return window.innerWidth <= 768;
97
+ }
98
+
99
+ // Validate popup animation string
100
+ export function isPopupAnimation(value: string): value is PopupAnimation {
101
+ return validAnimations.includes(value as PopupAnimation);
102
+ }
103
+
104
+ // Safe parser with fallback
105
+ function getPopupAnimation(raw: string | null | undefined): PopupAnimation {
106
+ return isPopupAnimation(raw ?? "") ? (raw as PopupAnimation) : "slide-up";
107
+ }
package/src/petal.ts CHANGED
@@ -1,22 +1,10 @@
1
1
  import gsap from "gsap";
2
-
3
- // Popup animation types
4
- export type PopupAnimation = "scale-up" | "scale-down" | "slide-up" | "slide-down" | "slide-left" | "slide-right";
5
-
6
- const validAnimations: PopupAnimation[] = ["scale-up", "scale-down", "slide-up", "slide-down", "slide-left", "slide-right"];
2
+ import { animateMaskClosed, animateMaskOpen, getAnimation, getAnimationNew, isPopupAnimation, PopupAnimation } from "./animation";
3
+ import { pauseVideo } from "./video";
7
4
 
8
5
  // Error types for debug logging
9
6
  export type ErrorType = "NO_NAME" | "NO_TRIGGER" | "NO_POPUP" | "NO_MASK" | "NO_SLOT";
10
7
 
11
- const animationMap: Record<PopupAnimation, [(show: boolean) => GSAPTweenVars, (show: boolean) => GSAPTweenVars]> = {
12
- "scale-up": [animateScaleUp, animateScaleDown],
13
- "scale-down": [animateScaleDown, animateScaleUp],
14
- "slide-up": [animateSlideUp, animateSlideDown],
15
- "slide-down": [animateSlideDown, animateSlideUp],
16
- "slide-left": [animateSlideLeft, animateSlideRight],
17
- "slide-right": [animateSlideRight, animateSlideLeft],
18
- };
19
-
20
8
  // Initialize popup triggers
21
9
  document.querySelectorAll("[petal-el='trigger'], [petal-el='mask']").forEach((trigger) => {
22
10
  const popupName = trigger.getAttribute("petal");
@@ -38,11 +26,6 @@ document.querySelectorAll("[petal-el='trigger'], [petal-el='mask']").forEach((tr
38
26
  // Mask Settings
39
27
  const maskOpacity = parseFloat(mask?.getAttribute("petal-mask-opacity") || "0.15");
40
28
 
41
- // Popup Settings
42
- const animation = getPopupAnimation(popup.getAttribute("petal-anim"));
43
- const animationMobile = getPopupAnimation(popup.getAttribute("petal-anim-mobile")) || animation;
44
- const duration = parseFloat(popup.getAttribute("petal-duration") || "1");
45
-
46
29
  // Initialize GSAP timeline
47
30
  const tl = gsap.timeline();
48
31
 
@@ -53,18 +36,13 @@ document.querySelectorAll("[petal-el='trigger'], [petal-el='mask']").forEach((tr
53
36
 
54
37
  // Animate open/close
55
38
  function animate(popup: HTMLElement): void {
56
- // Check if the popup is open or closed
57
- const open = getComputedStyle(popup).display !== "none";
58
-
59
39
  if (!slot) console.warn("A slot was not found for this popup.");
60
40
 
61
41
  console.log(`[Petal Popup]`, {
62
42
  popupName,
63
- animationDesktop: animation,
64
- animationMobile,
65
- duration,
43
+ popup,
44
+ slot,
66
45
  maskOpacity,
67
- isMobile: isMobile(),
68
46
  open,
69
47
  });
70
48
 
@@ -77,21 +55,18 @@ document.querySelectorAll("[petal-el='trigger'], [petal-el='mask']").forEach((tr
77
55
  tl.fromTo(mask, animateMaskOpen(maskOpacity).from, animateMaskOpen(maskOpacity).to, "<");
78
56
  }
79
57
  // Animate the popup
80
- const anim = isMobile() ? getAnimation(animationMobile, open) : getAnimation(animation, open);
81
- anim.to.duration = duration;
58
+ const anim = getAnimationNew(popup);
59
+ console.log(anim);
82
60
  tl.fromTo(slot, anim.from, anim.to);
83
61
  }
84
62
 
85
63
  // If the popup is open, close it
86
- if (open) {
87
- // Pause all <video> elements inside the popup before hiding it
88
- popup.querySelectorAll("video").forEach((video) => {
89
- console.log("[Petal Popup] Pausing video:", video);
90
- if (!video.paused) video.pause();
91
- });
64
+ else {
65
+ // Pause any videos in the popup
66
+ pauseVideo(popup);
92
67
  // Animate the popup
93
- const anim = isMobile() ? getAnimation(animationMobile, open) : getAnimation(animation, open);
94
- anim.to.duration = duration;
68
+ const anim = getAnimationNew(popup);
69
+ console.log(anim);
95
70
  tl.fromTo(slot, anim.from, anim.to);
96
71
  // Animate Mask Closed
97
72
  if (mask) {
@@ -102,85 +77,6 @@ document.querySelectorAll("[petal-el='trigger'], [petal-el='mask']").forEach((tr
102
77
  }
103
78
  });
104
79
 
105
- // Reusable mask animations
106
- function animateMaskOpen(opacity: number): GSAPTweenVars {
107
- return {
108
- from: { opacity: 0 },
109
- to: { opacity: opacity, duration: 0.5 },
110
- };
111
- }
112
-
113
- function animateMaskClosed(opacity: number): GSAPTweenVars {
114
- return {
115
- from: { opacity: opacity },
116
- to: { opacity: 0, duration: 0.5 },
117
- };
118
- }
119
-
120
- // Animation selection
121
- function getAnimation(animation: PopupAnimation, open: boolean): GSAPTweenVars {
122
- const [normal, reverse] = animationMap[animation];
123
- return open ? reverse(false) : normal(true);
124
- }
125
-
126
- // Individual animations
127
- function animateScaleUp(show: boolean): GSAPTweenVars {
128
- return {
129
- from: { scale: 0 },
130
- to: { scale: 1, opacity: show ? 1 : 0, ease: "power3.inOut" },
131
- };
132
- }
133
-
134
- function animateScaleDown(show: boolean): GSAPTweenVars {
135
- return {
136
- from: { scale: 1 },
137
- to: { scale: 0, opacity: show ? 1 : 0, ease: "power3.inOut" },
138
- };
139
- }
140
-
141
- function animateSlideUp(show: boolean): GSAPTweenVars {
142
- return {
143
- from: { y: "100%", x: "0%" },
144
- to: { y: "0%", opacity: show ? 1 : 0, ease: "power3.inOut" },
145
- };
146
- }
147
-
148
- function animateSlideDown(show: boolean): GSAPTweenVars {
149
- return {
150
- from: { y: "0%", x: "0%" },
151
- to: { y: "100%", opacity: show ? 1 : 0, ease: "power3.inOut" },
152
- };
153
- }
154
-
155
- function animateSlideRight(show: boolean): GSAPTweenVars {
156
- return {
157
- from: { x: "0%", y: "0%" },
158
- to: { x: "100%", opacity: show ? 1 : 0, ease: "power3.inOut" },
159
- };
160
- }
161
-
162
- function animateSlideLeft(show: boolean): GSAPTweenVars {
163
- return {
164
- from: { x: "100%", y: "0%" },
165
- to: { x: "0%", opacity: show ? 1 : 0, ease: "power3.inOut" },
166
- };
167
- }
168
-
169
- // Device check
170
- function isMobile(): boolean {
171
- return window.innerWidth <= 768;
172
- }
173
-
174
- // Validate popup animation string
175
- function isPopupAnimation(value: string): value is PopupAnimation {
176
- return validAnimations.includes(value as PopupAnimation);
177
- }
178
-
179
- // Safe parser with fallback
180
- function getPopupAnimation(raw: string | null | undefined): PopupAnimation {
181
- return isPopupAnimation(raw ?? "") ? (raw as PopupAnimation) : "slide-up";
182
- }
183
-
184
80
  // Centralized error logging
185
81
  function logError(error: ErrorType, popupName: string, trigger: Element): void {
186
82
  switch (error) {
package/src/video.ts ADDED
@@ -0,0 +1,6 @@
1
+ export function pauseVideo(popup: HTMLElement): void {
2
+ // Pause all <video> elements inside the popup before hiding it
3
+ popup.querySelectorAll("video").forEach((video) => {
4
+ if (!video.paused) video.pause();
5
+ });
6
+ }