[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
This commit is contained in:
Raphaël Bosi
2026-02-12 12:48:16 +01:00
committed by GitHub
parent c48ccbca99
commit cb7d0b83a8
133 changed files with 10556 additions and 984 deletions
@@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { type IconComponent } from '@ui/display';
type PillProps = {
export type PillProps = {
className?: string;
label?: string;
Icon?: IconComponent;
+2 -1
View File
@@ -16,6 +16,7 @@ export { ChipSize, ChipAccent, ChipVariant, Chip } from './chip/Chip';
export { LINK_CHIP_CLICK_OUTSIDE_ID } from './chip/constants/LinkChipClickOutsideId';
export type { LinkChipProps } from './chip/LinkChip';
export { LinkChip } from './chip/LinkChip';
export type { PillProps } from './Pill/Pill';
export { Pill } from './Pill/Pill';
export type { TagColor } from './tag/Tag';
export type { TagColor, TagProps } from './tag/Tag';
export { Tag } from './tag/Tag';
@@ -86,7 +86,7 @@ type TagWeight = 'regular' | 'medium';
type TagVariant = 'solid' | 'outline' | 'border';
export type TagColor = ThemeColor | 'transparent';
type TagProps = {
export type TagProps = {
className?: string;
color: TagColor;
text: string;