@khipu/design-system 0.2.0-alpha.9 → 0.2.0-alpha.91

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.
@@ -892,6 +892,7 @@ const ui = _context.ui;
892
892
  initCountdown();
893
893
  initSegmentedTabs();
894
894
  initStickyInvoice();
895
+ initHideOnScroll();
895
896
  initBankModal();
896
897
 
897
898
  console.log('Material Design initialization complete!');
@@ -991,10 +992,15 @@ const ui = _context.ui;
991
992
 
992
993
  if (!logoSource) return;
993
994
 
995
+ // Insert inside the amount div (first child of .kds-invoice-header)
996
+ var header = card.querySelector('.kds-invoice-header');
997
+ var amountDiv = header ? header.firstElementChild : null;
998
+ if (!amountDiv) return;
999
+
994
1000
  var inner = document.createElement('div');
995
1001
  inner.className = 'kds-brand-inner';
996
1002
  inner.appendChild(logoSource.cloneNode(true));
997
- card.insertBefore(inner, card.firstChild);
1003
+ amountDiv.insertBefore(inner, amountDiv.firstChild);
998
1004
  });
999
1005
  }
1000
1006
 
@@ -1046,8 +1052,12 @@ const ui = _context.ui;
1046
1052
  if (panel) {
1047
1053
  if (expanded) {
1048
1054
  panel.classList.remove('open');
1055
+ // Clear the inline cap so the CSS collapse rule (max-height: 0) animates the close.
1056
+ panel.style.maxHeight = '';
1049
1057
  } else {
1050
1058
  panel.classList.add('open');
1059
+ // Size to the content so the expand fits any length instead of clipping a fixed cap.
1060
+ panel.style.maxHeight = panel.scrollHeight + 'px';
1051
1061
  }
1052
1062
  }
1053
1063
  });
@@ -1325,9 +1335,9 @@ const ui = _context.ui;
1325
1335
  function initStickyInvoice(root) {
1326
1336
  root = root || document;
1327
1337
 
1328
- // Progressive collapse range: 0px (expanded) to 60px (collapsed)
1338
+ // Progressive collapse range: 0px (expanded) to 20px (collapsed)
1329
1339
  var COLLAPSE_START = 0;
1330
- var COLLAPSE_END = 60;
1340
+ var COLLAPSE_END = 20;
1331
1341
 
1332
1342
  var lastScrollY = 0;
1333
1343
  var ticking = false;
@@ -1382,6 +1392,9 @@ const ui = _context.ui;
1382
1392
  // Single DOM write per frame — set on screen (parent) so it cascades to sticky + siblings
1383
1393
  currentScreen.style.setProperty('--collapse-progress', progress);
1384
1394
 
1395
+ // Toggle collapsed state class for discrete styling that can't interpolate (e.g. align-items)
1396
+ currentSticky.classList.toggle('is-collapsed', progress >= 1);
1397
+
1385
1398
  // Close expand panels as soon as the sticky header starts collapsing
1386
1399
  if (progress > 0) {
1387
1400
  currentSticky.querySelectorAll('[data-expand-toggle][aria-expanded="true"]').forEach(function(toggle) {
@@ -1405,6 +1418,9 @@ const ui = _context.ui;
1405
1418
  screen.style.removeProperty('--collapse-progress');
1406
1419
  screen.style.removeProperty('--collapse-collapsible-h');
1407
1420
  });
1421
+ root.querySelectorAll('.kds-invoice-sticky.is-collapsed').forEach(function(el) {
1422
+ el.classList.remove('is-collapsed');
1423
+ });
1408
1424
  }
1409
1425
  });
1410
1426
 
@@ -1414,6 +1430,67 @@ const ui = _context.ui;
1414
1430
  onScroll();
1415
1431
  }
1416
1432
 
1433
+ /**
1434
+ * Initialize hide-on-scroll for floating elements (vanilla equivalent of the React
1435
+ * `useHideOnScroll` hook). Any element with `[data-hide-on-scroll]` gets its hide class
1436
+ * (default `kds-fab--hidden`, override with `data-hide-class`) toggled: hidden when
1437
+ * scrolling down past the threshold, shown when scrolling up, always shown within
1438
+ * `data-hide-top-offset` px of the top. Tune with `data-hide-threshold` (default 8).
1439
+ *
1440
+ * Works standalone (`window.scrollY`) and embedded in an iframe, where the parent posts
1441
+ * `postMessage({ type: 'VIEWPORT_OFFSET', offsetTop })`.
1442
+ * @param {Element} root - Root element to scope the query (default: document)
1443
+ */
1444
+ function initHideOnScroll(root) {
1445
+ root = root || document;
1446
+ var els = root.querySelectorAll('[data-hide-on-scroll]');
1447
+ if (!els.length) return;
1448
+
1449
+ var viewportOffset = 0;
1450
+ var ticking = false;
1451
+ var lastYs = new Map();
1452
+
1453
+ function currentY() {
1454
+ return Math.max(window.scrollY || window.pageYOffset || 0, viewportOffset);
1455
+ }
1456
+
1457
+ function apply() {
1458
+ ticking = false;
1459
+ var y = currentY();
1460
+ els.forEach(function(el) {
1461
+ var threshold = parseInt(el.getAttribute('data-hide-threshold'), 10) || 8;
1462
+ var topOffset = parseInt(el.getAttribute('data-hide-top-offset'), 10) || 0;
1463
+ var hideClass = el.getAttribute('data-hide-class') || 'kds-fab--hidden';
1464
+ var lastY = lastYs.has(el) ? lastYs.get(el) : y;
1465
+ if (y <= topOffset) {
1466
+ el.classList.remove(hideClass);
1467
+ lastYs.set(el, y);
1468
+ return;
1469
+ }
1470
+ var delta = y - lastY;
1471
+ if (Math.abs(delta) < threshold) return;
1472
+ el.classList.toggle(hideClass, delta > 0);
1473
+ lastYs.set(el, y);
1474
+ });
1475
+ }
1476
+
1477
+ function onScroll() {
1478
+ if (ticking) return;
1479
+ ticking = true;
1480
+ requestAnimationFrame(apply);
1481
+ }
1482
+
1483
+ window.addEventListener('scroll', onScroll, { passive: true });
1484
+ window.addEventListener('resize', onScroll);
1485
+ window.addEventListener('message', function(event) {
1486
+ if (event.data && event.data.type === 'VIEWPORT_OFFSET') {
1487
+ viewportOffset = Math.max(0, event.data.offsetTop || 0);
1488
+ onScroll();
1489
+ }
1490
+ });
1491
+ apply();
1492
+ }
1493
+
1417
1494
  /**
1418
1495
  * Initialize copyable table rows
1419
1496
  * Delegated click on .kds-copyable-table-row[data-copy] copies value and shows feedback
@@ -1456,7 +1533,7 @@ const ui = _context.ui;
1456
1533
  var rows = container.querySelectorAll('.kds-copyable-table-row[data-copy]');
1457
1534
  var values = [];
1458
1535
  rows.forEach(function(r) {
1459
- var key = r.querySelector('.k');
1536
+ var key = r.querySelector('.kds-key');
1460
1537
  var val = r.dataset.copy;
1461
1538
  if (key) {
1462
1539
  values.push(key.textContent.trim() + ': ' + val);
@@ -1584,6 +1661,7 @@ const ui = _context.ui;
1584
1661
  window.Khipu.initInfoTip = initInfoTip;
1585
1662
  window.Khipu.initBankModal = initBankModal;
1586
1663
  window.Khipu.initStickyInvoice = initStickyInvoice;
1664
+ window.Khipu.initHideOnScroll = initHideOnScroll;
1587
1665
 
1588
1666
  // Also export showSnackbar to global scope for backward compatibility
1589
1667
  window.showSnackbar = showSnackbar;