Feedbackfeedbackanimation
Confetti Success
Feedback with falling confetti celebration.
Live Preview
Order placed!
Usage
Copy and paste this code into your React component:
tsx
import { ConfettiFeedback } from 'react-component-kit-ui/feedback';
<ConfettiFeedback label="Order placed!" active={done} />Manual Installation
If you are not using the npm package, create a new file and paste the following code: src/components/ConfettiFeedback.tsx + ConfettiFeedback.css:
ConfettiFeedback.tsx
'use client';
import type { CSSProperties, HTMLAttributes } from 'react';
import './ConfettiFeedback.css';
/**
* ConfettiFeedback โ A celebration component that triggers a falling confetti animation.
*
* @param label - Optional. Default 'Success!'.
* @param color - Optional. Confetti color. Default 'var(--c-primary, #6366f1)'.
* @param active - Optional. Whether confetti is falling. Default true.
* @param pieces - Optional. Number of confetti pieces. Default 12.
*/
export interface ConfettiFeedbackProps extends HTMLAttributes<HTMLDivElement> {
label?: string;
color?: string;
active?: boolean;
pieces?: number;
}
// Deterministic pseudo-random (0โ1) so server and client renders match.
const rand = (seed: number) => {
const x = Math.sin(seed * 9301 + 49297) * 233280;
return x - Math.floor(x);
};
export function ConfettiFeedback({
label = 'Success!',
color = 'var(--c-primary, #6366f1)',
active = true,
pieces = 12,
className,
...rest
}: ConfettiFeedbackProps) {
return (
<div {...rest} className={['confetti-trigger', active && 'confetti-trigger--active', className].filter(Boolean).join(' ')}>
<span className="confetti-label">{label}</span>
<div className="confetti-container" aria-hidden="true" style={{ '--confetti-color': color } as CSSProperties}>
{Array.from({ length: pieces }, (_, i) => (
<div
key={i}
className="confetti-piece"
style={
{
'--l': `${rand(i + 1) * 100}%`,
'--d': `${rand(i + 101) * 2}s`,
'--r': `${rand(i + 201) * 360}deg`,
'--s': 0.5 + rand(i + 301),
} as CSSProperties
}
/>
))}
</div>
</div>
);
}
export default ConfettiFeedback;ConfettiFeedback.css
/* ConfettiFeedback โ ported from astro-component-kit (feedback/ConfettiFeedback.astro) */
.confetti-trigger {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
padding: var(--sp-4, 1rem);
width: fit-content;
overflow: hidden;
}
.confetti-label {
font-size: 1.25rem;
font-weight: 800;
color: var(--c-text-1, #fff);
z-index: 1;
text-shadow: 0 4px 10px rgba(0,0,0,0.3);
}
.confetti-container {
position: absolute;
inset: 0;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s;
}
.confetti-trigger--active .confetti-container { opacity: 1; }
.confetti-piece {
position: absolute;
left: var(--l);
top: -20px;
width: 10px; height: 10px;
background: var(--confetti-color);
border-radius: 2px;
transform: rotate(var(--r)) scale(var(--s));
opacity: 0;
}
.confetti-trigger--active .confetti-piece {
animation: confetti-feedback-confetti-fall 2.5s linear infinite var(--d);
}
@keyframes confetti-feedback-confetti-fall {
0% { transform: translateY(0) rotate(0deg) scale(var(--s)); opacity: 1; }
25% { transform: translateY(40px) rotate(90deg) translateX(10px); }
50% { transform: translateY(80px) rotate(180deg) translateX(-10px); }
75% { transform: translateY(120px) rotate(270deg) translateX(5px); }
100% { transform: translateY(160px) rotate(360deg); opacity: 0; }
}Quick Info
- Category
- Feedback
- Filename
ConfettiFeedback.tsx- Dependencies
- None โ pure React + CSS
- Tags
- feedbackanimation