import { type MouseEvent, useState } from 'react'; import Menu, { type MenuProps } from '@mui/material/Menu'; import { MRT_ActionMenuItem } from './MRT_ActionMenuItem'; import { MRT_FilterOptionMenu } from './MRT_FilterOptionMenu'; import { type MRT_Header, type MRT_RowData, type MRT_TableInstance, } from '../../types'; export interface MRT_ColumnActionMenuProps extends Partial { anchorEl: HTMLElement | null; header: MRT_Header; setAnchorEl: (anchorEl: HTMLElement | null) => void; table: MRT_TableInstance; } export const MRT_ColumnActionMenu = ({ anchorEl, header, setAnchorEl, table, ...rest }: MRT_ColumnActionMenuProps) => { const { getAllLeafColumns, getState, options: { columnFilterDisplayMode, columnFilterModeOptions, enableColumnFilterModes, enableColumnFilters, enableColumnPinning, enableColumnResizing, enableGrouping, enableHiding, enableSorting, enableSortingRemoval, icons: { ClearAllIcon, DynamicFeedIcon, FilterListIcon, FilterListOffIcon, PushPinIcon, RestartAltIcon, SortIcon, ViewColumnIcon, VisibilityOffIcon, }, localization, mrtTheme: { menuBackgroundColor }, renderColumnActionsMenuItems, }, refs: { filterInputRefs }, setColumnFilterFns, setColumnOrder, setColumnSizingInfo, setShowColumnFilters, } = table; const { column } = header; const { columnDef } = column; const { columnSizing, columnVisibility, density, showColumnFilters } = getState(); const columnFilterValue = column.getFilterValue(); const [filterMenuAnchorEl, setFilterMenuAnchorEl] = useState(null); const handleClearSort = () => { column.clearSorting(); setAnchorEl(null); }; const handleSortAsc = () => { column.toggleSorting(false); setAnchorEl(null); }; const handleSortDesc = () => { column.toggleSorting(true); setAnchorEl(null); }; const handleResetColumnSize = () => { setColumnSizingInfo((old) => ({ ...old, isResizingColumn: false })); column.resetSize(); setAnchorEl(null); }; const handleHideColumn = () => { column.toggleVisibility(false); setAnchorEl(null); }; const handlePinColumn = (pinDirection: 'left' | 'right' | false) => { column.pin(pinDirection); setAnchorEl(null); }; const handleGroupByColumn = () => { column.toggleGrouping(); setColumnOrder((old: any) => ['mrt-row-expand', ...old]); setAnchorEl(null); }; const handleClearFilter = () => { column.setFilterValue(undefined); setAnchorEl(null); if (['empty', 'notEmpty'].includes(columnDef._filterFn)) { setColumnFilterFns((prev) => ({ ...prev, [header.id]: allowedColumnFilterOptions?.[0] ?? 'fuzzy', })); } }; const handleFilterByColumn = () => { setShowColumnFilters(true); queueMicrotask(() => filterInputRefs.current?.[`${column.id}-0`]?.focus()); setAnchorEl(null); }; const handleShowAllColumns = () => { getAllLeafColumns() .filter((col) => col.columnDef.enableHiding !== false) .forEach((col) => col.toggleVisibility(true)); setAnchorEl(null); }; const handleOpenFilterModeMenu = (event: MouseEvent) => { event.stopPropagation(); setFilterMenuAnchorEl(event.currentTarget); }; const isSelectFilter = !!columnDef.filterSelectOptions; const allowedColumnFilterOptions = columnDef?.columnFilterModeOptions ?? columnFilterModeOptions; const showFilterModeSubMenu = enableColumnFilterModes && columnDef.enableColumnFilterModes !== false && !isSelectFilter && (allowedColumnFilterOptions === undefined || !!allowedColumnFilterOptions?.length); const internalColumnMenuItems = [ ...(enableSorting && column.getCanSort() ? [ enableSortingRemoval !== false && ( } key={0} label={localization.clearSort} onClick={handleClearSort} table={table} /> ), } key={1} label={localization.sortByColumnAsc?.replace( '{column}', String(columnDef.header), )} onClick={handleSortAsc} table={table} />, } key={2} label={localization.sortByColumnDesc?.replace( '{column}', String(columnDef.header), )} onClick={handleSortDesc} table={table} />, ] : []), ...(enableColumnFilters && column.getCanFilter() ? [ value).length) } icon={} key={3} label={localization.clearFilter} onClick={handleClearFilter} table={table} />, columnFilterDisplayMode === 'subheader' && ( } key={4} label={localization.filterByColumn?.replace( '{column}', String(columnDef.header), )} onClick={ showColumnFilters ? handleOpenFilterModeMenu : handleFilterByColumn } onOpenSubMenu={ showFilterModeSubMenu ? handleOpenFilterModeMenu : undefined } table={table} /> ), showFilterModeSubMenu && ( ), ].filter(Boolean) : []), ...(enableGrouping && column.getCanGroup() ? [ } key={6} label={localization[ column.getIsGrouped() ? 'ungroupByColumn' : 'groupByColumn' ]?.replace('{column}', String(columnDef.header))} onClick={handleGroupByColumn} table={table} />, ] : []), ...(enableColumnPinning && column.getCanPin() ? [ } key={7} label={localization.pinToLeft} onClick={() => handlePinColumn('left')} table={table} />, } key={8} label={localization.pinToRight} onClick={() => handlePinColumn('right')} table={table} />, } key={9} label={localization.unpin} onClick={() => handlePinColumn(false)} table={table} />, ] : []), ...(enableColumnResizing && column.getCanResize() ? [ } key={10} label={localization.resetColumnSize} onClick={handleResetColumnSize} table={table} />, ] : []), ...(enableHiding ? [ } key={11} label={localization.hideColumn?.replace( '{column}', String(columnDef.header), )} onClick={handleHideColumn} table={table} />, !visible) .length } icon={} key={12} label={localization.showAllColumns?.replace( '{column}', String(columnDef.header), )} onClick={handleShowAllColumns} table={table} />, ] : []), ].filter(Boolean); return ( setAnchorEl(null)} open={!!anchorEl} {...rest} > {columnDef.renderColumnActionsMenuItems?.({ closeMenu: () => setAnchorEl(null), column, internalColumnMenuItems, table, }) ?? renderColumnActionsMenuItems?.({ closeMenu: () => setAnchorEl(null), column, internalColumnMenuItems, table, }) ?? internalColumnMenuItems} ); };