Revert export twenty UI (#17929)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Charles Bochet
2026-02-13 17:55:04 +01:00
committed by GitHub
parent c173f01601
commit a95a286c59
121 changed files with 386 additions and 10004 deletions
-5
View File
@@ -6,10 +6,6 @@ import {
rule as effectComponents,
RULE_NAME as effectComponentsName,
} from './rules/effect-components';
import {
rule as exportComponentProps,
RULE_NAME as exportComponentPropsName,
} from './rules/export-component-props';
import {
rule as explicitBooleanPredicatesInIf,
RULE_NAME as explicitBooleanPredicatesInIfName,
@@ -99,7 +95,6 @@ module.exports = {
rules: {
[componentPropsNamingName]: componentPropsNaming,
[effectComponentsName]: effectComponents,
[exportComponentPropsName]: exportComponentProps,
[matchingStateVariableName]: matchingStateVariable,
[noHardcodedColorsName]: noHardcodedColors,
[noStateUserefName]: noStateUseref,
@@ -1,119 +0,0 @@
/**
* @jest-environment node
*/
import { RuleTester } from 'eslint';
import { rule, RULE_NAME } from './export-component-props';
const typescriptParser = require('@typescript-eslint/parser');
const ruleTester = new RuleTester({
languageOptions: {
parser: typescriptParser,
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
});
ruleTester.run(RULE_NAME, rule as any, {
valid: [
{
name: 'Props type is already exported',
code: `
export type MyComponentProps = { label: string };
`,
},
{
name: 'Props interface is already exported',
code: `
export interface MyComponentProps { label: string }
`,
},
{
name: 'Type that doesn\'t end with Props is ignored',
code: `
type MyComponentOptions = { flag: boolean };
`,
},
{
name: 'Interface that doesn\'t end with Props is ignored',
code: `
interface MyComponentConfig { flag: boolean }
`,
},
{
name: 'Props re-exported via export { FooProps } is treated as exported',
code: `
type MyComponentProps = { label: string };
export { MyComponentProps };
`,
},
{
name: 'Non-Props type is not required to be exported',
code: `
type InternalState = { count: number };
`,
},
],
invalid: [
{
name: 'Unexported Props type alias',
code: `
type MyComponentProps = { label: string };
`,
errors: [{ messageId: 'mustExportProps' }],
output: `
export type MyComponentProps = { label: string };
`,
},
{
name: 'Unexported Props interface',
code: `
interface MyComponentProps { label: string }
`,
errors: [{ messageId: 'mustExportProps' }],
output: `
export interface MyComponentProps { label: string }
`,
},
{
name: 'Unexported Props type used in a component',
code: `
type MyComponentProps = { label: string };
export const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
`,
errors: [{ messageId: 'mustExportProps' }],
output: `
export type MyComponentProps = { label: string };
export const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
`,
},
{
name: 'Unexported Props type with non-exported component',
code: `
type MyComponentProps = { label: string };
const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
`,
errors: [{ messageId: 'mustExportProps' }],
output: `
export type MyComponentProps = { label: string };
const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
`,
},
{
name: 'Unexported Props type defined after the component',
code: `
export const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
type MyComponentProps = { label: string };
`,
errors: [{ messageId: 'mustExportProps' }],
output: `
export const MyComponent = ({ label }: MyComponentProps) => <div>{label}</div>;
export type MyComponentProps = { label: string };
`,
},
],
});
@@ -1,99 +0,0 @@
import { ESLintUtils, TSESTree } from '@typescript-eslint/utils';
import { isIdentifier } from '@typescript-eslint/utils/ast-utils';
export const RULE_NAME = 'export-component-props';
// NOTE: The rule will be available in ESLint configs as "@nx/workspace-export-component-props"
export const rule = ESLintUtils.RuleCreator(() => __filename)({
name: RULE_NAME,
meta: {
type: 'problem',
docs: {
description:
'Ensure types/interfaces ending with "Props" are exported',
},
fixable: 'code',
schema: [],
messages: {
mustExportProps:
"Props type '{{ typeName }}' must be exported.",
},
},
defaultOptions: [],
create: (context) => {
const reExportedNames = new Set<string>();
const unexportedPropsNodes = new Map<
string,
| TSESTree.TSTypeAliasDeclaration
| TSESTree.TSInterfaceDeclaration
>();
const collectUnexportedProps = (
node:
| TSESTree.TSTypeAliasDeclaration
| TSESTree.TSInterfaceDeclaration,
) => {
const typeName = node.id.name;
if (!typeName.endsWith('Props')) {
return;
}
const isExported =
node.parent?.type ===
TSESTree.AST_NODE_TYPES.ExportNamedDeclaration;
if (!isExported) {
unexportedPropsNodes.set(typeName, node);
}
};
return {
TSTypeAliasDeclaration: collectUnexportedProps,
TSInterfaceDeclaration: collectUnexportedProps,
ExportNamedDeclaration: (
node: TSESTree.ExportNamedDeclaration,
) => {
for (const specifier of node.specifiers) {
if (
specifier.type ===
TSESTree.AST_NODE_TYPES.ExportSpecifier &&
isIdentifier(specifier.local)
) {
const name = specifier.local.name;
if (name.endsWith('Props')) {
reExportedNames.add(name);
}
}
}
},
'Program:exit': () => {
for (const [typeName, node] of unexportedPropsNodes) {
if (reExportedNames.has(typeName)) {
continue;
}
context.report({
node: node.id,
messageId: 'mustExportProps',
data: { typeName },
fix: (fixer) => {
const sourceCode = context.sourceCode;
const firstToken = sourceCode.getFirstToken(node);
const target = firstToken ?? node;
if (firstToken?.value === 'export') {
return null;
}
return fixer.insertTextBefore(target, 'export ');
},
});
}
},
};
},
});
+7 -1
View File
@@ -11,12 +11,18 @@ const dirname =
const sdkRoot = path.resolve(dirname, '..');
const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
stories: [
'../src/front-component-renderer/**/*.stories.@(js|jsx|ts|tsx)',
],
addons: ['@storybook/addon-vitest'],
framework: '@storybook/react-vite',
refs: {
'@chakra-ui/react': { disable: true },
},
staticDirs: [
{
from: '../src/front-component-renderer/__stories__/example-sources-built',
+1 -1
View File
@@ -171,7 +171,7 @@
"storybook:serve:dev": {
"executor": "nx:run-commands",
"options": {
"command": "echo 'storybook:serve:dev is disabled for twenty-sdk, use storybook:serve:static instead'"
"port": 6008
}
},
"storybook:serve:static": {
@@ -18,7 +18,6 @@ import {
HtmlElementConfigArrayZ,
OUTPUT_FILES,
} from './generators';
import { extractAllComponentsFromTwentyUi } from './twenty-ui-extractor';
import {
logCount,
logDetail,
@@ -77,25 +76,6 @@ const getHtmlElementSchemas = (): ComponentSchema[] => {
}));
};
const getUiComponentSchemas = (): ComponentSchema[] => {
const discoveredComponents = extractAllComponentsFromTwentyUi();
return discoveredComponents.map((component) => ({
name: component.name,
tagName: component.name,
customElementName: component.tag,
properties: component.properties,
slots: component.slots,
events: component.events,
isHtmlElement: false,
htmlTag: undefined,
componentImport: component.componentImport,
componentPath: component.componentPath,
propsTypeName: component.propsTypeName,
supportsRefForwarding: component.supportsRefForwarding,
}));
};
const createProject = (): Project => {
return new Project({
manipulationSettings: {
@@ -139,11 +119,9 @@ const main = (): void => {
logTitle('Remote DOM Elements Generator');
let htmlElements: ComponentSchema[];
let uiComponents: ComponentSchema[];
try {
htmlElements = getHtmlElementSchemas();
uiComponents = getUiComponentSchemas();
} catch (error) {
logError('Validation failed:', error);
process.exit(1);
@@ -158,13 +136,7 @@ const main = (): void => {
);
logDetail(`Events: ${COMMON_HTML_EVENTS.length} common events per element`);
logEmpty();
logCount('UI Components', uiComponents.length, 'component', 'components');
logDetail(
`Tags: ${uiComponents.map((component) => component.customElementName).join(', ')}`,
);
const allComponents = [...htmlElements, ...uiComponents];
const allComponents = [...htmlElements];
ensureDirectoriesExist();
@@ -1,7 +1,6 @@
import type { Project, SourceFile } from 'ts-morph';
import { EVENT_TO_REACT } from '@/sdk/front-component-api/constants/EventToReact';
import { isDefined, isNonEmptyArray } from 'twenty-shared/utils';
import { isDefined } from 'twenty-shared/utils';
import { CUSTOM_ELEMENT_NAMES } from './constants';
import { type ComponentSchema } from './schemas';
import { addFileHeader, addStatement } from './utils';
@@ -99,7 +98,7 @@ const wrapEventHandler = (handler: (detail: SerializedEventData) => void) => {
};
};
const filterHtmlProps = <T extends object>(props: T): T => {
const filterProps = <T extends object>(props: T): T => {
const filtered: Record<string, unknown> = {};
for (const [key, value] of Object.entries(props)) {
if (INTERNAL_PROPS.has(key) || value === undefined) continue;
@@ -116,22 +115,6 @@ const filterHtmlProps = <T extends object>(props: T): T => {
}
}
return filtered as T;
};
const filterUiProps = <T extends object>(props: T, eventPropNames?: Set<string>): T => {
const filtered: Record<string, unknown> = {};
for (const [key, value] of Object.entries(props)) {
if (INTERNAL_PROPS.has(key) || value === undefined) continue;
if (key === 'style') {
filtered.style = parseStyle(value as string | undefined);
} else if (eventPropNames?.has(key) && typeof value === 'function') {
filtered[key] = wrapEventHandler(value as (detail: SerializedEventData) => void);
} else {
filtered[key] = value;
}
}
return filtered as T;
};`;
};
@@ -153,47 +136,24 @@ const VOID_ELEMENTS = new Set([
'wbr',
]);
const generateHtmlWrapperComponent = (component: ComponentSchema): string => {
const generateWrapperComponent = (component: ComponentSchema): string => {
const isVoidElement = VOID_ELEMENTS.has(component.htmlTag ?? '');
if (isVoidElement) {
return `const ${component.name}Wrapper = React.forwardRef<HTMLElement, { children?: React.ReactNode } & Record<string, unknown>>(({ children: _children, ...props }, ref) => {
return React.createElement('${component.htmlTag}', { ...filterHtmlProps(props), ref });
});`;
}
return `const ${component.name}Wrapper = React.forwardRef<HTMLElement, { children?: React.ReactNode } & Record<string, unknown>>(({ children, ...props }, ref) => {
return React.createElement('${component.htmlTag}', { ...filterHtmlProps(props), ref }, children);
});`;
};
const generateUiWrapperComponent = (component: ComponentSchema): string => {
const propsType = isDefined(component.propsTypeName)
? `${component.propsTypeName} & { children?: React.ReactNode }`
: '{ children?: React.ReactNode } & Record<string, unknown>';
const hasEvents = isNonEmptyArray(component.events);
const filterCall = hasEvents
? `filterUiProps(props, new Set([${component.events.map((event) => `'${EVENT_TO_REACT[event]}'`).join(', ')}]))`
: 'filterUiProps(props)';
if (component.supportsRefForwarding) {
return `const ${component.name}Wrapper = React.forwardRef<unknown, ${propsType}>((props, ref) => {
return React.createElement(${component.componentImport} as React.ElementType, { ...${filterCall}, ref });
});`;
}
return `const ${component.name}Wrapper = (props: ${propsType}) => {
return React.createElement(${component.componentImport}, ${filterCall});
return `const ${component.name}Wrapper = ({ children: _children, ...props }: { children?: React.ReactNode } & Record<string, unknown>) => {
return React.createElement('${component.htmlTag}', filterProps(props));
};`;
};
const generateWrapperComponent = (component: ComponentSchema): string => {
if (component.isHtmlElement) {
return generateHtmlWrapperComponent(component);
}
return generateUiWrapperComponent(component);
if (component.isHtmlElement) {
return `const ${component.name}Wrapper = ({ children, ...props }: { children?: React.ReactNode } & Record<string, unknown>) => {
return React.createElement('${component.htmlTag}', filterProps(props), children);
};`;
}
return `const ${component.name}Wrapper = ({ children, ...props }: { children?: React.ReactNode } & Record<string, unknown>) => {
return React.createElement(${component.componentImport}, filterProps(props), children);
};`;
};
const generateRegistryMap = (components: ComponentSchema[]): string => {
@@ -214,45 +174,6 @@ ${entries}
]);`;
};
type ImportGroup = {
namedImports: string[];
typeImports: string[];
};
const groupImportsByPath = (
components: ComponentSchema[],
): Map<string, ImportGroup> => {
const importsByPath = new Map<string, ImportGroup>();
for (const component of components) {
if (
!component.isHtmlElement &&
isDefined(component.componentPath) &&
isDefined(component.componentImport)
) {
const existing = importsByPath.get(component.componentPath) ?? {
namedImports: [],
typeImports: [],
};
if (!existing.namedImports.includes(component.componentImport)) {
existing.namedImports.push(component.componentImport);
}
if (
isDefined(component.propsTypeName) &&
!existing.typeImports.includes(component.propsTypeName)
) {
existing.typeImports.push(component.propsTypeName);
}
importsByPath.set(component.componentPath, existing);
}
}
return importsByPath;
};
export const generateHostRegistry = (
project: Project,
components: ComponentSchema[],
@@ -279,21 +200,17 @@ export const generateHostRegistry = (
namedImports: [{ name: 'SerializedEventData', isTypeOnly: true }],
});
const uiImports = groupImportsByPath(components);
for (const [modulePath, importGroup] of uiImports) {
const allImports = [
...importGroup.namedImports,
...importGroup.typeImports.map((typeName) => ({
name: typeName,
isTypeOnly: true,
})),
];
sourceFile.addImportDeclaration({
moduleSpecifier: modulePath,
namedImports: allImports,
});
for (const component of components) {
if (
!component.isHtmlElement &&
isDefined(component.componentPath) &&
isDefined(component.componentImport)
) {
sourceFile.addImportDeclaration({
moduleSpecifier: component.componentPath,
namedImports: [component.componentImport],
});
}
}
addStatement(sourceFile, generateRuntimeUtilities(eventToReactMapping));
@@ -180,7 +180,6 @@ const generateElementDefinition = (
const hasEvents = component.events.length > 0;
const hasSpecificProps = Object.keys(specificProperties).length > 0;
const hasProps = Object.keys(component.properties).length > 0;
const hasSlots = (component.slots ?? []).length > 0;
const propsType = hasSpecificProps
? `${component.name}Properties`
@@ -188,9 +187,7 @@ const generateElementDefinition = (
? TYPE_NAMES.COMMON_PROPERTIES
: TYPE_NAMES.EMPTY_RECORD;
const slotsType = hasSlots
? `{ ${(component.slots ?? []).map((slot) => `'${slot}': true`).join('; ')} }`
: TYPE_NAMES.EMPTY_RECORD;
const slotsType = TYPE_NAMES.EMPTY_RECORD;
const eventsType = hasEvents
? useSharedEvents
@@ -216,7 +213,7 @@ const generateElementDefinition = (
writer.newLine();
writer.write('>');
const hasConfig = hasProps || hasEvents || hasSlots;
const hasConfig = hasProps || hasEvents;
if (!hasConfig) {
writer.write('({})');
return;
@@ -224,12 +221,6 @@ const generateElementDefinition = (
writer.write('(');
writer.block(() => {
if (hasSlots) {
writer.write(
`slots: [${(component.slots ?? []).map((slot) => `'${slot}'`).join(', ')}],`,
);
writer.newLine();
}
if (hasProps) {
if (hasSpecificProps && component.isHtmlElement) {
writer.write('properties: ');
@@ -1,7 +1,7 @@
import { z } from 'zod';
export const PropertySchemaZ = z.object({
type: z.enum(['string', 'number', 'boolean', 'array', 'object', 'function']),
type: z.enum(['string', 'number', 'boolean']),
optional: z.boolean(),
});
@@ -20,14 +20,11 @@ export const ComponentSchemaZ = z.object({
tagName: z.string().min(1),
customElementName: z.string().min(1),
properties: z.record(z.string(), PropertySchemaZ),
slots: z.array(z.string()).optional(),
events: z.array(z.string()).readonly(),
isHtmlElement: z.boolean(),
htmlTag: z.string().optional(),
componentImport: z.string().optional(),
componentPath: z.string().optional(),
propsTypeName: z.string().optional(),
supportsRefForwarding: z.boolean().optional(),
});
export type PropertySchema = z.infer<typeof PropertySchemaZ>;
@@ -4,9 +4,6 @@ const SCHEMA_TYPE_TO_CONSTRUCTOR: Record<PropertySchema['type'], string> = {
boolean: 'Boolean',
number: 'Number',
string: 'String',
array: 'Array',
object: 'Object',
function: 'Function',
};
export const schemaTypeToConstructor = (type: PropertySchema['type']): string =>
@@ -4,9 +4,6 @@ const SCHEMA_TYPE_TO_TS: Record<PropertySchema['type'], string> = {
boolean: 'boolean',
number: 'number',
string: 'string',
array: 'unknown[]',
object: 'Record<string, unknown>',
function: '(...args: unknown[]) => unknown',
};
export const schemaTypeToTs = (type: PropertySchema['type']): string =>
@@ -1,9 +0,0 @@
import { EVENT_TO_REACT } from '@/sdk/front-component-api/constants/EventToReact';
export const REACT_PROP_TO_DOM_EVENT: Record<string, string> =
Object.fromEntries(
Object.entries(EVENT_TO_REACT).map(([domEvent, reactProp]) => [
reactProp,
domEvent,
]),
);
@@ -1,9 +0,0 @@
export const TWENTY_UI_COMPONENT_CATEGORIES_TO_SCAN = [
'input',
'components',
'display',
'feedback',
'layout',
'navigation',
'accessibility',
];
@@ -1,8 +0,0 @@
import * as path from 'path';
import { fileURLToPath } from 'url';
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
const WORKSPACE_ROOT = path.resolve(SCRIPT_DIR, '../../../../../../');
const TWENTY_UI_ROOT = path.join(WORKSPACE_ROOT, 'packages/twenty-ui');
export const TWENTY_UI_ROOT_PATH = TWENTY_UI_ROOT;
@@ -1,3 +0,0 @@
export { REACT_PROP_TO_DOM_EVENT } from './ReactPropToDomEvent';
export { TWENTY_UI_COMPONENT_CATEGORIES_TO_SCAN } from './TwentyUiComponentCategoriesToScan';
export { TWENTY_UI_ROOT_PATH } from './TwentyUiRootPath';
@@ -1,153 +0,0 @@
import * as path from 'path';
import { type ExportSpecifier, Project } from 'ts-morph';
import { isDefined, pascalToKebab } from 'twenty-shared/utils';
import { type PropertySchema } from '@/front-component-renderer/types/PropertySchema';
import {
logCategory,
logCountInline,
logDimText,
logEmpty,
logLine,
logWarning,
} from '../utils/logger';
import {
TWENTY_UI_COMPONENT_CATEGORIES_TO_SCAN,
TWENTY_UI_ROOT_PATH,
} from './constants';
import { classifyComponentPropsForRemoteDomGeneration } from './utils/classify-component-props-for-remote-dom-generation';
import { doesComponentSupportRefForwarding } from './utils/does-component-support-ref-forwarding';
import { getTwentyUiComponentCategoryIndexPath } from './utils/get-twenty-ui-component-category-index-path';
import { isReactComponentExport } from './utils/is-react-component-export';
import { logDiscoveredComponents } from './utils/log-discovered-components';
import { shouldSkipExport } from './utils/should-skip-export';
export type DiscoveredComponent = {
tag: string;
name: string;
properties: Record<string, PropertySchema>;
events: string[];
slots: string[];
supportsRefForwarding: boolean;
componentImport: string;
componentPath: string;
propsTypeName: string;
};
const extractComponentsFromCategory = (
project: Project,
category: string,
): DiscoveredComponent[] => {
const indexPath = getTwentyUiComponentCategoryIndexPath(category);
const sourceFile = project.getSourceFile(indexPath);
if (!isDefined(sourceFile)) {
logWarning(`Could not find barrel file at ${indexPath}`);
return [];
}
const allNamedExports = sourceFile
.getExportDeclarations()
.flatMap((declaration) => declaration.getNamedExports());
const propsTypeExportsByName = new Map<string, ExportSpecifier>();
const componentExports: ExportSpecifier[] = [];
for (const namedExport of allNamedExports) {
if (namedExport.getName().endsWith('Props')) {
propsTypeExportsByName.set(namedExport.getName(), namedExport);
continue;
}
if (!isReactComponentExport(namedExport)) {
continue;
}
componentExports.push(namedExport);
}
const discoveredComponents: DiscoveredComponent[] = [];
for (const namedExport of componentExports) {
const exportName = namedExport.getName();
if (shouldSkipExport(exportName)) {
continue;
}
const expectedPropsTypeName = `${exportName}Props`;
const propsTypeExport = propsTypeExportsByName.get(expectedPropsTypeName);
if (!isDefined(propsTypeExport)) {
continue;
}
const propsType = propsTypeExport.getNameNode().getType();
const { properties, events, slots } =
classifyComponentPropsForRemoteDomGeneration(propsType);
const supportsRefForwarding =
doesComponentSupportRefForwarding(namedExport);
const kebabName = pascalToKebab(exportName);
discoveredComponents.push({
tag: `twenty-ui-${kebabName}`,
name: `TwentyUi${exportName}`,
properties,
events,
slots,
supportsRefForwarding,
componentImport: exportName,
componentPath: `twenty-ui/${category}`,
propsTypeName: expectedPropsTypeName,
});
}
return discoveredComponents;
};
export const extractAllComponentsFromTwentyUi = (): DiscoveredComponent[] => {
logDimText(' Loading twenty-ui TypeScript project...');
const project = new Project({
tsConfigFilePath: path.join(TWENTY_UI_ROOT_PATH, 'tsconfig.json'),
skipAddingFilesFromTsConfig: false,
});
logLine(
' ' +
logCountInline(
project.getSourceFiles().length,
'source file loaded from twenty-ui',
'source files loaded from twenty-ui',
),
);
logEmpty();
const allDiscoveredComponents: DiscoveredComponent[] = [];
for (const [
index,
category,
] of TWENTY_UI_COMPONENT_CATEGORIES_TO_SCAN.entries()) {
if (index > 0) {
logEmpty();
}
logCategory(category);
const discoveredComponents = extractComponentsFromCategory(
project,
category,
);
logDiscoveredComponents(discoveredComponents);
allDiscoveredComponents.push(...discoveredComponents);
}
return allDiscoveredComponents;
};
@@ -1,4 +0,0 @@
export {
extractAllComponentsFromTwentyUi,
type DiscoveredComponent,
} from './extract-all-components-from-twenty-ui';
@@ -1,65 +0,0 @@
import { type Type } from 'ts-morph';
import { type PropertySchema } from '@/front-component-renderer/types/PropertySchema';
import { isDefined, isNonEmptyArray } from 'twenty-shared/utils';
import { REACT_PROP_TO_DOM_EVENT } from '../constants/ReactPropToDomEvent';
import { mapTypeToPropertySchema } from './map-type-to-property-schema';
import { isDomEventHandler } from './is-dom-event-handler';
import { isReactElementType } from './is-react-element-type';
export type ClassifiedComponentProps = {
properties: Record<string, PropertySchema>;
events: string[];
slots: string[];
};
export const classifyComponentPropsForRemoteDomGeneration = (
propsType: Type,
): ClassifiedComponentProps => {
const properties: Record<string, PropertySchema> = {};
const events: string[] = [];
const slots: string[] = [];
const propsTypeProperties = propsType.getProperties();
for (const propertySymbol of propsTypeProperties) {
const propertyName = propertySymbol.getName();
const propertyDeclarations = propertySymbol.getDeclarations();
if (!isNonEmptyArray(propertyDeclarations)) {
continue;
}
const firstDeclaration = propertyDeclarations[0];
const propertyType = firstDeclaration.getType();
const correspondingDomEvent = REACT_PROP_TO_DOM_EVENT[propertyName];
if (isDefined(correspondingDomEvent) && isDomEventHandler(propertyType)) {
events.push(correspondingDomEvent);
continue;
}
const isOptional =
propertySymbol.isOptional() ||
propertyType.isNullable() ||
propertyType.isUndefined();
if (isReactElementType(propertyType)) {
slots.push(propertyName);
continue;
}
const classifiedType = mapTypeToPropertySchema(propertyType);
if (isDefined(classifiedType)) {
properties[propertyName] = {
type: classifiedType,
optional: isOptional,
};
}
}
return { properties, events, slots };
};
@@ -1,16 +0,0 @@
import { type ExportSpecifier } from 'ts-morph';
const REF_FORWARDING_TYPE_MARKERS = [
'StyledComponent',
'ForwardRefExoticComponent',
];
export const doesComponentSupportRefForwarding = (
namedExport: ExportSpecifier,
): boolean => {
const typeText = namedExport.getNameNode().getType().getText();
return REF_FORWARDING_TYPE_MARKERS.some((marker) =>
typeText.includes(marker),
);
};
@@ -1,9 +0,0 @@
import * as path from 'path';
import { TWENTY_UI_ROOT_PATH } from '../constants/TwentyUiRootPath';
const TWENTY_UI_SRC_PATH = path.join(TWENTY_UI_ROOT_PATH, 'src');
export const getTwentyUiComponentCategoryIndexPath = (
category: string,
): string => path.join(TWENTY_UI_SRC_PATH, `${category}/index.ts`);
@@ -1,6 +0,0 @@
export * from './does-component-support-ref-forwarding';
export * from './map-type-to-property-schema';
export * from './classify-component-props-for-remote-dom-generation';
export * from './is-react-element-type';
export * from './log-discovered-components';
export * from './should-skip-export';
@@ -1,57 +0,0 @@
import { type Type } from 'ts-morph';
import { isDefined, isNonEmptyArray } from 'twenty-shared/utils';
const DOM_EVENT_TYPE_NAMES = new Set([
'Event',
'UIEvent',
'MouseEvent',
'KeyboardEvent',
'FocusEvent',
'ChangeEvent',
'FormEvent',
'DragEvent',
'WheelEvent',
'ClipboardEvent',
'TouchEvent',
'PointerEvent',
'AnimationEvent',
'TransitionEvent',
'SyntheticEvent',
'BaseSyntheticEvent',
]);
const isEventType = (type: Type): boolean => {
const symbol = type.getSymbol() ?? type.getAliasSymbol();
if (isDefined(symbol) && DOM_EVENT_TYPE_NAMES.has(symbol.getName())) {
return true;
}
return type.getBaseTypes().some(isEventType);
};
export const isDomEventHandler = (propertyType: Type): boolean => {
const nonNullableType = propertyType.getNonNullableType();
const callSignatures = nonNullableType.getCallSignatures();
if (!isNonEmptyArray(callSignatures)) {
return false;
}
return callSignatures.some((signature) => {
const firstParam = signature.getParameters()[0];
if (!isDefined(firstParam)) {
return false;
}
const paramType = firstParam.getValueDeclaration()?.getType();
if (!isDefined(paramType)) {
return false;
}
return isEventType(paramType);
});
};
@@ -1,28 +0,0 @@
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,
),
);
};
@@ -1,24 +0,0 @@
import { type Type } from 'ts-morph';
import { typeSymbolMatchesAnyName } from './type-symbol-matches-any-name';
const REACT_ELEMENT_TYPE_NAMES = new Set([
'ReactNode',
'ReactElement',
'Element',
]);
const REACT_COMPONENT_TYPE_NAMES = new Set([
'FunctionComponent',
'ComponentType',
'IconComponent',
]);
const ALL_REACT_TYPE_NAMES = new Set([
...REACT_ELEMENT_TYPE_NAMES,
...REACT_COMPONENT_TYPE_NAMES,
]);
export const isReactElementType = (propertyType: Type): boolean => {
return typeSymbolMatchesAnyName(propertyType, ALL_REACT_TYPE_NAMES);
};
@@ -1,63 +0,0 @@
import chalk from 'chalk';
import {
formatEvents,
formatProps,
formatSlots,
logCountInline,
logDimText,
logLine,
} from '../../utils/logger';
type ComponentSummary = {
tag: string;
componentImport: string;
properties: Record<string, unknown>;
events: string[];
slots: string[];
};
export const logDiscoveredComponents = (
discoveredComponents: ComponentSummary[],
): void => {
if (discoveredComponents.length === 0) {
logDimText(' No components found');
return;
}
logLine(
' ' +
logCountInline(
discoveredComponents.length,
'component found',
'components found',
),
);
for (const discoveredComponent of discoveredComponents) {
const propertyCount = Object.keys(discoveredComponent.properties).length;
const eventCount = discoveredComponent.events.length;
const slotCount = discoveredComponent.slots.length;
const parts: string[] = [formatProps(propertyCount)];
if (eventCount > 0) {
parts.push(formatEvents(eventCount, discoveredComponent.events));
}
if (slotCount > 0) {
parts.push(formatSlots(slotCount, discoveredComponent.slots));
}
logLine(
chalk.green(' · ') +
chalk.green(discoveredComponent.componentImport) +
chalk.gray(' -> ') +
chalk.white(discoveredComponent.tag) +
chalk.gray(' (') +
parts.join(chalk.green(', ')) +
chalk.gray(')'),
);
}
};
@@ -1,75 +0,0 @@
import { type Type } from 'ts-morph';
import { type PropertySchema } from '@/front-component-renderer/types/PropertySchema';
import { isNonEmptyArray } from 'twenty-shared/utils';
type PropertyType = PropertySchema['type'];
export const mapTypeToPropertySchema = (
propertyType: Type,
): PropertyType | null => {
if (propertyType.isString() || propertyType.isStringLiteral()) {
return 'string';
}
if (propertyType.isNumber() || propertyType.isNumberLiteral()) {
return 'number';
}
if (propertyType.isBoolean() || propertyType.isBooleanLiteral()) {
return 'boolean';
}
if (propertyType.isArray()) {
return 'array';
}
if (propertyType.isTuple()) {
return 'array';
}
const callSignatures = propertyType.getCallSignatures();
if (isNonEmptyArray(callSignatures)) {
return 'function';
}
if (propertyType.isUnion()) {
const unionMemberTypes = propertyType.getUnionTypes();
const nonNullableTypes = unionMemberTypes.filter(
(memberType) => !memberType.isUndefined() && !memberType.isNull(),
);
if (!isNonEmptyArray(nonNullableTypes)) {
return null;
}
const classifiedTypeSet = new Set(
nonNullableTypes.map((memberType) => mapTypeToPropertySchema(memberType)),
);
if (classifiedTypeSet.size === 1) {
return classifiedTypeSet.values().next().value ?? null;
}
const primitiveTypes = new Set(['string', 'number', 'boolean']);
const allPrimitive = [...classifiedTypeSet].every(
(type) => type !== null && primitiveTypes.has(type),
);
if (allPrimitive && classifiedTypeSet.size > 0) {
return 'string';
}
}
if (propertyType.isEnum() || propertyType.isEnumLiteral()) {
return 'string';
}
if (propertyType.isObject() && !propertyType.isArray()) {
return 'object';
}
return null;
};
@@ -1,31 +0,0 @@
const SCREAMING_SNAKE_CASE_REGEX = /^[A-Z][A-Z_0-9]+$/;
const SKIP_PREFIXES = [
'Styled',
'use',
'Icon',
'Illustration',
'base',
'BASE',
'get',
] as const;
const SKIP_SUFFIXES = ['Provider', 'State', 'state'] as const;
const NEVER_SKIP = new Set(['Icon']);
export const shouldSkipExport = (exportName: string): boolean => {
if (NEVER_SKIP.has(exportName)) {
return false;
}
const hasSkipPrefix = SKIP_PREFIXES.some((prefix) =>
exportName.startsWith(prefix),
);
const hasSkipSuffix = SKIP_SUFFIXES.some((suffix) =>
exportName.endsWith(suffix),
);
const isScreamingSnakeCase = SCREAMING_SNAKE_CASE_REGEX.test(exportName);
return hasSkipPrefix || hasSkipSuffix || isScreamingSnakeCase;
};
@@ -1,27 +0,0 @@
import { type Type } from 'ts-morph';
import { isDefined } from 'twenty-shared/utils';
const getTypeSymbolName = (type: Type): string | undefined => {
return (type.getSymbol() ?? type.getAliasSymbol())?.getName();
};
export const typeSymbolMatchesAnyName = (
type: Type,
names: Set<string>,
): boolean => {
const symbolName = getTypeSymbolName(type);
if (isDefined(symbolName) && names.has(symbolName)) {
return true;
}
if (type.isUnion()) {
return type
.getUnionTypes()
.filter((memberType) => !memberType.isUndefined() && !memberType.isNull())
.some((memberType) => typeSymbolMatchesAnyName(memberType, names));
}
return false;
};
@@ -48,7 +48,6 @@ export {
HtmlThead,
HtmlTr,
HtmlUl,
TwentyUiButton,
} from './remote/generated/remote-components';
export {
HtmlAElement,
@@ -96,7 +95,6 @@ export {
HtmlUlElement,
RemoteFragmentElement,
RemoteRootElement,
TwentyUiButtonElement,
} from './remote/generated/remote-elements';
export type {
HtmlAProperties,
@@ -112,7 +110,6 @@ export type {
HtmlTdProperties,
HtmlTextareaProperties,
HtmlThProperties,
TwentyUiButtonProperties,
} from './remote/generated/remote-elements';
export { createRemoteWorker } from './remote/worker/utils/createRemoteWorker';
export type { FrontComponentExecutionContext } from './types/FrontComponentExecutionContext';
@@ -52,92 +52,6 @@ import {
HtmlTdElement,
HtmlBrElement,
HtmlHrElement,
TwentyUiAnimatedButtonElement,
TwentyUiAnimatedLightIconButtonElement,
TwentyUiButtonElement,
TwentyUiButtonGroupElement,
TwentyUiColorPickerButtonElement,
TwentyUiFloatingButtonElement,
TwentyUiFloatingButtonGroupElement,
TwentyUiFloatingIconButtonElement,
TwentyUiFloatingIconButtonGroupElement,
TwentyUiInsideButtonElement,
TwentyUiLightButtonElement,
TwentyUiLightIconButtonElement,
TwentyUiLightIconButtonGroupElement,
TwentyUiMainButtonElement,
TwentyUiRoundedIconButtonElement,
TwentyUiTabContentElement,
TwentyUiTabButtonElement,
TwentyUiCodeEditorElement,
TwentyUiCoreEditorHeaderElement,
TwentyUiColorSchemeCardElement,
TwentyUiColorSchemePickerElement,
TwentyUiCardPickerElement,
TwentyUiCheckboxElement,
TwentyUiRadioElement,
TwentyUiRadioGroupElement,
TwentyUiSearchInputElement,
TwentyUiToggleElement,
TwentyUiAvatarChipElement,
TwentyUiMultipleAvatarChipElement,
TwentyUiChipElement,
TwentyUiLinkChipElement,
TwentyUiPillElement,
TwentyUiTagElement,
TwentyUiAvatarElement,
TwentyUiAvatarGroupElement,
TwentyUiBannerElement,
TwentyUiSidePanelInformationBannerElement,
TwentyUiCalloutElement,
TwentyUiAnimatedCheckmarkElement,
TwentyUiCheckmarkElement,
TwentyUiColorSampleElement,
TwentyUiCommandBlockElement,
TwentyUiIconElement,
TwentyUiInfoElement,
TwentyUiStatusElement,
TwentyUiHorizontalSeparatorElement,
TwentyUiAppTooltipElement,
TwentyUiOverflowingTextWithTooltipElement,
TwentyUiH1TitleElement,
TwentyUiH2TitleElement,
TwentyUiH3TitleElement,
TwentyUiLoaderElement,
TwentyUiCircularProgressBarElement,
TwentyUiProgressBarElement,
TwentyUiAnimatedExpandableContainerElement,
TwentyUiAnimatedPlaceholderElement,
TwentyUiSectionElement,
TwentyUiAdvancedSettingsToggleElement,
TwentyUiClickToActionLinkElement,
TwentyUiContactLinkElement,
TwentyUiGithubVersionLinkElement,
TwentyUiRawLinkElement,
TwentyUiRoundedLinkElement,
TwentyUiSocialLinkElement,
TwentyUiUndecoratedLinkElement,
TwentyUiMenuPickerElement,
TwentyUiMenuItemElement,
TwentyUiMenuItemAvatarElement,
TwentyUiMenuItemDraggableElement,
TwentyUiMenuItemHotKeysElement,
TwentyUiMenuItemMultiSelectElement,
TwentyUiMenuItemMultiSelectAvatarElement,
TwentyUiMenuItemMultiSelectTagElement,
TwentyUiMenuItemNavigateElement,
TwentyUiMenuItemSelectElement,
TwentyUiMenuItemSelectAvatarElement,
TwentyUiMenuItemSelectColorElement,
TwentyUiMenuItemSelectTagElement,
TwentyUiMenuItemSuggestionElement,
TwentyUiMenuItemToggleElement,
TwentyUiMenuItemIconElement,
TwentyUiMenuItemIconWithGripSwapElement,
TwentyUiMenuItemLeftContentElement,
TwentyUiNavigationBarElement,
TwentyUiNavigationBarItemElement,
TwentyUiNotificationCounterElement,
} from './remote-elements';
export const HtmlDiv = createRemoteComponent('html-div', HtmlDivElement, {
@@ -1212,452 +1126,3 @@ export const HtmlHr = createRemoteComponent('html-hr', HtmlHrElement, {
onDrag: { event: 'drag' },
},
});
export const TwentyUiAnimatedButton = createRemoteComponent(
'twenty-ui-animated-button',
TwentyUiAnimatedButtonElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiAnimatedLightIconButton = createRemoteComponent(
'twenty-ui-animated-light-icon-button',
TwentyUiAnimatedLightIconButtonElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiButton = createRemoteComponent(
'twenty-ui-button',
TwentyUiButtonElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiButtonGroup = createRemoteComponent(
'twenty-ui-button-group',
TwentyUiButtonGroupElement,
);
export const TwentyUiColorPickerButton = createRemoteComponent(
'twenty-ui-color-picker-button',
TwentyUiColorPickerButtonElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiFloatingButton = createRemoteComponent(
'twenty-ui-floating-button',
TwentyUiFloatingButtonElement,
);
export const TwentyUiFloatingButtonGroup = createRemoteComponent(
'twenty-ui-floating-button-group',
TwentyUiFloatingButtonGroupElement,
);
export const TwentyUiFloatingIconButton = createRemoteComponent(
'twenty-ui-floating-icon-button',
TwentyUiFloatingIconButtonElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiFloatingIconButtonGroup = createRemoteComponent(
'twenty-ui-floating-icon-button-group',
TwentyUiFloatingIconButtonGroupElement,
);
export const TwentyUiInsideButton = createRemoteComponent(
'twenty-ui-inside-button',
TwentyUiInsideButtonElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiLightButton = createRemoteComponent(
'twenty-ui-light-button',
TwentyUiLightButtonElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiLightIconButton = createRemoteComponent(
'twenty-ui-light-icon-button',
TwentyUiLightIconButtonElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiLightIconButtonGroup = createRemoteComponent(
'twenty-ui-light-icon-button-group',
TwentyUiLightIconButtonGroupElement,
);
export const TwentyUiMainButton = createRemoteComponent(
'twenty-ui-main-button',
TwentyUiMainButtonElement,
);
export const TwentyUiRoundedIconButton = createRemoteComponent(
'twenty-ui-rounded-icon-button',
TwentyUiRoundedIconButtonElement,
);
export const TwentyUiTabContent = createRemoteComponent(
'twenty-ui-tab-content',
TwentyUiTabContentElement,
);
export const TwentyUiTabButton = createRemoteComponent(
'twenty-ui-tab-button',
TwentyUiTabButtonElement,
);
export const TwentyUiCodeEditor = createRemoteComponent(
'twenty-ui-code-editor',
TwentyUiCodeEditorElement,
);
export const TwentyUiCoreEditorHeader = createRemoteComponent(
'twenty-ui-core-editor-header',
TwentyUiCoreEditorHeaderElement,
);
export const TwentyUiColorSchemeCard = createRemoteComponent(
'twenty-ui-color-scheme-card',
TwentyUiColorSchemeCardElement,
);
export const TwentyUiColorSchemePicker = createRemoteComponent(
'twenty-ui-color-scheme-picker',
TwentyUiColorSchemePickerElement,
);
export const TwentyUiCardPicker = createRemoteComponent(
'twenty-ui-card-picker',
TwentyUiCardPickerElement,
);
export const TwentyUiCheckbox = createRemoteComponent(
'twenty-ui-checkbox',
TwentyUiCheckboxElement,
{
eventProps: {
onChange: { event: 'change' },
},
},
);
export const TwentyUiRadio = createRemoteComponent(
'twenty-ui-radio',
TwentyUiRadioElement,
{
eventProps: {
onChange: { event: 'change' },
},
},
);
export const TwentyUiRadioGroup = createRemoteComponent(
'twenty-ui-radio-group',
TwentyUiRadioGroupElement,
{
eventProps: {
onChange: { event: 'change' },
},
},
);
export const TwentyUiSearchInput = createRemoteComponent(
'twenty-ui-search-input',
TwentyUiSearchInputElement,
);
export const TwentyUiToggle = createRemoteComponent(
'twenty-ui-toggle',
TwentyUiToggleElement,
);
export const TwentyUiAvatarChip = createRemoteComponent(
'twenty-ui-avatar-chip',
TwentyUiAvatarChipElement,
);
export const TwentyUiMultipleAvatarChip = createRemoteComponent(
'twenty-ui-multiple-avatar-chip',
TwentyUiMultipleAvatarChipElement,
);
export const TwentyUiChip = createRemoteComponent(
'twenty-ui-chip',
TwentyUiChipElement,
);
export const TwentyUiLinkChip = createRemoteComponent(
'twenty-ui-link-chip',
TwentyUiLinkChipElement,
{
eventProps: {
onClick: { event: 'click' },
onMouseDown: { event: 'mousedown' },
},
},
);
export const TwentyUiPill = createRemoteComponent(
'twenty-ui-pill',
TwentyUiPillElement,
);
export const TwentyUiTag = createRemoteComponent(
'twenty-ui-tag',
TwentyUiTagElement,
);
export const TwentyUiAvatar = createRemoteComponent(
'twenty-ui-avatar',
TwentyUiAvatarElement,
);
export const TwentyUiAvatarGroup = createRemoteComponent(
'twenty-ui-avatar-group',
TwentyUiAvatarGroupElement,
);
export const TwentyUiBanner = createRemoteComponent(
'twenty-ui-banner',
TwentyUiBannerElement,
);
export const TwentyUiSidePanelInformationBanner = createRemoteComponent(
'twenty-ui-side-panel-information-banner',
TwentyUiSidePanelInformationBannerElement,
);
export const TwentyUiCallout = createRemoteComponent(
'twenty-ui-callout',
TwentyUiCalloutElement,
);
export const TwentyUiAnimatedCheckmark = createRemoteComponent(
'twenty-ui-animated-checkmark',
TwentyUiAnimatedCheckmarkElement,
);
export const TwentyUiCheckmark = createRemoteComponent(
'twenty-ui-checkmark',
TwentyUiCheckmarkElement,
);
export const TwentyUiColorSample = createRemoteComponent(
'twenty-ui-color-sample',
TwentyUiColorSampleElement,
);
export const TwentyUiCommandBlock = createRemoteComponent(
'twenty-ui-command-block',
TwentyUiCommandBlockElement,
);
export const TwentyUiIcon = createRemoteComponent(
'twenty-ui-icon',
TwentyUiIconElement,
);
export const TwentyUiInfo = createRemoteComponent(
'twenty-ui-info',
TwentyUiInfoElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiStatus = createRemoteComponent(
'twenty-ui-status',
TwentyUiStatusElement,
);
export const TwentyUiHorizontalSeparator = createRemoteComponent(
'twenty-ui-horizontal-separator',
TwentyUiHorizontalSeparatorElement,
);
export const TwentyUiAppTooltip = createRemoteComponent(
'twenty-ui-app-tooltip',
TwentyUiAppTooltipElement,
);
export const TwentyUiOverflowingTextWithTooltip = createRemoteComponent(
'twenty-ui-overflowing-text-with-tooltip',
TwentyUiOverflowingTextWithTooltipElement,
);
export const TwentyUiH1Title = createRemoteComponent(
'twenty-ui-h1-title',
TwentyUiH1TitleElement,
);
export const TwentyUiH2Title = createRemoteComponent(
'twenty-ui-h2-title',
TwentyUiH2TitleElement,
);
export const TwentyUiH3Title = createRemoteComponent(
'twenty-ui-h3-title',
TwentyUiH3TitleElement,
);
export const TwentyUiLoader = createRemoteComponent(
'twenty-ui-loader',
TwentyUiLoaderElement,
);
export const TwentyUiCircularProgressBar = createRemoteComponent(
'twenty-ui-circular-progress-bar',
TwentyUiCircularProgressBarElement,
);
export const TwentyUiProgressBar = createRemoteComponent(
'twenty-ui-progress-bar',
TwentyUiProgressBarElement,
);
export const TwentyUiAnimatedExpandableContainer = createRemoteComponent(
'twenty-ui-animated-expandable-container',
TwentyUiAnimatedExpandableContainerElement,
);
export const TwentyUiAnimatedPlaceholder = createRemoteComponent(
'twenty-ui-animated-placeholder',
TwentyUiAnimatedPlaceholderElement,
);
export const TwentyUiSection = createRemoteComponent(
'twenty-ui-section',
TwentyUiSectionElement,
);
export const TwentyUiAdvancedSettingsToggle = createRemoteComponent(
'twenty-ui-advanced-settings-toggle',
TwentyUiAdvancedSettingsToggleElement,
);
export const TwentyUiClickToActionLink = createRemoteComponent(
'twenty-ui-click-to-action-link',
TwentyUiClickToActionLinkElement,
);
export const TwentyUiContactLink = createRemoteComponent(
'twenty-ui-contact-link',
TwentyUiContactLinkElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiGithubVersionLink = createRemoteComponent(
'twenty-ui-github-version-link',
TwentyUiGithubVersionLinkElement,
);
export const TwentyUiRawLink = createRemoteComponent(
'twenty-ui-raw-link',
TwentyUiRawLinkElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiRoundedLink = createRemoteComponent(
'twenty-ui-rounded-link',
TwentyUiRoundedLinkElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiSocialLink = createRemoteComponent(
'twenty-ui-social-link',
TwentyUiSocialLinkElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiUndecoratedLink = createRemoteComponent(
'twenty-ui-undecorated-link',
TwentyUiUndecoratedLinkElement,
);
export const TwentyUiMenuPicker = createRemoteComponent(
'twenty-ui-menu-picker',
TwentyUiMenuPickerElement,
);
export const TwentyUiMenuItem = createRemoteComponent(
'twenty-ui-menu-item',
TwentyUiMenuItemElement,
{
eventProps: {
onClick: { event: 'click' },
onMouseEnter: { event: 'mouseenter' },
onMouseLeave: { event: 'mouseleave' },
},
},
);
export const TwentyUiMenuItemAvatar = createRemoteComponent(
'twenty-ui-menu-item-avatar',
TwentyUiMenuItemAvatarElement,
{
eventProps: {
onClick: { event: 'click' },
onMouseEnter: { event: 'mouseenter' },
onMouseLeave: { event: 'mouseleave' },
},
},
);
export const TwentyUiMenuItemDraggable = createRemoteComponent(
'twenty-ui-menu-item-draggable',
TwentyUiMenuItemDraggableElement,
);
export const TwentyUiMenuItemHotKeys = createRemoteComponent(
'twenty-ui-menu-item-hot-keys',
TwentyUiMenuItemHotKeysElement,
);
export const TwentyUiMenuItemMultiSelect = createRemoteComponent(
'twenty-ui-menu-item-multi-select',
TwentyUiMenuItemMultiSelectElement,
);
export const TwentyUiMenuItemMultiSelectAvatar = createRemoteComponent(
'twenty-ui-menu-item-multi-select-avatar',
TwentyUiMenuItemMultiSelectAvatarElement,
);
export const TwentyUiMenuItemMultiSelectTag = createRemoteComponent(
'twenty-ui-menu-item-multi-select-tag',
TwentyUiMenuItemMultiSelectTagElement,
);
export const TwentyUiMenuItemNavigate = createRemoteComponent(
'twenty-ui-menu-item-navigate',
TwentyUiMenuItemNavigateElement,
);
export const TwentyUiMenuItemSelect = createRemoteComponent(
'twenty-ui-menu-item-select',
TwentyUiMenuItemSelectElement,
);
export const TwentyUiMenuItemSelectAvatar = createRemoteComponent(
'twenty-ui-menu-item-select-avatar',
TwentyUiMenuItemSelectAvatarElement,
);
export const TwentyUiMenuItemSelectColor = createRemoteComponent(
'twenty-ui-menu-item-select-color',
TwentyUiMenuItemSelectColorElement,
);
export const TwentyUiMenuItemSelectTag = createRemoteComponent(
'twenty-ui-menu-item-select-tag',
TwentyUiMenuItemSelectTagElement,
);
export const TwentyUiMenuItemSuggestion = createRemoteComponent(
'twenty-ui-menu-item-suggestion',
TwentyUiMenuItemSuggestionElement,
{
eventProps: {
onClick: { event: 'click' },
},
},
);
export const TwentyUiMenuItemToggle = createRemoteComponent(
'twenty-ui-menu-item-toggle',
TwentyUiMenuItemToggleElement,
);
export const TwentyUiMenuItemIcon = createRemoteComponent(
'twenty-ui-menu-item-icon',
TwentyUiMenuItemIconElement,
);
export const TwentyUiMenuItemIconWithGripSwap = createRemoteComponent(
'twenty-ui-menu-item-icon-with-grip-swap',
TwentyUiMenuItemIconWithGripSwapElement,
);
export const TwentyUiMenuItemLeftContent = createRemoteComponent(
'twenty-ui-menu-item-left-content',
TwentyUiMenuItemLeftContentElement,
);
export const TwentyUiNavigationBar = createRemoteComponent(
'twenty-ui-navigation-bar',
TwentyUiNavigationBarElement,
);
export const TwentyUiNavigationBarItem = createRemoteComponent(
'twenty-ui-navigation-bar-item',
TwentyUiNavigationBarItemElement,
);
export const TwentyUiNotificationCounter = createRemoteComponent(
'twenty-ui-notification-counter',
TwentyUiNotificationCounterElement,
);
@@ -1,4 +1,4 @@
export type PropertySchema = {
type: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'function';
type: 'string' | 'number' | 'boolean';
optional: boolean;
};
-22
View File
@@ -69,26 +69,4 @@ export default [
'lingui/text-restrictions': 'off',
},
},
{
files: [
'**/src/input/**/*.tsx',
'**/src/components/**/*.tsx',
'**/src/display/**/*.tsx',
'**/src/feedback/**/*.tsx',
'**/src/layout/**/*.tsx',
'**/src/navigation/**/*.tsx',
'**/src/accessibility/**/*.tsx',
],
ignores: [
'**/*.stories.tsx',
'**/__stories__/**/*.tsx',
'**/*.test.tsx',
'**/__tests__/**/*.tsx',
'**/testing/**/*.tsx',
],
rules: {
'twenty/export-component-props': 'error',
},
},
];
@@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { type IconComponent } from '@ui/display';
export type PillProps = {
type PillProps = {
className?: string;
label?: string;
Icon?: IconComponent;
+1 -2
View File
@@ -16,7 +16,6 @@ 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, TagProps } from './tag/Tag';
export type { TagColor } 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';
export type TagProps = {
type TagProps = {
className?: string;
color: TagColor;
text: string;
@@ -22,7 +22,7 @@ const StyledBanner = styled.div<{ variant?: BannerVariant }>`
export type BannerVariant = 'danger' | 'default';
export type BannerProps = {
type BannerProps = {
variant?: BannerVariant;
className?: string;
children: React.ReactNode;
@@ -29,7 +29,7 @@ const StyledLineSpan = styled.span`
color: ${({ theme }) => theme.code.text.green};
`;
export type CommandBlockProps = {
type CommandBlockProps = {
commands: string[];
button?: ReactElement;
};
@@ -2,7 +2,7 @@ import IconAddressBookRaw from '@assets/icons/address-book.svg?react';
import { useTheme } from '@emotion/react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IconAddressBookProps = Pick<
type IconAddressBookProps = Pick<
IconComponentProps,
'size' | 'stroke' | 'color'
>;
@@ -9,7 +9,7 @@ const StyledRotatedIconWrapper = styled.div`
transform: rotate(90deg);
`;
export type IconChartBarHorizontalProps = Pick<
type IconChartBarHorizontalProps = Pick<
IconComponentProps,
'size' | 'stroke' | 'color'
>;
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import IconGmailRaw from '@assets/icons/gmail.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IconGmailProps = Pick<IconComponentProps, 'size'>;
type IconGmailProps = Pick<IconComponentProps, 'size'>;
export const IconGmail = (props: IconGmailProps) => {
const theme = useTheme();
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import IconGoogleRaw from '@assets/icons/google.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IconGoogleProps = Pick<IconComponentProps, 'size'>;
type IconGoogleProps = Pick<IconComponentProps, 'size'>;
export const IconGoogle = (props: IconGoogleProps) => {
const theme = useTheme();
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import IconGoogleCalendarRaw from '@assets/icons/google-calendar.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IconGoogleCalendarProps = Pick<IconComponentProps, 'size'>;
type IconGoogleCalendarProps = Pick<IconComponentProps, 'size'>;
export const IconGoogleCalendar = (props: IconGoogleCalendarProps) => {
const theme = useTheme();
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import IconLockRaw from '@assets/icons/lock.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IconLockCustomProps = Pick<IconComponentProps, 'size'>;
type IconLockCustomProps = Pick<IconComponentProps, 'size'>;
export const IconLockCustom = (props: IconLockCustomProps) => {
const theme = useTheme();
@@ -2,7 +2,7 @@ import { useTheme } from '@emotion/react';
import IconMicrosoftRaw from '@assets/icons/microsoft.svg?react';
export interface IconMicrosoftProps {
interface IconMicrosoftProps {
size?: number | string;
}
@@ -2,7 +2,7 @@ import { useTheme } from '@emotion/react';
import IconMicrosoftCalendarRaw from '@assets/icons/microsoft-calendar.svg?react';
export interface IconMicrosoftCalendarProps {
interface IconMicrosoftCalendarProps {
size?: number | string;
}
@@ -2,7 +2,7 @@ import { useTheme } from '@emotion/react';
import IconMicrosoftOutlookRaw from '@assets/icons/microsoft-outlook.svg?react';
export interface IconMicrosoftOutlookProps {
interface IconMicrosoftOutlookProps {
size?: number | string;
}
@@ -3,10 +3,7 @@ import { useTheme } from '@emotion/react';
import IconRelationManyToOneRaw from '@assets/icons/many-to-one.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IconRelationManyToOneProps = Pick<
IconComponentProps,
'size' | 'stroke'
>;
type IconRelationManyToOneProps = Pick<IconComponentProps, 'size' | 'stroke'>;
export const IconRelationManyToOne = (props: IconRelationManyToOneProps) => {
const theme = useTheme();
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import IconTrashXOffRaw from '@assets/icons/trash-x-off.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IconTrashXOffProps = Pick<IconComponentProps, 'size' | 'stroke'>;
type IconTrashXOffProps = Pick<IconComponentProps, 'size' | 'stroke'>;
export const IconTrashXOff = (props: IconTrashXOffProps) => {
const theme = useTheme();
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import IconTwentyStarRaw from '@assets/icons/twenty-star.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IconTwentyStarProps = Pick<IconComponentProps, 'size' | 'stroke'>;
type IconTwentyStarProps = Pick<IconComponentProps, 'size' | 'stroke'>;
export const IconTwentyStar = (props: IconTwentyStarProps) => {
const theme = useTheme();
@@ -2,10 +2,7 @@ import IconTwentyStarFilledRaw from '@assets/icons/twenty-star-filled.svg?react'
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
import { THEME_COMMON } from '@ui/theme';
export type IconTwentyStarFilledProps = Pick<
IconComponentProps,
'size' | 'stroke'
>;
type IconTwentyStarFilledProps = Pick<IconComponentProps, 'size' | 'stroke'>;
const iconStrokeMd = THEME_COMMON.icon.stroke.md;
@@ -2,7 +2,7 @@ import IllustrationIconArrayRaw from '@assets/icons/illustration-array.svg?react
import { useTheme } from '@emotion/react';
import { IllustrationIconWrapper } from '@ui/display/icon/components/IllustrationIconWrapper';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconArrayProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconArrayProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconArray = (props: IllustrationIconArrayProps) => {
const theme = useTheme();
@@ -2,10 +2,7 @@ import IllustrationIconCalendarEventRaw from '@assets/icons/illustration-calenda
import { useTheme } from '@emotion/react';
import { IllustrationIconWrapper } from '@ui/display/icon/components/IllustrationIconWrapper';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconCalendarEventProps = Pick<
IconComponentProps,
'size'
>;
type IllustrationIconCalendarEventProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconCalendarEvent = (
props: IllustrationIconCalendarEventProps,
@@ -3,10 +3,7 @@ import { useTheme } from '@emotion/react';
import { IllustrationIconWrapper } from '@ui/display/icon/components/IllustrationIconWrapper';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconCalendarTimeProps = Pick<
IconComponentProps,
'size'
>;
type IllustrationIconCalendarTimeProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconCalendarTime = (
props: IllustrationIconCalendarTimeProps,
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconCurrencyRaw from '@assets/icons/illustration-currency.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconCurrencyProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconCurrencyProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconCurrency = (
props: IllustrationIconCurrencyProps,
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconFileRaw from '@assets/icons/illustration-file.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconFileProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconFileProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconFile = (props: IllustrationIconFileProps) => {
const theme = useTheme();
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconJsonRaw from '@assets/icons/illustration-json.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconJsonProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconJsonProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconJson = (props: IllustrationIconJsonProps) => {
const theme = useTheme();
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconLinkRaw from '@assets/icons/illustration-link.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconLinkProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconLinkProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconLink = (props: IllustrationIconLinkProps) => {
const theme = useTheme();
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import { IllustrationIconWrapper } from '@ui/display/icon/components/IllustrationIconWrapper';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconMailProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconMailProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconMail = (props: IllustrationIconMailProps) => {
const theme = useTheme();
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import { IllustrationIconWrapper } from '@ui/display/icon/components/IllustrationIconWrapper';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconManyToManyProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconManyToManyProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconManyToMany = (
props: IllustrationIconManyToManyProps,
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import { IllustrationIconWrapper } from '@ui/display/icon/components/IllustrationIconWrapper';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconMapProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconMapProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconMap = (props: IllustrationIconMapProps) => {
const theme = useTheme();
@@ -3,7 +3,7 @@ import { useTheme } from '@emotion/react';
import { IllustrationIconWrapper } from '@ui/display/icon/components/IllustrationIconWrapper';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconNumbersProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconNumbersProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconNumbers = (
props: IllustrationIconNumbersProps,
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconOneToManyRaw from '@assets/icons/illustration-one-to-many.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconOneToManyProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconOneToManyProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconOneToMany = (
props: IllustrationIconOneToManyProps,
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconOneToOneRaw from '@assets/icons/illustration-one-to-one.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconOneToOneProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconOneToOneProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconOneToOne = (
props: IllustrationIconOneToOneProps,
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconPhoneRaw from '@assets/icons/illustration-phone.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconPhoneProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconPhoneProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconPhone = (props: IllustrationIconPhoneProps) => {
const theme = useTheme();
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconSettingRaw from '@assets/icons/illustration-setting.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconSettingProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconSettingProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconSetting = (
props: IllustrationIconSettingProps,
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconStarRaw from '@assets/icons/illustration-star.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconStarProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconStarProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconStar = (props: IllustrationIconStarProps) => {
const theme = useTheme();
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconTagRaw from '@assets/icons/illustration-tag.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconTagProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconTagProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconTag = (props: IllustrationIconTagProps) => {
const theme = useTheme();
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconTagsRaw from '@assets/icons/illustration-tags.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconTagsProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconTagsProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconTags = (props: IllustrationIconTagsProps) => {
const theme = useTheme();
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconTextRaw from '@assets/icons/illustration-text.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconTextProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconTextProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconText = (props: IllustrationIconTextProps) => {
const theme = useTheme();
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconToggleRaw from '@assets/icons/illustration-toggle.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconToggleProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconToggleProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconToggle = (props: IllustrationIconToggleProps) => {
const theme = useTheme();
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconUidRaw from '@assets/icons/illustration-uid.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconUidProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconUidProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconUid = (props: IllustrationIconUidProps) => {
const theme = useTheme();
@@ -4,7 +4,7 @@ import { IllustrationIconWrapper } from '@ui/display/icon/components/Illustratio
import IllustrationIconUserRaw from '@assets/icons/illustration-user.svg?react';
import { type IconComponentProps } from '@ui/display/icon/types/IconComponent';
export type IllustrationIconUserProps = Pick<IconComponentProps, 'size'>;
type IllustrationIconUserProps = Pick<IconComponentProps, 'size'>;
export const IllustrationIconUser = (props: IllustrationIconUserProps) => {
const theme = useTheme();
@@ -3,7 +3,7 @@ import { useEffect } from 'react';
import { iconsState } from '@ui/display/icon/states/iconsState';
export type IconsProviderProps = {
type IconsProviderProps = {
children: JSX.Element;
};
+1 -45
View File
@@ -15,7 +15,7 @@ export { invalidAvatarUrlsAtomV2 } from './avatar/components/states/invalidAvata
export { AVATAR_PROPERTIES_BY_SIZE } from './avatar/constants/AvatarPropertiesBySize';
export type { AvatarSize } from './avatar/types/AvatarSize';
export type { AvatarType } from './avatar/types/AvatarType';
export type { BannerVariant, BannerProps } from './banner/components/Banner';
export type { BannerVariant } from './banner/components/Banner';
export { Banner } from './banner/components/Banner';
export type { SidePanelInformationBannerProps } from './banner/components/SidePanelInformationBanner';
export { SidePanelInformationBanner } from './banner/components/SidePanelInformationBanner';
@@ -30,79 +30,43 @@ export type {
ColorSampleProps,
} from './color/components/ColorSample';
export { ColorSample } from './color/components/ColorSample';
export type { CommandBlockProps } from './command-block/components/CommandBlock';
export { CommandBlock } from './command-block/components/CommandBlock';
export type { IconProps } from './icon/components/Icon';
export { Icon } from './icon/components/Icon';
export type { IconAddressBookProps } from './icon/components/IconAddressBook';
export { IconAddressBook } from './icon/components/IconAddressBook';
export type { IconChartBarHorizontalProps } from './icon/components/IconChartBarHorizontal';
export { IconChartBarHorizontal } from './icon/components/IconChartBarHorizontal';
export type { IconGmailProps } from './icon/components/IconGmail';
export { IconGmail } from './icon/components/IconGmail';
export type { IconGoogleProps } from './icon/components/IconGoogle';
export { IconGoogle } from './icon/components/IconGoogle';
export type { IconGoogleCalendarProps } from './icon/components/IconGoogleCalendar';
export { IconGoogleCalendar } from './icon/components/IconGoogleCalendar';
export type { IconLockCustomProps } from './icon/components/IconLock';
export { IconLockCustom } from './icon/components/IconLock';
export type { IconMicrosoftProps } from './icon/components/IconMicrosoft';
export { IconMicrosoft } from './icon/components/IconMicrosoft';
export type { IconMicrosoftCalendarProps } from './icon/components/IconMicrosoftCalendar';
export { IconMicrosoftCalendar } from './icon/components/IconMicrosoftCalendar';
export type { IconMicrosoftOutlookProps } from './icon/components/IconMicrosoftOutlook';
export { IconMicrosoftOutlook } from './icon/components/IconMicrosoftOutlook';
export type { IconRelationManyToOneProps } from './icon/components/IconRelationManyToOne';
export { IconRelationManyToOne } from './icon/components/IconRelationManyToOne';
export type { IconTrashXOffProps } from './icon/components/IconTrashXOff';
export { IconTrashXOff } from './icon/components/IconTrashXOff';
export type { IconTwentyStarProps } from './icon/components/IconTwentyStar';
export { IconTwentyStar } from './icon/components/IconTwentyStar';
export type { IconTwentyStarFilledProps } from './icon/components/IconTwentyStarFilled';
export { IconTwentyStarFilled } from './icon/components/IconTwentyStarFilled';
export type { IllustrationIconArrayProps } from './icon/components/IllustrationIconArray';
export { IllustrationIconArray } from './icon/components/IllustrationIconArray';
export type { IllustrationIconCalendarEventProps } from './icon/components/IllustrationIconCalendarEvent';
export { IllustrationIconCalendarEvent } from './icon/components/IllustrationIconCalendarEvent';
export type { IllustrationIconCalendarTimeProps } from './icon/components/IllustrationIconCalendarTime';
export { IllustrationIconCalendarTime } from './icon/components/IllustrationIconCalendarTime';
export type { IllustrationIconCurrencyProps } from './icon/components/IllustrationIconCurrency';
export { IllustrationIconCurrency } from './icon/components/IllustrationIconCurrency';
export type { IllustrationIconFileProps } from './icon/components/IllustrationIconFile';
export { IllustrationIconFile } from './icon/components/IllustrationIconFile';
export type { IllustrationIconJsonProps } from './icon/components/IllustrationIconJson';
export { IllustrationIconJson } from './icon/components/IllustrationIconJson';
export type { IllustrationIconLinkProps } from './icon/components/IllustrationIconLink';
export { IllustrationIconLink } from './icon/components/IllustrationIconLink';
export type { IllustrationIconMailProps } from './icon/components/IllustrationIconMail';
export { IllustrationIconMail } from './icon/components/IllustrationIconMail';
export type { IllustrationIconManyToManyProps } from './icon/components/IllustrationIconManyToMany';
export { IllustrationIconManyToMany } from './icon/components/IllustrationIconManyToMany';
export type { IllustrationIconMapProps } from './icon/components/IllustrationIconMap';
export { IllustrationIconMap } from './icon/components/IllustrationIconMap';
export type { IllustrationIconNumbersProps } from './icon/components/IllustrationIconNumbers';
export { IllustrationIconNumbers } from './icon/components/IllustrationIconNumbers';
export type { IllustrationIconOneToManyProps } from './icon/components/IllustrationIconOneToMany';
export { IllustrationIconOneToMany } from './icon/components/IllustrationIconOneToMany';
export type { IllustrationIconOneToOneProps } from './icon/components/IllustrationIconOneToOne';
export { IllustrationIconOneToOne } from './icon/components/IllustrationIconOneToOne';
export type { IllustrationIconPhoneProps } from './icon/components/IllustrationIconPhone';
export { IllustrationIconPhone } from './icon/components/IllustrationIconPhone';
export type { IllustrationIconSettingProps } from './icon/components/IllustrationIconSetting';
export { IllustrationIconSetting } from './icon/components/IllustrationIconSetting';
export type { IllustrationIconStarProps } from './icon/components/IllustrationIconStar';
export { IllustrationIconStar } from './icon/components/IllustrationIconStar';
export type { IllustrationIconTagProps } from './icon/components/IllustrationIconTag';
export { IllustrationIconTag } from './icon/components/IllustrationIconTag';
export type { IllustrationIconTagsProps } from './icon/components/IllustrationIconTags';
export { IllustrationIconTags } from './icon/components/IllustrationIconTags';
export type { IllustrationIconTextProps } from './icon/components/IllustrationIconText';
export { IllustrationIconText } from './icon/components/IllustrationIconText';
export type { IllustrationIconToggleProps } from './icon/components/IllustrationIconToggle';
export { IllustrationIconToggle } from './icon/components/IllustrationIconToggle';
export type { IllustrationIconUidProps } from './icon/components/IllustrationIconUid';
export { IllustrationIconUid } from './icon/components/IllustrationIconUid';
export type { IllustrationIconUserProps } from './icon/components/IllustrationIconUser';
export { IllustrationIconUser } from './icon/components/IllustrationIconUser';
export { IllustrationIconWrapper } from './icon/components/IllustrationIconWrapper';
export type { TablerIconsProps } from './icon/components/TablerIcons';
@@ -508,7 +472,6 @@ export {
IconX,
} from './icon/components/TablerIcons';
export { useIcons } from './icon/hooks/useIcons';
export type { IconsProviderProps } from './icon/providers/IconsProvider';
export { IconsProvider } from './icon/providers/IconsProvider';
export { iconsState } from './icon/states/iconsState';
export type {
@@ -517,9 +480,7 @@ export type {
} from './icon/types/IconComponent';
export type { InfoAccent, InfoProps } from './info/components/Info';
export { Info } from './info/components/Info';
export type { StatusProps } from './status/components/Status';
export { Status } from './status/components/Status';
export type { HorizontalSeparatorProps } from './text/components/HorizontalSeparator';
export { HorizontalSeparator } from './text/components/HorizontalSeparator';
export { SeparatorLineText } from './text/components/SeparatorLineText';
export type { AppTooltipProps } from './tooltip/AppTooltip';
@@ -528,17 +489,12 @@ export {
TooltipDelay,
AppTooltip,
} from './tooltip/AppTooltip';
export type { OverflowingTextWithTooltipProps } from './tooltip/OverflowingTextWithTooltip';
export { OverflowingTextWithTooltip } from './tooltip/OverflowingTextWithTooltip';
export type { H1TitleProps } from './typography/components/H1Title';
export { H1TitleFontColor, H1Title } from './typography/components/H1Title';
export type { H2TitleProps } from './typography/components/H2Title';
export { H2Title } from './typography/components/H2Title';
export type { H3TitleProps } from './typography/components/H3Title';
export { H3Title } from './typography/components/H3Title';
export type { LabelVariant } from './typography/components/Label';
export { Label } from './typography/components/Label';
export type { StyledTextProps } from './typography/components/StyledText';
export {
StyledTextContent,
StyledTextWrapper,
@@ -43,7 +43,7 @@ const StyledContent = styled.span`
white-space: nowrap;
`;
export type StatusProps = {
type StatusProps = {
className?: string;
color: ThemeColor;
isLoaderVisible?: boolean;
@@ -2,7 +2,7 @@ import styled from '@emotion/styled';
import { type JSX } from 'react';
import { Label } from '@ui/display';
export type HorizontalSeparatorProps = {
type HorizontalSeparatorProps = {
visible?: boolean;
text?: string;
noMargin?: boolean;
@@ -59,7 +59,7 @@ const StyledPre = styled.pre`
white-space: pre-wrap;
`;
export type OverflowingTextWithTooltipProps = {
type OverflowingTextWithTooltipProps = {
size?: 'large' | 'small';
isTooltipMultiline?: boolean;
displayedMaxRows?: number;
@@ -1,7 +1,7 @@
import { type ReactNode } from 'react';
import styled from '@emotion/styled';
export type H1TitleProps = {
type H1TitleProps = {
title: ReactNode;
fontColor?: H1TitleFontColor;
className?: string;
@@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from '@ui/display/tooltip/OverflowingTextWithTooltip';
export type H2TitleProps = {
type H2TitleProps = {
title: string;
description?: string;
adornment?: React.ReactNode;
@@ -2,7 +2,7 @@ import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from '@ui/display/tooltip/OverflowingTextWithTooltip';
import { type ReactNode } from 'react';
export type H3TitleProps = {
type H3TitleProps = {
title: ReactNode;
description?: string;
className?: string;
@@ -1,7 +1,7 @@
import { type ReactElement, type ReactNode } from 'react';
import styled from '@emotion/styled';
export type StyledTextProps = {
type StyledTextProps = {
PrefixComponent?: ReactElement;
text: ReactNode;
color?: string;
-2
View File
@@ -7,9 +7,7 @@
* |___/
*/
export type { LoaderProps } from './loader/components/Loader';
export { Loader } from './loader/components/Loader';
export type { CircularProgressBarProps } from './progress-bar/components/CircularProgressBar';
export { CircularProgressBar } from './progress-bar/components/CircularProgressBar';
export type {
ProgressBarProps,
@@ -33,7 +33,7 @@ const StyledLoader = styled(motion.div)<{
width: 8px;
`;
export type LoaderProps = {
type LoaderProps = {
color?: ThemeColor;
};
@@ -1,7 +1,7 @@
import { motion, useAnimation } from 'framer-motion';
import { useEffect, useMemo } from 'react';
export interface CircularProgressBarProps {
interface CircularProgressBarProps {
size?: number;
barWidth?: number;
barColor?: string;
@@ -5,7 +5,7 @@ const StyledSoonPill = styled(Pill)`
margin-left: auto;
`;
export type ButtonSoonProps = {
type ButtonSoonProps = {
label?: string;
};
@@ -6,7 +6,7 @@ import {
type LightIconButtonProps,
} from '@ui/input/button/components/LightIconButton';
export type ColorPickerButtonProps = Pick<ColorSampleProps, 'colorName'> &
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';
export type Props = {
type Props = {
title: string;
fullWidth?: boolean;
width?: number;
@@ -102,7 +102,7 @@ const StyledButton = styled.button<
}};
`;
export type MainButtonProps = Props & {
type MainButtonProps = Props & {
Icon?: IconComponent | FunctionComponent<{ size: number }>;
};
@@ -28,7 +28,7 @@ const StyledIconButton = styled.button<{ size: RoundedIconButtonSize }>`
width: ${({ size }) => (size === 'small' ? '20px' : '24px')};
`;
export type RoundedIconButtonProps = {
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';
export type TabButtonProps = {
type TabButtonProps = {
id: string;
active?: boolean;
disabled?: boolean;
@@ -10,7 +10,7 @@ import { isDefined } from 'twenty-shared/utils';
type CodeEditorVariant = 'default' | 'with-header' | 'borderless';
export type CodeEditorProps = Pick<
type CodeEditorProps = Pick<
EditorProps,
'value' | 'language' | 'onMount' | 'onValidate' | 'height' | 'options'
> & {
@@ -23,7 +23,7 @@ const StyledRadioContainer = styled.div`
top: ${({ theme }) => theme.spacing(2)};
`;
export type CardPickerProps = {
type CardPickerProps = {
children: React.ReactNode;
handleChange?: () => void;
checked?: boolean;
@@ -24,7 +24,7 @@ export enum CheckboxAccent {
Orange = 'orange',
}
export type CheckboxProps = {
type CheckboxProps = {
checked: boolean;
indeterminate?: boolean;
hoverable?: boolean;
@@ -38,7 +38,7 @@ export type CheckboxProps = {
accent?: CheckboxAccent;
};
export type InputProps = {
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';
export type IconListViewGripProps = Pick<IconComponentProps, 'size' | 'stroke'>;
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';
export type RadioGroupProps = React.PropsWithChildren & {
type RadioGroupProps = React.PropsWithChildren & {
value?: string;
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
onValueChange?: (value: string) => void;
+2 -16
View File
@@ -22,7 +22,6 @@ 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,
@@ -65,16 +64,9 @@ export type {
export { LightIconButton } from './button/components/LightIconButton';
export type { LightIconButtonGroupProps } from './button/components/LightIconButtonGroup';
export { LightIconButtonGroup } from './button/components/LightIconButtonGroup';
export type {
MainButtonVariant,
Props,
MainButtonProps,
} from './button/components/MainButton';
export type { MainButtonVariant } from './button/components/MainButton';
export { MainButton } from './button/components/MainButton';
export type {
RoundedIconButtonSize,
RoundedIconButtonProps,
} from './button/components/RoundedIconButton';
export type { RoundedIconButtonSize } from './button/components/RoundedIconButton';
export { RoundedIconButton } from './button/components/RoundedIconButton';
export {
StyledTabButton,
@@ -83,9 +75,7 @@ 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';
@@ -98,9 +88,7 @@ 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,
@@ -108,11 +96,9 @@ 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';
@@ -23,7 +23,7 @@ const StyledMotionContainer = styled(motion.div)<{
`}
`;
export type AnimatedExpandableContainerProps = {
type AnimatedExpandableContainerProps = {
children: ReactNode;
isExpanded: boolean;
dimension?: AnimationDimension;
@@ -39,7 +39,7 @@ export type AnimatedPlaceholderType =
| keyof typeof BACKGROUND
| keyof typeof MOVING_IMAGE;
export interface AnimatedPlaceholderProps {
interface AnimatedPlaceholderProps {
type: AnimatedPlaceholderType;
}
+1 -6
View File
@@ -7,7 +7,6 @@
* |___/
*/
export type { AnimatedExpandableContainerProps } from './animated-expandable-container/components/AnimatedExpandableContainer';
export { AnimatedExpandableContainer } from './animated-expandable-container/components/AnimatedExpandableContainer';
export type { AnimationDimension } from './animated-expandable-container/types/AnimationDimension';
export type { AnimationDurationObject } from './animated-expandable-container/types/AnimationDurationObject';
@@ -17,10 +16,7 @@ export type { AnimationSize } from './animated-expandable-container/types/Animat
export { getCommonStyles } from './animated-expandable-container/utils/getCommonStyles';
export { getExpandableAnimationConfig } from './animated-expandable-container/utils/getExpandableAnimationConfig';
export { getTransitionValues } from './animated-expandable-container/utils/getTransitionValues';
export type {
AnimatedPlaceholderType,
AnimatedPlaceholderProps,
} from './animated-placeholder/components/AnimatedPlaceholder';
export type { AnimatedPlaceholderType } from './animated-placeholder/components/AnimatedPlaceholder';
export { AnimatedPlaceholder } from './animated-placeholder/components/AnimatedPlaceholder';
export {
AnimatedPlaceholderEmptyContainer,
@@ -43,7 +39,6 @@ export { Card } from './card/components/Card';
export { CardContent } from './card/components/CardContent';
export { CardFooter } from './card/components/CardFooter';
export { CardHeader } from './card/components/CardHeader';
export type { SectionProps } from './section/components/Section';
export {
SectionAlignment,
SectionFontColor,

Some files were not shown because too many files have changed in this diff Show More