Getting Started
Components
- Accordion
- Advanced Toast
- AlertMessage
- ArrowButton
- Arrows
- Avatar
- Backdrop
- Basic Toast
- Breadcrumb
- Button
- CardBackground
- Card
- Carousel
- Chapters
- ChatBody
- ChatButton
- ChatHeader
- ChatInput
- ChatMessageActions
- ChatMessageEditor
- ChatMessage
- ChatTypingIndicator
- ChatWindowCsatPrompt
- ChatWindowQuote
- ChatWindow
- CheckboxSelect
- Checkbox
- Checkboxes
- Chip
- ChoiceExpander
- Clickable
- ContentReview
- Countdown
- CriteriaDates
- CriteriaParticipants
- CriteriaTransports
- Date Field
- Datepicker
- Dropdown
- ElasticHeight
- ExpandableCard
- ExpandableText
- Filter
- FloatingLabelTextField
- Form Control
- Form Label
- Frame
- HamburgerIcon
- Heading
- Image
- JourneyCard
- LayerHeader
- Layer
- Link
- Loader
- Number Field
- PageNavigation
- Pagination
- Paragraph
- Password
- Phone Field
- Popin
- Portal
- ProductThumbnail
- Promises
- Prose
- Radio Group
- RadioSelect
- Radio
- Range
- Scrollbar
- Select
- SidebarLayout
- SliderFrame
- SparkleWrapper
- Spinner
- Switch
- Table
- Tabs
- Tag
- TextField
- Toggle
- Tooltip
- ValidationMessage
'use client';
import { useState } from 'react';
import { SparkleWrapper } from '@/ui/SparkleWrapper';
import { Icon } from '@clubmed/trident-icons';
export function SparkleWrapperDemo() {
const [key, setKey] = useState(0);
return (
<div className="flex flex-col items-center gap-48 p-48">
<SparkleWrapper className="text-green" count={3} key={key}>
<Icon name="CheckFilled" className="!text-green" width="75px" />
</SparkleWrapper>
{/* <SparkleWrapper key={`b-${key}`}>
<span className="text-h4 font-bold">🎉 Congratulations!</span>
</SparkleWrapper> */}
<button
type="button"
onClick={() => setKey((k) => k + 1)}
className="px-20 py-10 rounded-pill border-2 border-black font-semibold text-b3 hover:bg-black hover:text-white transition-colors cursor-pointer"
>
Replay animation
</button>
</div>
);
}
Installation
npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/sparkle-wrapper.json
Usage
import { SparkleWrapper } from '@/ui/SparkleWrapper';
export function Component() {
return (
<SparkleWrapper>
<div className="bg-saffron px-20 py-12 rounded-pill font-bold">New feature</div>
</SparkleWrapper>
);
}How it works
When the component mounts, two things happen simultaneously:
- Children animate in with
bounce-enter— scaling up from 50%, overshooting slightly, then settling at natural size. - 8 Diamond sparkles burst outward from the center in all directions (every 45°), each scaling down from 100% to 0 while fading out. Delays are staggered between 0–100ms and sizes vary (10–16px) for a natural, organic burst.
Both animations run once and do not repeat.
Delaying the sparkles
Pass delay (in milliseconds) to hold the sparkle burst back while the children still bounce in immediately. Sparkles are not rendered at all until the delay elapses, so nothing is visible beforehand. A good starting point is to let the bounce settle first:
<SparkleWrapper delay={400}>
<Icon name="CheckFilled" width="75px" />
</SparkleWrapper>API Reference
SparkleWrapper
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | The content to animate on mount |
count | number | 7 | Minimum number of sparkles (renders count to count + 3) |
delay | number | 0 | Milliseconds to wait before the sparkles start flying; children animate immediately |
className | string | undefined | Additional classes applied to the root div |
...props | HTMLAttributes<HTMLDivElement> | — | All standard div attributes are forwarded |
Notes
- The root element is
inline-flexso it shrinks to fit its content. Wrap it in a block container if you need full-width layout. - Animations fire once on mount. To replay them, unmount and remount the component (use a
keyprop). Changingdelayafter the sparkles have started does not replay them. - Sparkle icons are
aria-hidden="true"— they are purely decorative and invisible to assistive technology. - The
bounce-enterduration is 500ms; sparkles complete in 600ms. Nothing lingers after 700ms (including the longest 100ms delay).