11import classNames from "classnames" ;
2- import { HTMLAttributes , KeyboardEvent , ReactElement , ReactNode , useMemo } from "react" ;
2+ import { DragEventHandler , HTMLAttributes , KeyboardEvent , ReactElement , ReactNode , useMemo } from "react" ;
33import { FaArrowsAltV } from "./icons/FaArrowsAltV" ;
44import { FaLongArrowAltDown } from "./icons/FaLongArrowAltDown" ;
55import { 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
2025export 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+
87135function SortIcon ( ) : ReactNode {
88136 const column = useColumn ( ) ;
89137 switch ( column . sortDir ) {
0 commit comments