Skip to content

Commit

Permalink
handle swatch
Browse files Browse the repository at this point in the history
  • Loading branch information
wizardlyhel committed Aug 29, 2024
1 parent 05de025 commit d0c160c
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 38 deletions.
2 changes: 1 addition & 1 deletion packages/hydrogen/src/product/getProductOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export function getProductOptions({
selected: selectedOptions[option.name] === value.name,
exists: decodedVariantExistence.includes(targetKey),
available: variant?.availableForSale || false,
isDifferentProduct: handle !== productHandle,
isDifferentProduct: handle ? handle !== productHandle : false,
};
}),
};
Expand Down
100 changes: 64 additions & 36 deletions templates/skeleton/app/routes/products.$handle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import {ProductPrice} from '~/components/ProductPrice';
import {ProductImage} from '~/components/ProductImage';
import { AddToCartButton } from '~/components/AddToCartButton';
import type { ProductVariant } from '@shopify/hydrogen/storefront-api-types';
import type { Maybe, ProductOptionValueSwatch, ProductVariant } from '@shopify/hydrogen/storefront-api-types';
import { useAside } from '~/components/Aside';

export const meta: MetaFunction<typeof loader> = ({data}) => {
Expand Down Expand Up @@ -130,34 +130,20 @@ export default function Product() {
<h5>{option.name}</h5>
<div className="product-options-grid">
{option.optionValues.map((value) => {
const {name, handle, variantUriQuery, selected, exists, available, isDifferentProduct} = value;
if (selected) {
return (
<div
className="product-options-item"
key={option.name + name}
style={{
border: '1px solid black',
}}
>
{name}
</div>
);
}else if (exists && !isDifferentProduct) {
return (
<div
className="product-options-item link"
key={option.name + name}
onClick={() => {
navigate(`?${variantUriQuery}`, {
replace: true,
});
}}
>
{name}
</div>
);
} else if (handle && isDifferentProduct) {
const {
name,
handle,
variantUriQuery,
selected,
exists,
available,
isDifferentProduct,
swatch,
} = value;



if (isDifferentProduct) {
return (
<Link
className="product-options-item"
Expand All @@ -171,21 +157,30 @@ export default function Product() {
opacity: available ? 1 : 0.3,
}}
>
{name}
<ProductOptionSwatch swatch={swatch} name={name} />
</Link>
);
} else {
return (
<div
className="product-options-item"
<button
type="button"
className={`product-options-item${exists && !selected ? ' link' : ''}`}
key={option.name + name}
disabled={!exists}
style={{
border: '1px solid transparent',
opacity: 0.05,
border: selected ? '1px solid black' : '1px solid transparent',
opacity: available ? 1 : 0.3,
}}
onClick={() => {
if (!selected) {
navigate(`?${variantUriQuery}`, {
replace: true,
});
}
}}
>
{name}
</div>
<ProductOptionSwatch swatch={swatch} name={name} />
</button>
);
}
})}
Expand Down Expand Up @@ -237,6 +232,31 @@ export default function Product() {
);
}

function ProductOptionSwatch({
swatch,
name,
}: {
swatch?: Maybe<ProductOptionValueSwatch> | undefined;
name: string;
}) {
const image = swatch?.image?.previewImage?.url;
const color = swatch?.color;

if (!image && !color) return name;

return (
<div
aria-label={name}
className="product-option-label-swatch"
style={{
backgroundColor: color || 'transparent',
}}
>
{!!image && <img src={image} alt={name} /> }
</div>
);
}

const PRODUCT_VARIANT_FRAGMENT = `#graphql
fragment ProductVariant on ProductVariant {
availableForSale
Expand Down Expand Up @@ -286,6 +306,14 @@ const PRODUCT_FRAGMENT = `#graphql
name
optionValues {
name
swatch {
color
image {
previewImage {
url
}
}
}
}
}
encodedVariantExistence
Expand Down
15 changes: 14 additions & 1 deletion templates/skeleton/app/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,21 @@ button.reset:hover:not(:has(> *)) {
grid-gap: 0.75rem;
}

.product-options-item {
.product-options-item,
.product-options-item:disabled {
padding: 0.25rem 0.5rem;
background-color: transparent;
font-size: 1rem;
}

.product-option-label-swatch {
width: 1.25rem;
height: 1.25rem;
margin: 0.25rem 0;
}

.product-option-label-swatch img {
width: 100%;
}

/*
Expand Down

0 comments on commit d0c160c

Please sign in to comment.