@nok-integration/storefront-react 0.19.26 → 0.19.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -3537,11 +3537,23 @@ export declare interface Market {
3537
3537
  * Swipeable image gallery with dot indicators. Reduced-motion aware (smooth-scroll is
3538
3538
  * disabled globally under prefers-reduced-motion). Keyboard: dots are real buttons.
3539
3539
  */
3540
- export declare function MediaGallery({ media, alt }: MediaGalleryProps): JSX.Element;
3540
+ export declare function MediaGallery({ media, alt, focus }: MediaGalleryProps): JSX.Element;
3541
3541
 
3542
3542
  export declare interface MediaGalleryProps {
3543
3543
  media: string[];
3544
3544
  alt: string;
3545
+ /**
3546
+ * Jump to this slide whenever the value changes.
3547
+ *
3548
+ * How the PDP's colour tiles move the gallery: the set of images does not change when a
3549
+ * colour is picked, so the gallery is not rebuilt and nothing is hidden — it simply
3550
+ * lands on the shot of the colour that was chosen.
3551
+ *
3552
+ * Instant rather than animated, deliberately. Animating means scrolling THROUGH the
3553
+ * other colourways' photographs to reach the chosen one, so picking White would sweep
3554
+ * past the black shirts on the way. That is the very thing this is here to stop.
3555
+ */
3556
+ focus?: number;
3545
3557
  }
3546
3558
 
3547
3559
  export declare function minorUnitExponent(currency: string): number;
package/dist/index.mjs CHANGED
@@ -9316,7 +9316,7 @@ const styles$i = {
9316
9316
  dot: dot$2,
9317
9317
  dotActive: dotActive$2
9318
9318
  };
9319
- function MediaGallery({ media: media2, alt }) {
9319
+ function MediaGallery({ media: media2, alt, focus }) {
9320
9320
  const t = useT();
9321
9321
  const trackRef = useRef(null);
9322
9322
  const [active, setActive] = useState(0);
@@ -9339,6 +9339,13 @@ function MediaGallery({ media: media2, alt }) {
9339
9339
  track2.scrollLeft = 0;
9340
9340
  setActive(0);
9341
9341
  }, [mediaKey]);
9342
+ useEffect(() => {
9343
+ if (focus === void 0 || focus < 0) return;
9344
+ const track2 = trackRef.current;
9345
+ if (!track2) return;
9346
+ track2.scrollLeft = focus * track2.clientWidth;
9347
+ setActive(focus);
9348
+ }, [focus]);
9342
9349
  function goTo(index) {
9343
9350
  const track2 = trackRef.current;
9344
9351
  if (!track2) return;
@@ -10037,14 +10044,15 @@ function ProductDetail({ product, inventory: inventory2, recommendations = [] })
10037
10044
  const colourSoldOut = hasColours && selectedColour ? !colours.find((c) => c.value === selectedColour)?.available : false;
10038
10045
  const purchasable = anyInStock && !colourSoldOut;
10039
10046
  const colourImage = useMemo(() => selectedColour ? baseColours.find((c) => c.value === selectedColour)?.image : void 0, [baseColours, selectedColour]);
10040
- const shootColour = baseColours[0]?.value;
10041
10047
  const media2 = useMemo(() => {
10042
- if (!colourImage) return product.media;
10043
- if (selectedColour === shootColour) {
10044
- return [colourImage, ...product.media.filter((m) => m !== colourImage)];
10045
- }
10046
- return [colourImage];
10047
- }, [colourImage, product.media, selectedColour, shootColour]);
10048
+ const swatches2 = baseColours.map((c) => c.image).filter((src) => typeof src === "string" && src.length > 0);
10049
+ return [...swatches2, ...product.media.filter((m) => !swatches2.includes(m))];
10050
+ }, [baseColours, product.media]);
10051
+ const focus = useMemo(() => {
10052
+ if (!colourImage) return void 0;
10053
+ const at = media2.indexOf(colourImage);
10054
+ return at >= 0 ? at : void 0;
10055
+ }, [colourImage, media2]);
10048
10056
  function selectSize(value2) {
10049
10057
  setSelectedSize(value2);
10050
10058
  setSizeError(false);
@@ -10191,7 +10199,10 @@ function ProductDetail({ product, inventory: inventory2, recommendations = [] })
10191
10199
  className: styles$a.page,
10192
10200
  children: [jsx(MediaGallery, {
10193
10201
  media: media2,
10194
- alt: product.title
10202
+ alt: product.title,
10203
+ ...focus !== void 0 ? {
10204
+ focus
10205
+ } : {}
10195
10206
  }), jsxs("div", {
10196
10207
  className: styles$a.content,
10197
10208
  children: [jsxs("div", {
@@ -9316,7 +9316,7 @@ const styles$i = {
9316
9316
  dot: dot$2,
9317
9317
  dotActive: dotActive$2
9318
9318
  };
9319
- function MediaGallery({ media: media2, alt }) {
9319
+ function MediaGallery({ media: media2, alt, focus }) {
9320
9320
  const t = useT();
9321
9321
  const trackRef = useRef(null);
9322
9322
  const [active, setActive] = useState(0);
@@ -9339,6 +9339,13 @@ function MediaGallery({ media: media2, alt }) {
9339
9339
  track2.scrollLeft = 0;
9340
9340
  setActive(0);
9341
9341
  }, [mediaKey]);
9342
+ useEffect(() => {
9343
+ if (focus === void 0 || focus < 0) return;
9344
+ const track2 = trackRef.current;
9345
+ if (!track2) return;
9346
+ track2.scrollLeft = focus * track2.clientWidth;
9347
+ setActive(focus);
9348
+ }, [focus]);
9342
9349
  function goTo(index) {
9343
9350
  const track2 = trackRef.current;
9344
9351
  if (!track2) return;
@@ -10037,14 +10044,15 @@ function ProductDetail({ product, inventory: inventory2, recommendations = [] })
10037
10044
  const colourSoldOut = hasColours && selectedColour ? !colours.find((c) => c.value === selectedColour)?.available : false;
10038
10045
  const purchasable = anyInStock && !colourSoldOut;
10039
10046
  const colourImage = useMemo(() => selectedColour ? baseColours.find((c) => c.value === selectedColour)?.image : void 0, [baseColours, selectedColour]);
10040
- const shootColour = baseColours[0]?.value;
10041
10047
  const media2 = useMemo(() => {
10042
- if (!colourImage) return product.media;
10043
- if (selectedColour === shootColour) {
10044
- return [colourImage, ...product.media.filter((m) => m !== colourImage)];
10045
- }
10046
- return [colourImage];
10047
- }, [colourImage, product.media, selectedColour, shootColour]);
10048
+ const swatches2 = baseColours.map((c) => c.image).filter((src) => typeof src === "string" && src.length > 0);
10049
+ return [...swatches2, ...product.media.filter((m) => !swatches2.includes(m))];
10050
+ }, [baseColours, product.media]);
10051
+ const focus = useMemo(() => {
10052
+ if (!colourImage) return void 0;
10053
+ const at = media2.indexOf(colourImage);
10054
+ return at >= 0 ? at : void 0;
10055
+ }, [colourImage, media2]);
10048
10056
  function selectSize(value2) {
10049
10057
  setSelectedSize(value2);
10050
10058
  setSizeError(false);
@@ -10191,7 +10199,10 @@ function ProductDetail({ product, inventory: inventory2, recommendations = [] })
10191
10199
  className: styles$a.page,
10192
10200
  children: [jsx(MediaGallery, {
10193
10201
  media: media2,
10194
- alt: product.title
10202
+ alt: product.title,
10203
+ ...focus !== void 0 ? {
10204
+ focus
10205
+ } : {}
10195
10206
  }), jsxs("div", {
10196
10207
  className: styles$a.content,
10197
10208
  children: [jsxs("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nok-integration/storefront-react",
3
- "version": "0.19.26",
3
+ "version": "0.19.27",
4
4
  "description": "Mountable React storefront components: catalogue, product detail and cart, mounted directly into a host DOM tree. No iframe.",
5
5
  "license": "UNLICENSED",
6
6
  "publishConfig": {