Fix: Radio.Group cloneElement crashes on non-element children (#14407)

### What problem does this PR solve?

`Radio.Group` in `web/src/components/ui/radio.tsx` injects the parent's
`disabled` prop into each child via `React.cloneElement` with
`as React.ReactElement` and no validation.

This throws at runtime when a consumer passes strings, numbers, `null`,
`false`, or other non-element nodes, while the cast hides the unsafe
access from TypeScript.

Use `React.isValidElement<RadioProps>(child)` as a type guard before
calling `cloneElement`. Non-element children pass through unchanged,
and `child.props` access becomes type-checked without an `as` cast.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
很拉风的James
2026-05-11 09:54:42 +08:00
committed by GitHub
parent 6bfe0f9a10
commit 6cb4bc2947

View File

@@ -150,11 +150,12 @@ const Group = React.forwardRef<HTMLDivElement, RadioGroupProps>(
className,
)}
>
{React.Children.map(children, (child) =>
React.cloneElement(child as React.ReactElement, {
disabled: disabled || child?.props?.disabled,
}),
)}
{React.Children.map(children, (child) => {
if (!React.isValidElement<RadioProps>(child)) return child;
return React.cloneElement(child, {
disabled: disabled || child.props?.disabled,
});
})}
</div>
</RadioGroupContext.Provider>
);