Skip to content

Commit fa90eba

Browse files
committed
feat: enhance drag-and-drop functionality with DragHandle component
1 parent 838cc47 commit fa90eba

File tree

2 files changed

+56
-9
lines changed

2 files changed

+56
-9
lines changed

packages/pluggableWidgets/datagrid-web/src/components/ColumnContainer.tsx

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import classNames from "classnames";
2-
import { HTMLAttributes, KeyboardEvent, ReactElement, ReactNode, useMemo } from "react";
2+
import { DragEventHandler, HTMLAttributes, KeyboardEvent, ReactElement, ReactNode, useMemo } from "react";
33
import { FaArrowsAltV } from "./icons/FaArrowsAltV";
44
import { FaLongArrowAltDown } from "./icons/FaLongArrowAltDown";
55
import { FaLongArrowAltUp } from "./icons/FaLongArrowAltUp";
@@ -16,6 +16,11 @@ export interface ColumnContainerProps {
1616
isLast?: boolean;
1717
resizer: ReactElement<ColumnResizerProps>;
1818
}
19+
interface DragHandleProps {
20+
draggable: boolean;
21+
onDragStart?: DragEventHandler<HTMLSpanElement>;
22+
onDragEnd?: DragEventHandler<HTMLSpanElement>;
23+
}
1924

2025
export const ColumnContainer = observer(function ColumnContainer(props: ColumnContainerProps): ReactElement {
2126
const { columnsFilterable, id: gridId } = useDatagridConfig();
@@ -57,20 +62,24 @@ export const ColumnContainer = observer(function ColumnContainer(props: ColumnCo
5762
onDragEnter={draggableProps.onDragEnter}
5863
onDragOver={draggableProps.onDragOver}
5964
>
60-
<div
61-
className={classNames("column-container")}
62-
id={`${gridId}-column${column.columnId}`}
63-
draggable={draggableProps.draggable}
64-
onDragStart={draggableProps.onDragStart}
65-
onDragEnd={draggableProps.onDragEnd}
66-
>
65+
<div className={classNames("column-container")} id={`${gridId}-column${column.columnId}`}>
6766
<ColumnHeader
6867
sortProps={sortProps}
6968
canSort={canSort}
7069
caption={caption}
7170
isDragging={isDragging}
7271
columnAlignment={column.alignment}
7372
>
73+
{draggableProps.draggable && (
74+
<DragHandle
75+
draggable={draggableProps.draggable}
76+
onDragStart={draggableProps.onDragStart}
77+
onDragEnd={draggableProps.onDragEnd}
78+
/>
79+
)}
80+
<span style={draggableProps.draggable ? { paddingInlineStart: "4px" } : undefined}>
81+
{caption.length > 0 ? caption : "\u00a0"}
82+
</span>
7483
{canSort ? <SortIcon /> : null}
7584
</ColumnHeader>
7685
{columnsFilterable && (
@@ -84,6 +93,45 @@ export const ColumnContainer = observer(function ColumnContainer(props: ColumnCo
8493
);
8594
});
8695

96+
function DragHandle({ draggable, onDragStart, onDragEnd }: DragHandleProps): ReactElement {
97+
const handleMouseDown = (e: React.MouseEvent) => {
98+
// Only stop propagation, don't prevent default - we need default for drag to work
99+
e.stopPropagation();
100+
};
101+
102+
const handleClick = (e: React.MouseEvent) => {
103+
// Stop click events from bubbling to prevent sorting
104+
e.stopPropagation();
105+
e.preventDefault();
106+
};
107+
108+
const handleDragStart = (e: React.DragEvent<HTMLSpanElement>) => {
109+
// Don't stop propagation here - let the drag start properly
110+
if (onDragStart) {
111+
onDragStart(e);
112+
}
113+
};
114+
115+
const handleDragEnd = (e: React.DragEvent<HTMLSpanElement>) => {
116+
if (onDragEnd) {
117+
onDragEnd(e);
118+
}
119+
};
120+
121+
return (
122+
<span
123+
className="drag-handle"
124+
draggable={draggable}
125+
onDragStart={handleDragStart}
126+
onDragEnd={handleDragEnd}
127+
onMouseDown={handleMouseDown}
128+
onClick={handleClick}
129+
>
130+
131+
</span>
132+
);
133+
}
134+
87135
function SortIcon(): ReactNode {
88136
const column = useColumn();
89137
switch (column.sortDir) {

packages/pluggableWidgets/datagrid-web/src/components/ColumnHeader.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export default function ColumnHeader(props: ColumnHeaderProps): ReactElement {
2222
{...props.sortProps}
2323
aria-label={props.canSort ? "sort " + props.caption : props.caption}
2424
>
25-
<span>{props.caption.length > 0 ? props.caption : "\u00a0"}</span>
2625
{props.children}
2726
</div>
2827
);

0 commit comments

Comments
 (0)