Skip to content
← Inventory

Thumbnail

Base visual thumbnail component for colors and images. Used as the visual foundation for VariantSelectorItem, image upload previews, and decorative illustrations. Handles all visual states (selected, muted, dotted) while leaving interactivity to parent wrappers.

Oak veneer

Usage

import { Thumbnail, ThumbnailFrameRing, ThumbnailProps, ThumbnailSize, ThumbnailVariant } from "@desk/ui/components/thumbnail";

Best practices

  • Thumbnail is display-only — it handles selected/muted/disabled visuals but no click semantics; wrap it in a button/VariantSelectorItem for interaction.

  • Content precedence is children > src > color: pass a next/image as children for optimized loading, use src+alt for a plain <img>, or color for a solid swatch.

  • Give a meaningful alt for content images; pass alt="" (the default) only for decorative swatches so screen readers skip them.

  • Pick variant="card" for selectable framed tiles and variant="bare" for dense grid cells; size accepts a scale token, a pixel number, or "fluid" to fill the parent — don't wrap it in a fixed-size box to resize.

Props

Thumbnail

PropTypeDefaultDescription
altstring | undefined

Alt text for the image (used when src is provided)

borderColorstring | undefined

Border color override (e.g., "white" for decorative use)

childrenReactNode

Custom content — takes precedence over src and color

classNamestring | undefined

Additional className for the outer container

colorstring | undefined

Background color (solid fill, no image)

compactRadiusboolean | undefined

Use a slightly lighter corner radius profile (useful for dense selectors)

disabledboolean | undefined

Disabled state - blocks interaction, reduced opacity

dottedboolean | undefined

Dotted border style (e.g., for pending/preview states)

framedboolean | undefinedfalse

Show a subtle inset hairline ring (ring-1 ring-inset ring-black/5) that frames the image/color — a faint depth-defining edge, independent of padded's thicker card-colored separator ring. Follows the same corner radius as the container.

mutedboolean | undefined

Muted state - reduced opacity, restores on hover

paddedboolean | undefinedtrue (for card variant), false (for bare variant)

Show the white inset ring - card style with a solid inner border that frames the image/color. Drawn as an inset box-shadow overlay (follows the container radius, so it is always uniform). When false: image fills edge-to-edge.

priorityboolean | undefined

Prioritize image loading for above-the-fold or interactive CTAs

selectedboolean | undefined

Selection state - shows primary border + elevated shadow (card variant only)

sizeThumbnailSize | undefined

Size - ComponentSize scale ("xs", "base", "2xl") or pixel number (58, 88)

sizesstring | undefined

Responsive size hint forwarded to the underlying <img> element

srcstring | undefined

Image source URL — renders a native <img> with object-cover

styleimport("react").CSSProperties | undefined

Inline styles (useful for motion animations)

variantThumbnailVariant | undefined"card"

Visual style variant. - "card": Border, shadow, and optional padding (for selectable items) - "bare": Simple container with muted background (for data grids, etc.)

ThumbnailFrameRing

PropTypeDefaultDescription
radius(required)string

Also exports

  • interfaceThumbnailProps
  • typeThumbnailSize
  • typeThumbnailVariant

Composition