@frak-labs/components 0.0.26-beta.53dfa7b2 → 0.0.26-beta.5989fbc3

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 (38) 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 +26 -26
  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 +9 -8
  17. package/dist/banner.js +330 -94
  18. package/dist/buttonShare.js +10 -7
  19. package/dist/buttonWallet.js +2 -2
  20. package/dist/{formatReward-_UYA3aHE.js → formatReward-Bub6Z6eY.js} +8 -1
  21. package/dist/openInApp.js +2 -2
  22. package/dist/postPurchase.js +36 -1452
  23. package/dist/useGlobalComponents-Cmfszr7v.js +21 -0
  24. package/dist/{useLightDomStyles-B5Y_fH4K.js → useLightDomStyles-hgYYZsTy.js} +1 -1
  25. package/dist/{usePlacement-CHEgrdvN.js → usePlacement-LqYjZLX_.js} +1 -82
  26. package/dist/{useReward-XF2hB_C_.js → useReward-DU3_yP8Q.js} +1 -1
  27. package/package.json +8 -8
  28. package/cdn/Banner.BrITmwhY.js +0 -1
  29. package/cdn/ButtonShare.Byvhu5Tc.js +0 -1
  30. package/cdn/ButtonWallet.C_GtjZpW.js +0 -40
  31. package/cdn/OpenInAppButton.CZBmQT_a.js +0 -1
  32. package/cdn/PostPurchase.BNSQonvO.js +0 -2362
  33. package/cdn/formatReward.DXMr8a-D.js +0 -1
  34. package/cdn/jsxRuntime.module.GTd8MQxp.js +0 -138
  35. package/cdn/useLightDomStyles.B33IA3q5.js +0 -1
  36. package/cdn/useReward.CvZWCurW.js +0 -1
  37. package/cdn/useShareModal.BJBvkHbY.js +0 -1
  38. /package/dist/{useShareModal-Bmlk3eBJ.js → useShareModal-DgEf5WWG.js} +0 -0
package/dist/banner.d.ts CHANGED
@@ -60,17 +60,18 @@ type BannerProps = {
60
60
  /**
61
61
  * Auto-detecting notification banner component.
62
62
  *
63
- * Renders an inline banner on the merchant page that auto-detects which
64
- * message to display:
63
+ * Renders an inline banner on the merchant page with one of two distinct
64
+ * visual styles depending on the detected mode:
65
65
  *
66
- * - **Referral mode**: Shown after successful referral link processing.
67
- * Displays reward info and a dismiss button ("Got it").
68
- * - **In-app browser mode**: Shown when the page is opened inside a social
69
- * media in-app browser (Instagram, Facebook). Offers a redirect to the
70
- * default browser.
66
+ * - **Referral mode** (white): Shown after a successful referral link
67
+ * processing. Displays a gift icon, reward copy, and a "Got it" CTA.
68
+ * - **In-app browser mode** (dark transparent): Shown when the page is
69
+ * opened inside a social media in-app browser (Instagram, Facebook).
70
+ * Offers an inline link to redirect to the default browser plus a
71
+ * close button to dismiss.
71
72
  *
72
73
  * In-app browser mode takes priority over referral mode.
73
- * Uses Light DOM to inherit merchant page styles.
74
+ * Uses Light DOM + vanilla-extract styles from `@frak-labs/design-system`.
74
75
  *
75
76
  * @group components
76
77
  *
package/dist/banner.js CHANGED
@@ -1,82 +1,264 @@
1
- import { a as useClientReady, n as bannerBaseCss, o as registerWebComponent, t as usePlacement } from "./usePlacement-CHEgrdvN.js";
2
- import { t as useLightDomStyles } from "./useLightDomStyles-B5Y_fH4K.js";
3
- import { t as useReward } from "./useReward-XF2hB_C_.js";
1
+ import { a as registerWebComponent, i as useClientReady, 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 useReward } from "./useReward-DU3_yP8Q.js";
5
+ import { a as CloseCircleIcon, c as cssSource$5, i as ExternalLinkIcon, n as WarningIcon, o as cssSource$6, s as cssSource$4, t as GiftIcon } from "./GiftIcon-4sr9xXyq.js";
4
6
  import { isInAppBrowser, redirectToExternalBrowser } from "@frak-labs/core-sdk";
5
- import { REFERRAL_SUCCESS_EVENT } from "@frak-labs/core-sdk/actions";
7
+ import { REFERRAL_SUCCESS_EVENT, getMergeToken } from "@frak-labs/core-sdk/actions";
6
8
  import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
7
9
  import { jsx, jsxs } from "preact/jsx-runtime";
8
- //#region src/components/Banner/Banner.tsx
9
- /**
10
- * Reward/gift icon for referral mode.
11
- */
12
- function RewardIcon() {
13
- return /* @__PURE__ */ jsxs("svg", {
14
- viewBox: "0 0 24 24",
15
- fill: "none",
16
- stroke: "currentColor",
17
- "stroke-width": "1.5",
18
- "stroke-linecap": "round",
19
- "stroke-linejoin": "round",
20
- "aria-hidden": "true",
10
+ //#region \0ve-inline:../../packages/design-system/src/styles/inAppBanner.css.ts.vanilla.js
11
+ const cssSource$3 = `@keyframes inAppBanner_fadeIn__1ibpiy70 {
12
+ from {
13
+ opacity: 0;
14
+ transform: translateY(-4px);
15
+ }
16
+ to {
17
+ opacity: 1;
18
+ transform: translateY(0);
19
+ }
20
+ }
21
+ .inAppBanner_container__1ibpiy71 {
22
+ position: fixed;
23
+ top: max(8px, env(safe-area-inset-top));
24
+ left: 16px;
25
+ right: 16px;
26
+ z-index: 1000;
27
+ display: flex;
28
+ flex-direction: column;
29
+ gap: 4px;
30
+ padding: 12px 16px;
31
+ padding-right: 32px;
32
+ border-radius: 12px;
33
+ background-color: #000000CC;
34
+ backdrop-filter: blur(12px);
35
+ -webkit-backdrop-filter: blur(12px);
36
+ color: #ffffff;
37
+ animation: inAppBanner_fadeIn__1ibpiy70 300ms ease-out;
38
+ }
39
+ .inAppBanner_header__1ibpiy72 {
40
+ display: flex;
41
+ align-items: center;
42
+ gap: 8px;
43
+ }
44
+ .inAppBanner_iconWrapper__1ibpiy73 {
45
+ flex-shrink: 0;
46
+ width: 20px;
47
+ height: 20px;
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: center;
51
+ color: #ffffff;
52
+ }
53
+ .inAppBanner_title__1ibpiy74 {
54
+ margin: 0;
55
+ padding: 0;
56
+ font-size: 16px;
57
+ font-weight: 500;
58
+ line-height: 26px;
59
+ color: var(--text-onAction__pbq4ak6);
60
+ }
61
+ .inAppBanner_body__1ibpiy75 {
62
+ display: flex;
63
+ flex-wrap: wrap;
64
+ align-items: baseline;
65
+ gap: 0 4px;
66
+ }
67
+ .inAppBanner_description__1ibpiy76 {
68
+ margin: 0;
69
+ padding: 0;
70
+ font-size: 14px;
71
+ color: var(--text-onAction__pbq4ak6);
72
+ line-height: 22px;
73
+ opacity: 0.96;
74
+ }
75
+ .inAppBanner_cta__1ibpiy77 {
76
+ all: unset;
77
+ display: inline-flex;
78
+ align-items: center;
79
+ gap: 4px;
80
+ color: #2BB2FF;
81
+ font-size: 14px;
82
+ font-weight: 600;
83
+ text-decoration: underline;
84
+ text-underline-offset: 2px;
85
+ cursor: pointer;
86
+ }
87
+ .inAppBanner_cta__1ibpiy77:focus-visible {
88
+ outline: 2px solid #2BB2FF;
89
+ outline-offset: 2px;
90
+ border-radius: 4px;
91
+ }
92
+ .inAppBanner_closeButton__1ibpiy78 {
93
+ all: unset;
94
+ position: absolute;
95
+ top: 8px;
96
+ right: 8px;
97
+ width: 28px;
98
+ height: 28px;
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ border-radius: 9999px;
103
+ color: rgba(255, 255, 255, 0.6);
104
+ cursor: pointer;
105
+ }
106
+ .inAppBanner_closeButton__1ibpiy78:focus-visible {
107
+ outline: 2px solid #ffffff;
108
+ outline-offset: 2px;
109
+ }`;
110
+ //#endregion
111
+ //#region ../../packages/design-system/src/styles/inAppBanner.css.ts
112
+ var body = "inAppBanner_body__1ibpiy75";
113
+ var closeButton = "inAppBanner_closeButton__1ibpiy78";
114
+ var container = "inAppBanner_container__1ibpiy71";
115
+ var cta = "inAppBanner_cta__1ibpiy77";
116
+ var description = "inAppBanner_description__1ibpiy76";
117
+ var header = "inAppBanner_header__1ibpiy72";
118
+ var iconWrapper = "inAppBanner_iconWrapper__1ibpiy73";
119
+ var title = "inAppBanner_title__1ibpiy74";
120
+ cssSource$4 + cssSource$3;
121
+ //#endregion
122
+ //#region ../../packages/design-system/src/components/InAppBanner/index.tsx
123
+ function InAppBanner({ title: title$1, description: description$1, cta: cta$1, dismissLabel, onAction, onDismiss, className, classNames }) {
124
+ return /* @__PURE__ */ jsxs("div", {
125
+ className: `${container}${className ? ` ${className}` : ""}`,
126
+ role: "alert",
21
127
  children: [
22
- /* @__PURE__ */ jsx("rect", {
23
- x: "3",
24
- y: "11",
25
- width: "18",
26
- height: "11",
27
- rx: "1"
128
+ /* @__PURE__ */ jsxs("div", {
129
+ className: header,
130
+ children: [/* @__PURE__ */ jsx("span", {
131
+ className: `${iconWrapper}${classNames?.icon ? ` ${classNames.icon}` : ""}`,
132
+ children: /* @__PURE__ */ jsx(WarningIcon, {
133
+ width: 20,
134
+ height: 20
135
+ })
136
+ }), /* @__PURE__ */ jsx("p", {
137
+ className: `${title}${classNames?.title ? ` ${classNames.title}` : ""}`,
138
+ children: title$1
139
+ })]
28
140
  }),
29
- /* @__PURE__ */ jsx("path", { d: "M12 11v11" }),
30
- /* @__PURE__ */ jsx("rect", {
31
- x: "5",
32
- y: "7",
33
- width: "14",
34
- height: "4",
35
- rx: "1"
141
+ /* @__PURE__ */ jsxs("div", {
142
+ className: body,
143
+ children: [/* @__PURE__ */ jsx("p", {
144
+ className: `${description}${classNames?.description ? ` ${classNames.description}` : ""}`,
145
+ children: description$1
146
+ }), /* @__PURE__ */ jsxs("button", {
147
+ type: "button",
148
+ className: `${cta}${classNames?.cta ? ` ${classNames.cta}` : ""}`,
149
+ onClick: onAction,
150
+ children: [cta$1, /* @__PURE__ */ jsx(ExternalLinkIcon, {
151
+ width: 14,
152
+ height: 14
153
+ })]
154
+ })]
36
155
  }),
37
- /* @__PURE__ */ jsx("path", { d: "M12 7c0 0-1.5-4-4.5-4S5 5 7.5 7" }),
38
- /* @__PURE__ */ jsx("path", { d: "M12 7c0 0 1.5-4 4.5-4S19 5 16.5 7" })
39
- ]
40
- });
41
- }
42
- /**
43
- * External link icon for in-app browser mode.
44
- */
45
- function BrowserIcon() {
46
- return /* @__PURE__ */ jsxs("svg", {
47
- viewBox: "0 0 24 24",
48
- fill: "none",
49
- stroke: "currentColor",
50
- "stroke-width": "1.5",
51
- "stroke-linecap": "round",
52
- "stroke-linejoin": "round",
53
- "aria-hidden": "true",
54
- children: [
55
- /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6" }),
56
- /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
57
- /* @__PURE__ */ jsx("line", {
58
- x1: "10",
59
- y1: "14",
60
- x2: "21",
61
- y2: "3"
156
+ /* @__PURE__ */ jsx("button", {
157
+ type: "button",
158
+ className: `${closeButton}${classNames?.close ? ` ${classNames.close}` : ""}`,
159
+ onClick: onDismiss,
160
+ "aria-label": dismissLabel,
161
+ children: /* @__PURE__ */ jsx(CloseCircleIcon, {
162
+ width: 16,
163
+ height: 16
164
+ })
62
165
  })
63
166
  ]
64
167
  });
65
168
  }
169
+ //#endregion
170
+ //#region \0ve-inline:src/components/Banner/Banner.css.ts.vanilla.js
171
+ const cssSource$1 = `@keyframes Banner_fadeIn__1gnumzi0 {
172
+ from {
173
+ opacity: 0;
174
+ transform: translateY(-4px);
175
+ }
176
+ to {
177
+ opacity: 1;
178
+ transform: translateY(0);
179
+ }
180
+ }
181
+ .Banner_rootBase__1gnumzi1 {
182
+ position: relative;
183
+ display: flex;
184
+ animation: Banner_fadeIn__1gnumzi0 300ms ease-out;
185
+ }
186
+ .Banner_iconSvg__1gnumzi2 {
187
+ width: 100%;
188
+ height: 100%;
189
+ }
190
+ .Banner_referral__1gnumzi3 {
191
+ flex-direction: row;
192
+ align-items: center;
193
+ gap: 16px;
194
+ padding: 16px;
195
+ background-color: #ffffff;
196
+ color: var(--text-primary__pbq4ak0);
197
+ }
198
+ .Banner_referralIconWrapper__1gnumzi4 {
199
+ flex-shrink: 0;
200
+ align-self: flex-start;
201
+ width: 40px;
202
+ height: 40px;
203
+ }
204
+ .Banner_referralBody__1gnumzi5 {
205
+ flex: 1;
206
+ min-width: 0;
207
+ }
208
+ .Banner_referralTitle__1gnumzi6 {
209
+ font-size: 16px;
210
+ font-weight: 600;
211
+ color: var(--text-primary__pbq4ak0);
212
+ line-height: 22px;
213
+ }
214
+ .Banner_referralDescription__1gnumzi7 {
215
+ margin-bottom: 8px;
216
+ font-size: 14px;
217
+ color: #979797;
218
+ line-height: 22px;
219
+ }
220
+ .Banner_referralCta__1gnumzi8 {
221
+ display: inline-block;
222
+ padding: 8px 16px;
223
+ border: 1px solid #000000;
224
+ border-radius: 9999px;
225
+ color: var(--text-primary__pbq4ak0);
226
+ font-size: 10px;
227
+ font-weight: 700;
228
+ line-height: 12px;
229
+ text-transform: uppercase;
230
+ }
231
+ .Banner_referralCta__1gnumzi8:focus-visible {
232
+ outline: 2px solid #000000;
233
+ outline-offset: 2px;
234
+ }`;
235
+ //#endregion
236
+ //#region src/components/Banner/Banner.css.ts
237
+ var iconSvg = "Banner_iconSvg__1gnumzi2";
238
+ var referral = "Banner_referral__1gnumzi3 reset_base__1831jhd0 Banner_rootBase__1gnumzi1";
239
+ var referralBody = "Banner_referralBody__1gnumzi5";
240
+ var referralCta = "Banner_referralCta__1gnumzi8 reset_element_button__1831jhd6 reset_fieldAppearance__1831jhd2 reset_focusRing__1831jhd1";
241
+ var referralDescription = "Banner_referralDescription__1gnumzi7 reset_base__1831jhd0";
242
+ var referralIconWrapper = "Banner_referralIconWrapper__1gnumzi4";
243
+ var referralTitle = "Banner_referralTitle__1gnumzi6 reset_base__1831jhd0";
244
+ const cssSource = cssSource$5 + cssSource$4 + cssSource$6 + cssSource$1;
245
+ //#endregion
246
+ //#region src/components/Banner/Banner.tsx
66
247
  /**
67
248
  * Auto-detecting notification banner component.
68
249
  *
69
- * Renders an inline banner on the merchant page that auto-detects which
70
- * message to display:
250
+ * Renders an inline banner on the merchant page with one of two distinct
251
+ * visual styles depending on the detected mode:
71
252
  *
72
- * - **Referral mode**: Shown after successful referral link processing.
73
- * Displays reward info and a dismiss button ("Got it").
74
- * - **In-app browser mode**: Shown when the page is opened inside a social
75
- * media in-app browser (Instagram, Facebook). Offers a redirect to the
76
- * default browser.
253
+ * - **Referral mode** (white): Shown after a successful referral link
254
+ * processing. Displays a gift icon, reward copy, and a "Got it" CTA.
255
+ * - **In-app browser mode** (dark transparent): Shown when the page is
256
+ * opened inside a social media in-app browser (Instagram, Facebook).
257
+ * Offers an inline link to redirect to the default browser plus a
258
+ * close button to dismiss.
77
259
  *
78
260
  * In-app browser mode takes priority over referral mode.
79
- * Uses Light DOM to inherit merchant page styles.
261
+ * Uses Light DOM + vanilla-extract styles from `@frak-labs/design-system`.
80
262
  *
81
263
  * @group components
82
264
  *
@@ -97,7 +279,7 @@ function Banner({ placement: placementId, classname = "", interaction, referralT
97
279
  const resolvedPreviewMode = previewMode === "inapp" ? "inapp" : "referral";
98
280
  const placement = usePlacement(placementId);
99
281
  const { shouldRender, isHidden, isClientReady } = useClientReady();
100
- useLightDomStyles("frak-banner", placementId, placement?.components?.banner?.css, bannerBaseCss);
282
+ useLightDomStyles("frak-banner", placementId, placement?.components?.banner?.css, cssSource);
101
283
  const [dismissed, setDismissed] = useState(false);
102
284
  const [mode, setMode] = useState(() => {
103
285
  if (isPreview) return resolvedPreviewMode;
@@ -107,18 +289,50 @@ function Banner({ placement: placementId, classname = "", interaction, referralT
107
289
  if (isPreview) setMode(resolvedPreviewMode);
108
290
  }, [isPreview, resolvedPreviewMode]);
109
291
  const { reward } = useReward(mode === "referral" && isClientReady, interaction);
292
+ const [prefetchedMergeToken, setPrefetchedMergeToken] = useState(null);
293
+ useEffect(() => {
294
+ const client = window.FrakSetup?.client;
295
+ if (mode !== "inapp" || isPreview || !isClientReady || !client) return;
296
+ getMergeToken(client).then((token) => setPrefetchedMergeToken(token)).catch(() => {});
297
+ }, [
298
+ mode,
299
+ isPreview,
300
+ isClientReady
301
+ ]);
110
302
  useEffect(() => {
111
303
  if (isPreview || mode === "inapp") return;
112
304
  const handler = () => setMode("referral");
113
305
  window.addEventListener(REFERRAL_SUCCESS_EVENT, handler);
114
306
  return () => window.removeEventListener(REFERRAL_SUCCESS_EVENT, handler);
115
307
  }, [isPreview, mode]);
116
- const handleAction = useCallback(() => {
308
+ const handleAction = useCallback(async () => {
117
309
  if (isPreview) return;
118
- if (mode === "referral") setDismissed(true);
119
- else redirectToExternalBrowser(window.location.href);
120
- }, [isPreview, mode]);
121
- const bannerConfig = placement?.components?.banner;
310
+ if (mode === "referral") {
311
+ setDismissed(true);
312
+ return;
313
+ }
314
+ let mergeToken = prefetchedMergeToken;
315
+ if (!mergeToken && window.FrakSetup?.client) try {
316
+ mergeToken = await getMergeToken(window.FrakSetup?.client);
317
+ } catch {}
318
+ let targetUrl = window.location.href;
319
+ if (mergeToken) {
320
+ const url = new URL(targetUrl);
321
+ url.searchParams.set("fmt", mergeToken);
322
+ targetUrl = url.toString();
323
+ }
324
+ redirectToExternalBrowser(targetUrl);
325
+ }, [
326
+ isPreview,
327
+ mode,
328
+ prefetchedMergeToken
329
+ ]);
330
+ const handleDismiss = useCallback(() => {
331
+ if (isPreview) return;
332
+ setDismissed(true);
333
+ }, [isPreview]);
334
+ const globalComponents = useGlobalComponents();
335
+ const bannerConfig = placement?.components?.banner ?? globalComponents?.banner;
122
336
  const texts = useMemo(() => {
123
337
  if (mode === "referral") {
124
338
  const defaultTitle = reward ? `Earn ${reward} on purchases on this site` : "You've been referred!";
@@ -144,36 +358,58 @@ function Banner({ placement: placementId, classname = "", interaction, referralT
144
358
  propInappDescription,
145
359
  propInappCta
146
360
  ]);
147
- if (!isPreview && (!shouldRender || isHidden || dismissed || !mode)) return null;
148
- return /* @__PURE__ */ jsxs("div", {
149
- class: [
150
- "banner",
151
- "banner__fadeIn",
361
+ if (!mode || !isPreview && (!shouldRender || isHidden || dismissed)) return null;
362
+ const bannerClass = [
363
+ referral,
364
+ "frak-banner",
365
+ `frak-banner--${mode}`,
366
+ classname
367
+ ].filter(Boolean).join(" ");
368
+ if (mode === "inapp") return /* @__PURE__ */ jsx(InAppBanner, {
369
+ title: texts.title,
370
+ description: texts.description,
371
+ cta: texts.cta,
372
+ dismissLabel: "Dismiss",
373
+ onAction: handleAction,
374
+ onDismiss: handleDismiss,
375
+ className: [
376
+ "frak-banner",
377
+ "frak-banner--inapp",
152
378
  classname
153
379
  ].filter(Boolean).join(" "),
380
+ classNames: {
381
+ icon: "frak-banner__icon",
382
+ title: "frak-banner__title",
383
+ description: "frak-banner__description",
384
+ cta: "frak-banner__cta",
385
+ close: "frak-banner__close"
386
+ }
387
+ });
388
+ return /* @__PURE__ */ jsxs("div", {
389
+ class: bannerClass,
154
390
  role: "alert",
155
- children: [
156
- /* @__PURE__ */ jsx("div", {
157
- class: "banner__icon",
158
- children: mode === "referral" ? /* @__PURE__ */ jsx(RewardIcon, {}) : /* @__PURE__ */ jsx(BrowserIcon, {})
159
- }),
160
- /* @__PURE__ */ jsxs("div", {
161
- class: "banner__content",
162
- children: [/* @__PURE__ */ jsx("p", {
163
- class: "banner__title",
391
+ children: [/* @__PURE__ */ jsx("div", {
392
+ class: `${referralIconWrapper} frak-banner__icon`,
393
+ children: /* @__PURE__ */ jsx(GiftIcon, { class: iconSvg })
394
+ }), /* @__PURE__ */ jsxs("div", {
395
+ class: `${referralBody} frak-banner__text`,
396
+ children: [
397
+ /* @__PURE__ */ jsx("p", {
398
+ class: `${referralTitle} frak-banner__title`,
164
399
  children: texts.title
165
- }), /* @__PURE__ */ jsx("p", {
166
- class: "banner__description",
400
+ }),
401
+ /* @__PURE__ */ jsx("p", {
402
+ class: `${referralDescription} frak-banner__description`,
167
403
  children: texts.description
168
- })]
169
- }),
170
- /* @__PURE__ */ jsx("button", {
171
- type: "button",
172
- class: "banner__cta",
173
- onClick: handleAction,
174
- children: texts.cta
175
- })
176
- ]
404
+ }),
405
+ /* @__PURE__ */ jsx("button", {
406
+ type: "button",
407
+ class: `${referralCta} frak-banner__cta`,
408
+ onClick: handleAction,
409
+ children: texts.cta
410
+ })
411
+ ]
412
+ })]
177
413
  });
178
414
  }
179
415
  //#endregion
@@ -1,7 +1,9 @@
1
- import { a as useClientReady, c as openEmbeddedWallet, o as registerWebComponent, t as usePlacement } from "./usePlacement-CHEgrdvN.js";
2
- import { t as useLightDomStyles } from "./useLightDomStyles-B5Y_fH4K.js";
3
- import { t as useReward } from "./useReward-XF2hB_C_.js";
4
- import { t as useShareModal } from "./useShareModal-Bmlk3eBJ.js";
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";
5
7
  import { trackEvent } from "@frak-labs/core-sdk";
6
8
  import { displaySharingPage } from "@frak-labs/core-sdk/actions";
7
9
  import { useCallback, useMemo, useState } from "preact/hooks";
@@ -210,7 +212,8 @@ function ErrorMessage({ debugInfo }) {
210
212
  */
211
213
  function ButtonShare({ placement: placementId, text = "Share and earn!", classname = "", useReward: rawUseReward, noRewardText, targetInteraction, clickAction: rawClickAction }) {
212
214
  const placement = usePlacement(placementId);
213
- const componentConfig = placement?.components?.buttonShare;
215
+ const globalComponents = useGlobalComponents();
216
+ const componentConfig = placement?.components?.buttonShare ?? globalComponents?.buttonShare;
214
217
  useLightDomStyles("frak-button-share", placementId, componentConfig?.css);
215
218
  const resolvedTargetInteraction = useMemo(() => placement?.targetInteraction !== void 0 ? placement.targetInteraction : targetInteraction, [placement?.targetInteraction, targetInteraction]);
216
219
  const resolvedText = componentConfig?.text ?? text;
@@ -222,8 +225,8 @@ function ButtonShare({ placement: placementId, text = "Share and earn!", classna
222
225
  const { handleShare, isError, debugInfo } = useShareModal(resolvedTargetInteraction, placementId);
223
226
  const btnText = useMemo(() => {
224
227
  if (!shouldUseReward) return resolvedText;
225
- if (!reward) return resolvedNoRewardText ?? resolvedText.replace("{REWARD}", "");
226
- 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}`;
227
230
  }, [
228
231
  shouldUseReward,
229
232
  resolvedText,
@@ -1,5 +1,5 @@
1
- import { a as useClientReady, o as registerWebComponent, r as buildStyleContent, s as openWalletModal, t as usePlacement } from "./usePlacement-CHEgrdvN.js";
2
- import { t as useReward } from "./useReward-XF2hB_C_.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";
@@ -22,5 +22,12 @@ function formatEstimatedReward(reward, currency, basketAmount) {
22
22
  }
23
23
  }
24
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
+ }
25
32
  //#endregion
26
- export { formatEstimatedReward as t };
33
+ export { formatEstimatedReward as n, applyRewardPlaceholder as t };
package/dist/openInApp.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as useClientReady, o as registerWebComponent, t as usePlacement } from "./usePlacement-CHEgrdvN.js";
2
- import { t as useLightDomStyles } from "./useLightDomStyles-B5Y_fH4K.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";