import { Fragment, memo } from 'react'; import { Group, ActionIcon, Tooltip, Menu, Divider, Box, Button, MantineSpacing } from '@mantine/core'; import { RowActionProps } from './types'; import { getIntentColor } from './utils'; import { MoreVertical } from 'lucide-react'; export interface RowActionsProps { /** Array of configured row-level actions. */ actions: RowActionProps[]; showLabels?: boolean; responsiveView?: boolean; gapActionDesktop?: MantineSpacing; gapActionMobile?: MantineSpacing; } /** * A lightweight presentational component optimized for rendering inside data grid rows. * Automatically handles tooltip generation and constructs dropdown menus for nested actions. * * @performance Wrapped in React.memo to guarantee zero overhead inside large lists/grids. */ export const RowActions = memo(function RowActions(props: RowActionsProps) { const { actions = [], showLabels = false, responsiveView = true, gapActionDesktop = 0, gapActionMobile = 0 } = props; /** * Helper function to render a standalone item. */ const renderItem = (action: RowActionProps, fallbackKey: string) => { const actionKey = action.key || fallbackKey; const isButton = showLabels; const handleClick = (e: React.MouseEvent) => { e.stopPropagation(); action.onClick?.(action.key || ''); }; if (isButton) { return ( ); } const iconBtn = ( {action.icon} ); return action.tooltip ? ( {iconBtn} ) : ( iconBtn ); }; const renderFlatActions = () => { return actions.map((action, index) => { if (action.type === 'divider') { return ; } if (action.children && action.children.length > 0) { return ( {renderItem(action, `action-${index}`)} {action.children.map((child, childIndex) => { if (child.type === 'divider') { return ; } return ( { e.stopPropagation(); child.onClick?.(child.key || ''); }} > {child.label} ); })} ); } return renderItem(action, `action-${index}`); }); }; return ( {/* --- DESKTOP VIEW (hidden on mobile devices) --- */} {renderFlatActions()} {/* --- MOBILE VIEW (hidden on desktop devices) --- */} {responsiveView && ( {actions.map((action, index) => { if (action.type === 'divider') { return ; } if (action.children && action.children.length > 0) { return ( {action.label} {action.children.map((child, childIndex) => { if (child.type === 'divider') { return ; } return ( { e.stopPropagation(); child.onClick?.(child.key || ''); }} style={{ paddingLeft: '1.5rem' }} mt="sm" mb="sm" > {child.label} ); })} ); } return ( { e.stopPropagation(); action.onClick?.(action.key || ''); }} mt="sm" mb="sm" > {action.label} ); })} )} ); });