Skip to content

Radio group themes #1223

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

Merged
merged 8 commits into from
Jul 21, 2025
Merged

Radio group themes #1223

merged 8 commits into from
Jul 21, 2025

Conversation

GoldGroove06
Copy link
Collaborator

@GoldGroove06 GoldGroove06 commented Jul 18, 2025

Screen.Recording.2025-07-18.144530.mp4

Summary by CodeRabbit

  • New Features

    • Introduced new subcomponents for the radio group: Indicator and Label, now accessible for use in building custom radio group UIs.
  • Refactor

    • Simplified the radio group context and updated component props for greater clarity and flexibility, including new options for variant, size, and color.
  • Style

    • Enhanced radio group styling with modular classes, improved layout, and refined visual indicators for a more polished user experience.
  • Documentation

    • Updated story examples to reflect the new component structure and usage.

Copy link
Contributor

coderabbitai bot commented Jul 18, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

The RadioGroup UI component was refactored to introduce new subcomponents (Indicator and Label), simplify context usage, and update the root API with new props for variant, size, and color. The CSS was restructured with new class names and modular styles. Story and fragment implementations were updated to match the new structure.

Changes

File(s) Change Summary
RadioGroup.tsx, fragments/RadioGroupIndicator.tsx, fragments/RadioGroupLabel.tsx Added and exported new subcomponents: Indicator and Label for RadioGroup.
context/RadioGroupContext.tsx Simplified context, removing unused properties and renaming customRootClass to rootClass.
fragments/RadioGroupItem.tsx Refactored prop types for clarity; explicitly requires and forwards value prop.
fragments/RadioGroupRoot.tsx Updated props: removed defaultChecked/onChange, added variant, size, color; updated context usage.
stories/RadioGroup.stories.tsx Updated story to use new Label/Indicator structure and removed internal state logic.
.../RadioGroupPrimitiveRoot.tsx Added a trailing newline; no functional changes.
styles/themes/components/radio-group.scss Renamed/added CSS classes; modularized and enhanced visual styles for root, item, indicator, label.

Sequence Diagram(s)

sequenceDiagram
  participant ParentComponent
  participant RadioGroup.Root
  participant RadioGroup.Item
  participant RadioGroup.Indicator
  participant RadioGroup.Label

  ParentComponent->>RadioGroup.Root: Render with variant, size, color
  RadioGroup.Root->>RadioGroupContext: Provide rootClass
  loop For each option
    RadioGroup.Root->>RadioGroup.Label: Render label for item
    RadioGroup.Label->>RadioGroup.Item: Render radio item
    RadioGroup.Item->>RadioGroup.Indicator: Render indicator if selected
  end
Loading

Estimated code review effort

3 (90–240 minutes)

Possibly related PRs

  • Radio group themes #1223: The main PR and the retrieved PR make identical changes to the RadioGroup component and its fragments, including adding RadioGroupIndicator and RadioGroupLabel components, simplifying the RadioGroupContext, updating RadioGroupRoot props, and enhancing styling, indicating they are directly related.

Suggested reviewers

  • kotAPI

Poem

In the meadow, radios bloom anew,
With labels and indicators shining through.
Context trimmed, styles refined,
Variant, size, and color aligned.
A rabbit hops with CSS delight—
Modular radios, crisp and bright!
🐇🎨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-21T06_40_55_664Z-debug-0.log


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b8198f5 and 59d5ad4.

📒 Files selected for processing (1)
  • src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveRoot.tsx (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings

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.
    • @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 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.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

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

🔭 Outside diff range comments (1)
src/core/primitives/RadioGroup/RadioGroupPrimitive.stories.tsx (1)

15-26: Remove unused code and props

The RadioButton component has unused state, handler, and props that should be removed for cleanliness.

-const RadioButton = (args: RadioButtonProps) => {
+const RadioButton = () => {
     const options: Option[] = [
         { id: 'html', value: 'html', label: 'HTML' },
         { id: 'css', value: 'css', label: 'CSS' },
         { id: 'javascript', value: 'javascript', label: 'JavaScript' }
     ];

-    const [language, setLanguage] = useState<string>('css');
-
-    const handleChange = (item: string) => {
-        setLanguage(item);
-    };

Also update the render function:

-    render: (args: RadioButtonProps) => <RadioButton {...args}/>
+    render: () => <RadioButton />
🧹 Nitpick comments (4)
src/components/ui/RadioGroup/fragments/RadioGroupLabel.tsx (1)

14-14: Remove redundant rootClass in className computation.

The className computation includes both ${rootClass}-label and rootClass, which appears redundant. The rootClass alone doesn't seem necessary if you're already using ${rootClass}-label.

Consider this refactor:

-    return <Primitive.label {...props} className={clsx(`${rootClass}-label`, rootClass, className)} asChild={asChild}> {children} </Primitive.label>;
+    return <Primitive.label {...props} className={clsx(`${rootClass}-label`, className)} asChild={asChild}> {children} </Primitive.label>;
src/components/ui/RadioGroup/stories/RadioGroup.stories.tsx (1)

13-13: Consider adding a default selection to RadioGroup.Root

The previous implementation had a default selection (language state initialized to 'css'). Without defaultValue or value prop on RadioGroup.Root, no radio button will be selected by default.

-            <RadioGroup.Root >
+            <RadioGroup.Root defaultValue="css">
styles/themes/components/radio-group.scss (2)

1-8: Prefer relative units for top-level spacing to improve scalability

Hard-coded pixel values (margin-top: 20px;, gap: 32px) do not scale with the root font size and can look inconsistent under user zoom or large-text accessibility settings. Converting these to rem keeps spacing proportional across different environments.

-  margin-top: 20px;
-  gap: 32px;
+  margin-top: 1.25rem; /* 20px / 16 */
+  gap: 2rem;           /* 32px / 16 */

48-62: Redundant left margin & minor syntax / readability nits

  1. margin-left: 8px; is redundant because the flex container already sets gap: 8px;.
  2. For consistency with the rest of the file, add a space after the colon in width:max-content;.
-    margin-left: 8px;
-    width:max-content;
+    /* margin-left removed – gap already provides spacing */
+    width: max-content;
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0b43163 and b8198f5.

📒 Files selected for processing (17)
  • src/components/ui/RadioGroup/RadioGroup.tsx (2 hunks)
  • src/components/ui/RadioGroup/context/RadioGroupContext.tsx (1 hunks)
  • src/components/ui/RadioGroup/fragments/RadioGroupIndicator.tsx (1 hunks)
  • src/components/ui/RadioGroup/fragments/RadioGroupItem.tsx (1 hunks)
  • src/components/ui/RadioGroup/fragments/RadioGroupLabel.tsx (1 hunks)
  • src/components/ui/RadioGroup/fragments/RadioGroupRoot.tsx (1 hunks)
  • src/components/ui/RadioGroup/stories/RadioGroup.stories.tsx (2 hunks)
  • src/core/primitives/Primitive/index.tsx (1 hunks)
  • src/core/primitives/RadioGroup/RadioGroupPrimitive.stories.tsx (2 hunks)
  • src/core/primitives/RadioGroup/RadioGroupPrimitive.tsx (2 hunks)
  • src/core/primitives/RadioGroup/context/RadioGroupContext.tsx (0 hunks)
  • src/core/primitives/RadioGroup/context/RadioGroupPrimitiveItemContext.tsx (1 hunks)
  • src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveIndicator.tsx (1 hunks)
  • src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveItem.tsx (1 hunks)
  • src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveRoot.tsx (1 hunks)
  • src/core/primitives/RadioGroup/tests/RadioGroupPrimtive.test.tsx (1 hunks)
  • styles/themes/components/radio-group.scss (1 hunks)
💤 Files with no reviewable changes (1)
  • src/core/primitives/RadioGroup/context/RadioGroupContext.tsx
🧰 Additional context used
🧠 Learnings (13)
src/core/primitives/RadioGroup/RadioGroupPrimitive.tsx (1)
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
src/components/ui/RadioGroup/RadioGroup.tsx (1)
Learnt from: decipher-cs
PR: rad-ui/ui#417
File: src/components/ui/Dropdown/Dropdown.stories.tsx:43-50
Timestamp: 2024-12-12T08:34:33.079Z
Learning: Ensure to verify existing ARIA attributes in components before suggesting additions during code reviews, especially in the `Dropdown.Trigger` component in `src/components/ui/Dropdown/Dropdown.stories.tsx`.
src/core/primitives/Primitive/index.tsx (2)
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
Learnt from: krau5
PR: rad-ui/ui#609
File: src/components/ui/Text/Text.tsx:19-22
Timestamp: 2024-12-06T14:30:05.834Z
Learning: When the keys and values for the `as` prop are the same, we should define the type directly using string literals (e.g., `'div' | 'span' | 'p' | 'label'`) and eliminate extra mappings like `tagMap` to simplify the code.
src/components/ui/RadioGroup/context/RadioGroupContext.tsx (2)
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
Learnt from: kotAPI
PR: rad-ui/ui#1031
File: src/components/ui/Accordion/fragments/AccordionRoot.tsx:41-44
Timestamp: 2025-04-07T04:38:34.864Z
Learning: The Accordion component in rad-ui/ui supports both controlled and uncontrolled modes through props like `value`, `defaultValue`, and `onValueChange`. When implementing controlled components, remember to: 1) Initialize state from defaultValue, 2) Update internal state when value changes (controlled mode), 3) Call onValueChange callback, and 4) Prevent internal state updates when in controlled mode.
src/core/primitives/RadioGroup/context/RadioGroupPrimitiveItemContext.tsx (1)
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveIndicator.tsx (1)
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
src/components/ui/RadioGroup/fragments/RadioGroupItem.tsx (1)
Learnt from: kotAPI
PR: rad-ui/ui#1031
File: src/components/ui/Accordion/fragments/AccordionRoot.tsx:41-44
Timestamp: 2025-04-07T04:38:34.864Z
Learning: The Accordion component in rad-ui/ui supports both controlled and uncontrolled modes through props like `value`, `defaultValue`, and `onValueChange`. When implementing controlled components, remember to: 1) Initialize state from defaultValue, 2) Update internal state when value changes (controlled mode), 3) Call onValueChange callback, and 4) Prevent internal state updates when in controlled mode.
src/core/primitives/RadioGroup/RadioGroupPrimitive.stories.tsx (3)
Learnt from: decipher-cs
PR: rad-ui/ui#417
File: src/components/ui/Dropdown/Dropdown.stories.tsx:43-50
Timestamp: 2024-12-12T08:34:33.079Z
Learning: Ensure to verify existing ARIA attributes in components before suggesting additions during code reviews, especially in the `Dropdown.Trigger` component in `src/components/ui/Dropdown/Dropdown.stories.tsx`.
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
Learnt from: kotAPI
PR: rad-ui/ui#1031
File: src/components/ui/Accordion/fragments/AccordionRoot.tsx:41-44
Timestamp: 2025-04-07T04:38:34.864Z
Learning: The Accordion component in rad-ui/ui supports both controlled and uncontrolled modes through props like `value`, `defaultValue`, and `onValueChange`. When implementing controlled components, remember to: 1) Initialize state from defaultValue, 2) Update internal state when value changes (controlled mode), 3) Call onValueChange callback, and 4) Prevent internal state updates when in controlled mode.
src/components/ui/RadioGroup/stories/RadioGroup.stories.tsx (3)
Learnt from: decipher-cs
PR: rad-ui/ui#417
File: src/components/ui/Dropdown/Dropdown.stories.tsx:43-50
Timestamp: 2024-12-12T08:34:33.079Z
Learning: Ensure to verify existing ARIA attributes in components before suggesting additions during code reviews, especially in the `Dropdown.Trigger` component in `src/components/ui/Dropdown/Dropdown.stories.tsx`.
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
Learnt from: kotAPI
PR: rad-ui/ui#1031
File: src/components/ui/Accordion/fragments/AccordionRoot.tsx:41-44
Timestamp: 2025-04-07T04:38:34.864Z
Learning: The Accordion component in rad-ui/ui supports both controlled and uncontrolled modes through props like `value`, `defaultValue`, and `onValueChange`. When implementing controlled components, remember to: 1) Initialize state from defaultValue, 2) Update internal state when value changes (controlled mode), 3) Call onValueChange callback, and 4) Prevent internal state updates when in controlled mode.
src/core/primitives/RadioGroup/tests/RadioGroupPrimtive.test.tsx (2)
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
Learnt from: decipher-cs
PR: rad-ui/ui#417
File: src/components/ui/Dropdown/Dropdown.stories.tsx:43-50
Timestamp: 2024-12-12T08:34:33.079Z
Learning: Ensure to verify existing ARIA attributes in components before suggesting additions during code reviews, especially in the `Dropdown.Trigger` component in `src/components/ui/Dropdown/Dropdown.stories.tsx`.
src/components/ui/RadioGroup/fragments/RadioGroupRoot.tsx (4)
Learnt from: decipher-cs
PR: rad-ui/ui#417
File: src/components/ui/Dropdown/Dropdown.stories.tsx:43-50
Timestamp: 2024-12-12T08:34:33.079Z
Learning: Ensure to verify existing ARIA attributes in components before suggesting additions during code reviews, especially in the `Dropdown.Trigger` component in `src/components/ui/Dropdown/Dropdown.stories.tsx`.
Learnt from: kotAPI
PR: rad-ui/ui#1031
File: src/components/ui/Accordion/fragments/AccordionRoot.tsx:41-44
Timestamp: 2025-04-07T04:38:34.864Z
Learning: The Accordion component in rad-ui/ui supports both controlled and uncontrolled modes through props like `value`, `defaultValue`, and `onValueChange`. When implementing controlled components, remember to: 1) Initialize state from defaultValue, 2) Update internal state when value changes (controlled mode), 3) Call onValueChange callback, and 4) Prevent internal state updates when in controlled mode.
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
Learnt from: decipher-cs
PR: rad-ui/ui#417
File: src/components/ui/Dropdown/Dropdown.tsx:0-0
Timestamp: 2024-12-12T08:22:59.375Z
Learning: The `Dropdown.Trigger` component is customizable and needs to be used with `Dropdown.Root`.
src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveItem.tsx (2)
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
Learnt from: decipher-cs
PR: rad-ui/ui#417
File: src/components/ui/Dropdown/Dropdown.stories.tsx:43-50
Timestamp: 2024-12-12T08:34:33.079Z
Learning: Ensure to verify existing ARIA attributes in components before suggesting additions during code reviews, especially in the `Dropdown.Trigger` component in `src/components/ui/Dropdown/Dropdown.stories.tsx`.
src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveRoot.tsx (1)
Learnt from: kotAPI
PR: rad-ui/ui#576
File: src/core/primitives/Toggle/index.tsx:15-22
Timestamp: 2024-11-24T06:43:42.194Z
Learning: In the `TogglePrimitive` component (`src/core/primitives/Toggle/index.tsx`), when the component becomes controlled, it's acceptable to not sync the internal `isPressed` state with the external `pressed` prop.
🧬 Code Graph Analysis (2)
src/components/ui/RadioGroup/fragments/RadioGroupLabel.tsx (1)
src/components/ui/RadioGroup/context/RadioGroupContext.tsx (1)
  • RadioGroupContext (3-5)
src/components/ui/RadioGroup/fragments/RadioGroupItem.tsx (1)
src/components/ui/RadioGroup/context/RadioGroupContext.tsx (1)
  • RadioGroupContext (3-5)
⏰ 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: build
🔇 Additional comments (11)
src/core/primitives/Primitive/index.tsx (1)

4-4: LGTM! Clean extension of primitive support.

The addition of 'label' to the supported HTML elements is straightforward and enables the new RadioGroupLabel component functionality without breaking existing code.

src/core/primitives/RadioGroup/context/RadioGroupPrimitiveItemContext.tsx (1)

1-14: LGTM! Well-structured context implementation.

The context follows React best practices with proper typing, sensible defaults, and clean export pattern. The itemSelected boolean effectively manages selection state for radio group items.

src/core/primitives/RadioGroup/RadioGroupPrimitive.tsx (1)

5-5: LGTM! Consistent compound component pattern.

The addition of the Indicator fragment follows the established pattern of importing from fragments and attaching as a static property, maintaining consistency with the existing Root and Item components.

Also applies to: 19-19

src/components/ui/RadioGroup/RadioGroup.tsx (1)

4-5: LGTM! Proper extension of compound component API.

The addition of Indicator and Label fragments maintains the established compound component pattern, providing consistent API structure across the RadioGroup component hierarchy.

Also applies to: 21-22

src/components/ui/RadioGroup/context/RadioGroupContext.tsx (1)

3-5: Approve RadioGroupContext simplification

The new RadioGroupContext only provides a rootClass for styling, and all functional props (defaultChecked/defaultValue, onChange/onValueChange, etc.) continue to flow directly into RadioGroupPrimitive.Root via ...props. No UI components consume the removed context keys:

  • src/components/ui/RadioGroup/context/RadioGroupContext.tsx now exports { rootClass } only.
  • src/components/ui/RadioGroup/fragments/RadioGroupRoot.tsx spreads ...props into the primitive, so defaultChecked/onChange still work.
  • A global search shows no remaining references to defaultChecked, onChange or customRootClass in the UI RadioGroup context.

This refactor safely narrows the context API to styling concerns without breaking existing functionality.

src/components/ui/RadioGroup/fragments/RadioGroupIndicator.tsx (1)

11-18: LGTM! Clean implementation of the indicator component.

The component structure is well-designed with proper context usage and class name computation. The implementation follows React best practices.

src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveRoot.tsx (1)

35-46: LGTM! Excellent architectural improvement.

The restructuring to wrap components in a Primitive.div with proper ARIA attributes and the addition of a hidden radio input is a smart approach. This maintains native form behavior while allowing for more flexible UI composition with ARIA-enabled buttons.

src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveIndicator.tsx (1)

10-15: LGTM! Well-implemented conditional rendering component.

The conditional rendering logic based on itemSelected context is clean and efficient. The early return pattern and proper context usage make this component easy to understand and maintain.

src/components/ui/RadioGroup/fragments/RadioGroupItem.tsx (1)

6-14: LGTM! Excellent refactoring to explicit props.

The change from intersection types to explicit RadioGroupItemProps greatly improves code clarity and maintainability. The explicit forwarding of the value prop ensures proper integration with the primitive component.

src/core/primitives/RadioGroup/tests/RadioGroupPrimtive.test.tsx (1)

1-88: Test updates align perfectly with component refactoring!

The test suite has been properly updated to reflect the new component structure:

  • Correctly uses the new RadioGroupPrimitive.Root and .Item API
  • Appropriately queries button elements instead of inputs
  • Properly checks ARIA attributes instead of native properties
  • Maintains comprehensive coverage of all scenarios
src/core/primitives/RadioGroup/fragments/RadioGroupPrimitiveItem.tsx (1)

1-51: Excellent accessibility implementation!

The refactored component properly implements ARIA patterns for radio buttons:

  • Correct use of role="radio" on the button element
  • Appropriate ARIA attributes (aria-checked, aria-disabled, aria-required)
  • Proper keyboard navigation with both onClick and onFocus handlers
  • Clean context pattern for sharing selected state with child components

Comment on lines +9 to +31
.rad-ui-radio-group-item {
height: 24px;
width: 24px;
display: flex;
flex-direction: column;
gap: 24px;
color: var(--rad-ui-color-accent-900);

.rad-ui-radio-group-item{
display: flex;
align-items: center;
gap: 12px;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: var(--rad-ui-color-accent-100);
border: 2px solid var(--rad-ui-color-accent-400);
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
cursor: pointer;
transition: border-color 0.2s, box-shadow 0.2s, background 0.2s;
position: relative;

input{
width: 20px;
height: 20px;
position:relative;
display:inline-flex;
align-items:center;
justify-content:center;
flex-shrink:0;
outline:none;
margin:0;
border:none;
&:hover {
border-color: var(--rad-ui-color-accent-600);
background-color: var(--rad-ui-color-accent-200);
}

&::before{
content: '';
display: inline-block;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: var(--rad-ui-color-accent-900);
}
&:focus {
outline: 2px solid var(--rad-ui-color-accent-700);
outline-offset: 2px;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Swap :focus for :focus-visible to avoid distracting focus rings on mouse clicks

The current rule shows the outline on every click, which is unnecessary for mouse users and fails the WCAG “focus indication only on keyboard” best practice. Using :focus-visible retains the outline for keyboard navigation while keeping mouse interactions visually clean.

-    &:focus {
+    &:focus-visible {
       outline: 2px solid var(--rad-ui-color-accent-700);
       outline-offset: 2px;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.rad-ui-radio-group-item {
height: 24px;
width: 24px;
display: flex;
flex-direction: column;
gap: 24px;
color: var(--rad-ui-color-accent-900);
.rad-ui-radio-group-item{
display: flex;
align-items: center;
gap: 12px;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: var(--rad-ui-color-accent-100);
border: 2px solid var(--rad-ui-color-accent-400);
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
cursor: pointer;
transition: border-color 0.2s, box-shadow 0.2s, background 0.2s;
position: relative;
input{
width: 20px;
height: 20px;
position:relative;
display:inline-flex;
align-items:center;
justify-content:center;
flex-shrink:0;
outline:none;
margin:0;
border:none;
&:hover {
border-color: var(--rad-ui-color-accent-600);
background-color: var(--rad-ui-color-accent-200);
}
&::before{
content: '';
display: inline-block;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: var(--rad-ui-color-accent-900);
}
&:focus {
outline: 2px solid var(--rad-ui-color-accent-700);
outline-offset: 2px;
}
.rad-ui-radio-group-item {
height: 24px;
width: 24px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: var(--rad-ui-color-accent-100);
border: 2px solid var(--rad-ui-color-accent-400);
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
cursor: pointer;
transition: border-color 0.2s, box-shadow 0.2s, background 0.2s;
position: relative;
&:hover {
border-color: var(--rad-ui-color-accent-600);
background-color: var(--rad-ui-color-accent-200);
}
&:focus-visible {
outline: 2px solid var(--rad-ui-color-accent-700);
outline-offset: 2px;
}
}
🤖 Prompt for AI Agents
In styles/themes/components/radio-group.scss between lines 9 and 31, replace the
:focus pseudo-class with :focus-visible on the .rad-ui-radio-group-item selector
to ensure the focus outline only appears during keyboard navigation, preventing
distracting outlines on mouse clicks and improving accessibility.

@kotAPI kotAPI added the automerge A tag that tells kodiak bot to automerge PRs for us when tests and approval conditions are met label Jul 19, 2025
@kodiakhq kodiakhq bot removed the automerge A tag that tells kodiak bot to automerge PRs for us when tests and approval conditions are met label Jul 19, 2025
Copy link
Contributor

kodiakhq bot commented Jul 19, 2025

This PR currently has a merge conflict. Please resolve this and then re-add the automerge label.

@GoldGroove06 GoldGroove06 added the automerge A tag that tells kodiak bot to automerge PRs for us when tests and approval conditions are met label Jul 21, 2025
@kodiakhq kodiakhq bot merged commit c4d7bbc into main Jul 21, 2025
6 checks passed
@kodiakhq kodiakhq bot deleted the radio-group-themes branch July 21, 2025 06:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge A tag that tells kodiak bot to automerge PRs for us when tests and approval conditions are met
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants