import {Link, useNavigate} from 'react-router'; import {type MappedProductOptions} from '@shopify/hydrogen'; import type { Maybe, ProductOptionValueSwatch, } from '@shopify/hydrogen/storefront-api-types'; import {AddToCartButton} from './AddToCartButton'; import {useAside} from './Aside'; import type {ProductFragment} from 'storefrontapi.generated'; export function ProductForm({ productOptions, selectedVariant, }: { productOptions: MappedProductOptions[]; selectedVariant: ProductFragment['selectedOrFirstAvailableVariant']; }) { const navigate = useNavigate(); const {open} = useAside(); return (
{productOptions.map((option) => { // If there is only a single value in the option values, don't display the option if (option.optionValues.length === 1) return null; return (
{option.name}
{option.optionValues.map((value) => { const { name, handle, variantUriQuery, selected, available, exists, isDifferentProduct, swatch, } = value; if (isDifferentProduct) { // SEO // When the variant is a combined listing child product // that leads to a different url, we need to render it // as an anchor tag return ( ); } else { // SEO // When the variant is an update to the search param, // render it as a button with javascript navigating to // the variant so that SEO bots do not index these as // duplicated links return ( ); } })}

); })} { open('cart'); }} lines={ selectedVariant ? [ { merchandiseId: selectedVariant.id, quantity: 1, selectedVariant, }, ] : [] } > {selectedVariant?.availableForSale ? 'Add to cart' : 'Sold out'}
); } function ProductOptionSwatch({ swatch, name, }: { swatch?: Maybe | undefined; name: string; }) { const image = swatch?.image?.previewImage?.url; const color = swatch?.color; if (!image && !color) return name; return (
{!!image && {name}}
); }