@stianlarsen/react-light-beam 1.0.8 → 1.0.10
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/README.md +17 -10
- package/dist/css/lightBeam.module.css +3 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +23 -11
- package/package.json +3 -3
- package/types/types.d.ts +1 -0
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @stianlarsen/react-light-beam
|
|
2
2
|
|
|
3
|
+
## 🚀 New Feature Alert!
|
|
4
|
+
|
|
5
|
+
We've added a new prop: `scrollElement`. This allows you to specify which element should have the scroll listener attached, giving you greater flexibility in using the LightBeam component!
|
|
6
|
+
|
|
3
7
|
[](https://badge.fury.io/js/%40stianlarsen%2Freact-light-beam)
|
|
4
8
|
|
|
5
9
|
A customizable React component that creates a light beam effect using conic gradients. The component is fully responsive and supports both light and dark modes. Ideal for adding dynamic and engaging visual elements to your web applications.
|
|
@@ -39,6 +43,7 @@ const App = () => {
|
|
|
39
43
|
fullWidth={0.8}
|
|
40
44
|
maskLightByProgress={true}
|
|
41
45
|
invert={false}
|
|
46
|
+
scrollElement={window} // New prop to specify scroll element
|
|
42
47
|
/>
|
|
43
48
|
<YourContentHere />
|
|
44
49
|
</div>
|
|
@@ -50,16 +55,17 @@ export default App;
|
|
|
50
55
|
|
|
51
56
|
### Props
|
|
52
57
|
|
|
53
|
-
| Prop Name | Type
|
|
54
|
-
| --------------------- |
|
|
55
|
-
| `id` | `string`
|
|
56
|
-
| `className` | `string`
|
|
57
|
-
| `colorLightmode` | `string`
|
|
58
|
-
| `colorDarkmode` | `string`
|
|
59
|
-
| `fullWidth` | `number`
|
|
60
|
-
| `maskLightByProgress` | `boolean`
|
|
61
|
-
| `invert` | `boolean`
|
|
62
|
-
| `
|
|
58
|
+
| Prop Name | Type | Default Value | Description |
|
|
59
|
+
| --------------------- | ---------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
60
|
+
| `id` | `string` | `undefined` | Optional string representing a unique ID for the LightBeam container. |
|
|
61
|
+
| `className` | `string` | `undefined` | Optional string representing custom classes to be added to the LightBeam container. |
|
|
62
|
+
| `colorLightmode` | `string` | `rgba(0,0,0, 0.5)` | Optional string representing the color of the light beam in light mode. |
|
|
63
|
+
| `colorDarkmode` | `string` | `rgba(255, 255, 255, 0.5)` | Optional string representing the color of the light beam in dark mode. |
|
|
64
|
+
| `fullWidth` | `number` | `1.0` | Optional number between `0` and `1` representing the maximum width the light beam can reach. |
|
|
65
|
+
| `maskLightByProgress` | `boolean` | `false` | If `true`, the `mask-image`'s linear gradient will start with the chosen color at 0% and the transparent part starting at 50%. As the user scrolls, it will dynamically change to have the transparent part at 95%, reducing the glow effect. If `false`, it will default to `linear-gradient(to bottom, chosenColor 25%, transparent 95%)`. |
|
|
66
|
+
| `invert` | `boolean` | `false` | Optional boolean to invert the scroll progress calculation. |
|
|
67
|
+
| `scrollElement` | `EventTarget` or `undefined` | `window` | Optional prop for which element to attach the scroll listener to. This could be the `window`, `document.body`, or any other scrollable element. |
|
|
68
|
+
| `onLoaded` | `undefined or () => void` | `undefined` | Optional function to run when the component has mounted |
|
|
63
69
|
|
|
64
70
|
### Default Configuration
|
|
65
71
|
|
|
@@ -121,6 +127,7 @@ The component automatically adjusts between light and dark modes based on the us
|
|
|
121
127
|
fullWidth={0.5}
|
|
122
128
|
maskLightByProgress={true}
|
|
123
129
|
invert={true}
|
|
130
|
+
scrollElement={document.body} // Example usage of the new scrollElement prop
|
|
124
131
|
/>
|
|
125
132
|
```
|
|
126
133
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
.react__light__beam {
|
|
2
2
|
height: 500px;
|
|
3
3
|
width: 100vw;
|
|
4
|
-
transition: all 0.
|
|
5
|
-
will-change:
|
|
4
|
+
transition: all 0.25s ease;
|
|
5
|
+
will-change: all;
|
|
6
6
|
-webkit-user-select: none;
|
|
7
7
|
-moz-user-select: none;
|
|
8
8
|
user-select: none;
|
|
9
9
|
pointer-events: none;
|
|
10
|
+
-webkit-transition: all 0.25s ease;
|
|
10
11
|
}/*# sourceMappingURL=lightBeam.module.css.map */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { LightBeamProps } from "../types/types";
|
|
3
|
-
export declare const LightBeam: ({ className, colorLightmode, colorDarkmode, maskLightByProgress, fullWidth, invert, id, onLoaded, }: LightBeamProps) => React.JSX.Element;
|
|
3
|
+
export declare const LightBeam: ({ className, colorLightmode, colorDarkmode, maskLightByProgress, fullWidth, invert, id, onLoaded, scrollElement, }: LightBeamProps) => React.JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -33,20 +33,18 @@ const react_1 = __importStar(require("react"));
|
|
|
33
33
|
const lightBeam_module_css_1 = __importDefault(require("./css/lightBeam.module.css"));
|
|
34
34
|
const useDarkmode_1 = require("./hooks/useDarkmode");
|
|
35
35
|
const LightBeam = ({ className, colorLightmode = "rgba(0,0,0, 0.5)", colorDarkmode = "rgba(255, 255, 255, 0.5)", maskLightByProgress = false, fullWidth = 1.0, // Default to full width
|
|
36
|
-
invert = false, id = undefined, onLoaded = undefined,
|
|
36
|
+
invert = false, id = undefined, onLoaded = undefined, scrollElement, // Add this line
|
|
37
|
+
}) => {
|
|
37
38
|
const elementRef = (0, react_1.useRef)(null);
|
|
38
|
-
const [bodyElement, setBodyElement] = (0, react_1.useState)(null); // State to hold the body element
|
|
39
39
|
const inViewProgress = (0, framer_motion_1.useMotionValue)(0);
|
|
40
40
|
const opacity = (0, framer_motion_1.useMotionValue)(0.839322);
|
|
41
41
|
const { isDarkmode } = (0, useDarkmode_1.useIsDarkmode)();
|
|
42
42
|
const chosenColor = isDarkmode ? colorDarkmode : colorLightmode;
|
|
43
43
|
(0, react_1.useEffect)(() => {
|
|
44
|
-
// Set the body element after the component mounts
|
|
45
|
-
setBodyElement(document.body);
|
|
46
44
|
onLoaded && onLoaded();
|
|
47
45
|
}, []);
|
|
48
46
|
(0, react_1.useEffect)(() => {
|
|
49
|
-
if (
|
|
47
|
+
if (typeof window !== "undefined") {
|
|
50
48
|
const handleScroll = () => {
|
|
51
49
|
if (elementRef.current) {
|
|
52
50
|
const rect = elementRef.current.getBoundingClientRect();
|
|
@@ -64,17 +62,18 @@ invert = false, id = undefined, onLoaded = undefined, }) => {
|
|
|
64
62
|
opacity.set(0.839322 + (1 - 0.839322) * progress);
|
|
65
63
|
}
|
|
66
64
|
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
const handleScrollThrottled = throttle(handleScroll); // Approx 60fps
|
|
66
|
+
const target = scrollElement || window;
|
|
67
|
+
target.addEventListener("scroll", handleScrollThrottled);
|
|
68
|
+
window.addEventListener("resize", handleScrollThrottled);
|
|
70
69
|
// Initial call to handleScroll to set initial state
|
|
71
70
|
handleScroll();
|
|
72
71
|
return () => {
|
|
73
|
-
|
|
74
|
-
window.removeEventListener("resize",
|
|
72
|
+
target.removeEventListener("scroll", handleScrollThrottled);
|
|
73
|
+
window.removeEventListener("resize", handleScrollThrottled);
|
|
75
74
|
};
|
|
76
75
|
}
|
|
77
|
-
}, [
|
|
76
|
+
}, [inViewProgress, opacity, scrollElement]);
|
|
78
77
|
const backgroundPosition = (0, framer_motion_1.useTransform)(inViewProgress, [0, 1], [
|
|
79
78
|
`conic-gradient(from 90deg at 90% 0%, ${chosenColor}, transparent 180deg) 0% 0% / 50% 150% no-repeat, conic-gradient(from 270deg at 10% 0%, transparent 180deg, ${chosenColor}) 100% 0% / 50% 100% no-repeat`,
|
|
80
79
|
`conic-gradient(from 90deg at 0% 0%, ${chosenColor}, transparent 180deg) 0% 0% / 50% 100% no-repeat, conic-gradient(from 270deg at 100% 0%, transparent 180deg, ${chosenColor}) 100% 0% / 50% 100% no-repeat`,
|
|
@@ -91,6 +90,19 @@ invert = false, id = undefined, onLoaded = undefined, }) => {
|
|
|
91
90
|
opacity: opacity,
|
|
92
91
|
maskImage: maskImage,
|
|
93
92
|
WebkitMaskImage: maskImage,
|
|
93
|
+
willChange: "background, opacity",
|
|
94
94
|
}, ref: elementRef, id: id, className: `lightBeam ${className} ${lightBeam_module_css_1.default.react__light__beam}` }));
|
|
95
95
|
};
|
|
96
96
|
exports.LightBeam = LightBeam;
|
|
97
|
+
const throttle = (func) => {
|
|
98
|
+
let ticking = false;
|
|
99
|
+
return function (...args) {
|
|
100
|
+
if (!ticking) {
|
|
101
|
+
requestAnimationFrame(() => {
|
|
102
|
+
func.apply(this, args);
|
|
103
|
+
ticking = false;
|
|
104
|
+
});
|
|
105
|
+
ticking = true;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stianlarsen/react-light-beam",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "A customizable React component that creates a light beam effect using conic gradients. Supports dark mode and various customization options.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"framer-motion": "^11.11.1",
|
|
42
42
|
"react": "^18",
|
|
43
|
-
"react-dom": "^18"
|
|
43
|
+
"react-dom": "^18",
|
|
44
|
+
"@emotion/is-prop-valid": "^1.3.1"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@types/react": "^18",
|
|
@@ -49,7 +50,6 @@
|
|
|
49
50
|
"typescript": "^5.5.4"
|
|
50
51
|
},
|
|
51
52
|
"dependencies": {
|
|
52
|
-
"@emotion/is-prop-valid": "^1.3.1",
|
|
53
53
|
"framer-motion": "^11.11.1"
|
|
54
54
|
}
|
|
55
55
|
}
|