@frak-labs/components 1.0.3-beta.7dfd3480 → 1.0.3-beta.9d4f564a

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.
@@ -1,122 +0,0 @@
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-gbuSWvRx.js";
4
- import { t as applyRewardPlaceholder } from "./formatReward-Bub6Z6eY.js";
5
- import { t as useReward } from "./useReward-DU3_yP8Q.js";
6
- import { t as openSharingPage } from "./sharingPage-DFvQbviS.js";
7
- import { trackEvent } from "@frak-labs/core-sdk";
8
- import { useCallback, useMemo } from "preact/hooks";
9
- import { jsx } from "preact/jsx-runtime";
10
- //#region src/components/ButtonShare/ButtonShare.tsx
11
- /**
12
- * Button to share the current page
13
- *
14
- * @param args
15
- * @returns The share button with `<button>` tag
16
- *
17
- * @group components
18
- *
19
- * @example
20
- * Basic usage:
21
- * ```html
22
- * <frak-button-share></frak-button-share>
23
- * ```
24
- *
25
- * @example
26
- * Using a custom text:
27
- * ```html
28
- * <frak-button-share text="Share and earn!"></frak-button-share>
29
- * ```
30
- *
31
- * @example
32
- * Using a custom class:
33
- * ```html
34
- * <frak-button-share classname="button button-primary"></frak-button-share>
35
- * ```
36
- *
37
- * @example
38
- * Using reward information and fallback text:
39
- * ```html
40
- * <frak-button-share use-reward text="Share and earn up to {REWARD}!" no-reward-text="Share and earn!"></frak-button-share>
41
- * ```
42
- *
43
- * @example
44
- * Using reward information for specific reward and fallback text:
45
- * ```html
46
- * <frak-button-share use-reward text="Share and earn up to {REWARD}!" no-reward-text="Share and earn!" target-interaction="custom.customerMeeting"></frak-button-share>
47
- * ```
48
- *
49
- * @see {@link @frak-labs/core-sdk!actions.displaySharingPage | `displaySharingPage()`} for more info about the sharing-page flow
50
- * @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
51
- */
52
- function ButtonShare({ placement: placementId, text = "Share and earn!", classname = "", useReward: rawUseReward, noRewardText, targetInteraction, clickAction: rawClickAction, preview }) {
53
- const isPreview = !!preview;
54
- const placement = usePlacement(placementId);
55
- const globalComponents = useGlobalComponents();
56
- const componentConfig = placement?.components?.buttonShare ?? globalComponents?.buttonShare;
57
- useLightDomStyles("frak-button-share", placementId, componentConfig?.css);
58
- const resolvedTargetInteraction = useMemo(() => placement?.targetInteraction !== void 0 ? placement.targetInteraction : targetInteraction, [placement?.targetInteraction, targetInteraction]);
59
- const resolvedText = componentConfig?.text ?? text;
60
- const resolvedNoRewardText = componentConfig?.noRewardText ?? noRewardText;
61
- const shouldUseReward = useMemo(() => componentConfig?.useReward ?? rawUseReward === true, [componentConfig?.useReward, rawUseReward]);
62
- const resolvedClickAction = useMemo(() => componentConfig?.clickAction ?? rawClickAction ?? "sharing-page", [componentConfig?.clickAction, rawClickAction]);
63
- const { shouldRender, isHidden, isClientReady } = useClientReady();
64
- const { reward } = useReward(shouldUseReward && isClientReady, resolvedTargetInteraction);
65
- const btnText = useMemo(() => {
66
- if (!shouldUseReward) return resolvedText;
67
- if (!reward) return resolvedNoRewardText ?? applyRewardPlaceholder(resolvedText, void 0);
68
- return resolvedText.includes("{REWARD}") ? applyRewardPlaceholder(resolvedText, reward) : `${resolvedText} ${reward}`;
69
- }, [
70
- shouldUseReward,
71
- resolvedText,
72
- resolvedNoRewardText,
73
- reward
74
- ]);
75
- const onClick = useCallback(() => {
76
- if (isPreview) return;
77
- trackEvent(window.FrakSetup.client, "share_button_clicked", {
78
- placement: placementId,
79
- target_interaction: resolvedTargetInteraction,
80
- has_reward: Boolean(reward),
81
- click_action: resolvedClickAction
82
- });
83
- if (resolvedClickAction === "embedded-wallet") {
84
- openEmbeddedWallet(resolvedTargetInteraction, placementId);
85
- return;
86
- }
87
- openSharingPage(resolvedTargetInteraction, placementId);
88
- }, [
89
- isPreview,
90
- resolvedClickAction,
91
- resolvedTargetInteraction,
92
- placementId,
93
- reward
94
- ]);
95
- if (!isPreview && (!shouldRender || isHidden)) return null;
96
- const buttonClass = [
97
- "button",
98
- "button__fadeIn",
99
- classname
100
- ].filter(Boolean).join(" ");
101
- return /* @__PURE__ */ jsx("button", {
102
- type: "button",
103
- disabled: !isPreview && !isClientReady,
104
- class: buttonClass,
105
- onClick,
106
- children: btnText
107
- });
108
- }
109
- //#endregion
110
- //#region src/components/ButtonShare/index.ts
111
- registerWebComponent(ButtonShare, "frak-button-share", [
112
- "text",
113
- "placement",
114
- "classname",
115
- "clickAction",
116
- "useReward",
117
- "noRewardText",
118
- "targetInteraction",
119
- "preview"
120
- ], { shadow: false });
121
- //#endregion
122
- export { ButtonShare };
@@ -1,87 +0,0 @@
1
- import { InteractionTypeKey } from "@frak-labs/core-sdk";
2
- import * as _$preact from "preact";
3
-
4
- //#region src/components/ButtonWallet/types.d.ts
5
- /**
6
- * The props type for {@link ButtonWallet}.
7
- * @inline
8
- */
9
- type ButtonWalletProps = {
10
- placement?: string;
11
- /**
12
- * Classname to apply to the button
13
- */
14
- classname?: string;
15
- /**
16
- * Do we display the reward on the button?
17
- * @defaultValue `false`
18
- */
19
- useReward?: boolean;
20
- /**
21
- * Target interaction behind this sharing action (will be used to get the right reward to display)
22
- */
23
- targetInteraction?: InteractionTypeKey;
24
- };
25
- //#endregion
26
- //#region src/components/ButtonWallet/ButtonWallet.d.ts
27
- /**
28
- * Button to open wallet modal
29
- *
30
- * @param args
31
- * @returns The wallet button with `<button>` tag
32
- *
33
- * @group components
34
- *
35
- * @example
36
- * Basic usage:
37
- * ```html
38
- * <frak-button-wallet></frak-button-wallet>
39
- * ```
40
- *
41
- * @example
42
- * Using a custom class:
43
- * ```html
44
- * <frak-button-wallet classname="button button-primary"></frak-button-wallet>
45
- * ```
46
- *
47
- * @example
48
- * Using reward information:
49
- * ```html
50
- * <frak-button-wallet use-reward></frak-button-wallet>
51
- * ```
52
- *
53
- * @example
54
- * Using reward information for specific reward:
55
- * ```html
56
- * <frak-button-wallet use-reward target-interaction="custom.customerMeeting"></frak-button-wallet>
57
- * ```
58
- *
59
- * @example
60
- * Using placement:
61
- * ```html
62
- * <frak-button-wallet placement="hero-wallet"></frak-button-wallet>
63
- * ```
64
- *
65
- * @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
66
- * @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
67
- */
68
- declare function ButtonWallet({
69
- placement: placementId,
70
- classname,
71
- useReward: rawUseReward,
72
- targetInteraction
73
- }: ButtonWalletProps): _$preact.JSX.Element | null;
74
- //#endregion
75
- //#region src/components/ButtonWallet/index.d.ts
76
- /**
77
- * Custom element interface for `<frak-button-wallet>`.
78
- * Combines standard {@link HTMLElement} with {@link ButtonWalletProps}.
79
- */
80
- interface ButtonWalletElement extends HTMLElement, ButtonWalletProps {}
81
- declare global {
82
- interface HTMLElementTagNameMap {
83
- "frak-button-wallet": ButtonWalletElement;
84
- }
85
- }
86
- //#endregion
87
- export { ButtonWallet, ButtonWalletElement };
@@ -1,148 +0,0 @@
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";
3
- import { useEffect, useMemo, useState } from "preact/hooks";
4
- import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
5
- //#region src/components/ButtonWallet/assets/GiftIcon.tsx
6
- function GiftIcon(props) {
7
- return /* @__PURE__ */ jsxs("svg", {
8
- fill: "none",
9
- height: "1em",
10
- viewBox: "0 0 28 28",
11
- width: "1em",
12
- xmlns: "http://www.w3.org/2000/svg",
13
- ...props,
14
- children: [/* @__PURE__ */ jsx("title", { children: "Gift icon" }), /* @__PURE__ */ jsx("path", {
15
- d: "m23.1427 13.9999v11.4285h-18.2857v-11.4285m9.1429 11.4285v-17.14282m0 0h-5.1429c-.75776 0-1.48448-.30102-2.0203-.83684s-.83684-1.26255-.83684-2.02031.30102-1.48448.83684-2.0203 1.26254-.83684 2.0203-.83684c4 0 5.1429 5.71429 5.1429 5.71429zm0 0h5.1428c.7578 0 1.4845-.30102 2.0203-.83684s.8369-1.26255.8369-2.02031-.3011-1.48448-.8369-2.0203-1.2625-.83684-2.0203-.83684c-4 0-5.1428 5.71429-5.1428 5.71429zm-11.42861 0h22.85711v5.71432h-22.85711z",
16
- stroke: "#fff",
17
- "stroke-linecap": "round",
18
- "stroke-linejoin": "round"
19
- })]
20
- });
21
- }
22
- //#endregion
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
- `;
64
- /**
65
- * Button to open wallet modal
66
- *
67
- * @param args
68
- * @returns The wallet button with `<button>` tag
69
- *
70
- * @group components
71
- *
72
- * @example
73
- * Basic usage:
74
- * ```html
75
- * <frak-button-wallet></frak-button-wallet>
76
- * ```
77
- *
78
- * @example
79
- * Using a custom class:
80
- * ```html
81
- * <frak-button-wallet classname="button button-primary"></frak-button-wallet>
82
- * ```
83
- *
84
- * @example
85
- * Using reward information:
86
- * ```html
87
- * <frak-button-wallet use-reward></frak-button-wallet>
88
- * ```
89
- *
90
- * @example
91
- * Using reward information for specific reward:
92
- * ```html
93
- * <frak-button-wallet use-reward target-interaction="custom.customerMeeting"></frak-button-wallet>
94
- * ```
95
- *
96
- * @example
97
- * Using placement:
98
- * ```html
99
- * <frak-button-wallet placement="hero-wallet"></frak-button-wallet>
100
- * ```
101
- *
102
- * @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
103
- * @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
104
- */
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);
111
- const [position, setPosition] = useState("right");
112
- useEffect(() => {
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", {
125
- type: "button",
126
- "aria-label": "Open wallet",
127
- part: "button",
128
- disabled: !isClientReady,
129
- class: buttonClass,
130
- onClick: () => {
131
- openWalletModal(resolvedTargetInteraction, placementId);
132
- },
133
- children: [/* @__PURE__ */ jsx(GiftIcon, {}), reward && /* @__PURE__ */ jsx("span", {
134
- class: "reward",
135
- children: reward
136
- })]
137
- })] });
138
- }
139
- //#endregion
140
- //#region src/components/ButtonWallet/index.ts
141
- registerWebComponent(ButtonWallet, "frak-button-wallet", [
142
- "placement",
143
- "classname",
144
- "useReward",
145
- "targetInteraction"
146
- ], { shadow: true });
147
- //#endregion
148
- export { ButtonWallet };
@@ -1,33 +0,0 @@
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,66 +0,0 @@
1
- import * as _$preact from "preact";
2
-
3
- //#region src/components/OpenInAppButton/types.d.ts
4
- /**
5
- * The props type for {@link OpenInAppButton}.
6
- * @inline
7
- */
8
- type OpenInAppButtonProps = {
9
- placement?: string;
10
- /**
11
- * Text to display on the button
12
- * @defaultValue `"Open in App"`
13
- */
14
- text?: string;
15
- /**
16
- * Classname to apply to the button
17
- */
18
- classname?: string;
19
- };
20
- //#endregion
21
- //#region src/components/OpenInAppButton/OpenInAppButton.d.ts
22
- /**
23
- * Button to open the Frak Wallet mobile app via deep link
24
- *
25
- * @param args
26
- * @returns The open in app button with `<button>` tag (only renders on mobile devices)
27
- *
28
- * @group components
29
- *
30
- * @example
31
- * Basic usage:
32
- * ```html
33
- * <frak-open-in-app></frak-open-in-app>
34
- * ```
35
- *
36
- * @example
37
- * Using a custom text:
38
- * ```html
39
- * <frak-open-in-app text="Get the App"></frak-open-in-app>
40
- * ```
41
- *
42
- * @example
43
- * With login action:
44
- * ```html
45
- * <frak-open-in-app classname="button button-primary"></frak-open-in-app>
46
- * ```
47
- */
48
- declare function OpenInAppButton({
49
- placement: placementId,
50
- text,
51
- classname
52
- }: OpenInAppButtonProps): _$preact.JSX.Element | null;
53
- //#endregion
54
- //#region src/components/OpenInAppButton/index.d.ts
55
- /**
56
- * Custom element interface for `<frak-open-in-app>`.
57
- * Combines standard {@link HTMLElement} with {@link OpenInAppButtonProps}.
58
- */
59
- interface OpenInAppButtonElement extends HTMLElement, OpenInAppButtonProps {}
60
- declare global {
61
- interface HTMLElementTagNameMap {
62
- "frak-open-in-app": OpenInAppButtonElement;
63
- }
64
- }
65
- //#endregion
66
- export { OpenInAppButton, OpenInAppButtonElement };
package/dist/openInApp.js DELETED
@@ -1,110 +0,0 @@
1
- import { a as registerWebComponent, i as useClientReady, t as usePlacement } from "./usePlacement-V7NrKoub.js";
2
- import { t as useLightDomStyles } from "./useLightDomStyles-gbuSWvRx.js";
3
- import { DEEP_LINK_SCHEME, trackEvent, triggerDeepLinkWithFallback } from "@frak-labs/core-sdk";
4
- import { useMemo } from "preact/hooks";
5
- import { jsx } from "preact/jsx-runtime";
6
- //#region src/utils/isMobile.ts
7
- /**
8
- * Check if the current device is a mobile device
9
- * Uses UA regex + iPad desktop mode heuristic (maxTouchPoints)
10
- *
11
- * iPadOS 13+ sends a Macintosh UA in desktop mode, so the regex alone
12
- * misses it. The maxTouchPoints check catches iPads reporting as Mac.
13
- *
14
- * @returns True if the device is mobile (iOS, Android, iPadOS, etc.)
15
- */
16
- function isMobile() {
17
- if (typeof navigator === "undefined") return false;
18
- if (/iPhone|iPad|iPod|Android|webOS|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) return true;
19
- if (/Macintosh/i.test(navigator.userAgent) && navigator.maxTouchPoints > 1) return true;
20
- return false;
21
- }
22
- //#endregion
23
- //#region src/hooks/useIsMobile.ts
24
- function useIsMobile() {
25
- return { isMobile: useMemo(() => isMobile(), []) };
26
- }
27
- //#endregion
28
- //#region src/utils/openInApp.ts
29
- const DEFAULT_PATH = "wallet";
30
- /**
31
- * Open the Frak Wallet mobile app via deep link with fallback detection.
32
- *
33
- * Uses visibility-based detection to determine if the app opened.
34
- * If the app is not installed (page stays visible after 2.5s),
35
- * tracks an "app_not_installed" event.
36
- */
37
- function openFrakWalletApp(path = DEFAULT_PATH, placement) {
38
- const client = window.FrakSetup?.client;
39
- if (client) trackEvent(client, "open_in_app_clicked", {
40
- path,
41
- placement
42
- });
43
- triggerDeepLinkWithFallback(`${DEEP_LINK_SCHEME}${path}`, { onFallback: () => {
44
- if (client) trackEvent(client, "app_not_installed", {
45
- path,
46
- placement
47
- });
48
- } });
49
- }
50
- //#endregion
51
- //#region src/components/OpenInAppButton/OpenInAppButton.tsx
52
- /**
53
- * Button to open the Frak Wallet mobile app via deep link
54
- *
55
- * @param args
56
- * @returns The open in app button with `<button>` tag (only renders on mobile devices)
57
- *
58
- * @group components
59
- *
60
- * @example
61
- * Basic usage:
62
- * ```html
63
- * <frak-open-in-app></frak-open-in-app>
64
- * ```
65
- *
66
- * @example
67
- * Using a custom text:
68
- * ```html
69
- * <frak-open-in-app text="Get the App"></frak-open-in-app>
70
- * ```
71
- *
72
- * @example
73
- * With login action:
74
- * ```html
75
- * <frak-open-in-app classname="button button-primary"></frak-open-in-app>
76
- * ```
77
- */
78
- function OpenInAppButton({ placement: placementId, text = "Open in App", classname = "" }) {
79
- const placement = usePlacement(placementId);
80
- const { shouldRender, isHidden, isClientReady } = useClientReady();
81
- const { isMobile } = useIsMobile();
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;
85
- const handleClick = () => {
86
- openFrakWalletApp(void 0, placementId);
87
- };
88
- const buttonClass = [
89
- "button",
90
- "button__fadeIn",
91
- classname
92
- ].filter(Boolean).join(" ");
93
- return /* @__PURE__ */ jsx("button", {
94
- type: "button",
95
- "aria-label": "Open in Frak Wallet app",
96
- disabled: !isClientReady,
97
- class: buttonClass,
98
- onClick: handleClick,
99
- children: resolvedText
100
- });
101
- }
102
- //#endregion
103
- //#region src/components/OpenInAppButton/index.ts
104
- registerWebComponent(OpenInAppButton, "frak-open-in-app", [
105
- "text",
106
- "placement",
107
- "classname"
108
- ], { shadow: false });
109
- //#endregion
110
- export { OpenInAppButton };