

<Preview name="FileGridViewExample" />

## Overview [#overview]

`Files.Grid` lays out consumer-owned `Files.Item` children in an iCloud-style justified file grid. Cubitt owns the measured row layout, final-row spacer cells, item visuals, selection interaction, focus treatment, upload/error display, and folder/file icon rendering. Consumers own the item array, filtering, sorting, folder-first ordering, folder navigation, upload state, and actions.

## Usage [#usage]

```tsx
import {
  Files,
  type FilesItem,
} from "@tilt-legal/cubitt-components/files";

function FileGrid({
  items,
  selectedIds,
  setSelectedIds,
}: {
  items: FilesItem[];
  selectedIds: string[];
  setSelectedIds: (ids: string[]) => void;
}) {
  return (
    <Files
      selectedIds={selectedIds}
      onSelectedIdsChange={setSelectedIds}
      selectionMode="multiple"
    >
      <Files.Grid>
        {items.map((item) => (
          <Files.Item
            item={item}
            key={item.id}
            onOpen={(openedItem) => {
              if (openedItem.kind === "folder") {
                navigateToFolder(openedItem.id);
              }
            }}
          />
        ))}
      </Files.Grid>
    </Files>
  );
}
```

## Grid Item [#grid-item]

<Preview name="FileGridItemStatesExample" />

`Files.Item` renders one file or folder inside the measured grid. Its data
state controls only file lifecycle display:

| State       | Description                                                   |
| ----------- | ------------------------------------------------------------- |
| `default`   | Normal folder, thumbnail, virtual file, or MIME icon display. |
| `loading`   | Skeleton placeholder for an item whose data is not ready yet. |
| `uploading` | Circular progress treatment. Use `progress` for the value.    |
| `error`     | Failed upload treatment.                                      |

Selection, active highlight, inline rename, drag, drop-target, disabled,
hover, and focus are interaction states owned by `Files` and item props, not
`FilesItem.state` values.

## Props [#props]

### Files.Grid [#filesgrid]

| Prop        | Type        | Default | Description                                          |
| ----------- | ----------- | ------- | ---------------------------------------------------- |
| `children`  | `ReactNode` | -       | `Files.Item` children or compatible custom children. |
| `className` | `string`    | -       | Extends the grid root.                               |

Also accepts standard `table` props. `Files.Grid` has no `items`, sorting,
density, or layout prop.

### Files.Item [#filesitem]

| Prop        | Type                    | Default | Description                                                         |
| ----------- | ----------------------- | ------- | ------------------------------------------------------------------- |
| `item`      | `FilesItem<TSource>`    | -       | File or folder display data.                                        |
| `onOpen`    | `(item, event) => void` | -       | Called on double click, or Enter when inline rename is unavailable. |
| `disabled`  | `boolean`               | `false` | Disables the item in addition to root and item data disabled state. |
| `children`  | `ReactNode`             | -       | Optional custom grid item content built from item slots.            |
| `className` | `string`                | -       | Extends the item root.                                              |

Selection is controlled by the root `Files` props: `selectedIds`,
`onSelectedIdsChange`, `selectionMode`, `selectionBehavior`, and optional
`canSelect`.
