@frak-labs/components 0.0.26-beta.d2556d47 → 0.0.26-beta.eb3cff34

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 (37) hide show
  1. package/cdn/Banner.Ws9o79lU.js +64 -0
  2. package/cdn/ButtonShare.BDS1fgma.js +1 -0
  3. package/cdn/ButtonWallet.Be1UyRm8.js +40 -0
  4. package/cdn/OpenInAppButton.Diqt07eo.js +1 -0
  5. package/cdn/PostPurchase.DqFhm-Jn.js +52 -0
  6. package/cdn/components.js +1 -1
  7. package/cdn/formatReward.CXxVsWN3.js +1 -0
  8. package/cdn/loader.js +3 -55
  9. package/cdn/sprinkles.css.ts.vanilla.BtFkD4B3.js +1175 -0
  10. package/cdn/useGlobalComponents.BRe8dKO7.js +1 -0
  11. package/cdn/useLightDomStyles.ZFa154u8.js +1 -0
  12. package/cdn/usePlacement.B7jMsQvP.js +58 -0
  13. package/cdn/useReward.qEKeySJG.js +1 -0
  14. package/cdn/useShareModal.B--64ELG.js +1 -0
  15. package/dist/GiftIcon-4sr9xXyq.js +1501 -0
  16. package/dist/banner.d.ts +116 -0
  17. package/dist/banner.js +431 -0
  18. package/dist/buttonShare.d.ts +3 -3
  19. package/dist/buttonShare.js +26 -63
  20. package/dist/buttonWallet.d.ts +2 -2
  21. package/dist/buttonWallet.js +3 -7
  22. package/dist/formatReward-Bub6Z6eY.js +33 -0
  23. package/dist/openInApp.d.ts +2 -2
  24. package/dist/openInApp.js +3 -9
  25. package/dist/postPurchase.d.ts +122 -0
  26. package/dist/postPurchase.js +1579 -0
  27. package/dist/useGlobalComponents-Cmfszr7v.js +21 -0
  28. package/dist/{useLightDomStyles-ZGaYUErZ.js → useLightDomStyles-hgYYZsTy.js} +4 -7
  29. package/dist/{usePlacement-D99UDsVs.js → usePlacement-LqYjZLX_.js} +20 -62
  30. package/dist/useReward-DU3_yP8Q.js +65 -0
  31. package/dist/useShareModal-DgEf5WWG.js +53 -0
  32. package/package.json +23 -9
  33. package/cdn/ButtonShare.Chxmap9H.js +0 -1
  34. package/cdn/ButtonWallet.Bgt7hfbh.js +0 -40
  35. package/cdn/OpenInAppButton.CGXLv0k_.js +0 -1
  36. package/cdn/jsxRuntime.module.feNUq6Nq.js +0 -58
  37. package/dist/useReward-DAkT-7wT.js +0 -48
@@ -1,12 +1,22 @@
1
- import { a as registerWebComponent, i as useClientReady, s as openEmbeddedWallet, t as usePlacement } from "./usePlacement-D99UDsVs.js";
2
- import { t as useLightDomStyles } from "./useLightDomStyles-ZGaYUErZ.js";
3
- import { t as useReward } from "./useReward-DAkT-7wT.js";
4
- import { DebugInfoGatherer, trackEvent } from "@frak-labs/core-sdk";
5
- import { modalBuilder } from "@frak-labs/core-sdk/actions";
1
+ import { a as registerWebComponent, i as useClientReady, s as openEmbeddedWallet, t as usePlacement } from "./usePlacement-LqYjZLX_.js";
2
+ import { t as useGlobalComponents } from "./useGlobalComponents-Cmfszr7v.js";
3
+ import { t as useLightDomStyles } from "./useLightDomStyles-hgYYZsTy.js";
4
+ import { t as applyRewardPlaceholder } from "./formatReward-Bub6Z6eY.js";
5
+ import { t as useReward } from "./useReward-DU3_yP8Q.js";
6
+ import { t as useShareModal } from "./useShareModal-DgEf5WWG.js";
7
+ import { trackEvent } from "@frak-labs/core-sdk";
8
+ import { displaySharingPage } from "@frak-labs/core-sdk/actions";
6
9
  import { useCallback, useMemo, useState } from "preact/hooks";
7
10
  import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
8
- import { FrakRpcError, RpcErrorCodes } from "@frak-labs/frame-connector";
9
-
11
+ //#region src/utils/sharingPage.ts
12
+ async function openSharingPage(targetInteraction, placement) {
13
+ if (!window.FrakSetup?.client) {
14
+ console.error("Frak client not found");
15
+ return;
16
+ }
17
+ await displaySharingPage(window.FrakSetup.client, { metadata: { ...targetInteraction && { targetInteraction } } }, placement);
18
+ }
19
+ //#endregion
10
20
  //#region src/hooks/useCopyToClipboard.ts
11
21
  function useCopyToClipboard(options = {}) {
12
22
  const { successDuration = 2e3 } = options;
@@ -47,7 +57,6 @@ function useCopyToClipboard(options = {}) {
47
57
  copied
48
58
  };
49
59
  }
50
-
51
60
  //#endregion
52
61
  //#region src/components/ButtonShare/components/ErrorMessage.tsx
53
62
  const styles = {
@@ -158,52 +167,6 @@ function ErrorMessage({ debugInfo }) {
158
167
  ]
159
168
  });
160
169
  }
161
-
162
- //#endregion
163
- //#region src/components/ButtonShare/hooks/useShareModal.ts
164
- /**
165
- * Open the share modal
166
- *
167
- * @description
168
- * This function will open the share modal, lazily creating a modal builder on demand.
169
- */
170
- function useShareModal(targetInteraction, placement) {
171
- const [debugInfo, setDebugInfo] = useState(void 0);
172
- const [isError, setIsError] = useState(false);
173
- return {
174
- handleShare: useCallback(async () => {
175
- if (!window.FrakSetup?.client) {
176
- console.error("Frak client not found");
177
- setDebugInfo(DebugInfoGatherer.empty().formatDebugInfo("Frak client not found"));
178
- setIsError(true);
179
- return;
180
- }
181
- const builder = modalBuilder(window.FrakSetup.client, {});
182
- try {
183
- await builder.sharing({}).display((metadata) => ({
184
- ...metadata,
185
- targetInteraction
186
- }), placement);
187
- } catch (e) {
188
- if (e instanceof FrakRpcError && e.code === RpcErrorCodes.clientAborted) {
189
- console.debug("User aborted the modal");
190
- return;
191
- }
192
- const debugInfo = window.FrakSetup.client.debugInfo.formatDebugInfo(e);
193
- trackEvent(window.FrakSetup.client, "share_modal_error", {
194
- error: e instanceof Object && "message" in e ? e.message : "Unknown error",
195
- debugInfo
196
- });
197
- setDebugInfo(debugInfo);
198
- setIsError(true);
199
- console.error("Error while opening the modal", e);
200
- }
201
- }, [targetInteraction, placement]),
202
- isError,
203
- debugInfo
204
- };
205
- }
206
-
207
170
  //#endregion
208
171
  //#region src/components/ButtonShare/ButtonShare.tsx
209
172
  /**
@@ -249,20 +212,21 @@ function useShareModal(targetInteraction, placement) {
249
212
  */
250
213
  function ButtonShare({ placement: placementId, text = "Share and earn!", classname = "", useReward: rawUseReward, noRewardText, targetInteraction, clickAction: rawClickAction }) {
251
214
  const placement = usePlacement(placementId);
252
- const componentConfig = placement?.components?.buttonShare;
215
+ const globalComponents = useGlobalComponents();
216
+ const componentConfig = placement?.components?.buttonShare ?? globalComponents?.buttonShare;
253
217
  useLightDomStyles("frak-button-share", placementId, componentConfig?.css);
254
218
  const resolvedTargetInteraction = useMemo(() => placement?.targetInteraction !== void 0 ? placement.targetInteraction : targetInteraction, [placement?.targetInteraction, targetInteraction]);
255
219
  const resolvedText = componentConfig?.text ?? text;
256
220
  const resolvedNoRewardText = componentConfig?.noRewardText ?? noRewardText;
257
221
  const shouldUseReward = useMemo(() => componentConfig?.useReward ?? rawUseReward === true, [componentConfig?.useReward, rawUseReward]);
258
- const resolvedClickAction = useMemo(() => componentConfig?.clickAction ?? rawClickAction ?? "embedded-wallet", [componentConfig?.clickAction, rawClickAction]);
222
+ const resolvedClickAction = useMemo(() => componentConfig?.clickAction ?? rawClickAction ?? "sharing-page", [componentConfig?.clickAction, rawClickAction]);
259
223
  const { shouldRender, isHidden, isClientReady } = useClientReady();
260
224
  const { reward } = useReward(shouldUseReward && isClientReady, resolvedTargetInteraction);
261
225
  const { handleShare, isError, debugInfo } = useShareModal(resolvedTargetInteraction, placementId);
262
226
  const btnText = useMemo(() => {
263
227
  if (!shouldUseReward) return resolvedText;
264
- if (!reward) return resolvedNoRewardText ?? resolvedText.replace("{REWARD}", "");
265
- return resolvedText.includes("{REWARD}") ? resolvedText.replace("{REWARD}", reward) : `${resolvedText} ${reward}`;
228
+ if (!reward) return resolvedNoRewardText ?? applyRewardPlaceholder(resolvedText, void 0);
229
+ return resolvedText.includes("{REWARD}") ? applyRewardPlaceholder(resolvedText, reward) : `${resolvedText} ${reward}`;
266
230
  }, [
267
231
  shouldUseReward,
268
232
  resolvedText,
@@ -271,8 +235,9 @@ function ButtonShare({ placement: placementId, text = "Share and earn!", classna
271
235
  ]);
272
236
  const onClick = useCallback(async () => {
273
237
  trackEvent(window.FrakSetup.client, "share_button_clicked");
274
- if (resolvedClickAction === "share-modal") await handleShare();
275
- else openEmbeddedWallet(resolvedTargetInteraction, placementId);
238
+ if (resolvedClickAction === "embedded-wallet") openEmbeddedWallet(resolvedTargetInteraction, placementId);
239
+ else if (resolvedClickAction === "share-modal") await handleShare();
240
+ else openSharingPage(resolvedTargetInteraction, placementId);
276
241
  }, [
277
242
  resolvedClickAction,
278
243
  handleShare,
@@ -293,7 +258,6 @@ function ButtonShare({ placement: placementId, text = "Share and earn!", classna
293
258
  children: btnText
294
259
  }), isError && /* @__PURE__ */ jsx(ErrorMessage, { debugInfo })] });
295
260
  }
296
-
297
261
  //#endregion
298
262
  //#region src/components/ButtonShare/index.ts
299
263
  registerWebComponent(ButtonShare, "frak-button-share", [
@@ -305,6 +269,5 @@ registerWebComponent(ButtonShare, "frak-button-share", [
305
269
  "noRewardText",
306
270
  "targetInteraction"
307
271
  ], { shadow: false });
308
-
309
272
  //#endregion
310
- export { ButtonShare };
273
+ export { ButtonShare };
@@ -1,5 +1,5 @@
1
1
  import { InteractionTypeKey } from "@frak-labs/core-sdk";
2
- import * as preact from "preact";
2
+ import * as _$preact from "preact";
3
3
 
4
4
  //#region src/components/ButtonWallet/types.d.ts
5
5
  /**
@@ -70,7 +70,7 @@ declare function ButtonWallet({
70
70
  classname,
71
71
  useReward: rawUseReward,
72
72
  targetInteraction
73
- }: ButtonWalletProps): preact.JSX.Element | null;
73
+ }: ButtonWalletProps): _$preact.JSX.Element | null;
74
74
  //#endregion
75
75
  //#region src/components/ButtonWallet/index.d.ts
76
76
  /**
@@ -1,9 +1,8 @@
1
- import { a as registerWebComponent, i as useClientReady, n as buildStyleContent, o as openWalletModal, t as usePlacement } from "./usePlacement-D99UDsVs.js";
2
- import { t as useReward } from "./useReward-DAkT-7wT.js";
1
+ import { a as registerWebComponent, i as useClientReady, n as buildStyleContent, o as openWalletModal, t as usePlacement } from "./usePlacement-LqYjZLX_.js";
2
+ import { t as useReward } from "./useReward-DU3_yP8Q.js";
3
3
  import { trackEvent } from "@frak-labs/core-sdk";
4
4
  import { useEffect, useMemo, useState } from "preact/hooks";
5
5
  import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
6
-
7
6
  //#region src/components/ButtonWallet/assets/GiftIcon.tsx
8
7
  function GiftIcon(props) {
9
8
  return /* @__PURE__ */ jsxs("svg", {
@@ -21,7 +20,6 @@ function GiftIcon(props) {
21
20
  })]
22
21
  });
23
22
  }
24
-
25
23
  //#endregion
26
24
  //#region src/components/ButtonWallet/ButtonWallet.tsx
27
25
  const componentCss = `
@@ -140,7 +138,6 @@ function ButtonWallet({ placement: placementId, classname = "", useReward: rawUs
140
138
  })]
141
139
  })] });
142
140
  }
143
-
144
141
  //#endregion
145
142
  //#region src/components/ButtonWallet/index.ts
146
143
  registerWebComponent(ButtonWallet, "frak-button-wallet", [
@@ -149,6 +146,5 @@ registerWebComponent(ButtonWallet, "frak-button-wallet", [
149
146
  "useReward",
150
147
  "targetInteraction"
151
148
  ], { shadow: true });
152
-
153
149
  //#endregion
154
- export { ButtonWallet };
150
+ export { ButtonWallet };
@@ -0,0 +1,33 @@
1
+ import { formatAmount, getCurrencyAmountKey, getSupportedCurrency } from "@frak-labs/core-sdk";
2
+ //#region src/utils/formatReward.ts
3
+ /**
4
+ * Format an {@link EstimatedReward} into a human-readable string.
5
+ *
6
+ * - `fixed` → e.g. `"5 €"`
7
+ * - `percentage` → if `basketAmount` is provided, computes the actual value
8
+ * (e.g. `"10 €"`), otherwise returns `"10 %"`
9
+ * - `tiered` → max tier value, e.g. `"50 €"`
10
+ */
11
+ function formatEstimatedReward(reward, currency, basketAmount) {
12
+ const supportedCurrency = getSupportedCurrency(currency);
13
+ const key = getCurrencyAmountKey(supportedCurrency);
14
+ switch (reward.payoutType) {
15
+ case "fixed": return formatAmount(Math.round(reward.amount[key]), supportedCurrency);
16
+ case "percentage":
17
+ if (basketAmount !== void 0) return formatAmount(Math.round(reward.percent * basketAmount / 100), supportedCurrency);
18
+ return `${reward.percent} %`;
19
+ case "tiered": {
20
+ const max = reward.tiers.reduce((acc, tier) => Math.max(acc, tier.amount[key]), 0);
21
+ return formatAmount(Math.round(max), supportedCurrency);
22
+ }
23
+ }
24
+ }
25
+ /**
26
+ * Replace the `{REWARD}` placeholder in a text string with a reward value.
27
+ * If no reward is provided, returns the text with `{REWARD}` stripped.
28
+ */
29
+ function applyRewardPlaceholder(text, reward) {
30
+ return reward ? text.replace("{REWARD}", reward) : text.replace("{REWARD}", "");
31
+ }
32
+ //#endregion
33
+ export { formatEstimatedReward as n, applyRewardPlaceholder as t };
@@ -1,4 +1,4 @@
1
- import * as preact from "preact";
1
+ import * as _$preact from "preact";
2
2
 
3
3
  //#region src/components/OpenInAppButton/types.d.ts
4
4
  /**
@@ -49,7 +49,7 @@ declare function OpenInAppButton({
49
49
  placement: placementId,
50
50
  text,
51
51
  classname
52
- }: OpenInAppButtonProps): preact.JSX.Element | null;
52
+ }: OpenInAppButtonProps): _$preact.JSX.Element | null;
53
53
  //#endregion
54
54
  //#region src/components/OpenInAppButton/index.d.ts
55
55
  /**
package/dist/openInApp.js CHANGED
@@ -1,9 +1,8 @@
1
- import { a as registerWebComponent, i as useClientReady, t as usePlacement } from "./usePlacement-D99UDsVs.js";
2
- import { t as useLightDomStyles } from "./useLightDomStyles-ZGaYUErZ.js";
1
+ import { a as registerWebComponent, i as useClientReady, t as usePlacement } from "./usePlacement-LqYjZLX_.js";
2
+ import { t as useLightDomStyles } from "./useLightDomStyles-hgYYZsTy.js";
3
3
  import { DEEP_LINK_SCHEME, trackEvent, triggerDeepLinkWithFallback } from "@frak-labs/core-sdk";
4
4
  import { useMemo } from "preact/hooks";
5
5
  import { jsx } from "preact/jsx-runtime";
6
-
7
6
  //#region src/utils/isMobile.ts
8
7
  /**
9
8
  * Check if the current device is a mobile device
@@ -20,13 +19,11 @@ function isMobile() {
20
19
  if (/Macintosh/i.test(navigator.userAgent) && navigator.maxTouchPoints > 1) return true;
21
20
  return false;
22
21
  }
23
-
24
22
  //#endregion
25
23
  //#region src/hooks/useIsMobile.ts
26
24
  function useIsMobile() {
27
25
  return { isMobile: useMemo(() => isMobile(), []) };
28
26
  }
29
-
30
27
  //#endregion
31
28
  //#region src/utils/openInApp.ts
32
29
  const DEFAULT_PATH = "wallet";
@@ -46,7 +43,6 @@ function openFrakWalletApp(path = DEFAULT_PATH) {
46
43
  if (client) trackEvent(client, "app_not_installed");
47
44
  } });
48
45
  }
49
-
50
46
  //#endregion
51
47
  //#region src/components/OpenInAppButton/OpenInAppButton.tsx
52
48
  /**
@@ -99,7 +95,6 @@ function OpenInAppButton({ placement: placementId, text = "Open in App", classna
99
95
  children: resolvedText
100
96
  });
101
97
  }
102
-
103
98
  //#endregion
104
99
  //#region src/components/OpenInAppButton/index.ts
105
100
  registerWebComponent(OpenInAppButton, "frak-open-in-app", [
@@ -107,6 +102,5 @@ registerWebComponent(OpenInAppButton, "frak-open-in-app", [
107
102
  "placement",
108
103
  "classname"
109
104
  ], { shadow: false });
110
-
111
105
  //#endregion
112
- export { OpenInAppButton };
106
+ export { OpenInAppButton };
@@ -0,0 +1,122 @@
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
+ * Label for the pill badge displayed above the message.
46
+ * When omitted (and no placement config provides one), the badge is hidden.
47
+ */
48
+ badgeText?: string;
49
+ /**
50
+ * Override the message shown to referrers.
51
+ * Use `{REWARD}` as placeholder for the reward amount.
52
+ */
53
+ referrerText?: string;
54
+ /**
55
+ * Override the message shown to referees.
56
+ * Use `{REWARD}` as placeholder for the reward amount.
57
+ */
58
+ refereeText?: string;
59
+ /**
60
+ * Override the CTA button text.
61
+ * Use `{REWARD}` as placeholder for the reward amount.
62
+ */
63
+ ctaText?: string;
64
+ };
65
+ //#endregion
66
+ //#region src/components/PostPurchase/PostPurchase.d.ts
67
+ /**
68
+ * Post-purchase card component.
69
+ *
70
+ * Renders an inline card on the merchant's thank-you / order-status page
71
+ * that either congratulates a referee or invites a referrer to share.
72
+ *
73
+ * Fetches referral status and merchant information via two independent
74
+ * RPC calls, then computes the display variant locally.
75
+ *
76
+ * @group components
77
+ *
78
+ * @example
79
+ * Minimal — just show the card:
80
+ * ```html
81
+ * <frak-post-purchase></frak-post-purchase>
82
+ * ```
83
+ *
84
+ * @example
85
+ * With purchase tracking fallback and custom sharing URL:
86
+ * ```html
87
+ * <frak-post-purchase
88
+ * customer-id="cust_123"
89
+ * order-id="ord_456"
90
+ * token="checkout_abc"
91
+ * sharing-url="https://merchant.com/product/shoes"
92
+ * ></frak-post-purchase>
93
+ * ```
94
+ */
95
+ declare function PostPurchase({
96
+ customerId,
97
+ orderId,
98
+ token,
99
+ sharingUrl,
100
+ merchantId,
101
+ placement: placementId,
102
+ classname,
103
+ variant: forcedVariant,
104
+ badgeText: propBadgeText,
105
+ referrerText: propReferrerText,
106
+ refereeText: propRefereeText,
107
+ ctaText: propCtaText
108
+ }: PostPurchaseProps): _$preact.JSX.Element | null;
109
+ //#endregion
110
+ //#region src/components/PostPurchase/index.d.ts
111
+ /**
112
+ * Custom element interface for `<frak-post-purchase>`.
113
+ * Combines standard {@link HTMLElement} with {@link PostPurchaseProps}.
114
+ */
115
+ interface PostPurchaseElement extends HTMLElement, PostPurchaseProps {}
116
+ declare global {
117
+ interface HTMLElementTagNameMap {
118
+ "frak-post-purchase": PostPurchaseElement;
119
+ }
120
+ }
121
+ //#endregion
122
+ export { PostPurchase, PostPurchaseElement };