Nearby transfer
A photo or file going to a device nearby, or coming from it: who it goes to, the photo on its corner, and a ring with a stop button.

Sending to, or receiving from, a device nearby, laid out as a nearby share’s banner: who it goes to, what is going (the photo, on the device’s corner), and a ring with a stop button. It reads differently from the upload on purpose: the upload leads with the photo, this leads with the other device.
Install
npx shadcn@latest add https://islandcn.dev/r/nearby-transfer-activity.jsonpnpm dlx shadcn@latest add https://islandcn.dev/r/nearby-transfer-activity.jsonyarn dlx shadcn@latest add https://islandcn.dev/r/nearby-transfer-activity.jsonbunx shadcn@latest add https://islandcn.dev/r/nearby-transfer-activity.jsonThis writes components/islandcn/nearby-transfer-activity.tsx and media-row.tsx (the row, the ring and the device picture it shares with the upload), plus the content kit and the engine if the project lacks them. Mount the island once first, see Installation.
What it shows
- Compact: the device’s glyph in the accent on the leading side and a ring that fills on the trailing side, with a check at 100%.
- Split: its compact pair, which fits whole in the 62.18 wide capsule. When the split doesn’t fit at all, the fallback is the device glyph inside the ring.
- Expanded: one row, as tall as an incoming call. The device on a faint disc of the accent, with a thumbnail of what is being sent on its lower corner, then “Sending biscuit-in-the-sun.jpg” in grey over “To Maya’s Laptop” in white, and the ring large on the trailing side. With
onCancelthe ring holds a stop square that calls it; without, an arrow for the direction. Done, the grey line reads “Sent …” and the ring is a check. - Receiving:
direction="receive"reads “Receiving …” over “From Maya’s Laptop”, with the arrow pointing down when there is no stop button. - A person instead of a device: pass
avatarwith their photo and it takes the device’s place, in compact too.
Usage
"use client";
import { NearbyTransferActivity } from "@/components/islandcn/nearby-transfer-activity";
export const ShareIsland = ({ progress, cancel }: { progress: number; cancel: () => void }) => (
<NearbyTransferActivity
direction="send"
deviceName="Maya's Laptop"
device="laptop"
itemName="biscuit-in-the-sun.jpg"
src="/photos/biscuit-in-the-sun.jpg"
progress={progress}
onCancel={cancel}
/>
);
itemName can be a count as well as a name: “3 photos” reads “Sending 3 photos”.
Props
deviceNamestring
The other device's or person's name, such as "Maya's Laptop".
stringitemNamestring
What is moving, such as "biscuit-in-the-sun.jpg" or "3 photos", in the grey line ("Sending 3 photos").
stringprogressnumber
0 to 1. At 1 it shows a check and "Sent" or "Received".
numbersrc?string
A thumbnail of what is moving, set on the device's corner. Without it, no badge.
stringavatar?string
The other person's photo, in place of the device.
stringdirection?"send" | "receive"
Sending or receiving.
"send" | "receive""send"device?"phone" | "tablet" | "laptop" | "desktop"
Picks the glyph when there is no avatar.
"phone" | "tablet" | "laptop" | "desktop""phone"accent?string
Colour of the device, the ring and the check.
stringblueonCancel?() => void
Makes the expanded ring a stop button while it runs. Without it the ring shows an arrow for the direction.
() => voidid?string
Activity id.
string"nearby-transfer"priority?number
Higher priority takes the main pill when two activities run.
number0Make it yours
Install this preset when it is exactly what you need. Otherwise open it in the Playground, change what each region shows and copy the code, or read its source for technique and build your own island on the engine.