@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
@@ -0,0 +1 @@
1
+ import{t as e}from"./loader.js";import{a as t,u as n}from"./jsxRuntime.module.5UNmmhNi.js";function r(r,i,a,o){n(()=>{e.injectBase(r,o??t)},[r]),n(()=>{!i||!a||e.injectPlacement(r,i,a)},[r,i,a])}export{r as t};
@@ -0,0 +1 @@
1
+ import{_ as e,b as t,l as n}from"./loader.js";import{c as r,u as i}from"./jsxRuntime.module.5UNmmhNi.js";import{t as a}from"./formatReward.C8hlSKRj.js";function o(e,t){switch(e.payoutType){case`fixed`:return e.amount[t];case`tiered`:return e.tiers.reduce((e,n)=>Math.max(e,n.amount[t]),0);case`percentage`:return 0}}function s({rewards:n},r,i){let s=(i?n.filter(e=>e.interactionTypeKey===i):n).map(e=>e.referrer).filter(e=>e!==void 0);if(s.length===0)return;let c=t(e(r)),l=s[0],u=o(l,c);for(let e=1;e<s.length;e++){let t=o(s[e],c);t>u&&(l=s[e],u=t)}if(u<=0){let e=s.find(e=>e.payoutType===`percentage`);if(!e)return;l=e}return a(l,r)}function c(e,t){let[a,o]=r(void 0);return i(()=>{if(!e)return;let r=window.FrakSetup?.client;r&&n(r).then(e=>{let n=r.config.metadata?.currency,i=s(e,n,t);i&&o(i)}).catch(()=>{})},[e,t]),{reward:a}}export{c as t};
@@ -0,0 +1 @@
1
+ import{C as e,S as t,u as n,v as r,w as i}from"./loader.js";import{c as a,l as o}from"./jsxRuntime.module.5UNmmhNi.js";function s(s,c,l){let[u,d]=a(void 0),[f,p]=a(!1);return{handleShare:o(async()=>{if(!window.FrakSetup?.client){console.error(`Frak client not found`),d(r.empty().formatDebugInfo(`Frak client not found`)),p(!0);return}let a=n(window.FrakSetup.client,{});try{await a.sharing(l?{link:l}:{}).display(e=>({...e,targetInteraction:s}),c)}catch(n){if(n instanceof i&&n.code===e.clientAborted){console.debug(`User aborted the modal`);return}let r=window.FrakSetup.client.debugInfo.formatDebugInfo(n);t(window.FrakSetup.client,`share_modal_error`,{error:n instanceof Object&&`message`in n?n.message:`Unknown error`,debugInfo:r}),d(r),p(!0),console.error(`Error while opening the modal`,n)}},[s,c,l]),isError:f,debugInfo:u}}export{s as t};
@@ -0,0 +1,103 @@
1
+ import { InteractionTypeKey } from "@frak-labs/core-sdk";
2
+ import * as preact from "preact";
3
+
4
+ //#region src/components/Banner/types.d.ts
5
+ /**
6
+ * The props type for {@link Banner}.
7
+ * @inline
8
+ */
9
+ type BannerProps = {
10
+ /**
11
+ * Placement ID for backend-driven CSS customization.
12
+ */
13
+ placement?: string;
14
+ /**
15
+ * CSS class names passed through to the root element (Light DOM).
16
+ */
17
+ classname?: string;
18
+ /**
19
+ * Filter rewards by interaction type (e.g. "purchase", "referral").
20
+ * When omitted, the best reward across all interaction types is shown.
21
+ */
22
+ interaction?: InteractionTypeKey;
23
+ /**
24
+ * Override the referral banner title.
25
+ */
26
+ referralTitle?: string;
27
+ /**
28
+ * Override the referral banner description.
29
+ */
30
+ referralDescription?: string;
31
+ /**
32
+ * Override the referral banner CTA button text.
33
+ */
34
+ referralCta?: string;
35
+ /**
36
+ * Override the in-app browser banner title.
37
+ */
38
+ inappTitle?: string;
39
+ /**
40
+ * Override the in-app browser banner description.
41
+ */
42
+ inappDescription?: string;
43
+ /**
44
+ * Override the in-app browser banner CTA button text.
45
+ */
46
+ inappCta?: string;
47
+ };
48
+ //#endregion
49
+ //#region src/components/Banner/Banner.d.ts
50
+ /**
51
+ * Auto-detecting notification banner component.
52
+ *
53
+ * Renders an inline banner on the merchant page that auto-detects which
54
+ * message to display:
55
+ *
56
+ * - **Referral mode**: Shown after successful referral link processing.
57
+ * Displays reward info and a dismiss button ("Got it").
58
+ * - **In-app browser mode**: Shown when the page is opened inside a social
59
+ * media in-app browser (Instagram, Facebook). Offers a redirect to the
60
+ * default browser.
61
+ *
62
+ * In-app browser mode takes priority over referral mode.
63
+ * Uses Light DOM to inherit merchant page styles.
64
+ *
65
+ * @group components
66
+ *
67
+ * @example
68
+ * Basic usage (auto-detects mode):
69
+ * ```html
70
+ * <frak-banner></frak-banner>
71
+ * ```
72
+ *
73
+ * @example
74
+ * With a custom class:
75
+ * ```html
76
+ * <frak-banner classname="my-custom-banner"></frak-banner>
77
+ * ```
78
+ */
79
+ declare function Banner({
80
+ placement: placementId,
81
+ classname,
82
+ interaction,
83
+ referralTitle: propReferralTitle,
84
+ referralDescription: propReferralDescription,
85
+ referralCta: propReferralCta,
86
+ inappTitle: propInappTitle,
87
+ inappDescription: propInappDescription,
88
+ inappCta: propInappCta
89
+ }: BannerProps): preact.JSX.Element | null;
90
+ //#endregion
91
+ //#region src/components/Banner/index.d.ts
92
+ /**
93
+ * Custom element interface for `<frak-banner>`.
94
+ * Combines standard {@link HTMLElement} with {@link BannerProps}.
95
+ */
96
+ interface BannerElement extends HTMLElement, BannerProps {}
97
+ declare global {
98
+ interface HTMLElementTagNameMap {
99
+ "frak-banner": BannerElement;
100
+ }
101
+ }
102
+ //#endregion
103
+ export { Banner, BannerElement };
package/dist/banner.js ADDED
@@ -0,0 +1,187 @@
1
+ import { a as useClientReady, n as bannerBaseCss, o as registerWebComponent, t as usePlacement } from "./usePlacement-BbMuz8_A.js";
2
+ import { t as useLightDomStyles } from "./useLightDomStyles-DukxuNnJ.js";
3
+ import { t as useReward } from "./useReward-CI2yRrCj.js";
4
+ import { isInAppBrowser, redirectToExternalBrowser } from "@frak-labs/core-sdk";
5
+ import { REFERRAL_SUCCESS_EVENT } from "@frak-labs/core-sdk/actions";
6
+ import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
7
+ import { jsx, jsxs } from "preact/jsx-runtime";
8
+
9
+ //#region src/components/Banner/Banner.tsx
10
+ /**
11
+ * Reward/gift icon for referral mode.
12
+ */
13
+ function RewardIcon() {
14
+ return /* @__PURE__ */ jsxs("svg", {
15
+ viewBox: "0 0 24 24",
16
+ fill: "none",
17
+ stroke: "currentColor",
18
+ "stroke-width": "1.5",
19
+ "stroke-linecap": "round",
20
+ "stroke-linejoin": "round",
21
+ "aria-hidden": "true",
22
+ children: [
23
+ /* @__PURE__ */ jsx("rect", {
24
+ x: "3",
25
+ y: "11",
26
+ width: "18",
27
+ height: "11",
28
+ rx: "1"
29
+ }),
30
+ /* @__PURE__ */ jsx("path", { d: "M12 11v11" }),
31
+ /* @__PURE__ */ jsx("rect", {
32
+ x: "5",
33
+ y: "7",
34
+ width: "14",
35
+ height: "4",
36
+ rx: "1"
37
+ }),
38
+ /* @__PURE__ */ jsx("path", { d: "M12 7c0 0-1.5-4-4.5-4S5 5 7.5 7" }),
39
+ /* @__PURE__ */ jsx("path", { d: "M12 7c0 0 1.5-4 4.5-4S19 5 16.5 7" })
40
+ ]
41
+ });
42
+ }
43
+ /**
44
+ * External link icon for in-app browser mode.
45
+ */
46
+ function BrowserIcon() {
47
+ return /* @__PURE__ */ jsxs("svg", {
48
+ viewBox: "0 0 24 24",
49
+ fill: "none",
50
+ stroke: "currentColor",
51
+ "stroke-width": "1.5",
52
+ "stroke-linecap": "round",
53
+ "stroke-linejoin": "round",
54
+ "aria-hidden": "true",
55
+ children: [
56
+ /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6" }),
57
+ /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
58
+ /* @__PURE__ */ jsx("line", {
59
+ x1: "10",
60
+ y1: "14",
61
+ x2: "21",
62
+ y2: "3"
63
+ })
64
+ ]
65
+ });
66
+ }
67
+ /**
68
+ * Auto-detecting notification banner component.
69
+ *
70
+ * Renders an inline banner on the merchant page that auto-detects which
71
+ * message to display:
72
+ *
73
+ * - **Referral mode**: Shown after successful referral link processing.
74
+ * Displays reward info and a dismiss button ("Got it").
75
+ * - **In-app browser mode**: Shown when the page is opened inside a social
76
+ * media in-app browser (Instagram, Facebook). Offers a redirect to the
77
+ * default browser.
78
+ *
79
+ * In-app browser mode takes priority over referral mode.
80
+ * Uses Light DOM to inherit merchant page styles.
81
+ *
82
+ * @group components
83
+ *
84
+ * @example
85
+ * Basic usage (auto-detects mode):
86
+ * ```html
87
+ * <frak-banner></frak-banner>
88
+ * ```
89
+ *
90
+ * @example
91
+ * With a custom class:
92
+ * ```html
93
+ * <frak-banner classname="my-custom-banner"></frak-banner>
94
+ * ```
95
+ */
96
+ function Banner({ placement: placementId, classname = "", interaction, referralTitle: propReferralTitle, referralDescription: propReferralDescription, referralCta: propReferralCta, inappTitle: propInappTitle, inappDescription: propInappDescription, inappCta: propInappCta }) {
97
+ const placement = usePlacement(placementId);
98
+ const { shouldRender, isHidden, isClientReady } = useClientReady();
99
+ useLightDomStyles("frak-banner", placementId, placement?.components?.banner?.css, bannerBaseCss);
100
+ const [dismissed, setDismissed] = useState(false);
101
+ const [mode, setMode] = useState(() => isInAppBrowser ? "inapp" : null);
102
+ const { reward } = useReward(mode === "referral" && isClientReady, interaction);
103
+ useEffect(() => {
104
+ if (mode === "inapp") return;
105
+ const handler = () => setMode("referral");
106
+ window.addEventListener(REFERRAL_SUCCESS_EVENT, handler);
107
+ return () => window.removeEventListener(REFERRAL_SUCCESS_EVENT, handler);
108
+ }, [mode]);
109
+ const handleAction = useCallback(() => {
110
+ if (mode === "referral") setDismissed(true);
111
+ else redirectToExternalBrowser(window.location.href);
112
+ }, [mode]);
113
+ const bannerConfig = placement?.components?.banner;
114
+ const texts = useMemo(() => {
115
+ if (mode === "referral") {
116
+ const defaultTitle = reward ? `Earn ${reward} on purchases on this site` : "You've been referred!";
117
+ return {
118
+ title: propReferralTitle ?? bannerConfig?.referralTitle ?? defaultTitle,
119
+ description: propReferralDescription ?? bannerConfig?.referralDescription ?? "Earn rewards after your purchase via the Frak partner app.",
120
+ cta: propReferralCta ?? bannerConfig?.referralCta ?? "Got it"
121
+ };
122
+ }
123
+ return {
124
+ title: propInappTitle ?? bannerConfig?.inappTitle ?? "Open in your browser",
125
+ description: propInappDescription ?? bannerConfig?.inappDescription ?? "For a better experience and to earn your rewards, open this page in your default browser.",
126
+ cta: propInappCta ?? bannerConfig?.inappCta ?? "Open browser"
127
+ };
128
+ }, [
129
+ mode,
130
+ reward,
131
+ bannerConfig,
132
+ propReferralTitle,
133
+ propReferralDescription,
134
+ propReferralCta,
135
+ propInappTitle,
136
+ propInappDescription,
137
+ propInappCta
138
+ ]);
139
+ if (!shouldRender || isHidden || dismissed || !mode) return null;
140
+ return /* @__PURE__ */ jsxs("div", {
141
+ class: [
142
+ "banner",
143
+ "banner__fadeIn",
144
+ classname
145
+ ].filter(Boolean).join(" "),
146
+ role: "alert",
147
+ children: [
148
+ /* @__PURE__ */ jsx("div", {
149
+ class: "banner__icon",
150
+ children: mode === "referral" ? /* @__PURE__ */ jsx(RewardIcon, {}) : /* @__PURE__ */ jsx(BrowserIcon, {})
151
+ }),
152
+ /* @__PURE__ */ jsxs("div", {
153
+ class: "banner__content",
154
+ children: [/* @__PURE__ */ jsx("p", {
155
+ class: "banner__title",
156
+ children: texts.title
157
+ }), /* @__PURE__ */ jsx("p", {
158
+ class: "banner__description",
159
+ children: texts.description
160
+ })]
161
+ }),
162
+ /* @__PURE__ */ jsx("button", {
163
+ type: "button",
164
+ class: "banner__cta",
165
+ onClick: handleAction,
166
+ children: texts.cta
167
+ })
168
+ ]
169
+ });
170
+ }
171
+
172
+ //#endregion
173
+ //#region src/components/Banner/index.ts
174
+ registerWebComponent(Banner, "frak-banner", [
175
+ "placement",
176
+ "classname",
177
+ "interaction",
178
+ "referralTitle",
179
+ "referralDescription",
180
+ "referralCta",
181
+ "inappTitle",
182
+ "inappDescription",
183
+ "inappCta"
184
+ ], { shadow: false });
185
+
186
+ //#endregion
187
+ export { Banner };
@@ -7,6 +7,7 @@ import * as preact from "preact";
7
7
  * @inline
8
8
  */
9
9
  type ButtonShareProps = {
10
+ placement?: string;
10
11
  /**
11
12
  * Text to display on the button
12
13
  * - To specify where the reward should be displayed, use the placeholder `{REWARD}`, e.g. `Share and earn up to \{REWARD\}!`
@@ -31,10 +32,10 @@ type ButtonShareProps = {
31
32
  */
32
33
  targetInteraction?: InteractionTypeKey;
33
34
  /**
34
- * Do we display the wallet modal instead of the share modal?
35
- * @defaultValue `false`
35
+ * Which UI to open on click
36
+ * @defaultValue `"embedded-wallet"`
36
37
  */
37
- showWallet?: boolean;
38
+ clickAction?: "embedded-wallet" | "share-modal" | "sharing-page";
38
39
  };
39
40
  //#endregion
40
41
  //#region src/components/ButtonShare/ButtonShare.d.ts
@@ -80,13 +81,14 @@ type ButtonShareProps = {
80
81
  * @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
81
82
  */
82
83
  declare function ButtonShare({
84
+ placement: placementId,
83
85
  text,
84
86
  classname,
85
87
  useReward: rawUseReward,
86
88
  noRewardText,
87
89
  targetInteraction,
88
- showWallet: rawShowWallet
89
- }: ButtonShareProps): preact.JSX.Element;
90
+ clickAction: rawClickAction
91
+ }: ButtonShareProps): preact.JSX.Element | null;
90
92
  //#endregion
91
93
  //#region src/components/ButtonShare/index.d.ts
92
94
  /**
@@ -1,16 +1,20 @@
1
- import { n as registerWebComponent, r as getModalBuilderSteps, t as useClientReady } from "./useClientReady-0vKBG0-p.js";
2
- import { t as Spinner } from "./Spinner-Btnwk01x.js";
3
- import { t as useReward } from "./useReward-DAkT-7wT.js";
4
- import { DebugInfoGatherer, trackEvent } from "@frak-labs/core-sdk";
5
- import { displayEmbeddedWallet } from "@frak-labs/core-sdk/actions";
6
- import { cx } from "class-variance-authority";
1
+ import { a as useClientReady, c as openEmbeddedWallet, o as registerWebComponent, t as usePlacement } from "./usePlacement-BbMuz8_A.js";
2
+ import { t as useLightDomStyles } from "./useLightDomStyles-DukxuNnJ.js";
3
+ import { t as useReward } from "./useReward-CI2yRrCj.js";
4
+ import { t as useShareModal } from "./useShareModal-DHlayNqk.js";
5
+ import { trackEvent } from "@frak-labs/core-sdk";
6
+ import { displaySharingPage } from "@frak-labs/core-sdk/actions";
7
7
  import { useCallback, useMemo, useState } from "preact/hooks";
8
8
  import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
9
- import { FrakRpcError, RpcErrorCodes } from "@frak-labs/frame-connector";
10
9
 
11
- //#region src/components/ButtonShare/ButtonShare.module.css?css_module
12
- const classes = { "buttonShare": "nOB7Uq_buttonShare" };
13
- const _buttonShare0 = classes["buttonShare"];
10
+ //#region src/utils/sharingPage.ts
11
+ async function openSharingPage(targetInteraction, placement) {
12
+ if (!window.FrakSetup?.client) {
13
+ console.error("Frak client not found");
14
+ return;
15
+ }
16
+ await displaySharingPage(window.FrakSetup.client, { metadata: { ...targetInteraction && { targetInteraction } } }, placement);
17
+ }
14
18
 
15
19
  //#endregion
16
20
  //#region src/hooks/useCopyToClipboard.ts
@@ -165,65 +169,9 @@ function ErrorMessage({ debugInfo }) {
165
169
  });
166
170
  }
167
171
 
168
- //#endregion
169
- //#region src/components/ButtonShare/hooks/useShareModal.ts
170
- /**
171
- * Open the share modal
172
- *
173
- * @description
174
- * This function will open the share modal with the configuration provided in the `window.FrakSetup.modalShareConfig` object.
175
- */
176
- function useShareModal(targetInteraction) {
177
- const [debugInfo, setDebugInfo] = useState(void 0);
178
- const [isError, setIsError] = useState(false);
179
- return {
180
- handleShare: useCallback(async () => {
181
- if (!window.FrakSetup?.client) {
182
- console.error("Frak client not found");
183
- setDebugInfo(DebugInfoGatherer.empty().formatDebugInfo("Frak client not found"));
184
- setIsError(true);
185
- return;
186
- }
187
- const modalBuilderSteps = getModalBuilderSteps();
188
- if (!modalBuilderSteps) throw new Error("modalBuilderSteps not found");
189
- try {
190
- await modalBuilderSteps.sharing(window.FrakSetup?.modalShareConfig ?? {}).display((metadata) => ({
191
- ...metadata,
192
- targetInteraction
193
- }));
194
- } catch (e) {
195
- if (e instanceof FrakRpcError && e.code === RpcErrorCodes.clientAborted) {
196
- console.debug("User aborted the modal");
197
- return;
198
- }
199
- const debugInfo = window.FrakSetup.client.debugInfo.formatDebugInfo(e);
200
- trackEvent(window.FrakSetup.client, "share_modal_error", {
201
- error: e instanceof Object && "message" in e ? e.message : "Unknown error",
202
- debugInfo
203
- });
204
- setDebugInfo(debugInfo);
205
- setIsError(true);
206
- console.error("Error while opening the modal", e);
207
- }
208
- }, [targetInteraction]),
209
- isError,
210
- debugInfo
211
- };
212
- }
213
-
214
172
  //#endregion
215
173
  //#region src/components/ButtonShare/ButtonShare.tsx
216
174
  /**
217
- * Open the embedded wallet modal
218
- *
219
- * @description
220
- * This function will open the wallet modal with the configuration provided in the `window.FrakSetup.modalWalletConfig` object.
221
- */
222
- async function modalEmbeddedWallet() {
223
- if (!window.FrakSetup?.client) throw new Error("Frak client not found");
224
- await displayEmbeddedWallet(window.FrakSetup.client, window.FrakSetup?.modalWalletConfig ?? {});
225
- }
226
- /**
227
175
  * Button to share the current page
228
176
  *
229
177
  * @param args
@@ -264,48 +212,65 @@ async function modalEmbeddedWallet() {
264
212
  * @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
265
213
  * @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
266
214
  */
267
- function ButtonShare({ text = "Share and earn!", classname = "", useReward: rawUseReward, noRewardText, targetInteraction, showWallet: rawShowWallet }) {
268
- const shouldUseReward = useMemo(() => rawUseReward !== void 0, [rawUseReward]);
269
- const showWallet = useMemo(() => rawShowWallet !== void 0, [rawShowWallet]);
270
- const { isClientReady } = useClientReady();
271
- const { reward } = useReward(shouldUseReward && isClientReady, targetInteraction);
272
- const { handleShare, isError, debugInfo } = useShareModal(targetInteraction);
273
- /**
274
- * Compute the text we will display
275
- */
215
+ function ButtonShare({ placement: placementId, text = "Share and earn!", classname = "", useReward: rawUseReward, noRewardText, targetInteraction, clickAction: rawClickAction }) {
216
+ const placement = usePlacement(placementId);
217
+ const componentConfig = placement?.components?.buttonShare;
218
+ useLightDomStyles("frak-button-share", placementId, componentConfig?.css);
219
+ const resolvedTargetInteraction = useMemo(() => placement?.targetInteraction !== void 0 ? placement.targetInteraction : targetInteraction, [placement?.targetInteraction, targetInteraction]);
220
+ const resolvedText = componentConfig?.text ?? text;
221
+ const resolvedNoRewardText = componentConfig?.noRewardText ?? noRewardText;
222
+ const shouldUseReward = useMemo(() => componentConfig?.useReward ?? rawUseReward === true, [componentConfig?.useReward, rawUseReward]);
223
+ const resolvedClickAction = useMemo(() => componentConfig?.clickAction ?? rawClickAction ?? "sharing-page", [componentConfig?.clickAction, rawClickAction]);
224
+ const { shouldRender, isHidden, isClientReady } = useClientReady();
225
+ const { reward } = useReward(shouldUseReward && isClientReady, resolvedTargetInteraction);
226
+ const { handleShare, isError, debugInfo } = useShareModal(resolvedTargetInteraction, placementId);
276
227
  const btnText = useMemo(() => {
277
- if (!shouldUseReward) return text;
278
- if (!reward) return noRewardText ?? text.replace("{REWARD}", "");
279
- return text.includes("{REWARD}") ? text.replace("{REWARD}", reward) : `${text} ${reward}`;
228
+ if (!shouldUseReward) return resolvedText;
229
+ if (!reward) return resolvedNoRewardText ?? resolvedText.replace("{REWARD}", "");
230
+ return resolvedText.includes("{REWARD}") ? resolvedText.replace("{REWARD}", reward) : `${resolvedText} ${reward}`;
280
231
  }, [
281
232
  shouldUseReward,
282
- text,
283
- noRewardText,
233
+ resolvedText,
234
+ resolvedNoRewardText,
284
235
  reward
285
236
  ]);
286
- /**
287
- * The action when the button is clicked
288
- */
289
237
  const onClick = useCallback(async () => {
290
238
  trackEvent(window.FrakSetup.client, "share_button_clicked");
291
- if (showWallet) await modalEmbeddedWallet();
292
- else await handleShare();
293
- }, [showWallet, handleShare]);
294
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("button", {
239
+ if (resolvedClickAction === "embedded-wallet") openEmbeddedWallet(resolvedTargetInteraction, placementId);
240
+ else if (resolvedClickAction === "share-modal") await handleShare();
241
+ else openSharingPage(resolvedTargetInteraction, placementId);
242
+ }, [
243
+ resolvedClickAction,
244
+ handleShare,
245
+ resolvedTargetInteraction,
246
+ placementId
247
+ ]);
248
+ if (!shouldRender || isHidden) return null;
249
+ const buttonClass = [
250
+ "button",
251
+ "button__fadeIn",
252
+ classname
253
+ ].filter(Boolean).join(" ");
254
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
295
255
  type: "button",
296
- className: cx(classes.buttonShare, classname, "override"),
256
+ disabled: !isClientReady,
257
+ class: buttonClass,
297
258
  onClick,
298
- children: [
299
- !isClientReady && /* @__PURE__ */ jsx(Spinner, {}),
300
- " ",
301
- btnText
302
- ]
259
+ children: btnText
303
260
  }), isError && /* @__PURE__ */ jsx(ErrorMessage, { debugInfo })] });
304
261
  }
305
262
 
306
263
  //#endregion
307
264
  //#region src/components/ButtonShare/index.ts
308
- registerWebComponent(ButtonShare, "frak-button-share", ["text"], { shadow: false });
265
+ registerWebComponent(ButtonShare, "frak-button-share", [
266
+ "text",
267
+ "placement",
268
+ "classname",
269
+ "clickAction",
270
+ "useReward",
271
+ "noRewardText",
272
+ "targetInteraction"
273
+ ], { shadow: false });
309
274
 
310
275
  //#endregion
311
276
  export { ButtonShare };
@@ -7,6 +7,7 @@ import * as preact from "preact";
7
7
  * @inline
8
8
  */
9
9
  type ButtonWalletProps = {
10
+ placement?: string;
10
11
  /**
11
12
  * Classname to apply to the button
12
13
  */
@@ -55,14 +56,21 @@ type ButtonWalletProps = {
55
56
  * <frak-button-wallet use-reward target-interaction="custom.customerMeeting"></frak-button-wallet>
56
57
  * ```
57
58
  *
59
+ * @example
60
+ * Using placement:
61
+ * ```html
62
+ * <frak-button-wallet placement="hero-wallet"></frak-button-wallet>
63
+ * ```
64
+ *
58
65
  * @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
59
66
  * @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
60
67
  */
61
68
  declare function ButtonWallet({
69
+ placement: placementId,
62
70
  classname,
63
71
  useReward: rawUseReward,
64
72
  targetInteraction
65
- }: ButtonWalletProps): preact.JSX.Element;
73
+ }: ButtonWalletProps): preact.JSX.Element | null;
66
74
  //#endregion
67
75
  //#region src/components/ButtonWallet/index.d.ts
68
76
  /**