@khipu/design-system 0.3.5-alpha.35 → 0.3.5-alpha.37

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.
@@ -849,6 +849,7 @@ const ui = _context.ui;
849
849
  * - Sticky invoice card (collapse on scroll)
850
850
  * - Brand inner (logo inside sticky card on mobile)
851
851
  * - Secure footer (moved inside last card per screen)
852
+ * - Read-to-accept contracts (checkbox enabled after scrolling to the end)
852
853
  */
853
854
 
854
855
  (function() {
@@ -895,10 +896,71 @@ const ui = _context.ui;
895
896
  initHideOnScroll();
896
897
  initBankModal();
897
898
  initMerchantLogoBackdrop();
899
+ initContract();
898
900
 
899
901
  console.log('Material Design initialization complete!');
900
902
  }
901
903
 
904
+ /**
905
+ * Initialize read-to-accept contracts (KTUF-398)
906
+ * In each [data-kds-contract] the acceptance checkbox (.kds-contract-accept) stays
907
+ * disabled until .kds-contract-content is scrolled to the end, or right away if the
908
+ * content fits without scrolling. Then the hint (.kds-contract-hint) is hidden, the
909
+ * container gets .kds-contract--read and fires `kds:contract-read` once.
910
+ * Vanilla mirror of KdsContract for server-side views (payment).
911
+ * @param {Element} root - Root element to scope the query (default: document)
912
+ */
913
+ function initContract(root) {
914
+ root = root || document;
915
+ root.querySelectorAll('[data-kds-contract]').forEach(function(contract) {
916
+ if (contract.hasAttribute('data-kds-contract-ready')) return;
917
+ contract.setAttribute('data-kds-contract-ready', '');
918
+
919
+ var content = contract.querySelector('.kds-contract-content');
920
+ var checkbox = contract.querySelector('.kds-contract-accept input[type="checkbox"]');
921
+ var hint = contract.querySelector('.kds-contract-hint');
922
+ if (!content || !checkbox) return;
923
+
924
+ // The markup ships the checkbox enabled so the page still works without this
925
+ // script; here it is locked until the content has been read.
926
+ checkbox.disabled = true;
927
+
928
+ function markRead() {
929
+ if (contract.classList.contains('kds-contract--read')) return;
930
+ contract.classList.add('kds-contract--read');
931
+ checkbox.disabled = false;
932
+ if (hint) {
933
+ hint.hidden = true;
934
+ // The hidden hint no longer describes the checkbox (as in KdsContract).
935
+ if (hint.id) {
936
+ var describedBy = (checkbox.getAttribute('aria-describedby') || '')
937
+ .split(/\s+/)
938
+ .filter(function(id) { return id && id !== hint.id; });
939
+ if (describedBy.length) checkbox.setAttribute('aria-describedby', describedBy.join(' '));
940
+ else checkbox.removeAttribute('aria-describedby');
941
+ }
942
+ }
943
+ contract.dispatchEvent(new CustomEvent('kds:contract-read', { bubbles: true }));
944
+ }
945
+
946
+ // A few px of tolerance: zoom and sub-pixel rounding rarely land exactly on 0.
947
+ // clientHeight 0 means not laid out yet (hidden step or tab): wait for the
948
+ // ResizeObserver instead of reading 0 >= -8 as "reached the end".
949
+ function check() {
950
+ if (content.clientHeight === 0) return;
951
+ if (content.scrollTop + content.clientHeight >= content.scrollHeight - 8) {
952
+ markRead();
953
+ }
954
+ }
955
+
956
+ content.addEventListener('scroll', check, { passive: true });
957
+ if (typeof ResizeObserver !== 'undefined') {
958
+ new ResizeObserver(check).observe(content);
959
+ }
960
+ check();
961
+ });
962
+ }
963
+
902
964
  // El alto de la body card cambia de golpe entre pantallas, sin animar. Hubo una
903
965
  // transición acá (KTUF-239) y se quitó en KTUF-314: ver el comentario en
904
966
  // KdsThemeProvider.tsx — animar el alto obliga a fijar `height` en píxeles, y con el
@@ -1743,6 +1805,7 @@ const ui = _context.ui;
1743
1805
  window.Khipu.initBankModal = initBankModal;
1744
1806
  window.Khipu.initStickyInvoice = initStickyInvoice;
1745
1807
  window.Khipu.initHideOnScroll = initHideOnScroll;
1808
+ window.Khipu.initContract = initContract;
1746
1809
 
1747
1810
  // Also export showSnackbar to global scope for backward compatibility
1748
1811
  window.showSnackbar = showSnackbar;