Skip to content

Commit 36dc979

Browse files
admasodanielPaveltarno
authored andcommitted
Product Variant Selector API fixes (#104)
* Product Variant Selector API fixes * More API fixes * CR
1 parent a551a42 commit 36dc979

File tree

14 files changed

+114
-127
lines changed

14 files changed

+114
-127
lines changed

examples/astro-stores-demo/src/components/store/CategoryPage.tsx

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
import { CurrentCart } from '@wix/headless-ecom/react';
22
import type { LineItem } from '@wix/headless-ecom/services';
3-
import {
4-
MediaGalleryService,
5-
MediaGalleryServiceDefinition,
6-
} from '@wix/headless-media/services';
73
import {
84
Product,
95
ProductList,
@@ -16,13 +12,7 @@ import type {
1612
CategoriesListServiceConfig,
1713
ProductsListFiltersServiceConfig,
1814
} from '@wix/headless-stores/services';
19-
import {
20-
SelectedVariantService,
21-
SelectedVariantServiceDefinition,
22-
type ProductsListServiceConfig,
23-
} from '@wix/headless-stores/services';
24-
import { createServicesMap } from '@wix/services-manager';
25-
import { WixServices } from '@wix/services-manager-react';
15+
import { type ProductsListServiceConfig } from '@wix/headless-stores/services';
2616
import { productsV3 } from '@wix/stores';
2717
import { useEffect, useState } from 'react';
2818
import { WixMediaImage } from '../media';
@@ -218,10 +208,11 @@ export const ProductGridContent = ({
218208
isVisible,
219209
isInStock,
220210
isPreOrderEnabled,
221-
onSelect,
211+
select,
212+
optionName,
222213
}) => {
223214
// Check if this is a color option and if choice has color data
224-
const isColorOption = String(name)
215+
const isColorOption = String(optionName)
225216
.toLowerCase()
226217
.includes('color');
227218
const hasColorCode =
@@ -251,7 +242,7 @@ export const ProductGridContent = ({
251242
choice.colorCode ||
252243
'var(--theme-fallback-color)',
253244
}}
254-
onClick={onSelect}
245+
onClick={select}
255246
/>
256247
{/* Stock indicator for color swatches */}
257248
{!isInStock && !isPreOrderEnabled && (
@@ -292,7 +283,7 @@ export const ProductGridContent = ({
292283
? 'opacity-50 line-through'
293284
: ''
294285
}`}
295-
onClick={onSelect}
286+
onClick={select}
296287
>
297288
{String(value)}
298289
</span>
@@ -318,11 +309,11 @@ export const ProductGridContent = ({
318309
</ProductVariantSelector.Options>
319310

320311
<ProductVariantSelector.Reset>
321-
{({ onReset, hasSelections }) =>
312+
{({ reset, hasSelections }) =>
322313
hasSelections && (
323314
<div className="pt-4">
324315
<button
325-
onClick={onReset}
316+
onClick={reset}
326317
className="text-sm text-brand-primary hover:text-brand-light transition-colors"
327318
>
328319
Reset Selections

examples/astro-stores-demo/src/components/store/ProductActionButtons.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,23 +118,23 @@ export const ProductActionButtons: React.FC<ProductActionButtonsProps> = ({
118118
return (
119119
<SelectedVariant.Actions>
120120
{({
121-
onAddToCart,
122-
onBuyNow,
121+
addToCart,
122+
buyNow,
123123
canAddToCart,
124124
isLoading,
125125
inStock,
126126
isPreOrderEnabled,
127127
}) => {
128128
const handleAddToCart = async () => {
129-
await onAddToCart();
129+
await addToCart();
130130
if (isPreOrderEnabled) {
131131
window.location.href = '/cart';
132132
}
133133
};
134134

135135
const handleBuyNow = async () => {
136136
try {
137-
await onBuyNow();
137+
await buyNow();
138138
} catch (error) {
139139
console.error('Buy now failed:', error);
140140
}

examples/astro-stores-demo/src/components/store/ProductDetails.tsx

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const FreeTextInput = ({ modifier, name }: { modifier: any; name: string }) => (
1919
<ProductModifiers.FreeText modifier={modifier}>
2020
{({
2121
value,
22-
onChange,
22+
setText,
2323
placeholder: freeTextPlaceholder,
2424
charCount,
2525
isOverLimit,
@@ -29,7 +29,7 @@ const FreeTextInput = ({ modifier, name }: { modifier: any; name: string }) => (
2929
<textarea
3030
data-testid="product-modifier-free-text-input"
3131
value={value}
32-
onChange={e => onChange(e.target.value)}
32+
onChange={e => setText(e.target.value)}
3333
placeholder={
3434
freeTextPlaceholder || `Enter custom ${name.toLowerCase()}...`
3535
}
@@ -65,7 +65,7 @@ export default function ProductDetails({
6565
data-testid="product-details"
6666
>
6767
<Product.Root productServiceConfig={{ product }}>
68-
<SelectedVariant.Root selectedVariantServiceConfig={{}}>
68+
<SelectedVariant.Root>
6969
<Product.Media>
7070
{({ media }) => (
7171
<MediaGallery.Root mediaGalleryServiceConfig={{ media }}>
@@ -101,9 +101,9 @@ export default function ProductDetails({
101101
)}
102102

103103
<MediaGallery.Previous>
104-
{({ onPrevious, canGoPrevious }) => (
104+
{({ previous, canGoPrevious }) => (
105105
<button
106-
onClick={onPrevious}
106+
onClick={previous}
107107
disabled={!canGoPrevious}
108108
className="absolute left-4 top-1/2 -translate-y-1/2 btn-nav p-2 rounded-full transition-all"
109109
>
@@ -125,9 +125,9 @@ export default function ProductDetails({
125125
</MediaGallery.Previous>
126126

127127
<MediaGallery.Next>
128-
{({ onNext, canGoNext }) => (
128+
{({ next, canGoNext }) => (
129129
<button
130-
onClick={onNext}
130+
onClick={next}
131131
disabled={!canGoNext}
132132
className="absolute right-4 top-1/2 -translate-y-1/2 btn-nav p-2 rounded-full transition-all"
133133
>
@@ -169,9 +169,9 @@ export default function ProductDetails({
169169
<div className="grid grid-cols-4 gap-4">
170170
{items.map((_, i) => (
171171
<MediaGallery.ThumbnailItem key={i} index={i}>
172-
{({ src, isActive, onSelect, alt }) => (
172+
{({ src, isActive, select, alt }) => (
173173
<div
174-
onClick={onSelect}
174+
onClick={select}
175175
className={`aspect-square bg-surface-primary rounded-lg border cursor-pointer transition-all ${
176176
isActive
177177
? 'border-brand-medium ring-2 ring-brand-light'
@@ -283,7 +283,7 @@ export default function ProductDetails({
283283
</Product.Description>
284284

285285
{/* Product Options (if any) */}
286-
<ProductVariantSelector.Root selectedVariantServiceConfig={{}}>
286+
<ProductVariantSelector.Root>
287287
<ProductVariantSelector.Options>
288288
{({ options, hasOptions }) => (
289289
<>
@@ -329,7 +329,7 @@ export default function ProductDetails({
329329
isVisible,
330330
isInStock,
331331
isPreOrderEnabled,
332-
onSelect,
332+
select,
333333
}) => (
334334
<>
335335
{isColorOption &&
@@ -341,7 +341,7 @@ export default function ProductDetails({
341341
<div className="relative">
342342
<button
343343
data-testid="product-modifier-choice-button"
344-
onClick={onSelect}
344+
onClick={select}
345345
title={value}
346346
className={`w-10 h-10 rounded-full border-4 transition-all duration-200 ${
347347
isSelected
@@ -388,7 +388,7 @@ export default function ProductDetails({
388388
<div className="relative">
389389
<button
390390
data-testid="product-modifier-choice-button"
391-
onClick={onSelect}
391+
onClick={select}
392392
className={`px-4 py-2 border rounded-lg transition-all duration-200 ${
393393
isSelected
394394
? 'product-option-active'
@@ -433,11 +433,11 @@ export default function ProductDetails({
433433
))}
434434

435435
<ProductVariantSelector.Reset>
436-
{({ onReset, hasSelections }) =>
436+
{({ reset, hasSelections }) =>
437437
hasSelections && (
438438
<div className="pt-4">
439439
<button
440-
onClick={onReset}
440+
onClick={reset}
441441
className="text-sm text-brand-primary hover:text-brand-light transition-colors"
442442
>
443443
Reset Selections
@@ -501,11 +501,11 @@ export default function ProductDetails({
501501
value,
502502
isSelected,
503503
colorCode,
504-
onSelect,
504+
select,
505505
}) => (
506506
<button
507507
data-testid="product-modifier-choice-button"
508-
onClick={onSelect}
508+
onClick={select}
509509
className={`w-10 h-10 rounded-full border-4 transition-all duration-200 ${
510510
isSelected
511511
? 'border-brand-primary shadow-lg scale-110 ring-2 ring-brand-primary/30'
@@ -535,11 +535,11 @@ export default function ProductDetails({
535535
{({
536536
value,
537537
isSelected,
538-
onSelect,
538+
select,
539539
}) => (
540540
<button
541541
data-testid="product-modifier-choice-button"
542-
onClick={onSelect}
542+
onClick={select}
543543
className={`px-4 py-2 border rounded-lg transition-all duration-200 ${
544544
isSelected
545545
? 'product-option-active'
@@ -566,16 +566,13 @@ export default function ProductDetails({
566566
<ProductModifiers.ToggleFreeText
567567
modifier={modifier}
568568
>
569-
{({
570-
isTextInputShown,
571-
onToggle,
572-
}) => (
569+
{({ isTextInputShown, toggle }) => (
573570
<div className="space-y-3">
574571
<label className="flex items-center gap-2">
575572
<input
576573
type="checkbox"
577574
checked={isTextInputShown}
578-
onChange={onToggle}
575+
onChange={toggle}
579576
className="w-4 h-4 text-brand-primary rounded border-brand-light focus:ring-brand-primary"
580577
/>
581578
<span className="text-content-primary">

examples/astro-stores-demo/src/components/store/SortDropdown.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ export function SortDropdown() {
1111
</h3>
1212
</div>
1313
<ProductListSort.Options>
14-
{({ selectedSortOption, setSelectedSortOption, sortOptions }) => (
14+
{({ selectedSortOption, updateSortOption, sortOptions }) => (
1515
<select
1616
value={selectedSortOption}
17-
onChange={e => setSelectedSortOption(e.target.value as SortType)}
17+
onChange={e => updateSortOption(e.target.value as SortType)}
1818
className="px-3 py-2 bg-surface-primary border border-brand-light rounded-lg text-content-primary text-sm focus:outline-none focus:ring-2 focus:ring-brand-primary appearance-none min-w-[160px]"
1919
style={{
2020
backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='${encodeURIComponent(

examples/astro-stores-demo/src/layouts/StoreLayout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { useEffect, useState, type ReactNode } from 'react';
22
import { MiniCartContent, MiniCartIcon } from '../components/ecom/MiniCart';
33
import { CurrentCart } from '@wix/headless-ecom/react';
4+
import type { CurrentCartServiceConfig } from '@wix/headless-ecom/services';
45

56
interface StoreLayoutProps {
67
children: ReactNode;
7-
currentCartServiceConfig: any;
8+
currentCartServiceConfig: CurrentCartServiceConfig;
89
showSuccessMessage?: boolean;
910
onSuccessMessageChange?: (show: boolean) => void;
1011
}

examples/astro-stores-demo/src/pages/cart.astro

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,9 @@ const currentCartServiceConfig = await loadCurrentCartServiceConfig();
1414
content="Review and manage items in your Shopping Cart"
1515
/>
1616

17-
<CartPage client:load currentCartServiceConfig={currentCartServiceConfig} slot="body" />
17+
<CartPage
18+
client:load
19+
currentCartServiceConfig={currentCartServiceConfig}
20+
slot="body"
21+
/>
1822
</BaseLayout>

packages/headless-components/media/src/react/MediaGallery.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export interface ThumbnailItemRenderProps {
221221
/** Whether this thumbnail is currently active */
222222
isActive: boolean;
223223
/** Function to select this media */
224-
onSelect: () => void;
224+
select: () => void;
225225
/** Index of this thumbnail */
226226
index: number;
227227
/** Alt text for thumbnail */
@@ -239,9 +239,9 @@ export interface ThumbnailItemRenderProps {
239239
* function ThumbnailButton({ index }) {
240240
* return (
241241
* <MediaGallery.ThumbnailItem index={index}>
242-
* {({ src, isActive, onSelect, alt }) => (
242+
* {({ src, isActive, select, alt }) => (
243243
* <button
244-
* onClick={onSelect}
244+
* onClick={select}
245245
* className={`thumbnail-btn ${isActive ? 'active' : ''}`}
246246
* >
247247
* <img src={src} alt={alt} />
@@ -271,15 +271,15 @@ export const ThumbnailItem = (props: ThumbnailItemProps) => {
271271

272272
const isActive = currentIndex === props.index;
273273

274-
const onSelect = () => {
274+
const select = () => {
275275
mediaService.setSelectedMediaIndex(props.index);
276276
};
277277

278278
return props.children({
279279
item: mediaToDisplay[props.index],
280280
src,
281281
isActive,
282-
onSelect,
282+
select,
283283
index: props.index,
284284
alt,
285285
});
@@ -298,7 +298,7 @@ export interface NextProps {
298298
*/
299299
export interface NextRenderProps {
300300
/** Function to go to next media */
301-
onNext: () => void;
301+
next: () => void;
302302
/** Whether there is a next media available */
303303
canGoNext: boolean;
304304
}
@@ -314,9 +314,9 @@ export interface NextRenderProps {
314314
* function NextButton() {
315315
* return (
316316
* <MediaGallery.Next>
317-
* {({ onNext, canGoNext }) => (
317+
* {({ next, canGoNext }) => (
318318
* <button
319-
* onClick={onNext}
319+
* onClick={next}
320320
* disabled={!canGoNext}
321321
* className="nav-btn next-btn"
322322
* >
@@ -342,7 +342,7 @@ export const Next = (props: NextProps) => {
342342
}
343343

344344
return props.children({
345-
onNext: mediaService.nextMedia,
345+
next: mediaService.nextMedia,
346346
canGoNext,
347347
});
348348
};
@@ -360,7 +360,7 @@ export interface PreviousProps {
360360
*/
361361
export interface PreviousRenderProps {
362362
/** Function to go to previous media */
363-
onPrevious: () => void;
363+
previous: () => void;
364364
/** Whether there is a previous media available */
365365
canGoPrevious: boolean;
366366
}
@@ -376,9 +376,9 @@ export interface PreviousRenderProps {
376376
* function PreviousButton() {
377377
* return (
378378
* <MediaGallery.Previous>
379-
* {({ onPrevious, canGoPrevious }) => (
379+
* {({ previous, canGoPrevious }) => (
380380
* <button
381-
* onClick={onPrevious}
381+
* onClick={previous}
382382
* disabled={!canGoPrevious}
383383
* className="nav-btn prev-btn"
384384
* >
@@ -404,7 +404,7 @@ export const Previous = (props: PreviousProps) => {
404404
}
405405

406406
return props.children({
407-
onPrevious: mediaService.previousMedia,
407+
previous: mediaService.previousMedia,
408408
canGoPrevious,
409409
});
410410
};

0 commit comments

Comments
 (0)