react-fast-marquee
Advanced tools
Comparing version 1.3.5 to 1.4.0
@@ -1,96 +0,102 @@ | ||
import React from "react"; | ||
import { ReactNode, CSSProperties, FC } from "react"; | ||
import "./Marquee.scss"; | ||
interface MarqueeProps { | ||
/** | ||
* Inline style for the container div | ||
* Type: object | ||
* Default: {} | ||
* @description Inline style for the container div | ||
* @type {CSSProperties} | ||
* @default {} | ||
*/ | ||
style?: React.CSSProperties; | ||
style?: CSSProperties; | ||
/** | ||
* Class name to style the container div | ||
* Type: string | ||
* Default: "" | ||
* @description Class name to style the container div | ||
* @type {string} | ||
* @default "" | ||
*/ | ||
className?: string; | ||
/** | ||
* Whether to play or pause the marquee | ||
* Type: boolean | ||
* Default: true | ||
* @description Whether to automatically fill blank space in the marquee with copies of the children or not | ||
* @type {boolean} | ||
* @default true | ||
*/ | ||
autoFill?: boolean; | ||
/** | ||
* @description Whether to play or pause the marquee | ||
* @type {boolean} | ||
* @default true | ||
*/ | ||
play?: boolean; | ||
/** | ||
* Whether to pause the marquee when hovered | ||
* Type: boolean | ||
* Default: false | ||
* @description Whether to pause the marquee when hovered | ||
* @type {boolean} | ||
* @default false | ||
*/ | ||
pauseOnHover?: boolean; | ||
/** | ||
* Whether to pause the marquee when clicked | ||
* Type: boolean | ||
* Default: false | ||
* @description Whether to pause the marquee when clicked | ||
* @type {boolean} | ||
* @default false | ||
*/ | ||
pauseOnClick?: boolean; | ||
/** | ||
* The direction the marquee is sliding | ||
* Type: "left" or "right" | ||
* Default: "left" | ||
* @description The direction the marquee is sliding | ||
* @type {"left" | "right"} | ||
* @default "left" | ||
*/ | ||
direction?: "left" | "right"; | ||
/** | ||
* Speed calculated as pixels/second | ||
* Type: number | ||
* Default: 20 | ||
* @description Speed calculated as pixels/second | ||
* @type {number} | ||
* @default 100 | ||
*/ | ||
speed?: number; | ||
/** | ||
* Duration to delay the animation after render, in seconds | ||
* Type: number | ||
* Default: 0 | ||
* @description Duration to delay the animation after render, in seconds | ||
* @type {number} | ||
* @default 0 | ||
*/ | ||
delay?: number; | ||
/** | ||
* The number of times the marquee should loop, 0 is equivalent to infinite | ||
* Type: number | ||
* Default: 0 | ||
* @description The number of times the marquee should loop, 0 is equivalent to infinite | ||
* @type {number} | ||
* @default 0 | ||
*/ | ||
loop?: number; | ||
/** | ||
* Whether to show the gradient or not | ||
* Type: boolean | ||
* Default: true | ||
* @description Whether to show the gradient or not | ||
* @type {boolean} | ||
* @default false | ||
*/ | ||
gradient?: boolean; | ||
/** | ||
* The rgb color of the gradient as an array of length 3 | ||
* Type: Array<number> of length 3 | ||
* Default: [255, 255, 255] | ||
* @description The rgb color of the gradient as an array of length 3 | ||
* @type {Array<number>} of length 3 | ||
* @default [255, 255, 255] | ||
*/ | ||
gradientColor?: [number, number, number]; | ||
/** | ||
* The width of the gradient on either side | ||
* Type: string | ||
* Default: 200 | ||
* @description The width of the gradient on either side | ||
* @type {number | string} | ||
* @default 200 | ||
*/ | ||
gradientWidth?: number | string; | ||
/** | ||
* A callback for when the marquee finishes scrolling and stops. Only calls if loop is non-zero. | ||
* Type: Function | ||
* Default: null | ||
* @description A callback for when the marquee finishes scrolling and stops. Only calls if loop is non-zero. | ||
* @type {() => void} | ||
* @default null | ||
*/ | ||
onFinish?: () => void; | ||
/** | ||
* A callback for when the marquee finishes a loop. Does not call if maximum loops are reached (use onFinish instead). | ||
* Type: Function | ||
* Default: null | ||
* @description A callback for when the marquee finishes a loop. Does not call if maximum loops are reached (use onFinish instead). | ||
* @type {() => void} | ||
* @default null | ||
*/ | ||
onCycleComplete?: () => void; | ||
/** | ||
* The children rendered inside the marquee | ||
* Type: ReactNode | ||
* Default: null | ||
* @description The children rendered inside the marquee | ||
* @type {ReactNode} | ||
* @default null | ||
*/ | ||
children?: React.ReactNode; | ||
children?: ReactNode; | ||
} | ||
declare const Marquee: React.FC<MarqueeProps>; | ||
declare const Marquee: FC<MarqueeProps>; | ||
export default Marquee; |
@@ -22,89 +22,95 @@ | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
___$insertStyle(".marquee-container {\n overflow-x: hidden !important;\n display: flex !important;\n flex-direction: row !important;\n position: relative;\n width: 100%;\n}\n.marquee-container:hover div {\n animation-play-state: var(--pause-on-hover);\n}\n.marquee-container:active div {\n animation-play-state: var(--pause-on-click);\n}\n\n.overlay {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.overlay::before, .overlay::after {\n background: linear-gradient(to right, var(--gradient-color));\n content: \"\";\n height: 100%;\n position: absolute;\n width: var(--gradient-width);\n z-index: 2;\n}\n.overlay::after {\n right: 0;\n top: 0;\n transform: rotateZ(180deg);\n}\n.overlay::before {\n left: 0;\n top: 0;\n}\n\n.marquee {\n flex: 0 0 auto;\n min-width: var(--min-width);\n z-index: 1;\n display: flex;\n flex-direction: row;\n align-items: center;\n animation: scroll var(--duration) linear var(--delay) var(--iteration-count);\n animation-play-state: var(--play);\n animation-delay: var(--delay);\n animation-direction: var(--direction);\n}\n@keyframes scroll {\n 0% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(-100%);\n }\n}\n\n.children-container {\n flex: 0 0 auto;\n min-width: auto;\n}"); | ||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
const multiplyChildren = (multiplier, children) => { | ||
return [ | ||
...Array(Number.isFinite(multiplier) && multiplier >= 0 ? multiplier : 0), | ||
].map((_, i) => React__default["default"].createElement(React.Fragment, { key: i }, children)); | ||
}; | ||
___$insertStyle(".marquee-container {\n overflow-x: hidden !important;\n display: flex !important;\n flex-direction: row !important;\n position: relative;\n width: 100%;\n}\n.marquee-container:hover div {\n animation-play-state: var(--pause-on-hover);\n}\n.marquee-container:active div {\n animation-play-state: var(--pause-on-click);\n}\n\n.overlay {\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.overlay::before, .overlay::after {\n background: linear-gradient(to right, var(--gradient-color));\n content: \"\";\n height: 100%;\n position: absolute;\n width: var(--gradient-width);\n z-index: 2;\n}\n.overlay::after {\n right: 0;\n top: 0;\n transform: rotateZ(180deg);\n}\n.overlay::before {\n left: 0;\n top: 0;\n}\n\n.marquee {\n flex: 0 0 auto;\n min-width: 100%;\n z-index: 1;\n display: flex;\n flex-direction: row;\n align-items: center;\n animation: scroll var(--duration) linear var(--delay) var(--iteration-count);\n animation-play-state: var(--play);\n animation-delay: var(--delay);\n animation-direction: var(--direction);\n}\n@keyframes scroll {\n 0% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(-100%);\n }\n}"); | ||
var Marquee = function (_a) { | ||
var _b, _c, _d, _e; | ||
var _f = _a.style, style = _f === void 0 ? {} : _f, _g = _a.className, className = _g === void 0 ? "" : _g, _h = _a.play, play = _h === void 0 ? true : _h, _j = _a.pauseOnHover, pauseOnHover = _j === void 0 ? false : _j, _k = _a.pauseOnClick, pauseOnClick = _k === void 0 ? false : _k, _l = _a.direction, direction = _l === void 0 ? "left" : _l, _m = _a.speed, speed = _m === void 0 ? 20 : _m, _o = _a.delay, delay = _o === void 0 ? 0 : _o, _p = _a.loop, loop = _p === void 0 ? 0 : _p, _q = _a.gradient, gradient = _q === void 0 ? true : _q, _r = _a.gradientColor, gradientColor = _r === void 0 ? [255, 255, 255] : _r, _s = _a.gradientWidth, gradientWidth = _s === void 0 ? 200 : _s, onFinish = _a.onFinish, onCycleComplete = _a.onCycleComplete, children = _a.children; | ||
const Marquee = ({ style = {}, className = "", autoFill = true, play = true, pauseOnHover = false, pauseOnClick = false, direction = "left", speed = 100, delay = 0, loop = 0, gradient = false, gradientColor = [255, 255, 255], gradientWidth = 200, onFinish, onCycleComplete, children, }) => { | ||
// React Hooks | ||
var _t = React.useState(0), containerWidth = _t[0], setContainerWidth = _t[1]; | ||
var _u = React.useState(0), marqueeWidth = _u[0], setMarqueeWidth = _u[1]; | ||
var _v = React.useState(false), isMounted = _v[0], setIsMounted = _v[1]; | ||
var containerRef = React.useRef(null); | ||
var marqueeRef = React.useRef(null); | ||
React.useEffect(function () { | ||
const [containerWidth, setContainerWidth] = React.useState(0); | ||
const [marqueeWidth, setMarqueeWidth] = React.useState(0); | ||
const [multiplier, setMultiplier] = React.useState(1); | ||
const [isMounted, setIsMounted] = React.useState(false); | ||
const containerRef = React.useRef(null); | ||
const marqueeRef = React.useRef(null); | ||
// Calculate width of container and marquee and set multiplier | ||
const calculateWidth = React.useCallback(() => { | ||
if (marqueeRef.current && containerRef.current) { | ||
const containerWidth = containerRef.current.getBoundingClientRect().width; | ||
const marqueeWidth = marqueeRef.current.getBoundingClientRect().width; | ||
if (autoFill && containerWidth && marqueeWidth) { | ||
setMultiplier(marqueeWidth < containerWidth | ||
? Math.ceil(containerWidth / marqueeWidth) | ||
: 1); | ||
} | ||
else { | ||
setMultiplier(1); | ||
} | ||
setContainerWidth(containerWidth); | ||
setMarqueeWidth(marqueeWidth); | ||
} | ||
}, [autoFill, marqueeRef]); | ||
// Calculate width and multiplier on mount and on window resize | ||
React.useEffect(() => { | ||
if (!isMounted) | ||
return; | ||
var calculateWidth = function () { | ||
// Find width of container and width of marquee | ||
if (marqueeRef.current && containerRef.current) { | ||
setContainerWidth(containerRef.current.getBoundingClientRect().width); | ||
setMarqueeWidth(marqueeRef.current.getBoundingClientRect().width); | ||
} | ||
}; | ||
calculateWidth(); | ||
// Rerender on window resize | ||
window.addEventListener("resize", calculateWidth); | ||
return function () { | ||
window.removeEventListener("resize", calculateWidth); | ||
}; | ||
}, [isMounted]); | ||
React.useEffect(function () { | ||
if (marqueeRef.current) { | ||
const resizeObserver = new ResizeObserver(() => calculateWidth()); | ||
resizeObserver.observe(marqueeRef.current); | ||
return () => { | ||
if (!resizeObserver) | ||
return; | ||
resizeObserver.disconnect(); | ||
}; | ||
} | ||
}, [calculateWidth, isMounted]); | ||
// Recalculate width when children change | ||
React.useEffect(() => { | ||
calculateWidth(); | ||
}, [calculateWidth, children]); | ||
React.useEffect(() => { | ||
setIsMounted(true); | ||
}, []); | ||
// Animation duration | ||
const duration = React.useMemo(() => { | ||
if (autoFill) { | ||
return (marqueeWidth * multiplier) / speed; | ||
} | ||
else { | ||
return marqueeWidth < containerWidth | ||
? containerWidth / speed | ||
: marqueeWidth / speed; | ||
} | ||
}, [autoFill, containerWidth, marqueeWidth, multiplier, speed]); | ||
// Gradient color in an unfinished rgba format | ||
var rgbaGradientColor = "rgba(" + gradientColor[0] + ", " + gradientColor[1] + ", " + gradientColor[2]; | ||
// Animation duration | ||
var duration = marqueeWidth < containerWidth | ||
? containerWidth / speed | ||
: marqueeWidth / speed; | ||
return (React__default['default'].createElement(React.Fragment, null, !isMounted ? null : (React__default['default'].createElement("div", { ref: containerRef, style: __assign(__assign({}, style), (_b = {}, _b["--pause-on-hover"] = !play || pauseOnHover ? "paused" : "running", _b["--pause-on-click"] = !play || (pauseOnHover && !pauseOnClick) || pauseOnClick ? "paused" : "running", _b)), className: className + " marquee-container" }, | ||
gradient && (React__default['default'].createElement("div", { style: (_c = {}, | ||
_c["--gradient-color"] = rgbaGradientColor + ", 1), " + rgbaGradientColor + ", 0)", | ||
_c["--gradient-width"] = typeof gradientWidth === "number" | ||
? gradientWidth + "px" | ||
: gradientWidth, | ||
_c), className: "overlay" })), | ||
React__default['default'].createElement("div", { ref: marqueeRef, style: (_d = {}, | ||
_d["--play"] = play ? "running" : "paused", | ||
_d["--direction"] = direction === "left" ? "normal" : "reverse", | ||
_d["--duration"] = duration + "s", | ||
_d["--delay"] = delay + "s", | ||
_d["--iteration-count"] = !!loop ? "" + loop : "infinite", | ||
_d), className: "marquee", onAnimationIteration: onCycleComplete, onAnimationEnd: onFinish }, children), | ||
React__default['default'].createElement("div", { style: (_e = {}, | ||
_e["--play"] = play ? "running" : "paused", | ||
_e["--direction"] = direction === "left" ? "normal" : "reverse", | ||
_e["--duration"] = duration + "s", | ||
_e["--delay"] = delay + "s", | ||
_e["--iteration-count"] = !!loop ? "" + loop : "infinite", | ||
_e), className: "marquee", "aria-hidden": "true" }, children))))); | ||
const rgbaGradientColor = `rgba(${gradientColor[0]}, ${gradientColor[1]}, ${gradientColor[2]}`; | ||
const containerStyle = React.useMemo(() => (Object.assign(Object.assign({}, style), { ["--pause-on-hover"]: !play || pauseOnHover ? "paused" : "running", ["--pause-on-click"]: !play || (pauseOnHover && !pauseOnClick) || pauseOnClick | ||
? "paused" | ||
: "running" })), [style, play, pauseOnHover, pauseOnClick]); | ||
const gradientStyle = React.useMemo(() => ({ | ||
["--gradient-color"]: `${rgbaGradientColor}, 1), ${rgbaGradientColor}, 0)`, | ||
["--gradient-width"]: typeof gradientWidth === "number" | ||
? `${gradientWidth}px` | ||
: gradientWidth, | ||
}), [rgbaGradientColor, gradientWidth]); | ||
const marqueeStyle = React.useMemo(() => ({ | ||
["--play"]: play ? "running" : "paused", | ||
["--direction"]: direction === "left" ? "normal" : "reverse", | ||
["--duration"]: `${duration}s`, | ||
["--delay"]: `${delay}s`, | ||
["--iteration-count"]: !!loop ? `${loop}` : "infinite", | ||
["--min-width"]: autoFill ? `auto` : "100%", | ||
}), [play, direction, duration, delay, loop, autoFill]); | ||
return (React__default["default"].createElement(React.Fragment, null, !isMounted ? null : (React__default["default"].createElement("div", { ref: containerRef, style: containerStyle, className: className + " marquee-container" }, | ||
gradient && React__default["default"].createElement("div", { style: gradientStyle, className: "overlay" }), | ||
React__default["default"].createElement("div", { className: "marquee", style: marqueeStyle, onAnimationIteration: onCycleComplete, onAnimationEnd: onFinish }, | ||
React__default["default"].createElement("div", { className: "children-container", ref: marqueeRef }, children), | ||
multiplyChildren(multiplier - 1, children)), | ||
React__default["default"].createElement("div", { className: "marquee", style: marqueeStyle }, multiplyChildren(multiplier, children)))))); | ||
}; | ||
exports.default = Marquee; | ||
exports["default"] = Marquee; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "react-fast-marquee", | ||
"version": "1.3.5", | ||
"version": "1.4.0", | ||
"description": "A lightweight React component that utilizes the power of CSS animations to create silky smooth marquees.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -72,19 +72,19 @@ # React Fast Marquee | ||
| Property | Type | Default | Description | | ||
| :-------------- | :-------------------------- | :---------------- | :------------------------------------------------------- | | ||
| `style` | `object` | `{}` | Inline style for the container div | | ||
| `className` | `string` | `""` | Name of the css class to style the container div | | ||
| `play` | `boolean` | `true` | Whether to play or pause the marquee | | ||
| `pauseOnHover` | `boolean` | `false` | Whether to pause the marquee when hovered | | ||
| `pauseOnClick` | `boolean` | `false` | Whether to pause the marquee when clicked | | ||
| `direction` | `"left"` or `"right"` | `"left"` | The direction the marquee is sliding | | ||
| `speed` | `number` | `20` | Speed calculated as pixels/second | | ||
| `delay` | `number` | `0` | Duration to delay the animation after render, in seconds | | ||
| `loop` | `number` | `0` | The number of times the marquee should loop, 0 is equivalent to infinite | | ||
| `gradient` | `boolean` | `true` | Whether to show the gradient or not | | ||
| `gradientColor` | `Array<number>` of length 3 | `[255, 255, 255]` | The rgb color of the gradient as an array of length 3 | | ||
| `gradientWidth` | `number` or `string` | `200` | The width of the gradient on either side | | ||
| `onFinish` | `Function` | `null` | A callback for when the marquee finishes scrolling and stops. Only calls if loop is non-zero. | | ||
| `onCycleComplete` | `Function` | `null` | A callback for when the marquee finishes a loop. Does not call if maximum loops are reached (use onFinish instead). | | ||
| `children` | `ReactNode` | `null` | The children rendered inside the marquee | | ||
| Property | Type | Default | Description | | ||
| :---------------- | :-------------------------- | :---------------- | :------------------------------------------------------------------------------------------------------------------ | | ||
| `style` | `CSSProperties` | `{}` | Inline style for the container div | | ||
| `className` | `string` | `""` | Name of the css class to style the container div | | ||
| `autoFill` | `boolean` | `true` | Whether to automatically fill blank space in the marquee with copies of the children or not | | ||
| `play` | `boolean` | `true` | Whether to play or pause the marquee | | ||
| `pauseOnHover` | `boolean` | `false` | Whether to pause the marquee when hovered | | ||
| `pauseOnClick` | `boolean` | `false` | Whether to pause the marquee when clicked | | ||
| `direction` | `"left" \| "right"` | `"left"` | The direction the marquee is sliding | | ||
| `speed` | `number` | `100` | Speed calculated as pixels/second | | ||
| `delay` | `number` | `0` | Duration to delay the animation after render, in seconds | | ||
| `loop` | `number` | `0` | The number of times the marquee should loop, 0 is equivalent to infinite | | ||
| `gradient` | `boolean` | `false` | Whether to show the gradient or not | | ||
| `gradientColor` | `Array<number>` of length 3 | `[255, 255, 255]` | The rgb color of the gradient as an array of length 3 | | ||
| `gradientWidth` | `number \| string` | `200` | The width of the gradient on either side | | ||
| `onFinish` | `{() => void}` | `null` | A callback for when the marquee finishes scrolling and stops. Only calls if loop is non-zero. | | ||
| `onCycleComplete` | `{() => void}` | `null` | A callback for when the marquee finishes a loop. Does not call if maximum loops are reached (use onFinish instead). | | ||
| `children` | `ReactNode` | `null` | The children rendered inside the marquee | |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
31951
214
1