@nok-integration/storefront-react 0.20.5 → 0.20.7
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 +8 -6
- package/dist/index.mjs +77 -7
- package/dist/standalone/storefront.mjs +77 -7
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -4272,8 +4272,8 @@ declare type OrderDetail = z.infer<typeof OrderDetail>;
|
|
|
4272
4272
|
/**
|
|
4273
4273
|
* The fan's orders (Figma `mobile/order/list`).
|
|
4274
4274
|
*
|
|
4275
|
-
* Read-only, like the detail screen it links to.
|
|
4276
|
-
*
|
|
4275
|
+
* Read-only, like the detail screen it links to. A return is a row of its own beside the
|
|
4276
|
+
* order it came from, and opens its own progress — see {@link ReturnStatusBadge}.
|
|
4277
4277
|
*
|
|
4278
4278
|
* Scoped to the session at the engine: `GET /v1/orders` takes no customer parameter, so
|
|
4279
4279
|
* there is no identifier a caller could supply to read somebody else's history.
|
|
@@ -4284,11 +4284,13 @@ export declare interface OrderListViewProps {
|
|
|
4284
4284
|
/** Opens one order. Without it the rows render as static cards rather than dead links. */
|
|
4285
4285
|
onOpenOrder?: (orderRef: string) => void;
|
|
4286
4286
|
/**
|
|
4287
|
-
*
|
|
4287
|
+
* Open one return on a route of your own.
|
|
4288
4288
|
*
|
|
4289
|
-
*
|
|
4290
|
-
*
|
|
4291
|
-
*
|
|
4289
|
+
* Optional, and optional in the way every handler here is: it customises where the row
|
|
4290
|
+
* goes, it does not decide whether the row opens. Omit it and the return's progress opens
|
|
4291
|
+
* in place of the list, the way the order screen opens one. It is deliberately not
|
|
4292
|
+
* defaulted to `onOpenOrder`: a fan tapping a return is asking about the return, and
|
|
4293
|
+
* landing them on the order is a different answer to the question they asked.
|
|
4292
4294
|
*/
|
|
4293
4295
|
onOpenReturn?: (returnRef: string) => void;
|
|
4294
4296
|
/** The empty state's call to action — the design's "Continue shopping" button. */
|
package/dist/index.mjs
CHANGED
|
@@ -5189,8 +5189,8 @@ function resolveAssetUrl(src, base) {
|
|
|
5189
5189
|
const MAX_AGE_MS = 5 * 6e4;
|
|
5190
5190
|
const CAPACITY = 60;
|
|
5191
5191
|
class ProductCache {
|
|
5192
|
-
constructor(
|
|
5193
|
-
this.now =
|
|
5192
|
+
constructor(now2 = () => Date.now()) {
|
|
5193
|
+
this.now = now2;
|
|
5194
5194
|
}
|
|
5195
5195
|
now;
|
|
5196
5196
|
entries = /* @__PURE__ */ new Map();
|
|
@@ -5702,8 +5702,66 @@ function useTopOffset(ref, property, enabled = true) {
|
|
|
5702
5702
|
};
|
|
5703
5703
|
}, [ref, property, enabled]);
|
|
5704
5704
|
}
|
|
5705
|
+
const HOLD_MS = 1e3;
|
|
5706
|
+
const TRAVERSAL_WINDOW_MS = 1e3;
|
|
5707
|
+
const now = () => typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
5708
|
+
let lastTraversal = -Infinity;
|
|
5709
|
+
if (typeof window !== "undefined") {
|
|
5710
|
+
window.addEventListener("popstate", () => {
|
|
5711
|
+
lastTraversal = now();
|
|
5712
|
+
});
|
|
5713
|
+
}
|
|
5714
|
+
function followsTraversal() {
|
|
5715
|
+
return now() - lastTraversal < TRAVERSAL_WINDOW_MS;
|
|
5716
|
+
}
|
|
5717
|
+
const RELEASES = ["touchstart", "wheel", "keydown", "pointerdown"];
|
|
5718
|
+
function anchorTop(shouldHold = () => true) {
|
|
5719
|
+
let released = false;
|
|
5720
|
+
const top2 = () => {
|
|
5721
|
+
if (released) return;
|
|
5722
|
+
const scrolled2 = window.scrollY || document.documentElement.scrollTop || 0;
|
|
5723
|
+
if (scrolled2 > 0 && shouldHold()) window.scrollTo(0, 0);
|
|
5724
|
+
};
|
|
5725
|
+
const release = () => {
|
|
5726
|
+
if (released) return;
|
|
5727
|
+
released = true;
|
|
5728
|
+
if (frame2 !== null && typeof cancelAnimationFrame === "function") cancelAnimationFrame(frame2);
|
|
5729
|
+
clearTimeout(timer2);
|
|
5730
|
+
window.removeEventListener("scroll", top2);
|
|
5731
|
+
for (const type of RELEASES) window.removeEventListener(type, release);
|
|
5732
|
+
};
|
|
5733
|
+
top2();
|
|
5734
|
+
const frame2 = typeof requestAnimationFrame === "function" ? requestAnimationFrame(top2) : null;
|
|
5735
|
+
const timer2 = setTimeout(release, HOLD_MS);
|
|
5736
|
+
window.addEventListener("scroll", top2, {
|
|
5737
|
+
passive: true
|
|
5738
|
+
});
|
|
5739
|
+
for (const type of RELEASES) window.addEventListener(type, release, {
|
|
5740
|
+
passive: true
|
|
5741
|
+
});
|
|
5742
|
+
return release;
|
|
5743
|
+
}
|
|
5744
|
+
function documentTop(el) {
|
|
5745
|
+
let top2 = 0;
|
|
5746
|
+
for (let node = el; node; node = node.offsetParent) {
|
|
5747
|
+
top2 += node.offsetTop;
|
|
5748
|
+
}
|
|
5749
|
+
return top2;
|
|
5750
|
+
}
|
|
5751
|
+
function beginsOnTheFirstViewport(el) {
|
|
5752
|
+
return documentTop(el) < window.innerHeight;
|
|
5753
|
+
}
|
|
5754
|
+
function useScreenAnchor(ref, enabled = true) {
|
|
5755
|
+
useEffect(() => {
|
|
5756
|
+
const el = ref.current;
|
|
5757
|
+
if (!el || !enabled) return;
|
|
5758
|
+
if (followsTraversal()) return;
|
|
5759
|
+
return anchorTop(() => beginsOnTheFirstViewport(el));
|
|
5760
|
+
}, [ref, enabled]);
|
|
5761
|
+
}
|
|
5705
5762
|
const ShopSurface = forwardRef(function ShopSurface2({ tone, fill: fill2 = false, children, className, ...rest }, ref) {
|
|
5706
5763
|
const own = useRef(null);
|
|
5764
|
+
useScreenAnchor(own, fill2);
|
|
5707
5765
|
useTopOffset(own, "--surface-top", fill2);
|
|
5708
5766
|
const attach = useCallback((node) => {
|
|
5709
5767
|
own.current = node;
|
|
@@ -8297,11 +8355,19 @@ function Chevron() {
|
|
|
8297
8355
|
});
|
|
8298
8356
|
}
|
|
8299
8357
|
function OrderListView(props) {
|
|
8358
|
+
const [opened, setOpened] = useState(null);
|
|
8359
|
+
if (opened !== null) {
|
|
8360
|
+
return jsx(ReturnFlowView, {
|
|
8361
|
+
returnRef: opened,
|
|
8362
|
+
onDone: () => setOpened(null)
|
|
8363
|
+
});
|
|
8364
|
+
}
|
|
8300
8365
|
return jsx(ShopSurface, {
|
|
8301
8366
|
tone: "light",
|
|
8302
8367
|
fill: true,
|
|
8303
8368
|
children: jsx(OrderListContent, {
|
|
8304
|
-
...props
|
|
8369
|
+
...props,
|
|
8370
|
+
onOpenReturn: props.onOpenReturn ?? setOpened
|
|
8305
8371
|
})
|
|
8306
8372
|
});
|
|
8307
8373
|
}
|
|
@@ -10295,14 +10361,14 @@ function formatRemaining(ms) {
|
|
|
10295
10361
|
return `${hh}:${mm}:${ss}`;
|
|
10296
10362
|
}
|
|
10297
10363
|
function PromoBanner({ promo: promo2 }) {
|
|
10298
|
-
const [
|
|
10364
|
+
const [now2, setNow] = useState(null);
|
|
10299
10365
|
useEffect(() => {
|
|
10300
10366
|
if (!promo2.ends_at) return;
|
|
10301
10367
|
setNow(Date.now());
|
|
10302
10368
|
const id = setInterval(() => setNow(Date.now()), 1e3);
|
|
10303
10369
|
return () => clearInterval(id);
|
|
10304
10370
|
}, [promo2.ends_at]);
|
|
10305
|
-
const remaining = promo2.ends_at &&
|
|
10371
|
+
const remaining = promo2.ends_at && now2 !== null ? new Date(promo2.ends_at).getTime() - now2 : null;
|
|
10306
10372
|
const showTimer = remaining !== null && remaining > 0;
|
|
10307
10373
|
return jsxs("div", {
|
|
10308
10374
|
className: styles$b.banner,
|
|
@@ -11221,8 +11287,11 @@ function useDocumentSnap(ref, enabled = true) {
|
|
|
11221
11287
|
root2.style.scrollSnapType = "y mandatory";
|
|
11222
11288
|
root2.style.scrollPaddingTop = "0px";
|
|
11223
11289
|
const top2 = () => window.scrollTo(0, 0);
|
|
11224
|
-
|
|
11225
|
-
|
|
11290
|
+
const entered = !followsTraversal();
|
|
11291
|
+
if (entered) top2();
|
|
11292
|
+
const frame2 = entered && typeof window.requestAnimationFrame === "function" ? window.requestAnimationFrame(top2) : null;
|
|
11293
|
+
const release = entered ? anchorTop() : () => {
|
|
11294
|
+
};
|
|
11226
11295
|
const history = window.history;
|
|
11227
11296
|
const previousRestoration = history && "scrollRestoration" in history ? history.scrollRestoration : null;
|
|
11228
11297
|
if (previousRestoration !== null) history.scrollRestoration = "manual";
|
|
@@ -11231,6 +11300,7 @@ function useDocumentSnap(ref, enabled = true) {
|
|
|
11231
11300
|
};
|
|
11232
11301
|
window.addEventListener("pageshow", onPageShow);
|
|
11233
11302
|
return () => {
|
|
11303
|
+
release();
|
|
11234
11304
|
if (frame2 !== null && typeof window.cancelAnimationFrame === "function") {
|
|
11235
11305
|
window.cancelAnimationFrame(frame2);
|
|
11236
11306
|
}
|
|
@@ -5189,8 +5189,8 @@ function resolveAssetUrl(src, base) {
|
|
|
5189
5189
|
const MAX_AGE_MS = 5 * 6e4;
|
|
5190
5190
|
const CAPACITY = 60;
|
|
5191
5191
|
class ProductCache {
|
|
5192
|
-
constructor(
|
|
5193
|
-
this.now =
|
|
5192
|
+
constructor(now2 = () => Date.now()) {
|
|
5193
|
+
this.now = now2;
|
|
5194
5194
|
}
|
|
5195
5195
|
now;
|
|
5196
5196
|
entries = /* @__PURE__ */ new Map();
|
|
@@ -5702,8 +5702,66 @@ function useTopOffset(ref, property, enabled = true) {
|
|
|
5702
5702
|
};
|
|
5703
5703
|
}, [ref, property, enabled]);
|
|
5704
5704
|
}
|
|
5705
|
+
const HOLD_MS = 1e3;
|
|
5706
|
+
const TRAVERSAL_WINDOW_MS = 1e3;
|
|
5707
|
+
const now = () => typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
5708
|
+
let lastTraversal = -Infinity;
|
|
5709
|
+
if (typeof window !== "undefined") {
|
|
5710
|
+
window.addEventListener("popstate", () => {
|
|
5711
|
+
lastTraversal = now();
|
|
5712
|
+
});
|
|
5713
|
+
}
|
|
5714
|
+
function followsTraversal() {
|
|
5715
|
+
return now() - lastTraversal < TRAVERSAL_WINDOW_MS;
|
|
5716
|
+
}
|
|
5717
|
+
const RELEASES = ["touchstart", "wheel", "keydown", "pointerdown"];
|
|
5718
|
+
function anchorTop(shouldHold = () => true) {
|
|
5719
|
+
let released = false;
|
|
5720
|
+
const top2 = () => {
|
|
5721
|
+
if (released) return;
|
|
5722
|
+
const scrolled2 = window.scrollY || document.documentElement.scrollTop || 0;
|
|
5723
|
+
if (scrolled2 > 0 && shouldHold()) window.scrollTo(0, 0);
|
|
5724
|
+
};
|
|
5725
|
+
const release = () => {
|
|
5726
|
+
if (released) return;
|
|
5727
|
+
released = true;
|
|
5728
|
+
if (frame2 !== null && typeof cancelAnimationFrame === "function") cancelAnimationFrame(frame2);
|
|
5729
|
+
clearTimeout(timer2);
|
|
5730
|
+
window.removeEventListener("scroll", top2);
|
|
5731
|
+
for (const type of RELEASES) window.removeEventListener(type, release);
|
|
5732
|
+
};
|
|
5733
|
+
top2();
|
|
5734
|
+
const frame2 = typeof requestAnimationFrame === "function" ? requestAnimationFrame(top2) : null;
|
|
5735
|
+
const timer2 = setTimeout(release, HOLD_MS);
|
|
5736
|
+
window.addEventListener("scroll", top2, {
|
|
5737
|
+
passive: true
|
|
5738
|
+
});
|
|
5739
|
+
for (const type of RELEASES) window.addEventListener(type, release, {
|
|
5740
|
+
passive: true
|
|
5741
|
+
});
|
|
5742
|
+
return release;
|
|
5743
|
+
}
|
|
5744
|
+
function documentTop(el) {
|
|
5745
|
+
let top2 = 0;
|
|
5746
|
+
for (let node = el; node; node = node.offsetParent) {
|
|
5747
|
+
top2 += node.offsetTop;
|
|
5748
|
+
}
|
|
5749
|
+
return top2;
|
|
5750
|
+
}
|
|
5751
|
+
function beginsOnTheFirstViewport(el) {
|
|
5752
|
+
return documentTop(el) < window.innerHeight;
|
|
5753
|
+
}
|
|
5754
|
+
function useScreenAnchor(ref, enabled = true) {
|
|
5755
|
+
useEffect(() => {
|
|
5756
|
+
const el = ref.current;
|
|
5757
|
+
if (!el || !enabled) return;
|
|
5758
|
+
if (followsTraversal()) return;
|
|
5759
|
+
return anchorTop(() => beginsOnTheFirstViewport(el));
|
|
5760
|
+
}, [ref, enabled]);
|
|
5761
|
+
}
|
|
5705
5762
|
const ShopSurface = forwardRef(function ShopSurface2({ tone, fill: fill2 = false, children, className, ...rest }, ref) {
|
|
5706
5763
|
const own = useRef(null);
|
|
5764
|
+
useScreenAnchor(own, fill2);
|
|
5707
5765
|
useTopOffset(own, "--surface-top", fill2);
|
|
5708
5766
|
const attach = useCallback((node) => {
|
|
5709
5767
|
own.current = node;
|
|
@@ -8297,11 +8355,19 @@ function Chevron() {
|
|
|
8297
8355
|
});
|
|
8298
8356
|
}
|
|
8299
8357
|
function OrderListView(props) {
|
|
8358
|
+
const [opened, setOpened] = useState(null);
|
|
8359
|
+
if (opened !== null) {
|
|
8360
|
+
return jsx(ReturnFlowView, {
|
|
8361
|
+
returnRef: opened,
|
|
8362
|
+
onDone: () => setOpened(null)
|
|
8363
|
+
});
|
|
8364
|
+
}
|
|
8300
8365
|
return jsx(ShopSurface, {
|
|
8301
8366
|
tone: "light",
|
|
8302
8367
|
fill: true,
|
|
8303
8368
|
children: jsx(OrderListContent, {
|
|
8304
|
-
...props
|
|
8369
|
+
...props,
|
|
8370
|
+
onOpenReturn: props.onOpenReturn ?? setOpened
|
|
8305
8371
|
})
|
|
8306
8372
|
});
|
|
8307
8373
|
}
|
|
@@ -10295,14 +10361,14 @@ function formatRemaining(ms) {
|
|
|
10295
10361
|
return `${hh}:${mm}:${ss}`;
|
|
10296
10362
|
}
|
|
10297
10363
|
function PromoBanner({ promo: promo2 }) {
|
|
10298
|
-
const [
|
|
10364
|
+
const [now2, setNow] = useState(null);
|
|
10299
10365
|
useEffect(() => {
|
|
10300
10366
|
if (!promo2.ends_at) return;
|
|
10301
10367
|
setNow(Date.now());
|
|
10302
10368
|
const id = setInterval(() => setNow(Date.now()), 1e3);
|
|
10303
10369
|
return () => clearInterval(id);
|
|
10304
10370
|
}, [promo2.ends_at]);
|
|
10305
|
-
const remaining = promo2.ends_at &&
|
|
10371
|
+
const remaining = promo2.ends_at && now2 !== null ? new Date(promo2.ends_at).getTime() - now2 : null;
|
|
10306
10372
|
const showTimer = remaining !== null && remaining > 0;
|
|
10307
10373
|
return jsxs("div", {
|
|
10308
10374
|
className: styles$b.banner,
|
|
@@ -11221,8 +11287,11 @@ function useDocumentSnap(ref, enabled = true) {
|
|
|
11221
11287
|
root2.style.scrollSnapType = "y mandatory";
|
|
11222
11288
|
root2.style.scrollPaddingTop = "0px";
|
|
11223
11289
|
const top2 = () => window.scrollTo(0, 0);
|
|
11224
|
-
|
|
11225
|
-
|
|
11290
|
+
const entered = !followsTraversal();
|
|
11291
|
+
if (entered) top2();
|
|
11292
|
+
const frame2 = entered && typeof window.requestAnimationFrame === "function" ? window.requestAnimationFrame(top2) : null;
|
|
11293
|
+
const release = entered ? anchorTop() : () => {
|
|
11294
|
+
};
|
|
11226
11295
|
const history = window.history;
|
|
11227
11296
|
const previousRestoration = history && "scrollRestoration" in history ? history.scrollRestoration : null;
|
|
11228
11297
|
if (previousRestoration !== null) history.scrollRestoration = "manual";
|
|
@@ -11231,6 +11300,7 @@ function useDocumentSnap(ref, enabled = true) {
|
|
|
11231
11300
|
};
|
|
11232
11301
|
window.addEventListener("pageshow", onPageShow);
|
|
11233
11302
|
return () => {
|
|
11303
|
+
release();
|
|
11234
11304
|
if (frame2 !== null && typeof window.cancelAnimationFrame === "function") {
|
|
11235
11305
|
window.cancelAnimationFrame(frame2);
|
|
11236
11306
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nok-integration/storefront-react",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.7",
|
|
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
|
"type": "module",
|