From facba752504a76b435b6354b940e0715dc9b362a Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Fri, 29 May 2026 15:34:17 +0200 Subject: [PATCH 1/7] fixes --- .../generators/remote-elements.generator.ts | 6 ++- .../html-tag/svg/svg/svg-events.stories.tsx | 5 +++ .../svg/svg/svg-pointer.front-component.tsx | 42 +++++++++++++++++++ .../shared/front-components/event-log.tsx | 36 ++++++++++++++++ .../test-utils/createHtmlElementStory.ts | 25 ++++++++++- .../test-utils/matchers/expectEventLogged.ts | 6 +++ .../src/constants/SerializedEventData.ts | 2 + .../src/host/utils/createHtmlHostWrapper.ts | 6 +++ .../src/remote/generated/remote-elements.ts | 6 ++- 9 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-pointer.front-component.tsx diff --git a/packages/twenty-front-component-renderer/scripts/remote-dom/generators/remote-elements.generator.ts b/packages/twenty-front-component-renderer/scripts/remote-dom/generators/remote-elements.generator.ts index 18d5d9b632b19..a017211fc8d95 100644 --- a/packages/twenty-front-component-renderer/scripts/remote-dom/generators/remote-elements.generator.ts +++ b/packages/twenty-front-component-renderer/scripts/remote-dom/generators/remote-elements.generator.ts @@ -129,11 +129,15 @@ const generateCommonEventsType = ( }); writer.writeLine(');'); writer.blankLine(); - writer.writeLine('return new CustomEvent(eventType, {'); + writer.writeLine('const event = new CustomEvent(eventType, {'); writer.indent(() => { writer.writeLine('detail: eventData,'); }); writer.writeLine('}) as RemoteEvent;'); + writer.blankLine(); + writer.writeLine('Object.assign(event, eventData);'); + writer.blankLine(); + writer.writeLine('return event;'); }); writer.writeLine('},'); }); diff --git a/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-events.stories.tsx b/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-events.stories.tsx index 87dec6cf243bc..81a79be8d55a1 100644 --- a/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-events.stories.tsx +++ b/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-events.stories.tsx @@ -8,6 +8,7 @@ import { import { createHtmlTagClickStory, createHtmlTagFocusStory, + createHtmlTagPointerStory, } from '@/__stories__/shared/test-utils/createHtmlElementStory'; const meta: Meta = { @@ -27,3 +28,7 @@ export const Click = createHtmlTagClickStory({ export const FocusBlur = createHtmlTagFocusStory({ frontComponentBundleName: 'svg-focus-blur', }); + +export const Pointer = createHtmlTagPointerStory({ + frontComponentBundleName: 'svg-pointer', +}); diff --git a/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-pointer.front-component.tsx b/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-pointer.front-component.tsx new file mode 100644 index 0000000000000..6f3b0eeb77f9f --- /dev/null +++ b/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-pointer.front-component.tsx @@ -0,0 +1,42 @@ +import { useState } from 'react'; +import { defineFrontComponent } from 'twenty-sdk/define'; +import { + EventLog, + useEventLog, +} from '@/__stories__/shared/front-components/event-log'; +import { FrontComponentCard } from '@/__stories__/shared/front-components/front-component-card'; +import { SVG_ROOT_STYLE } from '@/__stories__/shared/front-components/styles'; + +const SvgPointerFrontComponent = () => { + const [interactionCount, setInteractionCount] = useState(0); + const { entries, pushEvent } = useEventLog(); + + return ( + + { + setInteractionCount((previous) => previous + 1); + pushEvent(event); + }} + onPointerMove={(event) => { + pushEvent(event); + }} + tabIndex={0} + style={SVG_ROOT_STYLE} + > + + + {interactionCount} + + + ); +}; + +export default defineFrontComponent({ + universalIdentifier: 'fc-svg-c-pointer-0000000-0000-0000-0000-000000000021', + name: 'svg-pointer-front-component', + description: 'Front component covering pointer events on ', + component: SvgPointerFrontComponent, +}); diff --git a/packages/twenty-front-component-renderer/src/__stories__/shared/front-components/event-log.tsx b/packages/twenty-front-component-renderer/src/__stories__/shared/front-components/event-log.tsx index 4ef380b60b65a..5daef98aa948d 100644 --- a/packages/twenty-front-component-renderer/src/__stories__/shared/front-components/event-log.tsx +++ b/packages/twenty-front-component-renderer/src/__stories__/shared/front-components/event-log.tsx @@ -24,6 +24,12 @@ export type LoggedEventEntry = { scrollLeft?: number; deltaX?: number; deltaY?: number; + clientX?: number; + clientY?: number; + offsetX?: number; + offsetY?: number; + movementX?: number; + movementY?: number; }; const EVENT_LOG_STYLE = { @@ -216,6 +222,36 @@ export const useEventLog = () => { entry.deltaY = deltaY; } + const clientX = pickFromRecords(records, 'clientX', isNumberValue); + if (isDefined(clientX)) { + entry.clientX = clientX; + } + + const clientY = pickFromRecords(records, 'clientY', isNumberValue); + if (isDefined(clientY)) { + entry.clientY = clientY; + } + + const offsetX = pickFromRecords(records, 'offsetX', isNumberValue); + if (isDefined(offsetX)) { + entry.offsetX = offsetX; + } + + const offsetY = pickFromRecords(records, 'offsetY', isNumberValue); + if (isDefined(offsetY)) { + entry.offsetY = offsetY; + } + + const movementX = pickFromRecords(records, 'movementX', isNumberValue); + if (isDefined(movementX)) { + entry.movementX = movementX; + } + + const movementY = pickFromRecords(records, 'movementY', isNumberValue); + if (isDefined(movementY)) { + entry.movementY = movementY; + } + return [...previousEntries, entry]; }); }; diff --git a/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/createHtmlElementStory.ts b/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/createHtmlElementStory.ts index 84dddf23e4c88..fcd59db0ffc93 100644 --- a/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/createHtmlElementStory.ts +++ b/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/createHtmlElementStory.ts @@ -1,10 +1,10 @@ import { type StoryObj } from '@storybook/react-vite'; -import { userEvent, within } from 'storybook/test'; +import { fireEvent, userEvent, within } from 'storybook/test'; -import { type FrontComponentRenderer } from '@/host/components/FrontComponentRenderer'; import { expectEventLogged } from '@/__stories__/shared/test-utils/matchers/expectEventLogged'; import { expectFrontComponentMounted } from '@/__stories__/shared/test-utils/matchers/expectFrontComponentMounted'; import { runFrontComponentStory } from '@/__stories__/shared/test-utils/runFrontComponentStory'; +import { type FrontComponentRenderer } from '@/host/components/FrontComponentRenderer'; type Story = StoryObj; @@ -30,6 +30,27 @@ export const createHtmlTagClickStory = ({ }, }); +export const createHtmlTagPointerStory = ({ + frontComponentBundleName, +}: CreateHtmlTagStoryParams): Story => + runFrontComponentStory({ + frontComponentBundleName, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + + await expectFrontComponentMounted(canvas); + + const subject = await canvas.findByTestId('subject'); + + fireEvent.pointerDown(subject, { clientX: 123, clientY: 45 }); + + await expectEventLogged({ + canvas, + matcher: { type: 'pointerdown', clientX: 123, clientY: 45 }, + }); + }, + }); + export const createHtmlTagFocusStory = ({ frontComponentBundleName, }: CreateHtmlTagStoryParams): Story => diff --git a/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/matchers/expectEventLogged.ts b/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/matchers/expectEventLogged.ts index b31d4ed46c830..1f5bc4d453e51 100644 --- a/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/matchers/expectEventLogged.ts +++ b/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/matchers/expectEventLogged.ts @@ -17,6 +17,12 @@ type LoggedEventMatcher = { ctrlKey?: boolean; metaKey?: boolean; altKey?: boolean; + clientX?: number; + clientY?: number; + offsetX?: number; + offsetY?: number; + movementX?: number; + movementY?: number; files?: { name?: string; type?: string }[]; }; diff --git a/packages/twenty-front-component-renderer/src/constants/SerializedEventData.ts b/packages/twenty-front-component-renderer/src/constants/SerializedEventData.ts index 57a7e033e0939..4b12cd0ec7742 100644 --- a/packages/twenty-front-component-renderer/src/constants/SerializedEventData.ts +++ b/packages/twenty-front-component-renderer/src/constants/SerializedEventData.ts @@ -13,6 +13,8 @@ export type SerializedEventData = { shiftKey?: boolean; clientX?: number; clientY?: number; + x?: number; + y?: number; pageX?: number; pageY?: number; screenX?: number; diff --git a/packages/twenty-front-component-renderer/src/host/utils/createHtmlHostWrapper.ts b/packages/twenty-front-component-renderer/src/host/utils/createHtmlHostWrapper.ts index cfaea56849914..33ef85b785529 100644 --- a/packages/twenty-front-component-renderer/src/host/utils/createHtmlHostWrapper.ts +++ b/packages/twenty-front-component-renderer/src/host/utils/createHtmlHostWrapper.ts @@ -144,6 +144,12 @@ const serializeEvent = (event: unknown): SerializedEventData => { if (isNumber(domEvent.clientY)) { serialized.clientY = domEvent.clientY; } + if (isNumber(domEvent.x)) { + serialized.x = domEvent.x; + } + if (isNumber(domEvent.y)) { + serialized.y = domEvent.y; + } if (isNumber(domEvent.pageX)) { serialized.pageX = domEvent.pageX; } diff --git a/packages/twenty-front-component-renderer/src/remote/generated/remote-elements.ts b/packages/twenty-front-component-renderer/src/remote/generated/remote-elements.ts index f9842a3c2c05a..b729b4d326cb6 100644 --- a/packages/twenty-front-component-renderer/src/remote/generated/remote-elements.ts +++ b/packages/twenty-front-component-renderer/src/remote/generated/remote-elements.ts @@ -94,9 +94,13 @@ const createSerializedEventConfig = ( eventData, ); - return new CustomEvent(eventType, { + const event = new CustomEvent(eventType, { detail: eventData, }) as RemoteEvent; + + Object.assign(event, eventData); + + return event; }, }); const HTML_COMMON_EVENTS_CONFIG = Object.fromEntries( From e15ff9065deac1bd3790c49879a5080e87a07b93 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Mon, 1 Jun 2026 17:42:47 +0200 Subject: [PATCH 2/7] fix --- .../generators/remote-elements.generator.ts | 26 ++++- .../svg/svg/svg-pointer.front-component.tsx | 7 +- .../test-utils/createHtmlElementStory.ts | 8 +- .../src/constants/SerializedEventData.ts | 110 ------------------ .../applySerializedEventProperties.ts | 50 ++++++++ .../applySerializedEventTargetProperties.ts | 54 +++++++++ .../src/host/utils/createHtmlHostWrapper.ts | 6 +- .../src/remote/generated/remote-elements.ts | 12 +- .../src/types/SerializedEventData.ts | 52 +++++++++ .../src/types/SerializedFileData.ts | 6 + 10 files changed, 203 insertions(+), 128 deletions(-) delete mode 100644 packages/twenty-front-component-renderer/src/constants/SerializedEventData.ts create mode 100644 packages/twenty-front-component-renderer/src/constants/applySerializedEventProperties.ts create mode 100644 packages/twenty-front-component-renderer/src/constants/applySerializedEventTargetProperties.ts create mode 100644 packages/twenty-front-component-renderer/src/types/SerializedEventData.ts create mode 100644 packages/twenty-front-component-renderer/src/types/SerializedFileData.ts diff --git a/packages/twenty-front-component-renderer/scripts/remote-dom/generators/remote-elements.generator.ts b/packages/twenty-front-component-renderer/scripts/remote-dom/generators/remote-elements.generator.ts index a017211fc8d95..1d4c58c024989 100644 --- a/packages/twenty-front-component-renderer/scripts/remote-dom/generators/remote-elements.generator.ts +++ b/packages/twenty-front-component-renderer/scripts/remote-dom/generators/remote-elements.generator.ts @@ -135,7 +135,14 @@ const generateCommonEventsType = ( }); writer.writeLine('}) as RemoteEvent;'); writer.blankLine(); - writer.writeLine('Object.assign(event, eventData);'); + writer.writeLine('applySerializedEventProperties('); + writer.indent(() => { + writer.writeLine( + 'event as unknown as Record,', + ); + writer.writeLine('eventData,'); + }); + writer.writeLine(');'); writer.blankLine(); writer.writeLine('return event;'); }); @@ -404,11 +411,18 @@ export const generateRemoteElements = ( }); sourceFile.addImportDeclaration({ - moduleSpecifier: '@/constants/SerializedEventData', - namedImports: [ - 'applySerializedEventTargetProperties', - { name: 'SerializedEventData', isTypeOnly: true }, - ], + moduleSpecifier: '@/constants/applySerializedEventProperties', + namedImports: ['applySerializedEventProperties'], + }); + + sourceFile.addImportDeclaration({ + moduleSpecifier: '@/constants/applySerializedEventTargetProperties', + namedImports: ['applySerializedEventTargetProperties'], + }); + + sourceFile.addImportDeclaration({ + moduleSpecifier: '@/types/SerializedEventData', + namedImports: [{ name: 'SerializedEventData', isTypeOnly: true }], }); const commonPropertyNames = new Set(Object.keys(commonProperties)); diff --git a/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-pointer.front-component.tsx b/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-pointer.front-component.tsx index 6f3b0eeb77f9f..79a91e0960fa4 100644 --- a/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-pointer.front-component.tsx +++ b/packages/twenty-front-component-renderer/src/__stories__/html-tag/svg/svg/svg-pointer.front-component.tsx @@ -1,14 +1,15 @@ -import { useState } from 'react'; -import { defineFrontComponent } from 'twenty-sdk/define'; import { EventLog, useEventLog, } from '@/__stories__/shared/front-components/event-log'; import { FrontComponentCard } from '@/__stories__/shared/front-components/front-component-card'; import { SVG_ROOT_STYLE } from '@/__stories__/shared/front-components/styles'; +import { useState } from 'react'; +import { defineFrontComponent } from 'twenty-sdk/define'; const SvgPointerFrontComponent = () => { const [interactionCount, setInteractionCount] = useState(0); + const [pointerCoordinates, setPointerCoordinates] = useState(''); const { entries, pushEvent } = useEventLog(); return ( @@ -18,6 +19,7 @@ const SvgPointerFrontComponent = () => { viewBox="0 0 200 120" onPointerDown={(event) => { setInteractionCount((previous) => previous + 1); + setPointerCoordinates(`${event.clientX},${event.clientY}`); pushEvent(event); }} onPointerMove={(event) => { @@ -29,6 +31,7 @@ const SvgPointerFrontComponent = () => { {interactionCount} + {pointerCoordinates} ); diff --git a/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/createHtmlElementStory.ts b/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/createHtmlElementStory.ts index fcd59db0ffc93..c632ee0a3deb3 100644 --- a/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/createHtmlElementStory.ts +++ b/packages/twenty-front-component-renderer/src/__stories__/shared/test-utils/createHtmlElementStory.ts @@ -1,5 +1,5 @@ import { type StoryObj } from '@storybook/react-vite'; -import { fireEvent, userEvent, within } from 'storybook/test'; +import { expect, fireEvent, userEvent, waitFor, within } from 'storybook/test'; import { expectEventLogged } from '@/__stories__/shared/test-utils/matchers/expectEventLogged'; import { expectFrontComponentMounted } from '@/__stories__/shared/test-utils/matchers/expectFrontComponentMounted'; @@ -48,6 +48,12 @@ export const createHtmlTagPointerStory = ({ canvas, matcher: { type: 'pointerdown', clientX: 123, clientY: 45 }, }); + + await waitFor(() => { + const coordinates = canvas.getByTestId('pointer-coordinates'); + + expect(coordinates.textContent).toBe('123,45'); + }); }, }); diff --git a/packages/twenty-front-component-renderer/src/constants/SerializedEventData.ts b/packages/twenty-front-component-renderer/src/constants/SerializedEventData.ts deleted file mode 100644 index 4b12cd0ec7742..0000000000000 --- a/packages/twenty-front-component-renderer/src/constants/SerializedEventData.ts +++ /dev/null @@ -1,110 +0,0 @@ -export type SerializedFileData = { - name: string; - size: number; - type: string; - lastModified: number; -}; - -export type SerializedEventData = { - type: string; - altKey?: boolean; - ctrlKey?: boolean; - metaKey?: boolean; - shiftKey?: boolean; - clientX?: number; - clientY?: number; - x?: number; - y?: number; - pageX?: number; - pageY?: number; - screenX?: number; - screenY?: number; - offsetX?: number; - offsetY?: number; - movementX?: number; - movementY?: number; - button?: number; - buttons?: number; - pointerId?: number; - pointerType?: string; - pressure?: number; - tangentialPressure?: number; - tiltX?: number; - tiltY?: number; - twist?: number; - width?: number; - height?: number; - isPrimary?: boolean; - key?: string; - code?: string; - repeat?: boolean; - value?: string; - checked?: boolean; - scrollTop?: number; - scrollLeft?: number; - deltaX?: number; - deltaY?: number; - deltaZ?: number; - deltaMode?: number; - currentTime?: number; - duration?: number; - paused?: boolean; - ended?: boolean; - volume?: number; - muted?: boolean; - playbackRate?: number; - files?: SerializedFileData[]; -}; - -export const applySerializedEventTargetProperties = ( - element: Record, - eventData: SerializedEventData, -): void => { - if ('value' in eventData) { - element.value = eventData.value; - } - - if ('checked' in eventData) { - element.checked = eventData.checked; - } - - if ('files' in eventData) { - element.files = eventData.files; - } - - if ('scrollTop' in eventData) { - element.scrollTop = eventData.scrollTop; - } - - if ('scrollLeft' in eventData) { - element.scrollLeft = eventData.scrollLeft; - } - - if ('currentTime' in eventData) { - element.currentTime = eventData.currentTime; - } - - if ('duration' in eventData) { - element.duration = eventData.duration; - } - - if ('paused' in eventData) { - element.paused = eventData.paused; - } - - if ('ended' in eventData) { - element.ended = eventData.ended; - } - - if ('volume' in eventData) { - element.volume = eventData.volume; - } - - if ('muted' in eventData) { - element.muted = eventData.muted; - } - - if ('playbackRate' in eventData) { - element.playbackRate = eventData.playbackRate; - } -}; diff --git a/packages/twenty-front-component-renderer/src/constants/applySerializedEventProperties.ts b/packages/twenty-front-component-renderer/src/constants/applySerializedEventProperties.ts new file mode 100644 index 0000000000000..385d18bafae21 --- /dev/null +++ b/packages/twenty-front-component-renderer/src/constants/applySerializedEventProperties.ts @@ -0,0 +1,50 @@ +import { type SerializedEventData } from '@/types/SerializedEventData'; + +const SERIALIZED_EVENT_PROPERTY_KEYS = [ + 'altKey', + 'ctrlKey', + 'metaKey', + 'shiftKey', + 'clientX', + 'clientY', + 'x', + 'y', + 'pageX', + 'pageY', + 'screenX', + 'screenY', + 'offsetX', + 'offsetY', + 'movementX', + 'movementY', + 'button', + 'buttons', + 'pointerId', + 'pointerType', + 'pressure', + 'tangentialPressure', + 'tiltX', + 'tiltY', + 'twist', + 'width', + 'height', + 'isPrimary', + 'key', + 'code', + 'repeat', + 'deltaX', + 'deltaY', + 'deltaZ', + 'deltaMode', +] as const satisfies readonly (keyof SerializedEventData)[]; + +export const applySerializedEventProperties = ( + event: Record, + eventData: SerializedEventData, +): void => { + for (const key of SERIALIZED_EVENT_PROPERTY_KEYS) { + if (key in eventData) { + event[key] = eventData[key]; + } + } +}; diff --git a/packages/twenty-front-component-renderer/src/constants/applySerializedEventTargetProperties.ts b/packages/twenty-front-component-renderer/src/constants/applySerializedEventTargetProperties.ts new file mode 100644 index 0000000000000..1cc6ea51805b8 --- /dev/null +++ b/packages/twenty-front-component-renderer/src/constants/applySerializedEventTargetProperties.ts @@ -0,0 +1,54 @@ +import { type SerializedEventData } from '@/types/SerializedEventData'; + +export const applySerializedEventTargetProperties = ( + element: Record, + eventData: SerializedEventData, +): void => { + if ('value' in eventData) { + element.value = eventData.value; + } + + if ('checked' in eventData) { + element.checked = eventData.checked; + } + + if ('files' in eventData) { + element.files = eventData.files; + } + + if ('scrollTop' in eventData) { + element.scrollTop = eventData.scrollTop; + } + + if ('scrollLeft' in eventData) { + element.scrollLeft = eventData.scrollLeft; + } + + if ('currentTime' in eventData) { + element.currentTime = eventData.currentTime; + } + + if ('duration' in eventData) { + element.duration = eventData.duration; + } + + if ('paused' in eventData) { + element.paused = eventData.paused; + } + + if ('ended' in eventData) { + element.ended = eventData.ended; + } + + if ('volume' in eventData) { + element.volume = eventData.volume; + } + + if ('muted' in eventData) { + element.muted = eventData.muted; + } + + if ('playbackRate' in eventData) { + element.playbackRate = eventData.playbackRate; + } +}; diff --git a/packages/twenty-front-component-renderer/src/host/utils/createHtmlHostWrapper.ts b/packages/twenty-front-component-renderer/src/host/utils/createHtmlHostWrapper.ts index 33ef85b785529..4c8d973a0f26d 100644 --- a/packages/twenty-front-component-renderer/src/host/utils/createHtmlHostWrapper.ts +++ b/packages/twenty-front-component-renderer/src/host/utils/createHtmlHostWrapper.ts @@ -11,10 +11,8 @@ import React, { useContext } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { EVENT_TO_REACT } from '@/constants/EventToReact'; -import { - type SerializedEventData, - type SerializedFileData, -} from '@/constants/SerializedEventData'; +import { type SerializedEventData } from '@/types/SerializedEventData'; +import { type SerializedFileData } from '@/types/SerializedFileData'; import { FrontComponentInputFocusContext, type SetEditableFocused, diff --git a/packages/twenty-front-component-renderer/src/remote/generated/remote-elements.ts b/packages/twenty-front-component-renderer/src/remote/generated/remote-elements.ts index b729b4d326cb6..51f0f92fe4dca 100644 --- a/packages/twenty-front-component-renderer/src/remote/generated/remote-elements.ts +++ b/packages/twenty-front-component-renderer/src/remote/generated/remote-elements.ts @@ -6,10 +6,9 @@ import { type RemoteElementEventListenerDefinition, type RemoteElementEventListenersDefinition, } from '@remote-dom/core/elements'; -import { - applySerializedEventTargetProperties, - type SerializedEventData, -} from '@/constants/SerializedEventData'; +import { applySerializedEventProperties } from '@/constants/applySerializedEventProperties'; +import { applySerializedEventTargetProperties } from '@/constants/applySerializedEventTargetProperties'; +import { type SerializedEventData } from '@/types/SerializedEventData'; export type HtmlCommonProperties = { id?: string; @@ -98,7 +97,10 @@ const createSerializedEventConfig = ( detail: eventData, }) as RemoteEvent; - Object.assign(event, eventData); + applySerializedEventProperties( + event as unknown as Record, + eventData, + ); return event; }, diff --git a/packages/twenty-front-component-renderer/src/types/SerializedEventData.ts b/packages/twenty-front-component-renderer/src/types/SerializedEventData.ts new file mode 100644 index 0000000000000..80863bfa625e4 --- /dev/null +++ b/packages/twenty-front-component-renderer/src/types/SerializedEventData.ts @@ -0,0 +1,52 @@ +import { type SerializedFileData } from '@/types/SerializedFileData'; + +export type SerializedEventData = { + type: string; + altKey?: boolean; + ctrlKey?: boolean; + metaKey?: boolean; + shiftKey?: boolean; + clientX?: number; + clientY?: number; + x?: number; + y?: number; + pageX?: number; + pageY?: number; + screenX?: number; + screenY?: number; + offsetX?: number; + offsetY?: number; + movementX?: number; + movementY?: number; + button?: number; + buttons?: number; + pointerId?: number; + pointerType?: string; + pressure?: number; + tangentialPressure?: number; + tiltX?: number; + tiltY?: number; + twist?: number; + width?: number; + height?: number; + isPrimary?: boolean; + key?: string; + code?: string; + repeat?: boolean; + value?: string; + checked?: boolean; + scrollTop?: number; + scrollLeft?: number; + deltaX?: number; + deltaY?: number; + deltaZ?: number; + deltaMode?: number; + currentTime?: number; + duration?: number; + paused?: boolean; + ended?: boolean; + volume?: number; + muted?: boolean; + playbackRate?: number; + files?: SerializedFileData[]; +}; diff --git a/packages/twenty-front-component-renderer/src/types/SerializedFileData.ts b/packages/twenty-front-component-renderer/src/types/SerializedFileData.ts new file mode 100644 index 0000000000000..e913f7abd6438 --- /dev/null +++ b/packages/twenty-front-component-renderer/src/types/SerializedFileData.ts @@ -0,0 +1,6 @@ +export type SerializedFileData = { + name: string; + size: number; + type: string; + lastModified: number; +}; From 12734165894153229a5ad7b0efeb3b53eb2bb228 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 2 Jun 2026 10:47:39 +0200 Subject: [PATCH 3/7] fix --- .../components/__stories__/PlaygroundSetupForm.stories.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/twenty-front/src/modules/settings/playground/components/__stories__/PlaygroundSetupForm.stories.tsx b/packages/twenty-front/src/modules/settings/playground/components/__stories__/PlaygroundSetupForm.stories.tsx index 48eaaa48feb04..d12d986cbcd60 100644 --- a/packages/twenty-front/src/modules/settings/playground/components/__stories__/PlaygroundSetupForm.stories.tsx +++ b/packages/twenty-front/src/modules/settings/playground/components/__stories__/PlaygroundSetupForm.stories.tsx @@ -1,11 +1,12 @@ import { PlaygroundSetupForm } from '@/settings/playground/components/PlaygroundSetupForm'; import { type Meta, type StoryObj } from '@storybook/react-vite'; import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing'; +import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; const meta: Meta = { title: 'Modules/Settings/Playground/PlaygroundSetupForm', component: PlaygroundSetupForm, - decorators: [ComponentDecorator, RouterDecorator], + decorators: [ComponentDecorator, RouterDecorator, SnackBarDecorator], parameters: { docs: { description: { From 299a6cc5da88567e7759d80dad2074d70450b3a4 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 2 Jun 2026 11:14:35 +0200 Subject: [PATCH 4/7] fix --- package.json | 2 ++ yarn.lock | 50 ++------------------------------------------------ 2 files changed, 4 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index b0a11cfe6c9af..63a7fada0fe85 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,8 @@ "graphql-redis-subscriptions/ioredis": "^5.6.0", "@lingui/core": "5.1.2", "@types/qs": "6.9.16", + "@types/react": "18.3.27", + "@types/react-dom": "18.3.0", "@wyw-in-js/transform@npm:0.6.0": "patch:@wyw-in-js/transform@npm%3A0.7.0#~/.yarn/patches/@wyw-in-js-transform-npm-0.7.0-ba641dc99f.patch", "@wyw-in-js/transform@npm:0.7.0": "patch:@wyw-in-js/transform@npm%3A0.7.0#~/.yarn/patches/@wyw-in-js-transform-npm-0.7.0-ba641dc99f.patch", "@opentelemetry/api": "1.9.1", diff --git a/yarn.lock b/yarn.lock index b9475879e48d9..19ffa35a25180 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24029,7 +24029,7 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.15": +"@types/react-dom@npm:18.3.0": version: 18.3.0 resolution: "@types/react-dom@npm:18.3.0" dependencies: @@ -24038,24 +24038,6 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^19": - version: 19.1.1 - resolution: "@types/react-dom@npm:19.1.1" - peerDependencies: - "@types/react": ^19.0.0 - checksum: 10c0/83833af502f501a372b370fdeb7cf933dfc8780903fe0e0d6e6a76b4ea3adbe5316159a62a0388d8afdd409afd76a40959e2ce82fbb788f57d32c786a63601ee - languageName: node - linkType: hard - -"@types/react-dom@npm:^19.0.0": - version: 19.2.3 - resolution: "@types/react-dom@npm:19.2.3" - peerDependencies: - "@types/react": ^19.2.0 - checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 - languageName: node - linkType: hard - "@types/react-grid-layout@npm:^1": version: 1.3.5 resolution: "@types/react-grid-layout@npm:1.3.5" @@ -24074,16 +24056,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:^19": - version: 19.1.0 - resolution: "@types/react@npm:19.1.0" - dependencies: - csstype: "npm:^3.0.2" - checksum: 10c0/632fd20ee176e55801a61c5f854141b043571a3e363ef106b047b766a813a12735cbb37abb3d61d126346979f530f2ed269a60c8ef3cdee54e5e9fe4174e5dad - languageName: node - linkType: hard - -"@types/react@npm:^18.0.0": +"@types/react@npm:18.3.27": version: 18.3.27 resolution: "@types/react@npm:18.3.27" dependencies: @@ -24093,25 +24066,6 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.39": - version: 18.3.3 - resolution: "@types/react@npm:18.3.3" - dependencies: - "@types/prop-types": "npm:*" - csstype: "npm:^3.0.2" - checksum: 10c0/fe455f805c5da13b89964c3d68060cebd43e73ec15001a68b34634604a78140e6fc202f3f61679b9d809dde6d7a7c2cb3ed51e0fd1462557911db09879b55114 - languageName: node - linkType: hard - -"@types/react@npm:^19.0.0": - version: 19.2.14 - resolution: "@types/react@npm:19.2.14" - dependencies: - csstype: "npm:^3.2.2" - checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 - languageName: node - linkType: hard - "@types/readdir-glob@npm:*": version: 1.1.5 resolution: "@types/readdir-glob@npm:1.1.5" From d4585fa50ceb3a76479a120111b7dcafdee2864c Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 2 Jun 2026 13:22:12 +0200 Subject: [PATCH 5/7] fix duplicated import --- .../components/__stories__/PlaygroundSetupForm.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/twenty-front/src/modules/settings/playground/components/__stories__/PlaygroundSetupForm.stories.tsx b/packages/twenty-front/src/modules/settings/playground/components/__stories__/PlaygroundSetupForm.stories.tsx index c4e0c409b2e7c..aacfbd9d99710 100644 --- a/packages/twenty-front/src/modules/settings/playground/components/__stories__/PlaygroundSetupForm.stories.tsx +++ b/packages/twenty-front/src/modules/settings/playground/components/__stories__/PlaygroundSetupForm.stories.tsx @@ -2,7 +2,6 @@ import { PlaygroundSetupForm } from '@/settings/playground/components/Playground import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; import { type Meta, type StoryObj } from '@storybook/react-vite'; import { ComponentDecorator, RouterDecorator } from 'twenty-ui/testing'; -import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; const meta: Meta = { title: 'Modules/Settings/Playground/PlaygroundSetupForm', From 286c07b5ff72f483961d1c44af9b2925bb42d00b Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 2 Jun 2026 14:29:15 +0200 Subject: [PATCH 6/7] fix --- package.json | 2 -- yarn.lock | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 63a7fada0fe85..b0a11cfe6c9af 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,6 @@ "graphql-redis-subscriptions/ioredis": "^5.6.0", "@lingui/core": "5.1.2", "@types/qs": "6.9.16", - "@types/react": "18.3.27", - "@types/react-dom": "18.3.0", "@wyw-in-js/transform@npm:0.6.0": "patch:@wyw-in-js/transform@npm%3A0.7.0#~/.yarn/patches/@wyw-in-js-transform-npm-0.7.0-ba641dc99f.patch", "@wyw-in-js/transform@npm:0.7.0": "patch:@wyw-in-js/transform@npm%3A0.7.0#~/.yarn/patches/@wyw-in-js-transform-npm-0.7.0-ba641dc99f.patch", "@opentelemetry/api": "1.9.1", diff --git a/yarn.lock b/yarn.lock index ed47e8b5274ee..acf928c1c13c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24029,12 +24029,21 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:18.3.0": - version: 18.3.0 - resolution: "@types/react-dom@npm:18.3.0" - dependencies: - "@types/react": "npm:*" - checksum: 10c0/6c90d2ed72c5a0e440d2c75d99287e4b5df3e7b011838cdc03ae5cd518ab52164d86990e73246b9d812eaf02ec351d74e3b4f5bd325bf341e13bf980392fd53b +"@types/react-dom@npm:^18.2.15": + version: 18.3.7 + resolution: "@types/react-dom@npm:18.3.7" + peerDependencies: + "@types/react": ^18.0.0 + checksum: 10c0/8bd309e2c3d1604a28a736a24f96cbadf6c05d5288cfef8883b74f4054c961b6b3a5e997fd5686e492be903c8f3380dba5ec017eff3906b1256529cd2d39603e + languageName: node + linkType: hard + +"@types/react-dom@npm:^19, @types/react-dom@npm:^19.0.0": + version: 19.2.3 + resolution: "@types/react-dom@npm:19.2.3" + peerDependencies: + "@types/react": ^19.2.0 + checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 languageName: node linkType: hard @@ -24056,13 +24065,22 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:18.3.27": - version: 18.3.27 - resolution: "@types/react@npm:18.3.27" +"@types/react@npm:*, @types/react@npm:^19, @types/react@npm:^19.0.0": + version: 19.2.15 + resolution: "@types/react@npm:19.2.15" + dependencies: + csstype: "npm:^3.2.2" + checksum: 10c0/b554eab715bb14e581f0ae60e5cefe91e1a5e06c31022b543a9806cf224aa056f21e4fb46208e46eb934d86ca0b247ebc82377192a0dead303cb28b8764c6e67 + languageName: node + linkType: hard + +"@types/react@npm:^18.0.0, @types/react@npm:^18.2.39": + version: 18.3.29 + resolution: "@types/react@npm:18.3.29" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.2.2" - checksum: 10c0/a761d2f58de03d0714806cc65d32bb3d73fb33a08dd030d255b47a295e5fff2a775cf1c20b786824d8deb6454eaccce9bc6998d9899c14fc04bbd1b0b0b72897 + checksum: 10c0/b582f5c3a034229b2e287f5e39aebf3988d6ce79e7fd81c8257dc55bee0e321ddf708d6014a44c5ceae8debea1e15a93326b207a4fec6a0170200a03d105adfb languageName: node linkType: hard From 9241f62dee22c1f856e73a80ff9e26f5f915bab1 Mon Sep 17 00:00:00 2001 From: bosiraphael Date: Tue, 2 Jun 2026 16:31:09 +0200 Subject: [PATCH 7/7] fix --- yarn.lock | 54 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/yarn.lock b/yarn.lock index 83f8680068471..3216ba17dbb7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24398,15 +24398,24 @@ __metadata: linkType: hard "@types/react-dom@npm:^18.2.15": - version: 18.3.7 - resolution: "@types/react-dom@npm:18.3.7" + version: 18.3.0 + resolution: "@types/react-dom@npm:18.3.0" + dependencies: + "@types/react": "npm:*" + checksum: 10c0/6c90d2ed72c5a0e440d2c75d99287e4b5df3e7b011838cdc03ae5cd518ab52164d86990e73246b9d812eaf02ec351d74e3b4f5bd325bf341e13bf980392fd53b + languageName: node + linkType: hard + +"@types/react-dom@npm:^19": + version: 19.1.1 + resolution: "@types/react-dom@npm:19.1.1" peerDependencies: - "@types/react": ^18.0.0 - checksum: 10c0/8bd309e2c3d1604a28a736a24f96cbadf6c05d5288cfef8883b74f4054c961b6b3a5e997fd5686e492be903c8f3380dba5ec017eff3906b1256529cd2d39603e + "@types/react": ^19.0.0 + checksum: 10c0/83833af502f501a372b370fdeb7cf933dfc8780903fe0e0d6e6a76b4ea3adbe5316159a62a0388d8afdd409afd76a40959e2ce82fbb788f57d32c786a63601ee languageName: node linkType: hard -"@types/react-dom@npm:^19, @types/react-dom@npm:^19.0.0": +"@types/react-dom@npm:^19.0.0": version: 19.2.3 resolution: "@types/react-dom@npm:19.2.3" peerDependencies: @@ -24433,22 +24442,41 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:^19, @types/react@npm:^19.0.0": - version: 19.2.15 - resolution: "@types/react@npm:19.2.15" +"@types/react@npm:*, @types/react@npm:^19": + version: 19.1.0 + resolution: "@types/react@npm:19.1.0" + dependencies: + csstype: "npm:^3.0.2" + checksum: 10c0/632fd20ee176e55801a61c5f854141b043571a3e363ef106b047b766a813a12735cbb37abb3d61d126346979f530f2ed269a60c8ef3cdee54e5e9fe4174e5dad + languageName: node + linkType: hard + +"@types/react@npm:^18.0.0": + version: 18.3.27 + resolution: "@types/react@npm:18.3.27" dependencies: + "@types/prop-types": "npm:*" csstype: "npm:^3.2.2" - checksum: 10c0/b554eab715bb14e581f0ae60e5cefe91e1a5e06c31022b543a9806cf224aa056f21e4fb46208e46eb934d86ca0b247ebc82377192a0dead303cb28b8764c6e67 + checksum: 10c0/a761d2f58de03d0714806cc65d32bb3d73fb33a08dd030d255b47a295e5fff2a775cf1c20b786824d8deb6454eaccce9bc6998d9899c14fc04bbd1b0b0b72897 languageName: node linkType: hard -"@types/react@npm:^18.0.0, @types/react@npm:^18.2.39": - version: 18.3.29 - resolution: "@types/react@npm:18.3.29" +"@types/react@npm:^18.2.39": + version: 18.3.3 + resolution: "@types/react@npm:18.3.3" dependencies: "@types/prop-types": "npm:*" + csstype: "npm:^3.0.2" + checksum: 10c0/fe455f805c5da13b89964c3d68060cebd43e73ec15001a68b34634604a78140e6fc202f3f61679b9d809dde6d7a7c2cb3ed51e0fd1462557911db09879b55114 + languageName: node + linkType: hard + +"@types/react@npm:^19.0.0": + version: 19.2.14 + resolution: "@types/react@npm:19.2.14" + dependencies: csstype: "npm:^3.2.2" - checksum: 10c0/b582f5c3a034229b2e287f5e39aebf3988d6ce79e7fd81c8257dc55bee0e321ddf708d6014a44c5ceae8debea1e15a93326b207a4fec6a0170200a03d105adfb + checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 languageName: node linkType: hard