Skip to content

feat(ui): introduce Card and EmptyState components, upgrade Charts#276

Merged
kylengn merged 3 commits intomainfrom
feat/charts
Dec 31, 2025
Merged

feat(ui): introduce Card and EmptyState components, upgrade Charts#276
kylengn merged 3 commits intomainfrom
feat/charts

Conversation

@kylengn
Copy link
Contributor

@kylengn kylengn commented Dec 30, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Added composable Card component with header, title, description, content, footer, and action sections.
    • Added EmptyState component for consistent empty data presentation in two variants (default and compact).
    • Added loading skeleton states to data table and charts.
  • Improvements

    • Enhanced bar and line charts with empty state overlays, improved styling, and interactive hover effects.
    • Extended chart color palette with new amber color option.
    • Added customizable axis, grid, and tooltip formatting for charts.
  • Documentation

    • Added comprehensive Storybook stories for Card, EmptyState, and chart components.

✏️ Tip: You can customize this high-level summary in your review settings.

@kylengn kylengn self-assigned this Dec 30, 2025
Copilot AI review requested due to automatic review settings December 30, 2025 15:08
@vercel
Copy link

vercel bot commented Dec 30, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
react-ui Ready Ready Preview, Comment Dec 30, 2025 3:42pm

@coderabbitai
Copy link

coderabbitai bot commented Dec 30, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Introduces a new composable Card component with subcomponents (CardHeader, CardTitle, CardDescription, CardContent, CardFooter, CardAction), a new EmptyState component with default and compact variants, and significantly refactors existing BarChart and LineChart components to include Card wrappers, empty state handling, improved hover interactions, and enhanced axis/grid/tooltip control. Adds utility functions for tooltip normalization, color selection, and hover opacity calculation. Updates DataTable with loading state skeleton rendering and improves styling for chart tooltips and table rows. Includes comprehensive Storybook stories for all new and updated components.

Changes

Cohort / File(s) Summary
New Card Component
libs/react/ui/src/components/card/card.tsx, libs/react/ui/src/components/card/index.ts
Introduces composable Card system with 7 subcomponents (Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter) extending div/typography props with predefined Tailwind classNames for spacing, borders, and layout. All components support prop spreading for extensibility.
Card Stories
libs/react/ui/src/components/card/card.stories.tsx
Adds Storybook configuration with Default, WithFooter, WithAction, and LoginForm story variants demonstrating Card composition with UI elements and form controls.
New EmptyState Component
libs/react/ui/src/components/empty-state/empty-state.tsx, libs/react/ui/src/components/empty-state/index.ts
Introduces EmptyState component with default and compact variants supporting optional icon, title, and description props; renders centered icon container with typography.
EmptyState Stories
libs/react/ui/src/components/empty-state/empty-state.stories.tsx
Adds Storybook configuration with 5 story variants (Default, CustomContent, Compact, NoDescription, NoTitle) demonstrating different states and content combinations.
Chart Component Refactoring
libs/react/ui/src/components/dashboard/components/charts/bar-chart.tsx, libs/react/ui/src/components/dashboard/components/charts/line-chart.tsx
Wraps charts in Card container with optional CardHeader/CardTitle; adds EmptyState overlay for no-data conditions; introduces data-driven bar/line visibility via hide flag; replaces inline axis/grid props with Pick types for better control; adds interactive hover state management (hoveredDataKey) with opacity-based highlighting; implements per-item legend/indicator row below chart; adds barRadius prop and stackId support for bars.
Chart Stories
libs/react/ui/src/components/dashboard/components/charts/bar-chart.stories.tsx, libs/react/ui/src/components/dashboard/components/charts/line-chart.stories.tsx
Adds comprehensive Storybook stories (Default, WithTitle, SingleBar/Line, CustomColors, StackedBars, RoundedBars, HiddenBars/Lines, CustomFormatter, EmptyState) demonstrating chart variants, configurations, formatters, and empty states.
Chart Utilities
libs/react/ui/src/components/dashboard/components/charts/utils.ts
Introduces three utility functions: normalizeTooltipPayload (formats Recharts payload with optional value formatter), getChartColor (resolves color by key or index cycling), getHoverOpacity (computes opacity based on hover state).
Chart Styling & Colors
libs/react/ui/src/components/dashboard/components/charts/chart-tooltip.tsx, libs/react/ui/src/components/dashboard/components/charts/colors.ts
Updates tooltip to use Text components for label and values with improved styling; adds amber color to chartColors palette; updates neutral color variable reference from --foreground-neutral-muted to --color-neutral-500.
Chart Exports
libs/react/ui/src/components/dashboard/components/charts/index.ts, libs/react/ui/src/components/dashboard/index.ts
Adds utils module re-export to charts index; adds ChartColor type export to dashboard index.
DataTable Loading State
libs/react/ui/src/components/table/data-table.tsx
Introduces isLoading prop that conditionally renders skeleton-based loading UI (Card → CardContent → Table with Skeleton cells) instead of actual table when true; skeleton row count derived from pageSize.
Table Component Updates
libs/react/ui/src/components/table/table.tsx, libs/react/ui/src/components/table/table.stories.components.tsx
Adds last:rounded-b-8 class to TableRow last child for bottom corner rounding; replaces custom JobsEmptyState JSX with standardized EmptyState component in stories.
Component Barrel Exports
libs/react/ui/src/components/index.ts
Adds three new re-exports: export \* from './card', './dashboard', './empty-state' to expand public component API surface.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • EnzalRad
  • dvxam
  • noe-charmet

Poem

🐰 The cards are stacked with care so neat,
Empty states make layouts complete,
Charts now glow with hovering grace,
While tables load at steady pace—
A dashboard dressed in tailored cloak!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the main changes: introducing Card and EmptyState components and upgrading Charts, which align with the substantial new files and enhancements across the codebase.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
libs/react/ui/src/components/table/data-table.tsx (1)

205-206: Inconsistent CardContent styling between loading and loaded states.

The loading state applies rounded-8 overflow-hidden to CardContent (line 206) while the loaded state only has p-0 (line 236). This may cause a subtle visual difference when transitioning from loading to loaded.

Consider aligning the classes for consistency:

🔎 Proposed fix
-      <CardContent className="p-0">
+      <CardContent className="rounded-8 overflow-hidden p-0">

Also applies to: 235-236

libs/react/ui/src/components/card/card.stories.tsx (1)

71-81: Consider extracting the common header layout pattern.

The header layout structure with CardAction is duplicated between the WithAction and LoginForm stories. While duplication in stories is acceptable for clarity, you might consider extracting this pattern into a reusable render helper if more stories follow this pattern.

Example refactor
const renderCardHeaderWithAction = (title: string, description: string, actionLabel: string) => (
  <CardHeader>
    <div className="flex items-start justify-between gap-16">
      <div className="flex flex-col gap-4 flex-1">
        <CardTitle>{title}</CardTitle>
        <CardDescription>{description}</CardDescription>
      </div>
      <CardAction>
        <Button variant="transparent" size="sm">
          {actionLabel}
        </Button>
      </CardAction>
    </div>
  </CardHeader>
);

Also applies to: 96-106

libs/react/ui/src/components/card/card.tsx (1)

1-84: Optional: Consider adding JSDoc comments for better developer experience.

While the component names are clear and self-documenting, adding JSDoc comments with usage examples could help developers understand the intended composition patterns (e.g., how CardAction fits within CardHeader, when to use CardFooter vs CardAction).

Example JSDoc pattern
+/**
+ * Main card container with padding, border, and rounded corners.
+ * Use with CardHeader, CardContent, and CardFooter for structured layouts.
+ * @example
+ * <Card>
+ *   <CardHeader>
+ *     <CardTitle>Title</CardTitle>
+ *   </CardHeader>
+ *   <CardContent>Content here</CardContent>
+ * </Card>
+ */
 export function Card({className, children, ...props}: CardProps) {
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b1fd1a and 1a0ea12.

📒 Files selected for processing (19)
  • libs/react/ui/src/components/card/card.stories.tsx
  • libs/react/ui/src/components/card/card.tsx
  • libs/react/ui/src/components/card/index.ts
  • libs/react/ui/src/components/dashboard/components/charts/bar-chart.stories.tsx
  • libs/react/ui/src/components/dashboard/components/charts/bar-chart.tsx
  • libs/react/ui/src/components/dashboard/components/charts/chart-tooltip.tsx
  • libs/react/ui/src/components/dashboard/components/charts/colors.ts
  • libs/react/ui/src/components/dashboard/components/charts/index.ts
  • libs/react/ui/src/components/dashboard/components/charts/line-chart.stories.tsx
  • libs/react/ui/src/components/dashboard/components/charts/line-chart.tsx
  • libs/react/ui/src/components/dashboard/components/charts/utils.ts
  • libs/react/ui/src/components/dashboard/index.ts
  • libs/react/ui/src/components/empty-state/empty-state.stories.tsx
  • libs/react/ui/src/components/empty-state/empty-state.tsx
  • libs/react/ui/src/components/empty-state/index.ts
  • libs/react/ui/src/components/index.ts
  • libs/react/ui/src/components/table/data-table.tsx
  • libs/react/ui/src/components/table/table.stories.components.tsx
  • libs/react/ui/src/components/table/table.tsx
🧰 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/index.ts
  • libs/react/ui/src/components/empty-state/index.ts
  • libs/react/ui/src/components/table/table.tsx
  • libs/react/ui/src/components/index.ts
  • libs/react/ui/src/components/dashboard/components/charts/colors.ts
  • libs/react/ui/src/components/table/table.stories.components.tsx
  • libs/react/ui/src/components/dashboard/components/charts/index.ts
  • libs/react/ui/src/components/empty-state/empty-state.tsx
  • libs/react/ui/src/components/empty-state/empty-state.stories.tsx
  • libs/react/ui/src/components/dashboard/index.ts
  • libs/react/ui/src/components/table/data-table.tsx
  • libs/react/ui/src/components/dashboard/components/charts/utils.ts
  • libs/react/ui/src/components/dashboard/components/charts/bar-chart.tsx
  • libs/react/ui/src/components/dashboard/components/charts/line-chart.stories.tsx
  • libs/react/ui/src/components/dashboard/components/charts/line-chart.tsx
  • libs/react/ui/src/components/dashboard/components/charts/chart-tooltip.tsx
  • libs/react/ui/src/components/dashboard/components/charts/bar-chart.stories.tsx
  • libs/react/ui/src/components/card/card.tsx
  • libs/react/ui/src/components/card/card.stories.tsx
🧬 Code graph analysis (11)
libs/react/ui/src/components/table/table.stories.components.tsx (4)
libs/react/ui/src/components/dashboard/components/charts/bar-chart.stories.tsx (1)
  • EmptyState (169-181)
libs/react/ui/src/components/dashboard/components/charts/line-chart.stories.tsx (1)
  • EmptyState (152-164)
libs/react/ui/src/components/empty-state/empty-state.tsx (1)
  • EmptyState (13-63)
libs/react/ui/src/components/table/table.stories.tsx (1)
  • EmptyState (57-68)
libs/react/ui/src/components/empty-state/empty-state.tsx (2)
libs/react/ui/src/components/icon/icon.tsx (2)
  • IconName (77-77)
  • Icon (86-90)
libs/react/ui/src/components/typography/text.tsx (1)
  • Text (27-50)
libs/react/ui/src/components/empty-state/empty-state.stories.tsx (1)
libs/react/ui/src/components/empty-state/empty-state.tsx (1)
  • EmptyState (13-63)
libs/react/ui/src/components/dashboard/components/charts/utils.ts (3)
libs/react/ui/src/components/dashboard/components/charts/chart-tooltip.tsx (1)
  • ChartTooltipContentProps (4-15)
libs/react/ui/src/components/dashboard/components/charts/colors.ts (3)
  • ChartColor (11-11)
  • chartColors (1-9)
  • chartColorsList (13-21)
libs/react/ui/src/components/dashboard/index.ts (1)
  • ChartColor (7-7)
libs/react/ui/src/components/dashboard/components/charts/bar-chart.tsx (3)
libs/react/ui/src/components/dashboard/components/charts/chart-tooltip.tsx (1)
  • ChartTooltipContent (17-60)
libs/react/ui/src/components/dashboard/components/charts/utils.ts (3)
  • normalizeTooltipPayload (11-30)
  • getChartColor (32-34)
  • getHoverOpacity (36-41)
libs/react/ui/src/components/empty-state/empty-state.tsx (1)
  • EmptyState (13-63)
libs/react/ui/src/components/dashboard/components/charts/line-chart.stories.tsx (1)
libs/react/ui/src/components/dashboard/components/charts/line-chart.tsx (2)
  • LineChart (49-187)
  • LineChartProps (33-47)
libs/react/ui/src/components/dashboard/components/charts/line-chart.tsx (7)
libs/react/ui/src/components/dashboard/index.ts (1)
  • LineChartProps (7-7)
libs/react/ui/src/components/card/card.tsx (4)
  • Card (7-19)
  • CardHeader (23-29)
  • CardTitle (33-39)
  • CardContent (68-74)
libs/react/ui/src/components/tooltip/tooltip.tsx (1)
  • Tooltip (114-114)
libs/react/ui/src/components/dashboard/components/charts/chart-tooltip.tsx (1)
  • ChartTooltipContent (17-60)
libs/react/ui/src/components/dashboard/components/charts/utils.ts (3)
  • normalizeTooltipPayload (11-30)
  • getChartColor (32-34)
  • getHoverOpacity (36-41)
libs/react/ui/src/components/dashboard/components/charts/line-chart.stories.tsx (1)
  • EmptyState (152-164)
libs/react/ui/src/components/empty-state/empty-state.tsx (1)
  • EmptyState (13-63)
libs/react/ui/src/components/dashboard/components/charts/chart-tooltip.tsx (1)
libs/react/ui/src/components/typography/text.tsx (1)
  • Text (27-50)
libs/react/ui/src/components/dashboard/components/charts/bar-chart.stories.tsx (1)
libs/react/ui/src/components/dashboard/components/charts/bar-chart.tsx (2)
  • BarChart (51-182)
  • BarChartProps (33-49)
libs/react/ui/src/components/card/card.tsx (1)
libs/react/ui/src/components/typography/text.tsx (1)
  • Text (27-50)
libs/react/ui/src/components/card/card.stories.tsx (8)
libs/react/ui/src/components/card/card.tsx (7)
  • Card (7-19)
  • CardHeader (23-29)
  • CardTitle (33-39)
  • CardDescription (43-54)
  • CardContent (68-74)
  • CardFooter (78-84)
  • CardAction (58-64)
libs/react/ui/src/components/dashboard/components/charts/bar-chart.stories.tsx (1)
  • Default (25-40)
libs/react/ui/src/components/dashboard/components/charts/line-chart.stories.tsx (1)
  • Default (25-40)
libs/react/ui/src/components/empty-state/empty-state.stories.tsx (1)
  • Default (16-23)
libs/react/ui/src/components/typography/text.tsx (1)
  • Text (27-50)
libs/react/ui/src/components/button/button.tsx (1)
  • Button (50-91)
libs/react/ui/src/components/label/label.tsx (1)
  • Label (13-15)
libs/react/ui/src/components/input/input.tsx (1)
  • Input (24-43)
🔇 Additional comments (42)
libs/react/ui/src/components/table/table.tsx (1)

41-47: Verify border-radius renders correctly on <tr> elements.

The last:rounded-b-8 utility may not visually apply to <tr> elements in standard table layouts, as border-radius is typically ignored on table rows with border-collapse: collapse. This usually requires either border-collapse: separate on the table or applying the radius to the <td> cells directly (e.g., last:first:rounded-bl-8 last:last:rounded-br-8 on cells).

If the table already uses separate border mode or a CSS layout where this works, feel free to disregard.

libs/react/ui/src/components/table/data-table.tsx (3)

16-19: LGTM!

Clean addition of the necessary imports for the new loading state and Card wrapper functionality.


156-170: LGTM!

Explicit type annotations improve clarity and the stopPropagation correctly prevents row click events when interacting with selection checkboxes.


253-284: LGTM!

Good implementation with proper accessibility for clickable rows (keyboard support with Enter/Space) and a sensible default EmptyState fallback.

libs/react/ui/src/components/dashboard/index.ts (1)

7-7: LGTM!

Clean extension of the public type exports to include ChartColor.

libs/react/ui/src/components/empty-state/index.ts (1)

1-1: LGTM!

Standard barrel export for the EmptyState module.

libs/react/ui/src/components/dashboard/components/charts/index.ts (1)

5-5: LGTM!

Properly extends the charts public API to include utility exports.

libs/react/ui/src/components/card/index.ts (1)

1-1: LGTM!

Standard barrel export for the Card module.

libs/react/ui/src/components/table/table.stories.components.tsx (1)

5-5: LGTM!

Excellent refactor to use the new standardized EmptyState component instead of custom markup. This improves consistency and maintainability across the UI library.

Also applies to: 25-30

libs/react/ui/src/components/index.ts (1)

7-7: LGTM!

Clean expansion of the public API to include the new Card, Dashboard, and EmptyState modules.

Also applies to: 12-12, 18-18

libs/react/ui/src/components/dashboard/components/charts/colors.ts (3)

7-7: LGTM!

Good addition of the amber color to expand the chart color palette.


19-20: LGTM!

Properly updated chartColorsList to include the new amber and updated neutral colors.


8-8: No verification necessary — neutral color is not currently used by any chart stories or implementations.

The neutral color in the chartColorsList serves only as a fallback when rendering more than 6 data series without explicit color assignments. Existing chart implementations (bar-chart and line-chart) all use explicit colors or rely on fallback colors through the getChartColor() utility. The Storybook stories for both BarChart and LineChart do not test the neutral color, and no production usage of this fallback scenario is documented.

libs/react/ui/src/components/dashboard/components/charts/chart-tooltip.tsx (3)

1-3: LGTM! Clean import organization.

The Text component import is properly added for consistent typography rendering.


29-32: Good use of design system tokens and Text component.

The tooltip container styling and label rendering are consistent with the design system. The labelFormatter fallback pattern is appropriate.


38-54: Well-structured hover interaction and consistent typography.

The conditional opacity class elegantly handles the hover state, and the Text components with tabular-nums ensure proper alignment for numeric values.

libs/react/ui/src/components/empty-state/empty-state.stories.tsx (2)

4-14: Well-structured Storybook meta configuration.

The meta configuration follows Storybook best practices with autodocs tags and centered layout.


16-73: Comprehensive story coverage for EmptyState variants.

The stories effectively demonstrate the component's API, including default behavior, custom content, compact variant, and optional props. Good use of fixed-width containers for consistent visual testing.

libs/react/ui/src/components/dashboard/components/charts/utils.ts (2)

11-30: Solid payload normalization with good type safety.

The function handles undefined payloads gracefully and provides safe type coercion. One minor consideration: Number(p.value) will produce NaN for non-numeric strings, which will then be formatted and displayed. This is acceptable behavior since the formatter is user-provided and should handle expected value types.


32-41: Clean utility functions for color and hover state management.

Both functions are pure, well-typed, and handle edge cases correctly. The modulo operation in getChartColor ensures safe cycling through the color list.

libs/react/ui/src/components/empty-state/empty-state.tsx (3)

6-11: Well-designed props interface extending native div attributes.

The EmptyStateProps interface properly extends ComponentProps<'div'>, allowing consumers to pass additional div props while providing type-safe component-specific props.


21-31: Clear variant-based styling logic.

The conditional class assignments for containerClasses, iconContainerClasses, and iconSize are easy to follow. This approach works well for two variants.


42-60: Good conditional rendering and typography hierarchy.

The optional title and description with appropriate text sizing (sm for title, xs for description) creates a clear visual hierarchy. The space-y-4 only applies in default variant which is correct.

libs/react/ui/src/components/dashboard/components/charts/line-chart.stories.tsx (2)

4-24: Well-organized Storybook configuration and sample data.

The meta configuration and shared sampleData provide a solid foundation for the stories. The data structure supports multi-series visualization testing.


25-164: Excellent story coverage demonstrating LineChart capabilities.

The stories thoroughly cover the component's API including title, colors, axis visibility, hidden lines, formatters, and empty state handling. The satisfies LineChartProps ensures type safety for story args.

libs/react/ui/src/components/dashboard/components/charts/bar-chart.stories.tsx (4)

4-24: Consistent Storybook setup matching LineChart stories pattern.

The meta configuration and sample data structure align well with the LineChart stories, maintaining consistency across the chart components.


91-107: Good demonstration of stacked bars feature.

The StackedBars story effectively showcases the stackId property for grouping bars into stacked visualizations.


109-125: Clear demonstration of rounded bar corners.

The RoundedBars story with barRadius: [4, 4, 0, 0] clearly shows how to customize bar corner rounding.


169-181: EmptyState story validates empty data handling.

Good coverage of the empty state scenario with data: [].

libs/react/ui/src/components/dashboard/components/charts/line-chart.tsx (5)

1-21: Clean imports for enhanced chart functionality.

The imports are well-organized, bringing in Card components for layout, EmptyState for no-data scenarios, and chart utilities for color/hover management.


25-47: Well-typed props interface with controlled API surface.

The Pick types for axis and grid props expose only the relevant configuration options, keeping the API clean. The hide property on LineChartLine enables selective series visibility.


62-72: Comprehensive empty state detection.

The logic correctly identifies empty scenarios: no data, no visible lines, or all-zero values. The all-zero check is a good UX decision since a chart with only zeros provides no meaningful visualization. Negative values are correctly handled.


127-157: Well-implemented hover interaction for line series.

The hover state management across both Line and activeDot ensures consistent interaction behavior. The strokeOpacity adjustment provides clear visual feedback for the hovered series.


169-183: Clean legend implementation with consistent coloring.

The legend correctly reuses getChartColor to ensure color consistency with the chart lines. The conditional rendering (!isEmpty && visibleLines.length > 0) is appropriate.

libs/react/ui/src/components/dashboard/components/charts/bar-chart.tsx (5)

1-21: Consistent imports matching LineChart structure.

The import organization mirrors the LineChart component, ensuring consistency across the chart suite.


25-49: Solid type definitions for BarChart configuration.

The BarChartBar interface properly extends BarProps while adding chart-specific properties. The stackId property enables stacked bar visualizations, and barRadius tuple type matches Recharts' corner radius specification.


66-76: Empty state detection consistent with LineChart.

The logic mirrors the LineChart implementation, ensuring consistent behavior across chart types. While there's some duplication, extracting this to a shared utility might be overkill for two components.


133-152: Clean Bar rendering with proper stacking and hover support.

The Bar components are rendered with consistent color resolution, hover opacity, and stacking via stackId. The barRadius and maxBarSize props provide visual customization.


155-178: Appropriate EmptyState and legend rendering.

The barChartBoxLine icon is contextually appropriate for the bar chart empty state. The legend implementation matches the LineChart pattern, maintaining consistency across the chart suite.

libs/react/ui/src/components/card/card.tsx (3)

1-19: LGTM! Solid foundation for the Card component.

The imports are appropriate, and the main Card component provides a well-structured container with sensible defaults (padding, border, flex layout). The type-safe props pattern and className merging with cn utility follow React best practices.


21-64: Excellent composable header components.

The CardHeader family demonstrates good design:

  • Proper type extensions (CardTitleProps extends ComponentProps<typeof Header> and CardDescriptionProps extends ComponentProps<typeof Text>) preserve full prop typing from the wrapped typography components.
  • Sensible defaults (variant='h3' for CardTitle, size='sm' for CardDescription) establish visual hierarchy.
  • Gap sizes create appropriate spacing (gap-4 within header vs gap-16 at Card level).
  • ml-auto on CardAction enables flexible right-aligned actions.

66-84: Well-designed content and footer sections.

CardContent's flex-1 appropriately fills remaining space in the flex column layout, and CardFooter provides sensible horizontal alignment with items-center. The consistent component pattern and prop handling make this family easy to compose.

@argos-ci
Copy link

argos-ci bot commented Dec 30, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ⚠️ Changes detected (Review) 5 changed, 26 added Dec 30, 2025, 4:18 PM

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

<span className="size-8 shrink-0 rounded-full" style={{backgroundColor: item.color}} />
{item.name && (
<span className="text-xs text-foreground-neutral-subtle">{item.name}</span>
<Text size="xs" className="text-foreground-neutral-subtle">
Copy link
Contributor

@noe-charmet noe-charmet Dec 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These Text elements should have the compact property to match the Figma design.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Text's compact props = true by default

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok my bad was not expecting this behavior

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't seem to find a clear part of the Figma design which would reference those components.

They most likely should exist, but it looks like we would need to discuss with the @y405 to check what such a component would entail.

Typically this screenshot of a full card in the Storybook

Image

However some cards seem to have a line for header/footer + title is different between the card with the table, the cards with KIP, and the card with a graph.

Image Image Image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@noe-charmet so what should I fix here? Card components are not available in the Design System, but we should have it to be a consistent wrapper component. The Charts and DataTable now are wrapped with Card components, however, since Modal had been made before we added Card, so it's been wrapped by its own Modal components, e.g Header, Content, Footer.

Copy link
Contributor

@noe-charmet noe-charmet Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this requires you to have a chat with Yael on how this should be consistent (or not).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I will connect with him on that. Meanwhile, is this PR good to merge or not? I need to release to continue working on the visibility PR using these components.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok this can be reworked in. a followup pr

@kylengn kylengn merged commit a18d6e7 into main Dec 31, 2025
5 checks passed
@kylengn kylengn deleted the feat/charts branch December 31, 2025 07:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants