@frak-labs/components 0.0.26 → 1.0.0-beta.bd7d4823
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.Ws9o79lU.js +64 -0
- package/cdn/ButtonShare.BDS1fgma.js +1 -0
- package/cdn/ButtonWallet.Be1UyRm8.js +40 -0
- package/cdn/OpenInAppButton.Diqt07eo.js +1 -0
- package/cdn/PostPurchase.DqFhm-Jn.js +52 -0
- package/cdn/components.js +1 -1
- package/cdn/formatReward.CXxVsWN3.js +1 -0
- package/cdn/loader.css +0 -14
- package/cdn/loader.js +14 -1
- package/cdn/sprinkles.css.ts.vanilla.BtFkD4B3.js +1175 -0
- package/cdn/useGlobalComponents.BRe8dKO7.js +1 -0
- package/cdn/useLightDomStyles.ZFa154u8.js +1 -0
- package/cdn/usePlacement.B7jMsQvP.js +58 -0
- package/cdn/useReward.qEKeySJG.js +1 -0
- package/cdn/useShareModal.B--64ELG.js +1 -0
- package/dist/GiftIcon-4sr9xXyq.js +1501 -0
- package/dist/banner.d.ts +116 -0
- package/dist/banner.js +431 -0
- package/dist/buttonShare.d.ts +8 -6
- package/dist/buttonShare.js +63 -101
- package/dist/buttonWallet.d.ts +10 -2
- package/dist/buttonWallet.js +79 -38
- package/dist/formatReward-Bub6Z6eY.js +33 -0
- package/dist/openInApp.d.ts +4 -2
- package/dist/openInApp.js +23 -27
- package/dist/postPurchase.d.ts +122 -0
- package/dist/postPurchase.js +1579 -0
- package/dist/useGlobalComponents-Cmfszr7v.js +21 -0
- package/dist/useLightDomStyles-hgYYZsTy.js +41 -0
- package/dist/usePlacement-LqYjZLX_.js +248 -0
- package/dist/useReward-DU3_yP8Q.js +65 -0
- package/dist/useShareModal-DgEf5WWG.js +53 -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/banner.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
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
|
+
* When set, forces the banner to render in preview mode (e.g. in Shopify theme editor).
|
|
49
|
+
* Bypasses normal event/browser detection and shows static content.
|
|
50
|
+
*/
|
|
51
|
+
preview?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Which banner variant to preview: "referral" or "inapp".
|
|
54
|
+
* Only used when {@link preview} is set. Defaults to "referral".
|
|
55
|
+
*/
|
|
56
|
+
previewMode?: "referral" | "inapp";
|
|
57
|
+
};
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/components/Banner/Banner.d.ts
|
|
60
|
+
/**
|
|
61
|
+
* Auto-detecting notification banner component.
|
|
62
|
+
*
|
|
63
|
+
* Renders an inline banner on the merchant page with one of two distinct
|
|
64
|
+
* visual styles depending on the detected mode:
|
|
65
|
+
*
|
|
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.
|
|
72
|
+
*
|
|
73
|
+
* In-app browser mode takes priority over referral mode.
|
|
74
|
+
* Uses Light DOM + vanilla-extract styles from `@frak-labs/design-system`.
|
|
75
|
+
*
|
|
76
|
+
* @group components
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* Basic usage (auto-detects mode):
|
|
80
|
+
* ```html
|
|
81
|
+
* <frak-banner></frak-banner>
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* With a custom class:
|
|
86
|
+
* ```html
|
|
87
|
+
* <frak-banner classname="my-custom-banner"></frak-banner>
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
declare function Banner({
|
|
91
|
+
placement: placementId,
|
|
92
|
+
classname,
|
|
93
|
+
interaction,
|
|
94
|
+
referralTitle: propReferralTitle,
|
|
95
|
+
referralDescription: propReferralDescription,
|
|
96
|
+
referralCta: propReferralCta,
|
|
97
|
+
inappTitle: propInappTitle,
|
|
98
|
+
inappDescription: propInappDescription,
|
|
99
|
+
inappCta: propInappCta,
|
|
100
|
+
preview,
|
|
101
|
+
previewMode
|
|
102
|
+
}: BannerProps): _$preact.JSX.Element | null;
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/components/Banner/index.d.ts
|
|
105
|
+
/**
|
|
106
|
+
* Custom element interface for `<frak-banner>`.
|
|
107
|
+
* Combines standard {@link HTMLElement} with {@link BannerProps}.
|
|
108
|
+
*/
|
|
109
|
+
interface BannerElement extends HTMLElement, BannerProps {}
|
|
110
|
+
declare global {
|
|
111
|
+
interface HTMLElementTagNameMap {
|
|
112
|
+
"frak-banner": BannerElement;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { Banner, BannerElement };
|
package/dist/banner.js
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
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";
|
|
6
|
+
import { isInAppBrowser, redirectToExternalBrowser } from "@frak-labs/core-sdk";
|
|
7
|
+
import { REFERRAL_SUCCESS_EVENT, getMergeToken } from "@frak-labs/core-sdk/actions";
|
|
8
|
+
import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
|
|
9
|
+
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
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",
|
|
127
|
+
children: [
|
|
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
|
+
})]
|
|
140
|
+
}),
|
|
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
|
+
})]
|
|
155
|
+
}),
|
|
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
|
+
})
|
|
165
|
+
})
|
|
166
|
+
]
|
|
167
|
+
});
|
|
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
|
|
247
|
+
/**
|
|
248
|
+
* Auto-detecting notification banner component.
|
|
249
|
+
*
|
|
250
|
+
* Renders an inline banner on the merchant page with one of two distinct
|
|
251
|
+
* visual styles depending on the detected mode:
|
|
252
|
+
*
|
|
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.
|
|
259
|
+
*
|
|
260
|
+
* In-app browser mode takes priority over referral mode.
|
|
261
|
+
* Uses Light DOM + vanilla-extract styles from `@frak-labs/design-system`.
|
|
262
|
+
*
|
|
263
|
+
* @group components
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* Basic usage (auto-detects mode):
|
|
267
|
+
* ```html
|
|
268
|
+
* <frak-banner></frak-banner>
|
|
269
|
+
* ```
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* With a custom class:
|
|
273
|
+
* ```html
|
|
274
|
+
* <frak-banner classname="my-custom-banner"></frak-banner>
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
function Banner({ placement: placementId, classname = "", interaction, referralTitle: propReferralTitle, referralDescription: propReferralDescription, referralCta: propReferralCta, inappTitle: propInappTitle, inappDescription: propInappDescription, inappCta: propInappCta, preview, previewMode }) {
|
|
278
|
+
const isPreview = !!preview;
|
|
279
|
+
const resolvedPreviewMode = previewMode === "inapp" ? "inapp" : "referral";
|
|
280
|
+
const placement = usePlacement(placementId);
|
|
281
|
+
const { shouldRender, isHidden, isClientReady } = useClientReady();
|
|
282
|
+
useLightDomStyles("frak-banner", placementId, placement?.components?.banner?.css, cssSource);
|
|
283
|
+
const [dismissed, setDismissed] = useState(false);
|
|
284
|
+
const [mode, setMode] = useState(() => {
|
|
285
|
+
if (isPreview) return resolvedPreviewMode;
|
|
286
|
+
return isInAppBrowser ? "inapp" : null;
|
|
287
|
+
});
|
|
288
|
+
useEffect(() => {
|
|
289
|
+
if (isPreview) setMode(resolvedPreviewMode);
|
|
290
|
+
}, [isPreview, resolvedPreviewMode]);
|
|
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
|
+
]);
|
|
302
|
+
useEffect(() => {
|
|
303
|
+
if (isPreview || mode === "inapp") return;
|
|
304
|
+
const handler = () => setMode("referral");
|
|
305
|
+
window.addEventListener(REFERRAL_SUCCESS_EVENT, handler);
|
|
306
|
+
return () => window.removeEventListener(REFERRAL_SUCCESS_EVENT, handler);
|
|
307
|
+
}, [isPreview, mode]);
|
|
308
|
+
const handleAction = useCallback(async () => {
|
|
309
|
+
if (isPreview) return;
|
|
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;
|
|
336
|
+
const texts = useMemo(() => {
|
|
337
|
+
if (mode === "referral") {
|
|
338
|
+
const defaultTitle = reward ? `Earn ${reward} on purchases on this site` : "You've been referred!";
|
|
339
|
+
return {
|
|
340
|
+
title: propReferralTitle ?? bannerConfig?.referralTitle ?? defaultTitle,
|
|
341
|
+
description: propReferralDescription ?? bannerConfig?.referralDescription ?? "Earn rewards after your purchase via the Frak partner app.",
|
|
342
|
+
cta: propReferralCta ?? bannerConfig?.referralCta ?? "Got it"
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
title: propInappTitle ?? bannerConfig?.inappTitle ?? "Open in your browser",
|
|
347
|
+
description: propInappDescription ?? bannerConfig?.inappDescription ?? "For a better experience and to earn your rewards, open this page in your default browser.",
|
|
348
|
+
cta: propInappCta ?? bannerConfig?.inappCta ?? "Open browser"
|
|
349
|
+
};
|
|
350
|
+
}, [
|
|
351
|
+
mode,
|
|
352
|
+
reward,
|
|
353
|
+
bannerConfig,
|
|
354
|
+
propReferralTitle,
|
|
355
|
+
propReferralDescription,
|
|
356
|
+
propReferralCta,
|
|
357
|
+
propInappTitle,
|
|
358
|
+
propInappDescription,
|
|
359
|
+
propInappCta
|
|
360
|
+
]);
|
|
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",
|
|
378
|
+
classname
|
|
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,
|
|
390
|
+
role: "alert",
|
|
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`,
|
|
399
|
+
children: texts.title
|
|
400
|
+
}),
|
|
401
|
+
/* @__PURE__ */ jsx("p", {
|
|
402
|
+
class: `${referralDescription} frak-banner__description`,
|
|
403
|
+
children: texts.description
|
|
404
|
+
}),
|
|
405
|
+
/* @__PURE__ */ jsx("button", {
|
|
406
|
+
type: "button",
|
|
407
|
+
class: `${referralCta} frak-banner__cta`,
|
|
408
|
+
onClick: handleAction,
|
|
409
|
+
children: texts.cta
|
|
410
|
+
})
|
|
411
|
+
]
|
|
412
|
+
})]
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
//#endregion
|
|
416
|
+
//#region src/components/Banner/index.ts
|
|
417
|
+
registerWebComponent(Banner, "frak-banner", [
|
|
418
|
+
"placement",
|
|
419
|
+
"classname",
|
|
420
|
+
"interaction",
|
|
421
|
+
"referralTitle",
|
|
422
|
+
"referralDescription",
|
|
423
|
+
"referralCta",
|
|
424
|
+
"inappTitle",
|
|
425
|
+
"inappDescription",
|
|
426
|
+
"inappCta",
|
|
427
|
+
"preview",
|
|
428
|
+
"previewMode"
|
|
429
|
+
], { shadow: false });
|
|
430
|
+
//#endregion
|
|
431
|
+
export { Banner };
|
package/dist/buttonShare.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/ButtonShare/types.d.ts
|
|
5
5
|
/**
|
|
@@ -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
|
-
*
|
|
35
|
-
* @defaultValue `
|
|
35
|
+
* Which UI to open on click
|
|
36
|
+
* @defaultValue `"embedded-wallet"`
|
|
36
37
|
*/
|
|
37
|
-
|
|
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
|
-
|
|
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
|
/**
|