import React, { useMemo } from 'react' import { useGridComponents } from '../context/grid-components-context/hook' import { useColumnResize } from '../hooks/use-column-resize' import { useGridContext, useGridSelector } from '../context/grid-context/hook' import { useFocusHandler } from '../hooks' import { size, useIsFocusVisible } from '@planview/pv-utilities' import { GridHeaderGroupCellDefaultRenderer } from '../renderers/' import type { GridRowId } from '../types' import { useDraggable } from '@dnd-kit/core' import { DRAG_TYPE_HEADER_GROUP_CELL } from './grid-drag-controller' import { createSelector } from 'reselect' export type GridHeaderGroupCellProps = { columnId: string columnIndex: number rowId: GridRowId height: number columnSpan: number tabIndex?: number placeholder?: boolean lastPlaceholder?: boolean } const stopPropagation: React.MouseEventHandler = (e): void => { e.stopPropagation() } export const GridHeaderGroupCell = ({ columnId, columnIndex, rowId, height, columnSpan, placeholder = false, lastPlaceholder = false, }: GridHeaderGroupCellProps) => { const { GridHeaderGroupCellLayout, GridCellFocusLayout, GridColumnMoveHandle, GridColumnResizeHandle, } = useGridComponents() const { selectors } = useGridContext() const { actualWidth, data: column } = useGridSelector((state) => selectors.selectColumn(state, columnId) ) const focusProps = useIsFocusVisible() const [hovering, setHovering] = React.useState(false) const [hasFocus, handleFocus] = useFocusHandler(columnId, 'header', rowId) const onEnter = React.useCallback(() => setHovering(true), []) const onLeave = React.useCallback(() => setHovering(false), []) const [resizing, resizeHandlers] = useColumnResize(column.id, actualWidth) const draggingSelector = useMemo( () => createSelector([selectors.selectHeaderHierarchy], ({ groups }) => { const { columnIds: columnsDragged } = groups.find( (g) => g.id === columnId )! const groupsDragged = groups.reduce( (prev, curr) => { if ( curr.childIds && curr.parentIds.includes(columnId) ) { prev.push(curr.id) } return prev }, [columnId] ) return { columnsDragged, groupsDragged } }), [columnId, selectors] ) const { columnsDragged, groupsDragged } = useGridSelector(draggingSelector) const { attributes, listeners, setNodeRef, setActivatorNodeRef, isDragging, } = useDraggable({ id: columnId, data: { type: DRAG_TYPE_HEADER_GROUP_CELL, columnsDragged, groupsDragged, column, height, offsetY: height - size.small, }, disabled: !column.movable, }) React.useEffect(() => { if (isDragging) { setHovering(false) } }, [isDragging]) const onPointerDown = listeners?.onPointerDown const handlePointerDown = React.useCallback< React.PointerEventHandler >( (e) => { handleFocus() onPointerDown?.(e) }, [handleFocus, onPointerDown] ) const sticky = column.sticky === 'left' || column.sticky === 'right' ? column.sticky : null const stickyOffset = useGridSelector((state) => selectors.selectColumnGroupStickyOffset(state, columnId) ) const extraStyle: Partial | null = sticky ? { [sticky]: stickyOffset, } : null return ( 1 ? columnSpan : undefined} > {!placeholder && ( )} {column.movable && hovering && !resizing && !placeholder ? ( ) : null} {((column.resizable && hovering) || resizing) && !placeholder ? ( ) : null} ) } export const GridHeaderGroupCellMemo = React.memo( GridHeaderGroupCell ) as typeof GridHeaderGroupCell