recur-tw 0.3.4 → 0.3.7

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.js CHANGED
@@ -637,21 +637,36 @@ var init_payment_form_skeleton = __esm({
637
637
  margin-bottom: 24px;
638
638
  }
639
639
 
640
+ .form-title {
641
+ font-size: 20px;
642
+ font-weight: 600;
643
+ color: #1a202c;
644
+ margin: 0 0 4px 0;
645
+ }
646
+
647
+ .form-subtitle {
648
+ font-size: 14px;
649
+ color: #718096;
650
+ margin: 0;
651
+ }
652
+
640
653
  .form-section {
641
654
  margin-bottom: 24px;
642
655
  }
643
656
 
644
657
  .section-title {
645
- margin: 0 0 12px 0;
646
- font-size: 16px;
658
+ font-size: 14px;
647
659
  font-weight: 600;
648
660
  color: #2d3748;
661
+ margin: 0 0 12px 0;
649
662
  }
650
663
 
651
664
  .label {
665
+ display: block;
652
666
  font-size: 14px;
653
- color: #4a5568;
654
- margin-bottom: 4px;
667
+ font-weight: 500;
668
+ color: #2d3748;
669
+ margin-bottom: 6px;
655
670
  }
656
671
 
657
672
  /* Skeleton base styles */
@@ -659,7 +674,7 @@ var init_payment_form_skeleton = __esm({
659
674
  background: linear-gradient(
660
675
  90deg,
661
676
  #f0f0f0 0%,
662
- #f8f8f8 50%,
677
+ #e8e8e8 50%,
663
678
  #f0f0f0 100%
664
679
  );
665
680
  background-size: 200% 100%;
@@ -676,68 +691,109 @@ var init_payment_form_skeleton = __esm({
676
691
  }
677
692
  }
678
693
 
679
- .skeleton-title {
680
- height: 28px;
681
- width: 200px;
694
+ /* Order Summary */
695
+ .order-summary {
696
+ background: #f7fafc;
697
+ border: 1px solid #e2e8f0;
698
+ border-radius: 8px;
699
+ padding: 16px;
700
+ margin-bottom: 24px;
701
+ }
702
+
703
+ .order-summary-title {
704
+ font-size: 14px;
705
+ font-weight: 600;
706
+ color: #2d3748;
707
+ margin: 0 0 12px 0;
708
+ }
709
+
710
+ .order-row {
711
+ display: flex;
712
+ justify-content: space-between;
713
+ align-items: center;
682
714
  margin-bottom: 8px;
683
715
  }
684
716
 
685
- .skeleton-subtitle {
686
- height: 18px;
687
- width: 320px;
717
+ .order-row:last-child {
718
+ margin-bottom: 0;
719
+ padding-top: 12px;
720
+ border-top: 1px solid #e2e8f0;
688
721
  }
689
722
 
690
- .skeleton-order-summary {
691
- padding: 16px;
723
+ .order-label {
724
+ font-size: 14px;
725
+ color: #4a5568;
726
+ }
727
+
728
+ .skeleton-order-value {
729
+ height: 20px;
730
+ width: 80px;
731
+ }
732
+
733
+ .skeleton-order-total {
734
+ height: 26px;
735
+ width: 100px;
736
+ }
737
+
738
+ /* Customer Info Display */
739
+ .customer-info-display {
692
740
  background: #f7fafc;
741
+ border: 1px solid #e2e8f0;
693
742
  border-radius: 6px;
694
- margin-bottom: 24px;
743
+ padding: 12px;
744
+ margin-bottom: 8px;
695
745
  }
696
746
 
697
- .skeleton-order-row {
747
+ .info-row {
698
748
  display: flex;
699
- justify-content: space-between;
700
749
  align-items: center;
701
- margin-bottom: 12px;
750
+ margin-bottom: 6px;
702
751
  }
703
752
 
704
- .skeleton-order-row:last-child {
753
+ .info-row:last-child {
705
754
  margin-bottom: 0;
706
- padding-top: 12px;
707
- border-top: 1px solid #e2e8f0;
708
- font-weight: 600;
709
755
  }
710
756
 
711
- .skeleton-order-value {
757
+ .info-label {
758
+ font-size: 13px;
759
+ color: #718096;
760
+ min-width: 80px;
761
+ }
762
+
763
+ .skeleton-info-value {
712
764
  height: 20px;
713
765
  width: 120px;
714
766
  }
715
767
 
716
- .input-group {
768
+ /* Card Fields */
769
+ .card-field {
717
770
  margin-bottom: 16px;
718
771
  }
719
772
 
720
- .input-group:last-child {
773
+ .card-field:last-child {
721
774
  margin-bottom: 0;
722
775
  }
723
776
 
724
777
  .skeleton-input {
725
- height: 44px;
778
+ height: 36px;
726
779
  width: 100%;
780
+ border-radius: 6px;
727
781
  }
728
782
 
729
- .card-fields-grid {
783
+ .card-row {
730
784
  display: grid;
731
785
  grid-template-columns: 1fr 1fr;
732
786
  gap: 12px;
733
787
  }
734
788
 
789
+ /* Submit Button - matches .recur-submit-button: padding 14px*2 + font 16px * line-height ~1.5 */
735
790
  .skeleton-button {
736
- height: 44px;
791
+ height: 52px;
737
792
  width: 100%;
738
793
  border-radius: 6px;
739
794
  }
740
795
 
796
+ /* Security Note */
741
797
  .security-note {
742
798
  display: flex;
743
799
  align-items: center;
@@ -760,73 +816,67 @@ var init_payment_form_skeleton = __esm({
760
816
  </style>
761
817
 
762
818
  <div class="payment-form-wrapper">
763
- <!-- Header Skeleton -->
819
+ <!-- Header (matches payment-form.ts) -->
764
820
  <div class="form-header">
765
- <div class="skeleton skeleton-title"></div>
766
- <div class="skeleton skeleton-subtitle"></div>
821
+ <h2 class="form-title">\u8A02\u95B1\u4ED8\u6B3E</h2>
822
+ <p class="form-subtitle">\u8ACB\u586B\u5BEB\u4FE1\u7528\u5361\u8CC7\u8A0A\u5B8C\u6210\u8A02\u95B1</p>
767
823
  </div>
768
824
 
769
- <!-- Order Summary - Static labels, skeleton values -->
770
- <div class="skeleton-order-summary">
771
- <h3 class="section-title">\u8A02\u55AE\u6458\u8981</h3>
772
- <div class="skeleton-order-row">
773
- <span class="label">\u65B9\u6848</span>
774
- <div class="skeleton skeleton-order-value"></div>
775
- </div>
776
- <div class="skeleton-order-row">
777
- <span class="label">\u91D1\u984D</span>
825
+ <!-- Order Summary (matches createOrderSummarySection) -->
826
+ <div class="order-summary">
827
+ <h3 class="order-summary-title">\u8A02\u55AE\u6458\u8981</h3>
828
+ <div class="order-row">
829
+ <span class="order-label">\u8A02\u95B1\u65B9\u6848</span>
778
830
  <div class="skeleton skeleton-order-value"></div>
779
831
  </div>
780
- <div class="skeleton-order-row">
781
- <span class="label">\u9031\u671F</span>
832
+ <div class="order-row">
833
+ <span class="order-label">\u8A08\u8CBB\u9031\u671F</span>
782
834
  <div class="skeleton skeleton-order-value"></div>
783
835
  </div>
784
- <div class="skeleton-order-row">
785
- <span class="label">\u7E3D\u8A08</span>
786
- <div class="skeleton skeleton-order-value"></div>
836
+ <div class="order-row">
837
+ <span class="order-label">\u7E3D\u8A08</span>
838
+ <div class="skeleton skeleton-order-total"></div>
787
839
  </div>
788
840
  </div>
789
841
 
790
- <!-- Customer Info Section - Static labels, skeleton inputs -->
842
+ <!-- Customer Info Section (matches createCustomerInfoSection read-only display) -->
791
843
  <div class="form-section">
792
844
  <h3 class="section-title">\u5BA2\u6236\u8CC7\u8A0A</h3>
793
- <div class="input-group">
794
- <div class="label">\u59D3\u540D</div>
795
- <div class="skeleton skeleton-input"></div>
796
- </div>
797
- <div class="input-group">
798
- <div class="label">Email</div>
799
- <div class="skeleton skeleton-input"></div>
800
- </div>
801
- <div class="input-group">
802
- <div class="label">\u96FB\u8A71\uFF08\u9078\u586B\uFF09</div>
803
- <div class="skeleton skeleton-input"></div>
845
+ <div class="customer-info-display">
846
+ <div class="info-row">
847
+ <span class="info-label">\u5BA2\u6236\u59D3\u540D\uFF1A</span>
848
+ <div class="skeleton skeleton-info-value"></div>
849
+ </div>
850
+ <div class="info-row">
851
+ <span class="info-label">\u96FB\u5B50\u90F5\u4EF6\uFF1A</span>
852
+ <div class="skeleton skeleton-info-value" style="width: 160px;"></div>
853
+ </div>
804
854
  </div>
805
855
  </div>
806
856
 
807
- <!-- Card Fields Section - Static labels, skeleton inputs -->
857
+ <!-- Card Fields Section (matches createCardFieldsSection) -->
808
858
  <div class="form-section">
809
859
  <h3 class="section-title">\u4FE1\u7528\u5361\u8CC7\u8A0A</h3>
810
- <div class="input-group">
811
- <div class="label">\u4FE1\u7528\u5361\u865F</div>
860
+ <div class="card-field">
861
+ <label class="label">\u5361\u865F</label>
812
862
  <div class="skeleton skeleton-input"></div>
813
863
  </div>
814
- <div class="card-fields-grid">
815
- <div class="input-group">
816
- <div class="label">\u6709\u6548\u671F\u9650</div>
864
+ <div class="card-row">
865
+ <div class="card-field">
866
+ <label class="label">\u6709\u6548\u671F\u9650</label>
817
867
  <div class="skeleton skeleton-input"></div>
818
868
  </div>
819
- <div class="input-group">
820
- <div class="label">\u5B89\u5168\u78BC</div>
869
+ <div class="card-field">
870
+ <label class="label">\u5B89\u5168\u78BC</label>
821
871
  <div class="skeleton skeleton-input"></div>
822
872
  </div>
823
873
  </div>
824
874
  </div>
825
875
 
826
- <!-- Submit Button Skeleton -->
876
+ <!-- Submit Button -->
827
877
  <div class="skeleton skeleton-button"></div>
828
878
 
829
- <!-- Security Note -->
879
+ <!-- Security Note (matches payment-form.ts) -->
830
880
  <div class="security-note">
831
881
  <svg class="security-icon" width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
832
882
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
@@ -1184,10 +1234,10 @@ var init_payment_form = __esm({
1184
1234
  }
1185
1235
 
1186
1236
  .form-title {
1187
- font-size: 24px;
1237
+ font-size: 20px;
1188
1238
  font-weight: 600;
1189
1239
  color: #1a202c;
1190
- margin: 0 0 8px 0;
1240
+ margin: 0 0 4px 0;
1191
1241
  }
1192
1242
 
1193
1243
  .form-subtitle {
@@ -1235,8 +1285,8 @@ var init_payment_form = __esm({
1235
1285
 
1236
1286
  <div class="payment-form-wrapper">
1237
1287
  <div class="form-header">
1238
- <h2 class="form-title">\u4ED8\u6B3E\u8CC7\u8A0A</h2>
1239
- <p class="form-subtitle">\u8ACB\u586B\u5BEB\u60A8\u7684\u4FE1\u7528\u5361\u8CC7\u8A0A\u4EE5\u5B8C\u6210\u8A02\u95B1</p>
1288
+ <h2 class="form-title">\u8A02\u95B1\u4ED8\u6B3E</h2>
1289
+ <p class="form-subtitle">\u8ACB\u586B\u5BEB\u4FE1\u7528\u5361\u8CC7\u8A0A\u5B8C\u6210\u8A02\u95B1</p>
1240
1290
  </div>
1241
1291
 
1242
1292
  <!-- Slot for order summary (Light DOM) -->
@@ -1369,12 +1419,14 @@ var init_payment_form = __esm({
1369
1419
 
1370
1420
  .order-summary-value {
1371
1421
  font-size: 14px;
1422
+ line-height: 20px;
1372
1423
  font-weight: 500;
1373
1424
  color: #2d3748;
1374
1425
  }
1375
1426
 
1376
1427
  .order-summary-total {
1377
1428
  font-size: 18px;
1429
+ line-height: 26px;
1378
1430
  font-weight: 700;
1379
1431
  color: #1a202c;
1380
1432
  }
@@ -1432,6 +1484,7 @@ var init_payment_form = __esm({
1432
1484
 
1433
1485
  .recur-info-value {
1434
1486
  font-size: 14px;
1487
+ line-height: 20px;
1435
1488
  color: #2d3748;
1436
1489
  font-weight: 500;
1437
1490
  }
@@ -1550,11 +1603,43 @@ var init_payment_form = __esm({
1550
1603
  grid-template-columns: 1fr 1fr;
1551
1604
  gap: 12px;
1552
1605
  }
1606
+
1607
+ /* Container needs relative positioning for skeleton overlay */
1608
+ .recur-card-field-container {
1609
+ position: relative;
1610
+ }
1611
+
1612
+ /* Loading skeleton for card fields - shown until PAYUNi iframe loads */
1613
+ .recur-card-skeleton {
1614
+ position: absolute;
1615
+ top: 0;
1616
+ left: 0;
1617
+ height: 36px;
1618
+ width: 100%;
1619
+ background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);
1620
+ background-size: 200% 100%;
1621
+ animation: recur-skeleton-loading 1.5s ease-in-out infinite;
1622
+ border-radius: 4px;
1623
+ z-index: 1;
1624
+ pointer-events: none;
1625
+ }
1626
+
1627
+ /* Hide skeleton when PAYUNi iframe is ready (has content) */
1628
+ .recur-card-skeleton.hidden {
1629
+ display: none;
1630
+ }
1631
+
1632
+ @keyframes recur-skeleton-loading {
1633
+ 0% { background-position: 200% 0; }
1634
+ 100% { background-position: -200% 0; }
1635
+ }
1553
1636
  </style>
1554
1637
 
1555
1638
  <div class="recur-card-field">
1556
1639
  <label class="recur-card-field-label">\u5361\u865F</label>
1557
1640
  <div class="recur-card-field-container" id="${this.containerId}-card-no-wrapper">
1641
+ <!-- Skeleton shown until PAYUNi iframe loads -->
1642
+ <div class="recur-card-skeleton" id="${this.containerId}-card-no-skeleton"></div>
1558
1643
  <!-- PAYUNi \u6703\u5728\u9019\u88E1\u6CE8\u5165 iframe -->
1559
1644
  <div id="${this.containerId}-card-no" class="recur-payuni-iframe"></div>
1560
1645
  </div>
@@ -1564,6 +1649,7 @@ var init_payment_form = __esm({
1564
1649
  <div class="recur-card-field">
1565
1650
  <label class="recur-card-field-label">\u6709\u6548\u671F\u9650</label>
1566
1651
  <div class="recur-card-field-container" id="${this.containerId}-card-exp-wrapper">
1652
+ <div class="recur-card-skeleton" id="${this.containerId}-card-exp-skeleton"></div>
1567
1653
  <div id="${this.containerId}-card-exp" class="recur-payuni-iframe"></div>
1568
1654
  </div>
1569
1655
  </div>
@@ -1571,6 +1657,7 @@ var init_payment_form = __esm({
1571
1657
  <div class="recur-card-field">
1572
1658
  <label class="recur-card-field-label">\u5B89\u5168\u78BC</label>
1573
1659
  <div class="recur-card-field-container" id="${this.containerId}-card-cvc-wrapper">
1660
+ <div class="recur-card-skeleton" id="${this.containerId}-card-cvc-skeleton"></div>
1574
1661
  <div id="${this.containerId}-card-cvc" class="recur-payuni-iframe"></div>
1575
1662
  </div>
1576
1663
  </div>
@@ -1578,6 +1665,22 @@ var init_payment_form = __esm({
1578
1665
  `;
1579
1666
  return section;
1580
1667
  }
1668
+ /**
1669
+ * Hide card field skeletons after PAYUNi iframes are loaded
1670
+ */
1671
+ hideCardSkeletons() {
1672
+ const skeletonIds = [
1673
+ `${this.containerId}-card-no-skeleton`,
1674
+ `${this.containerId}-card-exp-skeleton`,
1675
+ `${this.containerId}-card-cvc-skeleton`
1676
+ ];
1677
+ skeletonIds.forEach((id) => {
1678
+ const skeleton = document.getElementById(id);
1679
+ if (skeleton) {
1680
+ skeleton.classList.add("hidden");
1681
+ }
1682
+ });
1683
+ }
1581
1684
  createActionsSection() {
1582
1685
  const section = document.createElement("div");
1583
1686
  section.className = "actions-section";
@@ -1702,6 +1805,7 @@ var init_payment_form = __esm({
1702
1805
  this._isInitializing = false;
1703
1806
  return null;
1704
1807
  }
1808
+ this.hideCardSkeletons();
1705
1809
  paymentSession.onUpdate?.((data) => {
1706
1810
  if (this._initializationAborted) {
1707
1811
  console.log("[PaymentForm] Ignoring onUpdate event - component disconnected");
@@ -2277,9 +2381,6 @@ function RecurProvider({ children, config: initialConfig = {} }) {
2277
2381
  modalContent = document.createElement("div");
2278
2382
  modalContent.className = "recur-sdk__modal-content";
2279
2383
  modalContent.style.cssText = `
2280
- background: white;
2281
- padding: 32px;
2282
- border-radius: 12px;
2283
2384
  max-width: 500px;
2284
2385
  width: 90%;
2285
2386
  max-height: 90vh;
@@ -2291,11 +2392,11 @@ function RecurProvider({ children, config: initialConfig = {} }) {
2291
2392
  closeButton.innerHTML = "\u2715";
2292
2393
  closeButton.style.cssText = `
2293
2394
  position: absolute;
2294
- top: 16px;
2295
- right: 16px;
2296
- background: none;
2395
+ top: 12px;
2396
+ right: 12px;
2397
+ background: rgba(0, 0, 0, 0.05);
2297
2398
  border: none;
2298
- font-size: 24px;
2399
+ font-size: 18px;
2299
2400
  cursor: pointer;
2300
2401
  color: #666;
2301
2402
  padding: 0;
@@ -2304,24 +2405,32 @@ function RecurProvider({ children, config: initialConfig = {} }) {
2304
2405
  display: flex;
2305
2406
  align-items: center;
2306
2407
  justify-content: center;
2408
+ border-radius: 50%;
2409
+ z-index: 10;
2410
+ transition: background 0.2s;
2307
2411
  `;
2412
+ closeButton.onmouseover = () => {
2413
+ closeButton.style.background = "rgba(0, 0, 0, 0.1)";
2414
+ };
2415
+ closeButton.onmouseout = () => {
2416
+ closeButton.style.background = "rgba(0, 0, 0, 0.05)";
2417
+ };
2308
2418
  closeButton.onclick = () => {
2309
2419
  modalOverlay?.remove();
2310
2420
  setIsCheckingOut(false);
2311
2421
  options.onPaymentCancel?.();
2312
2422
  };
2313
- const title = document.createElement("h2");
2314
- title.className = "recur-sdk__title";
2315
- title.textContent = "\u8A02\u95B1\u4ED8\u6B3E";
2316
- title.style.cssText = "margin: 0 0 24px 0; font-size: 24px; font-weight: 600;";
2317
2423
  loadingContainer = document.createElement("div");
2318
2424
  loadingContainer.id = "recur-modal-loading";
2319
2425
  loadingContainer.className = "recur-sdk__loading-container";
2320
- loadingContainer.style.cssText = "padding: 0;";
2426
+ loadingContainer.style.cssText = `
2427
+ background: white;
2428
+ border-radius: 12px;
2429
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
2430
+ `;
2321
2431
  const skeleton = document.createElement("recur-payment-form-skeleton");
2322
2432
  loadingContainer.appendChild(skeleton);
2323
2433
  modalContent.appendChild(closeButton);
2324
- modalContent.appendChild(title);
2325
2434
  modalContent.appendChild(loadingContainer);
2326
2435
  modalOverlay.appendChild(modalContent);
2327
2436
  document.body.appendChild(modalOverlay);