@nok-integration/storefront-react 0.19.25 → 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 +13 -1
- package/dist/index.mjs +57 -36
- package/dist/standalone/storefront.mjs +57 -36
- package/package.json +1 -1
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
|
-
|
|
10043
|
-
|
|
10044
|
-
|
|
10045
|
-
|
|
10046
|
-
return
|
|
10047
|
-
|
|
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", {
|
|
@@ -10666,37 +10677,50 @@ function CategoryView({ code, initialData, onNotFound }) {
|
|
|
10666
10677
|
function ProductView({ sku, initialData, showRecommendations = true, onNotFound }) {
|
|
10667
10678
|
const t = useT();
|
|
10668
10679
|
const { api, market, emit } = useShop();
|
|
10669
|
-
const [
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10680
|
+
const [loaded, setLoaded] = useState(initialData ? {
|
|
10681
|
+
sku,
|
|
10682
|
+
product: initialData.product,
|
|
10683
|
+
inventory: initialData.inventory ?? null,
|
|
10684
|
+
recommendations: []
|
|
10685
|
+
} : null);
|
|
10686
|
+
const [failure, setFailure] = useState(null);
|
|
10687
|
+
const current2 = loaded?.sku === sku ? loaded : null;
|
|
10688
|
+
const error2 = failure?.sku === sku ? failure.code : void 0;
|
|
10674
10689
|
useEffect(() => {
|
|
10675
10690
|
let live = true;
|
|
10676
|
-
setError(void 0);
|
|
10677
10691
|
(async () => {
|
|
10678
10692
|
try {
|
|
10679
10693
|
const p = await api.catalog.getProduct(sku, market);
|
|
10680
10694
|
if (!live) return;
|
|
10681
|
-
|
|
10695
|
+
setLoaded({
|
|
10696
|
+
sku,
|
|
10697
|
+
product: p,
|
|
10698
|
+
inventory: null,
|
|
10699
|
+
recommendations: []
|
|
10700
|
+
});
|
|
10682
10701
|
const hasVariants = (p.variants?.length ?? 0) > 0;
|
|
10683
10702
|
const [inv, recs] = await Promise.allSettled([hasVariants ? Promise.resolve(null) : api.inventory.get(sku), showRecommendations ? api.catalog.getRecommendations(sku, market) : Promise.resolve({
|
|
10684
10703
|
data: []
|
|
10685
10704
|
})]);
|
|
10686
10705
|
if (!live) return;
|
|
10687
|
-
|
|
10688
|
-
|
|
10706
|
+
setLoaded({
|
|
10707
|
+
sku,
|
|
10708
|
+
product: p,
|
|
10709
|
+
inventory: inv.status === "fulfilled" ? inv.value : null,
|
|
10710
|
+
recommendations: recs.status === "fulfilled" ? recs.value.data : []
|
|
10711
|
+
});
|
|
10689
10712
|
} catch (err) {
|
|
10690
10713
|
if (!live) return;
|
|
10691
10714
|
const c = codeOf(err);
|
|
10692
|
-
|
|
10715
|
+
setFailure({
|
|
10716
|
+
sku,
|
|
10717
|
+
code: c
|
|
10718
|
+
});
|
|
10693
10719
|
emit({
|
|
10694
10720
|
type: "error",
|
|
10695
10721
|
code: c,
|
|
10696
10722
|
scope: "product"
|
|
10697
10723
|
});
|
|
10698
|
-
} finally {
|
|
10699
|
-
if (live) setLoading(false);
|
|
10700
10724
|
}
|
|
10701
10725
|
})();
|
|
10702
10726
|
return () => {
|
|
@@ -10717,26 +10741,23 @@ function ProductView({ sku, initialData, showRecommendations = true, onNotFound
|
|
|
10717
10741
|
});
|
|
10718
10742
|
return unavailable;
|
|
10719
10743
|
}
|
|
10720
|
-
if (
|
|
10744
|
+
if (current2) {
|
|
10721
10745
|
return jsx(ProductDetail, {
|
|
10722
|
-
product,
|
|
10723
|
-
inventory:
|
|
10724
|
-
recommendations
|
|
10746
|
+
product: current2.product,
|
|
10747
|
+
inventory: current2.inventory,
|
|
10748
|
+
recommendations: current2.recommendations
|
|
10725
10749
|
});
|
|
10726
10750
|
}
|
|
10727
|
-
if (
|
|
10751
|
+
if (!error2) return jsx(ScreenSkeleton, {
|
|
10728
10752
|
tone: "light"
|
|
10729
10753
|
});
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
|
|
10737
|
-
});
|
|
10738
|
-
}
|
|
10739
|
-
return unavailable;
|
|
10754
|
+
return jsx(ShopSurface, {
|
|
10755
|
+
tone: "light",
|
|
10756
|
+
fill: true,
|
|
10757
|
+
children: jsx(ErrorState, {
|
|
10758
|
+
code: error2
|
|
10759
|
+
})
|
|
10760
|
+
});
|
|
10740
10761
|
}
|
|
10741
10762
|
const showcase = "_showcase_1qnt2_44";
|
|
10742
10763
|
const panel = "_panel_1qnt2_48";
|
|
@@ -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
|
-
|
|
10043
|
-
|
|
10044
|
-
|
|
10045
|
-
|
|
10046
|
-
return
|
|
10047
|
-
|
|
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", {
|
|
@@ -10666,37 +10677,50 @@ function CategoryView({ code, initialData, onNotFound }) {
|
|
|
10666
10677
|
function ProductView({ sku, initialData, showRecommendations = true, onNotFound }) {
|
|
10667
10678
|
const t = useT();
|
|
10668
10679
|
const { api, market, emit } = useShop();
|
|
10669
|
-
const [
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10680
|
+
const [loaded, setLoaded] = useState(initialData ? {
|
|
10681
|
+
sku,
|
|
10682
|
+
product: initialData.product,
|
|
10683
|
+
inventory: initialData.inventory ?? null,
|
|
10684
|
+
recommendations: []
|
|
10685
|
+
} : null);
|
|
10686
|
+
const [failure, setFailure] = useState(null);
|
|
10687
|
+
const current2 = loaded?.sku === sku ? loaded : null;
|
|
10688
|
+
const error2 = failure?.sku === sku ? failure.code : void 0;
|
|
10674
10689
|
useEffect(() => {
|
|
10675
10690
|
let live = true;
|
|
10676
|
-
setError(void 0);
|
|
10677
10691
|
(async () => {
|
|
10678
10692
|
try {
|
|
10679
10693
|
const p = await api.catalog.getProduct(sku, market);
|
|
10680
10694
|
if (!live) return;
|
|
10681
|
-
|
|
10695
|
+
setLoaded({
|
|
10696
|
+
sku,
|
|
10697
|
+
product: p,
|
|
10698
|
+
inventory: null,
|
|
10699
|
+
recommendations: []
|
|
10700
|
+
});
|
|
10682
10701
|
const hasVariants = (p.variants?.length ?? 0) > 0;
|
|
10683
10702
|
const [inv, recs] = await Promise.allSettled([hasVariants ? Promise.resolve(null) : api.inventory.get(sku), showRecommendations ? api.catalog.getRecommendations(sku, market) : Promise.resolve({
|
|
10684
10703
|
data: []
|
|
10685
10704
|
})]);
|
|
10686
10705
|
if (!live) return;
|
|
10687
|
-
|
|
10688
|
-
|
|
10706
|
+
setLoaded({
|
|
10707
|
+
sku,
|
|
10708
|
+
product: p,
|
|
10709
|
+
inventory: inv.status === "fulfilled" ? inv.value : null,
|
|
10710
|
+
recommendations: recs.status === "fulfilled" ? recs.value.data : []
|
|
10711
|
+
});
|
|
10689
10712
|
} catch (err) {
|
|
10690
10713
|
if (!live) return;
|
|
10691
10714
|
const c = codeOf(err);
|
|
10692
|
-
|
|
10715
|
+
setFailure({
|
|
10716
|
+
sku,
|
|
10717
|
+
code: c
|
|
10718
|
+
});
|
|
10693
10719
|
emit({
|
|
10694
10720
|
type: "error",
|
|
10695
10721
|
code: c,
|
|
10696
10722
|
scope: "product"
|
|
10697
10723
|
});
|
|
10698
|
-
} finally {
|
|
10699
|
-
if (live) setLoading(false);
|
|
10700
10724
|
}
|
|
10701
10725
|
})();
|
|
10702
10726
|
return () => {
|
|
@@ -10717,26 +10741,23 @@ function ProductView({ sku, initialData, showRecommendations = true, onNotFound
|
|
|
10717
10741
|
});
|
|
10718
10742
|
return unavailable;
|
|
10719
10743
|
}
|
|
10720
|
-
if (
|
|
10744
|
+
if (current2) {
|
|
10721
10745
|
return jsx(ProductDetail, {
|
|
10722
|
-
product,
|
|
10723
|
-
inventory:
|
|
10724
|
-
recommendations
|
|
10746
|
+
product: current2.product,
|
|
10747
|
+
inventory: current2.inventory,
|
|
10748
|
+
recommendations: current2.recommendations
|
|
10725
10749
|
});
|
|
10726
10750
|
}
|
|
10727
|
-
if (
|
|
10751
|
+
if (!error2) return jsx(ScreenSkeleton, {
|
|
10728
10752
|
tone: "light"
|
|
10729
10753
|
});
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
|
|
10737
|
-
});
|
|
10738
|
-
}
|
|
10739
|
-
return unavailable;
|
|
10754
|
+
return jsx(ShopSurface, {
|
|
10755
|
+
tone: "light",
|
|
10756
|
+
fill: true,
|
|
10757
|
+
children: jsx(ErrorState, {
|
|
10758
|
+
code: error2
|
|
10759
|
+
})
|
|
10760
|
+
});
|
|
10740
10761
|
}
|
|
10741
10762
|
const showcase = "_showcase_1qnt2_44";
|
|
10742
10763
|
const panel = "_panel_1qnt2_48";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nok-integration/storefront-react",
|
|
3
|
-
"version": "0.19.
|
|
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": {
|