diff --git a/packages/twenty-front/src/modules/front-components/components/FrontComponentRenderer.tsx b/packages/twenty-front/src/modules/front-components/components/FrontComponentRenderer.tsx
index ff588847d9..7b45fb1703 100644
--- a/packages/twenty-front/src/modules/front-components/components/FrontComponentRenderer.tsx
+++ b/packages/twenty-front/src/modules/front-components/components/FrontComponentRenderer.tsx
@@ -1,10 +1,13 @@
+import { currentUserState } from '@/auth/states/currentUserState';
import { getMockFrontComponentUrl } from '@/front-components/utils/mockFrontComponent';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { useTheme } from '@emotion/react';
import { t } from '@lingui/core/macro';
import { useState } from 'react';
-import { FrontComponentRenderer as SharedFrontComponentRenderer } from 'twenty-sdk/front-component';
+import { useRecoilValue } from 'recoil';
+import { FrontComponentRenderer as SharedFrontComponentRenderer } from 'twenty-sdk/front-component/renderer';
import { isDefined } from 'twenty-shared/utils';
+
type FrontComponentRendererProps = {
frontComponentId: string;
};
@@ -16,6 +19,7 @@ export const FrontComponentRenderer = ({
const [hasError, setHasError] = useState(false);
const { enqueueErrorSnackBar } = useSnackBar();
+ const currentUser = useRecoilValue(currentUserState);
const handleError = (error?: Error) => {
if (isDefined(error)) {
@@ -36,6 +40,9 @@ export const FrontComponentRenderer = ({
);
diff --git a/packages/twenty-front/src/modules/front-components/utils/mockFrontComponent.ts b/packages/twenty-front/src/modules/front-components/utils/mockFrontComponent.ts
index 781e9b58ee..c8d3da9820 100644
--- a/packages/twenty-front/src/modules/front-components/utils/mockFrontComponent.ts
+++ b/packages/twenty-front/src/modules/front-components/utils/mockFrontComponent.ts
@@ -1,18 +1,107 @@
+/* eslint-disable */
import { isDefined } from 'twenty-shared/utils';
const mockFrontComponentCode = `
-const { jsx } = globalThis;
-const { TwentyUiButton } = globalThis.RemoteComponents;
+// react-globals:react
+var useState = globalThis.React.useState;
+var useEffect = globalThis.React.useEffect;
+var useSyncExternalStore = globalThis.React.useSyncExternalStore;
-export default jsx(TwentyUiButton, {
- variant: 'primary',
- disabled: false,
- fullWidth: false,
- onClick: () => {
- console.log('Button clicked');
- },
- title: 'Click me',
-});
+// react-globals:react/jsx-runtime
+var jsx = globalThis.jsx;
+var jsxs = globalThis.jsxs;
+var Fragment = globalThis.React.Fragment;
+
+// src/tata/test-component.front-component.tsx
+var RemoteComponents = globalThis.RemoteComponents;
+var getStore = () => {
+ const store = globalThis.frontComponentExecutionContextStore;
+ if (store === void 0) {
+ throw new Error(
+ "frontComponentExecutionContextStore not found on globalThis. This hook must be used within a front component running in the worker."
+ );
+ }
+ return store;
+};
+var useFrontComponentExecutionContext = () => {
+ const store = getStore();
+ return useSyncExternalStore(store.subscribe, store.getSnapshot);
+};
+var TestComponent = () => {
+ const [count, setCount] = useState(0);
+ const [timer, setTimer] = useState(0);
+ const context = useFrontComponentExecutionContext();
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setTimer((prevTimer) => prevTimer + 1);
+ }, 1e3);
+ return () => clearInterval(interval);
+ }, []);
+ return /* @__PURE__ */ jsxs(
+ RemoteComponents.HtmlDiv,
+ {
+ style: {
+ padding: "20px",
+ fontFamily: "Arial, sans-serif",
+ maxWidth: "400px",
+ margin: "0 auto",
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "center"
+ },
+ children: [
+ /* @__PURE__ */ jsx(RemoteComponents.HtmlH1, { style: { color: "#333", marginBottom: "20px", fontSize: "24px" }, children: "Test Component" }),
+ /* @__PURE__ */ jsxs(RemoteComponents.HtmlP, { style: { fontSize: "18px", marginBottom: "10px", color: "#666" }, children: [
+ "Count: ",
+ count
+ ] }),
+ /* @__PURE__ */ jsxs(RemoteComponents.HtmlP, { style: { fontSize: "18px", marginBottom: "20px", color: "#666" }, children: [
+ "Timer: ",
+ timer,
+ "s"
+ ] }),
+ /* @__PURE__ */ jsxs(RemoteComponents.HtmlP, { style: { fontSize: "18px", marginBottom: "20px", color: "#666" }, children: [
+ "User ID: ",
+ context?.userId
+ ] }),
+ /* @__PURE__ */ jsx(
+ RemoteComponents.HtmlButton,
+ {
+ onClick: () => setCount(count + 1),
+ style: {
+ padding: "10px 20px",
+ fontSize: "16px",
+ backgroundColor: "#007bff",
+ color: "white",
+ border: "none",
+ borderRadius: "5px",
+ cursor: "pointer",
+ transition: "all 0.3s ease",
+ boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
+ },
+ onMouseEnter: (e) => {
+ e.currentTarget.style.backgroundColor = "#0056b3";
+ e.currentTarget.style.transform = "translateY(-2px)";
+ e.currentTarget.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.3)";
+ },
+ onMouseLeave: (e) => {
+ e.currentTarget.style.backgroundColor = "#007bff";
+ e.currentTarget.style.transform = "translateY(0)";
+ e.currentTarget.style.boxShadow = "0 2px 4px rgba(0, 0, 0, 0.2)";
+ },
+ children: "Increment"
+ }
+ )
+ ]
+ }
+ );
+};
+var test_component_front_component_default = globalThis.jsx(TestComponent, {});
+export {
+ test_component_front_component_default as default,
+ useFrontComponentExecutionContext
+};
+//# sourceMappingURL=test-component.front-component.mjs.map
`;
let cachedMockBlobUrl: string | null = null;
diff --git a/packages/twenty-sdk/package.json b/packages/twenty-sdk/package.json
index aedcb772d4..8c6da6a97f 100644
--- a/packages/twenty-sdk/package.json
+++ b/packages/twenty-sdk/package.json
@@ -5,13 +5,12 @@
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"bin": {
- "twenty": "dist/cli/index.cjs"
+ "twenty": "dist/cli.cjs"
},
"files": [
"dist",
- "front-component",
- "front-component-constants",
- "ui"
+ "ui",
+ "front-component"
],
"scripts": {
"build": "npx rimraf dist && npx vite build",
@@ -32,20 +31,20 @@
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
- "./front-component": {
- "types": "./dist/front-component/index.d.ts",
- "import": "./dist/front-component/index.mjs",
- "require": "./dist/front-component/index.cjs"
- },
- "./front-component-constants": {
- "types": "./dist/front-component-constants/index.d.ts",
- "import": "./dist/front-component-constants/index.mjs",
- "require": "./dist/front-component-constants/index.cjs"
- },
"./ui": {
"types": "./dist/ui/index.d.ts",
"import": "./dist/ui/index.mjs",
"require": "./dist/ui/index.cjs"
+ },
+ "./front-component/renderer": {
+ "types": "./dist/front-component/renderer/index.d.ts",
+ "import": "./dist/front-component/renderer/index.mjs",
+ "require": "./dist/front-component/renderer/index.cjs"
+ },
+ "./front-component/api": {
+ "types": "./dist/front-component/api/index.d.ts",
+ "import": "./dist/front-component/api/index.mjs",
+ "require": "./dist/front-component/api/index.cjs"
}
},
"license": "AGPL-3.0",
@@ -105,14 +104,14 @@
},
"typesVersions": {
"*": {
- "front-component": [
- "dist/front-component/index.d.ts"
- ],
- "front-component-constants": [
- "dist/front-component-constants/index.d.ts"
- ],
"ui": [
"dist/ui/index.d.ts"
+ ],
+ "front-component/renderer": [
+ "dist/front-component/renderer/index.d.ts"
+ ],
+ "front-component/api": [
+ "dist/front-component/api/index.d.ts"
]
}
}
diff --git a/packages/twenty-sdk/project.json b/packages/twenty-sdk/project.json
index c5e7d72001..77da008d39 100644
--- a/packages/twenty-sdk/project.json
+++ b/packages/twenty-sdk/project.json
@@ -3,32 +3,15 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/twenty-sdk/src",
"projectType": "library",
- "tags": [
- "scope:sdk",
- "scope:shared"
- ],
+ "tags": ["scope:sdk", "scope:shared"],
"targets": {
"build": {
- "dependsOn": [
- "generateBarrels",
- "^build"
- ],
- "outputs": [
- "{projectRoot}/dist",
- "{projectRoot}/front-component/package.json",
- "{projectRoot}/front-component/dist",
- "{projectRoot}/front-component-constants/package.json",
- "{projectRoot}/front-component-constants/dist",
- "{projectRoot}/ui/package.json",
- "{projectRoot}/ui/dist"
- ]
+ "dependsOn": ["^build"],
+ "outputs": ["{projectRoot}/dist"]
},
"dev": {
"executor": "nx:run-commands",
- "dependsOn": [
- "generateBarrels",
- "^build"
- ],
+ "dependsOn": ["^build"],
"options": {
"cwd": "packages/twenty-sdk",
"command": "npx rimraf dist && npx vite build --watch"
@@ -36,43 +19,21 @@
},
"start": {
"executor": "nx:run-commands",
- "dependsOn": [
- "build"
- ],
+ "dependsOn": ["build"],
"options": {
"cwd": "packages/twenty-sdk",
"command": "node dist/cli.cjs"
}
},
- "generateBarrels": {
- "executor": "nx:run-commands",
- "cache": true,
- "inputs": [
- "production",
- "{projectRoot}/scripts/generateBarrels.ts"
- ],
- "outputs": [
- "{projectRoot}/src/index.ts",
- "{projectRoot}/src/*/index.ts",
- "{projectRoot}/package.json"
- ],
- "options": {
- "command": "tsx {projectRoot}/scripts/generateBarrels.ts"
- }
- },
"typecheck": {},
"lint": {
"options": {
- "lintFilePatterns": [
- "{projectRoot}/src/**/*.{ts,json}"
- ],
+ "lintFilePatterns": ["{projectRoot}/src/**/*.{ts,json}"],
"maxWarnings": 0
},
"configurations": {
"ci": {
- "lintFilePatterns": [
- "{projectRoot}/src/**/*.{ts,json}"
- ],
+ "lintFilePatterns": ["{projectRoot}/src/**/*.{ts,json}"],
"maxWarnings": 0
},
"fix": {}
@@ -80,9 +41,7 @@
},
"test": {
"executor": "@nx/vitest:test",
- "outputs": [
- "{workspaceRoot}/coverage/{projectRoot}"
- ],
+ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"config": "{projectRoot}/vitest.config.ts"
},
@@ -146,9 +105,7 @@
"storybook:prebuild": {
"executor": "nx:run-commands",
"cache": true,
- "dependsOn": [
- "generateRemoteDomElements"
- ],
+ "dependsOn": ["generateRemoteDomElements"],
"inputs": [
"{projectRoot}/src/front-component/__stories__/mocks/**/*",
"{projectRoot}/src/front-component/__stories__/utils/**/*",
@@ -156,25 +113,19 @@
"{projectRoot}/src/front-component-constants/**/*",
"{projectRoot}/src/sdk/**/*"
],
- "outputs": [
- "{projectRoot}/src/front-component/__stories__/built/*"
- ],
+ "outputs": ["{projectRoot}/src/front-component/__stories__/built/*"],
"options": {
"command": "tsx {projectRoot}/src/front-component/__stories__/utils/buildMockComponents.ts"
}
},
"storybook:build": {
- "dependsOn": [
- "storybook:prebuild"
- ],
+ "dependsOn": ["storybook:prebuild"],
"configurations": {
"test": {}
}
},
"storybook:serve:dev": {
- "dependsOn": [
- "storybook:prebuild"
- ],
+ "dependsOn": ["storybook:prebuild"],
"options": {
"port": 6008
}
@@ -189,17 +140,13 @@
}
},
"storybook:test": {
- "dependsOn": [
- "storybook:prebuild"
- ],
+ "dependsOn": ["storybook:prebuild"],
"options": {
"command": "vitest run --coverage --config vitest.storybook.config.ts --shard={args.shard}"
}
},
"storybook:test:no-coverage": {
- "dependsOn": [
- "storybook:prebuild"
- ],
+ "dependsOn": ["storybook:prebuild"],
"options": {
"command": "vitest run --config vitest.storybook.config.ts --shard={args.shard}"
}
diff --git a/packages/twenty-sdk/scripts/generateBarrels.ts b/packages/twenty-sdk/scripts/generateBarrels.ts
deleted file mode 100644
index 5c86bcf4a7..0000000000
--- a/packages/twenty-sdk/scripts/generateBarrels.ts
+++ /dev/null
@@ -1,559 +0,0 @@
-import prettier from '@prettier/sync';
-import * as fs from 'fs';
-import { globSync } from 'glob';
-import path from 'path';
-import { type Options } from 'prettier';
-import slash from 'slash';
-import ts from 'typescript';
-
-// TODO prastoin refactor this file in several one into its dedicated package and make it a TypeScript CLI
-
-const INDEX_FILENAME = 'index';
-const PACKAGE_JSON_FILENAME = 'package.json';
-const NX_PROJECT_CONFIGURATION_FILENAME = 'project.json';
-const PACKAGE_PATH = path.resolve('packages/twenty-sdk');
-const SRC_PATH = path.resolve(`${PACKAGE_PATH}/src`);
-const PACKAGE_JSON_PATH = path.join(PACKAGE_PATH, PACKAGE_JSON_FILENAME);
-const NX_PROJECT_CONFIGURATION_PATH = path.join(
- PACKAGE_PATH,
- NX_PROJECT_CONFIGURATION_FILENAME,
-);
-const EXCLUDED_EXTENSIONS = [
- '**/*.test.ts',
- '**/*.test.tsx',
- '**/*.spec.ts',
- '**/*.spec.tsx',
- '**/*.stories.ts',
- '**/*.stories.tsx',
-] as const;
-const EXCLUDED_DIRECTORIES = [
- '**/__tests__/**',
- '**/__mocks__/**',
- '**/__stories__/**',
- '**/internal/**',
- '**/cli/**',
-] as const;
-const ROOT_DIRECTORIES = ['sdk'];
-
-// Modules that re-export from external packages instead of local files
-const EXTERNAL_REEXPORT_MODULES: Record = {
- ui: `export * from 'twenty-ui';
-export * from 'twenty-ui/accessibility';
-export * from 'twenty-ui/components';
-export * from 'twenty-ui/display';
-export * from 'twenty-ui/feedback';
-export * from 'twenty-ui/input';
-export * from 'twenty-ui/json-visualizer';
-export * from 'twenty-ui/layout';
-export * from 'twenty-ui/navigation';
-export * from 'twenty-ui/theme';
-export * from 'twenty-ui/utilities';`,
-};
-
-const prettierConfigFile = prettier.resolveConfigFile();
-if (prettierConfigFile == null) {
- throw new Error('Prettier config file not found');
-}
-const prettierConfiguration = prettier.resolveConfig(prettierConfigFile);
-const prettierFormat = (str: string, parser: Options['parser']) =>
- prettier.format(str, {
- ...prettierConfiguration,
- parser,
- });
-type createTypeScriptFileArgs = {
- path: string;
- content: string;
- filename: string;
-};
-const createTypeScriptFile = ({
- content,
- path: filePath,
- filename,
-}: createTypeScriptFileArgs) => {
- const header = `
-/*
- * _____ _
- *|_ _|_ _____ _ __ | |_ _ _
- * | | \\ \\ /\\ / / _ \\ '_ \\| __| | | | Auto-generated file
- * | | \\ V V / __/ | | | |_| |_| | Any edits to this will be overridden
- * |_| \\_/\\_/ \\___|_| |_|\\__|\\__, |
- * |___/
- */
-`;
- const formattedContent = prettierFormat(
- `${header}\n${content}\n`,
- 'typescript',
- );
- fs.writeFileSync(
- path.join(filePath, `${filename}.ts`),
- formattedContent,
- 'utf-8',
- );
-};
-
-const getLastPathFolder = (pathStr: string) => path.basename(pathStr);
-
-const getSubDirectoryPaths = (directoryPath: string): string[] => {
- const pattern = slash(path.join(directoryPath, '*/'));
- return globSync(pattern, {
- ignore: [...EXCLUDED_DIRECTORIES],
- cwd: SRC_PATH,
- nodir: false,
- maxDepth: 1,
- }).sort((a, b) => a.localeCompare(b));
-};
-
-const partitionFileExportsByType = (declarations: DeclarationOccurrence[]) => {
- return declarations.reduce<{
- typeAndInterfaceDeclarations: DeclarationOccurrence[];
- otherDeclarations: DeclarationOccurrence[];
- }>(
- (acc, { kind, name }) => {
- if (kind === 'type' || kind === 'interface') {
- return {
- ...acc,
- typeAndInterfaceDeclarations: [
- ...acc.typeAndInterfaceDeclarations,
- { kind, name },
- ],
- };
- }
-
- return {
- ...acc,
- otherDeclarations: [...acc.otherDeclarations, { kind, name }],
- };
- },
- {
- typeAndInterfaceDeclarations: [],
- otherDeclarations: [],
- },
- );
-};
-
-const generateModuleIndexFiles = (exportByBarrel: ExportByBarrel[]) => {
- return exportByBarrel.map(
- ({ barrel: { moduleDirectory }, allFileExports }) => {
- const content = allFileExports
- .sort((a, b) => a.file.localeCompare(b.file))
- .map(({ exports, file }) => {
- const { otherDeclarations, typeAndInterfaceDeclarations } =
- partitionFileExportsByType(exports);
-
- const fileWithoutExtension = path.parse(file).name;
- const pathToImport = slash(
- path.relative(
- moduleDirectory,
- path.join(path.dirname(file), fileWithoutExtension),
- ),
- );
- const mapDeclarationNameAndJoin = (
- declarations: DeclarationOccurrence[],
- ) => declarations.map(({ name }) => name).join(', ');
-
- const typeExport =
- typeAndInterfaceDeclarations.length > 0
- ? `export type { ${mapDeclarationNameAndJoin(typeAndInterfaceDeclarations)} } from "./${pathToImport}"`
- : '';
- const othersExport =
- otherDeclarations.length > 0
- ? `export { ${mapDeclarationNameAndJoin(otherDeclarations)} } from "./${pathToImport}"`
- : '';
-
- return [typeExport, othersExport]
- .filter((el) => el !== '')
- .join('\n');
- })
- .join('\n');
-
- return {
- content,
- path: moduleDirectory,
- filename: INDEX_FILENAME,
- };
- },
- );
-};
-
-type JsonUpdate = Record;
-type WriteInJsonFileArgs = {
- content: JsonUpdate;
- file: string;
-};
-const updateJsonFile = ({ content, file }: WriteInJsonFileArgs) => {
- const updatedJsonFile = JSON.stringify(content);
- const formattedContent = prettierFormat(updatedJsonFile, 'json-stringify');
- fs.writeFileSync(file, formattedContent, 'utf-8');
-};
-
-const writeInPackageJson = (update: JsonUpdate) => {
- const rawJsonFile = fs.readFileSync(PACKAGE_JSON_PATH, 'utf-8');
- const initialJsonFile = JSON.parse(rawJsonFile);
-
- updateJsonFile({
- file: PACKAGE_JSON_PATH,
- content: {
- ...initialJsonFile,
- ...update,
- },
- });
-};
-
-const updateNxProjectConfigurationBuildOutputs = (outputs: JsonUpdate) => {
- const rawJsonFile = fs.readFileSync(NX_PROJECT_CONFIGURATION_PATH, 'utf-8');
- const initialJsonFile = JSON.parse(rawJsonFile);
-
- updateJsonFile({
- file: NX_PROJECT_CONFIGURATION_PATH,
- content: {
- ...initialJsonFile,
- targets: {
- ...initialJsonFile.targets,
- build: {
- ...initialJsonFile.targets.build,
- outputs,
- },
- },
- },
- });
-};
-
-type ExportOccurrence = {
- types: string;
- import: string;
- require: string;
-};
-type ExportsConfig = Record;
-
-const generateModulePackageExports = (moduleDirectories: string[]) => {
- return moduleDirectories.reduce((acc, moduleDirectory) => {
- const moduleName = getLastPathFolder(moduleDirectory);
- if (moduleName === undefined) {
- throw new Error(
- `Should never occur, moduleName is undefined ${moduleDirectory}`,
- );
- }
-
- return {
- ...acc,
- [`./${moduleName}`]: {
- types: `./dist/${moduleName}/index.d.ts`,
- import: `./dist/${moduleName}/index.mjs`,
- require: `./dist/${moduleName}/index.cjs`,
- },
- };
- }, {});
-};
-
-const computePackageJsonFilesAndExportsConfig = (
- moduleDirectories: string[],
-) => {
- const entrypoints = moduleDirectories.map(getLastPathFolder);
- const exports = {
- '.': {
- types: './dist/index.d.ts',
- import: './dist/index.mjs',
- require: './dist/index.cjs',
- },
- ...generateModulePackageExports(moduleDirectories),
- } satisfies ExportsConfig;
-
- const typesVersionsEntries = entrypoints.reduce>(
- (acc, moduleName) => ({
- ...acc,
- [`${moduleName}`]: [`dist/${moduleName}/index.d.ts`],
- }),
- {},
- );
-
- return {
- exports,
- typesVersions: { '*': typesVersionsEntries },
- files: ['dist', ...entrypoints],
- };
-};
-
-const computeProjectNxBuildOutputsPath = (moduleDirectories: string[]) => {
- const dynamicOutputsPath = moduleDirectories
- .map(getLastPathFolder)
- .flatMap((barrelName) =>
- ['package.json', 'dist'].map(
- (subPath) => `{projectRoot}/${barrelName}/${subPath}`,
- ),
- );
-
- return ['{projectRoot}/dist', ...dynamicOutputsPath];
-};
-
-const getTypeScriptFiles = (
- directoryPath: string,
- includeIndex: boolean = false,
-): string[] => {
- const pattern = slash(path.join(directoryPath, '**', '*.{ts,tsx}'));
- const files = globSync(pattern, {
- cwd: SRC_PATH,
- nodir: true,
- ignore: [...EXCLUDED_EXTENSIONS, ...EXCLUDED_DIRECTORIES],
- });
-
- return files.filter(
- (file) =>
- !file.endsWith('.d.ts') &&
- (includeIndex ? true : !file.endsWith('index.ts')),
- );
-};
-
-const getKind = (
- node: ts.VariableStatement,
-): Extract => {
- const isConst = (node.declarationList.flags & ts.NodeFlags.Const) !== 0;
- if (isConst) {
- return 'const';
- }
-
- const isLet = (node.declarationList.flags & ts.NodeFlags.Let) !== 0;
- if (isLet) {
- return 'let';
- }
-
- return 'var';
-};
-
-const extractExportsFromSourceFile = (sourceFile: ts.SourceFile) => {
- const exports: DeclarationOccurrence[] = [];
-
- const visit = (node: ts.Node) => {
- if (!ts.canHaveModifiers(node)) {
- ts.forEachChild(node, visit);
- return;
- }
- const modifiers = ts.getModifiers(node);
- const isExport = modifiers?.some(
- (mod) => mod.kind === ts.SyntaxKind.ExportKeyword,
- );
-
- if (!isExport && !ts.isExportDeclaration(node)) {
- ts.forEachChild(node, visit);
- return;
- }
-
- switch (true) {
- case ts.isTypeAliasDeclaration(node):
- exports.push({
- kind: 'type',
- name: node.name.text,
- });
- break;
-
- case ts.isInterfaceDeclaration(node):
- exports.push({
- kind: 'interface',
- name: node.name.text,
- });
- break;
-
- case ts.isEnumDeclaration(node):
- exports.push({
- kind: 'enum',
- name: node.name.text,
- });
- break;
-
- case ts.isFunctionDeclaration(node) && node.name !== undefined:
- exports.push({
- kind: 'function',
- name: node.name.text,
- });
- break;
-
- case ts.isVariableStatement(node):
- node.declarationList.declarations.forEach((decl) => {
- const kind = getKind(node);
-
- if (ts.isIdentifier(decl.name)) {
- exports.push({
- kind,
- name: decl.name.text,
- });
- } else if (ts.isObjectBindingPattern(decl.name)) {
- decl.name.elements.forEach((element) => {
- if (
- !ts.isBindingElement(element) ||
- !ts.isIdentifier(element.name)
- ) {
- return;
- }
-
- exports.push({
- kind,
- name: element.name.text,
- });
- });
- }
- });
- break;
-
- case ts.isClassDeclaration(node) && node.name !== undefined:
- exports.push({
- kind: 'class',
- name: node.name.text,
- });
- break;
- case ts.isExportDeclaration(node):
- if (node.exportClause && ts.isNamedExports(node.exportClause)) {
- node.exportClause.elements.forEach((element) => {
- const exportName = element.name.text;
-
- // Check both the declaration and the individual specifier for type-only exports
- const isTypeExport =
- node.isTypeOnly || ts.isTypeOnlyExportDeclaration(node);
- if (isTypeExport) {
- // should handle kind
- exports.push({
- kind: 'type',
- name: exportName,
- });
- return;
- }
-
- exports.push({
- kind: 'const',
- name: exportName,
- });
- });
- }
- break;
- }
- ts.forEachChild(node, visit);
- };
-
- visit(sourceFile);
- return exports;
-};
-
-type ExportKind =
- | 'type'
- | 'interface'
- | 'enum'
- | 'function'
- | 'const'
- | 'let'
- | 'var'
- | 'class';
-type DeclarationOccurrence = { kind: ExportKind; name: string };
-type FileExports = Array<{
- file: string;
- exports: DeclarationOccurrence[];
-}>;
-
-const findAllExports = (directoryPath: string): FileExports => {
- const results: FileExports = [];
-
- const files = getTypeScriptFiles(directoryPath);
-
- for (const file of files) {
- const sourceFile = ts.createSourceFile(
- file,
- fs.readFileSync(file, 'utf8'),
- ts.ScriptTarget.Latest,
- true,
- );
-
- const exports = extractExportsFromSourceFile(sourceFile);
- if (exports.length > 0) {
- results.push({
- file,
- exports,
- });
- }
- }
-
- return results;
-};
-
-type ExportByBarrel = {
- barrel: {
- moduleName: string;
- moduleDirectory: string;
- };
- allFileExports: FileExports;
-};
-const retrieveExportsByBarrel = (barrelDirectories: string[]) => {
- return barrelDirectories.map((moduleDirectory) => {
- const moduleExportsPerFile = findAllExports(moduleDirectory);
- const moduleName = getLastPathFolder(moduleDirectory);
- if (!moduleName) {
- throw new Error(
- `Should never occur moduleName not found ${moduleDirectory}`,
- );
- }
-
- return {
- barrel: {
- moduleName,
- moduleDirectory,
- },
- allFileExports: moduleExportsPerFile,
- };
- });
-};
-
-const main = () => {
- const moduleDirectories = getSubDirectoryPaths(SRC_PATH);
-
- const rootDirectory = moduleDirectories.find((dir) =>
- ROOT_DIRECTORIES.includes(getLastPathFolder(dir)),
- );
-
- // Separate modules that re-export from external packages
- const externalReexportModuleNames = Object.keys(EXTERNAL_REEXPORT_MODULES);
- const localModuleDirectories = moduleDirectories.filter(
- (dir) => !externalReexportModuleNames.includes(getLastPathFolder(dir)),
- );
-
- const otherBarrelDirectories = moduleDirectories.filter(
- (dir) => !ROOT_DIRECTORIES.includes(getLastPathFolder(dir)),
- );
-
- const exportsByBarrel = retrieveExportsByBarrel(localModuleDirectories);
- const moduleIndexFiles = generateModuleIndexFiles(exportsByBarrel);
-
- const packageJsonConfig = computePackageJsonFilesAndExportsConfig(
- otherBarrelDirectories,
- );
- const nxBuildOutputsPath = computeProjectNxBuildOutputsPath(
- otherBarrelDirectories,
- );
-
- updateNxProjectConfigurationBuildOutputs(nxBuildOutputsPath);
- writeInPackageJson(packageJsonConfig);
- moduleIndexFiles.forEach(createTypeScriptFile);
-
- // Generate index files for modules that re-export from external packages
- for (const [moduleName, content] of Object.entries(
- EXTERNAL_REEXPORT_MODULES,
- )) {
- const moduleDirectory = path.join(SRC_PATH, moduleName);
- if (!fs.existsSync(moduleDirectory)) {
- fs.mkdirSync(moduleDirectory, { recursive: true });
- }
- createTypeScriptFile({
- path: moduleDirectory,
- filename: INDEX_FILENAME,
- content,
- });
- }
-
- // Ensure top-level src/index.ts re-exports the root directories barrel so consumers can `import * from "twenty-sdk"`
- // We intentionally keep this file minimal: it delegates to the generated src//index.ts
- if (rootDirectory) {
- createTypeScriptFile({
- path: SRC_PATH,
- filename: INDEX_FILENAME,
- content: ROOT_DIRECTORIES.map(
- (rootDirectory) => `export * from "./${rootDirectory}";`,
- ).join('\n'),
- });
- }
-};
-main();
diff --git a/packages/twenty-sdk/scripts/remote-dom/generateRemoteDomElements.ts b/packages/twenty-sdk/scripts/remote-dom/generateRemoteDomElements.ts
index ebaa64215b..8048c13faa 100644
--- a/packages/twenty-sdk/scripts/remote-dom/generateRemoteDomElements.ts
+++ b/packages/twenty-sdk/scripts/remote-dom/generateRemoteDomElements.ts
@@ -3,11 +3,11 @@ import * as fs from 'fs';
import * as path from 'path';
import { IndentationText, Project, QuoteKind } from 'ts-morph';
-import { ALLOWED_HTML_ELEMENTS } from '../../src/front-component-constants/AllowedHtmlElements';
-import { ALLOWED_UI_COMPONENTS } from '../../src/front-component-constants/AllowedUiComponents';
-import { COMMON_HTML_EVENTS } from '../../src/front-component-constants/CommonHtmlEvents';
-import { EVENT_TO_REACT } from '../../src/front-component-constants/EventToReact';
-import { HTML_COMMON_PROPERTIES } from '../../src/front-component-constants/HtmlCommonProperties';
+import { ALLOWED_HTML_ELEMENTS } from '../../src/front-component/common/AllowedHtmlElements';
+import { ALLOWED_UI_COMPONENTS } from '../../src/front-component/common/AllowedUiComponents';
+import { COMMON_HTML_EVENTS } from '../../src/front-component/common/CommonHtmlEvents';
+import { EVENT_TO_REACT } from '../../src/front-component/common/EventToReact';
+import { HTML_COMMON_PROPERTIES } from '../../src/front-component/common/HtmlCommonProperties';
import {
type ComponentSchema,
diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/utils/replace-html-tags-with-remote-components.ts b/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/utils/replace-html-tags-with-remote-components.ts
index 5bbd4183d1..c3b7f6e50d 100644
--- a/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/utils/replace-html-tags-with-remote-components.ts
+++ b/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/utils/replace-html-tags-with-remote-components.ts
@@ -1,6 +1,6 @@
import { isDefined } from 'twenty-shared/utils';
-import { HTML_TAG_TO_REMOTE_COMPONENT } from '../../../../../../front-component-constants';
+import { HTML_TAG_TO_REMOTE_COMPONENT } from '../../../../../../front-component/common';
const REMOTE_COMPONENTS_GLOBAL_NAMESPACE = 'RemoteComponents';
diff --git a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts
index 57899c129b..20c3a4f7f8 100644
--- a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts
+++ b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts
@@ -6,11 +6,12 @@ import {
} from '@/cli/utilities/build/manifest/manifest-extract-config';
import { extractManifestFromFile } from '@/cli/utilities/build/manifest/manifest-extract-config-from-file';
import {
+ type ApplicationConfig,
type FrontComponentConfig,
type LogicFunctionConfig,
- type ApplicationConfig,
} from '@/sdk';
import { glob } from 'fast-glob';
+import * as fs from 'fs-extra';
import { readFile } from 'fs-extra';
import { basename, extname, relative, sep } from 'path';
import {
@@ -24,9 +25,8 @@ import {
type ObjectManifest,
type RoleManifest,
} from 'twenty-shared/application';
-import { assertUnreachable } from 'twenty-shared/utils';
import { type Sources } from 'twenty-shared/types';
-import * as fs from 'fs-extra';
+import { assertUnreachable } from 'twenty-shared/utils';
const loadSources = async (appPath: string): Promise => {
return await glob(['**/*.ts', '**/*.tsx'], {
diff --git a/packages/twenty-sdk/src/front-component/__stories__/FrontComponentRenderer.stories.tsx b/packages/twenty-sdk/src/front-component/__stories__/FrontComponentRenderer.stories.tsx
index 55d3e601dd..a80e94548f 100644
--- a/packages/twenty-sdk/src/front-component/__stories__/FrontComponentRenderer.stories.tsx
+++ b/packages/twenty-sdk/src/front-component/__stories__/FrontComponentRenderer.stories.tsx
@@ -1,7 +1,7 @@
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
-import { FrontComponentRenderer } from '../host/components/FrontComponentRenderer';
+import { FrontComponentRenderer } from '../renderer/host/components/FrontComponentRenderer';
import { getBuiltComponentPath } from './utils/loadBuiltComponent';
diff --git a/packages/twenty-sdk/src/front-component/api/hooks/useFrontComponentExecutionContext.ts b/packages/twenty-sdk/src/front-component/api/hooks/useFrontComponentExecutionContext.ts
new file mode 100644
index 0000000000..c89b322569
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/api/hooks/useFrontComponentExecutionContext.ts
@@ -0,0 +1,26 @@
+import { useSyncExternalStore } from 'react';
+import { type FrontComponentExecutionContext } from '../types/FrontComponentExecutionContext';
+import { type FrontComponentExecutionContextStore } from '../types/FrontComponentExecutionContextStore';
+
+const getStore = (): FrontComponentExecutionContextStore => {
+ const store = (globalThis as Record)
+ .frontComponentExecutionContextStore as
+ | FrontComponentExecutionContextStore
+ | undefined;
+
+ if (store === undefined) {
+ throw new Error(
+ 'frontComponentExecutionContextStore not found on globalThis. This hook must be used within a front component running in the worker.',
+ );
+ }
+
+ return store;
+};
+
+export const useFrontComponentExecutionContext = ():
+ | FrontComponentExecutionContext
+ | undefined => {
+ const store = getStore();
+
+ return useSyncExternalStore(store.subscribe, store.getSnapshot);
+};
diff --git a/packages/twenty-sdk/src/front-component/api/index.ts b/packages/twenty-sdk/src/front-component/api/index.ts
new file mode 100644
index 0000000000..fc03b9744d
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/api/index.ts
@@ -0,0 +1,3 @@
+export { useFrontComponentExecutionContext } from './hooks/useFrontComponentExecutionContext';
+export type { FrontComponentExecutionContext } from './types/FrontComponentExecutionContext';
+export type { FrontComponentExecutionContextStore } from './types/FrontComponentExecutionContextStore';
diff --git a/packages/twenty-sdk/src/front-component/api/types/FrontComponentExecutionContext.ts b/packages/twenty-sdk/src/front-component/api/types/FrontComponentExecutionContext.ts
new file mode 100644
index 0000000000..0b6fb8874e
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/api/types/FrontComponentExecutionContext.ts
@@ -0,0 +1,3 @@
+export type FrontComponentExecutionContext = {
+ userId: string;
+};
diff --git a/packages/twenty-sdk/src/front-component/api/types/FrontComponentExecutionContextStore.ts b/packages/twenty-sdk/src/front-component/api/types/FrontComponentExecutionContextStore.ts
new file mode 100644
index 0000000000..bcc043399c
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/api/types/FrontComponentExecutionContextStore.ts
@@ -0,0 +1,6 @@
+import { type FrontComponentExecutionContext } from './FrontComponentExecutionContext';
+
+export type FrontComponentExecutionContextStore = {
+ getSnapshot: () => FrontComponentExecutionContext | undefined;
+ subscribe: (listener: () => void) => () => void;
+};
diff --git a/packages/twenty-sdk/src/front-component-constants/AllowedHtmlElements.ts b/packages/twenty-sdk/src/front-component/common/AllowedHtmlElements.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component-constants/AllowedHtmlElements.ts
rename to packages/twenty-sdk/src/front-component/common/AllowedHtmlElements.ts
diff --git a/packages/twenty-sdk/src/front-component-constants/AllowedUiComponents.ts b/packages/twenty-sdk/src/front-component/common/AllowedUiComponents.ts
similarity index 89%
rename from packages/twenty-sdk/src/front-component-constants/AllowedUiComponents.ts
rename to packages/twenty-sdk/src/front-component/common/AllowedUiComponents.ts
index b9fb719a75..f13da74d43 100644
--- a/packages/twenty-sdk/src/front-component-constants/AllowedUiComponents.ts
+++ b/packages/twenty-sdk/src/front-component/common/AllowedUiComponents.ts
@@ -1,4 +1,4 @@
-import { type PropertySchema } from '../front-component/types/PropertySchema';
+import { type PropertySchema } from '../renderer/types/PropertySchema';
export type AllowedUiComponent = {
tag: string;
diff --git a/packages/twenty-sdk/src/front-component-constants/CommonHtmlEvents.ts b/packages/twenty-sdk/src/front-component/common/CommonHtmlEvents.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component-constants/CommonHtmlEvents.ts
rename to packages/twenty-sdk/src/front-component/common/CommonHtmlEvents.ts
diff --git a/packages/twenty-sdk/src/front-component-constants/EventToReact.ts b/packages/twenty-sdk/src/front-component/common/EventToReact.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component-constants/EventToReact.ts
rename to packages/twenty-sdk/src/front-component/common/EventToReact.ts
diff --git a/packages/twenty-sdk/src/front-component-constants/HtmlCommonProperties.ts b/packages/twenty-sdk/src/front-component/common/HtmlCommonProperties.ts
similarity index 86%
rename from packages/twenty-sdk/src/front-component-constants/HtmlCommonProperties.ts
rename to packages/twenty-sdk/src/front-component/common/HtmlCommonProperties.ts
index 29c0e25d70..12dfc40e41 100644
--- a/packages/twenty-sdk/src/front-component-constants/HtmlCommonProperties.ts
+++ b/packages/twenty-sdk/src/front-component/common/HtmlCommonProperties.ts
@@ -1,4 +1,4 @@
-import { type PropertySchema } from '../front-component/types/PropertySchema';
+import { type PropertySchema } from '../renderer/types/PropertySchema';
export const HTML_COMMON_PROPERTIES: Record = {
id: { type: 'string', optional: true },
diff --git a/packages/twenty-sdk/src/front-component-constants/HtmlTagToRemoteComponent.ts b/packages/twenty-sdk/src/front-component/common/HtmlTagToRemoteComponent.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component-constants/HtmlTagToRemoteComponent.ts
rename to packages/twenty-sdk/src/front-component/common/HtmlTagToRemoteComponent.ts
diff --git a/packages/twenty-sdk/src/front-component-constants/index.ts b/packages/twenty-sdk/src/front-component/common/index.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component-constants/index.ts
rename to packages/twenty-sdk/src/front-component/common/index.ts
diff --git a/packages/twenty-sdk/src/front-component/host/components/FrontComponentRenderer.tsx b/packages/twenty-sdk/src/front-component/host/components/FrontComponentRenderer.tsx
deleted file mode 100644
index a34a877662..0000000000
--- a/packages/twenty-sdk/src/front-component/host/components/FrontComponentRenderer.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import {
- type RemoteReceiver,
- RemoteRootRenderer,
-} from '@remote-dom/react/host';
-import { useState } from 'react';
-import { isDefined } from 'twenty-shared/utils';
-
-import { ThemeProvider } from '@emotion/react';
-import { type ThemeType } from 'twenty-ui/theme';
-import { FrontComponentWorkerEffect } from '../../remote/components/FrontComponentWorkerEffect';
-import { componentRegistry } from '../generated/host-component-registry';
-
-type FrontComponentContentProps = {
- componentUrl: string;
- onError: (error?: Error) => void;
- theme: ThemeType;
-};
-
-export const FrontComponentRenderer = ({
- componentUrl,
- onError,
- theme,
-}: FrontComponentContentProps) => {
- const [receiver, setReceiver] = useState(null);
-
- return (
- <>
-
-
- {isDefined(receiver) && (
-
-
-
- )}
- >
- );
-};
diff --git a/packages/twenty-sdk/src/front-component/renderer/host/components/FrontComponentRenderer.tsx b/packages/twenty-sdk/src/front-component/renderer/host/components/FrontComponentRenderer.tsx
new file mode 100644
index 0000000000..7d99bdefd0
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/renderer/host/components/FrontComponentRenderer.tsx
@@ -0,0 +1,73 @@
+import { FrontComponentErrorEffect } from '@/front-component/renderer/remote/components/FrontComponentErrorEffect';
+import { FrontComponentUpdateContextEffect } from '@/front-component/renderer/remote/components/FrontComponentUpdateContextEffect';
+import { type FrontComponentExecutionContext } from '@/front-component/renderer/types/FrontComponentExecutionContext';
+import { type WorkerExports } from '@/front-component/renderer/types/WorkerExports';
+import { type ThreadWebWorker } from '@quilted/threads';
+import {
+ type RemoteReceiver,
+ RemoteRootRenderer,
+} from '@remote-dom/react/host';
+import { useMemo, useState } from 'react';
+import { isDefined } from 'twenty-shared/utils';
+
+import { ThemeProvider } from '@emotion/react';
+import { type ThemeType } from 'twenty-ui/theme';
+import { FrontComponentWorkerEffect } from '../../remote/components/FrontComponentWorkerEffect';
+import { componentRegistry } from '../generated/host-component-registry';
+
+type FrontComponentContentProps = {
+ componentUrl: string;
+ executionContext: FrontComponentExecutionContext;
+ onError: (error?: Error) => void;
+ theme: ThemeType;
+};
+
+export const FrontComponentRenderer = ({
+ componentUrl,
+ executionContext,
+ onError,
+ theme,
+}: FrontComponentContentProps) => {
+ const [receiver, setReceiver] = useState(null);
+ const [thread, setThread] = useState | null>(
+ null,
+ );
+ const [error, setError] = useState(null);
+
+ const MemoizedFrontComponentWorkerEffect = useMemo(() => {
+ return (
+
+ );
+ }, [componentUrl, setError, setReceiver, setThread]);
+
+ return (
+ <>
+ {MemoizedFrontComponentWorkerEffect}
+
+ {isDefined(error) && (
+
+ )}
+
+ {isDefined(thread) && (
+
+ )}
+
+ {isDefined(receiver) && (
+
+
+
+ )}
+ >
+ );
+};
diff --git a/packages/twenty-sdk/src/front-component/renderer/host/generated/host-component-registry.ts b/packages/twenty-sdk/src/front-component/renderer/host/generated/host-component-registry.ts
new file mode 100644
index 0000000000..5668035e9e
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/renderer/host/generated/host-component-registry.ts
@@ -0,0 +1,405 @@
+/*
+ * _____ _
+ *|_ _|_ _____ _ __ | |_ _ _
+ * | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
+ * | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
+ * |_| \_/\_/ \___|_| |_|\__|\__, |
+ * |___/
+ */
+
+import React from 'react';
+import {
+ RemoteFragmentRenderer,
+ createRemoteComponentRenderer,
+} from '@remote-dom/react/host';
+import { Button } from 'twenty-ui/input';
+const INTERNAL_PROPS = new Set(['element', 'receiver', 'components']);
+
+const EVENT_NAME_MAP: Record = {
+ onclick: 'onClick',
+ ondblclick: 'onDoubleClick',
+ onmousedown: 'onMouseDown',
+ onmouseup: 'onMouseUp',
+ onmouseover: 'onMouseOver',
+ onmouseout: 'onMouseOut',
+ onmouseenter: 'onMouseEnter',
+ onmouseleave: 'onMouseLeave',
+ onkeydown: 'onKeyDown',
+ onkeyup: 'onKeyUp',
+ onkeypress: 'onKeyPress',
+ onfocus: 'onFocus',
+ onblur: 'onBlur',
+ onchange: 'onChange',
+ oninput: 'onInput',
+ onsubmit: 'onSubmit',
+ onscroll: 'onScroll',
+ onwheel: 'onWheel',
+ oncontextmenu: 'onContextMenu',
+ ondrag: 'onDrag',
+};
+
+const parseStyle = (
+ styleString: string | undefined,
+): React.CSSProperties | undefined => {
+ if (!styleString || typeof styleString !== 'string') {
+ return styleString as React.CSSProperties | undefined;
+ }
+
+ const style: Record = {};
+ const declarations = styleString.split(';').filter(Boolean);
+
+ for (const declaration of declarations) {
+ const colonIndex = declaration.indexOf(':');
+ if (colonIndex === -1) continue;
+
+ const property = declaration.slice(0, colonIndex).trim();
+ const value = declaration.slice(colonIndex + 1).trim();
+
+ const camelProperty = property.replace(/-([a-z])/g, (_, letter: string) =>
+ letter.toUpperCase(),
+ );
+ style[camelProperty] = value;
+ }
+
+ return style;
+};
+
+const wrapEventHandler = (handler: () => void) => {
+ return (_event: unknown) => {
+ handler();
+ };
+};
+
+const filterProps = (props: Record) => {
+ const filtered: Record = {};
+ 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 {
+ const normalizedKey = EVENT_NAME_MAP[key.toLowerCase()] || key;
+ if (normalizedKey.startsWith('on') && typeof value === 'function') {
+ filtered[normalizedKey] = wrapEventHandler(value as () => void);
+ } else {
+ filtered[normalizedKey] = value;
+ }
+ }
+ }
+ return filtered;
+};
+const HtmlDivWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('div', filterProps(props), children);
+};
+const HtmlSpanWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('span', filterProps(props), children);
+};
+const HtmlSectionWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('section', filterProps(props), children);
+};
+const HtmlArticleWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('article', filterProps(props), children);
+};
+const HtmlHeaderWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('header', filterProps(props), children);
+};
+const HtmlFooterWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('footer', filterProps(props), children);
+};
+const HtmlMainWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('main', filterProps(props), children);
+};
+const HtmlNavWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('nav', filterProps(props), children);
+};
+const HtmlAsideWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('aside', filterProps(props), children);
+};
+const HtmlPWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('p', filterProps(props), children);
+};
+const HtmlH1Wrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('h1', filterProps(props), children);
+};
+const HtmlH2Wrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('h2', filterProps(props), children);
+};
+const HtmlH3Wrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('h3', filterProps(props), children);
+};
+const HtmlH4Wrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('h4', filterProps(props), children);
+};
+const HtmlH5Wrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('h5', filterProps(props), children);
+};
+const HtmlH6Wrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('h6', filterProps(props), children);
+};
+const HtmlStrongWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('strong', filterProps(props), children);
+};
+const HtmlEmWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('em', filterProps(props), children);
+};
+const HtmlSmallWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('small', filterProps(props), children);
+};
+const HtmlCodeWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('code', filterProps(props), children);
+};
+const HtmlPreWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('pre', filterProps(props), children);
+};
+const HtmlBlockquoteWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('blockquote', filterProps(props), children);
+};
+const HtmlAWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('a', filterProps(props), children);
+};
+const HtmlImgWrapper = ({
+ children: _children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('img', filterProps(props));
+};
+const HtmlUlWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('ul', filterProps(props), children);
+};
+const HtmlOlWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('ol', filterProps(props), children);
+};
+const HtmlLiWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('li', filterProps(props), children);
+};
+const HtmlFormWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('form', filterProps(props), children);
+};
+const HtmlLabelWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('label', filterProps(props), children);
+};
+const HtmlInputWrapper = ({
+ children: _children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('input', filterProps(props));
+};
+const HtmlTextareaWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('textarea', filterProps(props), children);
+};
+const HtmlSelectWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('select', filterProps(props), children);
+};
+const HtmlOptionWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('option', filterProps(props), children);
+};
+const HtmlButtonWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('button', filterProps(props), children);
+};
+const HtmlTableWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('table', filterProps(props), children);
+};
+const HtmlTheadWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('thead', filterProps(props), children);
+};
+const HtmlTbodyWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('tbody', filterProps(props), children);
+};
+const HtmlTfootWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('tfoot', filterProps(props), children);
+};
+const HtmlTrWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('tr', filterProps(props), children);
+};
+const HtmlThWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('th', filterProps(props), children);
+};
+const HtmlTdWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('td', filterProps(props), children);
+};
+const HtmlBrWrapper = ({
+ children: _children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('br', filterProps(props));
+};
+const HtmlHrWrapper = ({
+ children: _children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement('hr', filterProps(props));
+};
+const TwentyUiButtonWrapper = ({
+ children,
+ ...props
+}: { children?: React.ReactNode } & Record) => {
+ return React.createElement(Button, filterProps(props), children);
+};
+type ComponentRegistryValue =
+ | ReturnType
+ | typeof RemoteFragmentRenderer;
+
+export const componentRegistry: Map = new Map([
+ ['html-div', createRemoteComponentRenderer(HtmlDivWrapper)],
+ ['html-span', createRemoteComponentRenderer(HtmlSpanWrapper)],
+ ['html-section', createRemoteComponentRenderer(HtmlSectionWrapper)],
+ ['html-article', createRemoteComponentRenderer(HtmlArticleWrapper)],
+ ['html-header', createRemoteComponentRenderer(HtmlHeaderWrapper)],
+ ['html-footer', createRemoteComponentRenderer(HtmlFooterWrapper)],
+ ['html-main', createRemoteComponentRenderer(HtmlMainWrapper)],
+ ['html-nav', createRemoteComponentRenderer(HtmlNavWrapper)],
+ ['html-aside', createRemoteComponentRenderer(HtmlAsideWrapper)],
+ ['html-p', createRemoteComponentRenderer(HtmlPWrapper)],
+ ['html-h1', createRemoteComponentRenderer(HtmlH1Wrapper)],
+ ['html-h2', createRemoteComponentRenderer(HtmlH2Wrapper)],
+ ['html-h3', createRemoteComponentRenderer(HtmlH3Wrapper)],
+ ['html-h4', createRemoteComponentRenderer(HtmlH4Wrapper)],
+ ['html-h5', createRemoteComponentRenderer(HtmlH5Wrapper)],
+ ['html-h6', createRemoteComponentRenderer(HtmlH6Wrapper)],
+ ['html-strong', createRemoteComponentRenderer(HtmlStrongWrapper)],
+ ['html-em', createRemoteComponentRenderer(HtmlEmWrapper)],
+ ['html-small', createRemoteComponentRenderer(HtmlSmallWrapper)],
+ ['html-code', createRemoteComponentRenderer(HtmlCodeWrapper)],
+ ['html-pre', createRemoteComponentRenderer(HtmlPreWrapper)],
+ ['html-blockquote', createRemoteComponentRenderer(HtmlBlockquoteWrapper)],
+ ['html-a', createRemoteComponentRenderer(HtmlAWrapper)],
+ ['html-img', createRemoteComponentRenderer(HtmlImgWrapper)],
+ ['html-ul', createRemoteComponentRenderer(HtmlUlWrapper)],
+ ['html-ol', createRemoteComponentRenderer(HtmlOlWrapper)],
+ ['html-li', createRemoteComponentRenderer(HtmlLiWrapper)],
+ ['html-form', createRemoteComponentRenderer(HtmlFormWrapper)],
+ ['html-label', createRemoteComponentRenderer(HtmlLabelWrapper)],
+ ['html-input', createRemoteComponentRenderer(HtmlInputWrapper)],
+ ['html-textarea', createRemoteComponentRenderer(HtmlTextareaWrapper)],
+ ['html-select', createRemoteComponentRenderer(HtmlSelectWrapper)],
+ ['html-option', createRemoteComponentRenderer(HtmlOptionWrapper)],
+ ['html-button', createRemoteComponentRenderer(HtmlButtonWrapper)],
+ ['html-table', createRemoteComponentRenderer(HtmlTableWrapper)],
+ ['html-thead', createRemoteComponentRenderer(HtmlTheadWrapper)],
+ ['html-tbody', createRemoteComponentRenderer(HtmlTbodyWrapper)],
+ ['html-tfoot', createRemoteComponentRenderer(HtmlTfootWrapper)],
+ ['html-tr', createRemoteComponentRenderer(HtmlTrWrapper)],
+ ['html-th', createRemoteComponentRenderer(HtmlThWrapper)],
+ ['html-td', createRemoteComponentRenderer(HtmlTdWrapper)],
+ ['html-br', createRemoteComponentRenderer(HtmlBrWrapper)],
+ ['html-hr', createRemoteComponentRenderer(HtmlHrWrapper)],
+ ['twenty-ui-button', createRemoteComponentRenderer(TwentyUiButtonWrapper)],
+ ['remote-fragment', RemoteFragmentRenderer],
+]);
diff --git a/packages/twenty-sdk/src/front-component/host/generated/host-index.ts b/packages/twenty-sdk/src/front-component/renderer/host/generated/host-index.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component/host/generated/host-index.ts
rename to packages/twenty-sdk/src/front-component/renderer/host/generated/host-index.ts
diff --git a/packages/twenty-sdk/src/front-component/index.ts b/packages/twenty-sdk/src/front-component/renderer/index.ts
similarity index 84%
rename from packages/twenty-sdk/src/front-component/index.ts
rename to packages/twenty-sdk/src/front-component/renderer/index.ts
index 32c9b1c6ae..fad9220aca 100644
--- a/packages/twenty-sdk/src/front-component/index.ts
+++ b/packages/twenty-sdk/src/front-component/renderer/index.ts
@@ -1,126 +1,124 @@
-/*
- * _____ _
- *|_ _|_ _____ _ __ | |_ _ _
- * | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
- * | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
- * |_| \_/\_/ \___|_| |_|\__|\__, |
- * |___/
- */
-
export { FrontComponentRenderer } from './host/components/FrontComponentRenderer';
export { componentRegistry } from './host/generated/host-component-registry';
+export { FrontComponentErrorEffect } from './remote/components/FrontComponentErrorEffect';
+export { FrontComponentUpdateContextEffect } from './remote/components/FrontComponentUpdateContextEffect';
export { FrontComponentWorkerEffect } from './remote/components/FrontComponentWorkerEffect';
export {
- HtmlDiv,
- HtmlSpan,
- HtmlSection,
+ FrontComponentExecutionContextStore,
+ frontComponentExecutionContextStore,
+} from './remote/context/FrontComponentExecutionContextStore';
+export {
+ HtmlA,
HtmlArticle,
- HtmlHeader,
- HtmlFooter,
- HtmlMain,
- HtmlNav,
HtmlAside,
- HtmlP,
+ HtmlBlockquote,
+ HtmlBr,
+ HtmlButton,
+ HtmlCode,
+ HtmlDiv,
+ HtmlEm,
+ HtmlFooter,
+ HtmlForm,
HtmlH1,
HtmlH2,
HtmlH3,
HtmlH4,
HtmlH5,
HtmlH6,
- HtmlStrong,
- HtmlEm,
- HtmlSmall,
- HtmlCode,
- HtmlPre,
- HtmlBlockquote,
- HtmlA,
- HtmlImg,
- HtmlUl,
- HtmlOl,
- HtmlLi,
- HtmlForm,
- HtmlLabel,
- HtmlInput,
- HtmlTextarea,
- HtmlSelect,
- HtmlOption,
- HtmlButton,
- HtmlTable,
- HtmlThead,
- HtmlTbody,
- HtmlTfoot,
- HtmlTr,
- HtmlTh,
- HtmlTd,
- HtmlBr,
+ HtmlHeader,
HtmlHr,
+ HtmlImg,
+ HtmlInput,
+ HtmlLabel,
+ HtmlLi,
+ HtmlMain,
+ HtmlNav,
+ HtmlOl,
+ HtmlOption,
+ HtmlP,
+ HtmlPre,
+ HtmlSection,
+ HtmlSelect,
+ HtmlSmall,
+ HtmlSpan,
+ HtmlStrong,
+ HtmlTable,
+ HtmlTbody,
+ HtmlTd,
+ HtmlTextarea,
+ HtmlTfoot,
+ HtmlTh,
+ HtmlThead,
+ HtmlTr,
+ HtmlUl,
TwentyUiButton,
} from './remote/generated/remote-components';
-export type {
- HtmlCommonProperties,
- HtmlCommonEvents,
- HtmlAProperties,
- HtmlImgProperties,
- HtmlFormProperties,
- HtmlLabelProperties,
- HtmlInputProperties,
- HtmlTextareaProperties,
- HtmlSelectProperties,
- HtmlOptionProperties,
- HtmlButtonProperties,
- HtmlThProperties,
- HtmlTdProperties,
- TwentyUiButtonProperties,
-} from './remote/generated/remote-elements';
export {
- HtmlDivElement,
- HtmlSpanElement,
- HtmlSectionElement,
+ HtmlAElement,
HtmlArticleElement,
- HtmlHeaderElement,
- HtmlFooterElement,
- HtmlMainElement,
- HtmlNavElement,
HtmlAsideElement,
- HtmlPElement,
+ HtmlBlockquoteElement,
+ HtmlBrElement,
+ HtmlButtonElement,
+ HtmlCodeElement,
+ HtmlDivElement,
+ HtmlEmElement,
+ HtmlFooterElement,
+ HtmlFormElement,
HtmlH1Element,
HtmlH2Element,
HtmlH3Element,
HtmlH4Element,
HtmlH5Element,
HtmlH6Element,
- HtmlStrongElement,
- HtmlEmElement,
- HtmlSmallElement,
- HtmlCodeElement,
- HtmlPreElement,
- HtmlBlockquoteElement,
- HtmlAElement,
- HtmlImgElement,
- HtmlUlElement,
- HtmlOlElement,
- HtmlLiElement,
- HtmlFormElement,
- HtmlLabelElement,
- HtmlInputElement,
- HtmlTextareaElement,
- HtmlSelectElement,
- HtmlOptionElement,
- HtmlButtonElement,
- HtmlTableElement,
- HtmlTheadElement,
- HtmlTbodyElement,
- HtmlTfootElement,
- HtmlTrElement,
- HtmlThElement,
- HtmlTdElement,
- HtmlBrElement,
+ HtmlHeaderElement,
HtmlHrElement,
- TwentyUiButtonElement,
- RemoteRootElement,
+ HtmlImgElement,
+ HtmlInputElement,
+ HtmlLabelElement,
+ HtmlLiElement,
+ HtmlMainElement,
+ HtmlNavElement,
+ HtmlOlElement,
+ HtmlOptionElement,
+ HtmlPElement,
+ HtmlPreElement,
+ HtmlSectionElement,
+ HtmlSelectElement,
+ HtmlSmallElement,
+ HtmlSpanElement,
+ HtmlStrongElement,
+ HtmlTableElement,
+ HtmlTbodyElement,
+ HtmlTdElement,
+ HtmlTextareaElement,
+ HtmlTfootElement,
+ HtmlThElement,
+ HtmlTheadElement,
+ HtmlTrElement,
+ HtmlUlElement,
RemoteFragmentElement,
+ RemoteRootElement,
+ TwentyUiButtonElement,
+} from './remote/generated/remote-elements';
+export type {
+ HtmlAProperties,
+ HtmlButtonProperties,
+ HtmlCommonEvents,
+ HtmlCommonProperties,
+ HtmlFormProperties,
+ HtmlImgProperties,
+ HtmlInputProperties,
+ HtmlLabelProperties,
+ HtmlOptionProperties,
+ HtmlSelectProperties,
+ HtmlTdProperties,
+ HtmlTextareaProperties,
+ HtmlThProperties,
+ TwentyUiButtonProperties,
} from './remote/generated/remote-elements';
export { createRemoteWorker } from './remote/worker/createRemoteWorker';
+export type { FrontComponentExecutionContext } from './types/FrontComponentExecutionContext';
export type { HostToWorkerRenderContext } from './types/HostToWorkerRenderContext';
export type { PropertySchema } from './types/PropertySchema';
export type { WorkerExports } from './types/WorkerExports';
diff --git a/packages/twenty-sdk/src/front-component/renderer/remote/components/FrontComponentErrorEffect.tsx b/packages/twenty-sdk/src/front-component/renderer/remote/components/FrontComponentErrorEffect.tsx
new file mode 100644
index 0000000000..a7e97bdd5d
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/renderer/remote/components/FrontComponentErrorEffect.tsx
@@ -0,0 +1,18 @@
+import { useEffect } from 'react';
+
+type FrontComponentErrorEffectProps = {
+ error: Error | null;
+ onError: (error: Error) => void;
+};
+export const FrontComponentErrorEffect = ({
+ error,
+ onError,
+}: FrontComponentErrorEffectProps) => {
+ useEffect(() => {
+ if (error) {
+ onError(error);
+ }
+ }, [error, onError]);
+
+ return null;
+};
diff --git a/packages/twenty-sdk/src/front-component/renderer/remote/components/FrontComponentUpdateContextEffect.tsx b/packages/twenty-sdk/src/front-component/renderer/remote/components/FrontComponentUpdateContextEffect.tsx
new file mode 100644
index 0000000000..381aebce86
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/renderer/remote/components/FrontComponentUpdateContextEffect.tsx
@@ -0,0 +1,20 @@
+import { type FrontComponentExecutionContext } from '@/front-component/renderer/types/FrontComponentExecutionContext';
+import { type WorkerExports } from '@/front-component/renderer/types/WorkerExports';
+import { type ThreadWebWorker } from '@quilted/threads';
+import { useEffect } from 'react';
+
+type FrontComponentUpdateContextEffectProps = {
+ thread: ThreadWebWorker;
+ executionContext: FrontComponentExecutionContext;
+};
+
+export const FrontComponentUpdateContextEffect = ({
+ thread,
+ executionContext,
+}: FrontComponentUpdateContextEffectProps) => {
+ useEffect(() => {
+ thread.imports.updateContext(executionContext).catch(() => {});
+ }, [executionContext, thread]);
+
+ return null;
+};
diff --git a/packages/twenty-sdk/src/front-component/remote/components/FrontComponentWorkerEffect.tsx b/packages/twenty-sdk/src/front-component/renderer/remote/components/FrontComponentWorkerEffect.tsx
similarity index 74%
rename from packages/twenty-sdk/src/front-component/remote/components/FrontComponentWorkerEffect.tsx
rename to packages/twenty-sdk/src/front-component/renderer/remote/components/FrontComponentWorkerEffect.tsx
index 680cf888b8..7872a79831 100644
--- a/packages/twenty-sdk/src/front-component/remote/components/FrontComponentWorkerEffect.tsx
+++ b/packages/twenty-sdk/src/front-component/renderer/remote/components/FrontComponentWorkerEffect.tsx
@@ -7,13 +7,17 @@ import { createRemoteWorker } from '../worker/createRemoteWorker';
type FrontComponentWorkerEffectProps = {
componentUrl: string;
setReceiver: React.Dispatch>;
- onError: (error?: Error) => void;
+ setThread: React.Dispatch<
+ React.SetStateAction | null>
+ >;
+ setError: React.Dispatch>;
};
export const FrontComponentWorkerEffect = ({
componentUrl,
setReceiver,
- onError,
+ setThread,
+ setError,
}: FrontComponentWorkerEffectProps) => {
useEffect(() => {
const newReceiver = new RemoteReceiver({ retain, release });
@@ -21,23 +25,25 @@ export const FrontComponentWorkerEffect = ({
const worker = createRemoteWorker();
worker.onerror = (event: ErrorEvent) => {
- onError(event.error);
+ setError(event.error);
};
const thread = new ThreadWebWorker(worker);
+ setThread(thread);
thread.imports
.render(newReceiver.connection, { componentUrl })
.catch((error: Error) => {
- onError(error);
+ setError(error);
});
setReceiver(newReceiver);
return () => {
+ setThread(null);
worker.terminate();
};
- }, [componentUrl, onError, setReceiver]);
+ }, [componentUrl, setError, setReceiver, setThread]);
return null;
};
diff --git a/packages/twenty-sdk/src/front-component/renderer/remote/context/FrontComponentExecutionContextStore.ts b/packages/twenty-sdk/src/front-component/renderer/remote/context/FrontComponentExecutionContextStore.ts
new file mode 100644
index 0000000000..708e7fa175
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/renderer/remote/context/FrontComponentExecutionContextStore.ts
@@ -0,0 +1,28 @@
+import { type FrontComponentExecutionContext } from '../../types/FrontComponentExecutionContext';
+
+type Listener = () => void;
+
+export class FrontComponentExecutionContextStore {
+ private context: FrontComponentExecutionContext | undefined = undefined;
+ private listeners = new Set();
+
+ getSnapshot = (): FrontComponentExecutionContext | undefined => {
+ return this.context;
+ };
+
+ subscribe = (listener: Listener): (() => void) => {
+ this.listeners.add(listener);
+
+ return () => this.listeners.delete(listener);
+ };
+
+ setContext = (context: FrontComponentExecutionContext): void => {
+ this.context = context;
+ for (const listener of this.listeners) {
+ listener();
+ }
+ };
+}
+
+export const frontComponentExecutionContextStore =
+ new FrontComponentExecutionContextStore();
diff --git a/packages/twenty-sdk/src/front-component/renderer/remote/generated/remote-components.ts b/packages/twenty-sdk/src/front-component/renderer/remote/generated/remote-components.ts
new file mode 100644
index 0000000000..5b3014ceac
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/renderer/remote/generated/remote-components.ts
@@ -0,0 +1,1157 @@
+/*
+ * _____ _
+ *|_ _|_ _____ _ __ | |_ _ _
+ * | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
+ * | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
+ * |_| \_/\_/ \___|_| |_|\__|\__, |
+ * |___/
+ */
+
+import { createRemoteComponent } from '@remote-dom/react';
+import {
+ HtmlDivElement,
+ HtmlSpanElement,
+ HtmlSectionElement,
+ HtmlArticleElement,
+ HtmlHeaderElement,
+ HtmlFooterElement,
+ HtmlMainElement,
+ HtmlNavElement,
+ HtmlAsideElement,
+ HtmlPElement,
+ HtmlH1Element,
+ HtmlH2Element,
+ HtmlH3Element,
+ HtmlH4Element,
+ HtmlH5Element,
+ HtmlH6Element,
+ HtmlStrongElement,
+ HtmlEmElement,
+ HtmlSmallElement,
+ HtmlCodeElement,
+ HtmlPreElement,
+ HtmlBlockquoteElement,
+ HtmlAElement,
+ HtmlImgElement,
+ HtmlUlElement,
+ HtmlOlElement,
+ HtmlLiElement,
+ HtmlFormElement,
+ HtmlLabelElement,
+ HtmlInputElement,
+ HtmlTextareaElement,
+ HtmlSelectElement,
+ HtmlOptionElement,
+ HtmlButtonElement,
+ HtmlTableElement,
+ HtmlTheadElement,
+ HtmlTbodyElement,
+ HtmlTfootElement,
+ HtmlTrElement,
+ HtmlThElement,
+ HtmlTdElement,
+ HtmlBrElement,
+ HtmlHrElement,
+ TwentyUiButtonElement,
+} from './remote-elements';
+
+export const HtmlDiv = createRemoteComponent('html-div', HtmlDivElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlSpan = createRemoteComponent('html-span', HtmlSpanElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlSection = createRemoteComponent(
+ 'html-section',
+ HtmlSectionElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlArticle = createRemoteComponent(
+ 'html-article',
+ HtmlArticleElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlHeader = createRemoteComponent(
+ 'html-header',
+ HtmlHeaderElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlFooter = createRemoteComponent(
+ 'html-footer',
+ HtmlFooterElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlMain = createRemoteComponent('html-main', HtmlMainElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlNav = createRemoteComponent('html-nav', HtmlNavElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlAside = createRemoteComponent('html-aside', HtmlAsideElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlP = createRemoteComponent('html-p', HtmlPElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlH1 = createRemoteComponent('html-h1', HtmlH1Element, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlH2 = createRemoteComponent('html-h2', HtmlH2Element, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlH3 = createRemoteComponent('html-h3', HtmlH3Element, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlH4 = createRemoteComponent('html-h4', HtmlH4Element, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlH5 = createRemoteComponent('html-h5', HtmlH5Element, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlH6 = createRemoteComponent('html-h6', HtmlH6Element, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlStrong = createRemoteComponent(
+ 'html-strong',
+ HtmlStrongElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlEm = createRemoteComponent('html-em', HtmlEmElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlSmall = createRemoteComponent('html-small', HtmlSmallElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlCode = createRemoteComponent('html-code', HtmlCodeElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlPre = createRemoteComponent('html-pre', HtmlPreElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlBlockquote = createRemoteComponent(
+ 'html-blockquote',
+ HtmlBlockquoteElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlA = createRemoteComponent('html-a', HtmlAElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlImg = createRemoteComponent('html-img', HtmlImgElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlUl = createRemoteComponent('html-ul', HtmlUlElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlOl = createRemoteComponent('html-ol', HtmlOlElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlLi = createRemoteComponent('html-li', HtmlLiElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlForm = createRemoteComponent('html-form', HtmlFormElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlLabel = createRemoteComponent('html-label', HtmlLabelElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlInput = createRemoteComponent('html-input', HtmlInputElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlTextarea = createRemoteComponent(
+ 'html-textarea',
+ HtmlTextareaElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlSelect = createRemoteComponent(
+ 'html-select',
+ HtmlSelectElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlOption = createRemoteComponent(
+ 'html-option',
+ HtmlOptionElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlButton = createRemoteComponent(
+ 'html-button',
+ HtmlButtonElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
+export const HtmlTable = createRemoteComponent('html-table', HtmlTableElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlThead = createRemoteComponent('html-thead', HtmlTheadElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlTbody = createRemoteComponent('html-tbody', HtmlTbodyElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlTfoot = createRemoteComponent('html-tfoot', HtmlTfootElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlTr = createRemoteComponent('html-tr', HtmlTrElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlTh = createRemoteComponent('html-th', HtmlThElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlTd = createRemoteComponent('html-td', HtmlTdElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlBr = createRemoteComponent('html-br', HtmlBrElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const HtmlHr = createRemoteComponent('html-hr', HtmlHrElement, {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+});
+export const TwentyUiButton = createRemoteComponent(
+ 'twenty-ui-button',
+ TwentyUiButtonElement,
+ {
+ eventProps: {
+ onClick: { event: 'click' },
+ onDblclick: { event: 'dblclick' },
+ onMousedown: { event: 'mousedown' },
+ onMouseup: { event: 'mouseup' },
+ onMouseover: { event: 'mouseover' },
+ onMouseout: { event: 'mouseout' },
+ onMouseenter: { event: 'mouseenter' },
+ onMouseleave: { event: 'mouseleave' },
+ onKeydown: { event: 'keydown' },
+ onKeyup: { event: 'keyup' },
+ onKeypress: { event: 'keypress' },
+ onFocus: { event: 'focus' },
+ onBlur: { event: 'blur' },
+ onChange: { event: 'change' },
+ onInput: { event: 'input' },
+ onSubmit: { event: 'submit' },
+ onScroll: { event: 'scroll' },
+ onWheel: { event: 'wheel' },
+ onContextmenu: { event: 'contextmenu' },
+ onDrag: { event: 'drag' },
+ },
+ },
+);
diff --git a/packages/twenty-sdk/src/front-component/renderer/remote/generated/remote-elements.ts b/packages/twenty-sdk/src/front-component/renderer/remote/generated/remote-elements.ts
new file mode 100644
index 0000000000..254606d588
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/renderer/remote/generated/remote-elements.ts
@@ -0,0 +1,733 @@
+/*
+ * _____ _
+ *|_ _|_ _____ _ __ | |_ _ _
+ * | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
+ * | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
+ * |_| \_/\_/ \___|_| |_|\__|\__, |
+ * |___/
+ */
+
+import {
+ createRemoteElement,
+ RemoteRootElement,
+ RemoteFragmentElement,
+ type RemoteEvent,
+} from '@remote-dom/core/elements';
+
+export type HtmlCommonProperties = {
+ id?: string;
+ className?: string;
+ style?: string;
+ title?: string;
+ tabIndex?: number;
+ role?: string;
+ 'aria-label'?: string;
+ 'aria-hidden'?: boolean;
+ 'data-testid'?: string;
+};
+export type HtmlCommonEvents = {
+ click(event: RemoteEvent): void;
+ dblclick(event: RemoteEvent): void;
+ mousedown(event: RemoteEvent): void;
+ mouseup(event: RemoteEvent): void;
+ mouseover(event: RemoteEvent): void;
+ mouseout(event: RemoteEvent): void;
+ mouseenter(event: RemoteEvent): void;
+ mouseleave(event: RemoteEvent): void;
+ keydown(event: RemoteEvent): void;
+ keyup(event: RemoteEvent): void;
+ keypress(event: RemoteEvent): void;
+ focus(event: RemoteEvent): void;
+ blur(event: RemoteEvent): void;
+ change(event: RemoteEvent): void;
+ input(event: RemoteEvent): void;
+ submit(event: RemoteEvent): void;
+ scroll(event: RemoteEvent): void;
+ wheel(event: RemoteEvent): void;
+ contextmenu(event: RemoteEvent): void;
+ drag(event: RemoteEvent): void;
+};
+
+const HTML_COMMON_EVENTS_ARRAY = [
+ 'click',
+ 'dblclick',
+ 'mousedown',
+ 'mouseup',
+ 'mouseover',
+ 'mouseout',
+ 'mouseenter',
+ 'mouseleave',
+ 'keydown',
+ 'keyup',
+ 'keypress',
+ 'focus',
+ 'blur',
+ 'change',
+ 'input',
+ 'submit',
+ 'scroll',
+ 'wheel',
+ 'contextmenu',
+ 'drag',
+] as const;
+const HTML_COMMON_PROPERTIES_CONFIG = {
+ id: { type: String },
+ className: { type: String },
+ style: { type: String },
+ title: { type: String },
+ tabIndex: { type: Number },
+ role: { type: String },
+ 'aria-label': { type: String },
+ 'aria-hidden': { type: Boolean },
+ 'data-testid': { type: String },
+};
+export const HtmlDivElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlSpanElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlSectionElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlArticleElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlHeaderElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlFooterElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlMainElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlNavElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlAsideElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlPElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlH1Element = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlH2Element = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlH3Element = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlH4Element = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlH5Element = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlH6Element = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlStrongElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlEmElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlSmallElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlCodeElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlPreElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlBlockquoteElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlAProperties = HtmlCommonProperties & {
+ href?: string;
+ target?: string;
+ rel?: string;
+};
+
+export const HtmlAElement = createRemoteElement<
+ HtmlAProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ href: { type: String },
+ target: { type: String },
+ rel: { type: String },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlImgProperties = HtmlCommonProperties & {
+ src?: string;
+ alt?: string;
+ width?: number;
+ height?: number;
+};
+
+export const HtmlImgElement = createRemoteElement<
+ HtmlImgProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ src: { type: String },
+ alt: { type: String },
+ width: { type: Number },
+ height: { type: Number },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlUlElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlOlElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlLiElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlFormProperties = HtmlCommonProperties & {
+ action?: string;
+ method?: string;
+};
+
+export const HtmlFormElement = createRemoteElement<
+ HtmlFormProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ action: { type: String },
+ method: { type: String },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlLabelProperties = HtmlCommonProperties & {
+ htmlFor?: string;
+};
+
+export const HtmlLabelElement = createRemoteElement<
+ HtmlLabelProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ htmlFor: { type: String },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlInputProperties = HtmlCommonProperties & {
+ type?: string;
+ name?: string;
+ value?: string;
+ placeholder?: string;
+ disabled?: boolean;
+ checked?: boolean;
+ readOnly?: boolean;
+};
+
+export const HtmlInputElement = createRemoteElement<
+ HtmlInputProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ type: { type: String },
+ name: { type: String },
+ value: { type: String },
+ placeholder: { type: String },
+ disabled: { type: Boolean },
+ checked: { type: Boolean },
+ readOnly: { type: Boolean },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlTextareaProperties = HtmlCommonProperties & {
+ name?: string;
+ value?: string;
+ placeholder?: string;
+ disabled?: boolean;
+ readOnly?: boolean;
+ rows?: number;
+ cols?: number;
+};
+
+export const HtmlTextareaElement = createRemoteElement<
+ HtmlTextareaProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ name: { type: String },
+ value: { type: String },
+ placeholder: { type: String },
+ disabled: { type: Boolean },
+ readOnly: { type: Boolean },
+ rows: { type: Number },
+ cols: { type: Number },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlSelectProperties = HtmlCommonProperties & {
+ name?: string;
+ value?: string;
+ disabled?: boolean;
+ multiple?: boolean;
+};
+
+export const HtmlSelectElement = createRemoteElement<
+ HtmlSelectProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ name: { type: String },
+ value: { type: String },
+ disabled: { type: Boolean },
+ multiple: { type: Boolean },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlOptionProperties = HtmlCommonProperties & {
+ value?: string;
+ disabled?: boolean;
+ selected?: boolean;
+};
+
+export const HtmlOptionElement = createRemoteElement<
+ HtmlOptionProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ value: { type: String },
+ disabled: { type: Boolean },
+ selected: { type: Boolean },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlButtonProperties = HtmlCommonProperties & {
+ type?: string;
+ disabled?: boolean;
+};
+
+export const HtmlButtonElement = createRemoteElement<
+ HtmlButtonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ type: { type: String },
+ disabled: { type: Boolean },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlTableElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlTheadElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlTbodyElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlTfootElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlTrElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlThProperties = HtmlCommonProperties & {
+ colSpan?: number;
+ rowSpan?: number;
+};
+
+export const HtmlThElement = createRemoteElement<
+ HtmlThProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ colSpan: { type: Number },
+ rowSpan: { type: Number },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type HtmlTdProperties = HtmlCommonProperties & {
+ colSpan?: number;
+ rowSpan?: number;
+};
+
+export const HtmlTdElement = createRemoteElement<
+ HtmlTdProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ colSpan: { type: Number },
+ rowSpan: { type: Number },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlBrElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+export const HtmlHrElement = createRemoteElement<
+ HtmlCommonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: HTML_COMMON_PROPERTIES_CONFIG,
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+
+export type TwentyUiButtonProperties = HtmlCommonProperties & {
+ variant?: string;
+ accent?: string;
+ size?: string;
+ disabled?: boolean;
+ fullWidth?: boolean;
+};
+
+export const TwentyUiButtonElement = createRemoteElement<
+ TwentyUiButtonProperties,
+ Record,
+ Record,
+ HtmlCommonEvents
+>({
+ properties: {
+ ...HTML_COMMON_PROPERTIES_CONFIG,
+ variant: { type: String },
+ accent: { type: String },
+ size: { type: String },
+ disabled: { type: Boolean },
+ fullWidth: { type: Boolean },
+ },
+ events: [...HTML_COMMON_EVENTS_ARRAY],
+});
+customElements.define('html-div', HtmlDivElement);
+customElements.define('html-span', HtmlSpanElement);
+customElements.define('html-section', HtmlSectionElement);
+customElements.define('html-article', HtmlArticleElement);
+customElements.define('html-header', HtmlHeaderElement);
+customElements.define('html-footer', HtmlFooterElement);
+customElements.define('html-main', HtmlMainElement);
+customElements.define('html-nav', HtmlNavElement);
+customElements.define('html-aside', HtmlAsideElement);
+customElements.define('html-p', HtmlPElement);
+customElements.define('html-h1', HtmlH1Element);
+customElements.define('html-h2', HtmlH2Element);
+customElements.define('html-h3', HtmlH3Element);
+customElements.define('html-h4', HtmlH4Element);
+customElements.define('html-h5', HtmlH5Element);
+customElements.define('html-h6', HtmlH6Element);
+customElements.define('html-strong', HtmlStrongElement);
+customElements.define('html-em', HtmlEmElement);
+customElements.define('html-small', HtmlSmallElement);
+customElements.define('html-code', HtmlCodeElement);
+customElements.define('html-pre', HtmlPreElement);
+customElements.define('html-blockquote', HtmlBlockquoteElement);
+customElements.define('html-a', HtmlAElement);
+customElements.define('html-img', HtmlImgElement);
+customElements.define('html-ul', HtmlUlElement);
+customElements.define('html-ol', HtmlOlElement);
+customElements.define('html-li', HtmlLiElement);
+customElements.define('html-form', HtmlFormElement);
+customElements.define('html-label', HtmlLabelElement);
+customElements.define('html-input', HtmlInputElement);
+customElements.define('html-textarea', HtmlTextareaElement);
+customElements.define('html-select', HtmlSelectElement);
+customElements.define('html-option', HtmlOptionElement);
+customElements.define('html-button', HtmlButtonElement);
+customElements.define('html-table', HtmlTableElement);
+customElements.define('html-thead', HtmlTheadElement);
+customElements.define('html-tbody', HtmlTbodyElement);
+customElements.define('html-tfoot', HtmlTfootElement);
+customElements.define('html-tr', HtmlTrElement);
+customElements.define('html-th', HtmlThElement);
+customElements.define('html-td', HtmlTdElement);
+customElements.define('html-br', HtmlBrElement);
+customElements.define('html-hr', HtmlHrElement);
+customElements.define('twenty-ui-button', TwentyUiButtonElement);
+customElements.define('remote-root', RemoteRootElement);
+customElements.define('remote-fragment', RemoteFragmentElement);
+
+export { RemoteRootElement, RemoteFragmentElement };
+declare global {
+ interface HTMLElementTagNameMap {
+ 'html-div': InstanceType;
+ 'html-span': InstanceType;
+ 'html-section': InstanceType;
+ 'html-article': InstanceType;
+ 'html-header': InstanceType;
+ 'html-footer': InstanceType;
+ 'html-main': InstanceType;
+ 'html-nav': InstanceType;
+ 'html-aside': InstanceType;
+ 'html-p': InstanceType;
+ 'html-h1': InstanceType;
+ 'html-h2': InstanceType;
+ 'html-h3': InstanceType;
+ 'html-h4': InstanceType;
+ 'html-h5': InstanceType;
+ 'html-h6': InstanceType;
+ 'html-strong': InstanceType;
+ 'html-em': InstanceType;
+ 'html-small': InstanceType;
+ 'html-code': InstanceType;
+ 'html-pre': InstanceType;
+ 'html-blockquote': InstanceType;
+ 'html-a': InstanceType;
+ 'html-img': InstanceType;
+ 'html-ul': InstanceType;
+ 'html-ol': InstanceType;
+ 'html-li': InstanceType;
+ 'html-form': InstanceType;
+ 'html-label': InstanceType;
+ 'html-input': InstanceType;
+ 'html-textarea': InstanceType;
+ 'html-select': InstanceType;
+ 'html-option': InstanceType;
+ 'html-button': InstanceType;
+ 'html-table': InstanceType;
+ 'html-thead': InstanceType;
+ 'html-tbody': InstanceType;
+ 'html-tfoot': InstanceType;
+ 'html-tr': InstanceType;
+ 'html-th': InstanceType;
+ 'html-td': InstanceType;
+ 'html-br': InstanceType;
+ 'html-hr': InstanceType;
+ 'twenty-ui-button': InstanceType;
+ 'remote-root': InstanceType;
+ 'remote-fragment': InstanceType;
+ }
+}
diff --git a/packages/twenty-sdk/src/front-component/remote/generated/remote-index.ts b/packages/twenty-sdk/src/front-component/renderer/remote/generated/remote-index.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component/remote/generated/remote-index.ts
rename to packages/twenty-sdk/src/front-component/renderer/remote/generated/remote-index.ts
diff --git a/packages/twenty-sdk/src/front-component/remote/mock/mock-front-component.ts b/packages/twenty-sdk/src/front-component/renderer/remote/mock/mock-front-component.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component/remote/mock/mock-front-component.ts
rename to packages/twenty-sdk/src/front-component/renderer/remote/mock/mock-front-component.ts
diff --git a/packages/twenty-sdk/src/front-component/remote/worker/createRemoteWorker.ts b/packages/twenty-sdk/src/front-component/renderer/remote/worker/createRemoteWorker.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component/remote/worker/createRemoteWorker.ts
rename to packages/twenty-sdk/src/front-component/renderer/remote/worker/createRemoteWorker.ts
diff --git a/packages/twenty-sdk/src/front-component/remote/worker/remote-worker.ts b/packages/twenty-sdk/src/front-component/renderer/remote/worker/remote-worker.ts
similarity index 71%
rename from packages/twenty-sdk/src/front-component/remote/worker/remote-worker.ts
rename to packages/twenty-sdk/src/front-component/renderer/remote/worker/remote-worker.ts
index c5b2a945a8..3b473d9b27 100644
--- a/packages/twenty-sdk/src/front-component/remote/worker/remote-worker.ts
+++ b/packages/twenty-sdk/src/front-component/renderer/remote/worker/remote-worker.ts
@@ -12,14 +12,18 @@ import {
import React from 'react';
import { createRoot } from 'react-dom/client';
import { jsx, jsxs } from 'react/jsx-runtime';
+import { type FrontComponentExecutionContext } from '../../types/FrontComponentExecutionContext';
import { type HostToWorkerRenderContext } from '../../types/HostToWorkerRenderContext';
import { type WorkerExports } from '../../types/WorkerExports';
+import { frontComponentExecutionContextStore } from '../context/FrontComponentExecutionContextStore';
import * as RemoteComponents from '../generated/remote-components';
(globalThis as Record).React = React;
(globalThis as Record).RemoteComponents = RemoteComponents;
(globalThis as Record).jsx = jsx;
(globalThis as Record).jsxs = jsxs;
+(globalThis as Record).frontComponentExecutionContextStore =
+ frontComponentExecutionContextStore;
const render: WorkerExports['render'] = async (
connection: RemoteConnection,
@@ -37,4 +41,10 @@ const render: WorkerExports['render'] = async (
reactRoot.render(componentModule.default);
};
-ThreadWebWorker.self.export({ render });
+const updateContext: WorkerExports['updateContext'] = async (
+ context: FrontComponentExecutionContext,
+) => {
+ frontComponentExecutionContextStore.setContext(context);
+};
+
+ThreadWebWorker.self.export({ render, updateContext });
diff --git a/packages/twenty-sdk/src/front-component/renderer/types/FrontComponentExecutionContext.ts b/packages/twenty-sdk/src/front-component/renderer/types/FrontComponentExecutionContext.ts
new file mode 100644
index 0000000000..732a36147a
--- /dev/null
+++ b/packages/twenty-sdk/src/front-component/renderer/types/FrontComponentExecutionContext.ts
@@ -0,0 +1,3 @@
+export type FrontComponentExecutionContext = {
+ userId: string | null;
+};
diff --git a/packages/twenty-sdk/src/front-component/types/HostToWorkerRenderContext.ts b/packages/twenty-sdk/src/front-component/renderer/types/HostToWorkerRenderContext.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component/types/HostToWorkerRenderContext.ts
rename to packages/twenty-sdk/src/front-component/renderer/types/HostToWorkerRenderContext.ts
diff --git a/packages/twenty-sdk/src/front-component/types/PropertySchema.ts b/packages/twenty-sdk/src/front-component/renderer/types/PropertySchema.ts
similarity index 100%
rename from packages/twenty-sdk/src/front-component/types/PropertySchema.ts
rename to packages/twenty-sdk/src/front-component/renderer/types/PropertySchema.ts
diff --git a/packages/twenty-sdk/src/front-component/types/WorkerExports.ts b/packages/twenty-sdk/src/front-component/renderer/types/WorkerExports.ts
similarity index 63%
rename from packages/twenty-sdk/src/front-component/types/WorkerExports.ts
rename to packages/twenty-sdk/src/front-component/renderer/types/WorkerExports.ts
index 102a72711c..2218b641f3 100644
--- a/packages/twenty-sdk/src/front-component/types/WorkerExports.ts
+++ b/packages/twenty-sdk/src/front-component/renderer/types/WorkerExports.ts
@@ -1,4 +1,5 @@
import { type RemoteConnection } from '@remote-dom/core/elements';
+import { type FrontComponentExecutionContext } from './FrontComponentExecutionContext';
import { type HostToWorkerRenderContext } from './HostToWorkerRenderContext';
export type WorkerExports = {
@@ -6,4 +7,5 @@ export type WorkerExports = {
connection: RemoteConnection,
context: HostToWorkerRenderContext,
) => Promise;
+ updateContext: (context: FrontComponentExecutionContext) => Promise;
};
diff --git a/packages/twenty-sdk/src/index.ts b/packages/twenty-sdk/src/index.ts
index c404b4b950..0c103ca217 100644
--- a/packages/twenty-sdk/src/index.ts
+++ b/packages/twenty-sdk/src/index.ts
@@ -1,10 +1 @@
-/*
- * _____ _
- *|_ _|_ _____ _ __ | |_ _ _
- * | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
- * | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
- * |_| \_/\_/ \___|_| |_|\__|\__, |
- * |___/
- */
-
export * from './sdk';
diff --git a/packages/twenty-sdk/src/sdk/front-components/__tests__/define-front-component.spec.ts b/packages/twenty-sdk/src/sdk/__tests__/define-front-component.spec.ts
similarity index 100%
rename from packages/twenty-sdk/src/sdk/front-components/__tests__/define-front-component.spec.ts
rename to packages/twenty-sdk/src/sdk/__tests__/define-front-component.spec.ts
diff --git a/packages/twenty-sdk/src/sdk/common/types/define-entity.type.ts b/packages/twenty-sdk/src/sdk/common/types/define-entity.type.ts
index b453294c7b..7895f1ca31 100644
--- a/packages/twenty-sdk/src/sdk/common/types/define-entity.type.ts
+++ b/packages/twenty-sdk/src/sdk/common/types/define-entity.type.ts
@@ -1,11 +1,11 @@
+import { type ApplicationConfig } from '@/sdk/application/application-config';
+import { type FrontComponentConfig } from '@/sdk/front-component-config';
+import { type LogicFunctionConfig } from '@/sdk/logic-functions/logic-function-config';
import {
type FieldManifest,
type ObjectManifest,
type RoleManifest,
} from 'twenty-shared/application';
-import { type FrontComponentConfig } from '@/sdk/front-components/front-component-config';
-import { type LogicFunctionConfig } from '@/sdk/logic-functions/logic-function-config';
-import { type ApplicationConfig } from '@/sdk/application/application-config';
export type ValidationResult = {
success: boolean;
diff --git a/packages/twenty-sdk/src/sdk/front-components/define-front-component.ts b/packages/twenty-sdk/src/sdk/define-front-component.ts
similarity index 96%
rename from packages/twenty-sdk/src/sdk/front-components/define-front-component.ts
rename to packages/twenty-sdk/src/sdk/define-front-component.ts
index a6c2c14129..42901d5ef3 100644
--- a/packages/twenty-sdk/src/sdk/front-components/define-front-component.ts
+++ b/packages/twenty-sdk/src/sdk/define-front-component.ts
@@ -1,6 +1,6 @@
-import { type FrontComponentConfig } from '@/sdk/front-components/front-component-config';
-import type { DefineEntity } from '@/sdk/common/types/define-entity.type';
import { createValidationResult } from '@/sdk';
+import type { DefineEntity } from '@/sdk/common/types/define-entity.type';
+import { type FrontComponentConfig } from '@/sdk/front-component-config';
export const defineFrontComponent: DefineEntity = (
config,
diff --git a/packages/twenty-sdk/src/sdk/front-components/front-component-config.ts b/packages/twenty-sdk/src/sdk/front-component-config.ts
similarity index 100%
rename from packages/twenty-sdk/src/sdk/front-components/front-component-config.ts
rename to packages/twenty-sdk/src/sdk/front-component-config.ts
diff --git a/packages/twenty-sdk/src/sdk/index.ts b/packages/twenty-sdk/src/sdk/index.ts
index 04ee7d5097..ff6573a88f 100644
--- a/packages/twenty-sdk/src/sdk/index.ts
+++ b/packages/twenty-sdk/src/sdk/index.ts
@@ -1,12 +1,3 @@
-/*
- * _____ _
- *|_ _|_ _____ _ __ | |_ _ _
- * | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
- * | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
- * |_| \_/\_/ \___|_| |_|\__|\__, |
- * |___/
- */
-
export type { ApplicationConfig } from './application/application-config';
export { defineApplication } from './application/define-application';
export type {
@@ -16,6 +7,7 @@ export type {
} from './common/types/define-entity.type';
export type { SyncableEntityOptions } from './common/types/syncable-entity-options.type';
export { createValidationResult } from './common/utils/create-validation-result';
+export { defineFrontComponent } from './define-front-component';
export type {
ActorField,
AddressField,
@@ -31,11 +23,10 @@ export { FieldType } from './fields/field-type';
export { OnDeleteAction } from './fields/on-delete-action';
export { RelationType } from './fields/relation-type';
export { validateFields } from './fields/validate-fields';
-export { defineFrontComponent } from './front-components/define-front-component';
export type {
FrontComponentType,
FrontComponentConfig,
-} from './front-components/front-component-config';
+} from './front-component-config';
export { defineLogicFunction } from './logic-functions/define-logic-function';
export type {
LogicFunctionHandler,
diff --git a/packages/twenty-sdk/src/ui/index.ts b/packages/twenty-sdk/src/ui/index.ts
index 2c682cedef..d35fd14e73 100644
--- a/packages/twenty-sdk/src/ui/index.ts
+++ b/packages/twenty-sdk/src/ui/index.ts
@@ -1,12 +1,3 @@
-/*
- * _____ _
- *|_ _|_ _____ _ __ | |_ _ _
- * | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
- * | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
- * |_| \_/\_/ \___|_| |_|\__|\__, |
- * |___/
- */
-
export * from 'twenty-ui';
export * from 'twenty-ui/accessibility';
export * from 'twenty-ui/components';
diff --git a/packages/twenty-sdk/tsconfig.json b/packages/twenty-sdk/tsconfig.json
index 8405d5d815..c6d8a86880 100644
--- a/packages/twenty-sdk/tsconfig.json
+++ b/packages/twenty-sdk/tsconfig.json
@@ -25,7 +25,6 @@
"**/__mocks__/**/*",
"**/__tests__/**/*",
"vite.config.ts",
- "scripts/**/*.ts",
"jest.config.mjs"
],
"exclude": [
diff --git a/packages/twenty-sdk/vite.config.ts b/packages/twenty-sdk/vite.config.ts
index 5e03c45d3e..15f36553b6 100644
--- a/packages/twenty-sdk/vite.config.ts
+++ b/packages/twenty-sdk/vite.config.ts
@@ -5,11 +5,13 @@ import dts from 'vite-plugin-dts';
import tsconfigPaths from 'vite-tsconfig-paths';
import packageJson from './package.json';
-const moduleEntries = Object.keys((packageJson as any).exports || {})
- .filter((key) => key !== '.' && !key.startsWith('./src/'))
- .map((module) => `src/${module.replace(/^\.\//, '')}/index.ts`);
-
-const entries = ['src/index.ts', 'src/cli/cli.ts', ...moduleEntries];
+const entries = [
+ 'src/index.ts',
+ 'src/cli/cli.ts',
+ 'src/ui/index.ts',
+ 'src/front-component/renderer/index.ts',
+ 'src/front-component/api/index.ts',
+];
export const PACKAGES_TO_VENDOR = ['twenty-ui', 'twenty-shared'];
@@ -20,18 +22,15 @@ const entryFileNames = (chunk: any, extension: 'cjs' | 'mjs') => {
);
}
- const splitFaceModuleId = chunk.facadeModuleId?.split('/');
- if (splitFaceModuleId === undefined) {
- throw new Error(
- `Should never occurs splitFaceModuleId is undefined ${chunk.facadeModuleId}`,
- );
- }
-
- const moduleDirectory = splitFaceModuleId[splitFaceModuleId?.length - 2];
- if (moduleDirectory === 'src') {
+ // Find which entry this chunk corresponds to
+ const entry = entries.find((e) => chunk.facadeModuleId?.endsWith(e));
+ if (!entry || entry === 'src/index.ts' || entry === 'src/cli/cli.ts') {
return `${chunk.name}.${extension}`;
}
- return `${moduleDirectory}/index.${extension}`;
+
+ // Remove 'src/' prefix and '/index.ts' suffix to get the module path
+ const modulePath = entry.replace('src/', '').replace('/index.ts', '');
+ return `${modulePath}/index.${extension}`;
};
const copyTwentyPackagesInVendor = (packages: string[]) => {