Domain

Artwork

Show a token’s preview, live artwork, and reveal status.

Usage

tsx
import { Artwork } from "@whitehash/ui"
<Artwork.Root token={token}>
<Artwork.Image />
<Artwork.Live />
<Artwork.PlayButton />
<Artwork.StatusBadge />
</Artwork.Root>

Why a compound component

Rendering one token safely requires a preview with gateway fallback, an executable artifact in a sandboxed iframe with the correct seed, a play/stop lifecycle, and explicit handling of unrevealed or unresolvable tokens. Artwork.Root owns that state through useArtworkFrame and shares it with each part. Use only the parts you need, or place them inside your own layout.

Anatomy

PartRendersKey props
Artwork.RootThe container. Required. Owns play state, live-view status, and the token context every other part reads.token: WhitehashToken (required), className
Artwork.ImageThe static preview with multi-gateway fallback. Hidden while the live frame plays.source: "thumbnail" | "display" (default display), alt, className
Artwork.LiveThe sandboxed iframe running the artifact URL (seed + params applied). Mounts only while playing.className; sandbox/allow attributes are supplied for you
Artwork.PlayButtonPlay/stop toggle. Renders only when the token is revealed and its artifact is resolvable.playLabel, stopLabel, className
Artwork.StatusBadgeWhy there is no live view: unrevealed token, or onchfs without a resolver. Renders nothing when playable.className

Minimal vs. full

tsx
// Minimal: just the live artwork with its play control
<Artwork.Root token={token}>
<Artwork.Image />
<Artwork.Live />
<Artwork.PlayButton />
</Artwork.Root>
// Inside your own card. Parts are position-independent.
<Card.Root>
<Card.Media>
<Artwork.Root token={token} className="size-full rounded-none border-0">
<Artwork.Image source="thumbnail" />
</Artwork.Root>
</Card.Media>
<Card.Body><Card.Title>{token.name}</Card.Title></Card.Body>
</Card.Root>

What Root decides for you

From the token alone, Root derives: the preview URL (gateways in your configured order), the live URL (artworkUrl, v1 seed applied, ipfs/onchfs resolved), and the status: ok, unrevealed (placeholder token), or needs-onchfs (artifact is on-chain but no resolver is enabled). The iframe always ships sandbox="allow-scripts allow-same-origin allow-modals" plus the device-permission allowlist generative pieces expect.

Live result

Reading a book #1