reactbits-mcp-server
Version:
MCP Server for React Bits - Access 99+ React components with animations, backgrounds, and UI elements
108 lines (103 loc) • 2.79 kB
JSX
import { motion, useSpring, useTransform } from "framer-motion";
import { useEffect } from "react";
import "./Counter.css";
function Number({ mv, number, height }) {
let y = useTransform(mv, (latest) => {
let placeValue = latest % 10;
let offset = (10 + number - placeValue) % 10;
let memo = offset * height;
if (offset > 5) {
memo -= 10 * height;
}
return memo;
});
return (
<motion.span className="counter-number" style={{ y }}>
{number}
</motion.span>
);
}
function Digit({ place, value, height, digitStyle }) {
let valueRoundedToPlace = Math.floor(value / place);
let animatedValue = useSpring(valueRoundedToPlace);
useEffect(() => {
animatedValue.set(valueRoundedToPlace);
}, [animatedValue, valueRoundedToPlace]);
return (
<div className="counter-digit" style={{ height, ...digitStyle }}>
{Array.from({ length: 10 }, (_, i) => (
<Number key={i} mv={animatedValue} number={i} height={height} />
))}
</div>
);
}
export default function Counter({
value,
fontSize = 100,
padding = 0,
places = [100, 10, 1],
gap = 8,
borderRadius = 4,
horizontalPadding = 8,
textColor = "white",
fontWeight = "bold",
containerStyle,
counterStyle,
digitStyle,
gradientHeight = 16,
gradientFrom = "black",
gradientTo = "transparent",
topGradientStyle,
bottomGradientStyle,
}) {
const height = fontSize + padding;
const defaultCounterStyle = {
fontSize,
gap: gap,
borderRadius: borderRadius,
paddingLeft: horizontalPadding,
paddingRight: horizontalPadding,
color: textColor,
fontWeight: fontWeight,
};
const defaultTopGradientStyle = {
height: gradientHeight,
background: `linear-gradient(to bottom, ${gradientFrom}, ${gradientTo})`,
};
const defaultBottomGradientStyle = {
height: gradientHeight,
background: `linear-gradient(to top, ${gradientFrom}, ${gradientTo})`,
};
return (
<div className="counter-container" style={containerStyle}>
<div
className="counter-counter"
style={{ ...defaultCounterStyle, ...counterStyle }}
>
{places.map((place) => (
<Digit
key={place}
place={place}
value={value}
height={height}
digitStyle={digitStyle}
/>
))}
</div>
<div className="gradient-container">
<div
className="top-gradient"
style={topGradientStyle ? topGradientStyle : defaultTopGradientStyle}
></div>
<div
className="bottom-gradient"
style={
bottomGradientStyle
? bottomGradientStyle
: defaultBottomGradientStyle
}
></div>
</div>
</div>
);
}