@parafin/core 2.3.1 → 3.0.0

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/index.ts CHANGED
@@ -158,3 +158,107 @@ export const openParafinDashboard = (
158
158
  return () => {} // noop
159
159
  }
160
160
  }
161
+
162
+ export const defaultWidgetStyles = {
163
+ width: '100%',
164
+ height: '258px',
165
+ backgroundColor: '#fff',
166
+ border: '1px solid #E8E8E8',
167
+ borderRadius: '16px',
168
+ transition: 'border 0.2s, border-radius 0.2s',
169
+ boxSizing: 'border-box' as const,
170
+ }
171
+
172
+ export type WidgetEvent = 'opted_in' | 'opted_out'
173
+
174
+ export type WidgetProps = {
175
+ token: string
176
+ product: 'capital' | 'spend_card' | 'cash_account'
177
+ externalBusinessId?: string
178
+ onEvent?: (eventType: WidgetEvent) => Promise<void> | void
179
+ onExit?: () => void
180
+ openInNewTab?: boolean
181
+ onLinkOpened?: (url: string, metadata: LinkOpenedMetadata) => void
182
+ inWebView?: boolean
183
+ }
184
+
185
+ export const initializeParafinWidget = (
186
+ iframe: HTMLIFrameElement,
187
+ props: WidgetProps
188
+ ) => {
189
+ // @ts-ignore
190
+ const url = new URL(props.widgetUrlOverride ?? 'https://widget.parafin.com')
191
+ const query = {
192
+ token: props.token,
193
+ product: props.product,
194
+ host: window.location.origin,
195
+ externalBusinessId: props.externalBusinessId ?? '',
196
+ ...Object.fromEntries(url.searchParams),
197
+ }
198
+ const iframeSrc = `${url.origin}?${new URLSearchParams(query).toString()}`
199
+
200
+ iframe.id = `parafin-${props.product}-widget`
201
+ iframe.src = iframeSrc
202
+
203
+ const sendMessage = (message: any) => {
204
+ iframe.contentWindow?.postMessage(message, url.origin)
205
+ }
206
+
207
+ const messageListener = async ({ data, origin }: MessageEvent) => {
208
+ if (origin === url.origin && data?.product === props.product) {
209
+ switch (data?.message) {
210
+ case 'set-border':
211
+ if (data?.borderColor) {
212
+ iframe.style.border = `1px solid ${data.borderColor}`
213
+ }
214
+ if (data?.borderRadius) {
215
+ iframe.style.borderRadius = data.borderRadius
216
+ }
217
+ break
218
+ case 'open-dashboard':
219
+ openParafinDashboard({
220
+ ...props,
221
+ route: data?.route,
222
+ onExit: () => {
223
+ iframe.src = iframeSrc
224
+ props.onExit?.()
225
+ },
226
+ })
227
+ break
228
+ case 'person-opt-in':
229
+ if (props.onEvent) {
230
+ try {
231
+ await props.onEvent('opted_in')
232
+ sendMessage({ message: 'person-opt-in', state: 'success' })
233
+ } catch {
234
+ sendMessage({ message: 'person-opt-in', state: 'error' })
235
+ }
236
+ } else {
237
+ sendMessage({ message: 'person-opt-in', state: 'noop' })
238
+ }
239
+ break
240
+ case 'person-opt-out':
241
+ if (props.onEvent) {
242
+ try {
243
+ await props.onEvent('opted_out')
244
+ sendMessage({ message: 'person-opt-out', state: 'success' })
245
+ } catch {
246
+ sendMessage({ message: 'person-opt-out', state: 'error' })
247
+ }
248
+ } else {
249
+ sendMessage({ message: 'person-opt-out', state: 'noop' })
250
+ }
251
+ break
252
+ case 'set-height':
253
+ if (data?.height) {
254
+ iframe.style.height = data.height
255
+ }
256
+ break
257
+ }
258
+ }
259
+ }
260
+
261
+ window.addEventListener('message', messageListener)
262
+
263
+ return () => window.removeEventListener('message', messageListener)
264
+ }
package/out/index.d.ts CHANGED
@@ -25,4 +25,25 @@ type BNPLProps = {
25
25
  onExit?: (id?: string) => Promise<void> | void;
26
26
  };
27
27
  export declare const openParafinDashboard: (props: BaseProps & (CapitalOrSpendProps | BNPLProps)) => () => void;
28
+ export declare const defaultWidgetStyles: {
29
+ width: string;
30
+ height: string;
31
+ backgroundColor: string;
32
+ border: string;
33
+ borderRadius: string;
34
+ transition: string;
35
+ boxSizing: "border-box";
36
+ };
37
+ export type WidgetEvent = 'opted_in' | 'opted_out';
38
+ export type WidgetProps = {
39
+ token: string;
40
+ product: 'capital' | 'spend_card' | 'cash_account';
41
+ externalBusinessId?: string;
42
+ onEvent?: (eventType: WidgetEvent) => Promise<void> | void;
43
+ onExit?: () => void;
44
+ openInNewTab?: boolean;
45
+ onLinkOpened?: (url: string, metadata: LinkOpenedMetadata) => void;
46
+ inWebView?: boolean;
47
+ };
48
+ export declare const initializeParafinWidget: (iframe: HTMLIFrameElement, props: WidgetProps) => () => void;
28
49
  export {};
package/out/index.js CHANGED
@@ -118,3 +118,88 @@ export const openParafinDashboard = (props) => {
118
118
  return () => { }; // noop
119
119
  }
120
120
  };
121
+ export const defaultWidgetStyles = {
122
+ width: '100%',
123
+ height: '258px',
124
+ backgroundColor: '#fff',
125
+ border: '1px solid #E8E8E8',
126
+ borderRadius: '16px',
127
+ transition: 'border 0.2s, border-radius 0.2s',
128
+ boxSizing: 'border-box',
129
+ };
130
+ export const initializeParafinWidget = (iframe, props) => {
131
+ // @ts-ignore
132
+ const url = new URL(props.widgetUrlOverride ?? 'https://widget.parafin.com');
133
+ const query = {
134
+ token: props.token,
135
+ product: props.product,
136
+ host: window.location.origin,
137
+ externalBusinessId: props.externalBusinessId ?? '',
138
+ ...Object.fromEntries(url.searchParams),
139
+ };
140
+ const iframeSrc = `${url.origin}?${new URLSearchParams(query).toString()}`;
141
+ iframe.id = `parafin-${props.product}-widget`;
142
+ iframe.src = iframeSrc;
143
+ const sendMessage = (message) => {
144
+ iframe.contentWindow?.postMessage(message, url.origin);
145
+ };
146
+ const messageListener = async ({ data, origin }) => {
147
+ if (origin === url.origin && data?.product === props.product) {
148
+ switch (data?.message) {
149
+ case 'set-border':
150
+ if (data?.borderColor) {
151
+ iframe.style.border = `1px solid ${data.borderColor}`;
152
+ }
153
+ if (data?.borderRadius) {
154
+ iframe.style.borderRadius = data.borderRadius;
155
+ }
156
+ break;
157
+ case 'open-dashboard':
158
+ openParafinDashboard({
159
+ ...props,
160
+ route: data?.route,
161
+ onExit: () => {
162
+ iframe.src = iframeSrc;
163
+ props.onExit?.();
164
+ },
165
+ });
166
+ break;
167
+ case 'person-opt-in':
168
+ if (props.onEvent) {
169
+ try {
170
+ await props.onEvent('opted_in');
171
+ sendMessage({ message: 'person-opt-in', state: 'success' });
172
+ }
173
+ catch {
174
+ sendMessage({ message: 'person-opt-in', state: 'error' });
175
+ }
176
+ }
177
+ else {
178
+ sendMessage({ message: 'person-opt-in', state: 'noop' });
179
+ }
180
+ break;
181
+ case 'person-opt-out':
182
+ if (props.onEvent) {
183
+ try {
184
+ await props.onEvent('opted_out');
185
+ sendMessage({ message: 'person-opt-out', state: 'success' });
186
+ }
187
+ catch {
188
+ sendMessage({ message: 'person-opt-out', state: 'error' });
189
+ }
190
+ }
191
+ else {
192
+ sendMessage({ message: 'person-opt-out', state: 'noop' });
193
+ }
194
+ break;
195
+ case 'set-height':
196
+ if (data?.height) {
197
+ iframe.style.height = data.height;
198
+ }
199
+ break;
200
+ }
201
+ }
202
+ };
203
+ window.addEventListener('message', messageListener);
204
+ return () => window.removeEventListener('message', messageListener);
205
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parafin/core",
3
- "version": "2.3.1",
3
+ "version": "3.0.0",
4
4
  "description": "Parafin embedded core",
5
5
  "author": "Parafin (https://www.parafin.com)",
6
6
  "module": "out/index.js",