



<Preview className="min-h-[560px]">
  <FilesDetailsPanelConsumerExample />
</Preview>

This example keeps `Files.Details` focused on metadata display and inline rename
mechanics. The consumer owns the file collection, selected IDs, rename mutation,
product-specific metadata, and the surrounding split layout.

```tsx title="components/files-details-panel/index.tsx"
import { useMemo, useState } from "react";
import { Files } from "@tilt-legal/cubitt-components/files";
import { Separator } from "@tilt-legal/cubitt-components/separator";
import { toast } from "@tilt-legal/cubitt-components/toast";
import { formatPlural } from "@tilt-legal/cubitt-components/utilities/formatters";
import { MatterFileDetailsPanel } from "@/components/files-details-panel/details-sidebar";
import {
  matterFiles,
  type MatterFileItem,
} from "@/components/files-details-panel/data";

function sleep(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

export function FilesDetailsPanel() {
  const [items, setItems] = useState(matterFiles);
  const [selectedIds, setSelectedIds] = useState<string[]>([
    "financial-report",
  ]);

  const selectedItems = useMemo(
    () =>
      selectedIds
        .map((id) => items.find((item) => item.id === id))
        .filter((item): item is MatterFileItem => Boolean(item)),
    [items, selectedIds],
  );
  const currentDetailsItem = useMemo<MatterFileItem>(
    () => ({
      id: "current-files",
      kind: "folder",
      name: "Files",
      itemCount: items.length,
      matter: "Bennett v Carter",
      createdBy: "Matter team",
      workflowStatus: "Reviewed",
      updatedAt: "2026-04-22",
    }),
    [items.length],
  );
  const detailsItems =
    selectedItems.length > 0 ? selectedItems : [currentDetailsItem];

  async function renameItem(item: MatterFileItem, name: string) {
    await sleep(300);
    setItems((currentItems) =>
      currentItems.map((currentItem) =>
        currentItem.id === item.id ? { ...currentItem, name } : currentItem,
      ),
    );
    toast.success("File renamed", { description: name });
  }

  return (
    <Files
      className="h-[420px] w-full max-w-4xl flex-row gap-6"
      canRename={(item) => item.id !== currentDetailsItem.id}
      detailsItem={currentDetailsItem}
      items={items}
      onRename={renameItem}
      onSelectedIdsChange={setSelectedIds}
      selectedIds={selectedIds}
      selectionMode="multiple"
    >
      <Files.Content className="overflow-auto">
        <Files.List>
          {items.map((item) => (
            <Files.Item item={item} key={item.id} />
          ))}
        </Files.List>
      </Files.Content>
      <Separator orientation="vertical" />
      <MatterFileDetailsPanel
        className="min-h-0 min-w-[400px] basis-[400px] shrink-0"
        selectedItems={detailsItems}
      />
    </Files>
  );
}
```

```tsx title="components/files-details-panel/details-sidebar.tsx"
import { Files } from "@tilt-legal/cubitt-components/files";
import { formatPlural } from "@tilt-legal/cubitt-components/utilities/formatters";
import type { MatterFileItem } from "@/components/files-details-panel/data";

type Props = {
  className?: string;
  selectedItems: MatterFileItem[];
};

export function MatterFileDetailsPanel({
  className,
  selectedItems,
}: Props) {
  const singleItem = selectedItems.length === 1 ? selectedItems[0] : null;
  const matterCount = new Set(
    selectedItems.map((item) => item.matter).filter(Boolean),
  ).size;
  const ownerCount = new Set(
    selectedItems.map((item) => item.createdBy).filter(Boolean),
  ).size;

  return (
    <Files.Details className={className}>
      <Files.Details.Icon />
      <Files.Details.Header>
        <Files.Details.Heading>
          <Files.Details.Name />
          <Files.Details.Type />
        </Files.Details.Heading>
        <Files.Details.EditNameButton />
      </Files.Details.Header>
      <Files.Details.Panels>
        <Files.Details.Panel label="Details" value="details">
          <Files.Details.Properties>
            <Files.Details.Metadata />
            {singleItem?.matter ? (
              <Files.Details.Property>
                <Files.Details.Property.Label>
                  Matter
                </Files.Details.Property.Label>
                <Files.Details.Property.Value>
                  {singleItem.matter}
                </Files.Details.Property.Value>
              </Files.Details.Property>
            ) : null}
            {singleItem?.workflowStatus ? (
              <Files.Details.Property>
                <Files.Details.Property.Label>
                  Status
                </Files.Details.Property.Label>
                <Files.Details.Property.Value>
                  {singleItem.workflowStatus}
                </Files.Details.Property.Value>
              </Files.Details.Property>
            ) : null}
            {selectedItems.length > 1 ? (
              <Files.Details.Property>
                <Files.Details.Property.Label>
                  Matters
                </Files.Details.Property.Label>
                <Files.Details.Property.Value>
                  {formatPlural(matterCount, "matter")}
                </Files.Details.Property.Value>
              </Files.Details.Property>
            ) : null}
            {selectedItems.length > 1 ? (
              <Files.Details.Property>
                <Files.Details.Property.Label>
                  Owners
                </Files.Details.Property.Label>
                <Files.Details.Property.Value>
                  {formatPlural(ownerCount, "owner")}
                </Files.Details.Property.Value>
              </Files.Details.Property>
            ) : null}
          </Files.Details.Properties>
        </Files.Details.Panel>
      </Files.Details.Panels>
    </Files.Details>
  );
}
```

```typescript title="components/files-details-panel/data.ts"
import type { FilesItem } from "@tilt-legal/cubitt-components/files";

export type MatterFileItem = FilesItem & {
  matter: string;
  workflowStatus: "Draft" | "Reviewed" | "Filed";
};

export const matterFiles: MatterFileItem[] = [
  {
    id: "financial-report",
    kind: "file",
    name: "Q4FinancialReportBennettVCarterLitigationBudgetAndSettlementExposureAnalysisFinalReviewedCopy.pdf",
    mimeType: "application/pdf",
    size: 2_458_624,
    matter: "Bennett v Carter",
    createdBy: "Sarah Chen",
    workflowStatus: "Reviewed",
    updatedAt: "2026-04-20",
  },
  {
    id: "deposition-outline",
    kind: "file",
    name: "Deposition Outline.docx",
    mimeType:
      "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    size: 884_736,
    matter: "Hudson Contract Review",
    createdBy: "Ava Johnson",
    workflowStatus: "Draft",
    updatedAt: "2026-04-18",
  },
  {
    id: "folder-discovery",
    kind: "folder",
    name: "Discovery",
    itemCount: 12,
    matter: "Bennett v Carter",
    createdBy: "Sarah Chen",
    workflowStatus: "Draft",
    updatedAt: "2026-04-22",
  },
];
```
