

<Preview name="FileContextMenuGridPreview" />

## Overview [#overview]

Right-click context menus for `FileGridView` and `FileListView`. The menu is selection-aware and adapts based on which files are selected, allowing actions on single or multiple files.

## Usage [#usage]

```tsx
import { FileGridView } from "@tilt-legal/cubitt-components/composites";
```

```tsx
<FileGridView
  files={files}
  selectedIds={selectedIds}
  onSelectionChange={setSelectedIds}
  onOpen={handleOpen}
  getContextMenuItems={(file, selectedFiles) => [
    { label: "Open", onClick: () => openFile(file) },
    { label: "Download", onClick: () => downloadFile(file) },
    { type: "separator" },
    {
      label: "Delete",
      onClick: () => deleteFile(file),
      variant: "destructive",
    },
  ]}
/>
```

## Examples [#examples]

### Multi-Select Aware [#multi-select-aware]

Adapt menu items based on selection count and file states.

```tsx
getContextMenuItems={(file, selectedFiles) => {
  const targetFiles = selectedFiles.length > 0 ? selectedFiles : [file];
  const targetName = targetFiles.length === 1
    ? targetFiles[0].name
    : `${targetFiles.length} files`;

  return [
    {
      label: "Open",
      onClick: () => openFile(file),
      disabled: targetFiles.length > 1
    },
    {
      label: `Download ${targetName}`,
      onClick: () => downloadFiles(targetFiles.map(f => f.id))
    },
    { type: "separator" },
    {
      label: "Rename",
      onClick: () => renameFile(file),
      disabled: targetFiles.length > 1
    },
    {
      label: `Delete ${targetName}`,
      onClick: () => deleteFiles(targetFiles.map(f => f.id)),
      variant: "destructive"
    },
  ];
}}
```

### With Icons and Shortcuts [#with-icons-and-shortcuts]

Add visual indicators and keyboard shortcuts to menu items.

```tsx
import { Download, Trash, Pencil2 } from "@tilt-legal/cubitt-icons/ui/outline";

getContextMenuItems={(file, selectedFiles) => [
  {
    label: "Open",
    onClick: () => openFile(file),
    shortcut: "↵"
  },
  {
    label: "Download",
    onClick: () => downloadFile(file),
    icon: <Download className="h-4 w-4" />,
    shortcut: "⌘D"
  },
  { type: "separator" },
  {
    label: "Rename",
    onClick: () => renameFile(file),
    icon: <Edit className="h-4 w-4" />,
    disabled: selectedFiles.length > 1
  },
  {
    label: "Delete",
    onClick: () => deleteFile(file),
    icon: <Trash2 className="h-4 w-4" />,
    variant: "destructive",
    shortcut: "⌘⌫"
  },
]}
```

### With Submenus [#with-submenus]

Group related actions into nested submenus.

```tsx
getContextMenuItems={(file, selectedFiles) => [
  { label: "Open", onClick: () => openFile(file) },
  { label: "Download", onClick: () => downloadFile(file) },
  { type: "separator" },
  {
    label: "Share",
    items: [
      { label: "Email link", onClick: () => emailLink(selectedFiles) },
      { label: "Copy link", onClick: () => copyLink(selectedFiles) },
      { label: "Get public URL", onClick: () => getPublicUrl(selectedFiles) },
    ],
  },
  { type: "separator" },
  {
    label: "Delete",
    onClick: () => deleteFile(file),
    variant: "destructive"
  },
]}
```

## API Reference [#api-reference]

### getContextMenuItems [#getcontextmenuitems]

Used by `FileListView` and `FileGridView` to build a selection-aware context menu. Provide a function that returns menu items for the clicked file and current selection.

| Parameter       | Type                    | Description                                                                |
| --------------- | ----------------------- | -------------------------------------------------------------------------- |
| `file`          | `DisplayFile`           | File that received the right-click (or long press).                        |
| `selectedFiles` | `DisplayFile[]`         | All currently selected files. When empty, fallback to the `file` argument. |
| **Returns**     | `FileContextMenuItem[]` | Array of menu items to render.                                             |

### FileContextMenuItem [#filecontextmenuitem]

A discriminated union that supports standard items, separators, and nested submenus.

**Standard Item**

| Property   | Type                         | Description                                      |
| ---------- | ---------------------------- | ------------------------------------------------ |
| `label`    | `string`                     | Display text.                                    |
| `onClick`  | `() => void`                 | Action handler invoked on selection.             |
| `disabled` | `boolean`                    | Disables the menu item when `true`.              |
| `variant`  | `'default' \| 'destructive'` | Applies visual emphasis for destructive actions. |
| `icon`     | `React.ReactNode`            | Optional leading icon.                           |
| `shortcut` | `string`                     | Optional keyboard shortcut hint (e.g. `"⌘D"`).   |

**Separator**

| Property | Type          | Description                            |
| -------- | ------------- | -------------------------------------- |
| `type`   | `'separator'` | Renders a divider between menu groups. |

**Submenu**

| Property   | Type                    | Description                                          |
| ---------- | ----------------------- | ---------------------------------------------------- |
| `label`    | `string`                | Display text for the submenu trigger.                |
| `items`    | `FileContextMenuItem[]` | Nested menu items (same union structure).            |
| `icon`     | `React.ReactNode`       | Optional icon displayed next to the submenu trigger. |
| `disabled` | `boolean`               | Disables the submenu trigger when `true`.            |
