@benji-money/connect-sdk 1.1.0-beta.1 → 1.1.0-beta.3

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/README.md CHANGED
@@ -86,10 +86,93 @@ The SDK accepts the following configuration options:
86
86
 
87
87
  - `environment` (required): One of `local`, `development`, `sandbox`, or `production`
88
88
  - `token` (required): Your API connect token
89
+ - `mode` (optional): `BenjiConnectMode` — `CONNECT` (default), `TRANSFER`, `REDEEM`, or `LOGIN`
90
+ - `authType` (optional): `PartnerIntegrationType` — LOGIN only; omit or set `DUMMY` for the visible modal iframe; set to your partner type (1–6) for popup-only auth
89
91
  - `onSuccess` (optional): Callback function called when connect completed successfully
90
92
  - `onError` (optional): Callback function called when error occurs in the connect flow
91
93
  - `onExit` (optional): Callback function called when the user exits the connect flow
92
94
  - `onEvent` (optional): Callback function for handling various events
95
+ - `anchor` (optional): Live anchor binding — `HTMLElement`, CSS selector, getter `() => HTMLElement | null`, or ref `{ value: HTMLElement | null }`. Re-resolved on every layout pass. Falls back to centered when missing or invalid. See [Placement](#placement)
96
+ - `placement` (optional): Placement relative to `anchor` — see [Placement](#placement) below
97
+ - `offset` (optional): Pixel gap after placement — `{ top?: number; left?: number }` (default `{ top: 0, left: 0 }`)
98
+
99
+ ### Modes
100
+
101
+ | Mode | Visible UX | Notes |
102
+ | ---- | ---------- | ----- |
103
+ | **CONNECT** (default) | Centered or anchored modal iframe | No `authType`; standard connect / verify flow |
104
+ | **LOGIN + DUMMY / no `authType`** | Same visible modal iframe | Partner auth runs in a nested iframe inside Benji Connect |
105
+ | **LOGIN + non-DUMMY** | Partner popup only | Pass `authType`; Benji Connect iframe is headless — see [LOGIN popup example](#login-popup-example) below |
106
+
107
+ ### Placement
108
+
109
+ Placement uses [Floating UI](https://floating-ui.com/docs/computePosition#placement) / CSS logical naming (`start` / `end`). In **LTR** layouts:
110
+
111
+ | Value | Meaning |
112
+ | ----- | ------- |
113
+ | `center` (default) | Full-viewport backdrop with iframe centered |
114
+ | `bottom-end` | Below the anchor, right edge aligned with anchor's right edge |
115
+ | `bottom-start` | Below the anchor, left edge aligned with anchor's left edge |
116
+
117
+ **What `anchor` positions:**
118
+
119
+ - **CONNECT, TRANSFER, REDEEM, and LOGIN + DUMMY:** the modal iframe
120
+ - **LOGIN + non-DUMMY:** the partner-auth popup window (modal iframe stays headless)
121
+
122
+ **Defaults:**
123
+
124
+ - No `anchor` → centered modal (unchanged behavior for existing integrations)
125
+ - `anchor` set, no `placement` → `bottom-end`
126
+ - If the anchor is missing or invalid on **initial open**, there is not enough viewport space below, or the viewport is narrower than the iframe (400px + padding), the SDK falls back to centered
127
+ - While the modal is **already open**, a temporarily hidden or detached anchor (e.g. crossing a responsive layout breakpoint) keeps the last anchored position instead of jumping to center; when the anchor becomes visible again, placement re-anchors automatically
128
+
129
+ **Live anchor bindings** (re-resolved on scroll, resize, and visual viewport changes):
130
+
131
+ | Form | Example | When to use |
132
+ | ---- | ------- | ----------- |
133
+ | CSS selector | `'#login-btn'` | Stable id on the anchor element |
134
+ | Ref object | `loginButtonRef` (Vue `{ value: el }`) | Anchor may re-render after async work |
135
+ | Getter | `() => document.querySelector('#login-btn')` | Custom lookup |
136
+ | `HTMLElement` | Snapshot at click time | Only when the node will not be replaced before `open()` |
137
+
138
+ Prefer selector, ref, or getter when the anchor can re-render (e.g. disabled/loading state) before the modal opens. A stale `HTMLElement` snapshot falls back to a centered modal on open instead of clipping to the top-left; while open, resize across breakpoints preserves the last anchored position until the anchor is visible again or the modal is closed.
139
+
140
+ **Viewport sizing:**
141
+
142
+ - Design size is **400×645** px (`IFRAME_WIDTH` / `IFRAME_HEIGHT`)
143
+ - **Centered** modals (default, explicit, or fallback) scale down proportionally when the viewport is smaller than the design size so the modal fits with 8px padding on each side
144
+ - **Anchored** popovers use the full design size when width and height checks pass; otherwise they fall back to a scaled centered modal
145
+ - Scroll, resize, and visual viewport changes while open recompute placement and size
146
+
147
+ #### LOGIN popup example
148
+
149
+ Popup below a top-right login button; pass `authType` for non-DUMMY partners:
150
+
151
+ ```typescript
152
+ import {
153
+ ConnectSDK,
154
+ BenjiConnectMode,
155
+ BenjiConnectPlacement,
156
+ PartnerIntegrationType,
157
+ } from "@benji-money/connect-sdk";
158
+
159
+ const sdk = new ConnectSDK({
160
+ environment: "sandbox",
161
+ token: connectToken,
162
+ mode: BenjiConnectMode.LOGIN,
163
+ authType: PartnerIntegrationType.OAUTH_PKCE,
164
+ anchor: "#login-btn",
165
+ placement: BenjiConnectPlacement.BOTTOM_END,
166
+ offset: { top: 8 },
167
+ onSuccess: (token) => { /* ... */ },
168
+ onError: (error) => { /* popup blocked, etc. */ },
169
+ onExit: (metadata) => { /* POPUP_CLOSED when user dismisses popup */ },
170
+ });
171
+
172
+ await sdk.open();
173
+ ```
174
+
175
+ > **`bottom-end`** positions the **partner popup** below the anchor with its right edge aligned to the anchor's right edge. The Benji Connect iframe stays headless (not visible).
93
176
 
94
177
  ### Environments
95
178