From d9757c2da7fd9f396345eb398cbece09c297dbb1 Mon Sep 17 00:00:00 2001 From: Sonarly Claude Code Date: Mon, 23 Mar 2026 07:47:55 +0000 Subject: [PATCH] fix: move droppable placeholder back inside innerRef container in Kanban board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://sonarly.com/issue/17390?type=bug Kanban board drops only register near the top of target columns because the `@hello-pangea/dnd` placeholder was moved outside the `innerRef` container, breaking the library's droppable area measurement. Fix: **What changed:** Moved `droppableProvided.innerRef` and `droppableProvided.droppableProps` from `StyledColumnCardsContainer` (inside the memo boundary) up to `StyledColumn` in `RecordBoardColumn.tsx` (outside the memo boundary). This ensures both the card list and the placeholder are children of the `innerRef` element, which is required by `@hello-pangea/dnd` for correct droppable area measurement. **RecordBoardColumn.tsx:** - Added `ref={droppableProvided.innerRef}` and `{...droppableProvided.droppableProps}` to `StyledColumn` - Removed `droppableProvided` from props passed to `RecordBoardColumnCardsContainer` **RecordBoardColumnCardsContainer.tsx:** - Removed `droppableProvided` from component props and type definition - Removed `ref` and spread of `droppableProps` from `StyledColumnCardsContainer` - Removed unused `DroppableProvided` type import **Why this works:** The `DragAndDropLibraryLegacyReRenderBreaker` (React.memo wrapper) blocks re-renders of the card list during drag — this is the performance optimization from PR #15714. Previously, to work around this, the placeholder was placed outside the `innerRef` container, breaking drop zone detection. By lifting `innerRef` to the parent `StyledColumn`, both the memo'd cards and the placeholder live inside the `innerRef` DOM element, satisfying the library's requirements while preserving the performance optimization. --- .../components/RecordBoardColumn.tsx | 7 +++++-- .../components/RecordBoardColumnCardsContainer.tsx | 10 ++-------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx index 4f5f11c192d..2beeb0bcadf 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx @@ -65,12 +65,15 @@ export const RecordBoardColumn = ({ > {(droppableProvided) => ( - + diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer.tsx index 8b00df02b08..e6c61c3046e 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer.tsx @@ -1,5 +1,5 @@ import { styled } from '@linaria/react'; -import { Draggable, type DroppableProvided } from '@hello-pangea/dnd'; +import { Draggable } from '@hello-pangea/dnd'; import { useContext } from 'react'; import { themeCssVariables } from 'twenty-ui/theme-constants'; @@ -25,12 +25,10 @@ const StyledNewButtonContainer = styled.div` type RecordBoardColumnCardsContainerProps = { recordBoardColumnId: string; - droppableProvided: DroppableProvided; }; export const RecordBoardColumnCardsContainer = ({ recordBoardColumnId, - droppableProvided, }: RecordBoardColumnCardsContainerProps) => { const { columnDefinition } = useContext(RecordBoardColumnContext); @@ -45,11 +43,7 @@ export const RecordBoardColumnCardsContainer = ({ ); return ( - + {recordIndexRecordIdsByGroup.map((recordId, index) => (