Files
twenty/packages/twenty-ui/src/input/components/RadioGroup.tsx
T
Raphaël Bosi cb7d0b83a8 [FRONT COMPONENTS] Twenty UI elements generation (#17866)
## PR description

This PR:
- Creates a TypeScript-based extractor that discovers all exported
twenty-ui components by scanning barrel files, extracting
props/slots/events via ts-morph type analysis, and generating the remote
DOM bindings automatically.

- Adds a new ESLint rule which enforces all *Props types in twenty-ui
components to be exported, which is required for the extractor to
discover component prop types. Existing twenty-ui components are updated
to comply with this rule.

- Extends the remote DOM generation to support slots, per-component
events, forwardRef wrappers, and richer property types (array, object,
function)

## Edge cases to fix in another PR

- Icons cannot be rendered inside buttons
- IconButtons throw an error when mounted
- MenuItems are not displayed correctly
- MenuItemNavigate throws on click

## Video Demo


https://github.com/user-attachments/assets/c2ed67cf-6a15-4896-9fec-e83fac0e862b
2026-02-12 12:48:16 +01:00

40 lines
961 B
TypeScript

import React from 'react';
import { useTheme } from '@emotion/react';
import { type RadioProps } from './Radio';
export type RadioGroupProps = React.PropsWithChildren & {
value?: string;
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
onValueChange?: (value: string) => void;
};
export const RadioGroup = ({
value,
onChange,
onValueChange,
children,
}: RadioGroupProps) => {
const theme = useTheme();
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange?.(event);
onValueChange?.(event.target.value);
};
return (
<>
{React.Children.map(children, (child) => {
if (React.isValidElement<RadioProps>(child)) {
return React.cloneElement(child, {
style: { marginBottom: theme.spacing(2) },
checked: child.props.value === value,
onChange: handleChange,
});
}
return child;
})}
</>
);
};