Luminous Card
A card wrapper component that adds a subtle cursor-tracking glow to enhance visual feedback in interactive UIs.
⚙️
Customizable Dashboard
Organize widgets, reports, and charts the way you need them to keep all your insights at a glance.
luminous-card-preview.jsx
import LuminousCard from "@/components/interactions/luminous-card/luminous-card";
const LuminousCardPreview = () => {
return (
<LuminousCard
color={{
light: "rgba(132, 250, 175, 0.15)",
dark: "rgba(132, 250, 175, 0.25)",
}}
style={cardStyle}
>
{/* Add your card content here */}
<span style={iconStyle}>⚙️</span>
<h2>Customizable Dashboard</h2>
<p>Organize widgets, reports, and charts the way you need them to keep all your insights at a glance.</p>
</LuminousCard>
)
};
const cardStyle = {
width: "320px",
background: "var(--layer-secondary)",
border: "1px solid var(--border-secondary)",
borderRadius: "8px",
padding: "24px",
};
const iconStyle = {
display: "inline-block",
marginBottom: "20px",
fontSize: "24px",
}
export default LuminousCardPreview; Installation
Run the command from your project root directory (the folder that contains package.json).
Terminal / Console
npx mosaicui-cli@latest interactions/luminous-card 1. Copy the component file
Create a new file called luminous-card.jsx
in your reusable components folder (for example
/src/components/) and paste the following
code into it.
luminous-card.jsx
import { memo, useCallback, useRef } from "react";
import styles from "./luminous-card.module.css";
const LuminousCard = (props) => {
const {
color = "rgba(255, 255, 255, 0.25)",
className,
tagName = "div",
children,
...restProps
} = props;
const Component = tagName || "div";
const cardWrapperRef = useRef();
const cardMouseMoveHandler = useCallback((e) => {
const cardWrapperNode = cardWrapperRef.current;
const { x: cardWrapperX, y: cardWrapperY } = cardWrapperNode.getBoundingClientRect();
const x = Math.max(0, e.clientX - cardWrapperX);
const y = Math.max(0, e.clientY - cardWrapperY);
let lightThemeColor = color;
let darkThemeColor = color;
if (typeof color === "object") {
lightThemeColor = color.light;
darkThemeColor = color.dark;
}
Object.entries({
"x": `${x}px`,
"y": `${y}px`,
"light-color": lightThemeColor,
"dark-color": darkThemeColor,
}).forEach(([key, value]) => {
cardWrapperNode.style.setProperty(`--${key}`, value);
});
}, [color]);
return (
<Component
{...restProps}
ref={cardWrapperRef}
onMouseMove={cardMouseMoveHandler}
className={[
className,
styles["luminous-card"],
].join(" ")}
>
{children}
</Component>
);
};
export default memo(LuminousCard); 2. Copy the CSS module file
In the same folder, create a file called luminous-card.module.css and paste the following
CSS.
luminous-card.module.css
.luminous-card {
--x: 0px;
--y: 0px;
--luminous-color: var(--light-color);
@media (prefers-color-scheme: dark) {
--luminous-color: var(--dark-color);
}
position: relative;
overflow: hidden;
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
background: transparent;
opacity: 0;
pointer-events: none;
transition:
background 250ms ease-in-out,
opacity 250ms ease-in-out;
}
&:hover {
&:before {
opacity: 0.85;
background:
radial-gradient(
circle at var(--x) var(--y),
var(--luminous-color),
transparent 85%
);
}
}
} Props
Configure the component with the following props:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
| children | React.ReactNode | No | — | Content rendered inside the component. |
| tagName | string | No | "div" | HTML tag used as the wrapper element for the component. |
| color | string | { light: string; dark: string } | No | "rgba(255, 255, 255, 0.25)" | Color used for the lighting / radial gradient effect. Accepts a single color string or an object with light and dark values for theme-specific colors. |
| className | string | No | — | Additional CSS classes applied to the root element. |
| style | React.CSSProperties | No | — | Inline styles applied to the root element. |