@khipu/design-system 0.2.0-alpha.11 → 0.2.0-alpha.111

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!');
@@ -1051,8 +1052,12 @@ const ui = _context.ui;
1051
1052
  if (panel) {
1052
1053
  if (expanded) {
1053
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 = '';
1054
1057
  } else {
1055
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';
1056
1061
  }
1057
1062
  }
1058
1063
  });
@@ -1330,9 +1335,9 @@ const ui = _context.ui;
1330
1335
  function initStickyInvoice(root) {
1331
1336
  root = root || document;
1332
1337
 
1333
- // Progressive collapse range: 0px (expanded) to 30px (collapsed)
1338
+ // Progressive collapse range: 0px (expanded) to 20px (collapsed)
1334
1339
  var COLLAPSE_START = 0;
1335
- var COLLAPSE_END = 30;
1340
+ var COLLAPSE_END = 20;
1336
1341
 
1337
1342
  var lastScrollY = 0;
1338
1343
  var ticking = false;
@@ -1380,13 +1385,16 @@ const ui = _context.ui;
1380
1385
  if (!currentScreen.style.getPropertyValue('--collapse-collapsible-h')) {
1381
1386
  var collapsible = currentSticky.querySelector('.kds-invoice-collapsible');
1382
1387
  if (collapsible) {
1383
- currentScreen.style.setProperty('--collapse-collapsible-h', Math.min(collapsible.offsetHeight, 87) + 'px');
1388
+ currentScreen.style.setProperty('--collapse-collapsible-h', collapsible.offsetHeight + 'px');
1384
1389
  }
1385
1390
  }
1386
1391
 
1387
1392
  // Single DOM write per frame — set on screen (parent) so it cascades to sticky + siblings
1388
1393
  currentScreen.style.setProperty('--collapse-progress', progress);
1389
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
+
1390
1398
  // Close expand panels as soon as the sticky header starts collapsing
1391
1399
  if (progress > 0) {
1392
1400
  currentSticky.querySelectorAll('[data-expand-toggle][aria-expanded="true"]').forEach(function(toggle) {
@@ -1410,6 +1418,9 @@ const ui = _context.ui;
1410
1418
  screen.style.removeProperty('--collapse-progress');
1411
1419
  screen.style.removeProperty('--collapse-collapsible-h');
1412
1420
  });
1421
+ root.querySelectorAll('.kds-invoice-sticky.is-collapsed').forEach(function(el) {
1422
+ el.classList.remove('is-collapsed');
1423
+ });
1413
1424
  }
1414
1425
  });
1415
1426
 
@@ -1419,6 +1430,67 @@ const ui = _context.ui;
1419
1430
  onScroll();
1420
1431
  }
1421
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
+
1422
1494
  /**
1423
1495
  * Initialize copyable table rows
1424
1496
  * Delegated click on .kds-copyable-table-row[data-copy] copies value and shows feedback
@@ -1461,7 +1533,7 @@ const ui = _context.ui;
1461
1533
  var rows = container.querySelectorAll('.kds-copyable-table-row[data-copy]');
1462
1534
  var values = [];
1463
1535
  rows.forEach(function(r) {
1464
- var key = r.querySelector('.k');
1536
+ var key = r.querySelector('.kds-key');
1465
1537
  var val = r.dataset.copy;
1466
1538
  if (key) {
1467
1539
  values.push(key.textContent.trim() + ': ' + val);
@@ -1589,6 +1661,7 @@ const ui = _context.ui;
1589
1661
  window.Khipu.initInfoTip = initInfoTip;
1590
1662
  window.Khipu.initBankModal = initBankModal;
1591
1663
  window.Khipu.initStickyInvoice = initStickyInvoice;
1664
+ window.Khipu.initHideOnScroll = initHideOnScroll;
1592
1665
 
1593
1666
  // Also export showSnackbar to global scope for backward compatibility
1594
1667
  window.showSnackbar = showSnackbar;