# Thumbnail

- Page: https://jiguang132.com/resources/astryx/docs/thumbnail
- Resource: Astryx (https://jiguang132.com/resources/astryx.md)
- All guides: https://jiguang132.com/resources/astryx/docs.md

Thumbnail displays a compact, square preview of an image attachment. It shows a shimmer effect while uploading, the image on success, and a placeholder icon when no source is set. Use it in chat composers, file upload lists, or anywhere you need a small image preview with optional remove and click actions.

## Installation

```bash
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
```

Requires React 19+, base CSS and a Theme provider. See [Setup](/resources/astryx/docs/getting-started).

## Thumbnail

Thumbnail displays a compact, square preview of an image attachment. It shows a shimmer effect while uploading, the image on success, and a placeholder icon when no source is set. Use it in chat composers, file upload lists, or anywhere you need a small image preview with optional remove and click actions.

| Prop | Type | Default | Description |
|---|---|---|---|
| src | string |  | Image source URL. |
| alt | string |  | Alt text for the image. When omitted, the image is explicitly decorative (alt="", role="presentation", aria-hidden) and hidden from screen readers; a dev warning fires if neither alt nor label is set. |
| label | string |  | Accessible label (e.g. file name). Shown as tooltip on hover. |
| onRemove | (e: React.MouseEvent) => void |  | Callback for the overlaid remove button. |
| onClick | (e: React.MouseEvent) => void |  | Click handler. Adds button semantics and a hover overlay. |
| isLoading | boolean | false | Shows skeleton (no src) or upload overlay (with src). |
| isDisabled | boolean | false | Whether the thumbnail is disabled. |
| showRemoveOn | 'always' \| 'hover' | 'hover' | When the remove button is visible. `hover` (the default) reveals it on hover and on keyboard focus, and keeps it visible on any touch-capable device; `always` shows it at rest. Only applies when `onRemove` is set. |
| xstyle | StyleXStyles |  | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value, not an inline style object like style={{}}. |
| className | string |  | CSS class name for the root element. Prefer xstyle for styling; className is provided for integration with non-StyleX systems. |
| style | CSSProperties |  | Inline styles for the root element. Prefer xstyle for styling; inline styles bypass StyleX optimization. |
| data-testid | string |  | Test selector for automated testing frameworks. |

### Usage guidance

- Always provide a label prop with the file name so the thumbnail and its remove button are accessible to screen readers and show a tooltip on hover.
- Use isLoading without a src to show a skeleton during initial upload, and isLoading with a src to show a spinner overlay once a preview URL is available.
- Pair onClick with a lightbox or detail view so users can inspect the full image; the thumbnail adds button semantics and a hover overlay automatically.
- Avoid: Don't use Thumbnail for non-image file types like PDFs or spreadsheets; use a file attachment component with an appropriate icon instead.
- Avoid: Don't omit alt text when a src is provided; screen readers need a description of the image content, not just the file name from label.

### Theming API

```json
{
  "targets": [
    {
      "className": "astryx-thumbnail"
    }
  ],
  "vars": [
    {
      "name": "--_thumbnail-hit-inset",
      "description": "Outset of the remove button's invisible hit area, applied to a ::after overlay. 0 on a fine pointer; negative on a coarse one, which grows the 20px button to the 24px touch target without changing what is drawn.",
      "default": "0px",
      "private": true
    },
    {
      "name": "--_press-overlay",
      "description": "Fill of the ::after interaction overlay: transparent at rest, the hover overlay token on hover (hover-capable pointers), the pressed overlay token while pressed (`:active` on a mouse; `data-astryx-press=\"on\"` written by the touch press controller under a finger) and the hover token for the release fade. Set on the card element by its own interaction arms.",
      "default": "transparent",
      "private": true
    },
    {
      "name": "--_press-overlay-transition",
      "description": "Duration of the overlay's background-color transition: the fast duration token, except 0s while a believed touch press paints so it lands on the first frame.",
      "default": "var(--duration-fast)",
      "private": true
    }
  ]
}
```

### Anatomy

- **Image**: The preview image, displayed as a square with cover fit.
- **Placeholder**: An image silhouette icon shown when no src is provided.
- **Remove button**: An overlaid close button in the top-right corner. Appears when onRemove is set. Sits on a fixed --color-overlay scrim with an --color-on-dark icon to stay visible on any image.
- **Upload overlay**: A semi-transparent overlay with a spinner, shown when isLoading is true and a src preview is available.
- **Skeleton**: A shimmer animation shown when isLoading is true and no src is set.


## Examples

- Thumbnail: A thumbnail with an image and label.
- Thumbnail — Disabled: Thumbnails in the disabled state with reduced opacity. The remove button and click handler are suppressed when disabled.
- Thumbnail — Gallery: A row of clickable thumbnails with labels that open a detail view. Use for image attachment lists where users need to preview and manage uploads.
- Thumbnail — Removable: Thumbnails with a remove button overlay. The close button uses APCA luminance detection to stay visible on both dark and light images.
- Thumbnail — States: All visual states side by side: image loaded, placeholder, skeleton loading, and upload overlay. Demonstrates the full lifecycle of a thumbnail from empty to loaded.

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
