cb7d0b83a8
## 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
40 lines
961 B
TypeScript
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;
|
|
})}
|
|
</>
|
|
);
|
|
};
|