@redotech/redo-hydrogen 1.4.5 → 1.4.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/CHANGELOG.md +36 -24
- package/dist/cjs/index.js +11 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/types.d.ts +100 -0
- package/package.json +1 -1
- package/src/hooks/use-purple-dot-preorder.ts +42 -0
- package/src/index.ts +3 -1
- package/src/utils/purple-dot.ts +92 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import {
|
|
3
|
+
updatePurpleDotButtons,
|
|
4
|
+
cleanupPurpleDotButtons,
|
|
5
|
+
} from "../utils/purple-dot";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* React hook to disable add-to-cart buttons when a Purple Dot preorder element is present.
|
|
9
|
+
* Watches for DOM changes and automatically disables/enables buttons based on the presence
|
|
10
|
+
* of the <purple-dot-learn-more> element.
|
|
11
|
+
*
|
|
12
|
+
* @param disablePreorderButtons - When true, enables the preorder button disabling logic.
|
|
13
|
+
* When false, the hook does nothing.
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* ```tsx
|
|
17
|
+
* function ProductPage() {
|
|
18
|
+
* const isShopOnSiteActive = true; // your condition here
|
|
19
|
+
* useDisablePurpleDotPreorder(isShopOnSiteActive);
|
|
20
|
+
* return <div>...</div>;
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function useDisablePurpleDotPreorder(disablePreorderButtons: boolean): void {
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!disablePreorderButtons) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Initial check
|
|
31
|
+
updatePurpleDotButtons();
|
|
32
|
+
|
|
33
|
+
// Watch for DOM changes (variant selection, page navigation, etc.)
|
|
34
|
+
const observer = new MutationObserver(updatePurpleDotButtons);
|
|
35
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
36
|
+
|
|
37
|
+
return () => {
|
|
38
|
+
observer.disconnect();
|
|
39
|
+
cleanupPurpleDotButtons();
|
|
40
|
+
};
|
|
41
|
+
}, [disablePreorderButtons]);
|
|
42
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { REDO_REQUIRED_HOSTNAMES } from "./utils/security";
|
|
|
4
4
|
import { CartProductVariantFragment, CartAttributeKey, CartInfoToEnable, RedoContextValue, RedoCoverageClient, RedoError, RedoErrorType } from "./types";
|
|
5
5
|
import { LoadState, Loader, useLoad } from './utils/react-utils'
|
|
6
6
|
import { RedoInfoCard } from "./components/redo-info-modal";
|
|
7
|
+
import { useDisablePurpleDotPreorder } from "./hooks/use-purple-dot-preorder";
|
|
7
8
|
|
|
8
9
|
export {
|
|
9
10
|
RedoCheckoutButtons,
|
|
@@ -12,7 +13,8 @@ export {
|
|
|
12
13
|
useLoad,
|
|
13
14
|
REDO_REQUIRED_HOSTNAMES,
|
|
14
15
|
RedoErrorType,
|
|
15
|
-
RedoInfoCard
|
|
16
|
+
RedoInfoCard,
|
|
17
|
+
useDisablePurpleDotPreorder
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
export type {
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const DISABLED_ATTR = "data-redo-preorder-disabled";
|
|
2
|
+
const ORIGINAL_DISABLED_ATTR = "data-redo-original-disabled";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Finds add-to-cart buttons on the page
|
|
6
|
+
*/
|
|
7
|
+
function findAddToCartButtons(): HTMLButtonElement[] {
|
|
8
|
+
const buttons = document.querySelectorAll<HTMLButtonElement>(
|
|
9
|
+
'button[name="add"], button[type="submit"], .product-form__submit'
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
return Array.from(buttons).filter((button) => {
|
|
13
|
+
const text = button.textContent?.toLowerCase().trim() ?? "";
|
|
14
|
+
return text.includes("add to cart") || text.includes("add to bag");
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Checks for Purple Dot preorder element and updates button states accordingly.
|
|
20
|
+
* Disables add-to-cart buttons when purple-dot-learn-more element is present.
|
|
21
|
+
* Re-enables them when the element is removed.
|
|
22
|
+
*/
|
|
23
|
+
export function updatePurpleDotButtons(): void {
|
|
24
|
+
const hasPurpleDot = document.querySelector("purple-dot-learn-more") !== null;
|
|
25
|
+
const addToCartButtons = findAddToCartButtons();
|
|
26
|
+
|
|
27
|
+
for (const button of addToCartButtons) {
|
|
28
|
+
if (hasPurpleDot) {
|
|
29
|
+
// Disable the button
|
|
30
|
+
if (!button.hasAttribute(DISABLED_ATTR)) {
|
|
31
|
+
// Preserve original disabled state
|
|
32
|
+
if (!button.hasAttribute(ORIGINAL_DISABLED_ATTR)) {
|
|
33
|
+
button.setAttribute(ORIGINAL_DISABLED_ATTR, String(button.disabled));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
button.setAttribute(DISABLED_ATTR, "true");
|
|
37
|
+
button.disabled = true;
|
|
38
|
+
button.style.opacity = "0.5";
|
|
39
|
+
button.style.cursor = "not-allowed";
|
|
40
|
+
button.style.pointerEvents = "none";
|
|
41
|
+
|
|
42
|
+
// Add message if not already present
|
|
43
|
+
if (!button.parentElement?.querySelector(".redo-preorder-msg")) {
|
|
44
|
+
const msg = document.createElement("div");
|
|
45
|
+
msg.className = "redo-preorder-msg";
|
|
46
|
+
msg.textContent = "Preorder items cannot be added during exchanges";
|
|
47
|
+
msg.style.cssText =
|
|
48
|
+
"color: #d63031; font-size: 12px; margin-top: 8px; font-weight: 500;";
|
|
49
|
+
button.parentElement?.insertBefore(msg, button.nextSibling);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
// Re-enable the button if we disabled it
|
|
54
|
+
if (button.hasAttribute(DISABLED_ATTR)) {
|
|
55
|
+
const wasDisabled =
|
|
56
|
+
button.getAttribute(ORIGINAL_DISABLED_ATTR) === "true";
|
|
57
|
+
button.removeAttribute(DISABLED_ATTR);
|
|
58
|
+
button.removeAttribute(ORIGINAL_DISABLED_ATTR);
|
|
59
|
+
button.disabled = wasDisabled;
|
|
60
|
+
button.style.opacity = "";
|
|
61
|
+
button.style.cursor = "";
|
|
62
|
+
button.style.pointerEvents = "";
|
|
63
|
+
button.parentElement?.querySelector(".redo-preorder-msg")?.remove();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Cleans up all disabled buttons (used on unmount).
|
|
71
|
+
* Restores original disabled state.
|
|
72
|
+
*/
|
|
73
|
+
export function cleanupPurpleDotButtons(): void {
|
|
74
|
+
const disabledButtons = Array.from(
|
|
75
|
+
document.querySelectorAll<HTMLButtonElement>(`button[${DISABLED_ATTR}]`)
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
for (const button of disabledButtons) {
|
|
79
|
+
const wasDisabled = button.getAttribute(ORIGINAL_DISABLED_ATTR) === "true";
|
|
80
|
+
button.removeAttribute(DISABLED_ATTR);
|
|
81
|
+
button.removeAttribute(ORIGINAL_DISABLED_ATTR);
|
|
82
|
+
button.disabled = wasDisabled;
|
|
83
|
+
button.style.opacity = "";
|
|
84
|
+
button.style.cursor = "";
|
|
85
|
+
button.style.pointerEvents = "";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Remove all messages
|
|
89
|
+
document
|
|
90
|
+
.querySelectorAll(".redo-preorder-msg")
|
|
91
|
+
.forEach((msg) => msg.remove());
|
|
92
|
+
}
|