@frak-labs/components 0.0.23 → 0.0.24-beta.1e44255d

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.
@@ -0,0 +1,36 @@
1
+ import { cx } from "class-variance-authority";
2
+ import { jsx, jsxs } from "preact/jsx-runtime";
3
+
4
+ //#region src/components/Spinner/index.module.css?css_module
5
+ const classes = {
6
+ "spinner__leaf": "M4fSKa_spinner__leaf",
7
+ "rt-spinner-leaf-fade": "M4fSKa_rt-spinner-leaf-fade",
8
+ "spinner": "M4fSKa_spinner"
9
+ };
10
+ const _spinner__leaf0 = classes["spinner__leaf"];
11
+ const _rt_spinner_leaf_fade0 = classes["rt-spinner-leaf-fade"];
12
+ const _spinner0 = classes["spinner"];
13
+
14
+ //#endregion
15
+ //#region src/components/Spinner/index.tsx
16
+ const Spinner = ({ ref, className, ...props }) => {
17
+ return /* @__PURE__ */ jsxs("span", {
18
+ ...props,
19
+ ref,
20
+ className: cx(classes.spinner),
21
+ children: [
22
+ /* @__PURE__ */ jsx("span", { className: classes.spinner__leaf }),
23
+ /* @__PURE__ */ jsx("span", { className: classes.spinner__leaf }),
24
+ /* @__PURE__ */ jsx("span", { className: classes.spinner__leaf }),
25
+ /* @__PURE__ */ jsx("span", { className: classes.spinner__leaf }),
26
+ /* @__PURE__ */ jsx("span", { className: classes.spinner__leaf }),
27
+ /* @__PURE__ */ jsx("span", { className: classes.spinner__leaf }),
28
+ /* @__PURE__ */ jsx("span", { className: classes.spinner__leaf }),
29
+ /* @__PURE__ */ jsx("span", { className: classes.spinner__leaf })
30
+ ]
31
+ });
32
+ };
33
+ Spinner.displayName = "Spinner";
34
+
35
+ //#endregion
36
+ export { Spinner as t };
@@ -1 +1 @@
1
- .spinner-KHk8mw{--spinner-opacity:.65;opacity:var(--spinner-opacity);width:16px;height:16px;display:block;position:relative}.spinner__leaf-xtOJmT{--spinner-animation-duration:.8s;width:12.5%;height:100%;animation:rt-spinner-leaf-fade-OXYBVY var(--spinner-animation-duration)linear infinite;position:absolute;top:0;left:43.75%}.spinner__leaf-xtOJmT:before{content:"";background-color:currentColor;border-radius:3px;width:100%;height:30%;display:block}.spinner__leaf-xtOJmT:where(:first-child){animation-delay:calc(-8/8*var(--spinner-animation-duration));transform:rotate(0)}.spinner__leaf-xtOJmT:where(:nth-child(2)){animation-delay:calc(-7/8*var(--spinner-animation-duration));transform:rotate(45deg)}.spinner__leaf-xtOJmT:where(:nth-child(3)){animation-delay:calc(-6/8*var(--spinner-animation-duration));transform:rotate(90deg)}.spinner__leaf-xtOJmT:where(:nth-child(4)){animation-delay:calc(-5/8*var(--spinner-animation-duration));transform:rotate(135deg)}.spinner__leaf-xtOJmT:where(:nth-child(5)){animation-delay:calc(-4/8*var(--spinner-animation-duration));transform:rotate(180deg)}.spinner__leaf-xtOJmT:where(:nth-child(6)){animation-delay:calc(-3/8*var(--spinner-animation-duration));transform:rotate(225deg)}.spinner__leaf-xtOJmT:where(:nth-child(7)){animation-delay:calc(-2/8*var(--spinner-animation-duration));transform:rotate(270deg)}.spinner__leaf-xtOJmT:where(:nth-child(8)){animation-delay:calc(-1/8*var(--spinner-animation-duration));transform:rotate(315deg)}@keyframes rt-spinner-leaf-fade-OXYBVY{0%{opacity:1}to{opacity:.25}}.buttonShare-F23Y9m{justify-content:center;align-items:center;gap:10px;display:flex}
1
+ .nOB7Uq_buttonShare{justify-content:center;align-items:center;gap:10px;display:flex}
@@ -1,85 +1,103 @@
1
- import type { FullInteractionTypesKey } from '@frak-labs/core-sdk';
2
- import { JSX } from 'preact';
3
-
4
- /**
5
- * Button to share the current page
6
- *
7
- * @param args
8
- * @returns The share button with `<button>` tag
9
- *
10
- * @group components
11
- *
12
- * @example
13
- * Basic usage:
14
- * ```html
15
- * <frak-button-share></frak-button-share>
16
- * ```
17
- *
18
- * @example
19
- * Using a custom text:
20
- * ```html
21
- * <frak-button-share text="Share and earn!"></frak-button-share>
22
- * ```
23
- *
24
- * @example
25
- * Using a custom class:
26
- * ```html
27
- * <frak-button-share classname="button button-primary"></frak-button-share>
28
- * ```
29
- *
30
- * @example
31
- * Using reward information and fallback text:
32
- * ```html
33
- * <frak-button-share use-reward text="Share and earn up to {REWARD}!" no-reward-text="Share and earn!"></frak-button-share>
34
- * ```
35
- *
36
- * @example
37
- * Using reward information for specific reward and fallback text:
38
- * ```html
39
- * <frak-button-share use-reward text="Share and earn up to {REWARD}!" no-reward-text="Share and earn!" target-interaction="retail.customerMeeting"></frak-button-share>
40
- * ```
41
- *
42
- * @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
43
- * @see {@link @frak-labs/core-sdk!actions.getProductInformation | `getProductInformation()`} for more info about the estimated reward fetching
44
- */
45
- export declare function ButtonShare({ text, classname, useReward: rawUseReward, noRewardText, targetInteraction, showWallet: rawShowWallet, }: ButtonShareProps): JSX.Element;
46
-
47
- export declare interface ButtonShareElement extends HTMLElement, ButtonShareProps {
48
- }
49
-
50
- /**
51
- * The props type for {@link ButtonShare}.
52
- * @inline
53
- */
54
- declare type ButtonShareProps = {
55
- /**
56
- * Text to display on the button
57
- * - To specify where the reward should be displayed, use the placeholder `{REWARD}`, e.g. `Share and earn up to {REWARD}!`
58
- * @defaultValue `"Share and earn!"`
59
- */
60
- text?: string;
61
- /**
62
- * Classname to apply to the button
63
- */
64
- classname?: string;
65
- /**
66
- * Do we display the reward on the share modal?
67
- * @defaultValue `false`
68
- */
69
- useReward?: boolean;
70
- /**
71
- * Fallback text if the reward isn't found
72
- */
73
- noRewardText?: string;
74
- /**
75
- * Target interaction behind this sharing action (will be used to get the right reward to display)
76
- */
77
- targetInteraction?: FullInteractionTypesKey;
78
- /**
79
- * Do we display the wallet modal instead of the share modal?
80
- * @defaultValue `false`
81
- */
82
- showWallet?: boolean;
83
- };
84
-
85
- export { }
1
+ import { InteractionTypeKey } from "@frak-labs/core-sdk";
2
+ import * as preact from "preact";
3
+
4
+ //#region src/components/ButtonShare/types.d.ts
5
+ /**
6
+ * The props type for {@link ButtonShare}.
7
+ * @inline
8
+ */
9
+ type ButtonShareProps = {
10
+ /**
11
+ * Text to display on the button
12
+ * - To specify where the reward should be displayed, use the placeholder `{REWARD}`, e.g. `Share and earn up to \{REWARD\}!`
13
+ * @defaultValue `"Share and earn!"`
14
+ */
15
+ text?: string;
16
+ /**
17
+ * Classname to apply to the button
18
+ */
19
+ classname?: string;
20
+ /**
21
+ * Do we display the reward on the share modal?
22
+ * @defaultValue `false`
23
+ */
24
+ useReward?: boolean;
25
+ /**
26
+ * Fallback text if the reward isn't found
27
+ */
28
+ noRewardText?: string;
29
+ /**
30
+ * Target interaction behind this sharing action (will be used to get the right reward to display)
31
+ */
32
+ targetInteraction?: InteractionTypeKey;
33
+ /**
34
+ * Do we display the wallet modal instead of the share modal?
35
+ * @defaultValue `false`
36
+ */
37
+ showWallet?: boolean;
38
+ };
39
+ //#endregion
40
+ //#region src/components/ButtonShare/ButtonShare.d.ts
41
+ /**
42
+ * Button to share the current page
43
+ *
44
+ * @param args
45
+ * @returns The share button with `<button>` tag
46
+ *
47
+ * @group components
48
+ *
49
+ * @example
50
+ * Basic usage:
51
+ * ```html
52
+ * <frak-button-share></frak-button-share>
53
+ * ```
54
+ *
55
+ * @example
56
+ * Using a custom text:
57
+ * ```html
58
+ * <frak-button-share text="Share and earn!"></frak-button-share>
59
+ * ```
60
+ *
61
+ * @example
62
+ * Using a custom class:
63
+ * ```html
64
+ * <frak-button-share classname="button button-primary"></frak-button-share>
65
+ * ```
66
+ *
67
+ * @example
68
+ * Using reward information and fallback text:
69
+ * ```html
70
+ * <frak-button-share use-reward text="Share and earn up to {REWARD}!" no-reward-text="Share and earn!"></frak-button-share>
71
+ * ```
72
+ *
73
+ * @example
74
+ * Using reward information for specific reward and fallback text:
75
+ * ```html
76
+ * <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>
77
+ * ```
78
+ *
79
+ * @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
80
+ * @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
81
+ */
82
+ declare function ButtonShare({
83
+ text,
84
+ classname,
85
+ useReward: rawUseReward,
86
+ noRewardText,
87
+ targetInteraction,
88
+ showWallet: rawShowWallet
89
+ }: ButtonShareProps): preact.JSX.Element;
90
+ //#endregion
91
+ //#region src/components/ButtonShare/index.d.ts
92
+ /**
93
+ * Custom element interface for `<frak-button-share>`.
94
+ * Combines standard {@link HTMLElement} with {@link ButtonShareProps}.
95
+ */
96
+ interface ButtonShareElement extends HTMLElement, ButtonShareProps {}
97
+ declare global {
98
+ interface HTMLElementTagNameMap {
99
+ "frak-button-share": ButtonShareElement;
100
+ }
101
+ }
102
+ //#endregion
103
+ export { ButtonShare, ButtonShareElement };
@@ -1 +1,311 @@
1
- import e from"preact-custom-element";import{DebugInfoGatherer as t,formatAmount as n,getCurrencyAmountKey as o,setupClient as r,trackEvent as a}from"@frak-labs/core-sdk";import{displayEmbeddedWallet as i,getProductInformation as l,modalBuilder as d,referralInteraction as s}from"@frak-labs/core-sdk/actions";import{Fragment as c,jsx as u,jsxs as p}from"preact/jsx-runtime";import{cx as f}from"class-variance-authority";import{useCallback as m,useEffect as w,useMemo as g,useState as k}from"preact/hooks";import{FrakRpcError as h,RpcErrorCodes as S}from"@frak-labs/frame-connector";import*as y from"@frak-labs/core-sdk/bundle";let b="frakClientReady";function F(e,t){if(window.FrakSetup?.client&&"add"===e)return void t();("add"===e?window.addEventListener:window.removeEventListener)(b,t,!1)}async function v(e){console.log("referral",await s(e,{modalConfig:window.FrakSetup?.modalWalletConfig}))}async function x(){if(window.FrakSetup.core=y,!(window.frakSetupInProgress?(console.log("[Frak SDK] Initialization already in progress"),!1):window.FrakSetup?.client?(console.log("[Frak SDK] Client already initialized"),!1):!!window.FrakSetup?.config||(console.error("[Frak SDK] Configuration not found. Please ensure window.FrakSetup.config is set."),!1)))return;if(console.log("[Frak SDK] Starting initialization"),window.frakSetupInProgress=!0,!window.FrakSetup.config){console.error("[Frak SDK] Configuration not found"),window.frakSetupInProgress=!1;return}let e=await r({config:window.FrakSetup.config});if(!e){console.error("[Frak SDK] Failed to create client"),window.frakSetupInProgress=!1;return}window.FrakSetup.client=e,console.log("[Frak SDK] Client initialized successfully");let t=new CustomEvent(b);window.dispatchEvent(t),window.modalBuilderSteps=d(e,window.FrakSetup?.modalConfig??{}),v(e),window.frakSetupInProgress=!1,function(){let e=new URLSearchParams(window.location.search).get("frakAction");e&&"share"===e&&(console.log("[Frak SDK] Auto open query param found"),function(){if(!window.FrakSetup?.client)return console.error("Frak client not found");"vibrate"in navigator?navigator.vibrate(10):console.log("Vibration not supported"),i(window.FrakSetup.client,window.FrakSetup?.modalWalletConfig??{})}())}()}let C="spinner__leaf-xtOJmT",D=({ref:e,className:t,...n})=>p("span",{...n,ref:e,className:f("spinner-KHk8mw"),children:[u("span",{className:C}),u("span",{className:C}),u("span",{className:C}),u("span",{className:C}),u("span",{className:C}),u("span",{className:C}),u("span",{className:C}),u("span",{className:C})]});async function E({targetInteraction:e}){let t=window.FrakSetup?.client;if(!t)return void console.warn("Frak client not ready yet");let{maxReferrer:r,rewards:a}=await l(t);if(!r)return;let i=o(t.config.metadata?.currency),d=Math.round(r[i]);if(e){let t=a.filter(t=>t.interactionTypeKey===e).map(e=>e.referrer[i]).reduce((e,t)=>t>e?t:e,0);t>0&&(d=Math.round(t))}return n(d,t.config.metadata?.currency)}D.displayName="Spinner";let I={marginTop:"16px",padding:"16px",backgroundColor:"#FEE2E2",border:"1px solid #FCA5A5",borderRadius:"4px",color:"#991B1B"},B={display:"flex",alignItems:"center",gap:"8px",marginBottom:"12px"},N={margin:0,fontSize:"16px",fontWeight:500},R={fontSize:"14px",lineHeight:"1.5",margin:"0 0 12px 0"},z={color:"#991B1B",textDecoration:"underline",textUnderlineOffset:"2px"},K={display:"inline-flex",alignItems:"center",gap:"8px",marginBottom:"10px",padding:"8px 12px",backgroundColor:"white",border:"1px solid #D1D5DB",borderRadius:"4px",color:"black",fontSize:"14px",fontWeight:500};function W({debugInfo:e}){let[t,n]=k(!1);return p("div",{children:[u("button",{type:"button",style:K,onClick:()=>n(!t),children:"Ouvrir les informations"}),t&&u("textarea",{style:{display:"block",width:"100%",height:"200px",fontSize:"12px"},children:e})]})}function A({debugInfo:e}){let{copied:t,copy:n}=function(e={}){let{successDuration:t=2e3}=e,[n,o]=k(!1);return{copy:m(async e=>{try{if(navigator.clipboard&&window.isSecureContext)await navigator.clipboard.writeText(e),o(!0);else{let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy"),o(!0)}catch(e){return console.error("Failed to copy text:",e),!1}finally{t.remove()}}return setTimeout(()=>{o(!1)},t),!0}catch(e){return console.error("Failed to copy text:",e),!1}},[t]),copied:n}}();return p("div",{style:I,children:[u("div",{style:B,children:u("h3",{style:N,children:"Oups ! Nous avons rencontr\xe9 un petit probl\xe8me"})}),p("p",{style:R,children:["Impossible d'ouvrir le menu de partage pour le moment. Si le probl\xe8me persiste, copiez les informations ci-dessous et collez-les dans votre mail \xe0"," ",u("a",{href:"mailto:help@frak-labs.com?subject=Debug",style:z,children:"help@frak-labs.com"})," ",u("br",{}),"Merci pour votre retour, nous traitons votre demande dans les plus brefs d\xe9lais."]}),u("button",{type:"button",onClick:()=>n(e??""),style:K,children:t?"Informations copi\xe9es !":"Copier les informations de d\xe9bogage"}),u(W,{debugInfo:e})]})}async function P(){if(!window.FrakSetup?.client)throw Error("Frak client not found");await i(window.FrakSetup.client,window.FrakSetup?.modalWalletConfig??{})}function L({text:e="Share and earn!",classname:n="",useReward:o,noRewardText:r,targetInteraction:i,showWallet:l}){let d=g(()=>void 0!==o,[o]),s=g(()=>void 0!==l,[l]),{isClientReady:y}=function(){let[e,t]=k(!0),n=m(()=>{t(!1)},[]);return w(()=>(F("add",n),()=>F("remove",n)),[n]),{isClientReady:!e}}(),{reward:b}=function(e,t){let[n,o]=k(void 0);return w(()=>{e&&E({targetInteraction:t}).then(e=>{e&&o(e)})},[e,t]),{reward:n}}(d&&y,i),{handleShare:v,isError:x,debugInfo:C}=function(e){let[n,o]=k(void 0),[r,i]=k(!1);return{handleShare:m(async()=>{if(!window.FrakSetup?.client){console.error("Frak client not found"),o(t.empty().formatDebugInfo("Frak client not found")),i(!0);return}let n=function(){if(!window.modalBuilderSteps)throw Error("modalBuilderSteps not found");return window.modalBuilderSteps}();if(!n)throw Error("modalBuilderSteps not found");try{await n.sharing(window.FrakSetup?.modalShareConfig??{}).display(t=>({...t,targetInteraction:e}))}catch(t){if(t instanceof h&&t.code===S.clientAborted)return void console.debug("User aborted the modal");let e=window.FrakSetup.client.debugInfo.formatDebugInfo(t);a(window.FrakSetup.client,"share_modal_error",{error:t instanceof Object&&"message"in t?t.message:"Unknown error",debugInfo:e}),o(e),i(!0),console.error("Error while opening the modal",t)}},[e]),isError:r,debugInfo:n}}(i),I=g(()=>d?b?e.includes("{REWARD}")?e.replace("{REWARD}",b):`${e} ${b}`:r??e.replace("{REWARD}",""):e,[d,e,r,b]),B=m(async()=>{a(window.FrakSetup.client,"share_button_clicked"),s?await P():await v()},[s,v]);return p(c,{children:[p("button",{type:"button",className:f("buttonShare-F23Y9m",n,"override"),onClick:B,children:[!y&&u(D,{})," ",I]}),x&&u(A,{debugInfo:C})]})}!function(t,n,o=[],r={shadow:!1}){"undefined"!=typeof window&&("complete"===document.readyState||"interactive"===document.readyState?setTimeout(x,1):document.addEventListener?document.addEventListener("DOMContentLoaded",x):document.attachEvent("onreadystatechange",()=>{"complete"===document.readyState&&x()}),customElements.get(n)||e(t,n,o,r))}(L,"frak-button-share",["text"],{shadow:!1});export{L as ButtonShare};
1
+ import { n as registerWebComponent, r as getModalBuilderSteps, t as useClientReady } from "./useClientReady-iCtUeDsc.js";
2
+ import { t as Spinner } from "./Spinner-CO7JOohC.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";
7
+ import { useCallback, useMemo, useState } from "preact/hooks";
8
+ import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
9
+ import { FrakRpcError, RpcErrorCodes } from "@frak-labs/frame-connector";
10
+
11
+ //#region src/components/ButtonShare/ButtonShare.module.css?css_module
12
+ const classes = { "buttonShare": "nOB7Uq_buttonShare" };
13
+ const _buttonShare0 = classes["buttonShare"];
14
+
15
+ //#endregion
16
+ //#region src/hooks/useCopyToClipboard.ts
17
+ function useCopyToClipboard(options = {}) {
18
+ const { successDuration = 2e3 } = options;
19
+ const [copied, setCopied] = useState(false);
20
+ return {
21
+ copy: useCallback(async (text) => {
22
+ try {
23
+ if (navigator.clipboard && window.isSecureContext) {
24
+ await navigator.clipboard.writeText(text);
25
+ setCopied(true);
26
+ } else {
27
+ const textArea = document.createElement("textarea");
28
+ textArea.value = text;
29
+ textArea.style.position = "fixed";
30
+ textArea.style.opacity = "0";
31
+ document.body.appendChild(textArea);
32
+ textArea.focus();
33
+ textArea.select();
34
+ try {
35
+ document.execCommand("copy");
36
+ setCopied(true);
37
+ } catch (err) {
38
+ console.error("Failed to copy text:", err);
39
+ return false;
40
+ } finally {
41
+ textArea.remove();
42
+ }
43
+ }
44
+ setTimeout(() => {
45
+ setCopied(false);
46
+ }, successDuration);
47
+ return true;
48
+ } catch (err) {
49
+ console.error("Failed to copy text:", err);
50
+ return false;
51
+ }
52
+ }, [successDuration]),
53
+ copied
54
+ };
55
+ }
56
+
57
+ //#endregion
58
+ //#region src/components/ButtonShare/components/ErrorMessage.tsx
59
+ const styles = {
60
+ errorContainer: {
61
+ marginTop: "16px",
62
+ padding: "16px",
63
+ backgroundColor: "#FEE2E2",
64
+ border: "1px solid #FCA5A5",
65
+ borderRadius: "4px",
66
+ color: "#991B1B"
67
+ },
68
+ header: {
69
+ display: "flex",
70
+ alignItems: "center",
71
+ gap: "8px",
72
+ marginBottom: "12px"
73
+ },
74
+ title: {
75
+ margin: 0,
76
+ fontSize: "16px",
77
+ fontWeight: 500
78
+ },
79
+ message: {
80
+ fontSize: "14px",
81
+ lineHeight: "1.5",
82
+ margin: "0 0 12px 0"
83
+ },
84
+ link: {
85
+ color: "#991B1B",
86
+ textDecoration: "underline",
87
+ textUnderlineOffset: "2px"
88
+ },
89
+ copyButton: {
90
+ display: "inline-flex",
91
+ alignItems: "center",
92
+ gap: "8px",
93
+ marginBottom: "10px",
94
+ padding: "8px 12px",
95
+ backgroundColor: "white",
96
+ border: "1px solid #D1D5DB",
97
+ borderRadius: "4px",
98
+ color: "black",
99
+ fontSize: "14px",
100
+ fontWeight: 500
101
+ }
102
+ };
103
+ /**
104
+ * Renders a toggleable debug information section
105
+ * @param {Object} props - Component props
106
+ * @param {string} [props.debugInfo] - Debug information to display in textarea
107
+ */
108
+ function ToggleMessage({ debugInfo }) {
109
+ const [showInfo, setShowInfo] = useState(false);
110
+ return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("button", {
111
+ type: "button",
112
+ style: styles.copyButton,
113
+ onClick: () => setShowInfo(!showInfo),
114
+ children: "Ouvrir les informations"
115
+ }), showInfo && /* @__PURE__ */ jsx("textarea", {
116
+ style: {
117
+ display: "block",
118
+ width: "100%",
119
+ height: "200px",
120
+ fontSize: "12px"
121
+ },
122
+ children: debugInfo
123
+ })] });
124
+ }
125
+ /**
126
+ * Displays an error message with debug information and copy functionality
127
+ * @param {Object} props - Component props
128
+ * @param {string} [props.debugInfo] - Debug information that can be copied or displayed
129
+ */
130
+ function ErrorMessage({ debugInfo }) {
131
+ const { copied, copy } = useCopyToClipboard();
132
+ return /* @__PURE__ */ jsxs("div", {
133
+ style: styles.errorContainer,
134
+ children: [
135
+ /* @__PURE__ */ jsx("div", {
136
+ style: styles.header,
137
+ children: /* @__PURE__ */ jsx("h3", {
138
+ style: styles.title,
139
+ children: "Oups ! Nous avons rencontré un petit problème"
140
+ })
141
+ }),
142
+ /* @__PURE__ */ jsxs("p", {
143
+ style: styles.message,
144
+ children: [
145
+ "Impossible d'ouvrir le menu de partage pour le moment. Si le problème persiste, copiez les informations ci-dessous et collez-les dans votre mail à",
146
+ " ",
147
+ /* @__PURE__ */ jsx("a", {
148
+ href: "mailto:help@frak-labs.com?subject=Debug",
149
+ style: styles.link,
150
+ children: "help@frak-labs.com"
151
+ }),
152
+ " ",
153
+ /* @__PURE__ */ jsx("br", {}),
154
+ "Merci pour votre retour, nous traitons votre demande dans les plus brefs délais."
155
+ ]
156
+ }),
157
+ /* @__PURE__ */ jsx("button", {
158
+ type: "button",
159
+ onClick: () => copy(debugInfo ?? ""),
160
+ style: styles.copyButton,
161
+ children: copied ? "Informations copiées !" : "Copier les informations de débogage"
162
+ }),
163
+ /* @__PURE__ */ jsx(ToggleMessage, { debugInfo })
164
+ ]
165
+ });
166
+ }
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
+ //#endregion
215
+ //#region src/components/ButtonShare/ButtonShare.tsx
216
+ /**
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
+ * Button to share the current page
228
+ *
229
+ * @param args
230
+ * @returns The share button with `<button>` tag
231
+ *
232
+ * @group components
233
+ *
234
+ * @example
235
+ * Basic usage:
236
+ * ```html
237
+ * <frak-button-share></frak-button-share>
238
+ * ```
239
+ *
240
+ * @example
241
+ * Using a custom text:
242
+ * ```html
243
+ * <frak-button-share text="Share and earn!"></frak-button-share>
244
+ * ```
245
+ *
246
+ * @example
247
+ * Using a custom class:
248
+ * ```html
249
+ * <frak-button-share classname="button button-primary"></frak-button-share>
250
+ * ```
251
+ *
252
+ * @example
253
+ * Using reward information and fallback text:
254
+ * ```html
255
+ * <frak-button-share use-reward text="Share and earn up to {REWARD}!" no-reward-text="Share and earn!"></frak-button-share>
256
+ * ```
257
+ *
258
+ * @example
259
+ * Using reward information for specific reward and fallback text:
260
+ * ```html
261
+ * <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>
262
+ * ```
263
+ *
264
+ * @see {@link @frak-labs/core-sdk!actions.modalBuilder | `modalBuilder()`} for more info about the modal display
265
+ * @see {@link @frak-labs/core-sdk!actions.getMerchantInformation | `getMerchantInformation()`} for more info about the estimated reward fetching
266
+ */
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
+ */
276
+ 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}`;
280
+ }, [
281
+ shouldUseReward,
282
+ text,
283
+ noRewardText,
284
+ reward
285
+ ]);
286
+ /**
287
+ * The action when the button is clicked
288
+ */
289
+ const onClick = useCallback(async () => {
290
+ 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", {
295
+ type: "button",
296
+ className: cx(classes.buttonShare, classname, "override"),
297
+ onClick,
298
+ children: [
299
+ !isClientReady && /* @__PURE__ */ jsx(Spinner, {}),
300
+ " ",
301
+ btnText
302
+ ]
303
+ }), isError && /* @__PURE__ */ jsx(ErrorMessage, { debugInfo })] });
304
+ }
305
+
306
+ //#endregion
307
+ //#region src/components/ButtonShare/index.ts
308
+ registerWebComponent(ButtonShare, "frak-button-share", ["text"], { shadow: false });
309
+
310
+ //#endregion
311
+ export { ButtonShare };
@@ -1 +1 @@
1
- .button-aPZnsb{all:unset;z-index:2000000;cursor:pointer;text-align:center;background-color:#3e557e;border-radius:50%;justify-content:center;align-items:center;width:45px;height:45px;font-size:24px;display:flex;position:fixed;bottom:20px}.button__left-fQJUnK{left:20px}.button__right-TkFFFK{right:20px}.reward-w5dm3K{color:#fff;white-space:nowrap;background:#ff3f3f;border-radius:5px;padding:2px 3px;font-size:9px;font-weight:600;line-height:9px;position:absolute;top:-4px;right:27px}
1
+ .Kl62ia_button{all:unset;z-index:2000000;cursor:pointer;text-align:center;background-color:#3e557e;border-radius:50%;justify-content:center;align-items:center;width:45px;height:45px;font-size:24px;display:flex;position:fixed;bottom:20px}.Kl62ia_button__left{left:20px}.Kl62ia_button__right{right:20px}.Kl62ia_reward{color:#fff;white-space:nowrap;background:#ff3f3f;border-radius:5px;padding:2px 3px;font-size:9px;font-weight:600;line-height:9px;position:absolute;top:-4px;right:27px}