Files
twenty/packages/twenty-sdk/scripts/remote-dom/twenty-ui-extractor/utils/is-react-component-export.ts
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

29 lines
696 B
TypeScript

import { type ExportSpecifier } from 'ts-morph';
import { isNonEmptyArray } from 'twenty-shared/utils';
import { typeSymbolMatchesAnyName } from './type-symbol-matches-any-name';
const REACT_RETURN_TYPE_NAMES = new Set([
'ReactNode',
'ReactElement',
'Element',
]);
export const isReactComponentExport = (
namedExport: ExportSpecifier,
): boolean => {
const exportType = namedExport.getNameNode().getType();
const callSignatures = exportType.getCallSignatures();
if (!isNonEmptyArray(callSignatures)) {
return false;
}
return callSignatures.some((signature) =>
typeSymbolMatchesAnyName(
signature.getReturnType(),
REACT_RETURN_TYPE_NAMES,
),
);
};