> Leaf UI 0.8.1 · Package: @ifhover/leaf-ui · Source: 435bab23cad7d343653d9b63b049c0b0601eeefb
> Browser documentation: https://ifhover.github.io/leaf-ui/en/components/file-list.html

> For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/en/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/en/llms-full.txt.

# FileList

Display file information and upload status, with preview, download and removal actions.

## File information

Icons identify each file type. File size is optional. Preview images or download other files.


- Project proposal.pdf

PDF685 B[](/leaf-ui/media/sample.pdf)
- Quarterly data.csv

CSV[](/leaf-ui/media/quarterly-data.csv)
- Summer landscape.svg

SVG414 B[](/leaf-ui/media/landscape-1.svg)
- Delivery notes.md

MD[](/leaf-ui/media/file-list-readme.md)

basic.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/file-list/basic.tsx"
import { FileList, Space } from '@ifhover/leaf-ui';

import { withBase } from '@rspress/core/runtime';

export function FileListBasic() {
  return (
    <Space direction="vertical" align="stretch">
      <FileList
        items={[
          {
            url: withBase('/media/sample.pdf'),
            name: 'Project proposal.pdf',
            size: 685,
          },
          { url: withBase('/media/quarterly-data.csv'), name: 'Quarterly data.csv' },
          { url: withBase('/media/landscape-1.svg'), name: 'Summer landscape.svg', size: 414 },
          { url: withBase('/media/file-list-readme.md'), name: 'Delivery notes.md' },
        ]}
      />
    </Space>
  );
}
```

Expand code

## Thumbnail list

Use `listType="picture"` to show image thumbnails. Other files keep their type icons.


- ![](/leaf-ui/media/landscape-1.svg)Summer landscape.svg

SVG414 B[](/leaf-ui/media/landscape-1.svg)
- ![](/leaf-ui/media/landscape-2.svg)Mountain trail.svg

SVG[](/leaf-ui/media/landscape-2.svg)
- Project proposal.pdf

PDF685 B[](/leaf-ui/media/sample.pdf)

picture.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/file-list/picture.tsx"
import { FileList } from '@ifhover/leaf-ui';

import { withBase } from '@rspress/core/runtime';

export function FileListPicture() {
  return (
    <div>
      <FileList
        listType="picture"
        items={[
          {
            uid: 'lake',
            url: withBase('/media/landscape-1.svg'),
            name: 'Summer landscape.svg',
            size: 414,
          },
          { uid: 'trail', url: withBase('/media/landscape-2.svg'), name: 'Mountain trail.svg' },
          {
            uid: 'plan',
            url: withBase('/media/sample.pdf'),
            name: 'Project proposal.pdf',
            size: 685,
          },
        ]}
      />
    </div>
  );
}
```

Expand code

## Picture cards

Use `listType="picture-card"` to show picture cards. The preview lets you switch between images in the same list.


- ![](/leaf-ui/media/landscape-1.svg)Summer landscape.svg

SVG414 B[](/leaf-ui/media/landscape-1.svg)
- ![](/leaf-ui/media/landscape-2.svg)Mountain trail.svg

SVG[](/leaf-ui/media/landscape-2.svg)
- ![](/leaf-ui/media/landscape-3.svg)Homepage cover final.svg

SVG[](/leaf-ui/media/landscape-3.svg)

cards.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/file-list/cards.tsx"
import { FileList } from '@ifhover/leaf-ui';

import { withBase } from '@rspress/core/runtime';

export function FileListCards() {
  return (
    <div>
      <FileList
        listType="picture-card"
        items={[
          {
            uid: 'lake',
            url: withBase('/media/landscape-1.svg'),
            name: 'Summer landscape.svg',
            size: 414,
          },
          { uid: 'trail', url: withBase('/media/landscape-2.svg'), name: 'Mountain trail.svg' },
          {
            uid: 'cover',
            url: withBase('/media/landscape-3.svg'),
            name: 'Homepage cover final.svg',
          },
        ]}
      />
    </div>
  );
}
```

Expand code

## Upload status

Show progress, completed, failed, ready and cancelled uploads. Error details appear below the affected file.


- Project introduction.mp4

MP412 MBUploading 42%
- Delivery notes.pdf

PDF685 BUpload complete
- Attachments.zip

ZIP3 MBUpload failedConnection interrupted. Please upload again.


- Project notes.md

MDReady
- Backup.zip

ZIPCancelled

states.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/file-list/states.tsx"
import { FileList } from '@ifhover/leaf-ui';

import { withBase } from '@rspress/core/runtime';

export function FileListStates() {
  return (
    <div>
      <FileList
        downloadable={false}
        previewable={false}
        items={[
          {
            uid: 'uploading',
            name: 'Project introduction.mp4',
            size: 12582912,
            status: 'uploading',
            percent: 42,
          },
          {
            uid: 'done',
            name: 'Delivery notes.pdf',
            size: 685,
            status: 'done',
            url: withBase('/media/sample.pdf'),
          },
          {
            uid: 'error',
            name: 'Attachments.zip',
            size: 3145728,
            status: 'error',
            error: 'Connection interrupted. Please upload again.',
          },
          { uid: 'ready', name: 'Project notes.md', status: 'ready' },
          { uid: 'cancelled', name: 'Backup.zip', status: 'cancelled' },
        ]}
      />
    </div>
  );
}
```

Expand code

## URL-only files and removal

Names can come from the URL. Update `items` in `onRemove`; the remove button waits when the callback returns a Promise.


Names can come from the URL; size is optional. Zero-byte files still display their size.

- main.zip

ZIP[](https://github.com/ifhover/leaf-ui/archive/refs/heads/main.zip)
- file-list-readme.md

MD[](/leaf-ui/media/file-list-readme.md)
- empty.txt

TXT0 B[](/leaf-ui/media/empty.txt)

advanced.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/file-list/advanced.tsx"
import { type FileItem, FileList, Space, Text } from '@ifhover/leaf-ui';

import { withBase } from '@rspress/core/runtime';

import { useState } from 'react';

export function FileListActions() {
  const [items, setItems] = useState<FileItem[]>([
    { uid: 'a', url: 'https://github.com/ifhover/leaf-ui/archive/refs/heads/main.zip' },
    { uid: 'b', url: withBase('/media/file-list-readme.md') },
    { uid: 'c', url: withBase('/media/empty.txt'), size: 0 },
  ]);
  return (
    <Space direction="vertical" align="stretch">
      <Text tone="muted">
        Names can come from the URL; size is optional. Zero-byte files still display their size.
      </Text>
      <FileList
        items={items}
        removable
        onRemove={(file) => setItems((current) => current.filter((item) => item.uid !== file.uid))}
      />
    </Space>
  );
}
```

Expand code

## Empty list

An empty state appears when there are no files. Use `emptyContent` to customize it.


No files

empty.tsx

Copy code

```tsx lineNumbers file="../../../src/examples/en/file-list/empty.tsx"
import { FileList } from '@ifhover/leaf-ui';

export function FileListEmpty() {
  return (
    <div>
      <FileList items={[]} />
    </div>
  );
}
```

Expand code

## Usage notes

Size is optional and no file metadata is fetched automatically. Icons follow MIME types or extensions; failed thumbnails fall back to a type icon. Preview is available for images, video and audio; other files show download only. Browser codec support determines media playback. Cross-origin downloads may open in a new tab; use `onDownload` for your download service. Use [Upload](https://ifhover.github.io/leaf-ui/en/components/upload.md) to handle file uploads.

## Types

```ts
import type { FileItem, FileListProps } from '@ifhover/leaf-ui';
```

## FileListProps API

| Property        | Type                                                                                            | Default  | Description                                                                                                                                     |
| --------------- | ----------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `items`         | `readonly `[`FileItem`](#fileitem-api)`[]`                                                      | Required | Required. Files to display                                                                                                                      |
| `downloadable`  | `boolean`                                                                                       | `true`   | Show download actions for files with a URL                                                                                                      |
| `previewable`   | `boolean`                                                                                       | `true`   | Show preview actions for images, video and audio with a URL                                                                                     |
| `removable`     | `boolean`                                                                                       | `false`  | Show removal actions when `onRemove` is also provided                                                                                           |
| `onPreview`     | `(file: `[`FileItem`](#fileitem-api)`) => void`                                                 | —        | Override media preview; uses the built-in preview when omitted                                                                                  |
| `onDownload`    | `(file: `[`FileItem`](#fileitem-api)`) => void`                                                 | —        | Override download; uses the file URL when omitted                                                                                               |
| `onRemove`      | `(file: `[`FileItem`](#fileitem-api)`) => void \| boolean \| Promise<void> \| Promise<boolean>` | —        | Request removal; the caller updates `items`. Waits for async callbacks and shows rejections in the affected row. Return `false` to deny removal |
| `renderActions` | `(file: `[`FileItem`](#fileitem-api)`, actions: ReactNode) => ReactNode`                        | —        | Customize the action area                                                                                                                       |
| `emptyContent`  | `ReactNode`                                                                                     | No files | Empty list content                                                                                                                              |
| `disabled`      | `boolean`                                                                                       | `false`  | Disable interaction.                                                                                                                            |
| `listType`      | `'text' \| 'picture' \| 'picture-card'`                                                         | `'text'` | File list presentation.                                                                                                                         |

## FileItem API

| Property     | Type                                                         | Default | Description                                       |
| ------------ | ------------------------------------------------------------ | ------- | ------------------------------------------------- |
| `uid`        | `string`                                                     | —       | Stable identifier, recommended                    |
| `url`        | `string`                                                     | —       | File URL                                          |
| `name`       | `string`                                                     | —       | Name, inferred from URL if omitted                |
| `size`       | `number`                                                     | —       | Bytes; omitted sizes are not displayed            |
| `type`       | `string`                                                     | —       | MIME type; inferred from the extension if omitted |
| `status`     | `'ready' \| 'uploading' \| 'done' \| 'error' \| 'cancelled'` | —       | Optional upload status                            |
| `percent`    | `number`                                                     | —       | Upload progress from 0 to 100                     |
| `error`      | `string`                                                     | —       | Error description                                 |
| `originFile` | `globalThis.File`                                            | —       | Original browser File                             |
