feat(ui): add Item and DynamicItem components and update Avatar, Icons#106
feat(ui): add Item and DynamicItem components and update Avatar, Icons#106
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. WalkthroughA comprehensive UI component update introducing a new Card system with composable sub-components, Slack and Stripe logo icons, Avatar logo customization support, and a useBreakpoint hook for responsive design. Global theme reset removed from CSS, react-responsive dependency added, and icon system refactored to support dynamic logo selection. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CardContent
participant useBreakpoint
participant CardTitle
participant CardDescription
participant CardAction
User->>CardContent: render with props
CardContent->>useBreakpoint: check if sm breakpoint
useBreakpoint-->>CardContent: return boolean
alt isSmallScreen
CardContent->>CardContent: apply column layout & center text
else
CardContent->>CardContent: apply row layout & left-align text
end
CardContent->>CardTitle: render with title prop
CardTitle-->>CardContent: return h3 element
CardContent->>CardDescription: render with description prop
CardDescription-->>CardContent: return p element
CardContent->>CardAction: render with action prop
CardAction-->>CardContent: return div with flex layout
CardContent-->>User: rendered card with responsive layout
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 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.
Pull Request Overview
This PR adds a new Card component system with responsive design capabilities to the React UI library. The main changes include:
- Introduction of
react-responsivepackage for media query handling - New Card component with multiple sub-components (CardContent, CardTitle, CardDescription, CardAction)
- New custom icon components (Slack and Stripe logos) and addition of GitHub icon
- Enhanced Avatar component to support dynamic logo rendering
Reviewed Changes
Copilot reviewed 19 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Added react-responsive@10.0.1 and its dependencies |
| libs/react/ui/package.json | Added react-responsive dependency |
| libs/react/ui/src/hooks/useBreakpoint.ts | New hook for responsive breakpoint detection |
| libs/react/ui/src/components/card/* | New Card component system with content, title, description, and action subcomponents |
| libs/react/ui/src/components/icon/* | Added Slack and Stripe logo components, updated icon exports |
| libs/react/ui/src/components/avatar/* | Enhanced to support dynamic logo names and custom logo styling |
| libs/react/ui/index.css | Commented out @theme directive that broke Tailwind breakpoints |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
libs/react/ui/src/components/card/card.stories.tsx (1)
2-2: Fix typo in asset filename:illutration-1.svg→illustration-1.svgThe asset file exists with a typo in its name (missing 'a' in "illustration"). The import correctly references the misspelled filename, so the code works, but this violates naming conventions. Since only this one file references the asset, rename both the file and the import statement.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
libs/react/ui/src/assets/illutration-1.svgis excluded by!**/*.svgpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (19)
libs/react/ui/index.css(1 hunks)libs/react/ui/package.json(1 hunks)libs/react/ui/src/components/avatar/avatar-group.tsx(2 hunks)libs/react/ui/src/components/avatar/avatar.stories.tsx(3 hunks)libs/react/ui/src/components/avatar/avatar.tsx(4 hunks)libs/react/ui/src/components/card/card-action.tsx(1 hunks)libs/react/ui/src/components/card/card-content.tsx(1 hunks)libs/react/ui/src/components/card/card-description.tsx(1 hunks)libs/react/ui/src/components/card/card-title.tsx(1 hunks)libs/react/ui/src/components/card/card.stories.tsx(1 hunks)libs/react/ui/src/components/card/card.tsx(1 hunks)libs/react/ui/src/components/card/index.ts(1 hunks)libs/react/ui/src/components/icon/custom/index.ts(1 hunks)libs/react/ui/src/components/icon/custom/slack-logo.tsx(1 hunks)libs/react/ui/src/components/icon/custom/stripe-logo.tsx(1 hunks)libs/react/ui/src/components/icon/icon.stories.tsx(1 hunks)libs/react/ui/src/components/icon/icon.tsx(3 hunks)libs/react/ui/src/components/index.ts(1 hunks)libs/react/ui/src/hooks/useBreakpoint.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/components/card/card-description.tsxlibs/react/ui/package.jsonlibs/react/ui/src/components/avatar/avatar.stories.tsxlibs/react/ui/src/components/card/card.tsxlibs/react/ui/src/components/icon/custom/slack-logo.tsxlibs/react/ui/src/components/avatar/avatar.tsxlibs/react/ui/src/components/icon/custom/stripe-logo.tsxlibs/react/ui/src/components/icon/custom/index.tslibs/react/ui/src/components/card/card.stories.tsxlibs/react/ui/src/components/index.tslibs/react/ui/src/components/card/card-action.tsxlibs/react/ui/src/components/icon/icon.stories.tsxlibs/react/ui/src/components/card/card-title.tsxlibs/react/ui/src/components/card/index.tslibs/react/ui/src/components/icon/icon.tsxlibs/react/ui/src/components/card/card-content.tsxlibs/react/ui/index.csslibs/react/ui/src/hooks/useBreakpoint.tslibs/react/ui/src/components/avatar/avatar-group.tsx
🧬 Code graph analysis (5)
libs/react/ui/src/components/avatar/avatar.tsx (1)
libs/react/ui/src/components/icon/icon.tsx (2)
IconName(49-49)Icon(55-58)
libs/react/ui/src/components/card/card.stories.tsx (7)
libs/react/ui/src/components/card/card.tsx (1)
Card(19-25)libs/react/ui/src/components/card/card-content.tsx (1)
CardContent(39-90)libs/react/ui/src/components/avatar/avatar.tsx (1)
Avatar(117-217)libs/react/ui/src/components/avatar/avatar-group.tsx (1)
AvatarGroup(119-184)libs/react/ui/src/components/button.tsx (1)
Button(39-63)libs/react/ui/src/hooks/useBreakpoint.ts (1)
useBreakpoint(13-17)libs/react/ui/src/components/icon/icon.tsx (1)
Icon(55-58)
libs/react/ui/src/components/icon/icon.stories.tsx (1)
libs/react/ui/src/components/icon/icon.tsx (1)
Icon(55-58)
libs/react/ui/src/components/icon/icon.tsx (3)
libs/react/ui/src/components/icon/custom/shipfox-logo.tsx (1)
ShipfoxLogo(8-20)libs/react/ui/src/components/icon/custom/slack-logo.tsx (1)
SlackLogo(8-37)libs/react/ui/src/components/icon/custom/stripe-logo.tsx (1)
StripeLogo(8-27)
libs/react/ui/src/components/card/card-content.tsx (4)
libs/react/ui/src/components/card/card.tsx (1)
Card(19-25)libs/react/ui/src/components/card/card-title.tsx (1)
CardTitle(6-18)libs/react/ui/src/components/card/card-description.tsx (1)
CardDescription(6-18)libs/react/ui/src/components/card/card-action.tsx (1)
CardAction(6-12)
🔇 Additional comments (24)
libs/react/ui/index.css (1)
7-10: LGTM! Fixes Tailwind breakpoint compatibility.Commenting out the aggressive CSS variable reset (
--*: initial) is the correct fix. The wildcard reset was breaking Tailwind's default theme system, which the newuseBreakpointhook depends on.libs/react/ui/src/hooks/useBreakpoint.ts (1)
1-17: LGTM! Clean breakpoint hook implementation.The breakpoint values correctly match Tailwind's defaults (sm=640px, md=768px, lg=1024px, xl=1280px, 2xl=1536px), and the type-safe generic implementation with
react-responsiveis well-structured.libs/react/ui/src/components/index.ts (1)
4-4: LGTM! Card component export follows the established pattern.The barrel export is positioned appropriately and makes the new Card component family available to consumers.
libs/react/ui/src/components/avatar/avatar-group.tsx (2)
20-21: Visual refinement: increased avatar overlap for sm/md sizes.The spacing change from
-space-x-4to-space-x-6increases the overlap between avatars in small and medium sizes, creating a more compact visual grouping.
79-79: Enhanced hover animation with smoother easing.The animation improvements enhance the user experience:
- Doubled lift distance (
-translate-y-4vs-translate-y-2) makes the hover effect more noticeable- Added
ease-in-outtiming provides smoother motionlibs/react/ui/src/components/icon/custom/index.ts (1)
10-10: LGTM! New logo exports follow the established pattern.The Slack and Stripe logo exports are properly integrated into the icon system's barrel exports.
Also applies to: 12-12
libs/react/ui/src/components/icon/icon.stories.tsx (1)
20-22: LGTM! Improved icon gallery layout.Wrapping each icon in a fixed-size, centered container provides consistent visual presentation in the Storybook gallery, making it easier to compare icon sizes and styles.
libs/react/ui/src/components/card/card-action.tsx (1)
1-12: LGTM! Clean CardAction implementation.The component provides a well-structured container for card actions with appropriate spacing (
mt-8), flexible wrapping (flex-wrap), and consistent gap (gap-16) between action items.libs/react/ui/package.json (1)
39-39: Version is current—no action needed.The latest stable version of react-responsive on npm as of November 7, 2025 is 10.0.1, which matches the version specified in the package.json. The caret constraint (
^10.0.1) appropriately permits future patch and minor updates.libs/react/ui/src/components/card/card-description.tsx (1)
1-18: LGTM! Clean component implementation.The CardDescription component follows React best practices with proper type safety and className composition. The
line-clamp-3class provides sensible overflow handling for description text.libs/react/ui/src/components/card/card-title.tsx (1)
6-18: Verify single-line truncation is the desired behavior.The
truncateclass on line 10 will limit card titles to a single line with an ellipsis for overflow. Ensure this aligns with the design requirements, especially for cards that might have longer titles.Consider if multi-line titles with
line-clamp-2would provide better UX in some cases, or if the single-line constraint is intentional for layout consistency.libs/react/ui/src/components/icon/custom/stripe-logo.tsx (1)
1-27: LGTM! Well-implemented logo component.The StripeLogo component correctly implements a customizable color prop (line 23) and includes proper accessibility attributes. The default Stripe brand color (#6772E5) is appropriate.
libs/react/ui/src/components/card/index.ts (1)
1-5: LGTM! Clean barrel export structure.The barrel exports provide a convenient single entry point for all Card-related components.
libs/react/ui/src/components/avatar/avatar.stories.tsx (1)
9-9: LGTM! Story updates showcase new logo functionality.The additions properly demonstrate the new
logoNameprop with multiple logo options (shipfox, slack, stripe, github). The Default story now showcases logo content instead of upload, which better highlights the new feature.Also applies to: 37-41, 48-48, 57-58
libs/react/ui/src/components/avatar/avatar.tsx (2)
113-114: LGTM! Dynamic logo support is well-implemented.The new
logoNameandlogoClassNameprops enable flexible logo rendering while maintaining backward compatibility with the 'shipfox' default.Also applies to: 126-127
165-175: No issues found — Remixicon components support the color prop.The @remixicon/react components accept a color prop, so the code at lines 165-175 is correct. The Icon component is properly typed with
BaseIconProps = ComponentProps<typeof RiGoogleFill>, ensuring all Remixicon icons (including 'github') accept the color prop passed on line 170. No conditional logic or changes are needed.Likely an incorrect or invalid review comment.
libs/react/ui/src/components/icon/icon.tsx (1)
4-4: LGTM! Icon system expansion is well-structured.The additions of Slack, Stripe, and GitHub icons expand the icon library appropriately. The renaming from
shipfoxLogotoshipfox(line 43) improves naming consistency across the icon set.Also applies to: 20-22, 43-46
libs/react/ui/src/components/card/card.tsx (1)
1-25: LGTM! Clean Card component implementation.The Card component is well-structured with proper TypeScript typing, CVA variant management, and a clean API. The use of
data-slot="card"provides a good hook for testing and styling.libs/react/ui/src/components/card/card-content.tsx (3)
8-37: LGTM! Well-documented type definition.The CardContentProps type is comprehensive with clear JSDoc comments describing each prop's purpose. The type safely extends Card props while adding layout-specific options.
39-58: LGTM! Clean setup logic.The derived values and conditional flags are well-implemented with sensible defaults.
60-90: Solid responsive layout implementation.The layout logic correctly handles optional elements with appropriate responsive behavior (column on mobile, row on larger screens). The use of flex utilities and conditional rendering is well-executed.
libs/react/ui/src/components/card/card.stories.tsx (3)
10-37: LGTM! Clean Storybook configuration.The meta configuration and Default story are well-structured and follow Storybook best practices.
39-123: LGTM! Comprehensive OrganizationCard examples.This story effectively demonstrates CardContent with avatars, avatar groups, and tooltips. The variety of examples (Slack, Stripe, Shipfox) with different member counts provides good visual documentation.
125-248: LGTM! Excellent demonstration of responsive behavior.These stories showcase advanced usage patterns:
- ConnectGithubAccount demonstrates composite avatar elements with absolute positioning
- WithCustomElements shows responsive layout adjustments using the useBreakpoint hook
The conditional rendering based on breakpoints (lines 219, 233-239) provides a clear example of adaptive UI design.
| import {useMediaQuery} from 'react-responsive'; | ||
|
|
||
| const breakpoints = { | ||
| sm: '40rem', | ||
| md: '48rem', | ||
| lg: '64rem', | ||
| xl: '80rem', | ||
| '2xl': '96rem', | ||
| }; | ||
|
|
||
| type BreakpointKey = keyof typeof breakpoints; | ||
|
|
||
| export function useBreakpoint<K extends BreakpointKey>(breakpointKey: K): boolean { | ||
| return useMediaQuery({ | ||
| query: `(min-width: ${breakpoints[breakpointKey]})`, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Looks like this is only used in stories. Do we actually need to add some external dependency and this hook for this purpose ?
There was a problem hiding this comment.
Yes, you're right. We don't really need extra deps for this. I have removed it here 04513d2
…ce DynamicItem component
Summary by CodeRabbit