# ActionTools Component The `ActionTools` suite provides flexible, responsive, and semantic action menus and toolbars for standardizing interactions across the application. It consists of two main presentational components: `PageActions` and `RowActions`. These components automatically adapt to screen sizes, handle tooltip generation, and construct dropdown menus for nested actions. ## Overview - **`PageActions`**: A responsive toolbar for page-level actions. On desktop, it renders a horizontal button group. On mobile, it collapses into a single "More" dropdown menu. Best used in page headers, toolbars, or detailed forms. - **`RowActions`**: A lightweight component optimized for dense areas like data grid rows or list items. It renders standalone icon buttons or kebab menus for nested actions. Uses `React.memo` for zero overhead inside large lists. ## Import Statement ```tsx import { PageActions, RowActions, type PageAction, type RowAction } from '@repo/ui/components'; ``` ## Usage Examples ### 1. Page Actions (Toolbars & Headers) `PageActions` requires a text `label` (unless the type is `divider`). You can customize the look using Mantine's button variants and map specific intents for semantic colors. ```tsx import { PageActions, type PageAction } from '@repo/ui/components'; import { Save, Printer, Trash, FileText, CheckCircle } from 'lucide-react'; function PageHeader() { const actions: PageAction[] = [ { key: 'save', label: 'Save Changes', icon: , intent: 'primary', onClick: (key) => console.log('Clicked', key), }, { type: 'divider' }, { key: 'print', label: 'Print', icon: , // Nested actions render as a dropdown menu below the main button children: [ { key: 'print-original', label: 'Print Original', icon: , onClick: (k) => console.log(k), }, { key: 'print-copy', label: 'Print Copy', icon: , onClick: (k) => console.log(k), }, ], }, { key: 'delete', label: 'Delete', icon: , intent: 'destructive', onClick: (key) => console.log('Clicked', key), }, ]; return console.log('closed')} />; } ``` ### 2. Row Actions (Data Grids & Lists) `RowActions` are optimized for density. Text labels are optional and primarily shown inside nested dropdowns. Hover tooltips are supported. ```tsx import { RowActions, type RowAction } from '@repo/ui/components'; import { Edit, CheckCircle, MoreVertical, Trash } from 'lucide-react'; import { Table } from '@repo/ui/components'; function DataTable() { const rowActions: RowAction[] = [ { key: 'edit', tooltip: 'Edit Record', icon: , onClick: (key) => console.log('Clicked', key), }, { key: 'approve', tooltip: 'Approve', icon: , intent: 'success', onClick: (key) => console.log('Clicked', key), }, { key: 'more', label: 'More Options', icon: , children: [ { key: 'delete', label: 'Delete Record', icon: , intent: 'destructive', onClick: (k) => console.log(k), }, ], }, ]; return ( Invoice #001
); } ``` ## Props API Reference ### PageActions Props | Prop | Type | Default | Description | | --------- | -------------- | ----------- | ----------------------------------------------------------------- | | `actions` | `PageAction[]` | Required | Array of configured page-level actions. | | `onClose` | `() => void` | `undefined` | Optional callback triggered when the close (X) button is clicked. | ### RowActions Props | Prop | Type | Default | Description | | ------------ | ------------- | ------- | ------------------------------------------------------------------------- | | `actions` | `RowAction[]` | `[]` | Array of configured row-level actions. | | `showLabels` | `boolean` | `false` | If true, renders the text label alongside the icon for top-level buttons. | ### Action Definitions Both `PageAction` and `RowAction` share a common base interface. **Base Action Properties (`BaseAction`)** | Property | Type | Description | | ---------- | --------------------------------------------------------------------------- | ----------------------------------------------------------------- | | `key` | `string` | Unique identifier. Required for 'action', optional for 'divider'. | | `type` | `'action'` \| `'divider'` | Type of action. Defaults to 'action'. | | `icon` | `ReactNode` | Visual representation of the action. | | `disabled` | `boolean` | Disables interaction if set to true. | | `intent` | `'default'` \| `'success'` \| `'warning'` \| `'destructive'` \| `'primary'` | Semantic context to determine visual emphasis (color mapping). | | `onClick` | `(key: string) => void` | Callback triggered upon execution. | **`PageAction` Specific Properties** | Property | Type | Description | | ---------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | `label` | `string` | Text label displayed on the button. Required for 'action' type. | | `variant` | `'filled'` \| `'light'` \| `'outline'` \| `'default'` \| `'subtle'` \| `'transparent'` | Specifies the Mantine button variant. Defaults to 'transparent' internally. | | `children` | `PageAction[]` | Nested actions rendered as a dropdown menu below the main button. | **`RowAction` Specific Properties** | Property | Type | Description | | ---------- | ------------- | ------------------------------------------------------------ | | `label` | `string` | Text primarily used when rendered inside a nested menu item. | | `tooltip` | `string` | Optional text displayed on hover over the standalone icon. | | `children` | `RowAction[]` | Nested actions that will be rendered inside a dropdown menu. | ## Best Practices - **Semantic Intents:** Always map your actions to a specific `intent` (e.g., `intent: 'destructive'` for deletions). The components will automatically map these to the appropriate theme colors. - **Nested Actions (Dropdowns):** For actions that trigger sub-actions (like multiple print options), use the `children` array property. The component automatically manages the dropdown positioning and presentation. - **Density in Rows:** Inside lists and tables, favor `RowActions` over `PageActions` and provide a `tooltip` instead of forcing a full `label`. This keeps the UI clean and performs efficiently, especially over many rows. Keep `showLabels` as `false` (default) for a tighter grid layout unless specifically required. - **Dividers:** Use `{ type: 'divider' }` within your actions array to visually group related buttons together. The component handles both horizontal and vertical divider logic depending on the screen size.