@frak-labs/components 0.0.26-beta.b38eef2e → 0.0.26-beta.d04602ec

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.
Files changed (42) hide show
  1. package/cdn/Banner.BfkMel9Q.js +1 -0
  2. package/cdn/ButtonShare.BM9Inhmf.js +1 -0
  3. package/cdn/ButtonWallet.B7UmJcbb.js +40 -0
  4. package/cdn/OpenInAppButton.B4mrsz6L.js +1 -0
  5. package/cdn/PostPurchase.BIc0C4Ma.js +1 -0
  6. package/cdn/components.js +1 -1
  7. package/cdn/formatReward.C8hlSKRj.js +1 -0
  8. package/cdn/jsxRuntime.module.5UNmmhNi.js +138 -0
  9. package/cdn/loader.css +0 -14
  10. package/cdn/loader.js +66 -1
  11. package/cdn/useLightDomStyles.D895e4W1.js +1 -0
  12. package/cdn/useReward.DEU0AF3P.js +1 -0
  13. package/cdn/useShareModal.CN9_P7Sl.js +1 -0
  14. package/dist/banner.d.ts +103 -0
  15. package/dist/banner.js +187 -0
  16. package/dist/buttonShare.d.ts +7 -5
  17. package/dist/buttonShare.js +59 -94
  18. package/dist/buttonWallet.d.ts +9 -1
  19. package/dist/buttonWallet.js +78 -33
  20. package/dist/formatReward-6JQldDEC.js +28 -0
  21. package/dist/openInApp.d.ts +2 -0
  22. package/dist/openInApp.js +22 -20
  23. package/dist/postPurchase.d.ts +116 -0
  24. package/dist/postPurchase.js +146 -0
  25. package/dist/useLightDomStyles-DukxuNnJ.js +44 -0
  26. package/dist/usePlacement-BbMuz8_A.js +340 -0
  27. package/dist/useReward-CI2yRrCj.js +67 -0
  28. package/dist/useShareModal-DHlayNqk.js +55 -0
  29. package/package.json +21 -15
  30. package/cdn/ButtonShare.CSPl5Bi5.js +0 -1
  31. package/cdn/ButtonWallet.3Hp62hGr.js +0 -1
  32. package/cdn/OpenInAppButton.BTvukMkp.js +0 -1
  33. package/cdn/Spinner.DQogVqic.js +0 -1
  34. package/cdn/initFrakSdk.CMgrZQwQ.js +0 -14
  35. package/cdn/useClientReady.CKKC4IMk.js +0 -1
  36. package/dist/Spinner-Btnwk01x.js +0 -36
  37. package/dist/Spinner-CHZD3tMn.css +0 -1
  38. package/dist/buttonShare.css +0 -1
  39. package/dist/buttonWallet.css +0 -1
  40. package/dist/openInApp.css +0 -1
  41. package/dist/useClientReady-0vKBG0-p.js +0 -197
  42. package/dist/useReward-DAkT-7wT.js +0 -48
@@ -1,9 +1,8 @@
1
- import { i as openWalletModal, n as registerWebComponent, t as useClientReady } from "./useClientReady-0vKBG0-p.js";
2
- import { t as useReward } from "./useReward-DAkT-7wT.js";
1
+ import { a as useClientReady, o as registerWebComponent, r as buildStyleContent, s as openWalletModal, t as usePlacement } from "./usePlacement-BbMuz8_A.js";
2
+ import { t as useReward } from "./useReward-CI2yRrCj.js";
3
3
  import { trackEvent } from "@frak-labs/core-sdk";
4
- import { cx } from "class-variance-authority";
5
4
  import { useEffect, useMemo, useState } from "preact/hooks";
6
- import { jsx, jsxs } from "preact/jsx-runtime";
5
+ import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
7
6
 
8
7
  //#region src/components/ButtonWallet/assets/GiftIcon.tsx
9
8
  function GiftIcon(props) {
@@ -23,21 +22,48 @@ function GiftIcon(props) {
23
22
  });
24
23
  }
25
24
 
26
- //#endregion
27
- //#region src/components/ButtonWallet/ButtonWallet.module.css?css_module
28
- const classes = {
29
- "button__left": "Kl62ia_button__left",
30
- "button__right": "Kl62ia_button__right",
31
- "button": "Kl62ia_button",
32
- "reward": "Kl62ia_reward"
33
- };
34
- const _button__left0 = classes["button__left"];
35
- const _button__right0 = classes["button__right"];
36
- const _button0 = classes["button"];
37
- const _reward0 = classes["reward"];
38
-
39
25
  //#endregion
40
26
  //#region src/components/ButtonWallet/ButtonWallet.tsx
27
+ const componentCss = `
28
+ .button {
29
+ all: unset;
30
+ position: fixed;
31
+ bottom: 20px;
32
+ z-index: 2000000;
33
+ display: flex;
34
+ justify-content: center;
35
+ align-items: center;
36
+ background-color: #3e557e;
37
+ width: 45px;
38
+ height: 45px;
39
+ border-radius: 50%;
40
+ cursor: pointer;
41
+ text-align: center;
42
+ font-size: 24px;
43
+ }
44
+
45
+ .button__left {
46
+ left: 20px;
47
+ }
48
+
49
+ .button__right {
50
+ right: 20px;
51
+ }
52
+
53
+ .reward {
54
+ position: absolute;
55
+ top: -4px;
56
+ right: 27px;
57
+ padding: 2px 3px;
58
+ border-radius: 5px;
59
+ background: #ff3f3f;
60
+ font-size: 9px;
61
+ color: #fff;
62
+ font-weight: 600;
63
+ white-space: nowrap;
64
+ line-height: 9px;
65
+ }
66
+ `;
41
67
  /**
42
68
  * Button to open wallet modal
43
69
  *
@@ -70,40 +96,59 @@ const _reward0 = classes["reward"];
70
96
  * <frak-button-wallet use-reward target-interaction="custom.customerMeeting"></frak-button-wallet>
71
97
  * ```
72
98
  *
99
+ * @example
100
+ * Using placement:
101
+ * ```html
102
+ * <frak-button-wallet placement="hero-wallet"></frak-button-wallet>
103
+ * ```
104
+ *
73
105
  * @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
74
106
  * @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
75
107
  */
76
- function ButtonWallet({ classname = "", useReward: rawUseReward, targetInteraction }) {
77
- const shouldUseReward = useMemo(() => rawUseReward !== void 0, [rawUseReward]);
78
- const { isClientReady } = useClientReady();
79
- const { reward } = useReward(shouldUseReward && isClientReady, targetInteraction);
108
+ function ButtonWallet({ placement: placementId, classname = "", useReward: rawUseReward, targetInteraction }) {
109
+ const placement = usePlacement(placementId);
110
+ const resolvedTargetInteraction = useMemo(() => placement?.targetInteraction !== void 0 ? placement.targetInteraction : targetInteraction, [placement?.targetInteraction, targetInteraction]);
111
+ const shouldUseReward = useMemo(() => rawUseReward === true, [rawUseReward]);
112
+ const { shouldRender, isHidden, isClientReady } = useClientReady();
113
+ const { reward } = useReward(shouldUseReward && isClientReady, resolvedTargetInteraction);
80
114
  const [position, setPosition] = useState("right");
81
- /**
82
- * Setup the position of the button
83
- */
84
115
  useEffect(() => {
85
- const position = window.FrakSetup?.modalWalletConfig?.metadata?.position;
86
- setPosition(position ?? "right");
87
- }, []);
88
- return /* @__PURE__ */ jsxs("button", {
116
+ const placementPosition = placement?.components?.buttonWallet?.position;
117
+ const configPosition = window.FrakSetup?.modalWalletConfig?.metadata?.position;
118
+ setPosition(placementPosition ?? configPosition ?? "right");
119
+ }, [placement?.components?.buttonWallet?.position]);
120
+ if (!shouldRender || isHidden) return null;
121
+ const buttonClass = [
122
+ "button",
123
+ "button__fadeIn",
124
+ position === "left" ? "button__left" : "button__right",
125
+ classname
126
+ ].filter(Boolean).join(" ");
127
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("style", { children: buildStyleContent(componentCss, placement?.components?.buttonWallet?.css) }), /* @__PURE__ */ jsxs("button", {
89
128
  type: "button",
90
129
  "aria-label": "Open wallet",
91
- class: cx(classes.button, position === "left" ? classes.button__left : classes.button__right, classname, "override"),
130
+ part: "button",
92
131
  disabled: !isClientReady,
132
+ class: buttonClass,
93
133
  onClick: () => {
94
134
  trackEvent(window.FrakSetup.client, "wallet_button_clicked");
95
- openWalletModal();
135
+ openWalletModal(resolvedTargetInteraction, placementId);
96
136
  },
97
137
  children: [/* @__PURE__ */ jsx(GiftIcon, {}), reward && /* @__PURE__ */ jsx("span", {
98
- className: classes.reward,
138
+ class: "reward",
99
139
  children: reward
100
140
  })]
101
- });
141
+ })] });
102
142
  }
103
143
 
104
144
  //#endregion
105
145
  //#region src/components/ButtonWallet/index.ts
106
- registerWebComponent(ButtonWallet, "frak-button-wallet", [], { shadow: false });
146
+ registerWebComponent(ButtonWallet, "frak-button-wallet", [
147
+ "placement",
148
+ "classname",
149
+ "useReward",
150
+ "targetInteraction"
151
+ ], { shadow: true });
107
152
 
108
153
  //#endregion
109
154
  export { ButtonWallet };
@@ -0,0 +1,28 @@
1
+ import { formatAmount, getCurrencyAmountKey, getSupportedCurrency } from "@frak-labs/core-sdk";
2
+
3
+ //#region src/utils/formatReward.ts
4
+ /**
5
+ * Format an {@link EstimatedReward} into a human-readable string.
6
+ *
7
+ * - `fixed` → e.g. `"5 €"`
8
+ * - `percentage` → if `basketAmount` is provided, computes the actual value
9
+ * (e.g. `"10 €"`), otherwise returns `"10 %"`
10
+ * - `tiered` → max tier value, e.g. `"50 €"`
11
+ */
12
+ function formatEstimatedReward(reward, currency, basketAmount) {
13
+ const supportedCurrency = getSupportedCurrency(currency);
14
+ const key = getCurrencyAmountKey(supportedCurrency);
15
+ switch (reward.payoutType) {
16
+ case "fixed": return formatAmount(Math.round(reward.amount[key]), supportedCurrency);
17
+ case "percentage":
18
+ if (basketAmount !== void 0) return formatAmount(Math.round(reward.percent * basketAmount / 100), supportedCurrency);
19
+ return `${reward.percent} %`;
20
+ case "tiered": {
21
+ const max = reward.tiers.reduce((acc, tier) => Math.max(acc, tier.amount[key]), 0);
22
+ return formatAmount(Math.round(max), supportedCurrency);
23
+ }
24
+ }
25
+ }
26
+
27
+ //#endregion
28
+ export { formatEstimatedReward as t };
@@ -6,6 +6,7 @@ import * as preact from "preact";
6
6
  * @inline
7
7
  */
8
8
  type OpenInAppButtonProps = {
9
+ placement?: string;
9
10
  /**
10
11
  * Text to display on the button
11
12
  * @defaultValue `"Open in App"`
@@ -45,6 +46,7 @@ type OpenInAppButtonProps = {
45
46
  * ```
46
47
  */
47
48
  declare function OpenInAppButton({
49
+ placement: placementId,
48
50
  text,
49
51
  classname
50
52
  }: OpenInAppButtonProps): preact.JSX.Element | null;
package/dist/openInApp.js CHANGED
@@ -1,9 +1,8 @@
1
- import { n as registerWebComponent, t as useClientReady } from "./useClientReady-0vKBG0-p.js";
2
- import { t as Spinner } from "./Spinner-Btnwk01x.js";
1
+ import { a as useClientReady, o as registerWebComponent, t as usePlacement } from "./usePlacement-BbMuz8_A.js";
2
+ import { t as useLightDomStyles } from "./useLightDomStyles-DukxuNnJ.js";
3
3
  import { DEEP_LINK_SCHEME, trackEvent, triggerDeepLinkWithFallback } from "@frak-labs/core-sdk";
4
- import { cx } from "class-variance-authority";
5
4
  import { useMemo } from "preact/hooks";
6
- import { jsx, jsxs } from "preact/jsx-runtime";
5
+ import { jsx } from "preact/jsx-runtime";
7
6
 
8
7
  //#region src/utils/isMobile.ts
9
8
  /**
@@ -48,11 +47,6 @@ function openFrakWalletApp(path = DEFAULT_PATH) {
48
47
  } });
49
48
  }
50
49
 
51
- //#endregion
52
- //#region src/components/OpenInAppButton/OpenInAppButton.module.css?css_module
53
- const classes = { "button": "XYfqGq_button" };
54
- const _button0 = classes["button"];
55
-
56
50
  //#endregion
57
51
  //#region src/components/OpenInAppButton/OpenInAppButton.tsx
58
52
  /**
@@ -81,30 +75,38 @@ const _button0 = classes["button"];
81
75
  * <frak-open-in-app classname="button button-primary"></frak-open-in-app>
82
76
  * ```
83
77
  */
84
- function OpenInAppButton({ text = "Open in App", classname = "" }) {
85
- const { isClientReady } = useClientReady();
78
+ function OpenInAppButton({ placement: placementId, text = "Open in App", classname = "" }) {
79
+ const placement = usePlacement(placementId);
80
+ const { shouldRender, isHidden, isClientReady } = useClientReady();
86
81
  const { isMobile } = useIsMobile();
87
- if (!isMobile) return null;
82
+ useLightDomStyles("frak-open-in-app", placementId, placement?.components?.openInApp?.css);
83
+ const resolvedText = placement?.components?.openInApp?.text ?? text;
84
+ if (!isMobile || !shouldRender || isHidden) return null;
88
85
  const handleClick = () => {
89
86
  openFrakWalletApp();
90
87
  };
91
- return /* @__PURE__ */ jsxs("button", {
88
+ const buttonClass = [
89
+ "button",
90
+ "button__fadeIn",
91
+ classname
92
+ ].filter(Boolean).join(" ");
93
+ return /* @__PURE__ */ jsx("button", {
92
94
  type: "button",
93
95
  "aria-label": "Open in Frak Wallet app",
94
- className: cx(classes.button, classname, "override"),
95
96
  disabled: !isClientReady,
97
+ class: buttonClass,
96
98
  onClick: handleClick,
97
- children: [
98
- !isClientReady && /* @__PURE__ */ jsx(Spinner, {}),
99
- " ",
100
- text
101
- ]
99
+ children: resolvedText
102
100
  });
103
101
  }
104
102
 
105
103
  //#endregion
106
104
  //#region src/components/OpenInAppButton/index.ts
107
- registerWebComponent(OpenInAppButton, "frak-open-in-app", ["text"], { shadow: false });
105
+ registerWebComponent(OpenInAppButton, "frak-open-in-app", [
106
+ "text",
107
+ "placement",
108
+ "classname"
109
+ ], { shadow: false });
108
110
 
109
111
  //#endregion
110
112
  export { OpenInAppButton };
@@ -0,0 +1,116 @@
1
+ import * as preact from "preact";
2
+
3
+ //#region src/components/PostPurchase/types.d.ts
4
+ /**
5
+ * Props for the {@link PostPurchase} component.
6
+ * @inline
7
+ */
8
+ type PostPurchaseProps = {
9
+ /**
10
+ * Merchant customer ID for purchase tracking fallback.
11
+ * All three tracking props (`customerId`, `orderId`, `token`) must be
12
+ * present for tracking to fire.
13
+ */
14
+ customerId?: string;
15
+ /**
16
+ * Merchant order ID for purchase tracking fallback.
17
+ */
18
+ orderId?: string;
19
+ /**
20
+ * Checkout token for purchase tracking fallback.
21
+ */
22
+ token?: string;
23
+ /**
24
+ * Base URL to share. Falls back to the merchant domain returned by
25
+ * the backend when omitted.
26
+ */
27
+ sharingUrl?: string;
28
+ /**
29
+ * Override the merchant ID resolved from the SDK config.
30
+ */
31
+ merchantId?: string;
32
+ /**
33
+ * Placement ID for backend-driven CSS customization.
34
+ */
35
+ placement?: string;
36
+ /**
37
+ * CSS class names passed through to the root element (Light DOM).
38
+ */
39
+ classname?: string;
40
+ /**
41
+ * Force a display variant instead of relying on the backend evaluation.
42
+ */
43
+ variant?: "referrer" | "referee";
44
+ /**
45
+ * Override the message shown to referrers.
46
+ * Use `{REWARD}` as placeholder for the reward amount.
47
+ */
48
+ referrerText?: string;
49
+ /**
50
+ * Override the message shown to referees.
51
+ * Use `{REWARD}` as placeholder for the reward amount.
52
+ */
53
+ refereeText?: string;
54
+ /**
55
+ * Override the CTA button text.
56
+ * Use `{REWARD}` as placeholder for the reward amount.
57
+ */
58
+ ctaText?: string;
59
+ };
60
+ //#endregion
61
+ //#region src/components/PostPurchase/PostPurchase.d.ts
62
+ /**
63
+ * Post-purchase card component.
64
+ *
65
+ * Renders an inline card on the merchant's thank-you / order-status page
66
+ * that either congratulates a referee or invites a referrer to share.
67
+ *
68
+ * Fetches referral status and merchant information via two independent
69
+ * RPC calls, then computes the display variant locally.
70
+ *
71
+ * @group components
72
+ *
73
+ * @example
74
+ * Minimal — just show the card:
75
+ * ```html
76
+ * <frak-post-purchase></frak-post-purchase>
77
+ * ```
78
+ *
79
+ * @example
80
+ * With purchase tracking fallback and custom sharing URL:
81
+ * ```html
82
+ * <frak-post-purchase
83
+ * customer-id="cust_123"
84
+ * order-id="ord_456"
85
+ * token="checkout_abc"
86
+ * sharing-url="https://merchant.com/product/shoes"
87
+ * ></frak-post-purchase>
88
+ * ```
89
+ */
90
+ declare function PostPurchase({
91
+ customerId,
92
+ orderId,
93
+ token,
94
+ sharingUrl,
95
+ merchantId,
96
+ placement: placementId,
97
+ classname,
98
+ variant: forcedVariant,
99
+ referrerText: propReferrerText,
100
+ refereeText: propRefereeText,
101
+ ctaText: propCtaText
102
+ }: PostPurchaseProps): preact.JSX.Element | null;
103
+ //#endregion
104
+ //#region src/components/PostPurchase/index.d.ts
105
+ /**
106
+ * Custom element interface for `<frak-post-purchase>`.
107
+ * Combines standard {@link HTMLElement} with {@link PostPurchaseProps}.
108
+ */
109
+ interface PostPurchaseElement extends HTMLElement, PostPurchaseProps {}
110
+ declare global {
111
+ interface HTMLElementTagNameMap {
112
+ "frak-post-purchase": PostPurchaseElement;
113
+ }
114
+ }
115
+ //#endregion
116
+ export { PostPurchase, PostPurchaseElement };
@@ -0,0 +1,146 @@
1
+ import { a as useClientReady, o as registerWebComponent, t as usePlacement } from "./usePlacement-BbMuz8_A.js";
2
+ import { t as useLightDomStyles } from "./useLightDomStyles-DukxuNnJ.js";
3
+ import { t as formatEstimatedReward } from "./formatReward-6JQldDEC.js";
4
+ import { t as useShareModal } from "./useShareModal-DHlayNqk.js";
5
+ import { getMerchantInformation, getUserReferralStatus, trackPurchaseStatus } from "@frak-labs/core-sdk/actions";
6
+ import { useEffect, useMemo, useState } from "preact/hooks";
7
+ import { jsx, jsxs } from "preact/jsx-runtime";
8
+ import { FrakRpcError, RpcErrorCodes } from "@frak-labs/frame-connector";
9
+
10
+ //#region src/components/PostPurchase/PostPurchase.tsx
11
+ /**
12
+ * Given referral status and merchant info, compute the display variant
13
+ * and pick the appropriate purchase reward.
14
+ */
15
+ function resolvePostPurchaseContext(referralStatus, merchantInfo) {
16
+ const purchaseReward = merchantInfo.rewards.find((r) => r.interactionTypeKey === "purchase" && (r.referrer || r.referee));
17
+ if (!purchaseReward) return null;
18
+ const variant = referralStatus?.isReferred && purchaseReward.referee ? "referee" : "referrer";
19
+ return {
20
+ variant,
21
+ reward: variant === "referee" ? purchaseReward.referee : purchaseReward.referrer,
22
+ merchantDomain: merchantInfo.onChainMetadata.domain
23
+ };
24
+ }
25
+ /**
26
+ * Post-purchase card component.
27
+ *
28
+ * Renders an inline card on the merchant's thank-you / order-status page
29
+ * that either congratulates a referee or invites a referrer to share.
30
+ *
31
+ * Fetches referral status and merchant information via two independent
32
+ * RPC calls, then computes the display variant locally.
33
+ *
34
+ * @group components
35
+ *
36
+ * @example
37
+ * Minimal — just show the card:
38
+ * ```html
39
+ * <frak-post-purchase></frak-post-purchase>
40
+ * ```
41
+ *
42
+ * @example
43
+ * With purchase tracking fallback and custom sharing URL:
44
+ * ```html
45
+ * <frak-post-purchase
46
+ * customer-id="cust_123"
47
+ * order-id="ord_456"
48
+ * token="checkout_abc"
49
+ * sharing-url="https://merchant.com/product/shoes"
50
+ * ></frak-post-purchase>
51
+ * ```
52
+ */
53
+ function PostPurchase({ customerId, orderId, token, sharingUrl, merchantId, placement: placementId, classname = "", variant: forcedVariant, referrerText: propReferrerText, refereeText: propRefereeText, ctaText: propCtaText }) {
54
+ const { shouldRender, isHidden, isClientReady } = useClientReady();
55
+ const placement = usePlacement(placementId);
56
+ useLightDomStyles("frak-post-purchase", placementId, placement?.components?.postPurchase?.css);
57
+ const [context, setContext] = useState(null);
58
+ const [hasFetched, setHasFetched] = useState(false);
59
+ useEffect(() => {
60
+ if (!isClientReady || !customerId || !orderId || !token) return;
61
+ trackPurchaseStatus({
62
+ customerId,
63
+ orderId,
64
+ token,
65
+ merchantId
66
+ }).catch(() => {});
67
+ }, [
68
+ isClientReady,
69
+ customerId,
70
+ orderId,
71
+ token,
72
+ merchantId
73
+ ]);
74
+ useEffect(() => {
75
+ if (!isClientReady || hasFetched) return;
76
+ const client = window.FrakSetup?.client;
77
+ if (!client) return;
78
+ setHasFetched(true);
79
+ Promise.all([getUserReferralStatus(client), getMerchantInformation(client)]).then(([referralStatus, merchantInfo]) => {
80
+ setContext(resolvePostPurchaseContext(referralStatus, merchantInfo));
81
+ }).catch((e) => {
82
+ if (e instanceof FrakRpcError && e.code === RpcErrorCodes.configError) return;
83
+ console.warn("[Frak] Post-purchase context error", e);
84
+ });
85
+ }, [isClientReady, hasFetched]);
86
+ const resolvedVariant = forcedVariant ?? context?.variant;
87
+ const resolvedSharingUrl = sharingUrl ?? context?.merchantDomain;
88
+ const rewardText = useMemo(() => {
89
+ if (!context?.reward) return void 0;
90
+ const currency = window.FrakSetup?.client?.config?.metadata?.currency;
91
+ return formatEstimatedReward(context.reward, currency);
92
+ }, [context?.reward]);
93
+ const postPurchaseConfig = placement?.components?.postPurchase;
94
+ const texts = useMemo(() => {
95
+ const applyReward = (text) => rewardText ? text.replace("{REWARD}", rewardText) : text;
96
+ return {
97
+ message: resolvedVariant === "referee" ? rewardText ? applyReward(propRefereeText ?? postPurchaseConfig?.refereeText ?? "You just earned {REWARD}! Share with friends to earn even more.") : propRefereeText ?? postPurchaseConfig?.refereeNoRewardText ?? "You just earned a reward! Share with friends to earn even more." : rewardText ? applyReward(propReferrerText ?? postPurchaseConfig?.referrerText ?? "Earn {REWARD} by sharing this with your friends!") : propReferrerText ?? postPurchaseConfig?.referrerNoRewardText ?? "Share this with your friends and earn rewards!",
98
+ cta: rewardText ? applyReward(propCtaText ?? postPurchaseConfig?.ctaText ?? "Share & earn {REWARD}") : propCtaText ?? postPurchaseConfig?.ctaNoRewardText ?? "Share & earn"
99
+ };
100
+ }, [
101
+ resolvedVariant,
102
+ rewardText,
103
+ postPurchaseConfig,
104
+ propReferrerText,
105
+ propRefereeText,
106
+ propCtaText
107
+ ]);
108
+ const { handleShare } = useShareModal(void 0, placementId, resolvedSharingUrl);
109
+ if (!shouldRender || isHidden) return null;
110
+ if (!context || !resolvedVariant) return null;
111
+ return /* @__PURE__ */ jsxs("div", {
112
+ class: ["post-purchase", classname].filter(Boolean).join(" "),
113
+ children: [/* @__PURE__ */ jsx("div", {
114
+ class: "post-purchase__content",
115
+ children: /* @__PURE__ */ jsx("p", {
116
+ class: "post-purchase__message",
117
+ children: texts.message
118
+ })
119
+ }), /* @__PURE__ */ jsx("button", {
120
+ type: "button",
121
+ class: "post-purchase__cta button",
122
+ disabled: !isClientReady,
123
+ onClick: handleShare,
124
+ children: texts.cta
125
+ })]
126
+ });
127
+ }
128
+
129
+ //#endregion
130
+ //#region src/components/PostPurchase/index.ts
131
+ registerWebComponent(PostPurchase, "frak-post-purchase", [
132
+ "customerId",
133
+ "orderId",
134
+ "token",
135
+ "sharingUrl",
136
+ "merchantId",
137
+ "placement",
138
+ "classname",
139
+ "variant",
140
+ "referrerText",
141
+ "refereeText",
142
+ "ctaText"
143
+ ], { shadow: false });
144
+
145
+ //#endregion
146
+ export { PostPurchase };
@@ -0,0 +1,44 @@
1
+ import { i as lightDomBaseCss } from "./usePlacement-BbMuz8_A.js";
2
+ import { useEffect } from "preact/hooks";
3
+
4
+ //#region src/utils/styleManager.ts
5
+ function ensureStyle(id, css) {
6
+ const existing = document.getElementById(id);
7
+ if (existing) {
8
+ if (existing.textContent !== css) existing.textContent = css;
9
+ return;
10
+ }
11
+ const style = document.createElement("style");
12
+ style.id = id;
13
+ style.textContent = css;
14
+ document.head.appendChild(style);
15
+ }
16
+ function injectBase(tag, css) {
17
+ ensureStyle(`frak-base-${tag}`, css);
18
+ }
19
+ function injectPlacement(tag, placementId, scopedCss) {
20
+ ensureStyle(`frak-placement-${tag}-${placementId}`, scopedCss);
21
+ }
22
+ const styleManager = {
23
+ injectBase,
24
+ injectPlacement
25
+ };
26
+
27
+ //#endregion
28
+ //#region src/hooks/useLightDomStyles.ts
29
+ function useLightDomStyles(tag, placementId, placementCss, baseCss) {
30
+ useEffect(() => {
31
+ styleManager.injectBase(tag, baseCss ?? lightDomBaseCss);
32
+ }, [tag]);
33
+ useEffect(() => {
34
+ if (!placementId || !placementCss) return;
35
+ styleManager.injectPlacement(tag, placementId, placementCss);
36
+ }, [
37
+ tag,
38
+ placementId,
39
+ placementCss
40
+ ]);
41
+ }
42
+
43
+ //#endregion
44
+ export { useLightDomStyles as t };