@frak-labs/components 0.0.26 → 1.0.0-beta.61e6fb99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cdn/Banner.UBeCtoRQ.js +162 -0
- package/cdn/ButtonShare.COa5uY94.js +1 -0
- package/cdn/ButtonWallet.BUzysl1S.js +40 -0
- package/cdn/OpenInAppButton.Bmzm2fL9.js +1 -0
- package/cdn/PostPurchase._st1hB42.js +52 -0
- package/cdn/components.js +1 -1
- package/cdn/formatReward.B0iBskOJ.js +1 -0
- package/cdn/loader.css +0 -14
- package/cdn/loader.js +14 -1
- package/cdn/sprinkles.css.ts.vanilla.Ct795MMK.js +1175 -0
- package/cdn/useGlobalComponents.CLH7id-Y.js +1 -0
- package/cdn/useLightDomStyles.DqYouFn3.js +1 -0
- package/cdn/usePlacement.Di6eZ4ty.js +58 -0
- package/cdn/useReward.DJwgphI1.js +1 -0
- package/cdn/useShareModal.UYsKX7L2.js +1 -0
- package/dist/GiftIcon-4sr9xXyq.js +1501 -0
- package/dist/banner.d.ts +116 -0
- package/dist/banner.js +464 -0
- package/dist/buttonShare.d.ts +16 -6
- package/dist/buttonShare.js +78 -103
- package/dist/buttonWallet.d.ts +10 -2
- package/dist/buttonWallet.js +79 -40
- package/dist/formatReward-Bub6Z6eY.js +33 -0
- package/dist/openInApp.d.ts +4 -2
- package/dist/openInApp.js +33 -33
- package/dist/postPurchase.d.ts +136 -0
- package/dist/postPurchase.js +1618 -0
- package/dist/useGlobalComponents-Cmfszr7v.js +21 -0
- package/dist/useLightDomStyles-C3lcOwY2.js +41 -0
- package/dist/usePlacement-V7NrKoub.js +253 -0
- package/dist/useReward-DU3_yP8Q.js +65 -0
- package/dist/useShareModal-BEVkLrBP.js +54 -0
- package/package.json +29 -20
- package/cdn/ButtonShare.CqRLxX5u.js +0 -1
- package/cdn/ButtonWallet.ToH_g8FC.js +0 -1
- package/cdn/OpenInAppButton.BMZnXQLT.js +0 -1
- package/cdn/Spinner.DRiAlyyq.js +0 -1
- package/cdn/initFrakSdk.CA6zXtGT.js +0 -14
- package/cdn/useClientReady.DskSqlAg.js +0 -1
- package/dist/Spinner-1CZC_zy6.js +0 -36
- package/dist/Spinner-CHZD3tMn.css +0 -1
- package/dist/buttonShare.css +0 -1
- package/dist/buttonWallet.css +0 -1
- package/dist/openInApp.css +0 -1
- package/dist/useClientReady-iCtUeDsc.js +0 -197
- package/dist/useReward-DAkT-7wT.js +0 -48
package/dist/buttonShare.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import { t as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { a as registerWebComponent, i as useClientReady, s as openEmbeddedWallet, t as usePlacement } from "./usePlacement-V7NrKoub.js";
|
|
2
|
+
import { t as useGlobalComponents } from "./useGlobalComponents-Cmfszr7v.js";
|
|
3
|
+
import { t as useLightDomStyles } from "./useLightDomStyles-C3lcOwY2.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-BEVkLrBP.js";
|
|
7
|
+
import { trackEvent } from "@frak-labs/core-sdk";
|
|
8
|
+
import { displaySharingPage } from "@frak-labs/core-sdk/actions";
|
|
7
9
|
import { useCallback, useMemo, useState } from "preact/hooks";
|
|
8
10
|
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
+
}
|
|
15
19
|
//#endregion
|
|
16
20
|
//#region src/hooks/useCopyToClipboard.ts
|
|
17
21
|
function useCopyToClipboard(options = {}) {
|
|
@@ -53,7 +57,6 @@ function useCopyToClipboard(options = {}) {
|
|
|
53
57
|
copied
|
|
54
58
|
};
|
|
55
59
|
}
|
|
56
|
-
|
|
57
60
|
//#endregion
|
|
58
61
|
//#region src/components/ButtonShare/components/ErrorMessage.tsx
|
|
59
62
|
const styles = {
|
|
@@ -129,6 +132,9 @@ function ToggleMessage({ debugInfo }) {
|
|
|
129
132
|
*/
|
|
130
133
|
function ErrorMessage({ debugInfo }) {
|
|
131
134
|
const { copied, copy } = useCopyToClipboard();
|
|
135
|
+
const handleCopy = () => {
|
|
136
|
+
copy(debugInfo ?? "");
|
|
137
|
+
};
|
|
132
138
|
return /* @__PURE__ */ jsxs("div", {
|
|
133
139
|
style: styles.errorContainer,
|
|
134
140
|
children: [
|
|
@@ -156,7 +162,7 @@ function ErrorMessage({ debugInfo }) {
|
|
|
156
162
|
}),
|
|
157
163
|
/* @__PURE__ */ jsx("button", {
|
|
158
164
|
type: "button",
|
|
159
|
-
onClick:
|
|
165
|
+
onClick: handleCopy,
|
|
160
166
|
style: styles.copyButton,
|
|
161
167
|
children: copied ? "Informations copiées !" : "Copier les informations de débogage"
|
|
162
168
|
}),
|
|
@@ -164,66 +170,9 @@ function ErrorMessage({ debugInfo }) {
|
|
|
164
170
|
]
|
|
165
171
|
});
|
|
166
172
|
}
|
|
167
|
-
|
|
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
173
|
//#endregion
|
|
215
174
|
//#region src/components/ButtonShare/ButtonShare.tsx
|
|
216
175
|
/**
|
|
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
176
|
* Button to share the current page
|
|
228
177
|
*
|
|
229
178
|
* @param args
|
|
@@ -264,48 +213,74 @@ async function modalEmbeddedWallet() {
|
|
|
264
213
|
* @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
|
|
265
214
|
* @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
|
|
266
215
|
*/
|
|
267
|
-
function ButtonShare({ text = "Share and earn!", classname = "", useReward: rawUseReward, noRewardText, targetInteraction,
|
|
268
|
-
const
|
|
269
|
-
const
|
|
270
|
-
const
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
216
|
+
function ButtonShare({ placement: placementId, text = "Share and earn!", classname = "", useReward: rawUseReward, noRewardText, targetInteraction, clickAction: rawClickAction, preview }) {
|
|
217
|
+
const isPreview = !!preview;
|
|
218
|
+
const placement = usePlacement(placementId);
|
|
219
|
+
const globalComponents = useGlobalComponents();
|
|
220
|
+
const componentConfig = placement?.components?.buttonShare ?? globalComponents?.buttonShare;
|
|
221
|
+
useLightDomStyles("frak-button-share", placementId, componentConfig?.css);
|
|
222
|
+
const resolvedTargetInteraction = useMemo(() => placement?.targetInteraction !== void 0 ? placement.targetInteraction : targetInteraction, [placement?.targetInteraction, targetInteraction]);
|
|
223
|
+
const resolvedText = componentConfig?.text ?? text;
|
|
224
|
+
const resolvedNoRewardText = componentConfig?.noRewardText ?? noRewardText;
|
|
225
|
+
const shouldUseReward = useMemo(() => componentConfig?.useReward ?? rawUseReward === true, [componentConfig?.useReward, rawUseReward]);
|
|
226
|
+
const resolvedClickAction = useMemo(() => componentConfig?.clickAction ?? rawClickAction ?? "sharing-page", [componentConfig?.clickAction, rawClickAction]);
|
|
227
|
+
const { shouldRender, isHidden, isClientReady } = useClientReady();
|
|
228
|
+
const { reward } = useReward(shouldUseReward && isClientReady, resolvedTargetInteraction);
|
|
229
|
+
const { handleShare, isError, debugInfo } = useShareModal(resolvedTargetInteraction, placementId);
|
|
276
230
|
const btnText = useMemo(() => {
|
|
277
|
-
if (!shouldUseReward) return
|
|
278
|
-
if (!reward) return
|
|
279
|
-
return
|
|
231
|
+
if (!shouldUseReward) return resolvedText;
|
|
232
|
+
if (!reward) return resolvedNoRewardText ?? applyRewardPlaceholder(resolvedText, void 0);
|
|
233
|
+
return resolvedText.includes("{REWARD}") ? applyRewardPlaceholder(resolvedText, reward) : `${resolvedText} ${reward}`;
|
|
280
234
|
}, [
|
|
281
235
|
shouldUseReward,
|
|
282
|
-
|
|
283
|
-
|
|
236
|
+
resolvedText,
|
|
237
|
+
resolvedNoRewardText,
|
|
284
238
|
reward
|
|
285
239
|
]);
|
|
286
|
-
/**
|
|
287
|
-
* The action when the button is clicked
|
|
288
|
-
*/
|
|
289
240
|
const onClick = useCallback(async () => {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
241
|
+
if (isPreview) return;
|
|
242
|
+
trackEvent(window.FrakSetup.client, "share_button_clicked", {
|
|
243
|
+
placement: placementId,
|
|
244
|
+
target_interaction: resolvedTargetInteraction,
|
|
245
|
+
has_reward: Boolean(reward),
|
|
246
|
+
click_action: resolvedClickAction
|
|
247
|
+
});
|
|
248
|
+
if (resolvedClickAction === "embedded-wallet") openEmbeddedWallet(resolvedTargetInteraction, placementId);
|
|
249
|
+
else if (resolvedClickAction === "share-modal") await handleShare();
|
|
250
|
+
else openSharingPage(resolvedTargetInteraction, placementId);
|
|
251
|
+
}, [
|
|
252
|
+
isPreview,
|
|
253
|
+
resolvedClickAction,
|
|
254
|
+
handleShare,
|
|
255
|
+
resolvedTargetInteraction,
|
|
256
|
+
placementId,
|
|
257
|
+
reward
|
|
258
|
+
]);
|
|
259
|
+
if (!isPreview && (!shouldRender || isHidden)) return null;
|
|
260
|
+
const buttonClass = [
|
|
261
|
+
"button",
|
|
262
|
+
"button__fadeIn",
|
|
263
|
+
classname
|
|
264
|
+
].filter(Boolean).join(" ");
|
|
265
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
|
|
295
266
|
type: "button",
|
|
296
|
-
|
|
267
|
+
disabled: !isPreview && !isClientReady,
|
|
268
|
+
class: buttonClass,
|
|
297
269
|
onClick,
|
|
298
|
-
children:
|
|
299
|
-
!isClientReady && /* @__PURE__ */ jsx(Spinner, {}),
|
|
300
|
-
" ",
|
|
301
|
-
btnText
|
|
302
|
-
]
|
|
270
|
+
children: btnText
|
|
303
271
|
}), isError && /* @__PURE__ */ jsx(ErrorMessage, { debugInfo })] });
|
|
304
272
|
}
|
|
305
|
-
|
|
306
273
|
//#endregion
|
|
307
274
|
//#region src/components/ButtonShare/index.ts
|
|
308
|
-
registerWebComponent(ButtonShare, "frak-button-share", [
|
|
309
|
-
|
|
275
|
+
registerWebComponent(ButtonShare, "frak-button-share", [
|
|
276
|
+
"text",
|
|
277
|
+
"placement",
|
|
278
|
+
"classname",
|
|
279
|
+
"clickAction",
|
|
280
|
+
"useReward",
|
|
281
|
+
"noRewardText",
|
|
282
|
+
"targetInteraction",
|
|
283
|
+
"preview"
|
|
284
|
+
], { shadow: false });
|
|
310
285
|
//#endregion
|
|
311
|
-
export { ButtonShare };
|
|
286
|
+
export { ButtonShare };
|
package/dist/buttonWallet.d.ts
CHANGED
|
@@ -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
|
/**
|
|
@@ -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
|
/**
|
package/dist/buttonWallet.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { i as
|
|
2
|
-
import { t as useReward } from "./useReward-
|
|
3
|
-
import { trackEvent } from "@frak-labs/core-sdk";
|
|
4
|
-
import { cx } from "class-variance-authority";
|
|
1
|
+
import { a as registerWebComponent, i as useClientReady, n as buildStyleContent, o as openWalletModal, t as usePlacement } from "./usePlacement-V7NrKoub.js";
|
|
2
|
+
import { t as useReward } from "./useReward-DU3_yP8Q.js";
|
|
5
3
|
import { useEffect, useMemo, useState } from "preact/hooks";
|
|
6
|
-
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
7
|
-
|
|
4
|
+
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
8
5
|
//#region src/components/ButtonWallet/assets/GiftIcon.tsx
|
|
9
6
|
function GiftIcon(props) {
|
|
10
7
|
return /* @__PURE__ */ jsxs("svg", {
|
|
@@ -22,22 +19,48 @@ function GiftIcon(props) {
|
|
|
22
19
|
})]
|
|
23
20
|
});
|
|
24
21
|
}
|
|
25
|
-
|
|
26
|
-
//#endregion
|
|
27
|
-
//#region src/components/ButtonWallet/ButtonWallet.module.css?css_module
|
|
28
|
-
const classes = {
|
|
29
|
-
"reward": "Kl62ia_reward",
|
|
30
|
-
"button__left": "Kl62ia_button__left",
|
|
31
|
-
"button": "Kl62ia_button",
|
|
32
|
-
"button__right": "Kl62ia_button__right"
|
|
33
|
-
};
|
|
34
|
-
const _reward0 = classes["reward"];
|
|
35
|
-
const _button__left0 = classes["button__left"];
|
|
36
|
-
const _button0 = classes["button"];
|
|
37
|
-
const _button__right0 = classes["button__right"];
|
|
38
|
-
|
|
39
22
|
//#endregion
|
|
40
23
|
//#region src/components/ButtonWallet/ButtonWallet.tsx
|
|
24
|
+
const componentCss = `
|
|
25
|
+
.button {
|
|
26
|
+
all: unset;
|
|
27
|
+
position: fixed;
|
|
28
|
+
bottom: 20px;
|
|
29
|
+
z-index: 2000000;
|
|
30
|
+
display: flex;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
align-items: center;
|
|
33
|
+
background-color: #3e557e;
|
|
34
|
+
width: 45px;
|
|
35
|
+
height: 45px;
|
|
36
|
+
border-radius: 50%;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
text-align: center;
|
|
39
|
+
font-size: 24px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.button__left {
|
|
43
|
+
left: 20px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.button__right {
|
|
47
|
+
right: 20px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.reward {
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: -4px;
|
|
53
|
+
right: 27px;
|
|
54
|
+
padding: 2px 3px;
|
|
55
|
+
border-radius: 5px;
|
|
56
|
+
background: #ff3f3f;
|
|
57
|
+
font-size: 9px;
|
|
58
|
+
color: #fff;
|
|
59
|
+
font-weight: 600;
|
|
60
|
+
white-space: nowrap;
|
|
61
|
+
line-height: 9px;
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
41
64
|
/**
|
|
42
65
|
* Button to open wallet modal
|
|
43
66
|
*
|
|
@@ -70,40 +93,56 @@ const _button__right0 = classes["button__right"];
|
|
|
70
93
|
* <frak-button-wallet use-reward target-interaction="custom.customerMeeting"></frak-button-wallet>
|
|
71
94
|
* ```
|
|
72
95
|
*
|
|
96
|
+
* @example
|
|
97
|
+
* Using placement:
|
|
98
|
+
* ```html
|
|
99
|
+
* <frak-button-wallet placement="hero-wallet"></frak-button-wallet>
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
73
102
|
* @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
|
|
74
103
|
* @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
|
|
75
104
|
*/
|
|
76
|
-
function ButtonWallet({ classname = "", useReward: rawUseReward, targetInteraction }) {
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
const
|
|
105
|
+
function ButtonWallet({ placement: placementId, classname = "", useReward: rawUseReward, targetInteraction }) {
|
|
106
|
+
const placement = usePlacement(placementId);
|
|
107
|
+
const resolvedTargetInteraction = useMemo(() => placement?.targetInteraction !== void 0 ? placement.targetInteraction : targetInteraction, [placement?.targetInteraction, targetInteraction]);
|
|
108
|
+
const shouldUseReward = useMemo(() => rawUseReward === true, [rawUseReward]);
|
|
109
|
+
const { shouldRender, isHidden, isClientReady } = useClientReady();
|
|
110
|
+
const { reward } = useReward(shouldUseReward && isClientReady, resolvedTargetInteraction);
|
|
80
111
|
const [position, setPosition] = useState("right");
|
|
81
|
-
/**
|
|
82
|
-
* Setup the position of the button
|
|
83
|
-
*/
|
|
84
112
|
useEffect(() => {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
113
|
+
const placementPosition = placement?.components?.buttonWallet?.position;
|
|
114
|
+
const configPosition = window.FrakSetup?.modalWalletConfig?.metadata?.position;
|
|
115
|
+
setPosition(placementPosition ?? configPosition ?? "right");
|
|
116
|
+
}, [placement?.components?.buttonWallet?.position]);
|
|
117
|
+
if (!shouldRender || isHidden) return null;
|
|
118
|
+
const buttonClass = [
|
|
119
|
+
"button",
|
|
120
|
+
"button__fadeIn",
|
|
121
|
+
position === "left" ? "button__left" : "button__right",
|
|
122
|
+
classname
|
|
123
|
+
].filter(Boolean).join(" ");
|
|
124
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("style", { children: buildStyleContent(componentCss, placement?.components?.buttonWallet?.css) }), /* @__PURE__ */ jsxs("button", {
|
|
89
125
|
type: "button",
|
|
90
126
|
"aria-label": "Open wallet",
|
|
91
|
-
|
|
127
|
+
part: "button",
|
|
92
128
|
disabled: !isClientReady,
|
|
129
|
+
class: buttonClass,
|
|
93
130
|
onClick: () => {
|
|
94
|
-
|
|
95
|
-
openWalletModal();
|
|
131
|
+
openWalletModal(resolvedTargetInteraction, placementId);
|
|
96
132
|
},
|
|
97
133
|
children: [/* @__PURE__ */ jsx(GiftIcon, {}), reward && /* @__PURE__ */ jsx("span", {
|
|
98
|
-
|
|
134
|
+
class: "reward",
|
|
99
135
|
children: reward
|
|
100
136
|
})]
|
|
101
|
-
});
|
|
137
|
+
})] });
|
|
102
138
|
}
|
|
103
|
-
|
|
104
139
|
//#endregion
|
|
105
140
|
//#region src/components/ButtonWallet/index.ts
|
|
106
|
-
registerWebComponent(ButtonWallet, "frak-button-wallet", [
|
|
107
|
-
|
|
141
|
+
registerWebComponent(ButtonWallet, "frak-button-wallet", [
|
|
142
|
+
"placement",
|
|
143
|
+
"classname",
|
|
144
|
+
"useReward",
|
|
145
|
+
"targetInteraction"
|
|
146
|
+
], { shadow: true });
|
|
108
147
|
//#endregion
|
|
109
|
-
export { ButtonWallet };
|
|
148
|
+
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 };
|
package/dist/openInApp.d.ts
CHANGED
|
@@ -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
|
/**
|
|
@@ -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,9 +46,10 @@ type OpenInAppButtonProps = {
|
|
|
45
46
|
* ```
|
|
46
47
|
*/
|
|
47
48
|
declare function OpenInAppButton({
|
|
49
|
+
placement: placementId,
|
|
48
50
|
text,
|
|
49
51
|
classname
|
|
50
|
-
}: OpenInAppButtonProps): preact.JSX.Element | null;
|
|
52
|
+
}: OpenInAppButtonProps): _$preact.JSX.Element | null;
|
|
51
53
|
//#endregion
|
|
52
54
|
//#region src/components/OpenInAppButton/index.d.ts
|
|
53
55
|
/**
|
package/dist/openInApp.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
1
|
+
import { a as registerWebComponent, i as useClientReady, t as usePlacement } from "./usePlacement-V7NrKoub.js";
|
|
2
|
+
import { t as useLightDomStyles } from "./useLightDomStyles-C3lcOwY2.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
|
|
7
|
-
|
|
5
|
+
import { jsx } from "preact/jsx-runtime";
|
|
8
6
|
//#region src/utils/isMobile.ts
|
|
9
7
|
/**
|
|
10
8
|
* Check if the current device is a mobile device
|
|
@@ -21,13 +19,11 @@ function isMobile() {
|
|
|
21
19
|
if (/Macintosh/i.test(navigator.userAgent) && navigator.maxTouchPoints > 1) return true;
|
|
22
20
|
return false;
|
|
23
21
|
}
|
|
24
|
-
|
|
25
22
|
//#endregion
|
|
26
23
|
//#region src/hooks/useIsMobile.ts
|
|
27
24
|
function useIsMobile() {
|
|
28
25
|
return { isMobile: useMemo(() => isMobile(), []) };
|
|
29
26
|
}
|
|
30
|
-
|
|
31
27
|
//#endregion
|
|
32
28
|
//#region src/utils/openInApp.ts
|
|
33
29
|
const DEFAULT_PATH = "wallet";
|
|
@@ -37,22 +33,20 @@ const DEFAULT_PATH = "wallet";
|
|
|
37
33
|
* Uses visibility-based detection to determine if the app opened.
|
|
38
34
|
* If the app is not installed (page stays visible after 2.5s),
|
|
39
35
|
* tracks an "app_not_installed" event.
|
|
40
|
-
*
|
|
41
|
-
* @param path - Path to open in the app (default: "wallet")
|
|
42
36
|
*/
|
|
43
|
-
function openFrakWalletApp(path = DEFAULT_PATH) {
|
|
37
|
+
function openFrakWalletApp(path = DEFAULT_PATH, placement) {
|
|
44
38
|
const client = window.FrakSetup?.client;
|
|
45
|
-
if (client) trackEvent(client, "open_in_app_clicked"
|
|
39
|
+
if (client) trackEvent(client, "open_in_app_clicked", {
|
|
40
|
+
path,
|
|
41
|
+
placement
|
|
42
|
+
});
|
|
46
43
|
triggerDeepLinkWithFallback(`${DEEP_LINK_SCHEME}${path}`, { onFallback: () => {
|
|
47
|
-
if (client) trackEvent(client, "app_not_installed"
|
|
44
|
+
if (client) trackEvent(client, "app_not_installed", {
|
|
45
|
+
path,
|
|
46
|
+
placement
|
|
47
|
+
});
|
|
48
48
|
} });
|
|
49
49
|
}
|
|
50
|
-
|
|
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,36 @@ 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
|
|
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
|
-
|
|
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
|
-
openFrakWalletApp();
|
|
86
|
+
openFrakWalletApp(void 0, placementId);
|
|
90
87
|
};
|
|
91
|
-
|
|
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
|
-
|
|
105
102
|
//#endregion
|
|
106
103
|
//#region src/components/OpenInAppButton/index.ts
|
|
107
|
-
registerWebComponent(OpenInAppButton, "frak-open-in-app", [
|
|
108
|
-
|
|
104
|
+
registerWebComponent(OpenInAppButton, "frak-open-in-app", [
|
|
105
|
+
"text",
|
|
106
|
+
"placement",
|
|
107
|
+
"classname"
|
|
108
|
+
], { shadow: false });
|
|
109
109
|
//#endregion
|
|
110
|
-
export { OpenInAppButton };
|
|
110
|
+
export { OpenInAppButton };
|