Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: button-migration #69

Merged
merged 4 commits into from
Mar 12, 2025

Conversation

Harman-singh-waraich
Copy link
Contributor

@Harman-singh-waraich Harman-singh-waraich commented Mar 12, 2025

PR-Codex overview

This PR focuses on refactoring the Button component and its related files, updating event handlers, and improving accessibility. It also introduces new button variants and modifies styles for better usability.

Detailed summary

  • Removed base.tsx, primary.tsx, secondary.tsx, and tertiary.tsx.
  • Updated Button component's event handler from onClick to onPress.
  • Changed disabled prop to isDisabled in multiple components.
  • Introduced new components: ButtonIcon, ButtonText, KlerosSymbol.
  • Updated styles in global.css for button animations.
  • Enhanced Storybook stories for better button variant representation.
  • Refactored Button component to use AriaButton for accessibility.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Introduced new button components: ButtonIcon, ButtonText, and KlerosSymbol for enhanced functionality.
    • Added Storybook documentation for various button styles, including primary, secondary, and tertiary options.
  • Refactor

    • Replaced the custom styled button components with standard button implementations for improved accessibility and consistency.
    • Updated the button's disable property to isDisabled for uniform behavior across components.
    • Modified event handlers from onClick to onPress for better alignment with interaction models.
  • Style

    • Refined global styling with new CSS variables and optimized animations for smoother visual transitions.

Copy link
Contributor

coderabbitai bot commented Mar 12, 2025

Walkthrough

The changes update the button components and their styling across the project. In src/App.tsx, a styled component is replaced with a standard button applying a utility class. Several button usages now use isDisabled instead of disabled. New components—ButtonIcon, ButtonText, and KlerosSymbol—are added to assemble the new Button structure. Legacy styled button components (BaseButton, PrimaryButton, SecondaryButton, TertiaryButton) have been removed, and the main Button implementation in src/lib/button/index.tsx has been refactored to improve consistency. Global CSS receives new variables and animation definitions.

Changes

File(s) Change Summary
src/App.tsx Replaced the styled StyledButton with a standard Button that uses the utility class mt-16.
src/examples/buttons.tsx Renamed the Button prop from disabled to isDisabled for consistency.
src/lib/button/ButtonIcon.tsx, src/lib/button/ButtonText.tsx, src/lib/button/KlerosSymbol.tsx Introduced new components to handle button icons, text, and symbols with conditional styling based on state and variant.
src/lib/button/base.tsx, src/lib/button/primary.tsx, src/lib/button/secondary.tsx, src/lib/button/tertiary.tsx Removed legacy styled button components.
src/lib/button/index.tsx Refactored the main Button implementation to use react-aria-components, updated interfaces, replaced disabled with isDisabled, and consolidated visual styling logic.
src/lib/dropdown/cascader/selector.tsx Updated the Button prop from disabled to isDisabled without changing functionality.
src/styles/global.css Added new CSS variables and reorganized animation definitions (including fadeIn, breathe, and a new easing function).
.storybook/main.ts Introduced reactDocgenTypescriptOptions for improved TypeScript documentation control.
src/stories/button.stories.tsx Added a new Storybook configuration for the Button component with multiple story variations.

Possibly related PRs

  • feat: custom-counter-arrows-in-number-field #55: The changes in the main PR, which involve modifying the button component's event handler and styling, are related to the retrieved PR's updates on the Field component's button functionality and event handling, as both involve transitioning from onClick to onPress and modifying button properties.
  • feat: hover effects, abstract common styles, transition timings, brea… #58: The changes in the main PR, which involve modifying the button component's event handler and styling approach, are related to the retrieved PR's updates on button styling and hover effects, particularly the renaming of the disabled prop to isDisabled. Both PRs focus on enhancing button components, indicating a direct connection at the code level.
  • Feat/tooltip redesign and check animation #60: The changes in the main PR, which involve modifying the Button component's event handler and styling approach, are related to the changes in the retrieved PR that also update the Button component's event handler from onClick to onPress. Both PRs reflect a consistent shift in how button interactions are handled.

Suggested reviewers

  • alcercu

Poem

Oh, how I hop with glee in the code garden today,
New buttons dance in utility light and play.
Old styled friends have hopped away,
Making room for clear, fresh arrays.
From icons to text, every change fills me with cheer 🐰,
A bunny’s delight as the code becomes clear!


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (2)
src/lib/button/KlerosSymbol.tsx (1)

10-12: Consider simplifying variant logic

The current implementation works well, but you could make it more concise using a default value in the destructuring.

-const KlerosSymbol: React.FC<Pick<ButtonProps, "isDisabled" | "variant">> = ({
-  isDisabled,
-  variant,
-}) => {
-  const isPrimary = variant === "primary" || variant === undefined;
-  const isSecondary = variant === "secondary";
-  const isTertiary = variant === "tertiary";
+const KlerosSymbol: React.FC<Pick<ButtonProps, "isDisabled" | "variant">> = ({
+  isDisabled,
+  variant = "primary",
+}) => {
+  const isPrimary = variant === "primary";
+  const isSecondary = variant === "secondary";
+  const isTertiary = variant === "tertiary";
src/lib/button/ButtonIcon.tsx (1)

8-8: Consider handling all variants

Currently, you're only checking for the "secondary" variant. Consider also setting variables for "primary" and "tertiary" to make the code more consistent with KlerosSymbol.tsx.

const ButtonIcon: React.FC<
  Pick<ButtonProps, "Icon" | "icon" | "isDisabled" | "isLoading" | "variant">
> = ({ Icon, icon, isDisabled, isLoading, variant }) => {
+  const isPrimary = variant === "primary" || variant === undefined;
  const isSecondary = variant === "secondary";
+  const isTertiary = variant === "tertiary";
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c2211a3 and 0fb0ec1.

📒 Files selected for processing (12)
  • src/App.tsx (1 hunks)
  • src/examples/buttons.tsx (1 hunks)
  • src/lib/button/ButtonIcon.tsx (1 hunks)
  • src/lib/button/ButtonText.tsx (1 hunks)
  • src/lib/button/KlerosSymbol.tsx (1 hunks)
  • src/lib/button/base.tsx (0 hunks)
  • src/lib/button/index.tsx (2 hunks)
  • src/lib/button/primary.tsx (0 hunks)
  • src/lib/button/secondary.tsx (0 hunks)
  • src/lib/button/tertiary.tsx (0 hunks)
  • src/lib/dropdown/cascader/selector.tsx (1 hunks)
  • src/styles/global.css (2 hunks)
💤 Files with no reviewable changes (4)
  • src/lib/button/tertiary.tsx
  • src/lib/button/secondary.tsx
  • src/lib/button/primary.tsx
  • src/lib/button/base.tsx
🔇 Additional comments (21)
src/lib/dropdown/cascader/selector.tsx (1)

36-36: Consistent prop naming with isDisabled

Good change! Updating from disabled to isDisabled improves the API consistency across components and follows React's common pattern of using the "is" prefix for boolean props.

src/examples/buttons.tsx (2)

9-9: Property renamed to isDisabled

Good update to use isDisabled instead of disabled for consistency with the updated Button component API.


11-11: Property renamed to isDisabled

Consistent update to use isDisabled instead of disabled for the secondary button variant as well.

src/App.tsx (1)

117-120: Good migration to utility classes

Nice change from a styled component to using utility classes with className="mt-16". This approach promotes consistency with the design system and makes the styling more maintainable.

src/lib/button/ButtonText.tsx (1)

1-24: Well-structured ButtonText component with proper state handling

This new component is well-designed with:

  • Clear separation of concerns by handling only text rendering
  • Appropriate conditional styling based on button state (loading, disabled, variant)
  • Proper use of the className utility for composing classes
  • Good text styling with font weight, line height, and whitespace preservation

The implementation follows React best practices and will make the button structure more maintainable.

src/lib/button/KlerosSymbol.tsx (2)

6-9: Good use of TypeScript's Pick utility type

Using Pick<ButtonProps, "isDisabled" | "variant"> is an excellent way to ensure type safety while limiting the props this component needs to handle.


14-23: Well-structured conditional class names

The use of the cn utility function for combining class names is clean and readable. The animation class "animate-breathing" suggests this component handles loading states visually.

src/lib/button/ButtonIcon.tsx (2)

5-7: Good component prop definition

The component properly defines its props using TypeScript's Pick utility, ensuring it only receives the relevant props from ButtonProps.


10-23:

❓ Verification inconclusive

Verify the conditional rendering logic

The code uses the nullish coalescing operator (??) to conditionally render either icon or Icon. This approach assumes that icon is not explicitly set to null or undefined when you want to use Icon. Make sure this pattern works with your usage scenarios.


🏁 Script executed:

#!/bin/bash
# Check for places where both icon and Icon are provided to Button components
rg -p "Button.*icon.*Icon" --type=tsx

Length of output: 67


Verify Conditional Rendering in ButtonIcon Component

  • The code relies on the nullish coalescing operator (??) to determine whether to render icon or the fallback <Icon />. This assumes that when you want to fallback to <Icon />, the icon prop is explicitly null or undefined rather than any other falsy value.
  • Please ensure that in every usage scenario of the Button component, icon is either provided with a valid (non-null/undefined) value or omitted so that the fallback logic works as intended.
  • Note: The shell script originally used (rg -p "Button.*icon.*Icon" --type=tsx) returned an error due to an unrecognized file type. You might want to re-run your search using a glob pattern (e.g., rg "Button.*icon.*Icon" -g "*.tsx") to verify that no other components inadvertently pass both props.
src/styles/global.css (5)

36-36: Good addition of base radius variable

Adding --klerosUIComponentsBaseRadius as a CSS variable promotes consistency in UI components and makes it easier to update the border radius across the application.


158-158: Good utilization of CSS variables

Creating a semantic alias --radius-base that references the technical variable --klerosUIComponentsBaseRadius is a good practice. It creates an abstraction layer that makes the code more maintainable.


161-173: Well-structured fadeIn animation

The fadeIn animation is properly defined with keyframes and a custom property for easy reuse. The transition through 50% opacity provides a smoother animation effect.


175-189: Effective breathing animation for loading states

The breathe animation provides a good visual cue for loading states. The scale transition from 1 to 1.3 and back creates a subtle pulsing effect.


190-190: Good addition of easing function variable

The --ease-ease variable provides a reusable cubic-bezier curve, which ensures consistency in animations throughout the application.

src/lib/button/index.tsx (7)

3-9: Good component composition

Importing specialized sub-components (ButtonText, KlerosSymbol, ButtonIcon) promotes better separation of concerns and makes the codebase more maintainable.


11-15: Good interface definition for base button props

The BaseButtonProps interface clearly defines the common properties that all button variants share. Using optional properties with the ? syntax is appropriate here.


17-25: Good extension of AriaButtonProps

Extending AriaButtonProps ensures your buttons inherit all the accessibility features provided by react-aria-components. The use of Omit to avoid property conflicts is a good practice.


35-35: Naming convention improvement

Changing from disabled to isDisabled follows the common React boolean prop naming convention, which improves code readability and consistency.


38-40: Consistent variant handling

The approach to determining the button variant matches the pattern used in the KlerosSymbol component, which is good for consistency.


42-66: Good use of utility classes for styling

Using the cn utility function with Tailwind CSS classes creates a clean, maintainable approach to styling that's easier to update than styled-components.


69-71: Clean component composition

The Button component is now cleanly composed of specialized sub-components, each receiving only the props they need. This approach improves maintainability and readability.

@Harman-singh-waraich Harman-singh-waraich marked this pull request as ready for review March 12, 2025 15:21
Copy link
Contributor

@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 (3)
src/lib/button/index.tsx (3)

29-29: Optional text property for icon-only buttons.
text is mandatory, potentially disallowing icon-only usage. If an icon-only button variant is desired, consider making text? optional.


38-48: Destructure small for clarity.
You access props.small within the body but destructure isDisabled and others. Consistency improvements: explicitly destructure small along with the other props to improve readability and avoid extraneous property passing to <AriaButton>.

Possible fix:

-function Button({
-  text,
-  variant,
-  Icon,
-  icon,
-  onClick,
-  isLoading,
-  className,
-  isDisabled,
-  ...props
-}: Readonly<ButtonProps>): React.ReactElement {
-  const isPrimary = variant === "primary" || variant === undefined;
+function Button({
+  text,
+  variant,
+  Icon,
+  icon,
+  onClick,
+  isLoading,
+  className,
+  isDisabled,
+  small,
+  ...props
+}: Readonly<ButtonProps>): React.ReactElement {
+  const isPrimary = variant === "primary" || variant == null;

80-82: Loading and icon combination logic.
The button shows KlerosSymbol, ButtonIcon, and ButtonText together while loading. If the design calls for disabling the icon or text while loading, consider conditional hiding for clarity of user feedback.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 269e5d7 and 54cf95c.

📒 Files selected for processing (1)
  • src/lib/button/index.tsx (1 hunks)
🔇 Additional comments (3)
src/lib/button/index.tsx (3)

53-79:

❓ Verification inconclusive

Confirm Tailwind classes & theming approach.
The usage of "transition-[background]", custom durations & color tokens may depend on specialized Tailwind or PostCSS configuration. Ensure the classes are valid and consistent with the design system.


🏁 Script executed:

#!/bin/bash
# Description: Search for the relevant tailwind.config.js or postcss config to confirm custom classes.

fd "tailwind.config.js" --exec cat

Length of output: 34


Manual Verification of Tailwind/PostCSS Configuration

The automated search for a Tailwind configuration file (i.e. tailwind.config.js) did not return any files. This makes it unclear whether the custom Tailwind classes—such as "transition-[background]" and the custom duration token "duration-(--klerosUIComponentsTransitionSpeed)"—are defined or processed by a specialized PostCSS setup.

Next Steps:

  • Please manually verify if your project includes a Tailwind configuration (e.g. tailwind.config.js or tailwind.config.ts) or a PostCSS configuration (e.g. postcss.config.js) that defines these custom classes and tokens.
  • Confirm that the classes are valid within your design system guidelines.

11-24:

❓ Verification inconclusive

Documentation vs. defaults mismatch.
While the doc comments declare default values (variant="primary", small=false, isLoading=false), there is no explicit assignment in the interface or the component. If consumers omit these props, the code logic must set them internally. Confirm that all defaults are honored at runtime.


🏁 Script executed:

#!/bin/bash
# Description: Grep for usages of `Button` to ensure default props are handled or validated.

rg -A 3 "Button\s*\("

Length of output: 168


Attention: Verify Runtime Default Prop Handling for Button Component

The documented default values for variant ("primary"), small (false), and isLoading (false) aren’t clearly assigned in the Button function. The grep output shows that the props are simply destructured (e.g., function Button({ text, variant, Icon, … })) with no default assignment at the parameter level. Please confirm that default values are properly applied via internal logic (or elsewhere) at runtime. If not, consider explicitly assigning default values (e.g., using destructuring defaults) to ensure consistency with the documentation.

  • Location to review: src/lib/button/index.tsx (the Button function parameters)
  • Action: Verify that the runtime assigns variant: "primary", small: false, and isLoading: false when these props are omitted.

2-3:

❓ Verification inconclusive

Consider verifying the utility import path.
Please ensure "../../utils" accurately points to the cn function. Misconfigured or missing utilities often lead to runtime errors.


🏁 Script executed:

#!/bin/bash
# Description: Validate that the `cn` function is indeed located in the resolved path.

fd "utils" --exec rg -A 5 "export function cn"

Length of output: 46


Below is a new shell script that digs deeper into the src/utils directory (which is what "../../utils" resolves to from src/lib/button/index.tsx) to search for an export of the cn function. This should help determine whether the import path is correct or if manual verification is needed:

#!/bin/bash
# Validate the presence of an export for the 'cn' function in the src/utils directory.
echo "Listing all files in src/utils:"
find src/utils -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \)

echo -e "\nSearching for the export of 'cn'..."
rg -n "export[[:space:]]+(function|const|let|var)[[:space:]]+cn" src/utils

Action Required:

  • Run the above script to see if any file in src/utils exports the cn function.
  • If the script still produces no output, please perform manual verification to confirm that cn is indeed available at the resolved path "../../utils" (i.e. in src/utils).

Copy link
Contributor

@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: 0

🧹 Nitpick comments (2)
src/lib/button/index.tsx (1)

51-77: Well-structured dynamic class composition

The use of the cn utility for class composition is excellent, creating a clean, maintainable approach to styling. The conditional classes based on button state provide consistent visual feedback.

One minor optimization suggestion:

-      {...{ variant, isLoading, isDisabled, ...props }}
+      {...props}

Since variant, isLoading, and isDisabled are already destructured from props, no need to pass them again.

src/lib/form/datepicker/dropdown.tsx (1)

88-88: Updated event handler for compatibility with AriaButton

The change from onClick to onPress is appropriate and consistent with the migration to AriaButton from React Aria Components.

A minor syntax optimization:

-      <Button small variant={"primary"} text={"Select"} onPress={onSelect} />
+      <Button small variant="primary" text="Select" onPress={onSelect} />
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 54cf95c and cff2b83.

📒 Files selected for processing (4)
  • src/App.tsx (1 hunks)
  • src/lib/button/index.tsx (1 hunks)
  • src/lib/dropdown/cascader/selector.tsx (1 hunks)
  • src/lib/form/datepicker/dropdown.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/dropdown/cascader/selector.tsx
  • src/App.tsx
🔇 Additional comments (6)
src/lib/button/index.tsx (6)

2-9: Great use of React Aria Components for enhanced accessibility!

The migration to AriaButton from React Aria Components is an excellent choice for improving accessibility. The imports of the new button subcomponents (ButtonText, KlerosSymbol, and ButtonIcon) establish a clean composition pattern.


11-24: Well-documented interface with appropriate defaults

The BaseButtonProps interface is well structured with JSDoc comments providing clear descriptions and default values. The naming convention using isLoading instead of loading follows React's boolean prop naming convention for better readability.


26-28: Unused property omission.

Omit<BaseButtonProps, "$loading"> is excluding a non-existent property $loading. This might be a vestige of a previous implementation.

Consider removing the $loading omission:

-export interface ButtonProps
-  extends AriaButtonProps,
-    Omit<BaseButtonProps, "$loading"> {
+export interface ButtonProps
+  extends AriaButtonProps,
+    BaseButtonProps {

30-35: Improved props documentation and flexibility

Good addition of JSDoc comments for the icon props and the optional className for better styling flexibility.


37-50: Clean component signature with proper TypeScript typing

The function signature uses Readonly<ButtonProps> for immutability and includes clear variant determination logic. Renaming disabled to isDisabled is consistent with React boolean prop naming conventions.


78-81: Excellent component composition pattern

Using specialized sub-components (KlerosSymbol, ButtonIcon, ButtonText) creates a maintainable and clean button implementation. Passing the appropriate props to each component ensures consistent styling and behavior.

Copy link
Contributor

@alcercu alcercu left a comment

Choose a reason for hiding this comment

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

lgtm

@alcercu alcercu merged commit 66a0326 into feat/add-accordion-stories Mar 12, 2025
3 checks passed
This was referenced Mar 13, 2025
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