@gait-financial/react 0.1.0 → 0.1.2

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/wc/button.js ADDED
@@ -0,0 +1,958 @@
1
+ (function(I){"use strict";function F(r,t){const e=r.replace("#",""),i=parseInt(e,16),a=i>>16&255,n=i>>8&255,o=i&255,d=Math.max(0,Math.floor(a*(1-t))),l=Math.max(0,Math.floor(n*(1-t))),s=Math.max(0,Math.floor(o*(1-t)));return`#${(d<<16|l<<8|s).toString(16).padStart(6,"0")}`}function q(r){const t=r.replace("#",""),e=parseInt(t,16),i=e>>16&255,a=e>>8&255,n=e&255;return(.299*i+.587*a+.114*n)/255<.5}const h={primary:{main:"rgb(47, 44, 37)",dark:"rgb(35, 33, 28)",contrastText:"#ffffff"}},E={sm:"8px",md:"16px",lg:"24px"},P={md:"8px"},f={normal:"250ms ease-in-out"},O={modalBackdrop:1040},y={fontFamily:{primary:'"Inter", "Helvetica", "Arial", sans-serif'},fontSize:{sm:"0.875rem",md:"1rem",lg:"1.125rem"},fontWeight:{medium:500},lineHeight:{normal:1.5}},g="#4147BF",C="#F3F2FF",B={fee:10};function N(r,t){return{bg:g,bgHover:r(g,.15),bgActive:r(g,.25),color:t(g)?"#ffffff":"#000000"}}function G(r){return{small:{padding:"8px 20px",fontSize:y.fontSize.sm,minHeight:"36px"},medium:{padding:"12px 28px",fontSize:y.fontSize.md,minHeight:"44px"},large:{padding:"16px 36px",fontSize:y.fontSize.lg,minHeight:"52px"}}[r]}function D(r,t,e){const i=N(t,e),a=G(r);return`
2
+ <style>
3
+ :host {
4
+ display: inline-block;
5
+ --gait-button-bg: ${i.bg};
6
+ --gait-button-bg-hover: ${i.bgHover};
7
+ --gait-button-bg-active: ${i.bgActive};
8
+ --gait-button-color: ${i.color};
9
+ --gait-button-padding: ${a.padding};
10
+ --gait-button-font-size: ${a.fontSize};
11
+ --gait-button-min-height: ${a.minHeight};
12
+ }
13
+
14
+ button {
15
+ display: inline-flex;
16
+ align-items: center;
17
+ justify-content: center;
18
+ gap: ${E.sm};
19
+
20
+ font-family: ${y.fontFamily.primary};
21
+ font-weight: ${y.fontWeight.medium};
22
+ line-height: ${y.lineHeight.normal};
23
+ font-size: var(--gait-button-font-size);
24
+
25
+ padding: var(--gait-button-padding);
26
+ min-height: var(--gait-button-min-height);
27
+
28
+ background-color: var(--gait-button-bg);
29
+ color: var(--gait-button-color);
30
+
31
+ border: none;
32
+ border-radius: ${P.md};
33
+ cursor: pointer;
34
+
35
+ transition: all ${f.normal};
36
+
37
+ /* Remove default button styles */
38
+ outline: none;
39
+ text-decoration: none;
40
+ user-select: none;
41
+ will-change: transform, box-shadow;
42
+ }
43
+
44
+ button:hover:not(:disabled) {
45
+ background-color: var(--gait-button-bg-hover);
46
+ }
47
+
48
+ button:active:not(:disabled) {
49
+ background-color: var(--gait-button-bg-active);
50
+ transform: translateY(1px);
51
+ }
52
+
53
+ button:focus-visible {
54
+ outline: 2px solid var(--gait-button-bg);
55
+ outline-offset: 2px;
56
+ }
57
+
58
+ button:disabled {
59
+ opacity: 0.6;
60
+ cursor: not-allowed;
61
+ pointer-events: none;
62
+ }
63
+
64
+ /* Icon + label layout */
65
+ .gait-button-icon {
66
+ display: inline-flex;
67
+ align-items: center;
68
+ flex-shrink: 0;
69
+ }
70
+ .gait-button-icon svg {
71
+ display: block;
72
+ width: 20px;
73
+ height: 20px;
74
+ }
75
+ .gait-button-label {
76
+ margin-left: 6px;
77
+ }
78
+
79
+ /* Allow custom styling via :host */
80
+ :host([style*="width"]) button {
81
+ width: 100%;
82
+ }
83
+ </style>
84
+ `}function V(){if(document.getElementById("gait-modal-styles"))return;const r=document.createElement("style");r.id="gait-modal-styles",r.textContent=`
85
+ /* Modal Backdrop - The overlay behind the modal */
86
+ .gait-modal-backdrop {
87
+ position: fixed;
88
+ top: 0;
89
+ left: 0;
90
+ right: 0;
91
+ bottom: 0;
92
+ background-color: rgba(0, 0, 0, 0.5);
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ z-index: ${O.modalBackdrop};
97
+ opacity: 0;
98
+ transition: opacity ${f.normal};
99
+ overflow: hidden;
100
+ }
101
+
102
+ .gait-modal-backdrop.gait-modal-open {
103
+ opacity: 1;
104
+ }
105
+
106
+ /* Modal Container - The main modal box */
107
+ .gait-modal-container {
108
+ background: #fff;
109
+ border-radius: 12px;
110
+ max-width: 1080px;
111
+ width: 60%;
112
+ max-height: 90vh;
113
+ display: flex;
114
+ flex-direction: column;
115
+ overflow: hidden;
116
+ }
117
+
118
+ .gait-modal-backdrop.gait-modal-open .gait-modal-container {
119
+ transform: scale(1);
120
+ }
121
+
122
+ /* Modal Header - The title section with close icon */
123
+ .gait-modal-header {
124
+ padding: 16px 24px;
125
+ border-bottom: 1px solid #e5e7eb;
126
+ display: flex;
127
+ justify-content: space-between;
128
+ align-items: center;
129
+ }
130
+
131
+ .gait-modal-header-title {
132
+ font-size: 20px;
133
+ font-weight: 600;
134
+ margin: 0;
135
+ }
136
+
137
+ .gait-modal-close-icon {
138
+ background: none;
139
+ border: none;
140
+ padding: 8px;
141
+ border-radius: 999px;
142
+ cursor: pointer;
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: center;
146
+ color: #6b7280;
147
+ width: 36px;
148
+ height: 36px;
149
+ }
150
+
151
+ .gait-modal-close-icon:hover {
152
+ background-color: #f3f4f6;
153
+ color: #111827;
154
+ }
155
+
156
+ .gait-modal-close-icon svg {
157
+ width: 20px;
158
+ height: 20px;
159
+ }
160
+
161
+ /* Modal Body - The content section */
162
+ .gait-modal-body {
163
+ display: flex;
164
+ flex: 1;
165
+ overflow-y: auto;
166
+ }
167
+
168
+
169
+ .gait-modal-right-panel {
170
+ width: 440px;
171
+ padding: 24px;
172
+ border-left: 1px solid #e5e7eb;
173
+ background: #fafafa;
174
+ }
175
+
176
+ /* Responsive: Full screen drawer on mobile */
177
+ @media (max-width: 768px) {
178
+ .gait-modal-backdrop {
179
+ align-items: flex-start;
180
+ justify-content: flex-start;
181
+ padding: 0;
182
+ overflow: hidden;
183
+ }
184
+
185
+ .gait-modal-container {
186
+ max-width: 100%;
187
+ width: 100%;
188
+ height: 100vh;
189
+ max-height: 100vh;
190
+ min-height: 100vh;
191
+ border-radius: 0;
192
+ display: flex;
193
+ flex-direction: column;
194
+ overflow: hidden;
195
+ margin: 0;
196
+ position: relative;
197
+ }
198
+
199
+ .gait-modal-body {
200
+ flex-direction: column;
201
+ flex: 1 1 auto;
202
+ overflow-y: auto;
203
+ overflow-x: hidden;
204
+ -webkit-overflow-scrolling: touch;
205
+ min-height: 0;
206
+ overscroll-behavior: contain;
207
+ }
208
+
209
+ .gait-modal-left-panel {
210
+ border-right: none;
211
+ border-bottom: 1px solid #e5e7eb;
212
+ flex-shrink: 0;
213
+ }
214
+
215
+ .gait-modal-right-panel {
216
+ width: 100%;
217
+ border-left: none;
218
+ flex-shrink: 0;
219
+ }
220
+
221
+ .gait-modal-header {
222
+ flex-shrink: 0;
223
+ position: sticky;
224
+ top: 0;
225
+ background: #fff;
226
+ z-index: 1;
227
+ }
228
+ }
229
+
230
+ .gait-modal-left-panel {
231
+ flex: 1;
232
+ padding: 24px;
233
+ }
234
+
235
+ /* Items Container */
236
+ .gait-modal-items-container {
237
+ display: flex;
238
+ flex-direction: column;
239
+ gap: 16px;
240
+ padding-bottom: 20px;
241
+ border-bottom: 1px solid #e5e7eb;
242
+ margin-bottom: 20px;
243
+ }
244
+
245
+ .gait-modal-item {
246
+ display: flex;
247
+ gap: 16px;
248
+ }
249
+
250
+ .gait-modal-item-image {
251
+ width: 60px;
252
+ height: 40px;
253
+ border-radius: 4px;
254
+ object-fit: cover;
255
+ flex-shrink: 0;
256
+ }
257
+
258
+ .gait-modal-item-meta {
259
+ flex: 1;
260
+ min-width: 0;
261
+ }
262
+
263
+ .gait-modal-item-title {
264
+ font-size: 15px;
265
+ font-weight: 600;
266
+ margin: 0 0 4px;
267
+ }
268
+
269
+ .gait-modal-item-quantity {
270
+ font-size: 13px;
271
+ color: #6b7280;
272
+ }
273
+
274
+ .gait-modal-item-price {
275
+ margin-left: 6px;
276
+ font-size: 13px;
277
+ font-weight: 500;
278
+ color:rgb(10, 10, 10);
279
+ }
280
+
281
+ /* Price Details */
282
+ .gait-modal-price-section {
283
+ margin-bottom: 0;
284
+ }
285
+
286
+ .gait-modal-price-title {
287
+ font-size: 16px;
288
+ font-weight: 600;
289
+ margin-bottom: 12px;
290
+ }
291
+
292
+ .gait-modal-price-item,
293
+ .gait-modal-price-total {
294
+ display: flex;
295
+ justify-content: space-between;
296
+ font-size: 14px;
297
+ margin-bottom: 8px;
298
+ }
299
+
300
+ .gait-modal-price-item.discount {
301
+ color: #059669;
302
+ }
303
+
304
+ .gait-modal-price-total {
305
+ padding-top: 12px;
306
+ margin-top: 12px;
307
+ border-top: 1px solid #e5e7eb;
308
+ font-weight: 600;
309
+ }
310
+
311
+ .gait-modal-price-breakdown-link {
312
+ font-size: 13px;
313
+ color: #6b7280;
314
+ text-decoration: underline;
315
+ cursor: pointer;
316
+ margin-top: 4px;
317
+ display: inline-block;
318
+ }
319
+
320
+ .gait-modal-price-breakdown-link:hover {
321
+ color: #374151;
322
+ }
323
+
324
+ /* Payment Section */
325
+ .gait-modal-payment-section {
326
+ margin-bottom: 0;
327
+ }
328
+
329
+ .gait-modal-payment-header {
330
+ display: flex;
331
+ justify-content: space-between;
332
+ align-items: center;
333
+ margin-bottom: 10px;
334
+ }
335
+
336
+ .gait-modal-payment-header h4 {
337
+ font-size: 16px;
338
+ margin: 0;
339
+ font-weight: 600;
340
+ }
341
+
342
+ .gait-modal-payment-change {
343
+ color: #6b7280;
344
+ text-decoration: underline;
345
+ cursor: pointer;
346
+ font-size: 14px;
347
+ }
348
+
349
+ .gait-modal-payment-change:hover {
350
+ color: #374151;
351
+ }
352
+
353
+ .gait-modal-payment-card {
354
+ padding: 12px;
355
+ border: 1px solid #e5e7eb;
356
+ border-radius: 8px;
357
+ background: #fff;
358
+ font-size: 14px;
359
+ }
360
+
361
+ .gait-modal-payment-icons {
362
+ display: flex;
363
+ gap: 8px;
364
+ margin-top: 10px;
365
+ font-size: 12px;
366
+ color: #6b7280;
367
+ }
368
+
369
+ /* Split Payment Section */
370
+ .gait-modal-split-section {
371
+ margin-bottom: 20px;
372
+ }
373
+
374
+ .gait-modal-split-title {
375
+ font-size: 16px;
376
+ font-weight: 600;
377
+ margin: 0 0 12px;
378
+ color: #111827;
379
+ }
380
+
381
+ .gait-modal-split-options {
382
+ display: flex;
383
+ gap: 8px;
384
+ margin-bottom: 20px;
385
+ flex-wrap: wrap;
386
+ }
387
+
388
+ .gait-modal-split-option {
389
+ flex: 1;
390
+ min-width: 100px;
391
+ padding: 10px 12px;
392
+ font-size: 14px;
393
+ font-weight: 500;
394
+ text-align: center;
395
+ background: #f9fafb;
396
+ border: 1px solid #e5e7eb;
397
+ border-radius: 8px;
398
+ cursor: pointer;
399
+ transition: all ${f.normal};
400
+ color: #6b7280;
401
+ }
402
+
403
+ .gait-modal-split-option:hover {
404
+ border-color: #d1d5db;
405
+ background: #f3f4f6;
406
+ color: #374151;
407
+ }
408
+
409
+ .gait-modal-split-option.selected {
410
+ background: ${C};
411
+ border: 1px solid ${g};
412
+ color: ${g};
413
+ }
414
+
415
+ .gait-modal-email-inputs {
416
+ display: flex;
417
+ flex-direction: column;
418
+ gap: 10px;
419
+ margin-bottom: 12px;
420
+ }
421
+
422
+ .gait-modal-email-input {
423
+ width: 100%;
424
+ padding: 10px 12px;
425
+ font-size: 14px;
426
+ border: 1px solid #e5e7eb;
427
+ border-radius: 8px;
428
+ background: #fff;
429
+ color: #111827;
430
+ outline: none;
431
+ transition: all ${f.normal};
432
+ }
433
+
434
+ .gait-modal-email-input:focus {
435
+ border-color: ${h.primary.main};
436
+ box-shadow: 0 0 0 2px rgba(47, 44, 37, 0.1);
437
+ }
438
+
439
+ .gait-modal-email-input::placeholder {
440
+ color: #9ca3af;
441
+ }
442
+
443
+ .gait-modal-email-item {
444
+ display: flex;
445
+ align-items: center;
446
+ justify-content: space-between;
447
+ padding: 10px 12px;
448
+ font-size: 14px;
449
+ border: 1px solid #e5e7eb;
450
+ border-radius: 8px;
451
+ background: #fff;
452
+ color: #111827;
453
+ position: relative;
454
+ }
455
+
456
+
457
+ .gait-modal-email-item-sent-check {
458
+ width: 16px;
459
+ height: 16px;
460
+ border-radius: 50%;
461
+ background: #10b981;
462
+ display: flex;
463
+ align-items: center;
464
+ justify-content: center;
465
+ color: #fff;
466
+ padding: 2px;
467
+ flex-shrink: 0;
468
+ }
469
+
470
+ .gait-modal-email-item-sent-check svg {
471
+ width: 100%;
472
+ height: 100%;
473
+ }
474
+
475
+ .gait-modal-email-item-email {
476
+ flex: 1;
477
+ min-width: 0;
478
+ overflow: hidden;
479
+ text-overflow: ellipsis;
480
+ white-space: nowrap;
481
+ }
482
+
483
+ .gait-modal-email-item-right {
484
+ display: flex;
485
+ flex-direction: column;
486
+ align-items: flex-end;
487
+ gap: 6px;
488
+ }
489
+
490
+ .gait-modal-email-item-amount-container {
491
+ display: flex;
492
+ align-items: center;
493
+ gap: 8px;
494
+ }
495
+
496
+ .gait-modal-email-item-amount {
497
+ font-weight: 500;
498
+ color: ${h.primary.main};
499
+ font-size: 14px;
500
+ }
501
+
502
+ .gait-modal-email-item-actions {
503
+ display: flex;
504
+ flex-direction: row;
505
+ align-items: center;
506
+ gap: 8px;
507
+ }
508
+
509
+ .gait-modal-email-item-edit,
510
+ .gait-modal-email-item-remove {
511
+ font-size: 13px;
512
+ color: #6b7280;
513
+ background: none;
514
+ border: none;
515
+ cursor: pointer;
516
+ padding: 2px 4px;
517
+ transition: color ${f.normal};
518
+ }
519
+
520
+ .gait-modal-email-item-edit:hover,
521
+ .gait-modal-email-item-remove:hover {
522
+ color: ${h.primary.main};
523
+ }
524
+
525
+ /* For "By amount" mode - two input fields side by side */
526
+ .gait-modal-email-amount-row {
527
+ display: flex;
528
+ gap: 8px;
529
+ width: 100%;
530
+ }
531
+
532
+ .gait-modal-email-amount-row .gait-modal-email-input {
533
+ flex: 1;
534
+ }
535
+
536
+ .gait-modal-email-amount-row .gait-modal-email-amount-input {
537
+ width: 120px;
538
+ flex: 0 0 120px;
539
+ }
540
+
541
+ .gait-modal-done-button {
542
+ padding: 8px 16px;
543
+ font-size: 13px;
544
+ font-weight: 500;
545
+ border: 1px solid ${h.primary.main};
546
+ border-radius: 6px;
547
+ background: ${h.primary.main};
548
+ color: ${h.primary.contrastText};
549
+ cursor: pointer;
550
+ transition: all ${f.normal};
551
+ white-space: nowrap;
552
+ }
553
+
554
+ .gait-modal-done-button:hover {
555
+ background: ${h.primary.dark};
556
+ border-color: ${h.primary.dark};
557
+ }
558
+
559
+ .gait-modal-email-amount-input {
560
+ width: 80px;
561
+ padding: 6px 8px;
562
+ font-size: 13px;
563
+ border: 1px solid #e5e7eb;
564
+ border-radius: 6px;
565
+ background: #fff;
566
+ color: #111827;
567
+ outline: none;
568
+ text-align: right;
569
+ }
570
+
571
+ .gait-modal-email-amount-input:focus {
572
+ border-color: ${h.primary.main};
573
+ box-shadow: 0 0 0 2px rgba(47, 44, 37, 0.1);
574
+ }
575
+
576
+ .gait-modal-add-email-button {
577
+ padding: 8px 12px;
578
+ font-size: 13px;
579
+ color: #6b7280;
580
+ background: none;
581
+ border: none;
582
+ cursor: pointer;
583
+ text-align: left;
584
+ transition: color ${f.normal};
585
+ }
586
+
587
+ .gait-modal-add-email-button:hover {
588
+ color: ${h.primary.main};
589
+ text-decoration: underline;
590
+ }
591
+
592
+ .gait-modal-split-summary {
593
+ margin-top: 20px;
594
+ padding-top: 16px;
595
+ border-top: 1px solid #e5e7eb;
596
+ }
597
+
598
+ .gait-modal-split-summary-title {
599
+ font-size: 14px;
600
+ font-weight: 600;
601
+ margin: 0 0 8px;
602
+ color: #111827;
603
+ }
604
+
605
+ .gait-modal-split-amount {
606
+ font-size: 18px;
607
+ font-weight: 600;
608
+ color: ${g};
609
+ }
610
+
611
+ .gait-modal-send-split-button {
612
+ width: 100%;
613
+ padding: 12px;
614
+ font-size: 14px;
615
+ font-weight: 500;
616
+ border-radius: 8px;
617
+ border: 1px solid ${g};
618
+ background: ${C};
619
+ color: ${g};
620
+ cursor: pointer;
621
+ transition: all ${f.normal};
622
+ margin-top: 16px;
623
+ }
624
+
625
+ .gait-modal-send-split-button:hover {
626
+ background: ${C};
627
+ filter: brightness(0.98);
628
+ }
629
+
630
+ .gait-modal-send-split-button:active {
631
+ transform: translateY(1px);
632
+ }
633
+
634
+ .gait-modal-send-split-button:disabled {
635
+ opacity: 0.6;
636
+ cursor: not-allowed;
637
+ }
638
+
639
+ .gait-modal-confirm-button-with-amount {
640
+ width: 100%;
641
+ padding: 14px;
642
+ font-size: 15px;
643
+ font-weight: 600;
644
+ border-radius: 10px;
645
+ border: none;
646
+ background: var(--gait-modal-button-bg, ${h.primary.main});
647
+ color: var(--gait-modal-button-color, ${h.primary.contrastText});
648
+ cursor: pointer;
649
+ transition: all ${f.normal};
650
+ margin-top: 12px;
651
+ display: flex;
652
+ flex-direction: row;
653
+ align-items: center;
654
+
655
+ justify-content: center;
656
+ gap: 4px;
657
+ }
658
+
659
+ .gait-modal-confirm-button-with-amount:hover {
660
+ background-color: var(--gait-modal-button-bg-hover, ${h.primary.dark});
661
+ }
662
+
663
+ .gait-modal-confirm-button-with-amount:active {
664
+ transform: translateY(1px);
665
+ }
666
+
667
+ .gait-modal-confirm-button-label {
668
+ font-size: 15px;
669
+ font-weight: 600;
670
+ }
671
+
672
+ .gait-modal-confirm-button-amount {
673
+ font-size: 13px;
674
+ font-weight: 500;
675
+ opacity: 0.9;
676
+ }
677
+
678
+ /* Terms */
679
+ .gait-modal-terms {
680
+ font-size: 12px;
681
+ color: #6b7280;
682
+ margin: 16px 0;
683
+ line-height: 1.5;
684
+ }
685
+
686
+ .gait-modal-terms a {
687
+ text-decoration: underline;
688
+ cursor: pointer;
689
+ color: #6b7280;
690
+ }
691
+
692
+ .gait-modal-terms a:hover {
693
+ color: #374151;
694
+ }
695
+
696
+ /* Confirm Button */
697
+ .gait-modal-confirm-button {
698
+ width: 100%;
699
+ padding: 14px;
700
+ font-size: 15px;
701
+ font-weight: 600;
702
+ border-radius: 10px;
703
+ border: none;
704
+ background: var(--gait-modal-button-bg, #e91e63);
705
+ color: var(--gait-modal-button-color, #fff);
706
+ cursor: pointer;
707
+ transition: all ${f.normal};
708
+ }
709
+
710
+ .gait-modal-confirm-button:hover {
711
+ background-color: var(--gait-modal-button-bg-hover, #c2185b);
712
+ }
713
+
714
+ .gait-modal-confirm-button:active {
715
+ transform: translateY(1px);
716
+ }
717
+
718
+ /* Modal Footer - The button section */
719
+ .gait-modal-footer {
720
+ padding: ${E.lg};
721
+ border-top: 1px solid #e5e7eb;
722
+ display: flex;
723
+ justify-content: flex-end;
724
+ gap: ${E.md};
725
+ }
726
+
727
+ /* Modal Button - The close button */
728
+ .gait-modal-button {
729
+ padding: ${E.sm} ${E.lg};
730
+ font-family: ${y.fontFamily.primary};
731
+ font-size: ${y.fontSize.md};
732
+ font-weight: ${y.fontWeight.medium};
733
+ border: none;
734
+ border-radius: ${P.md};
735
+ cursor: pointer;
736
+ transition: all ${f.normal};
737
+ background-color: ${h.primary.main};
738
+ color: ${h.primary.contrastText};
739
+ }
740
+
741
+ .gait-modal-button:hover {
742
+ background-color: ${h.primary.dark};
743
+ }
744
+
745
+ .gait-modal-button:active {
746
+ transform: translateY(1px);
747
+ }
748
+
749
+ /* Split Payment Feedback Banner */
750
+ .gait-modal-feedback {
751
+ display: flex;
752
+ align-items: center;
753
+ gap: 12px;
754
+ padding: 12px 16px;
755
+ border-radius: 8px;
756
+ margin-bottom: 16px;
757
+ font-size: 14px;
758
+ font-weight: 500;
759
+ animation: slideDown 0.3s ease-out;
760
+ transition: opacity 0.3s ease-out;
761
+ }
762
+
763
+ @keyframes slideDown {
764
+ from {
765
+ opacity: 0;
766
+ transform: translateY(-10px);
767
+ }
768
+ to {
769
+ opacity: 1;
770
+ transform: translateY(0);
771
+ }
772
+ }
773
+
774
+ .gait-modal-feedback-icon {
775
+ display: flex;
776
+ align-items: center;
777
+ justify-content: center;
778
+ width: 16px;
779
+ height: 16px;
780
+ border-radius: 50%;
781
+ flex-shrink: 0;
782
+ padding: 2px;
783
+ }
784
+
785
+ .gait-modal-feedback-icon svg {
786
+ width: 100%;
787
+ height: 100%;
788
+ }
789
+
790
+ .gait-modal-feedback-message {
791
+ flex: 1;
792
+ line-height: 1.4;
793
+ }
794
+
795
+ .gait-modal-feedback-loading {
796
+ background-color: #f0f9ff;
797
+ border: 1px solid #bae6fd;
798
+ color: #0369a1;
799
+ }
800
+
801
+ .gait-modal-feedback-loading .gait-modal-feedback-icon {
802
+ background-color: #0ea5e9;
803
+ color: #fff;
804
+ animation: spin 1s linear infinite;
805
+ }
806
+
807
+ @keyframes spin {
808
+ from {
809
+ transform: rotate(0deg);
810
+ }
811
+ to {
812
+ transform: rotate(360deg);
813
+ }
814
+ }
815
+
816
+ .gait-modal-feedback-success {
817
+ background-color: #f0fdf4;
818
+ border: 1px solid #bbf7d0;
819
+ color: #166534;
820
+ }
821
+
822
+ .gait-modal-feedback-success .gait-modal-feedback-icon {
823
+ background-color: #22c55e;
824
+ color: #fff;
825
+ }
826
+
827
+ .gait-modal-feedback-error {
828
+ background-color: #fef2f2;
829
+ border: 1px solid #fecaca;
830
+ color: #991b1b;
831
+ }
832
+
833
+ .gait-modal-feedback-error .gait-modal-feedback-icon {
834
+ background-color: #ef4444;
835
+ color: #fff;
836
+ }
837
+ `,document.head.appendChild(r)}const j='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 311.96 313.95" width="20" height="20" aria-hidden="true"><path fill="currentColor" d="M168.07,139.33c6.81-15.69,22.45-26.66,40.65-26.66s33.83,10.97,40.66,26.66h62.58C303.19,60.94,236.71,0,155.98,0S8.77,60.95,0,139.33h168.07Z"/><path fill="currentColor" d="M249.37,174.62c-6.81,15.68-22.46,26.65-40.65,26.65s-33.82-10.97-40.64-26.65H0c8.77,78.39,75.25,139.33,155.98,139.33s147.21-60.94,155.98-139.33h-62.59Z"/></svg>';function H(r,t){return`
838
+ <button
839
+ type="button"
840
+ ${r?"disabled":""}
841
+ style="${t}"
842
+ >
843
+ <span class="gait-button-icon">${j}</span>
844
+ <span class="gait-button-label">Gait</span>
845
+ </button>
846
+ `}function A(r){return`R ${r.toFixed(2)}`}const _=`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
847
+ <path d="M18 6L6 18M6 6l12 12" />
848
+ </svg>
849
+ `,$=`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
850
+ <path d="M20 6L9 17l-5-5" />
851
+ </svg>
852
+ `,U=`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
853
+ <path d="M18 6L6 18M6 6l12 12" />
854
+ </svg>
855
+ `,W=`<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
856
+ <path d="M21 12a9 9 0 11-6.22-8.56" />
857
+ </svg>
858
+ `;function J(r){return!r||r.length===0?"":r.map(t=>`
859
+ <div class="gait-modal-item">
860
+ <img
861
+ src="${t.image||""}"
862
+ alt="${t.name||"Product"}"
863
+ class="gait-modal-item-image"
864
+ />
865
+ <div class="gait-modal-item-meta">
866
+ <h3 class="gait-modal-item-title">
867
+ ${t.name||""}
868
+ </h3>
869
+ <div class="gait-modal-item-quantity">
870
+ Qty: ${t.quantity||0}
871
+ <span class="gait-modal-item-price">${A(t.price||0)}</span>
872
+ </div>
873
+ </div>
874
+ </div>
875
+ `).join("")}function Y(r){return!r||r.length===0?"":r.map(t=>{const e=typeof t.price=="number"?t.price:parseFloat(String(t.price))||0;return`
876
+ <div class="gait-modal-price-item">
877
+ <span>${t.name||""}</span>
878
+ <span>${A(e)}</span>
879
+ </div>
880
+ `}).join("")}function K(r,t,e){return`
881
+ <div class="gait-modal-container">
882
+ <div class="gait-modal-header">
883
+ <h2 class="gait-modal-header-title">Split Payment</h2>
884
+ <button class="gait-modal-close-icon" data-gait-modal-close aria-label="Close">
885
+ ${_}
886
+ </button>
887
+ </div>
888
+
889
+ <div class="gait-modal-body">
890
+ <!-- LEFT -->
891
+ <div class="gait-modal-left-panel">
892
+ <div class="gait-modal-items-container">
893
+ ${J(r)}
894
+ </div>
895
+
896
+ <div class="gait-modal-price-section">
897
+ <h4 class="gait-modal-price-title">Price details</h4>
898
+
899
+ ${Y(t)}
900
+
901
+ ${e>0?`
902
+ <div class="gait-modal-price-total">
903
+ <span>Total</span>
904
+ <span>${A(e)}</span>
905
+ </div>
906
+ `:""}
907
+ </div>
908
+ </div>
909
+
910
+ <!-- RIGHT -->
911
+ <div class="gait-modal-right-panel">
912
+ <div class="gait-modal-split-section">
913
+ <!-- Feedback banner will be inserted here dynamically -->
914
+ <h4 class="gait-modal-split-title">How to split</h4>
915
+
916
+ <div class="gait-modal-split-options">
917
+ <div class="gait-modal-split-option selected" data-split-method="equally">Equally</div>
918
+ <div class="gait-modal-split-option" data-split-method="by-amount">By amount</div>
919
+ </div>
920
+
921
+ <div class="gait-modal-email-inputs" data-email-inputs>
922
+ </div>
923
+
924
+ <button class="gait-modal-add-email-button" data-add-email>
925
+ Add someone
926
+ </button>
927
+
928
+ <button class="gait-modal-send-split-button" data-send-split>
929
+ Send split
930
+ </button>
931
+
932
+ <button class="gait-modal-confirm-button-with-amount" data-gait-modal-confirm>
933
+ <span class="gait-modal-confirm-button-label">Pay remaining - </span>
934
+ <span class="gait-modal-confirm-button-amount" data-confirm-amount>R 0.00</span>
935
+ </button>
936
+ </div>
937
+ </div>
938
+ </div>
939
+ </div>
940
+ `}function Z(r){const t={};return Array.from(r.attributes).forEach(e=>{e.name.startsWith("data-")&&(t[e.name]=e.value)}),t}function Q(r){const t={};return Array.from(r.attributes).forEach(e=>{t[e.name]=e.value}),t}function X(r){return{get dataId(){return r.getAttribute("data-id")||null},get disabled(){return r.hasAttribute("disabled")&&r.getAttribute("disabled")!=="false"},get size(){return r.getAttribute("size")||"medium"},get items(){const t=r.getAttribute("items");if(!t)return[];try{return JSON.parse(t)}catch(e){return console.warn("[GaitButton] Failed to parse items attribute:",e),[]}},get totalCost(){const t=r.getAttribute("total-cost");if(!t)return 0;const e=parseFloat(t);return(isNaN(e)?0:e)+B.fee},get priceBreakdown(){const t=r.getAttribute("total-cost"),e=parseFloat(t||"0");return[{name:"Subtotal",price:isNaN(e)?0:e},{name:"Split Payment Fee",price:B.fee}]},get customer(){const t=r.getAttribute("customer");if(!t)return null;try{return JSON.parse(t)}catch(e){return console.warn("[GaitButton] Failed to parse customer attribute:",e),null}},get webhook(){const t=r.getAttribute("webhook");if(!t)return null;try{return JSON.parse(t)}catch(e){return console.warn("[GaitButton] Failed to parse webhook attribute:",e),null}},get merchantStoreUrl(){const t=r.getAttribute("merchant-store-url");return t&&t.trim()!==""?t.trim():typeof window<"u"&&window.location?window.location.origin:""}}}function v(r){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r)}function L(r,t,e){if(e.length===0)return r;if(t==="equally"){const i=e.length+1,a=r/i;return Math.max(0,r-a*e.length)}else if(t==="by-amount"){let i=0;return e.forEach(a=>{const n=a.amount||0;i+=n}),Math.max(0,r-i)}return r}function w(r,t){return r/t}function R(r,t,e){const i=[],a=r.querySelectorAll("[data-email-item]");return a.forEach(n=>{const o=n.getAttribute("data-email-item")||"";if(o)if(t==="by-amount"){const d=n.querySelector(".gait-modal-email-item-amount"),l=d&&parseFloat(d.textContent?.replace(/[^\d.]/g,"")||"0")||0;i.push({email:o,amount:l})}else{const d=a.length+1,l=w(e,d);i.push({email:o,amount:l})}}),i}function z(r){const t=r.querySelectorAll("[data-email-item]"),e=r.querySelectorAll("[data-email-input]");return t.length+e.length}class tt{modalElement;totalCost;currentSplitMethod="equally";dispatchEventFn;isSplitSent=!1;isSplitLoading=!1;splitFeedbackElement=null;feedbackHandler=null;constructor(t,e,i){this.modalElement=t,this.totalCost=e,this.dispatchEventFn=i,this.setup(),this.setupFeedbackListener()}setup(){const t=this.modalElement.querySelectorAll("[data-split-method]"),e=this.modalElement.querySelector("[data-email-inputs]"),i=this.modalElement.querySelector("[data-add-email]"),a=this.modalElement.querySelector("[data-send-split]");!e||!i||!a||(t.forEach(n=>{n.addEventListener("click",()=>{if(this.isSplitSent)return;t.forEach(l=>l.classList.remove("selected")),n.classList.add("selected");const o=n.getAttribute("data-split-method")||"equally",d=this.currentSplitMethod;this.currentSplitMethod=o,d!==o&&this.updateActiveInputsForSplitMethod(d,o),this.updateEmailItemsForSplitMethod(),this.updateSplitCalculation()})}),i.addEventListener("click",()=>this.addEmailField()),e.addEventListener("input",n=>{n.target.hasAttribute("data-email-input")&&this.updateSplitCalculation()}),a.addEventListener("click",()=>this.handleSendSplit()),this.updateSplitCalculation())}addEmailField(){if(this.isSplitSent)return;const t=this.modalElement.querySelector("[data-email-inputs]");if(!t)return;const e=this.findEmptyInput(t);if(e){if(e instanceof HTMLInputElement)e.focus();else{const i=e.querySelector("[data-email-input]");i&&i.focus()}return}this.currentSplitMethod==="by-amount"?this.addByAmountInput(t):this.addEquallyInput(t)}findEmptyInput(t){if(this.currentSplitMethod==="by-amount"){const e=t.querySelectorAll(".gait-modal-email-amount-row");for(const i of Array.from(e)){const a=i.querySelector("[data-email-input]");if(a&&!a.value.trim())return i}}else{const e=t.querySelectorAll("[data-email-input]");for(const i of Array.from(e))if(!i.parentElement?.classList.contains("gait-modal-email-amount-row")&&!i.value.trim())return i}return null}removeEmptyInputs(t){t.querySelectorAll(".gait-modal-email-amount-row").forEach(a=>{const n=a.querySelector("[data-email-input]");n&&!n.value.trim()&&t.removeChild(a)}),t.querySelectorAll("[data-email-input]").forEach(a=>{a.parentElement?.classList.contains("gait-modal-email-amount-row")||a.value.trim()||t.removeChild(a)})}calculateRemainingAmount(t){const e=this.modalElement.querySelector("[data-email-inputs]");if(!e)return this.totalCost;let i=0;return e.querySelectorAll("[data-email-item]").forEach(d=>{const l=d.querySelector(".gait-modal-email-item-amount");if(l){const s=l.textContent||"0.00",m=parseFloat(s.replace(/[^\d.]/g,""))||0;i+=m}}),e.querySelectorAll(".gait-modal-email-amount-row").forEach(d=>{if(d===t)return;const l=d.querySelector("[data-email-amount-input]");if(l&&l.value){const s=parseFloat(l.value)||0;i+=s}}),Math.max(0,this.totalCost-i)}updateAmountInputMaxValues(t){const e=this.modalElement.querySelector("[data-email-inputs]");if(!e)return;const i=this.calculateRemainingAmount(t),a=i.toFixed(2);e.querySelectorAll("[data-email-amount-input]").forEach(o=>{o.closest(".gait-modal-email-amount-row")!==t&&(o.max=a,(parseFloat(o.value)||0)>i&&(o.value=a,o.style.borderColor="#ef4444",setTimeout(()=>{o.style.borderColor=""},2e3)))})}addByAmountInput(t){const e=document.createElement("div");e.className="gait-modal-email-amount-row";const i=document.createElement("input");i.type="email",i.className="gait-modal-email-input",i.placeholder="Email address",i.setAttribute("data-email-input","");const a=document.createElement("input");a.type="number",a.className="gait-modal-email-amount-input",a.placeholder="0.00",a.step="0.01",a.min="0",a.setAttribute("data-email-amount-input","");const n=this.calculateRemainingAmount();a.max=n.toFixed(2);const o=document.createElement("button");o.type="button",o.className="gait-modal-done-button",o.textContent="Done",o.setAttribute("data-done-email","");const d=()=>{const l=i.value.trim();let s=parseFloat(a.value)||0;const m=this.calculateRemainingAmount(e);if(s>m&&(s=m,a.value=m.toFixed(2),a.style.borderColor="#ef4444",setTimeout(()=>{a.style.borderColor=""},2e3)),l&&v(l)){const u=this.createEmailItem(l,s);t.replaceChild(u,e),this.updateSplitCalculation(),this.updateAmountInputMaxValues()}else l||(t.removeChild(e),this.updateAmountInputMaxValues())};a.addEventListener("input",()=>{const l=this.calculateRemainingAmount(e);(parseFloat(a.value)||0)>l?(a.value=l.toFixed(2),a.style.borderColor="#ef4444",setTimeout(()=>{a.style.borderColor=""},2e3)):a.style.borderColor="",this.updateAmountInputMaxValues(e)}),o.addEventListener("click",d),i.addEventListener("blur",()=>{!i.value.trim()&&!a.value&&setTimeout(()=>{e.parentElement&&!i.value.trim()&&t.removeChild(e)},100)}),e.appendChild(i),e.appendChild(a),e.appendChild(o),t.appendChild(e),i.focus()}addEquallyInput(t){const e=document.createElement("input");e.type="email",e.className="gait-modal-email-input",e.placeholder="Email address",e.setAttribute("data-email-input","");const i=()=>{const a=e.value.trim();a&&v(a)&&(this.convertInputToEmailItem(e),this.updateSplitCalculation())};e.addEventListener("blur",()=>{const a=e.value.trim();a&&v(a)?i():a||setTimeout(()=>{e.parentElement&&!e.value.trim()&&t.removeChild(e)},100)}),e.addEventListener("keydown",a=>{a.key==="Enter"&&(a.preventDefault(),i())}),t.appendChild(e),e.focus()}createEmailItem(t,e=0,i=!1){const a=document.createElement("div");a.className=`gait-modal-email-item${i?" sent":""}`,a.setAttribute("data-email-item",t);let n=e;if(this.currentSplitMethod==="equally"){const s=this.modalElement.querySelector("[data-email-inputs]"),m=s?z(s)+1:2;n=w(this.totalCost,m)}const o=i?`<div class="gait-modal-email-item-sent-check">${$}</div>`:"";a.innerHTML=`
941
+ <span class="gait-modal-email-item-email">${t}</span>
942
+ <div class="gait-modal-email-item-right">
943
+ <div class="gait-modal-email-item-amount-container">
944
+ <span class="gait-modal-email-item-amount">R ${n.toFixed(2)}</span>
945
+ ${o}
946
+ </div>
947
+ <div class="gait-modal-email-item-actions">
948
+ <button class="gait-modal-email-item-edit" data-edit-email="${t}">Edit</button>
949
+ <button class="gait-modal-email-item-remove" data-remove-email="${t}">Remove</button>
950
+ </div>
951
+ </div>
952
+ `;const d=a.querySelector(`[data-edit-email="${t}"]`);d&&d.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation(),this.convertEmailItemToInput(a)});const l=a.querySelector(`[data-remove-email="${t}"]`);return l&&l.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation(),this.removeEmailItem(a)}),a}convertEmailItemToInput(t){if(!t.parentElement)return;const i=t.getAttribute("data-email-item")||"";if(this.currentSplitMethod==="by-amount"){const a=document.createElement("div");a.className="gait-modal-email-amount-row";const n=document.createElement("input");n.type="email",n.className="gait-modal-email-input",n.placeholder="Email address",n.setAttribute("data-email-input",""),n.value=i;const o=document.createElement("input");o.type="number",o.className="gait-modal-email-amount-input",o.placeholder="0.00",o.step="0.01",o.min="0",o.setAttribute("data-email-amount-input","");const d=t.querySelector(".gait-modal-email-item-amount");let l=0;if(d){const u=d.textContent||"0.00";l=parseFloat(u.replace(/[^\d.]/g,""))||0,o.value=l.toFixed(2)}const s=this.calculateRemainingAmount(a)+l;o.max=s.toFixed(2);const m=document.createElement("button");m.type="button",m.className="gait-modal-done-button",m.textContent="Done",m.setAttribute("data-done-email",""),m.addEventListener("click",()=>{const u=n.value.trim();let c=parseFloat(o.value)||0;const p=this.calculateRemainingAmount(a)+l;if(c>p&&(c=p,o.value=p.toFixed(2),o.style.borderColor="#ef4444",setTimeout(()=>{o.style.borderColor=""},2e3)),u&&v(u)){const b=this.createEmailItem(u,c);a.parentElement&&a.parentElement.replaceChild(b,a),this.updateSplitCalculation(),this.updateAmountInputMaxValues()}else u||(a.parentElement&&a.parentElement.removeChild(a),this.updateAmountInputMaxValues())}),o.addEventListener("input",()=>{const u=this.calculateRemainingAmount(a)+l;(parseFloat(o.value)||0)>u?(o.value=u.toFixed(2),o.style.borderColor="#ef4444",setTimeout(()=>{o.style.borderColor=""},2e3)):o.style.borderColor="",this.updateAmountInputMaxValues(a)}),a.appendChild(n),a.appendChild(o),a.appendChild(m),t.parentElement&&t.parentElement.replaceChild(a,t),n.focus(),n.select()}else{const a=document.createElement("input");a.type="email",a.className="gait-modal-email-input",a.placeholder="Email address",a.setAttribute("data-email-input",""),a.value=i;const n=()=>{const o=a.value.trim();o&&v(o)?(this.convertInputToEmailItem(a),this.updateSplitCalculation()):o||setTimeout(()=>{a.parentElement&&!a.value.trim()&&a.parentElement.removeChild(a)},100)};a.addEventListener("blur",n),a.addEventListener("keydown",o=>{o.key==="Enter"&&(o.preventDefault(),n())}),t.parentElement&&t.parentElement.replaceChild(a,t),a.focus(),a.select()}}convertInputToEmailItem(t){const e=t.value.trim();if(!e||!v(e))return;const i=t.parentElement;if(!i)return;const a=z(i)+1,n=this.currentSplitMethod==="equally"?w(this.totalCost,a):0,o=this.createEmailItem(e,n);i.replaceChild(o,t)}removeEmailItem(t){const e=t.parentElement;e&&(e.removeChild(t),this.updateSplitCalculation(),this.updateAmountInputMaxValues())}updateActiveInputsForSplitMethod(t,e){const i=this.modalElement.querySelector("[data-email-inputs]");i&&(this.removeEmptyInputs(i),t==="equally"&&e==="by-amount"&&Array.from(i.querySelectorAll("[data-email-input]")).filter(n=>!n.parentElement?.classList.contains("gait-modal-email-amount-row")).forEach(n=>{const o=n.value.trim(),d=n.parentElement;if(!d)return;const l=document.createElement("div");l.className="gait-modal-email-amount-row";const s=document.createElement("input");s.type="email",s.className="gait-modal-email-input",s.placeholder="Email address",s.setAttribute("data-email-input",""),s.value=o;const m=document.createElement("input");m.type="number",m.className="gait-modal-email-amount-input",m.placeholder="0.00",m.step="0.01",m.min="0",m.setAttribute("data-email-amount-input","");const u=this.calculateRemainingAmount(l);m.max=u.toFixed(2);const c=document.createElement("button");c.type="button",c.className="gait-modal-done-button",c.textContent="Done",c.setAttribute("data-done-email",""),c.addEventListener("click",()=>{const p=s.value.trim();let b=parseFloat(m.value)||0;const T=this.calculateRemainingAmount(l);if(b>T&&(b=T,m.value=T.toFixed(2),m.style.borderColor="#ef4444",setTimeout(()=>{m.style.borderColor=""},2e3)),p&&v(p)){const st=this.createEmailItem(p,b);d.replaceChild(st,l),this.updateSplitCalculation(),this.updateAmountInputMaxValues()}}),m.addEventListener("input",()=>{const p=this.calculateRemainingAmount(l);(parseFloat(m.value)||0)>p?(m.value=p.toFixed(2),m.style.borderColor="#ef4444",setTimeout(()=>{m.style.borderColor=""},2e3)):m.style.borderColor="",this.updateAmountInputMaxValues(l)}),l.appendChild(s),l.appendChild(m),l.appendChild(c),d.replaceChild(l,n),s.focus()}),t==="by-amount"&&e==="equally"&&i.querySelectorAll(".gait-modal-email-amount-row").forEach(n=>{const o=n.querySelector("[data-email-input]");if(!o)return;const d=o.value.trim(),l=n.parentElement;if(!l)return;const s=document.createElement("input");s.type="email",s.className="gait-modal-email-input",s.placeholder="Email address",s.setAttribute("data-email-input",""),s.value=d;const m=()=>{const u=s.value.trim();u&&v(u)&&(this.convertInputToEmailItem(s),this.updateSplitCalculation())};s.addEventListener("blur",m),s.addEventListener("keydown",u=>{u.key==="Enter"&&(u.preventDefault(),m())}),l.replaceChild(s,n),s.focus()}))}updateEmailItemsForSplitMethod(){const t=this.modalElement.querySelector("[data-email-inputs]");if(!t)return;const e=t.querySelectorAll("[data-email-item]"),i=e.length+1;e.forEach(a=>{const n=a.querySelector(".gait-modal-email-item-right");if(!n)return;const o=n.querySelector(".gait-modal-email-item-amount");if(o){if(this.currentSplitMethod==="equally"){const d=w(this.totalCost,i);o.textContent=`R ${d.toFixed(2)}`}else if(this.currentSplitMethod==="by-amount"){const d=o.textContent||"R 0.00",l=parseFloat(d.replace(/[^\d.]/g,""))||0;o.textContent=`R ${l.toFixed(2)}`}}})}updateSplitCalculation(){const t=this.modalElement.querySelector("[data-email-inputs]"),e=this.modalElement.querySelector("[data-confirm-amount]");if(!t||!e)return;const i=R(t,this.currentSplitMethod,this.totalCost),a=t.querySelectorAll("[data-email-input]");a.forEach(o=>{const d=o.value.trim();if(d&&v(d)){const l=i.length+a.length+1,s=this.currentSplitMethod==="equally"?w(this.totalCost,l):0;i.push({email:d,amount:s})}});const n=i.length>0?L(this.totalCost,this.currentSplitMethod,i):this.totalCost;e.textContent=`R ${n.toFixed(2)}`,this.currentSplitMethod==="by-amount"&&this.updateAmountInputMaxValues()}handleSendSplit(){const t=this.modalElement.querySelector("[data-email-inputs]"),e=this.modalElement.querySelector("[data-send-split]");if(!t||!e)return;const i=R(t,this.currentSplitMethod,this.totalCost);if(i.length===0){this.showFeedback("Please add at least one email address","error");return}if(this.isSplitSent||this.isSplitLoading)return;this.isSplitLoading=!0,e.disabled=!0,e.textContent="Sending...",this.showFeedback("Sending split payment...","loading");const a=L(this.totalCost,this.currentSplitMethod,i);this.dispatchEventFn(new CustomEvent("gait-split-sent",{detail:{splitMethod:this.currentSplitMethod,emails:i.map(n=>n.email),emailData:i,totalCost:this.totalCost,yourAmount:a,timestamp:new Date().toISOString()},bubbles:!0,composed:!0}))}setupFeedbackListener(){this.feedbackHandler=t=>{const e=t;e.detail&&this.handleSplitFeedback(e.detail)},document.addEventListener("gait-split-feedback",this.feedbackHandler)}cleanup(){this.feedbackHandler&&(document.removeEventListener("gait-split-feedback",this.feedbackHandler),this.feedbackHandler=null)}handleSplitFeedback(t){this.isSplitLoading=!1;const e=this.modalElement.querySelector("[data-send-split]");t.success?(this.isSplitSent=!0,this.markEmailsAsSent(),this.disableSplitOptions(),e&&(e.disabled=!0,e.textContent="Split sent!"),this.showFeedback(t.message||"Split payment sent successfully","success")):(e&&(e.disabled=!1,e.textContent="Send split"),this.showFeedback(t.message||t.error||"Failed to send split payment","error"))}markEmailsAsSent(){const t=this.modalElement.querySelector("[data-email-inputs]");if(!t)return;t.querySelectorAll("[data-email-item]").forEach(i=>{if(!i.classList.contains("sent")){i.classList.add("sent");const a=i.querySelector(".gait-modal-email-item-right");if(a){let o=a.querySelector(".gait-modal-email-item-amount-container");const d=a.querySelector(".gait-modal-email-item-amount");if(!o&&d&&(o=document.createElement("div"),o.className="gait-modal-email-item-amount-container",d.parentElement?.replaceChild(o,d),o.appendChild(d)),o&&!o.querySelector(".gait-modal-email-item-sent-check")){const l=document.createElement("div");l.className="gait-modal-email-item-sent-check",l.innerHTML=$,o.appendChild(l)}}const n=i.querySelector(".gait-modal-email-item-actions");n&&(n.style.display="none")}})}showFeedback(t,e){this.splitFeedbackElement&&(this.splitFeedbackElement.remove(),this.splitFeedbackElement=null);const i=document.createElement("div");i.className=`gait-modal-feedback gait-modal-feedback-${e}`,i.setAttribute("data-split-feedback","");const a=e==="success"?$:e==="error"?U:W;i.innerHTML=`
953
+ <span class="gait-modal-feedback-icon">${a}</span>
954
+ <span class="gait-modal-feedback-message">${t}</span>
955
+ `;const n=this.modalElement.querySelector(".gait-modal-split-section");n&&(n.insertBefore(i,n.firstChild),this.splitFeedbackElement=i,e!=="loading"&&setTimeout(()=>{this.splitFeedbackElement===i&&(i.style.opacity="0",setTimeout(()=>{i.parentElement&&i.remove(),this.splitFeedbackElement===i&&(this.splitFeedbackElement=null)},300))},5e3))}disableSplitOptions(){this.modalElement.querySelectorAll("[data-split-method]").forEach(i=>{const a=i;a.style.pointerEvents="none",a.style.opacity="0.5",a.style.cursor="not-allowed",a.setAttribute("aria-disabled","true")});const e=this.modalElement.querySelector("[data-add-email]");e&&(e.style.pointerEvents="none",e.style.opacity="0.5",e.style.cursor="not-allowed",e.setAttribute("aria-disabled","true"))}}async function et(r,t=2e3){console.log("[SplitPaymentAPI] Sending split payment request:",r);const e="https://api.usegait.com/checkout";try{const a=await(await fetch(`${e}/v1/payments`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),signal:AbortSignal.timeout(t)})).json().catch(()=>({success:!1,error:"Failed to parse API response"}));if(a.success){const n={success:!0,message:a.message,data:a.data};return console.log("[SplitPaymentAPI] Split payment sent successfully:",n),n}else{const n={success:!1,message:a.message,error:a.error};return console.error("[SplitPaymentAPI] Split payment failed:",n),n}}catch(i){const a={success:!1,message:"Failed to send split payment",error:i instanceof Error?i.message:"Network error or server unavailable"};return console.error("[SplitPaymentAPI] Split payment failed:",a,i),a}}let at=r=>crypto.getRandomValues(new Uint8Array(r)),it=(r,t,e)=>{let i=(2<<Math.log2(r.length-1))-1,a=-~(1.6*i*t/r.length);return(n=t)=>{let o="";for(;;){let d=e(a),l=a|0;for(;l--;)if(o+=r[d[l]&i]||"",o.length>=n)return o}}},ot=(r,t=21)=>it(r,t|0,at);const M={apiGateway:{MERCHANT_SERVICE_API:"https://api.usegait.com/merchant",CHECKOUT_SERVICE_API:"https://api.usegait.com/checkout"},paylink:{DOMAIN:"https://checkout.usegait.com"}},nt=M.apiGateway.MERCHANT_SERVICE_API;class rt{static async getMerchant(t){try{return await(await fetch(`${nt}/v1/merchant/identity/${t}`,{method:"GET",headers:{"Content-Type":"application/json"}})).json()}catch(e){return e}}}const k=M.apiGateway.CHECKOUT_SERVICE_API;class lt{static async getPayment(t){try{return await(await fetch(`${k}/v1/payments/${t}`,{method:"GET",headers:{"Content-Type":"application/json"}})).json()}catch(e){return e}}static async updatePaymentStatus(t,e,i){try{return await(await fetch(`${k}/v1/payments/merchants/${t}/${e}/status`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:i})})).json()}catch(a){return a}}static async createWebhook(t,e,i){try{return await(await fetch(`${k}/v1/webhooks/${t}/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)})).json()}catch(a){return a}}static async updatePayment(t,e,i){try{return await(await fetch(`${k}/v1/payments/merchants/${t}/${i}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({paymentId:e})})).json()}catch(a){return a}}}const S=(typeof process<"u"&&process.env?"0.1.0":void 0)||"0.0.0";class x extends HTMLElement{buttonElement=null;hasRendered=!1;mutationObserver=null;modalElement=null;modalId;splitPaymentManager=null;attributeGetters;storedSplitPaymentRequest=null;merchantId=null;paymentProvider="stripe";static version=S;version=S;static get observedAttributes(){return["data-id","disabled","size","style","items","price-breakdown","total-cost","webhook","merchant-store-url"]}constructor(){super(),this.attachShadow({mode:"open"}),this.modalId=`gait-modal-${Math.random().toString(36).substr(2,9)}`,this.attributeGetters=X(this)}connectedCallback(){!this.hasRendered&&this.shadowRoot&&this.render(),this.setupEventListeners(),this.setupMutationObserver(),this.setupApiListeners(),setTimeout(()=>this.processData(),0)}disconnectedCallback(){this.buttonElement&&this.buttonElement.removeEventListener("click",this.handleClick),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.closeModal(),this.splitPaymentManager&&(this.splitPaymentManager=null),this.removeEventListener("gait-split-sent",this.handleSplitSent)}attributeChangedCallback(t,e,i){if(e!==i&&!(!this.isConnected||!this.shadowRoot)){if(t==="style"&&this.buttonElement&&this.hasRendered){const a=(i||"").replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"");this.buttonElement.setAttribute("style",a);return}this.hasRendered&&(this.render(),this.setupEventListeners()),(t==="data-id"||t.startsWith("data-"))&&(t==="data-id"&&(this.merchantId=null),setTimeout(()=>this.processData(),0))}}get dataId(){return this.attributeGetters.dataId}get disabled(){return this.attributeGetters.disabled}get size(){return this.attributeGetters.size}get items(){return this.attributeGetters.items}get priceBreakdown(){return this.attributeGetters.priceBreakdown}get totalCost(){return this.attributeGetters.totalCost}get customer(){return this.attributeGetters.customer}get webhook(){return this.attributeGetters.webhook}get merchantStoreUrl(){return this.attributeGetters.merchantStoreUrl}getDataAttributes(){return Z(this)}async fetchMerchantId(){const t=this.dataId;if(!t)return console.warn("[GaitButton] No checkoutId (data-id) provided, cannot fetch merchantId"),this.showMerchantIdError(),!1;try{const e=await rt.getMerchant(t);return e.success&&e.data?.merchantId?(this.merchantId=e.data.merchantId,this.paymentProvider=e.data.paymentProvider,!0):(console.error("[GaitButton] Failed to fetch merchantId:",e),this.showMerchantIdError(),!1)}catch(e){return console.error("[GaitButton] Error fetching merchantId:",e),this.showMerchantIdError(),!1}}showMerchantIdError(){const t="Unable to identify your account. Please go to your dashboard and copy your checkout identity.";alert(t),this.dispatchEvent(new CustomEvent("gait-merchant-id-error",{detail:{message:t,timestamp:new Date().toISOString()},bubbles:!0,composed:!0}))}async processData(){const t=this.dataId,e=this.getDataAttributes();if(t&&!this.merchantId&&await this.fetchMerchantId(),t||Object.keys(e).length>0){const i={id:t,...e,timestamp:new Date().toISOString()};this.dispatchEvent(new CustomEvent("gait-data-processed",{detail:i,bubbles:!0,composed:!0}))}}handleClick=async t=>{if(this.disabled){t.preventDefault(),t.stopPropagation();return}const e={label:"Gait",dataId:this.dataId,dataAttributes:this.getDataAttributes(),timestamp:new Date().toISOString()};this.dispatchEvent(new CustomEvent("gait-click",{detail:e,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("click",{detail:e,bubbles:!0,composed:!0})),!(!this.merchantId&&(!await this.fetchMerchantId()||!this.merchantId))&&this.openModal()};setupEventListeners(){this.shadowRoot&&(this.buttonElement&&this.buttonElement.removeEventListener("click",this.handleClick),this.buttonElement=this.shadowRoot.querySelector("button"),this.buttonElement&&this.buttonElement.addEventListener("click",this.handleClick))}setupMutationObserver(){this.mutationObserver&&this.mutationObserver.disconnect(),this.mutationObserver=new MutationObserver(t=>{let e=!1;for(const i of t)if(i.type==="attributes"){const a=i.attributeName;if(a&&a.startsWith("data-")&&!x.observedAttributes.includes(a)){e=!0;break}}e&&this.isConnected&&this.processData()}),this.mutationObserver.observe(this,{attributes:!0,attributeFilter:void 0})}setupApiListeners(){this.addEventListener("gait-split-sent",this.handleSplitSent)}handleConfirmPayment=async()=>{if(console.log("[GaitButton] Pay remaining button clicked"),!this.storedSplitPaymentRequest){console.error("[GaitButton] Split payment must be sent first before paying remaining amount");return}if(!this.merchantId&&(!await this.fetchMerchantId()||!this.merchantId))return;const t={merchantId:this.merchantId,splitId:this.storedSplitPaymentRequest.splitId,paymentId:this.storedSplitPaymentRequest.paymentSplits.find(a=>a.initiator)?.paymentId},i=`${M.paylink.DOMAIN}/payment/${t.paymentId}`;window.open(i,"_blank"),this.dispatchEvent(new CustomEvent("gait-confirm",{detail:t,bubbles:!0,composed:!0})),this.closeModal()};handleSplitSent=async t=>{const i=t.detail;if(!this.merchantId&&(!await this.fetchMerchantId()||!this.merchantId))return;const a=this.merchantId,n=this.customer;if(!n||!n.email){console.error("[GaitButton] Customer email is required for split payment");return}const o=this.webhook;if(!o||!o.url||o.body==null){console.error("[GaitButton] Webhook with url and body is required");return}const l=ot("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",6),s=l(),m=[];m.push({paymentId:l(),email:n.email,amount:i.yourAmount,isPaid:!1,datePaid:null,initiator:!0}),i.emailData.forEach(c=>{m.push({paymentId:l(),email:c.email,amount:c.amount||0,isPaid:!1,datePaid:null,initiator:!1})});const u={merchantId:a,splitId:s,paymentSplits:m,splitMethod:i.splitMethod,timestamp:i.timestamp,totalCost:i.totalCost,items:this.items,priceBreakdown:this.priceBreakdown,brandColor:g,merchantStoreUrl:this.merchantStoreUrl,subTotal:this.priceBreakdown.find(c=>c.name==="Subtotal")?.price||0,paymentProvider:this.paymentProvider};console.log("[GaitButton] Split payment request body:",JSON.stringify(u,null,2));try{const c=await et(u,2e3);if(c.success){const p=c.data?.splitId||s;this.storedSplitPaymentRequest={...u,splitId:p};try{const b=await lt.createWebhook(a,p,{url:o.url,body:o.body});console.log("[GaitButton] Webhook created:",b)}catch(b){console.error("[GaitButton] Failed to create webhook:",b)}}if(this.modalElement){const p=this.modalElement.querySelector("[data-gait-modal-confirm]");p&&(p.disabled=!1,p.style.opacity="1",p.style.cursor="pointer")}this.dispatchEvent(new CustomEvent("gait-split-feedback",{detail:{success:c.success,message:c.message,data:c.success?this.storedSplitPaymentRequest:c.data,error:c.error,timestamp:new Date().toISOString()},bubbles:!0,composed:!0})),console.log("[GaitButton] Split payment API response:",c)}catch(c){console.error("[GaitButton] Split payment API error:",c),this.dispatchEvent(new CustomEvent("gait-split-feedback",{detail:{success:!1,message:"Failed to send split payment",error:c instanceof Error?c.message:"Unknown error",timestamp:new Date().toISOString()},bubbles:!0,composed:!0}))}};openModal(){V(),this.closeModal(),this.modalElement=document.createElement("div"),this.modalElement.className="gait-modal-backdrop",this.modalElement.id=this.modalId,this.modalElement&&(this.modalElement.style.setProperty("--gait-modal-brand-color",g),this.modalElement.style.setProperty("--gait-modal-button-bg",g),this.modalElement.style.setProperty("--gait-modal-button-bg-hover",F(g,.15)),this.modalElement.style.setProperty("--gait-modal-button-color",q(g)?"#ffffff":"#000000")),this.modalElement.innerHTML=K(this.items,this.priceBreakdown,this.totalCost);const t=this.modalElement.querySelector("[data-gait-modal-close]");t&&t.addEventListener("click",this.closeModal);const e=this.modalElement.querySelector("[data-gait-modal-confirm]");e&&(e.disabled=!0,e.style.opacity="0.5",e.style.cursor="not-allowed",e.addEventListener("click",this.handleConfirmPayment)),this.splitPaymentManager=new tt(this.modalElement,this.totalCost,a=>this.dispatchEvent(a)),this.modalElement._splitPaymentManager=this.splitPaymentManager,this.modalElement.addEventListener("click",a=>{a.target===this.modalElement&&this.closeModal()});const i=a=>{a.key==="Escape"&&this.modalElement&&(this.closeModal(),document.removeEventListener("keydown",i))};document.addEventListener("keydown",i),document.body.appendChild(this.modalElement),requestAnimationFrame(()=>{this.modalElement&&this.modalElement.classList.add("gait-modal-open")})}closeModal=()=>{this.modalElement&&(this.splitPaymentManager&&this.splitPaymentManager.cleanup(),this.modalElement.classList.remove("gait-modal-open"),setTimeout(()=>{this.modalElement&&this.modalElement.parentNode&&this.modalElement.parentNode.removeChild(this.modalElement),this.modalElement=null,this.splitPaymentManager=null},250))};render(){const t=this.shadowRoot;if(!t)return;const e=!this.hasRendered,i=D(this.size,F,q),n=(this.getAttribute("style")||"").replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"");if(t.innerHTML=`
956
+ ${i}
957
+ ${H(this.disabled,n)}
958
+ `,this.hasRendered=!0,this.setupEventListeners(),e){const o=Q(this);console.log("[GaitButton] rendered",o),this.dispatchEvent(new CustomEvent("gait-loaded",{detail:{attributes:o,dataId:this.dataId,dataAttributes:this.getDataAttributes(),label:"Gait",size:this.size,disabled:this.disabled,timestamp:new Date().toISOString()},bubbles:!0,composed:!0}))}}}customElements.get("gait-button")||customElements.define("gait-button",x),customElements.get("gait-button")||customElements.define("gait-button",x),typeof window<"u"&&(window.GaitButton=x,window.GaitButtonVersion=S,console.log(`[GaitButton] Version: ${S}`)),I.GAIT_BUTTON_VERSION=S,I.GaitButton=x,Object.defineProperty(I,Symbol.toStringTag,{value:"Module"})})(this.GaitButton=this.GaitButton||{});