From 383935d0d9302d3afd18d3cccf0c152d303a8bc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20Bosi?=
<71827178+bosiraphael@users.noreply.github.com>
Date: Mon, 30 Mar 2026 19:07:49 +0200
Subject: [PATCH] Fix widgets drag handles (#19133)
- Remove drag handles and cursor resize for the placeholder
- Fix the drag handles no longer appearing on hover and always present
drag handle for north and south
This was due to the linaria migration: adding a minus sign or px after a
css variable isn't working, we have to use calc.
## Before
https://github.com/user-attachments/assets/cba398ab-92c8-4924-ba3c-1a28fb4fd163
## After
https://github.com/user-attachments/assets/aec675cd-b809-434d-a8a7-edb12ce37364
---
.../components/PageLayoutGridLayout.tsx | 8 ++-
.../components/PageLayoutGridResizeHandle.tsx | 58 ++++++++++++-------
2 files changed, 41 insertions(+), 25 deletions(-)
diff --git a/packages/twenty-front/src/modules/page-layout/components/PageLayoutGridLayout.tsx b/packages/twenty-front/src/modules/page-layout/components/PageLayoutGridLayout.tsx
index f7edc20559..8d680f84c9 100644
--- a/packages/twenty-front/src/modules/page-layout/components/PageLayoutGridLayout.tsx
+++ b/packages/twenty-front/src/modules/page-layout/components/PageLayoutGridLayout.tsx
@@ -205,13 +205,15 @@ export const PageLayoutGridLayout = ({ tabId }: PageLayoutGridLayoutProps) => {
maxCols={12}
containerPadding={[0, 0]}
margin={[PAGE_LAYOUT_GRID_MARGIN, PAGE_LAYOUT_GRID_MARGIN]}
- isDraggable={isPageLayoutInEditMode}
- isResizable={isPageLayoutInEditMode}
+ isDraggable={isPageLayoutInEditMode && !isLayoutEmpty}
+ isResizable={isPageLayoutInEditMode && !isLayoutEmpty}
draggableHandle=".drag-handle"
compactType="vertical"
preventCollision={false}
resizeHandle={
- isPageLayoutInEditMode ? : undefined
+ isPageLayoutInEditMode && !isLayoutEmpty ? (
+
+ ) : undefined
}
resizeHandles={['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw']}
onDragStart={(_layout, _oldItem, newItem) => {
diff --git a/packages/twenty-front/src/modules/page-layout/components/PageLayoutGridResizeHandle.tsx b/packages/twenty-front/src/modules/page-layout/components/PageLayoutGridResizeHandle.tsx
index f4b7d5f2ea..2cdf9c7723 100644
--- a/packages/twenty-front/src/modules/page-layout/components/PageLayoutGridResizeHandle.tsx
+++ b/packages/twenty-front/src/modules/page-layout/components/PageLayoutGridResizeHandle.tsx
@@ -6,8 +6,7 @@ import {
IconRadiusTopLeft,
IconRadiusTopRight,
} from 'twenty-ui/display';
-import { ResizeHandle } from 'twenty-ui/layout';
-import { themeCssVariables, ThemeContext } from 'twenty-ui/theme-constants';
+import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type WidgetHandleAxis = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';
type WidgetHorizontalHandleAxis = 'n' | 's';
type WidgetVerticalHandleAxis = 'e' | 'w';
@@ -32,28 +31,28 @@ const StyledCornerIconWrapper = styled.div<{
justify-content: center;
width: ${themeCssVariables.spacing[4]};
- & svg {
+ & > svg {
color: transparent;
flex-shrink: 0;
pointer-events: none;
transform: ${({ position }) => {
if (position === 'se') {
- return `translate(-${themeCssVariables.spacing[2]}, -${themeCssVariables.spacing[2]})`;
+ return `translate(calc(-1 * ${themeCssVariables.spacing[2]}), calc(-1 * ${themeCssVariables.spacing[2]}))`;
}
if (position === 'sw') {
- return `translate(${themeCssVariables.spacing[2]}, -${themeCssVariables.spacing[2]})`;
+ return `translate(${themeCssVariables.spacing[2]}, calc(-1 * ${themeCssVariables.spacing[2]}))`;
}
if (position === 'ne') {
- return `translate(-${themeCssVariables.spacing[2]}, ${themeCssVariables.spacing[2]})`;
+ return `translate(calc(-1 * ${themeCssVariables.spacing[2]}), ${themeCssVariables.spacing[2]})`;
}
if (position === 'nw') {
- return `translate(${themeCssVariables.spacing[2]}, ${themeCssVariables.spacing[2]})`;
+ return `translate( ${themeCssVariables.spacing[2]}, ${themeCssVariables.spacing[2]})`;
}
return '';
}};
}
- :hover {
+ &:hover {
svg {
color: ${themeCssVariables.font.color.tertiary};
}
@@ -63,7 +62,7 @@ const StyledCornerIconWrapper = styled.div<{
const StyledVerticalHandle = styled.div`
border-radius: ${themeCssVariables.border.radius.sm};
height: ${themeCssVariables.spacing[5]};
- width: ${themeCssVariables.icon.stroke.lg}px;
+ width: calc(${themeCssVariables.icon.stroke.lg} * 1px);
`;
const StyledVerticalHandleWrapper = styled.div<{
@@ -75,13 +74,34 @@ const StyledVerticalHandleWrapper = styled.div<{
transform: ${({ widgetHandleAxis }) =>
widgetHandleAxis === 'w' ? 'translateX(-50%)' : 'translateX(50%)'};
- :hover {
+ &:hover {
& > div {
background-color: ${themeCssVariables.font.color.tertiary};
}
}
`;
+const StyledHorizontalHandle = styled.div`
+ border-radius: ${themeCssVariables.border.radius.sm};
+ height: calc(${themeCssVariables.icon.stroke.lg} * 1px);
+ width: ${themeCssVariables.spacing[5]};
+`;
+
+const StyledHorizontalHandleWrapper = styled.div<{
+ widgetHandleAxis: WidgetHorizontalHandleAxis;
+}>`
+ border-radius: ${themeCssVariables.border.radius.sm};
+ cursor: row-resize;
+ padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[2]};
+ transform: ${({ widgetHandleAxis }) =>
+ widgetHandleAxis === 'n' ? 'translateY(-50%)' : 'translateY(50%)'};
+ &:hover {
+ & div {
+ background-color: ${themeCssVariables.font.color.tertiary};
+ }
+ }
+`;
+
const StyledResizeHandleWrapper = styled.div<{
widgetHandleAxis?: WidgetHandleAxis;
}>`
@@ -124,11 +144,11 @@ const StyledResizeHandleWrapper = styled.div<{
case 'se':
return `translate(${themeCssVariables.spacing[1]}, ${themeCssVariables.spacing[1]})`;
case 'sw':
- return `translate(-${themeCssVariables.spacing[1]}, ${themeCssVariables.spacing[1]})`;
+ return `translate(calc(-1 * ${themeCssVariables.spacing[1]}), ${themeCssVariables.spacing[1]})`;
case 'ne':
- return `translate(${themeCssVariables.spacing[1]}, -${themeCssVariables.spacing[1]})`;
+ return `translate(${themeCssVariables.spacing[1]}, calc(-1 * ${themeCssVariables.spacing[1]}))`;
case 'nw':
- return `translate(-${themeCssVariables.spacing[1]}, -${themeCssVariables.spacing[1]})`;
+ return `translate(calc(-1 * ${themeCssVariables.spacing[1]}), calc(-1 * ${themeCssVariables.spacing[1]}))`;
default:
return 'none';
}
@@ -178,15 +198,9 @@ export const PageLayoutGridResizeHandle = forwardRef<
)}
{isHorizontalHandle(widgetHandleAxis) && (
-
+
+
+
)}
{widgetHandleAxis === 'ne' && (