feat: add shiny text, confetti, shipfox loader components#236
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughThis PR introduces two new decorative UI components to the React library: ShinyText (CSS-based text animation with gradient fill and shine effect) and Confetti (canvas-based celebration component with context-based API). Supporting dependencies are added, and both components are integrated into existing stories and components for demonstrating their usage. Changes
Sequence DiagramsequenceDiagram
participant User
participant ConfettiButton
participant ConfettiContext
participant Confetti
participant CanvasConfetti as canvas-confetti lib
User->>ConfettiButton: Click button
ConfettiButton->>ConfettiButton: Compute button position & origin
ConfettiButton->>ConfettiContext: Call context.fire(options)
ConfettiContext->>Confetti: Invoke ref.current.fire(mergedOptions)
Confetti->>Confetti: Merge call options with component options
Confetti->>CanvasConfetti: confetti(mergedOptions)
CanvasConfetti-->>Confetti: Animation renders on canvas
Confetti-->>ConfettiButton: Returns Promise
ConfettiButton-->>User: Confetti animation plays
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (5)
libs/react/ui/src/components/shiny-text/shiny-text.tsx (2)
1-6: ExportShinyTextPropsfor consumer type safety.The
ShinyTextPropsinterface should be exported so consumers can properly type their props when wrapping or extending this component.-interface ShinyTextProps { +export interface ShinyTextProps { text: string; disabled?: boolean; speed?: number; className?: string; }
11-17: Consider usingcn()utility for className composition.The codebase uses the
cn()utility (fromutils/cn) for className merging elsewhere. Using it here would provide consistent behavior and better handling of conditional classes.+import {cn} from 'utils/cn'; + function ShinyText({text, disabled = false, speed = 5, className = ''}: ShinyTextProps) { const animationDuration = `${speed}s`; return ( <div - className={`shiny-text ${disabled ? 'disabled' : ''} ${className}`} + className={cn('shiny-text', disabled && 'disabled', className)} style={{animationDuration}} > {text} </div> ); }libs/react/ui/src/components/modal/modal.stories.tsx (1)
221-231: Effect dependency may cause unintended timer restarts.The first effect has
[open, footerState]as dependencies, but the timer should only start when the modal opens withfooterState === 'running'. IffooterStatechanges while the modal is open, this won't cause issues due to the condition check, but consider removingfooterStatefrom the dependency array if the intent is only to react toopenchanges.The current implementation is functionally correct due to the condition guard, but you could simplify by only depending on
openif that's the sole trigger:useEffect(() => { if (open && footerState === 'running') { const timer = setTimeout(() => { setFooterState('done'); }, 3000); return () => { clearTimeout(timer); }; } - }, [open, footerState]); + }, [open]); // footerState check is inside the conditionHowever, keeping
footerStatein deps is also valid if re-evaluation on state change is desired.libs/react/ui/src/components/confetti/confetti.tsx (2)
23-25: UnusedConfettiContextand related type.
ConfettiContextis created and provided but never consumed. If this is intended for future use, consider adding a TODO comment; otherwise, remove the dead code.If not needed:
-type ConfettiContextValue = ConfettiApi; - -const ConfettiContext = createContext<ConfettiContextValue | null>(null);If intended for future use, export a hook:
export function useConfetti() { const context = useContext(ConfettiContext); if (!context) { throw new Error('useConfetti must be used within a Confetti component'); } return context; }
107-109:ConfettiButtonPropstype includescanvasoption that may cause confusion.The type allows
canvas?: HTMLCanvasElementin options, but the globalconfetti()function handles this differently than expected. If passed, it would override where confetti renders, which might not be the intended use case for this button component.Consider omitting
canvasfrom the allowed options:-export type ConfettiButtonProps = ComponentProps<'button'> & { - options?: ConfettiOptions & ConfettiGlobalOptions & {canvas?: HTMLCanvasElement}; -}; +export type ConfettiButtonProps = ComponentProps<'button'> & { + options?: Omit<ConfettiOptions & ConfettiGlobalOptions, 'canvas'>; +};
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (11)
libs/react/ui/index.css(1 hunks)libs/react/ui/package.json(3 hunks)libs/react/ui/src/components/code-block/code-block-footer.tsx(3 hunks)libs/react/ui/src/components/confetti/confetti.stories.tsx(1 hunks)libs/react/ui/src/components/confetti/confetti.tsx(1 hunks)libs/react/ui/src/components/confetti/index.ts(1 hunks)libs/react/ui/src/components/index.ts(2 hunks)libs/react/ui/src/components/modal/modal.stories.tsx(4 hunks)libs/react/ui/src/components/shiny-text/index.ts(1 hunks)libs/react/ui/src/components/shiny-text/shiny-text.tsx(1 hunks)libs/react/ui/src/index.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*
⚙️ CodeRabbit configuration file
We handle errors at the edge of our applications in most cases. Do not recommend to add error handling around every single function. We prefer them to bubble up and be handled at upper layers.
Files:
libs/react/ui/src/index.tslibs/react/ui/src/components/confetti/index.tslibs/react/ui/src/components/shiny-text/index.tslibs/react/ui/index.csslibs/react/ui/src/components/index.tslibs/react/ui/src/components/confetti/confetti.stories.tsxlibs/react/ui/src/components/confetti/confetti.tsxlibs/react/ui/package.jsonlibs/react/ui/src/components/modal/modal.stories.tsxlibs/react/ui/src/components/code-block/code-block-footer.tsxlibs/react/ui/src/components/shiny-text/shiny-text.tsx
🧬 Code graph analysis (4)
libs/react/ui/src/components/confetti/confetti.stories.tsx (1)
libs/react/ui/src/components/confetti/confetti.tsx (2)
Confetti(105-105)ConfettiButton(111-135)
libs/react/ui/src/components/confetti/confetti.tsx (1)
libs/react/ui/src/components/button/button.tsx (1)
Button(50-91)
libs/react/ui/src/components/modal/modal.stories.tsx (1)
libs/react/ui/src/components/confetti/confetti.tsx (2)
ConfettiRef(27-27)Confetti(105-105)
libs/react/ui/src/components/code-block/code-block-footer.tsx (2)
libs/react/ui/src/index.ts (1)
ShipfoxLoader(4-4)libs/react/ui/src/components/shiny-text/shiny-text.tsx (1)
ShinyText(21-21)
🔇 Additional comments (12)
libs/react/ui/src/index.ts (1)
4-4: LGTM!The re-export of
ShipfoxLoaderfromshipfox-loader-reactis clean and the dependency is properly declared inpackage.json.libs/react/ui/src/components/confetti/index.ts (1)
1-1: LGTM!Standard barrel export pattern for the confetti module.
libs/react/ui/index.css (1)
941-970: LGTM!The shiny-text CSS implementation is well-structured with proper vendor prefixes for Safari compatibility (
-webkit-background-clip,-webkit-text-fill-color). The hardcoded5sduration in CSS serves as a sensible default and is correctly overridden by the component's inlineanimationDurationstyle when thespeedprop is provided.libs/react/ui/src/components/confetti/confetti.stories.tsx (1)
1-38: LGTM!The Storybook stories provide good coverage of both default and customized confetti usage patterns. The
WithOptionsstory effectively demonstrates the configurable nature of the component.libs/react/ui/src/components/modal/modal.stories.tsx (1)
255-265: LGTM!The Confetti component integration is well-implemented with
manualstartto prevent auto-firing, proper ref handling, and appropriate z-index/pointer-events styling to avoid blocking interactions.libs/react/ui/src/components/confetti/confetti.tsx (1)
111-135:ConfettiButtonuses global confetti instead of canvas instance.Unlike the
Confetticomponent which uses a dedicated canvas,ConfettiButtoncalls the globalconfetti()function directly. This creates confetti on a default canvas that may overlay the entire viewport. This is likely intentional for standalone use, but documenting this behavior difference would help consumers.Is this intentional? If
ConfettiButtonshould use the same canvas as a parentConfetticomponent, it could consume theConfettiContextinstead:// Alternative: Use context if available, fallback to global const context = useContext(ConfettiContext); const fireConfetti = context?.fire ?? confetti;libs/react/ui/package.json (2)
48-48: Theshipfox-loader-reactpackage is published and publicly accessible on npm. No action needed.
39-39: canvas-confetti@^1.9.4 is verified as secure and legitimate.Version 1.9.4 is the current latest stable release with no known security vulnerabilities. The package is actively maintained, has zero dependencies, and is published by a verified maintainer.
libs/react/ui/src/components/index.ts (1)
8-8: LGTM! Barrel exports follow the established pattern.The new component exports are correctly positioned alphabetically and follow the existing barrel export pattern in this index file.
Also applies to: 23-23
libs/react/ui/src/components/code-block/code-block-footer.tsx (2)
3-3: LGTM! Imports are correctly structured.The new imports for ShinyText and ShipfoxLoader are properly added and follow the project's import conventions.
Also applies to: 6-6
32-32: Manual verification required for ShipfoxLoader props.The
shipfox-loader-reactpackage is not publicly available, preventing verification of the props API. Access to the package documentation or source code is needed to confirm whethersize,animation,color, andbackgroundare valid props and whether the provided values are acceptable.libs/react/ui/src/components/shiny-text/index.ts (1)
1-1: LGTM! Standard barrel export.The barrel export follows the established pattern for component modules in this library.
There was a problem hiding this comment.
Pull request overview
This PR adds three new UI components to the React component library: a ShinyText component for animated text effects, a Confetti component for celebratory animations, and integrates the ShipfoxLoader from an external package. The changes enhance the visual experience by replacing static icons with animated loaders and adding visual feedback for completion states.
Key Changes:
- Adds ShinyText component with customizable animation speed for text shimmer effects
- Adds Confetti component with canvas-based particle animations and a ConfettiButton wrapper
- Integrates shipfox-loader-react external package and exports it from the main library index
- Updates CodeBlockFooter to use ShipfoxLoader and ShinyText for enhanced visual feedback
- Adds interactive demo in modal stories showing confetti trigger on completion state
Reviewed changes
Copilot reviewed 11 out of 12 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds canvas-confetti@1.9.4, @types/canvas-confetti@1.9.0, and shipfox-loader-react@1.0.1 dependencies |
| libs/react/ui/package.json | Declares new dependencies in dependencies and devDependencies sections |
| libs/react/ui/src/index.ts | Exports ShipfoxLoader from external package at library root level |
| libs/react/ui/src/components/index.ts | Exports new confetti and shiny-text components |
| libs/react/ui/src/components/shiny-text/* | Implements ShinyText component with text, disabled, speed, and className props |
| libs/react/ui/src/components/confetti/* | Implements Confetti canvas component with ref API and ConfettiButton wrapper, includes Storybook stories |
| libs/react/ui/src/components/code-block/code-block-footer.tsx | Replaces static shipfox icon with ShipfoxLoader, wraps running state messages with ShinyText |
| libs/react/ui/src/components/modal/modal.stories.tsx | Adds GithubActions story demo with state management, confetti trigger on completion |
| libs/react/ui/index.css | Adds CSS for shiny-text animation with linear gradient and keyframe animation |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
…t to use span element
Summary by CodeRabbit
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.