Product Gallery
The image gallery of a product page, with thumbnails, zoom and a full-screen viewer. Handles variant images, swipe on touch, broken photos, video and loading.
Product Gallery is the photo area of a product page. On desktop a thumbnail rail sits beside the main image, or a row sits under it, and a ring slides to the chosen thumbnail. Picking a thumbnail crossfades the photo in place instead of sliding through every shot in between, and it waits for the new photo to decode so the frame never flashes empty.
Hover a photo with a mouse and, after a short pause, it zooms to 2× around the cursor and swaps in the higher resolution zoomSrc. Click or press Enter to open the full-screen viewer. On touch the photos swipe with native scroll snapping that follows the finger, the thumbnails stay visible and a 2 / 5 counter sits in the corner. Tap opens the viewer and double-tap opens it zoomed in on that spot.
The viewer is a modal dialog. Arrows, swipes and thumbnails move between photos, and pinch, double-tap, click, the trackpad, the wheel and the + and − keys zoom and pan with soft edges. Swipe down to close, or press Escape, which first resets the zoom. Focus returns to the chosen thumbnail. With reduced motion, zoom and slide changes happen without animation.
Pass activeId to drive it from a variant picker: when it changes the gallery crossfades to that photo and scrolls the thumbnail into view. No photos shows a quiet placeholder, one photo drops the thumbnails and counter, a broken URL becomes a placeholder in the same frame, long sets scroll with a faded edge, and videos show their poster with a play button and never autoplay. ProductGallerySkeleton matches the layout while media loads.
Obtén HextaUI Pro
Un solo pago desbloquea todos los bloques, incluidos los futuros. Ver precios.
Añade el registro Pro a components.json
components.json Añade tu token
Crea un token en tu página de cuenta y colócalo en
.env.localcomoHEXTAUI_PRO_TOKEN.Añade el bloque
pnpm dlx shadcn@latest add @hextaui-pro/product-gallery
With VariantPicker
Keep the active image in state and point it at getVariantImage when a color changes. The gallery crossfades to that photo and scrolls its thumbnail into view, and the shopper can still browse the other photos.
From Shopify media
Map the Storefront API media connection once. Images get a 1200px src, a 2400px zoomSrc and a 240px thumbnail through the CDN width param, and videos keep their preview image as the poster.
Standalone, with a skeleton
Show ProductGallerySkeleton while media loads, then the gallery. Square frames with fit="contain" suit cut-out shots of mixed shapes, and thumbnails can sit in a row under the image.
Anatomía
Las partes que compones, de fuera hacia dentro.
| Parte | Descripción |
|---|---|
ProductGallery | The labelled carousel region: the main image, the thumbnails and the viewer. |
Thumbnails | A tab list, one tab per photo or video, with a sliding ring on the chosen one. |
Slides | One tab panel per item. Only the active one is focusable and shown to screen readers. |
Viewer | A full-screen dialog with zoom, pan, swipe, arrows and its own thumbnails. |
ProductGallerySkeleton | A loading placeholder with the same frame and thumbnail geometry. |
ProductGallery
Also takes section props.
| Prop | Tipo | Predeterminado |
|---|---|---|
imagesPhotos and videos in order. A photo is a ProductImage with optional zoomSrc and thumbnailSrc. | ProductMedia[] | – |
activeIdThe shown item when controlled, such as the image of the chosen variant. | string | null | – |
defaultActiveIdThe first item shown when uncontrolled. Defaults to the first one. | string | – |
onActiveChangeCalled when a thumbnail, swipe, arrow key or the viewer changes the shown item. | (id: string, media: ProductMedia) => void | – |
aspectWidth over height of the main frame and thumbnails. | number | 4 / 5 |
fitcontain letterboxes photos of mixed shapes on the muted background instead of cropping them. | "cover" | "contain" | "cover" |
thumbnailsA rail beside the image, which becomes a row when the gallery is narrower than 448px, or always a row under it. | "start" | "bottom" | "start" |
zoomHover zoom for mouse pointers. The viewer always zooms. | boolean | true |
badgesShown over the top start corner of the main image, such as a New or Sale badge. | ReactNode | – |
labelsWords for the region, thumbnails, counter, announcements, viewer controls, placeholders and the zoom hint. | Partial<ProductGalleryLabels> | – |
| Prop | Tipo | Predeterminado |
|---|---|---|
idMatches ProductVariant.imageId for photos. | string | – |
srcThe photo, or the video file for type video. | string | – |
altDescribe the shot, such as Moss glazed vase with eucalyptus stems. | string | – |
zoomSrcA larger photo loaded when zoom starts. | string | – |
thumbnailSrcA small photo for the thumbnail. Defaults to src or the poster. | string | – |
typeVideos also need a poster. | "image" | "video" | "image" |
posterThe still shown before a video plays. | string | – |
ProductGallerySkeleton
Also takes div props.
| Prop | Tipo | Predeterminado |
|---|---|---|
countHow many thumbnails to sketch. 1 hides them. | number | 5 |
aspectMatch the gallery. | number | 4 / 5 |
thumbnailsMatch the gallery. | "start" | "bottom" | "start" |
| Key | Acción |
|---|---|
| Tab | Moves to the main image, then into the thumbnails at the chosen one. |
| ArrowUpArrowDownArrowLeftArrowRight | On the thumbnails, moves to the previous or next one and shows it, wrapping at the ends. On the main image, shows the previous or next item. |
| HomeEnd | Shows the first or last thumbnail. |
| Enter | On the main image, opens the viewer, or plays a video. |
| +-0 | In the viewer, zooms in, zooms out or resets. |
| Escape | In the viewer, resets the zoom first, then closes and returns focus to the thumbnail. |
- The gallery follows the APG carousel pattern with tabs as the slide picker: a region named Product images with the carousel role description, a tab list of thumbnails named Image 3 of 7, and one tab panel per slide labelled 3 of 7. Selection follows focus, and only the chosen tab is in the tab order.
- The visible image carries its own alt text. Hidden slides are removed from the accessibility tree, and the visual counter is hidden because the tabs already say the position.
- A polite live region announces Image 3 of 7 with its alt text only when the shopper changes the image, never on load or when a variant picker moves it.
- The viewer is a modal dialog with a title. Focus starts on the image and returns to the chosen thumbnail on close. Videos never autoplay, and play only after a press, with native controls.
- Zoom and slides animate only without reduced motion. Focus rings use the focus ring token, the chosen thumbnail gets an outline in forced colors, and touch thumbnails are at least 44px.
Construido con
Los componentes gratuitos de HextaUI con los que está hecho Product Gallery. Cada uno se instala por separado.
Código
6 archivos, añadidos a components/blocks/product-gallery.