well-petal 0.0.18 → 0.0.20

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