bison-web-components 1.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/LICENSE +21 -0
- package/README.md +749 -0
- package/api.js +659 -0
- package/bison-operator-payments.js +1913 -0
- package/bison_logo.png +0 -0
- package/bison_logo_green.png +0 -0
- package/bison_logo_green.svg +103 -0
- package/bison_logo_white.svg +68 -0
- package/component.js +48 -0
- package/demo-payments.html +275 -0
- package/index.html +199 -0
- package/operator-bank-account.js +1193 -0
- package/operator-management.js +823 -0
- package/operator-onboarding.js +3750 -0
- package/operator-payment.js +2404 -0
- package/operator-underwriting.js +1473 -0
- package/package.json +14 -0
- package/test.js +3 -0
- package/test.mjs +3 -0
- package/theme.css +312 -0
- package/wio-bank-account.js +536 -0
- package/wio-onboarding.js +3981 -0
- package/wio-payment-linking.js +2054 -0
- package/wio-payment.js +579 -0
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WioBankAccount Web Component
|
|
3
|
+
*
|
|
4
|
+
* A simple web component that provides a button to directly trigger the Plaid flow
|
|
5
|
+
* and calls the getAccountByEmail API when an email prop is provided.
|
|
6
|
+
*
|
|
7
|
+
* @author @kfajardo
|
|
8
|
+
* @version 1.0.0
|
|
9
|
+
*
|
|
10
|
+
* @requires BisonJibPayAPI - Must be loaded before this component (from component.js)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```html
|
|
14
|
+
* <script src="component.js"></script>
|
|
15
|
+
* <script src="wio-bank-account.js"></script>
|
|
16
|
+
*
|
|
17
|
+
* <wio-bank-account id="linking" email="user@example.com" button-text="Link Bank Account"></wio-bank-account>
|
|
18
|
+
* <script>
|
|
19
|
+
* const linking = document.getElementById('linking');
|
|
20
|
+
* linking.addEventListener('plaid-link-success', (e) => {
|
|
21
|
+
* console.log('Success:', e.detail);
|
|
22
|
+
* });
|
|
23
|
+
* </script>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
class WioBankAccount extends HTMLElement {
|
|
28
|
+
constructor() {
|
|
29
|
+
super();
|
|
30
|
+
this.attachShadow({ mode: "open" });
|
|
31
|
+
|
|
32
|
+
// Consumer-assignable callback
|
|
33
|
+
this._onPlaidSuccess = null;
|
|
34
|
+
|
|
35
|
+
// API Configuration
|
|
36
|
+
this.apiBaseURL =
|
|
37
|
+
this.getAttribute("api-base-url") ||
|
|
38
|
+
"https://bison-jib-development.azurewebsites.net";
|
|
39
|
+
this.embeddableKey =
|
|
40
|
+
this.getAttribute("embeddable-key") ||
|
|
41
|
+
"R80WMkbNN8457RofiMYx03DL65P06IaVT30Q2emYJUBQwYCzRC";
|
|
42
|
+
|
|
43
|
+
// Check if BisonJibPayAPI is available
|
|
44
|
+
if (typeof BisonJibPayAPI === "undefined") {
|
|
45
|
+
console.error(
|
|
46
|
+
"WioBankAccount: BisonJibPayAPI is not available. Please ensure component.js is loaded before wio-bank-account.js"
|
|
47
|
+
);
|
|
48
|
+
this.api = null;
|
|
49
|
+
} else {
|
|
50
|
+
this.api = new BisonJibPayAPI(this.apiBaseURL, this.embeddableKey);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Internal state
|
|
54
|
+
this._state = {
|
|
55
|
+
email: null,
|
|
56
|
+
buttonText: this.getAttribute("button-text") || "Link Bank Account",
|
|
57
|
+
isLoading: false,
|
|
58
|
+
accountData: null,
|
|
59
|
+
moovAccountId: null,
|
|
60
|
+
error: null,
|
|
61
|
+
plaidLoaded: false,
|
|
62
|
+
plaidLinkToken: null,
|
|
63
|
+
initializationError: false,
|
|
64
|
+
isRefetchingPaymentMethods: false,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Render the component
|
|
68
|
+
this.render();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ==================== STATIC PROPERTIES ====================
|
|
72
|
+
|
|
73
|
+
static get observedAttributes() {
|
|
74
|
+
return ["email", "api-base-url", "embeddable-key", "button-text"];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ==================== PROPERTY GETTERS/SETTERS ====================
|
|
78
|
+
|
|
79
|
+
get email() {
|
|
80
|
+
return this._state.email;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get moovAccountId() {
|
|
84
|
+
return this._state.moovAccountId;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
get buttonText() {
|
|
88
|
+
return this._state.buttonText;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
get onPlaidSuccess() {
|
|
92
|
+
return this._onPlaidSuccess;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
set onPlaidSuccess(fn) {
|
|
96
|
+
if (fn !== null && typeof fn !== "function") {
|
|
97
|
+
console.warn("WioBankAccount: onPlaidSuccess must be a function or null");
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
this._onPlaidSuccess = fn;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
set email(value) {
|
|
104
|
+
console.log("WioBankAccount: Setting email to:", value);
|
|
105
|
+
const oldEmail = this._state.email;
|
|
106
|
+
this._state.email = value;
|
|
107
|
+
|
|
108
|
+
const currentAttr = this.getAttribute("email");
|
|
109
|
+
if (currentAttr !== value) {
|
|
110
|
+
if (value) {
|
|
111
|
+
this.setAttribute("email", value);
|
|
112
|
+
} else {
|
|
113
|
+
this.removeAttribute("email");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (value && value !== oldEmail && this.isConnected) {
|
|
118
|
+
this.initializeAccount();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
set buttonText(value) {
|
|
123
|
+
const nextValue = value == null ? "" : String(value);
|
|
124
|
+
const oldValue = this._state.buttonText;
|
|
125
|
+
|
|
126
|
+
this._state.buttonText = nextValue || "Link Bank Account";
|
|
127
|
+
|
|
128
|
+
const currentAttr = this.getAttribute("button-text");
|
|
129
|
+
if (currentAttr !== nextValue) {
|
|
130
|
+
if (nextValue) {
|
|
131
|
+
this.setAttribute("button-text", nextValue);
|
|
132
|
+
} else {
|
|
133
|
+
this.removeAttribute("button-text");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (oldValue !== this._state.buttonText) {
|
|
138
|
+
this.updateButtonLabel();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ==================== LIFECYCLE METHODS ====================
|
|
143
|
+
|
|
144
|
+
connectedCallback() {
|
|
145
|
+
const emailAttr = this.getAttribute("email");
|
|
146
|
+
if (emailAttr && !this._state.email) {
|
|
147
|
+
this._state.email = emailAttr;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
this.ensurePlaidSDK();
|
|
151
|
+
this.setupEventListeners();
|
|
152
|
+
|
|
153
|
+
if (this._state.email) {
|
|
154
|
+
this.initializeAccount();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
disconnectedCallback() {
|
|
159
|
+
this.removeEventListeners();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
163
|
+
if (oldValue === newValue) return;
|
|
164
|
+
|
|
165
|
+
switch (name) {
|
|
166
|
+
case "email":
|
|
167
|
+
this._state.email = newValue;
|
|
168
|
+
if (newValue && this.isConnected) {
|
|
169
|
+
this.initializeAccount();
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
|
|
173
|
+
case "api-base-url":
|
|
174
|
+
this.apiBaseURL = newValue;
|
|
175
|
+
if (this.api) {
|
|
176
|
+
this.api = new BisonJibPayAPI(this.apiBaseURL, this.embeddableKey);
|
|
177
|
+
}
|
|
178
|
+
if (this._state.email && this.isConnected) {
|
|
179
|
+
this.initializeAccount();
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
|
|
183
|
+
case "embeddable-key":
|
|
184
|
+
this.embeddableKey = newValue;
|
|
185
|
+
if (this.api) {
|
|
186
|
+
this.api = new BisonJibPayAPI(this.apiBaseURL, this.embeddableKey);
|
|
187
|
+
}
|
|
188
|
+
if (this._state.email && this.isConnected) {
|
|
189
|
+
this.initializeAccount();
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
|
|
193
|
+
case "button-text":
|
|
194
|
+
this._state.buttonText = newValue || "Link Bank Account";
|
|
195
|
+
this.updateButtonLabel();
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ==================== PLAID SDK LOADING ====================
|
|
201
|
+
|
|
202
|
+
async ensurePlaidSDK() {
|
|
203
|
+
if (window.Plaid) {
|
|
204
|
+
this._state.plaidLoaded = true;
|
|
205
|
+
return Promise.resolve();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const existingScript = document.querySelector(
|
|
209
|
+
'script[src*="plaid.com/link"]'
|
|
210
|
+
);
|
|
211
|
+
if (existingScript) {
|
|
212
|
+
return new Promise((resolve, reject) => {
|
|
213
|
+
existingScript.addEventListener("load", () => {
|
|
214
|
+
this._state.plaidLoaded = true;
|
|
215
|
+
resolve();
|
|
216
|
+
});
|
|
217
|
+
existingScript.addEventListener("error", () =>
|
|
218
|
+
reject(new Error("Failed to load Plaid SDK"))
|
|
219
|
+
);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return new Promise((resolve, reject) => {
|
|
224
|
+
const script = document.createElement("script");
|
|
225
|
+
script.src = "https://cdn.plaid.com/link/v2/stable/link-initialize.js";
|
|
226
|
+
script.async = true;
|
|
227
|
+
script.defer = true;
|
|
228
|
+
|
|
229
|
+
script.onload = () => {
|
|
230
|
+
this._state.plaidLoaded = true;
|
|
231
|
+
resolve();
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
script.onerror = () => {
|
|
235
|
+
const error = new Error("Failed to load Plaid SDK from CDN");
|
|
236
|
+
this._state.error = error.message;
|
|
237
|
+
reject(error);
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
document.head.appendChild(script);
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// ==================== EVENT HANDLING ====================
|
|
245
|
+
|
|
246
|
+
setupEventListeners() {
|
|
247
|
+
const button = this.shadowRoot.querySelector(".link-payment-btn");
|
|
248
|
+
if (button) {
|
|
249
|
+
button.addEventListener("click", this.openPlaidLink.bind(this));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
removeEventListeners() {
|
|
254
|
+
// No specific global listeners to remove
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ==================== INITIALIZATION METHODS ====================
|
|
258
|
+
|
|
259
|
+
async initializeAccount() {
|
|
260
|
+
if (!this._state.email) {
|
|
261
|
+
console.warn("WioBankAccount: Email is required for initialization");
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (!this.api) {
|
|
266
|
+
console.error(
|
|
267
|
+
"WioBankAccount: BisonJibPayAPI is not available."
|
|
268
|
+
);
|
|
269
|
+
this._state.initializationError = true;
|
|
270
|
+
this.updateMainButtonState();
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
this._state.isLoading = true;
|
|
276
|
+
this._state.error = null;
|
|
277
|
+
this._state.initializationError = false;
|
|
278
|
+
|
|
279
|
+
this.updateMainButtonState();
|
|
280
|
+
|
|
281
|
+
const result = await this.api.getAccountByEmail(this._state.email);
|
|
282
|
+
this._state.accountData = result.data;
|
|
283
|
+
this._state.moovAccountId = result.data.moovAccountId || null;
|
|
284
|
+
|
|
285
|
+
this.updateMainButtonState();
|
|
286
|
+
|
|
287
|
+
await this.initializePlaidToken();
|
|
288
|
+
} catch (error) {
|
|
289
|
+
this._state.isLoading = false;
|
|
290
|
+
this._state.error = error.message || "Failed to fetch account data";
|
|
291
|
+
this._state.initializationError = true;
|
|
292
|
+
console.error("WioBankAccount: Account initialization failed", error);
|
|
293
|
+
this.updateMainButtonState();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async initializePlaidToken() {
|
|
298
|
+
try {
|
|
299
|
+
const plaidLinkResult = await this.api.generatePlaidToken(
|
|
300
|
+
this._state.email
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
if (!plaidLinkResult.success) {
|
|
304
|
+
throw new Error(
|
|
305
|
+
plaidLinkResult.message ||
|
|
306
|
+
"Error occurred while generating Plaid Link token"
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
this._state.plaidLinkToken = plaidLinkResult.data.linkToken;
|
|
311
|
+
this._state.isLoading = false;
|
|
312
|
+
this.updateMainButtonState();
|
|
313
|
+
} catch (error) {
|
|
314
|
+
this._state.isLoading = false;
|
|
315
|
+
this._state.error = error.message || "Failed to generate Plaid token";
|
|
316
|
+
this._state.initializationError = true;
|
|
317
|
+
this.updateMainButtonState();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async openPlaidLink() {
|
|
322
|
+
if (!this._state.plaidLoaded) {
|
|
323
|
+
try {
|
|
324
|
+
await this.ensurePlaidSDK();
|
|
325
|
+
} catch (error) {
|
|
326
|
+
console.error("WioBankAccount: Failed to load Plaid SDK:", error);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (!this._state.plaidLinkToken) {
|
|
332
|
+
console.error("WioBankAccount: Plaid Link token not available");
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const handler = window.Plaid.create({
|
|
337
|
+
token: this._state.plaidLinkToken,
|
|
338
|
+
onSuccess: async (public_token, metadata) => {
|
|
339
|
+
// Invoke consumer-assigned callback immediately on Plaid success
|
|
340
|
+
if (typeof this._onPlaidSuccess === "function") {
|
|
341
|
+
try {
|
|
342
|
+
this._onPlaidSuccess({ public_token, metadata });
|
|
343
|
+
} catch (cbError) {
|
|
344
|
+
console.error("WioBankAccount: onPlaidSuccess callback error", cbError);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const moovAccountId = this._state.moovAccountId;
|
|
349
|
+
|
|
350
|
+
if (!moovAccountId) {
|
|
351
|
+
console.error("WioBankAccount: Moov Account ID not found");
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Show spinner on button while adding account
|
|
356
|
+
this._state.isLoading = true;
|
|
357
|
+
this.updateMainButtonState();
|
|
358
|
+
|
|
359
|
+
requestAnimationFrame(async () => {
|
|
360
|
+
try {
|
|
361
|
+
console.log("WioBankAccount: Adding Plaid account to Moov...");
|
|
362
|
+
|
|
363
|
+
const result = await this.api.addPlaidAccountToMoov(
|
|
364
|
+
public_token,
|
|
365
|
+
metadata.account_id,
|
|
366
|
+
moovAccountId
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
console.log("WioBankAccount: Plaid Link success", result);
|
|
370
|
+
|
|
371
|
+
this._state.isLoading = false;
|
|
372
|
+
this.updateMainButtonState();
|
|
373
|
+
|
|
374
|
+
const successDetail = { public_token, metadata, result };
|
|
375
|
+
|
|
376
|
+
this.dispatchEvent(
|
|
377
|
+
new CustomEvent("plaid-link-success", {
|
|
378
|
+
detail: successDetail,
|
|
379
|
+
bubbles: true,
|
|
380
|
+
composed: true,
|
|
381
|
+
})
|
|
382
|
+
);
|
|
383
|
+
} catch (error) {
|
|
384
|
+
console.error(
|
|
385
|
+
"WioBankAccount: Failed to add Plaid account to Moov",
|
|
386
|
+
error
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
this._state.isLoading = false;
|
|
390
|
+
this.updateMainButtonState();
|
|
391
|
+
|
|
392
|
+
this.dispatchEvent(
|
|
393
|
+
new CustomEvent("plaid-link-error", {
|
|
394
|
+
detail: { error: error.message, metadata },
|
|
395
|
+
bubbles: true,
|
|
396
|
+
composed: true,
|
|
397
|
+
})
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
},
|
|
402
|
+
onExit: (err, metadata) => {
|
|
403
|
+
console.log("WioBankAccount: Plaid Link exit", err, metadata);
|
|
404
|
+
if (err) {
|
|
405
|
+
this.dispatchEvent(
|
|
406
|
+
new CustomEvent("plaid-link-error", {
|
|
407
|
+
detail: { error: err, metadata },
|
|
408
|
+
bubbles: true,
|
|
409
|
+
composed: true,
|
|
410
|
+
})
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
handler.open();
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
updateMainButtonState() {
|
|
420
|
+
const button = this.shadowRoot.querySelector(".link-payment-btn");
|
|
421
|
+
if (!button) return;
|
|
422
|
+
|
|
423
|
+
if (this._state.isLoading) {
|
|
424
|
+
button.classList.add("loading");
|
|
425
|
+
button.classList.remove("error");
|
|
426
|
+
button.disabled = true;
|
|
427
|
+
} else if (this._state.initializationError) {
|
|
428
|
+
button.classList.remove("loading");
|
|
429
|
+
button.classList.add("error");
|
|
430
|
+
button.disabled = true;
|
|
431
|
+
} else {
|
|
432
|
+
button.classList.remove("loading");
|
|
433
|
+
button.classList.remove("error");
|
|
434
|
+
button.disabled = false;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
updateButtonLabel() {
|
|
439
|
+
const label = this.shadowRoot.querySelector(".link-payment-label");
|
|
440
|
+
if (label) {
|
|
441
|
+
label.textContent = this._state.buttonText || "Link Bank Account";
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
render() {
|
|
446
|
+
this.shadowRoot.innerHTML = `
|
|
447
|
+
<style>
|
|
448
|
+
:host {
|
|
449
|
+
display: inline-block;
|
|
450
|
+
font-family: var(--font-sans, 'Inter', system-ui, sans-serif);
|
|
451
|
+
color: var(--color-secondary, #5f6e78);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.link-payment-btn {
|
|
455
|
+
padding: 12px 24px;
|
|
456
|
+
background: var(--color-primary, #4c7b63);
|
|
457
|
+
color: var(--color-white, #fff);
|
|
458
|
+
border: none;
|
|
459
|
+
border-radius: var(--radius-xl, 0.75rem);
|
|
460
|
+
font-size: var(--text-sm, 0.875rem);
|
|
461
|
+
font-weight: var(--font-weight-medium, 500);
|
|
462
|
+
cursor: pointer;
|
|
463
|
+
transition: all var(--duration-normal, 200ms) var(--ease-in-out, cubic-bezier(0.4, 0, 0.2, 1));
|
|
464
|
+
display: inline-flex;
|
|
465
|
+
align-items: center;
|
|
466
|
+
gap: 8px;
|
|
467
|
+
height: 40px;
|
|
468
|
+
box-sizing: border-box;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.link-payment-btn:hover:not(.error):not(.loading) {
|
|
472
|
+
background: var(--color-primary-hover, #436c57);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.link-payment-btn:active:not(.error):not(.loading) {
|
|
476
|
+
background: var(--color-primary-active, #3d624f);
|
|
477
|
+
transform: translateY(0);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
.link-payment-btn.error {
|
|
481
|
+
background: var(--color-gray-400, #9ca3af);
|
|
482
|
+
cursor: not-allowed;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.link-payment-btn.loading {
|
|
486
|
+
background: var(--color-primary-soft, #678f7a);
|
|
487
|
+
cursor: wait;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
.link-payment-btn .loading-spinner {
|
|
491
|
+
display: none;
|
|
492
|
+
width: 16px;
|
|
493
|
+
height: 16px;
|
|
494
|
+
border: 2px solid rgba(255, 255, 255, 0.3);
|
|
495
|
+
border-top-color: var(--color-white, #fff);
|
|
496
|
+
border-radius: 50%;
|
|
497
|
+
animation: spin 0.8s linear infinite;
|
|
498
|
+
box-sizing: border-box;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
.link-payment-btn.loading .loading-spinner {
|
|
502
|
+
display: inline-block;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
@keyframes spin {
|
|
506
|
+
to {
|
|
507
|
+
transform: rotate(360deg);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
</style>
|
|
511
|
+
|
|
512
|
+
<button class="link-payment-btn" id="mainButton">
|
|
513
|
+
<span class="loading-spinner"></span>
|
|
514
|
+
<span class="link-payment-label">${this._state.buttonText}</span>
|
|
515
|
+
<svg class="broken-link-icon" style="display:none; width:16px; height:16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
516
|
+
<path d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
517
|
+
</svg>
|
|
518
|
+
</button>
|
|
519
|
+
`;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Register the custom element only if it hasn't been registered yet
|
|
524
|
+
if (!customElements.get("wio-bank-account")) {
|
|
525
|
+
customElements.define("wio-bank-account", WioBankAccount);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Export for module usage
|
|
529
|
+
if (typeof module !== "undefined" && module.exports) {
|
|
530
|
+
module.exports = { WioBankAccount };
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Make available globally for script tag usage
|
|
534
|
+
if (typeof window !== "undefined") {
|
|
535
|
+
window.WioBankAccount = WioBankAccount;
|
|
536
|
+
}
|