Product Viewer

A large stage for one product image at a time, with pill tabs under it to switch views.

Take a closer look.

The camera seen from the front.

Rangefinder windows on the left.

import { ProductViewer } from '@brand-studio/ui';
import { camera } from '@/demos/assets';

const view = (name: string, alt: string) => {
  const image = camera(name, alt);
  return <img src={image.src} alt={image.alt} width={1600} height={900} />;
};

export default function ProductViewerDemo() {
  return (
    <ProductViewer
      title="Take a closer look."
      items={[
        { value: 'front', label: 'Front', media: view('front', 'The camera seen from the front.'), caption: 'Rangefinder windows on the left.' },
        { value: 'top', label: 'Top', media: view('top', 'The camera seen from above.'), caption: 'Shutter dial, advance lever and rewind crank.' },
        { value: 'back', label: 'Back', media: view('back', 'The back of the camera.'), caption: 'A bright finder and a film door.' },
        { value: 'side', label: 'Side', media: view('side', 'The camera from the side.'), caption: 'The lens adds 42 mm to the body.' },
      ]}
    />
  );
}

Installation

pnpm add @brand-studio/ui

Usage

import { ProductViewer } from '@brand-studio/ui';
<ProductViewer
  title="Take a closer look."
  items={[
    { value: 'front', label: 'Front', media: <img src="/front.webp" alt="…" /> },
    { value: 'back', label: 'Back', media: <img src="/back.webp" alt="…" /> },
  ]}
/>

Use pictures with the same framing, so switching views feels like turning the product.

Accessibility

  • Built on Base UI Tabs: arrow keys move between tabs, and each panel is labelled by its tab.
  • The tabs follow the stage in reading order, so a screen reader hears the view before the choice of views.

API Reference

PropTypeDefault
title?React.ReactNode
itemsViewerItem[]
defaultValue?string
label?string
className?string

Still, Deskhand and Hollis are fictional brands. The coffee photographs are original generated artwork. @brand-studio/ui is MIT licensed.