ProductGallery
A product page's image slider with thumbnails, an in-page zoom popup, video and 3D slides, replaceable through the registry.
import { ProductGallery, ProductGalleryProps } from '@salla.sa/twilight-theme-engine/components/product';In plain words
The big picture area of a product page: the main image, a row of thumbnails when there are several, and a popup that zooms the image when the shopper clicks it, without leaving the page.
Pass the product (its details, which include every image) and it lays itself out as the left half of the product row, like the engine's product page.
Signature
function ProductGallery(props: ProductGalleryProps): JSX.Element
interface ProductGalleryProps {
product: Product;
}Try it live
Loading products…
import { useQuery } from '@tanstack/react-query';
import { product } from '@salla.sa/twilight-theme-engine/api/product';
import { ProductGallery } from '@salla.sa/twilight-theme-engine/components/product';
export function Gallery({ id }: { id: string }) {
const { data } = useQuery(product.queries.detail(id));
if (!data) return null;
return (
<div className="flex flex-col md:flex-row items-start">
<ProductGallery product={data} />
</div>
);
}
Example
import { useQuery } from '@tanstack/react-query';
import { product } from '@salla.sa/twilight-theme-engine/api/product';
import { ProductGallery } from '@salla.sa/twilight-theme-engine/components/product';
export function Gallery({ id }: { id: string }) {
const { data } = useQuery(product.queries.detail(id));
if (!data) return null;
return (
<div className="flex flex-col md:flex-row items-start">
<ProductGallery product={data} />
</div>
);
}
How it behaves
Not lazy. Slides come from
product.images; with none it falls back to[product.image], so a list item still shows its one picture, without thumbnails.A click on an image opens the engine
ImageModal. Video slides open their URL in a new tab; 3D slides render a<model-viewer>element. In the Salla mobile app (Salla.mobile.isEnabled()) a click dispatchesmobile::gallery.openwith the media list instead.Object fit comes from the theme setting
slider_background_size(defaultcover).promotion_titleandcaloriesare drawn over the slider.registry.override('product:gallery', MyGallery)is enough to replace it (no seed registration needed, unlike the card). The lookup runs once per mount.
Gotchas
Nothing in the engine or the reference theme loads the definition of the
model-viewerelement, so unless something else on the page does, a 3D slide is an empty box 500px tall. Load it yourself if your products have 3D models.product.queries.detail(id)first answers with the list card as placeholder data when a list already loaded that product: one image, no gallery. CheckisPlaceholderDataif the first paint must show every image.The slider element id is
details-slider-<product id>. Two galleries for the same product on one page share it, and the one-frame re-insert the gallery does after mounting (to restart the slider) can pick the wrong one.Like the card, a replacement cannot render the engine
ProductGalleryinside itself: it resolves the key again and recurses.
Related
The information half of a product page: brand, name, rating, price, description, tags, share and wishlist, SKU and stock counters.
AddToCartFormThe product page buy box: options, notes and files, live price, quantity and the Add to cart button, submitted through Salla's SDK.
registryThe shared name-to-component table the engine consults for a few swappable parts: the product card, the product gallery and home blocks.