Skip to content

feat(ui): add ButtonLink and IconButton components#125

Merged
kylengn merged 3 commits intomainfrom
feat/add-buttons
Nov 13, 2025
Merged

feat(ui): add ButtonLink and IconButton components#125
kylengn merged 3 commits intomainfrom
feat/add-buttons

Conversation

@kylengn
Copy link
Contributor

@kylengn kylengn commented Nov 12, 2025

Summary by CodeRabbit

  • New Features

    • Added IconButton component with multiple size and style variants.
    • Added ButtonLink component for link-styled button interactions.
    • Added success variant for buttons with themed styling.
    • Added new icon options: add and chevron-right.
  • Style

    • Refined button sizing with explicit height adjustments.
    • Enhanced success button styling with hover, pressed, and focused states across light and dark themes.
    • Updated button shadow tokens for visual consistency.

@kylengn kylengn self-assigned this Nov 12, 2025
Copilot AI review requested due to automatic review settings November 12, 2025 11:15
@vercel
Copy link

vercel bot commented Nov 12, 2025

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

Project Deployment Preview Comments Updated (UTC)
react-ui Ready Ready Preview Comment Nov 13, 2025 2:32am

@coderabbitai
Copy link

coderabbitai bot commented Nov 12, 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.

Note

Other AI code review bot(s) detected

CodeRabbit 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.

Walkthrough

The pull request introduces two new button component variants (ButtonLink and IconButton), adds a "success" variant to the existing button component, expands the design token system with new success-related color and shadow tokens, adds comprehensive Storybook stories for all button variants, and extends the icon map with two new icon entries (addLine and chevronRight).

Changes

Cohort / File(s) Summary
Design Tokens
libs/react/ui/index.css
Added success button variant tokens for light and dark themes including hover, pressed, and default states; updated button hover states (white-6 to black-6); added success shadow tokens and focus variants; exposed new tokens in public mappings.
Button Components
libs/react/ui/src/components/button/button.tsx, libs/react/ui/src/components/button/button-link.tsx, libs/react/ui/src/components/button/icon-button.tsx
Enhanced button.tsx with new success variant and explicit height values in size definitions; introduced new ButtonLink component (anchor-based with optional iconLeft/iconRight); introduced new IconButton component with variant, size, radius, and muted configuration options.
Button Stories
libs/react/ui/src/components/button/button.stories.tsx, libs/react/ui/src/components/button/button-link.stories.tsx, libs/react/ui/src/components/button/icon-button.stories.tsx
Updated button.stories.tsx to include success variant and removed active state column; added comprehensive button-link.stories.tsx with Default, Variants, WithUnderline, and WithIcons stories; added icon-button.stories.tsx with Default, Variants, Muted, and Sizes stories.
Component Exports
libs/react/ui/src/components/button/index.ts
Added re-exports for ButtonLink and IconButton components to the barrel export.
Icon Map
libs/react/ui/src/components/icon/icon.tsx
Extended icon map with two new entries: addLine (RiAddLine) and chevronRight (RiArrowRightSLine).

Sequence Diagram

sequenceDiagram
    participant Consumer
    participant ButtonLink
    participant Slot
    participant Icon

    Consumer->>ButtonLink: Render with variant, size, iconLeft/iconRight props
    alt asChild is true
        ButtonLink->>Slot: Pass through via Slot
        Slot->>Consumer: Render custom element
    else asChild is false
        ButtonLink->>ButtonLink: Compute classNames via buttonLinkVariants
        alt iconLeft provided
            ButtonLink->>Icon: Render iconLeft
            Icon-->>ButtonLink: Icon element
        end
        ButtonLink->>ButtonLink: Render children
        alt iconRight provided
            ButtonLink->>Icon: Render iconRight
            Icon-->>ButtonLink: Icon element
        end
    end
    ButtonLink-->>Consumer: Render anchor with applied styles

    participant Consumer as Consumer2
    participant IconButton
    participant Slot as Slot2
    participant Icon as Icon2

    Consumer2->>IconButton: Render with variant, size, icon, muted props
    alt asChild is true
        IconButton->>Slot2: Pass through via Slot
        Slot2-->>Consumer2: Render custom element
    else asChild is false
        IconButton->>IconButton: Compute classNames via iconButtonVariants
        alt icon provided
            IconButton->>Icon2: Render Icon
            Icon2-->>IconButton: Icon element
        else icon not provided
            IconButton->>IconButton: Render children
        end
    end
    IconButton-->>Consumer2: Render button with applied styles
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • CSS token structure: Verify the success variant tokens align with design system patterns and that light/dark theme mappings are symmetric
  • ButtonLink and IconButton implementations: Confirm proper composition patterns, CVA variant definitions, and polymorphic rendering (asChild) behavior
  • Story configurations: Validate argTypes, controls, and render functions produce expected UI states (variants, sizes, states)
  • Icon additions: Ensure new icon imports and map entries are correct and non-conflicting

Possibly related PRs

Suggested reviewers

  • EnzalRad
  • dvxam
  • noe-charmet

Poem

🐰 Buttons bloom with success, links dance free—
IconButtons stand tall in varieties three!
With Remix icons and tokens so bright,
New composable wonders bring joy to the sight.
From addLine to chevronRight, the icons now cheer,
The button component garden is blooming this year! 🌸

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: introduction of two new button components (ButtonLink and IconButton) to the UI library.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

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.

Pull Request Overview

This PR adds two new button component variants (ButtonLink and IconButton) to enhance the UI library's button capabilities, along with supporting icon additions and styling updates.

  • Adds ButtonLink component for link-styled buttons with icon support
  • Adds IconButton component for icon-only button interactions
  • Introduces a new success button variant with complete theming

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
libs/react/ui/src/components/icon/icon.tsx Adds addLine and chevronRight icons to support new button components
libs/react/ui/src/components/button/index.ts Exports new ButtonLink and IconButton components
libs/react/ui/src/components/button/icon-button.tsx Implements new IconButton component with primary and transparent variants, multiple sizes, and radius options
libs/react/ui/src/components/button/icon-button.stories.tsx Adds Storybook documentation and visual testing for IconButton variants
libs/react/ui/src/components/button/button.tsx Adds success variant and standardizes button heights across all sizes
libs/react/ui/src/components/button/button.stories.tsx Updates button stories to include success variant and simplifies state documentation
libs/react/ui/src/components/button/button-link.tsx Implements new ButtonLink component with text-based link styling and optional icons
libs/react/ui/src/components/button/button-link.stories.tsx Adds Storybook documentation for ButtonLink variants and icon usage
libs/react/ui/index.css Adds CSS variables for success button variant and refines transparent button styling for light mode

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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: 1

🧹 Nitpick comments (1)
libs/react/ui/src/components/button/icon-button.tsx (1)

66-66: Consider coordinating icon size with button size.

The Icon component is rendered without an explicit size prop, which may result in icons that don't scale appropriately with the button's size variant (2xs through xl).

Consider mapping button sizes to icon sizes:

 export function IconButton({
   className,
   variant,
   size,
   radius,
   muted,
   asChild = false,
   children,
   icon,
   ...props
 }: ComponentProps<'button'> &
   VariantProps<typeof iconButtonVariants> & {
     asChild?: boolean;
     icon?: IconName;
   }) {
   const Comp = asChild ? Slot : 'button';
+  
+  // Map button size to icon size if needed
+  const iconSize = size === '2xs' || size === 'xs' ? 'sm' : 
+                   size === 'sm' || size === 'md' ? 'md' : 'lg';
 
   return (
     <Comp
       data-slot="icon-button"
       className={cn(iconButtonVariants({variant, size, radius, muted, className}))}
       {...props}
     >
-      {icon ? <Icon name={icon} /> : children}
+      {icon ? <Icon name={icon} size={iconSize} /> : children}
     </Comp>
   );
 }

Note: Adjust the size mapping based on your Icon component's size prop API.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fedb3d7 and 26f1f48.

📒 Files selected for processing (9)
  • libs/react/ui/index.css (7 hunks)
  • libs/react/ui/src/components/button/button-link.stories.tsx (1 hunks)
  • libs/react/ui/src/components/button/button-link.tsx (1 hunks)
  • libs/react/ui/src/components/button/button.stories.tsx (1 hunks)
  • libs/react/ui/src/components/button/button.tsx (1 hunks)
  • libs/react/ui/src/components/button/icon-button.stories.tsx (1 hunks)
  • libs/react/ui/src/components/button/icon-button.tsx (1 hunks)
  • libs/react/ui/src/components/button/index.ts (1 hunks)
  • libs/react/ui/src/components/icon/icon.tsx (2 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/button/button-link.stories.tsx
  • libs/react/ui/src/components/button/index.ts
  • libs/react/ui/src/components/button/icon-button.tsx
  • libs/react/ui/src/components/button/button-link.tsx
  • libs/react/ui/index.css
  • libs/react/ui/src/components/icon/icon.tsx
  • libs/react/ui/src/components/button/button.tsx
  • libs/react/ui/src/components/button/button.stories.tsx
  • libs/react/ui/src/components/button/icon-button.stories.tsx
🧬 Code graph analysis (4)
libs/react/ui/src/components/button/button-link.stories.tsx (1)
libs/react/ui/src/components/button/button-link.tsx (1)
  • ButtonLink (39-68)
libs/react/ui/src/components/button/icon-button.tsx (1)
libs/react/ui/src/components/icon/icon.tsx (2)
  • IconName (65-65)
  • Icon (71-74)
libs/react/ui/src/components/button/button-link.tsx (1)
libs/react/ui/src/components/icon/icon.tsx (2)
  • IconName (65-65)
  • Icon (71-74)
libs/react/ui/src/components/button/icon-button.stories.tsx (1)
libs/react/ui/src/components/button/icon-button.tsx (1)
  • IconButton (43-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Agent
🔇 Additional comments (24)
libs/react/ui/src/components/button/button-link.stories.tsx (4)

1-27: LGTM!

The Storybook meta configuration is well-structured with appropriate controls for all ButtonLink props. Default args are sensible.


32-51: LGTM!

The Default and Variants stories effectively demonstrate all variant options with clear visual organization.


53-70: LGTM!

The WithUnderline story provides comprehensive coverage of the underline prop across all variants.


72-86: LGTM!

The WithIcons story demonstrates all icon placement options (left, right, both) using the newly added icons effectively.

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

2-3: LGTM!

The new barrel exports correctly expose ButtonLink and IconButton components to the public API.

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

9-9: LGTM!

The addition of the 'success' variant to the story options correctly aligns with the new button variant, ensuring comprehensive Storybook coverage.

libs/react/ui/src/components/icon/icon.tsx (2)

3-4: LGTM!

The new icon imports follow the existing pattern for Remix Icon components.


61-62: LGTM!

The new icon mappings are properly configured and align with the naming conventions used throughout the icon map.

libs/react/ui/index.css (7)

201-211: LGTM!

The success button background tokens follow the established pattern from the danger variant, with appropriate green color progression (600→700→800 for default→hover→pressed).


327-334: LGTM!

The success button shadow tokens are properly defined, mirroring the danger button shadow structure with appropriate green color references.


406-416: LGTM!

Dark mode success button tokens are correctly configured with appropriate color values (800→700→600 for default→hover→pressed), following the established dark mode pattern.


530-536: LGTM!

Dark mode success button shadows are properly configured with appropriate color references for the dark theme.


751-761: LGTM!

The theme inline token mappings correctly expose the success button background colors for use in the Tailwind theme system.


902-903: LGTM!

The shadow token mappings correctly expose the success button shadows for use in the Tailwind theme system.


204-206: LGTM!

The transparent button hover/pressed states now correctly use black alpha values instead of white, which provides appropriate visual feedback on light backgrounds.

libs/react/ui/src/components/button/button.tsx (2)

18-19: LGTM!

The success variant is properly implemented with all necessary states (default, hover, pressed, focus, disabled) and follows the established pattern from the danger variant.


26-31: LGTM!

The explicit height values ensure consistent button dimensions across all sizes, which is important for a robust design system. The progression from h-20 to h-40 is logical and well-structured.

libs/react/ui/src/components/button/button-link.tsx (3)

1-5: LGTM!

All necessary imports are present and follow the established patterns used in other button components.


7-37: LGTM!

The buttonLinkVariants are well-structured with semantic variant names and proper use of design tokens. The underline implementation uses modern CSS with [text-underline-position:from-font] for proper text rendering.


39-68: LGTM!

The ButtonLink component is well-implemented following established patterns. The icon size of 16px is appropriate for link contexts, and the asChild pattern enables flexible composition.

libs/react/ui/src/components/button/icon-button.stories.tsx (3)

1-36: LGTM!

The Storybook meta configuration comprehensively covers all IconButton props with appropriate controls and default values.


43-121: LGTM!

The Variants story provides excellent comprehensive coverage of all size, radius, and variant combinations across different states, making it valuable for visual regression testing.


130-164: LGTM!

The Muted and Sizes stories provide focused demonstrations of specific features, complementing the comprehensive Variants story effectively.

libs/react/ui/src/components/button/icon-button.tsx (1)

18-23: The review comment is incorrect. The classes used in icon-button.tsx are not custom design tokens requiring verification.

The size classes (w-20, h-20, w-24, h-24, etc.) are standard Tailwind utilities, not custom tokens. The only custom radius token (rounded-6) is already properly defined in libs/react/ui/index.css as --radius-6: 6px within the @theme inline block. All other styling tokens (bg-background-button-*, text-tag-*, shadow-button-*) are comprehensively defined in the same CSS file. The codebase uses Tailwind v4 with its config-free @import "tailwindcss" approach, and all tokens are properly available.

Likely an incorrect or invalid review comment.

…con sizes and add aria-labels for accessibility
@noe-charmet
Copy link
Contributor

Need to add changeset 😉

@kylengn kylengn merged commit ec0b437 into main Nov 13, 2025
5 checks passed
@kylengn kylengn deleted the feat/add-buttons branch November 13, 2025 05:27
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