Skip to content

feat(checkbox): add state-specific class overrides and renderIcon + docs #413

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

SameerAther
Copy link

@SameerAther SameerAther commented Aug 5, 2025

This PR makes <Checkbox /> fully customizable without breaking existing usage:

  • Adds state-aware style props: checkedClassName, uncheckedClassName, iconCheckedClassName, iconUncheckedClassName, plus indicatorClassName.
  • Adds renderIcon to swap the default checkmark with any custom node.
  • Keeps sane defaults so <Checkbox checked onCheckedChange /> works as before.
  • Updates docs.

What’s changed

  • components/ui/checkbox.tsx

    • Implemented state-specific class props and renderIcon.

    • Preserved default theme behavior:

      • Unchecked: border-primary
      • Checked: bg-primary border-primary
      • Checked icon: text-primary-foreground
    • Export remains a forwardRef component (wrapped so JSX interop is stable).

  • Docs

    • Added new props table and customization examples.
    • Included renderIcon usage.
    • Reordered sections for faster scanning (Usage → Props → Customization → Examples).

API

New optional props:

  • checkedClassName?: string
  • uncheckedClassName?: string
  • indicatorClassName?: string
  • iconClassName?: string
  • iconCheckedClassName?: string
  • iconUncheckedClassName?: string
  • renderIcon?: (opts: { checked: boolean }) => React.ReactNode

Backward compatibility

  • ✅ No breaking changes.
  • Existing code using <Checkbox checked onCheckedChange /> continues to render with theme defaults.
  • If renderIcon is provided, iconClassName props are ignored by design (caller fully controls the icon).

Examples

<Checkbox
  checked={checked}
  onCheckedChange={setChecked}
  className="native:rounded-none web:rounded-none"
  checkedClassName="bg-emerald-600 border-emerald-600 native:bg-emerald-600 native:border-emerald-600"
  uncheckedClassName="border-zinc-400"
  iconCheckedClassName="text-white"
/>

Custom icon:

renderIcon={({ checked }) =>
  checked ? <Check size={14} className="text-white" /> : null
}


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Checkbox component now supports advanced customization options, including new props for styling checked/unchecked states and custom icon rendering.
  * Added support for passing a custom icon via a render function.

* **Documentation**
  * Checkbox documentation extensively expanded and restructured with detailed prop tables, usage examples, customization guides, and visual examples.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Copy link

vercel bot commented Aug 5, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-native-reusables ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 5, 2025 10:23am
rnr-showcase ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 5, 2025 10:23am

Copy link

coderabbitai bot commented Aug 5, 2025

Walkthrough

The Checkbox component was refactored to support ref forwarding, extended styling customization, and custom icon rendering through new props. The documentation was extensively rewritten to detail these new features, including expanded prop tables, usage examples, and customization guides. No changes were made to the component's external API beyond the new props.

Changes

Cohort / File(s) Change Summary
Documentation Overhaul
apps/docs/src/content/docs/components/checkbox.mdx
Expanded and restructured Checkbox documentation: improved formatting, added explicit React imports, simplified usage examples, replaced minimal prop list with a detailed table, explained theme defaults, introduced sections on style and icon customization, and provided new code examples and styled demos.
Component Refactor and Extensibility
packages/reusables/src/components/ui/checkbox.tsx
Refactored Checkbox to a forwardRef component, introduced CheckboxProps interface with new optional className and icon customization props, added renderIcon support, restructured class name logic for conditional styling, and updated export to use a ref-forwarding wrapper for enhanced extensibility and customization. No breaking changes to existing usage, only expanded capabilities.

Sequence Diagram(s)

sequenceDiagram
    participant ParentComponent
    participant Checkbox

    ParentComponent->>Checkbox: Render with props (checkedClassName, renderIcon, etc.)
    Checkbox->>Checkbox: Compute base and conditional classNames
    Checkbox->>Checkbox: Forward ref to root element
    Checkbox->>Checkbox: Determine checked state
    Checkbox->>Checkbox: Render indicator
    alt renderIcon provided
        Checkbox->>Checkbox: Call renderIcon(checked)
        Checkbox-->>ParentComponent: Render custom icon
    else
        Checkbox->>Checkbox: Render default Check icon with computed classes
        Checkbox-->>ParentComponent: Render default icon
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Poem

In the garden of code where checkboxes grow,
New props and icons now steal the show.
With docs refreshed and styles anew,
Custom checks hop in, both old and new.
Forwarded refs and options abound—
This rabbit’s checkbox leaps off the ground!
🐇✅

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
  • 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 explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this 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 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

@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 (1)
packages/reusables/src/components/ui/checkbox.tsx (1)

76-80: Consider simplifying the export pattern.

While the current export structure works, it adds unnecessary indirection. The more standard React pattern would be to export the forwardRef component directly:

-const ForwardedCheckbox = React.forwardRef<CheckboxPrimitive.RootRef, CheckboxProps>(CheckboxImpl);
-ForwardedCheckbox.displayName = 'Checkbox';
-export function Checkbox(props: CheckboxProps) {
-  return <ForwardedCheckbox {...props} />;
-}
+export const Checkbox = React.forwardRef<CheckboxPrimitive.RootRef, CheckboxProps>(CheckboxImpl);
+Checkbox.displayName = 'Checkbox';

This eliminates the wrapper function while maintaining the same functionality and ref forwarding capabilities.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 82620c0 and 628e4d8.

📒 Files selected for processing (2)
  • apps/docs/src/content/docs/components/checkbox.mdx (3 hunks)
  • packages/reusables/src/components/ui/checkbox.tsx (1 hunks)
🔇 Additional comments (9)
packages/reusables/src/components/ui/checkbox.tsx (4)

7-15: Excellent interface design with clear prop organization.

The CheckboxProps interface is well-structured with descriptive names and proper TypeScript typing. All new props are optional, ensuring backward compatibility, and the renderIcon function signature provides clear context with the { checked: boolean } parameter.


17-31: LGTM! Clean function signature with proper ref forwarding.

The function signature correctly implements the forwardRef pattern and destructures all props clearly. The explicit destructuring of the checked prop helps with readability in the conditional logic below.


32-55: Well-designed class calculation with proper precedence.

The class name calculation follows a logical hierarchy: base styles → defaults → conditional state classes → user overrides. This ensures the component works out-of-the-box while allowing full customization. The use of the cn utility properly handles conditional classes and the checked/unchecked state logic is correctly implemented.


57-74: Clean rendering logic with proper conditional icon handling.

The rendering implementation correctly handles both custom and default icons. The !!checked conversion ensures a proper boolean is passed to renderIcon, and the fallback to the default Check icon maintains existing behavior. Ref forwarding is properly implemented.

apps/docs/src/content/docs/components/checkbox.mdx (5)

14-17: Good documentation formatting improvements.

The formatting changes improve consistency and the addition of the React import in the usage example follows best practices. The simplified return statement makes the example more concise and easier to read.

Also applies to: 24-24, 42-42, 48-56


57-82: Comprehensive and accurate props documentation.

The props table thoroughly documents all available props with accurate default values and helpful notes. The theme defaults section clearly explains the component's default styling behavior, which will help developers understand how customization works.


83-115: Excellent customization examples with platform considerations.

The customization examples clearly demonstrate how to use the new state-specific className props. The inclusion of web-only data-* selector examples provides developers with alternatives, and the note about React Native limitations is valuable for cross-platform development.


116-148: Clear renderIcon examples with cross-platform awareness.

The renderIcon examples effectively demonstrate custom icon rendering with proper conditional logic for checked/unchecked states. The platform-specific strokeWidth consideration shows attention to cross-platform details, and the subtle dot example provides creative inspiration for developers.


150-176: Practical examples showcasing component flexibility.

The final examples section provides diverse visual variations that demonstrate the component's flexibility. The examples are concise yet illustrative, showing practical customization patterns that developers can adapt for their use cases.

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.

1 participant