@createlex/onetapforms-sdk 1.1.4 → 1.2.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/dist/index.d.ts CHANGED
@@ -1,2 +1,19 @@
1
1
  export { OneTapForms, default } from './sdk';
2
2
  export type { OneTapFormsConfig, RequestOptions, CompletionResult } from './types';
3
+ /**
4
+ * Create and show a QR modal
5
+ */
6
+ declare function showQRModal(options: {
7
+ title?: string;
8
+ subtitle?: string;
9
+ onClose?: () => void;
10
+ }): {
11
+ setQR: (qrDataUrl: string) => void;
12
+ setStatus: (status: string) => void;
13
+ close: () => void;
14
+ };
15
+ /**
16
+ * Initialize widget elements with data-onetapforms attribute
17
+ */
18
+ declare function initWidgets(): void;
19
+ export { initWidgets, showQRModal };
package/dist/index.esm.js CHANGED
@@ -153,5 +153,287 @@ class OneTapForms {
153
153
  }
154
154
  }
155
155
 
156
- export { OneTapForms, OneTapForms as default };
156
+ var sdk = /*#__PURE__*/Object.freeze({
157
+ __proto__: null,
158
+ OneTapForms: OneTapForms,
159
+ default: OneTapForms
160
+ });
161
+
162
+ // Export the OneTapForms class and types
163
+ // Widget auto-initialization for CDN/script tag usage
164
+ // This runs automatically when loaded via <script> tag
165
+ /**
166
+ * Built-in QR Modal styles (CSS-in-JS, no external CSS required)
167
+ */
168
+ const MODAL_STYLES = `
169
+ .onetapforms-modal {
170
+ position: fixed;
171
+ top: 0;
172
+ left: 0;
173
+ right: 0;
174
+ bottom: 0;
175
+ background: rgba(0, 0, 0, 0.6);
176
+ display: flex;
177
+ align-items: center;
178
+ justify-content: center;
179
+ z-index: 10000;
180
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
181
+ opacity: 0;
182
+ transition: opacity 0.2s ease;
183
+ }
184
+ .onetapforms-modal.active {
185
+ opacity: 1;
186
+ }
187
+ .onetapforms-modal-content {
188
+ background: white;
189
+ padding: 32px;
190
+ border-radius: 16px;
191
+ max-width: 360px;
192
+ width: 90%;
193
+ text-align: center;
194
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
195
+ transform: scale(0.95);
196
+ transition: transform 0.2s ease;
197
+ }
198
+ .onetapforms-modal.active .onetapforms-modal-content {
199
+ transform: scale(1);
200
+ }
201
+ .onetapforms-modal-title {
202
+ margin: 0 0 8px 0;
203
+ font-size: 20px;
204
+ font-weight: 600;
205
+ color: #1a1a1a;
206
+ }
207
+ .onetapforms-modal-subtitle {
208
+ margin: 0 0 24px 0;
209
+ font-size: 14px;
210
+ color: #666;
211
+ }
212
+ .onetapforms-qr-container {
213
+ background: #f5f5f5;
214
+ border-radius: 12px;
215
+ padding: 20px;
216
+ margin-bottom: 20px;
217
+ }
218
+ .onetapforms-qr-container img {
219
+ max-width: 100%;
220
+ height: auto;
221
+ }
222
+ .onetapforms-status {
223
+ font-size: 13px;
224
+ color: #888;
225
+ margin-bottom: 16px;
226
+ }
227
+ .onetapforms-close-btn {
228
+ background: #f0f0f0;
229
+ border: none;
230
+ padding: 10px 24px;
231
+ border-radius: 8px;
232
+ cursor: pointer;
233
+ font-size: 14px;
234
+ color: #333;
235
+ transition: background 0.15s;
236
+ }
237
+ .onetapforms-close-btn:hover {
238
+ background: #e0e0e0;
239
+ }
240
+ .onetapforms-spinner {
241
+ width: 200px;
242
+ height: 200px;
243
+ display: flex;
244
+ align-items: center;
245
+ justify-content: center;
246
+ }
247
+ .onetapforms-spinner::after {
248
+ content: '';
249
+ width: 40px;
250
+ height: 40px;
251
+ border: 3px solid #e0e0e0;
252
+ border-top-color: #007AFF;
253
+ border-radius: 50%;
254
+ animation: onetapforms-spin 0.8s linear infinite;
255
+ }
256
+ @keyframes onetapforms-spin {
257
+ to { transform: rotate(360deg); }
258
+ }
259
+ `;
260
+ /**
261
+ * Inject modal styles into the page (once)
262
+ */
263
+ function injectStyles() {
264
+ if (typeof document === 'undefined')
265
+ return;
266
+ if (document.getElementById('onetapforms-styles'))
267
+ return;
268
+ const style = document.createElement('style');
269
+ style.id = 'onetapforms-styles';
270
+ style.textContent = MODAL_STYLES;
271
+ document.head.appendChild(style);
272
+ }
273
+ /**
274
+ * Create and show a QR modal
275
+ */
276
+ function showQRModal(options) {
277
+ injectStyles();
278
+ const modal = document.createElement('div');
279
+ modal.className = 'onetapforms-modal';
280
+ modal.innerHTML = `
281
+ <div class="onetapforms-modal-content">
282
+ <h3 class="onetapforms-modal-title">${options.title || 'Scan to Complete'}</h3>
283
+ <p class="onetapforms-modal-subtitle">${options.subtitle || 'Scan with your OneTapForms app'}</p>
284
+ <div class="onetapforms-qr-container">
285
+ <div class="onetapforms-spinner"></div>
286
+ </div>
287
+ <p class="onetapforms-status">Waiting for scan...</p>
288
+ <button class="onetapforms-close-btn">Cancel</button>
289
+ </div>
290
+ `;
291
+ const qrContainer = modal.querySelector('.onetapforms-qr-container');
292
+ const statusEl = modal.querySelector('.onetapforms-status');
293
+ const closeBtn = modal.querySelector('.onetapforms-close-btn');
294
+ const close = () => {
295
+ modal.classList.remove('active');
296
+ setTimeout(() => modal.remove(), 200);
297
+ if (options.onClose)
298
+ options.onClose();
299
+ };
300
+ closeBtn.addEventListener('click', close);
301
+ modal.addEventListener('click', (e) => {
302
+ if (e.target === modal)
303
+ close();
304
+ });
305
+ document.body.appendChild(modal);
306
+ // Trigger animation
307
+ requestAnimationFrame(() => modal.classList.add('active'));
308
+ return {
309
+ setQR: (qrDataUrl) => {
310
+ qrContainer.innerHTML = `<img src="${qrDataUrl}" alt="QR Code" />`;
311
+ },
312
+ setStatus: (status) => {
313
+ statusEl.textContent = status;
314
+ },
315
+ close
316
+ };
317
+ }
318
+ /**
319
+ * Initialize widget elements with data-onetapforms attribute
320
+ */
321
+ function initWidgets() {
322
+ if (typeof document === 'undefined')
323
+ return;
324
+ const widgets = document.querySelectorAll('[data-onetapforms]');
325
+ widgets.forEach((element) => {
326
+ // Skip if already initialized
327
+ if (element.dataset.onetapformsInit === 'true')
328
+ return;
329
+ element.dataset.onetapformsInit = 'true';
330
+ const clientId = element.dataset.clientId;
331
+ const clientSecret = element.dataset.clientSecret;
332
+ const purpose = element.dataset.purpose || 'Complete form';
333
+ const bundles = element.dataset.bundles?.split(',').map(b => b.trim()) || ['basic'];
334
+ const formId = element.dataset.formId;
335
+ const apiUrl = element.dataset.apiUrl;
336
+ if (!clientId) {
337
+ console.error('[OneTapForms] Missing data-client-id attribute');
338
+ return;
339
+ }
340
+ // Import OneTapForms dynamically to avoid circular deps
341
+ Promise.resolve().then(function () { return sdk; }).then(({ OneTapForms }) => {
342
+ const sdk = new OneTapForms({
343
+ clientId,
344
+ clientSecret,
345
+ apiUrl
346
+ });
347
+ element.addEventListener('click', async (e) => {
348
+ e.preventDefault();
349
+ let modal = null;
350
+ try {
351
+ await sdk.request({
352
+ purpose,
353
+ bundles,
354
+ onQRReady: (qrDataUrl) => {
355
+ modal = showQRModal({
356
+ title: 'Scan with OneTapForms',
357
+ subtitle: purpose,
358
+ onClose: () => sdk.cancelPolling()
359
+ });
360
+ modal.setQR(qrDataUrl);
361
+ },
362
+ onComplete: (result) => {
363
+ if (modal) {
364
+ modal.setStatus('Complete!');
365
+ setTimeout(() => modal?.close(), 500);
366
+ }
367
+ // Dispatch custom event with result
368
+ const event = new CustomEvent('onetapforms:complete', {
369
+ bubbles: true,
370
+ detail: result
371
+ });
372
+ element.dispatchEvent(event);
373
+ // Auto-inject token into form if formId is specified
374
+ if (formId) {
375
+ const form = document.getElementById(formId);
376
+ if (form) {
377
+ let tokenInput = form.querySelector('input[name="onetapforms_token"]');
378
+ if (!tokenInput) {
379
+ tokenInput = document.createElement('input');
380
+ tokenInput.type = 'hidden';
381
+ tokenInput.name = 'onetapforms_token';
382
+ form.appendChild(tokenInput);
383
+ }
384
+ tokenInput.value = result.token;
385
+ }
386
+ }
387
+ },
388
+ onError: (error) => {
389
+ if (modal)
390
+ modal.close();
391
+ const event = new CustomEvent('onetapforms:error', {
392
+ bubbles: true,
393
+ detail: { error }
394
+ });
395
+ element.dispatchEvent(event);
396
+ }
397
+ });
398
+ }
399
+ catch (error) {
400
+ console.error('[OneTapForms] Request failed:', error);
401
+ const event = new CustomEvent('onetapforms:error', {
402
+ bubbles: true,
403
+ detail: { error }
404
+ });
405
+ element.dispatchEvent(event);
406
+ }
407
+ });
408
+ });
409
+ });
410
+ }
411
+ // Auto-initialize on DOM ready (for UMD/script tag usage)
412
+ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
413
+ if (document.readyState === 'loading') {
414
+ document.addEventListener('DOMContentLoaded', initWidgets);
415
+ }
416
+ else {
417
+ // DOM already ready
418
+ initWidgets();
419
+ }
420
+ // Also observe for dynamically added elements
421
+ const observer = new MutationObserver((mutations) => {
422
+ for (const mutation of mutations) {
423
+ if (mutation.addedNodes.length) {
424
+ initWidgets();
425
+ }
426
+ }
427
+ });
428
+ if (document.body) {
429
+ observer.observe(document.body, { childList: true, subtree: true });
430
+ }
431
+ else {
432
+ document.addEventListener('DOMContentLoaded', () => {
433
+ observer.observe(document.body, { childList: true, subtree: true });
434
+ });
435
+ }
436
+ }
437
+
438
+ export { OneTapForms, OneTapForms as default, initWidgets, showQRModal };
157
439
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/sdk.ts"],"sourcesContent":["import type { OneTapFormsConfig, RequestOptions, CompletionResult } from './types';\nimport { OneTapForms as OneTapFormsImpl } from './onetapforms.js';\n\n/**\n * OneTapForms SDK class for secure, biometric-authenticated form completion\n */\nexport class OneTapForms {\n private instance: any;\n\n constructor(config: OneTapFormsConfig) {\n this.instance = new OneTapFormsImpl(config);\n }\n\n /**\n * Create a form completion request\n */\n async request(options: RequestOptions): Promise<void> {\n return this.instance.request(options);\n }\n\n /**\n * Cancel active polling (useful for cleanup)\n */\n cancelPolling(): void {\n return this.instance.cancelPolling();\n }\n\n /**\n * Handle callback from redirect flow\n * Call this when user returns to your site with token in URL\n */\n handleCallback(): CompletionResult | null {\n return this.instance.handleCallback();\n }\n\n /**\n * Exchange token for user data (server-side only!)\n * This should be called from your backend, not the browser\n */\n async exchangeToken(token: string): Promise<any> {\n return this.instance.exchangeToken(token);\n }\n\n /**\n * Get the App Store URL for downloading OneTapForms app\n * Use this to encourage users to download the app for faster form completion\n */\n getAppDownloadUrl(): string {\n return 'https://apps.apple.com/app/onetapforms';\n }\n\n /**\n * Show a prompt encouraging users to download the OneTapForms app\n * This helps developers get faster form completion and better conversion rates\n *\n * @param options Customization options for the prompt\n */\n showDownloadPrompt(options?: {\n title?: string;\n message?: string;\n buttonText?: string;\n onDismiss?: () => void;\n }): void {\n if (typeof window === 'undefined') {\n return; // Server-side, do nothing\n }\n\n const title = options?.title || 'Download OneTapForms for Faster Form Completion';\n const message = options?.message ||\n 'Complete forms in seconds with one tap! Download the OneTapForms app to instantly fill forms using Face ID/Touch ID.';\n const buttonText = options?.buttonText || 'Download App';\n const appUrl = this.getAppDownloadUrl();\n\n // Create a simple modal/prompt\n const modal = document.createElement('div');\n modal.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n `;\n\n const content = document.createElement('div');\n content.style.cssText = `\n background: white;\n padding: 24px;\n border-radius: 12px;\n max-width: 400px;\n margin: 20px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n `;\n\n const titleEl = document.createElement('h3');\n titleEl.textContent = title;\n titleEl.style.cssText = `\n margin: 0 0 12px 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n `;\n\n const messageEl = document.createElement('p');\n messageEl.textContent = message;\n messageEl.style.cssText = `\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #666;\n line-height: 1.5;\n `;\n\n const buttonContainer = document.createElement('div');\n buttonContainer.style.cssText = `\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n `;\n\n const dismissBtn = document.createElement('button');\n dismissBtn.textContent = 'Maybe Later';\n dismissBtn.style.cssText = `\n padding: 10px 20px;\n border: 1px solid #ddd;\n background: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n color: #666;\n `;\n dismissBtn.onclick = () => {\n document.body.removeChild(modal);\n if (options?.onDismiss) {\n options.onDismiss();\n }\n };\n\n const downloadBtn = document.createElement('button');\n downloadBtn.textContent = buttonText;\n downloadBtn.style.cssText = `\n padding: 10px 20px;\n border: none;\n background: #007AFF;\n color: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n `;\n downloadBtn.onclick = () => {\n window.open(appUrl, '_blank');\n document.body.removeChild(modal);\n };\n\n buttonContainer.appendChild(dismissBtn);\n buttonContainer.appendChild(downloadBtn);\n\n content.appendChild(titleEl);\n content.appendChild(messageEl);\n content.appendChild(buttonContainer);\n modal.appendChild(content);\n\n // Close on background click\n modal.onclick = (e) => {\n if (e.target === modal) {\n document.body.removeChild(modal);\n if (options?.onDismiss) {\n options.onDismiss();\n }\n }\n };\n\n document.body.appendChild(modal);\n }\n}\n\nexport default OneTapForms;\n"],"names":["OneTapFormsImpl"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/sdk.ts","../src/index.ts"],"sourcesContent":["import type { OneTapFormsConfig, RequestOptions, CompletionResult } from './types';\nimport { OneTapForms as OneTapFormsImpl } from './onetapforms.js';\n\n/**\n * OneTapForms SDK class for secure, biometric-authenticated form completion\n */\nexport class OneTapForms {\n private instance: any;\n\n constructor(config: OneTapFormsConfig) {\n this.instance = new OneTapFormsImpl(config);\n }\n\n /**\n * Create a form completion request\n */\n async request(options: RequestOptions): Promise<void> {\n return this.instance.request(options);\n }\n\n /**\n * Cancel active polling (useful for cleanup)\n */\n cancelPolling(): void {\n return this.instance.cancelPolling();\n }\n\n /**\n * Handle callback from redirect flow\n * Call this when user returns to your site with token in URL\n */\n handleCallback(): CompletionResult | null {\n return this.instance.handleCallback();\n }\n\n /**\n * Exchange token for user data (server-side only!)\n * This should be called from your backend, not the browser\n */\n async exchangeToken(token: string): Promise<any> {\n return this.instance.exchangeToken(token);\n }\n\n /**\n * Get the App Store URL for downloading OneTapForms app\n * Use this to encourage users to download the app for faster form completion\n */\n getAppDownloadUrl(): string {\n return 'https://apps.apple.com/app/onetapforms';\n }\n\n /**\n * Show a prompt encouraging users to download the OneTapForms app\n * This helps developers get faster form completion and better conversion rates\n *\n * @param options Customization options for the prompt\n */\n showDownloadPrompt(options?: {\n title?: string;\n message?: string;\n buttonText?: string;\n onDismiss?: () => void;\n }): void {\n if (typeof window === 'undefined') {\n return; // Server-side, do nothing\n }\n\n const title = options?.title || 'Download OneTapForms for Faster Form Completion';\n const message = options?.message ||\n 'Complete forms in seconds with one tap! Download the OneTapForms app to instantly fill forms using Face ID/Touch ID.';\n const buttonText = options?.buttonText || 'Download App';\n const appUrl = this.getAppDownloadUrl();\n\n // Create a simple modal/prompt\n const modal = document.createElement('div');\n modal.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n `;\n\n const content = document.createElement('div');\n content.style.cssText = `\n background: white;\n padding: 24px;\n border-radius: 12px;\n max-width: 400px;\n margin: 20px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n `;\n\n const titleEl = document.createElement('h3');\n titleEl.textContent = title;\n titleEl.style.cssText = `\n margin: 0 0 12px 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n `;\n\n const messageEl = document.createElement('p');\n messageEl.textContent = message;\n messageEl.style.cssText = `\n margin: 0 0 20px 0;\n font-size: 14px;\n color: #666;\n line-height: 1.5;\n `;\n\n const buttonContainer = document.createElement('div');\n buttonContainer.style.cssText = `\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n `;\n\n const dismissBtn = document.createElement('button');\n dismissBtn.textContent = 'Maybe Later';\n dismissBtn.style.cssText = `\n padding: 10px 20px;\n border: 1px solid #ddd;\n background: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n color: #666;\n `;\n dismissBtn.onclick = () => {\n document.body.removeChild(modal);\n if (options?.onDismiss) {\n options.onDismiss();\n }\n };\n\n const downloadBtn = document.createElement('button');\n downloadBtn.textContent = buttonText;\n downloadBtn.style.cssText = `\n padding: 10px 20px;\n border: none;\n background: #007AFF;\n color: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n font-weight: 500;\n `;\n downloadBtn.onclick = () => {\n window.open(appUrl, '_blank');\n document.body.removeChild(modal);\n };\n\n buttonContainer.appendChild(dismissBtn);\n buttonContainer.appendChild(downloadBtn);\n\n content.appendChild(titleEl);\n content.appendChild(messageEl);\n content.appendChild(buttonContainer);\n modal.appendChild(content);\n\n // Close on background click\n modal.onclick = (e) => {\n if (e.target === modal) {\n document.body.removeChild(modal);\n if (options?.onDismiss) {\n options.onDismiss();\n }\n }\n };\n\n document.body.appendChild(modal);\n }\n}\n\nexport default OneTapForms;\n","// Export the OneTapForms class and types\nexport { OneTapForms, default } from './sdk';\nexport type {\n OneTapFormsConfig,\n RequestOptions,\n CompletionResult\n} from './types';\n\n// Widget auto-initialization for CDN/script tag usage\n// This runs automatically when loaded via <script> tag\n\n/**\n * Built-in QR Modal styles (CSS-in-JS, no external CSS required)\n */\nconst MODAL_STYLES = `\n .onetapforms-modal {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.6);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n opacity: 0;\n transition: opacity 0.2s ease;\n }\n .onetapforms-modal.active {\n opacity: 1;\n }\n .onetapforms-modal-content {\n background: white;\n padding: 32px;\n border-radius: 16px;\n max-width: 360px;\n width: 90%;\n text-align: center;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);\n transform: scale(0.95);\n transition: transform 0.2s ease;\n }\n .onetapforms-modal.active .onetapforms-modal-content {\n transform: scale(1);\n }\n .onetapforms-modal-title {\n margin: 0 0 8px 0;\n font-size: 20px;\n font-weight: 600;\n color: #1a1a1a;\n }\n .onetapforms-modal-subtitle {\n margin: 0 0 24px 0;\n font-size: 14px;\n color: #666;\n }\n .onetapforms-qr-container {\n background: #f5f5f5;\n border-radius: 12px;\n padding: 20px;\n margin-bottom: 20px;\n }\n .onetapforms-qr-container img {\n max-width: 100%;\n height: auto;\n }\n .onetapforms-status {\n font-size: 13px;\n color: #888;\n margin-bottom: 16px;\n }\n .onetapforms-close-btn {\n background: #f0f0f0;\n border: none;\n padding: 10px 24px;\n border-radius: 8px;\n cursor: pointer;\n font-size: 14px;\n color: #333;\n transition: background 0.15s;\n }\n .onetapforms-close-btn:hover {\n background: #e0e0e0;\n }\n .onetapforms-spinner {\n width: 200px;\n height: 200px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .onetapforms-spinner::after {\n content: '';\n width: 40px;\n height: 40px;\n border: 3px solid #e0e0e0;\n border-top-color: #007AFF;\n border-radius: 50%;\n animation: onetapforms-spin 0.8s linear infinite;\n }\n @keyframes onetapforms-spin {\n to { transform: rotate(360deg); }\n }\n`;\n\n/**\n * Inject modal styles into the page (once)\n */\nfunction injectStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.getElementById('onetapforms-styles')) return;\n\n const style = document.createElement('style');\n style.id = 'onetapforms-styles';\n style.textContent = MODAL_STYLES;\n document.head.appendChild(style);\n}\n\n/**\n * Create and show a QR modal\n */\nfunction showQRModal(options: {\n title?: string;\n subtitle?: string;\n onClose?: () => void;\n}): {\n setQR: (qrDataUrl: string) => void;\n setStatus: (status: string) => void;\n close: () => void;\n} {\n injectStyles();\n\n const modal = document.createElement('div');\n modal.className = 'onetapforms-modal';\n modal.innerHTML = `\n <div class=\"onetapforms-modal-content\">\n <h3 class=\"onetapforms-modal-title\">${options.title || 'Scan to Complete'}</h3>\n <p class=\"onetapforms-modal-subtitle\">${options.subtitle || 'Scan with your OneTapForms app'}</p>\n <div class=\"onetapforms-qr-container\">\n <div class=\"onetapforms-spinner\"></div>\n </div>\n <p class=\"onetapforms-status\">Waiting for scan...</p>\n <button class=\"onetapforms-close-btn\">Cancel</button>\n </div>\n `;\n\n const qrContainer = modal.querySelector('.onetapforms-qr-container')!;\n const statusEl = modal.querySelector('.onetapforms-status')!;\n const closeBtn = modal.querySelector('.onetapforms-close-btn')!;\n\n const close = () => {\n modal.classList.remove('active');\n setTimeout(() => modal.remove(), 200);\n if (options.onClose) options.onClose();\n };\n\n closeBtn.addEventListener('click', close);\n modal.addEventListener('click', (e) => {\n if (e.target === modal) close();\n });\n\n document.body.appendChild(modal);\n // Trigger animation\n requestAnimationFrame(() => modal.classList.add('active'));\n\n return {\n setQR: (qrDataUrl: string) => {\n qrContainer.innerHTML = `<img src=\"${qrDataUrl}\" alt=\"QR Code\" />`;\n },\n setStatus: (status: string) => {\n statusEl.textContent = status;\n },\n close\n };\n}\n\n/**\n * Initialize widget elements with data-onetapforms attribute\n */\nfunction initWidgets(): void {\n if (typeof document === 'undefined') return;\n\n const widgets = document.querySelectorAll<HTMLElement>('[data-onetapforms]');\n\n widgets.forEach((element) => {\n // Skip if already initialized\n if (element.dataset.onetapformsInit === 'true') return;\n element.dataset.onetapformsInit = 'true';\n\n const clientId = element.dataset.clientId;\n const clientSecret = element.dataset.clientSecret;\n const purpose = element.dataset.purpose || 'Complete form';\n const bundles = element.dataset.bundles?.split(',').map(b => b.trim()) || ['basic'];\n const formId = element.dataset.formId;\n const apiUrl = element.dataset.apiUrl;\n\n if (!clientId) {\n console.error('[OneTapForms] Missing data-client-id attribute');\n return;\n }\n\n // Import OneTapForms dynamically to avoid circular deps\n import('./sdk').then(({ OneTapForms }) => {\n const sdk = new OneTapForms({\n clientId,\n clientSecret,\n apiUrl\n });\n\n element.addEventListener('click', async (e) => {\n e.preventDefault();\n\n let modal: ReturnType<typeof showQRModal> | null = null;\n\n try {\n await sdk.request({\n purpose,\n bundles,\n onQRReady: (qrDataUrl) => {\n modal = showQRModal({\n title: 'Scan with OneTapForms',\n subtitle: purpose,\n onClose: () => sdk.cancelPolling()\n });\n modal.setQR(qrDataUrl);\n },\n onComplete: (result) => {\n if (modal) {\n modal.setStatus('Complete!');\n setTimeout(() => modal?.close(), 500);\n }\n\n // Dispatch custom event with result\n const event = new CustomEvent('onetapforms:complete', {\n bubbles: true,\n detail: result\n });\n element.dispatchEvent(event);\n\n // Auto-inject token into form if formId is specified\n if (formId) {\n const form = document.getElementById(formId) as HTMLFormElement;\n if (form) {\n let tokenInput = form.querySelector('input[name=\"onetapforms_token\"]') as HTMLInputElement;\n if (!tokenInput) {\n tokenInput = document.createElement('input');\n tokenInput.type = 'hidden';\n tokenInput.name = 'onetapforms_token';\n form.appendChild(tokenInput);\n }\n tokenInput.value = result.token;\n }\n }\n },\n onError: (error) => {\n if (modal) modal.close();\n\n const event = new CustomEvent('onetapforms:error', {\n bubbles: true,\n detail: { error }\n });\n element.dispatchEvent(event);\n }\n });\n } catch (error) {\n console.error('[OneTapForms] Request failed:', error);\n\n const event = new CustomEvent('onetapforms:error', {\n bubbles: true,\n detail: { error }\n });\n element.dispatchEvent(event);\n }\n });\n });\n });\n}\n\n// Auto-initialize on DOM ready (for UMD/script tag usage)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initWidgets);\n } else {\n // DOM already ready\n initWidgets();\n }\n\n // Also observe for dynamically added elements\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.addedNodes.length) {\n initWidgets();\n }\n }\n });\n\n if (document.body) {\n observer.observe(document.body, { childList: true, subtree: true });\n } else {\n document.addEventListener('DOMContentLoaded', () => {\n observer.observe(document.body, { childList: true, subtree: true });\n });\n }\n}\n\n// Export widget utilities for advanced usage\nexport { initWidgets, showQRModal };\n"],"names":["OneTapFormsImpl"],"mappings":"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"}
@@ -2133,12 +2133,14 @@ class OneTapForms {
2133
2133
  try {
2134
2134
  this.log("Creating request", options);
2135
2135
  const deviceType = detectDevice();
2136
+ // Default to "auto" mode if not specified - this ensures mobile web works correctly
2137
+ const requestedMode = options.mode || "auto";
2136
2138
  let effectiveMode = "qr";
2137
- if (options.mode === "auto") {
2139
+ if (requestedMode === "auto") {
2138
2140
  effectiveMode = deviceType === "mobile" ? "redirect" : "qr";
2139
- } else if (options.mode === "redirect") {
2141
+ } else if (requestedMode === "redirect") {
2140
2142
  effectiveMode = "redirect";
2141
- } else if (options.mode === "qr") {
2143
+ } else if (requestedMode === "qr") {
2142
2144
  effectiveMode = "qr";
2143
2145
  }
2144
2146
  this.log("Effective mode:", effectiveMode, "Device:", deviceType);