

<Preview name="FileListViewExample" />

## Overview [#overview]

`Files.List` lays out consumer-owned `Files.Item` children in the same compact row treatment as the previous Files surface. Cubitt owns the row visuals, selection interaction, focus treatment, upload/error display, and file/folder icon rendering. Consumers own row metadata, filtering, sorting, folder navigation, upload state, and actions.

## Usage [#usage]

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

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

## List Item [#list-item]

<Preview name="FileListItemStatesExample" />

`Files.Item` renders one file or folder row inside `Files.List`. Its data
state controls only file lifecycle display:

| State       | Description                                                       |
| ----------- | ----------------------------------------------------------------- |
| `default`   | Normal folder, thumbnail, virtual file, or MIME icon display.     |
| `loading`   | Skeleton placeholder row 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.

## Custom Rows [#custom-rows]

`Files.Item` renders sensible default row cells. Consumers can provide children when they need app-specific columns while still reusing the same item slots. Use the `header` prop to replace or remove the default list header when your custom rows have a different column shape.

```tsx
<Files.List header={<MyListHeader />}>
  <Files.Item item={item}>
    <div className="flex justify-center">
      <Files.ItemIcon />
    </div>
    <div className="flex min-w-0 items-center gap-1.5 py-2 ps-1 pe-3">
      <Files.ItemName />
      <Files.ItemBadge />
    </div>
    <span>{item.kind === "folder" ? "Folder" : item.mediaType}</span>
    <span>{item.sizeLabel}</span>
    <span>{item.source?.owner}</span>
    <Files.ItemProgress />
  </Files.Item>
</Files.List>
```

## Props [#props]

### Files.List [#fileslist]

| Prop        | Type        | Default        | Description                                                            |
| ----------- | ----------- | -------------- | ---------------------------------------------------------------------- |
| `children`  | `ReactNode` | -              | `Files.Item` rows or compatible custom row children.                   |
| `header`    | `ReactNode` | default header | Pass `null` to remove the header or a node to provide a custom header. |
| `className` | `string`    | -              | Extends the list root.                                                 |

Also accepts standard `div` props. `Files.List` has no `items` 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 row 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`.
