Skip to content
caliper ui docs

Pro

Avatar upload

Change a profile photo in place. Click the avatar or drop an image on it and the photo opens inside the circle to position and zoom; saving crops it, uploads it through a ring that fills around the avatar, and settles with a tick.

Pro
pnpm dlx shadcn@latest add @caliper/avatar-upload

Profile photo

Shown on comments, mentions and your profile.

Click or drop a photo

Installs components/ui/avatar-upload.tsxDepends on @radix-ui/react-slot, lucide-reactMotion none in component source

When to use

Use it for

  • Profile, account and team member settings.
  • Workspace and organisation logos (any square image).

Skip it when

  • Galleries or several files at once; use `FileDropzone`.
  • Free-form crops; use `ImageCrop`.

Decisions

Why it is built this way, so you know what to keep when you change your copy.

Behaviour

Crop where it will live
Positioning happens inside the avatar's own circle, so what you see is what everyone will see.
Progress on the edge
The upload ring wraps the avatar instead of replacing it, and turns green with a tick when done.

Usage

Clear failures
Wrong file types and large files are refused with a reason, and a failed upload offers Try again with the same crop.

Installation

terminal
pnpm dlx shadcn@latest add @caliper/avatar-upload

Adds its 4 files to components/ui/, each with its own stylesheet, and installs their packages. Pro installs with your access token, set up once per project. See Pro access. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage

Import it from your copy of the source. The example behind the preview comes with the source.

example.tsx
import { AvatarUpload } from "@/components/ui/avatar-upload"

The worked example comes with Pro

The 38-line example behind the preview opens here, ready to copy.

  • 602 Pro parts, blocks and page templates, all with source
  • $199 once, with a year of updates. What you have stays yours
  • A full refund within 14 days if it is not for you
Checking your licence…

API reference

AvatarUpload

component

Also accepts the native props of its root element and a ref.

PropTypeDefaultDescription
name *string—The person's name, for the photo's fallback and labels.
srcstring—The current photo.
onUpload *(photo: Blob, progress: (fraction: number) => void) => Promise<string | void>—Uploads the cropped square photo, calling `progress` with 0 to 1 as it goes. Resolve with the new photo's URL, or throw to show an error.
sizenumber96Pixels across.

Accessibility

It exposes img semantics, with aria-label, aria-hidden and aria-live kept in step with state. Changes that matter are announced through a live region.

KeyBehaviour
EnterActivates the focused control.
EscapeCloses or cancels, then returns focus to where it came from.

Motion

It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.

All Media examples