diff --git a/.changeset/orange-cars-worry.md b/.changeset/orange-cars-worry.md new file mode 100644 index 000000000..d2c5b90c4 --- /dev/null +++ b/.changeset/orange-cars-worry.md @@ -0,0 +1,5 @@ +--- +"@frak-labs/nexus-sdk": patch +--- + +Add a `modalBuilder` to ease modal creation diff --git a/example/vanilla-js/src/main.ts b/example/vanilla-js/src/main.ts index 6b9b0d3fb..3024997ec 100644 --- a/example/vanilla-js/src/main.ts +++ b/example/vanilla-js/src/main.ts @@ -5,7 +5,12 @@ import { setupFrakClient } from "./module/setupClient"; import { displayWalletStatus } from "./module/walletStatus"; // Export the setup function and config for use in other files -window.FrakSetup = { frakConfig, frakClient: null, modalShare }; +window.FrakSetup = { + frakConfig, + frakClient: null, + modalShare, + modalBuilder: null, +}; document.addEventListener("DOMContentLoaded", () => { console.log("NexusSDK", window.NexusSDK); @@ -16,22 +21,19 @@ document.addEventListener("DOMContentLoaded", () => { return; } + const modalStepBuilder = window.NexusSDK.modalBuilder(frakClient, { + metadata: { + lang: "fr", + isDismissible: true, + }, + login: loginModalStep, + }); + window.FrakSetup.frakClient = frakClient; + window.FrakSetup.modalBuilder = modalStepBuilder; window.NexusSDK.referralInteraction(frakClient, { - modalConfig: { - steps: { - login: loginModalStep, - openSession: {}, - final: { - action: { key: "reward" }, - }, - }, - metadata: { - lang: "fr", - isDismissible: true, - }, - }, + modalConfig: modalStepBuilder.reward().params, options: { alwaysAppendUrl: true, }, diff --git a/example/vanilla-js/src/module/login.ts b/example/vanilla-js/src/module/login.ts index 2cd412b56..528ac852d 100644 --- a/example/vanilla-js/src/module/login.ts +++ b/example/vanilla-js/src/module/login.ts @@ -1,5 +1,3 @@ -import { loginModalStep } from "./config"; - export function bindLoginButton() { const loginButton = document.getElementById("login-button"); loginButton?.addEventListener("click", handleLogin); @@ -19,20 +17,11 @@ async function handleLogin() { loginButton.textContent = "Logging in..."; try { - if (!window.FrakSetup.frakClient) { + if (!window.FrakSetup.modalBuilder) { console.error("Frak client not initialized"); return; } - await window.NexusSDK.displayModal(window.FrakSetup.frakClient, { - metadata: { - lang: "fr", - isDismissible: true, - }, - steps: { - login: loginModalStep, - openSession: {}, - }, - }); + await window.FrakSetup.modalBuilder.display(); loginButton.textContent = "Logged In"; } catch (error) { console.error("Login error:", error); diff --git a/example/vanilla-js/src/module/modalShare.ts b/example/vanilla-js/src/module/modalShare.ts index e10d7d07f..a052cb6f0 100644 --- a/example/vanilla-js/src/module/modalShare.ts +++ b/example/vanilla-js/src/module/modalShare.ts @@ -1,29 +1,13 @@ -import { loginModalStep } from "./config"; - export function modalShare() { - const finalAction = { - key: "sharing", - options: { - popupTitle: "Share this article with your friends", - text: "Discover this awesome article", - link: typeof window !== "undefined" ? window.location.href : "", - }, - } as const; - if (!window.FrakSetup.frakClient) { + if (!window.FrakSetup.modalBuilder) { console.error("Frak client not initialized"); return; } - window.NexusSDK.displayModal(window.FrakSetup.frakClient, { - metadata: { - lang: "fr", - isDismissible: true, - }, - steps: { - login: loginModalStep, - openSession: {}, - final: { - action: finalAction, - }, - }, - }); + window.FrakSetup.modalBuilder + .sharing({ + popupTitle: "Share this article with your friends", + text: "Discover this awesome article", + link: typeof window !== "undefined" ? window.location.href : "", + }) + .display(); } diff --git a/example/vanilla-js/src/types/globals.d.ts b/example/vanilla-js/src/types/globals.d.ts index 223bb351a..949b71050 100644 --- a/example/vanilla-js/src/types/globals.d.ts +++ b/example/vanilla-js/src/types/globals.d.ts @@ -1,5 +1,7 @@ import type { + ModalBuilder, displayModal, + modalBuilder, referralInteraction, watchWalletStatus, } from "@frak-labs/nexus-sdk/actions"; @@ -18,11 +20,13 @@ declare global { displayModal: typeof displayModal; referralInteraction: typeof referralInteraction; watchWalletStatus: typeof watchWalletStatus; + modalBuilder: typeof modalBuilder; }; FrakSetup: { frakConfig: NexusWalletSdkConfig; frakClient: NexusClient | null; modalShare: () => void; + modalBuilder: ModalBuilder | null; }; } } diff --git a/packages/sdk/src/core/actions/index.ts b/packages/sdk/src/core/actions/index.ts index 622be228a..2264fa240 100644 --- a/packages/sdk/src/core/actions/index.ts +++ b/packages/sdk/src/core/actions/index.ts @@ -13,7 +13,11 @@ export { sendTransaction, type SendTransactionParams, } from "./wrapper/sendTransaction"; -export { modalBuilder } from "./wrapper/modalBuilder"; +export { + modalBuilder, + type ModalStepBuilder, + type ModalBuilder, +} from "./wrapper/modalBuilder"; // Referral interaction export { referralInteraction } from "./referral/referralInteraction"; export { processReferral } from "./referral/processReferral"; diff --git a/packages/sdk/src/core/actions/wrapper/modalBuilder.ts b/packages/sdk/src/core/actions/wrapper/modalBuilder.ts index 7986f57b9..7caf50cc1 100644 --- a/packages/sdk/src/core/actions/wrapper/modalBuilder.ts +++ b/packages/sdk/src/core/actions/wrapper/modalBuilder.ts @@ -12,6 +12,36 @@ import type { } from "../../types"; import { displayModal } from "../displayModal"; +/** + * Represent the type of the modal step builder + */ +export type ModalStepBuilder< + Steps extends ModalStepTypes[] = ModalStepTypes[], +> = { + params: DisplayModalParamsType; + sendTx: ( + options: SendTransactionModalStepType["params"] + ) => ModalStepBuilder<[...Steps, SendTransactionModalStepType]>; + reward: ( + options?: Omit + ) => ModalStepBuilder<[...Steps, FinalModalStepType]>; + sharing: ( + sharingOptions?: Extract< + FinalActionType, + { key: "sharing" } + >["options"], + options?: Omit + ) => ModalStepBuilder<[...Steps, FinalModalStepType]>; + display: () => Promise>; +}; + +/** + * Represent the output type of the modal builder + */ +export type ModalBuilder = ModalStepBuilder< + [LoginModalStepType, OpenInteractionSessionModalStepType] +>; + /** * Simple modal builder params builder * @param client @@ -30,7 +60,7 @@ export function modalBuilder( login?: LoginModalStepType["params"]; openSession?: OpenInteractionSessionModalStepType["params"]; } -): ModalStepBuilder<[LoginModalStepType, OpenInteractionSessionModalStepType]> { +): ModalBuilder { // Build the initial modal params const baseParams: DisplayModalParamsType< [LoginModalStepType, OpenInteractionSessionModalStepType] @@ -46,27 +76,6 @@ export function modalBuilder( return modalStepsBuilder(client, baseParams); } -/** - * Represent the type of the modal step builder - */ -type ModalStepBuilder = { - params: DisplayModalParamsType; - sendTx: ( - options: SendTransactionModalStepType["params"] - ) => ModalStepBuilder<[...Steps, SendTransactionModalStepType]>; - reward: ( - options?: Omit - ) => ModalStepBuilder<[...Steps, FinalModalStepType]>; - sharing: ( - sharingOptions?: Extract< - FinalActionType, - { key: "sharing" } - >["options"], - options?: Omit - ) => ModalStepBuilder<[...Steps, FinalModalStepType]>; - display: () => Promise>; -}; - /** * Build builder helping to add steps to the modal * @param client