gsap-react-marquee 0.1.4 → 0.1.5

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/index.d.ts CHANGED
@@ -107,6 +107,32 @@ declare const GSAPReactMarquee: react.ForwardRefExoticComponent<GSAPReactMarquee
107
107
  * @returns Merged and deduplicated class string
108
108
  */
109
109
  declare const cn: (...inputs: ClassValue[]) => string;
110
+ /**
111
+ * Traverses the DOM tree upward to find the first non-transparent background color
112
+ *
113
+ * This function walks up the element hierarchy starting from the given element,
114
+ * checking each parent's computed backgroundColor style until it finds a visible
115
+ * (non-transparent) background color. This is useful for automatically detecting
116
+ * the effective background behind an element for gradient overlays.
117
+ *
118
+ * The traversal stops at the first element with a visible background color,
119
+ * which could be the element itself or any of its ancestors up to the document root.
120
+ *
121
+ * @param el - The HTMLElement to start the background color search from
122
+ * @returns The first non-transparent background color found in the hierarchy,
123
+ * or "transparent" if no visible background is found
124
+ *
125
+ * @example
126
+ * // Element with white parent background
127
+ * const color = getEffectiveBackgroundColor(marqueeElement);
128
+ * // Returns: "rgb(255, 255, 255)" or "#ffffff"
129
+ *
130
+ * @example
131
+ * // Element with no background set anywhere in hierarchy
132
+ * const color = getEffectiveBackgroundColor(marqueeElement);
133
+ * // Returns: "transparent"
134
+ */
135
+ declare const getEffectiveBackgroundColor: (el: HTMLElement) => string;
110
136
  /**
111
137
  * Sets up container styles and rotation handling for the marquee
112
138
  *
@@ -186,5 +212,5 @@ declare const getMinWidth: (marqueesChildren: HTMLElement[], totalWidth: number,
186
212
  */
187
213
  declare const coreAnimation: (elementsToAnimate: HTMLElement[], startX: number, tl: gsap.core.Timeline, isReverse: boolean, props: GSAPReactMarqueeProps) => void;
188
214
 
189
- export { calculateDuplicates, cn, coreAnimation, GSAPReactMarquee as default, getMinWidth, setupContainerStyles };
215
+ export { calculateDuplicates, cn, coreAnimation, GSAPReactMarquee as default, getEffectiveBackgroundColor, getMinWidth, setupContainerStyles };
190
216
  export type { GSAPReactMarqueeProps };
@@ -1 +1 @@
1
- .gsap-react-marquee{flex:1;height:max-content;width:auto}.gsap-react-marquee,.gsap-react-marquee-content{display:flex;line-height:100%;white-space:preserve nowrap}.gsap-react-marquee-content{overflow:hidden;width:max-content}
1
+ .gsap-react-marquee-container:after{background:linear-gradient(270deg,hsla(0,0%,100%,0) 0,var(--gradient-color) 75%);content:"";height:100%;left:0;position:absolute;top:0;width:15%;z-index:10}.gsap-react-marquee-container:before{background:linear-gradient(90deg,hsla(0,0%,100%,0) 0,var(--gradient-color) 75%);content:"";height:100%;position:absolute;right:0;top:0;width:15%;z-index:10}.gsap-react-marquee{flex:1;height:max-content;width:auto}.gsap-react-marquee,.gsap-react-marquee-content{display:flex;line-height:100%;white-space:preserve nowrap}.gsap-react-marquee-content{overflow:hidden;width:max-content}
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import require$$0, { forwardRef, useRef, useState, useMemo } from 'react';
1
+ import require$$0, { forwardRef, useRef, useState, useLayoutEffect, useMemo } from 'react';
2
2
  import { useGSAP } from '@gsap/react';
3
3
  import gsap$1 from 'gsap';
4
4
 
@@ -3632,6 +3632,43 @@ const twMerge = /*#__PURE__*/createTailwindMerge(getDefaultConfig);
3632
3632
  const cn = (...inputs) => {
3633
3633
  return twMerge(clsx(inputs));
3634
3634
  };
3635
+ /**
3636
+ * Traverses the DOM tree upward to find the first non-transparent background color
3637
+ *
3638
+ * This function walks up the element hierarchy starting from the given element,
3639
+ * checking each parent's computed backgroundColor style until it finds a visible
3640
+ * (non-transparent) background color. This is useful for automatically detecting
3641
+ * the effective background behind an element for gradient overlays.
3642
+ *
3643
+ * The traversal stops at the first element with a visible background color,
3644
+ * which could be the element itself or any of its ancestors up to the document root.
3645
+ *
3646
+ * @param el - The HTMLElement to start the background color search from
3647
+ * @returns The first non-transparent background color found in the hierarchy,
3648
+ * or "transparent" if no visible background is found
3649
+ *
3650
+ * @example
3651
+ * // Element with white parent background
3652
+ * const color = getEffectiveBackgroundColor(marqueeElement);
3653
+ * // Returns: "rgb(255, 255, 255)" or "#ffffff"
3654
+ *
3655
+ * @example
3656
+ * // Element with no background set anywhere in hierarchy
3657
+ * const color = getEffectiveBackgroundColor(marqueeElement);
3658
+ * // Returns: "transparent"
3659
+ */
3660
+ const getEffectiveBackgroundColor = (el) => {
3661
+ let current = el;
3662
+ while (current) {
3663
+ const bg = window.getComputedStyle(current).backgroundColor;
3664
+ // Check if background color is visible (not transparent or rgba(0,0,0,0))
3665
+ if (bg && bg !== "rgba(0, 0, 0, 0)" && bg !== "transparent") {
3666
+ return bg;
3667
+ }
3668
+ current = current.parentElement;
3669
+ }
3670
+ return "transparent"; // fallback when no visible background is found
3671
+ };
3635
3672
  /**
3636
3673
  * Sets up container styles and rotation handling for the marquee
3637
3674
  *
@@ -3953,11 +3990,18 @@ const coreAnimation = (elementsToAnimate, startX, tl, isReverse, props) => {
3953
3990
  };
3954
3991
 
3955
3992
  const GSAPReactMarquee = forwardRef((props, ref) => {
3956
- const { children, className, dir = "left", loop = -1, paused = false, fill = false, followScrollDir = false, scrollSpeed = 2.5, } = props;
3993
+ const { children, className, dir = "left", loop = -1, paused = false, fill = false, followScrollDir = false, scrollSpeed = 2.5, gradient = false, gradientColor = null, } = props;
3957
3994
  const rootRef = useRef(null) || ref;
3958
3995
  const containerRef = rootRef;
3959
3996
  const marqueeRef = useRef(null);
3960
3997
  const [marqueeDuplicates, setMarqueeDuplicates] = useState(1);
3998
+ const [effectivelyGradient, setEffectivelyGradient] = useState(null);
3999
+ useLayoutEffect(() => {
4000
+ if (!gradient || !(containerRef === null || containerRef === void 0 ? void 0 : containerRef.current))
4001
+ return;
4002
+ const effectiveBg = getEffectiveBackgroundColor(containerRef.current);
4003
+ setEffectivelyGradient(effectiveBg);
4004
+ }, [gradient]);
3961
4005
  const isVertical = dir === "up" || dir === "down";
3962
4006
  const isReverse = dir === "down" || dir === "right";
3963
4007
  useGSAP(() => {
@@ -4047,6 +4091,16 @@ const GSAPReactMarquee = forwardRef((props, ref) => {
4047
4091
  }, {
4048
4092
  dependencies: [marqueeDuplicates],
4049
4093
  });
4094
+ const getGradientColor = () => {
4095
+ // Priority order: explicit gradientColor > auto-detected > fallback
4096
+ if (gradientColor) {
4097
+ return gradientColor; // User-specified color takes precedence
4098
+ }
4099
+ if (gradient && effectivelyGradient) {
4100
+ return effectivelyGradient; // Auto-detected background color
4101
+ }
4102
+ return "transparent"; // Default fallback
4103
+ };
4050
4104
  /**
4051
4105
  * Generate cloned marquee elements for seamless looping
4052
4106
  *
@@ -4059,9 +4113,11 @@ const GSAPReactMarquee = forwardRef((props, ref) => {
4059
4113
  return null;
4060
4114
  return Array.from({ length: marqueeDuplicates }, (_, i) => (jsxRuntimeExports.jsx("div", { className: cn("gsap-react-marquee"), children: jsxRuntimeExports.jsx("div", { className: cn("gsap-react-marquee-content", className), children: children }) }, i)));
4061
4115
  }, [marqueeDuplicates, className, children]);
4062
- return (jsxRuntimeExports.jsxs("div", { ref: containerRef, className: cn("gsap-react-marquee-container flex w-full overflow-hidden whitespace-nowrap"), children: [jsxRuntimeExports.jsx("div", { ref: marqueeRef, className: cn("gsap-react-marquee"), children: jsxRuntimeExports.jsx("div", { className: cn("gsap-react-marquee-content", className), children: children }) }), clonedMarquees] }));
4116
+ return (jsxRuntimeExports.jsxs("div", { ref: containerRef, style: {
4117
+ "--gradient-color": getGradientColor(),
4118
+ }, className: cn("gsap-react-marquee-container flex w-full overflow-hidden whitespace-nowrap"), children: [jsxRuntimeExports.jsx("div", { ref: marqueeRef, className: cn("gsap-react-marquee"), children: jsxRuntimeExports.jsx("div", { className: cn("gsap-react-marquee-content", className), children: children }) }), clonedMarquees] }));
4063
4119
  });
4064
4120
  GSAPReactMarquee.displayName = "GSAPReactMarquee";
4065
4121
 
4066
- export { calculateDuplicates, cn, coreAnimation, GSAPReactMarquee as default, getMinWidth, setupContainerStyles };
4122
+ export { calculateDuplicates, cn, coreAnimation, GSAPReactMarquee as default, getEffectiveBackgroundColor, getMinWidth, setupContainerStyles };
4067
4123
  //# sourceMappingURL=index.esm.js.map