[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:
@@ -5,7 +5,7 @@ const StyledSoonPill = styled(Pill)`
|
||||
margin-left: auto;
|
||||
`;
|
||||
|
||||
type ButtonSoonProps = {
|
||||
export type ButtonSoonProps = {
|
||||
label?: string;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
type LightIconButtonProps,
|
||||
} from '@ui/input/button/components/LightIconButton';
|
||||
|
||||
type ColorPickerButtonProps = Pick<ColorSampleProps, 'colorName'> &
|
||||
export type ColorPickerButtonProps = Pick<ColorSampleProps, 'colorName'> &
|
||||
Pick<LightIconButtonProps, 'onClick'> & {
|
||||
isSelected?: boolean;
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ import React, { type FunctionComponent } from 'react';
|
||||
|
||||
export type MainButtonVariant = 'primary' | 'secondary';
|
||||
|
||||
type Props = {
|
||||
export type Props = {
|
||||
title: string;
|
||||
fullWidth?: boolean;
|
||||
width?: number;
|
||||
@@ -102,7 +102,7 @@ const StyledButton = styled.button<
|
||||
}};
|
||||
`;
|
||||
|
||||
type MainButtonProps = Props & {
|
||||
export type MainButtonProps = Props & {
|
||||
Icon?: IconComponent | FunctionComponent<{ size: number }>;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ const StyledIconButton = styled.button<{ size: RoundedIconButtonSize }>`
|
||||
width: ${({ size }) => (size === 'small' ? '20px' : '24px')};
|
||||
`;
|
||||
|
||||
type RoundedIconButtonProps = {
|
||||
export type RoundedIconButtonProps = {
|
||||
Icon: IconComponent;
|
||||
size?: RoundedIconButtonSize;
|
||||
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { TabContent } from '@ui/input/button/components/TabButton/internals/comp
|
||||
import { type ReactElement } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
type TabButtonProps = {
|
||||
export type TabButtonProps = {
|
||||
id: string;
|
||||
active?: boolean;
|
||||
disabled?: boolean;
|
||||
|
||||
@@ -10,7 +10,7 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
type CodeEditorVariant = 'default' | 'with-header' | 'borderless';
|
||||
|
||||
type CodeEditorProps = Pick<
|
||||
export type CodeEditorProps = Pick<
|
||||
EditorProps,
|
||||
'value' | 'language' | 'onMount' | 'onValidate' | 'height' | 'options'
|
||||
> & {
|
||||
|
||||
@@ -23,7 +23,7 @@ const StyledRadioContainer = styled.div`
|
||||
top: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
type CardPickerProps = {
|
||||
export type CardPickerProps = {
|
||||
children: React.ReactNode;
|
||||
handleChange?: () => void;
|
||||
checked?: boolean;
|
||||
|
||||
@@ -24,7 +24,7 @@ export enum CheckboxAccent {
|
||||
Orange = 'orange',
|
||||
}
|
||||
|
||||
type CheckboxProps = {
|
||||
export type CheckboxProps = {
|
||||
checked: boolean;
|
||||
indeterminate?: boolean;
|
||||
hoverable?: boolean;
|
||||
@@ -38,7 +38,7 @@ type CheckboxProps = {
|
||||
accent?: CheckboxAccent;
|
||||
};
|
||||
|
||||
type InputProps = {
|
||||
export type InputProps = {
|
||||
checkboxSize: CheckboxSize;
|
||||
variant: CheckboxVariant;
|
||||
accent?: CheckboxAccent;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import IconListViewGripRaw from '@assets/misc/list-view-grip.svg?react';
|
||||
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
|
||||
|
||||
type IconListViewGripProps = Pick<IconComponentProps, 'size' | 'stroke'>;
|
||||
export type IconListViewGripProps = Pick<IconComponentProps, 'size' | 'stroke'>;
|
||||
|
||||
export const IconListViewGrip = (props: IconListViewGripProps) => {
|
||||
const width = props.size ?? 8;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
|
||||
|
||||
import { type RadioProps } from './Radio';
|
||||
|
||||
type RadioGroupProps = React.PropsWithChildren & {
|
||||
export type RadioGroupProps = React.PropsWithChildren & {
|
||||
value?: string;
|
||||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
onValueChange?: (value: string) => void;
|
||||
|
||||
@@ -22,6 +22,7 @@ export { Button } from './button/components/Button/Button';
|
||||
export { baseTransitionTiming } from './button/components/Button/constant';
|
||||
export type { ButtonGroupProps } from './button/components/ButtonGroup';
|
||||
export { ButtonGroup } from './button/components/ButtonGroup';
|
||||
export type { ColorPickerButtonProps } from './button/components/ColorPickerButton';
|
||||
export { ColorPickerButton } from './button/components/ColorPickerButton';
|
||||
export type {
|
||||
FloatingButtonSize,
|
||||
@@ -64,9 +65,16 @@ export type {
|
||||
export { LightIconButton } from './button/components/LightIconButton';
|
||||
export type { LightIconButtonGroupProps } from './button/components/LightIconButtonGroup';
|
||||
export { LightIconButtonGroup } from './button/components/LightIconButtonGroup';
|
||||
export type { MainButtonVariant } from './button/components/MainButton';
|
||||
export type {
|
||||
MainButtonVariant,
|
||||
Props,
|
||||
MainButtonProps,
|
||||
} from './button/components/MainButton';
|
||||
export { MainButton } from './button/components/MainButton';
|
||||
export type { RoundedIconButtonSize } from './button/components/RoundedIconButton';
|
||||
export type {
|
||||
RoundedIconButtonSize,
|
||||
RoundedIconButtonProps,
|
||||
} from './button/components/RoundedIconButton';
|
||||
export { RoundedIconButton } from './button/components/RoundedIconButton';
|
||||
export {
|
||||
StyledTabButton,
|
||||
@@ -75,7 +83,9 @@ export {
|
||||
} from './button/components/TabButton/internals/components/StyledTabBase';
|
||||
export type { TabContentProps } from './button/components/TabButton/internals/components/TabContent';
|
||||
export { TabContent } from './button/components/TabButton/internals/components/TabContent';
|
||||
export type { TabButtonProps } from './button/components/TabButton/TabButton';
|
||||
export { TabButton } from './button/components/TabButton/TabButton';
|
||||
export type { CodeEditorProps } from './code-editor/components/CodeEditor';
|
||||
export { CodeEditor } from './code-editor/components/CodeEditor';
|
||||
export type { CoreEditorHeaderProps } from './code-editor/components/CodeEditorHeader';
|
||||
export { CoreEditorHeader } from './code-editor/components/CodeEditorHeader';
|
||||
@@ -88,7 +98,9 @@ export type {
|
||||
export { ColorSchemeCard } from './color-scheme/components/ColorSchemeCard';
|
||||
export type { ColorSchemePickerProps } from './color-scheme/components/ColorSchemePicker';
|
||||
export { ColorSchemePicker } from './color-scheme/components/ColorSchemePicker';
|
||||
export type { CardPickerProps } from './components/CardPicker';
|
||||
export { CardPicker } from './components/CardPicker';
|
||||
export type { CheckboxProps, InputProps } from './components/Checkbox';
|
||||
export {
|
||||
CheckboxVariant,
|
||||
CheckboxShape,
|
||||
@@ -96,9 +108,11 @@ export {
|
||||
CheckboxAccent,
|
||||
Checkbox,
|
||||
} from './components/Checkbox';
|
||||
export type { IconListViewGripProps } from './components/IconListViewGrip';
|
||||
export { IconListViewGrip } from './components/IconListViewGrip';
|
||||
export type { RadioProps } from './components/Radio';
|
||||
export { RadioSize, LabelPosition, Radio } from './components/Radio';
|
||||
export type { RadioGroupProps } from './components/RadioGroup';
|
||||
export { RadioGroup } from './components/RadioGroup';
|
||||
export type { SearchInputProps } from './components/SearchInput';
|
||||
export { SearchInput } from './components/SearchInput';
|
||||
|
||||
Reference in New Issue
Block a user