zcomponents-ui 1.5.12 → 1.5.14
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-BbHVfHYa.js → index-8z2jr57w.js} +333 -184
- package/dist/index-8z2jr57w.js.map +1 -0
- package/dist/{index-DK-YMElu.js → index-BxoOD-Vf.js} +334 -184
- package/dist/index-BxoOD-Vf.js.map +1 -0
- package/dist/index.cjs.js +267 -184
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +268 -185
- package/dist/index.esm.js.map +1 -1
- package/dist/react-hook-form.cjs.js +1 -1
- package/dist/react-hook-form.esm.js +1 -1
- package/dist/zcomponents-ui.css +1 -1
- package/dist/zcomponents-ui.css.map +1 -1
- package/dist/zdrop.css +1 -1
- package/dist/zdrop.css.map +1 -1
- package/package.json +1 -1
- package/dist/index-BbHVfHYa.js.map +0 -1
- package/dist/index-DK-YMElu.js.map +0 -1
|
@@ -375,7 +375,6 @@ const getElementVerticalBorders = (el) => {
|
|
|
375
375
|
};
|
|
376
376
|
|
|
377
377
|
const minUsableHeight = 50;
|
|
378
|
-
const subPixelSafetyBufferPx = 2;
|
|
379
378
|
const calculateHeightForTop = (scrollHeight, maxHeightLimiter, wrapperMaxHeight) => {
|
|
380
379
|
const currentHeightLimiter = maxHeightLimiter < wrapperMaxHeight ? maxHeightLimiter : wrapperMaxHeight;
|
|
381
380
|
return scrollHeight > currentHeightLimiter
|
|
@@ -398,14 +397,16 @@ const ZDropListWrapper = (props) => {
|
|
|
398
397
|
const wrapperClasses = classNames(styles["zd__list-wrapper"], className);
|
|
399
398
|
const getWrapperVerticalSpacing = react.useCallback(() => {
|
|
400
399
|
const wrapper = listWrapperRef.current;
|
|
401
|
-
if (!wrapper)
|
|
400
|
+
if (!wrapper) {
|
|
402
401
|
return 0;
|
|
402
|
+
}
|
|
403
403
|
return (getElementVerticalMargins(wrapper) + getElementVerticalBorders(wrapper));
|
|
404
404
|
}, []);
|
|
405
405
|
const getWrapperVerticalExtrasPx = react.useCallback(() => {
|
|
406
406
|
const wrapper = listWrapperRef.current;
|
|
407
|
-
if (!wrapper)
|
|
407
|
+
if (!wrapper) {
|
|
408
408
|
return 0;
|
|
409
|
+
}
|
|
409
410
|
const bordersPx = getElementVerticalBorders(wrapper);
|
|
410
411
|
const cs = window.getComputedStyle(wrapper);
|
|
411
412
|
const paddingTopPx = parseFloat(cs.paddingTop || "0") || 0;
|
|
@@ -424,10 +425,66 @@ const ZDropListWrapper = (props) => {
|
|
|
424
425
|
setMeasuredContentHeight(0);
|
|
425
426
|
setAnimatedWrapperHeightPx(0);
|
|
426
427
|
}, [optionsCount]);
|
|
428
|
+
const measureVisualContentHeightPx = react.useCallback((wrapper, wrapperVerticalExtrasPx) => {
|
|
429
|
+
const prevHeight = wrapper.style.height;
|
|
430
|
+
const prevMaxHeight = wrapper.style.maxHeight;
|
|
431
|
+
wrapper.style.height = "auto";
|
|
432
|
+
wrapper.style.maxHeight = "none";
|
|
433
|
+
wrapper.offsetHeight;
|
|
434
|
+
const wrapperRect = wrapper.getBoundingClientRect();
|
|
435
|
+
const childrenElements = Array.from(wrapper.children);
|
|
436
|
+
if (childrenElements.length === 0) {
|
|
437
|
+
const height = (wrapper.scrollHeight || 0) + wrapperVerticalExtrasPx;
|
|
438
|
+
wrapper.style.height = prevHeight;
|
|
439
|
+
wrapper.style.maxHeight = prevMaxHeight;
|
|
440
|
+
return Math.max(0, height);
|
|
441
|
+
}
|
|
442
|
+
let minTop = Number.POSITIVE_INFINITY;
|
|
443
|
+
let maxBottom = Number.NEGATIVE_INFINITY;
|
|
444
|
+
let topMostEl = null;
|
|
445
|
+
let bottomMostEl = null;
|
|
446
|
+
let topMostTop = Number.POSITIVE_INFINITY;
|
|
447
|
+
let bottomMostBottom = Number.NEGATIVE_INFINITY;
|
|
448
|
+
for (const child of childrenElements) {
|
|
449
|
+
const rect = child.getBoundingClientRect();
|
|
450
|
+
const topRel = rect.top - wrapperRect.top;
|
|
451
|
+
const bottomRel = rect.bottom - wrapperRect.top;
|
|
452
|
+
if (topRel < minTop) {
|
|
453
|
+
minTop = topRel;
|
|
454
|
+
}
|
|
455
|
+
if (bottomRel > maxBottom) {
|
|
456
|
+
maxBottom = bottomRel;
|
|
457
|
+
}
|
|
458
|
+
if (rect.top < topMostTop) {
|
|
459
|
+
topMostTop = rect.top;
|
|
460
|
+
topMostEl = child;
|
|
461
|
+
}
|
|
462
|
+
if (rect.bottom > bottomMostBottom) {
|
|
463
|
+
bottomMostBottom = rect.bottom;
|
|
464
|
+
bottomMostEl = child;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
let topMarginPx = 0;
|
|
468
|
+
let bottomMarginPx = 0;
|
|
469
|
+
if (topMostEl) {
|
|
470
|
+
const cs = window.getComputedStyle(topMostEl);
|
|
471
|
+
topMarginPx = parseFloat(cs.marginTop || "0") || 0;
|
|
472
|
+
}
|
|
473
|
+
if (bottomMostEl) {
|
|
474
|
+
const cs = window.getComputedStyle(bottomMostEl);
|
|
475
|
+
bottomMarginPx = parseFloat(cs.marginBottom || "0") || 0;
|
|
476
|
+
}
|
|
477
|
+
const unionHeight = Math.max(0, maxBottom - minTop);
|
|
478
|
+
const total = unionHeight + topMarginPx + bottomMarginPx + wrapperVerticalExtrasPx;
|
|
479
|
+
wrapper.style.height = prevHeight;
|
|
480
|
+
wrapper.style.maxHeight = prevMaxHeight;
|
|
481
|
+
return Math.max(0, total);
|
|
482
|
+
}, []);
|
|
427
483
|
const measureContentHeightPx = react.useCallback(() => {
|
|
428
484
|
const wrapper = listWrapperRef.current;
|
|
429
|
-
if (!wrapper)
|
|
485
|
+
if (!wrapper) {
|
|
430
486
|
return 0;
|
|
487
|
+
}
|
|
431
488
|
const wrapperVerticalExtrasPx = getWrapperVerticalExtrasPx();
|
|
432
489
|
if (optionsCount > 0) {
|
|
433
490
|
const firstListItem = wrapper.querySelector("li");
|
|
@@ -446,31 +503,8 @@ const ZDropListWrapper = (props) => {
|
|
|
446
503
|
}
|
|
447
504
|
}
|
|
448
505
|
cachedListItemHeightRef.current = null;
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
return wrapperVerticalExtrasPx;
|
|
452
|
-
}
|
|
453
|
-
const previousInlineHeight = wrapper.style.height;
|
|
454
|
-
const previousInlineMaxHeight = wrapper.style.maxHeight;
|
|
455
|
-
wrapper.style.height = "auto";
|
|
456
|
-
wrapper.style.maxHeight = "none";
|
|
457
|
-
wrapper.offsetHeight;
|
|
458
|
-
let contentRawPx = 0;
|
|
459
|
-
const childScrollHeight = firstChild.scrollHeight || 0;
|
|
460
|
-
if (childScrollHeight > 0) {
|
|
461
|
-
contentRawPx = childScrollHeight;
|
|
462
|
-
}
|
|
463
|
-
else {
|
|
464
|
-
const rectHeightPx = firstChild.getBoundingClientRect().height || 0;
|
|
465
|
-
const childComputedStyles = window.getComputedStyle(firstChild);
|
|
466
|
-
const childMarginTopPx = parseFloat(childComputedStyles.marginTop || "0") || 0;
|
|
467
|
-
const childMarginBottomPx = parseFloat(childComputedStyles.marginBottom || "0") || 0;
|
|
468
|
-
contentRawPx = rectHeightPx + childMarginTopPx + childMarginBottomPx;
|
|
469
|
-
}
|
|
470
|
-
wrapper.style.height = previousInlineHeight;
|
|
471
|
-
wrapper.style.maxHeight = previousInlineMaxHeight;
|
|
472
|
-
return Math.max(0, contentRawPx + wrapperVerticalExtrasPx);
|
|
473
|
-
}, [optionsCount, getWrapperVerticalExtrasPx]);
|
|
506
|
+
return measureVisualContentHeightPx(wrapper, wrapperVerticalExtrasPx);
|
|
507
|
+
}, [optionsCount, getWrapperVerticalExtrasPx, measureVisualContentHeightPx]);
|
|
474
508
|
const updateMaxSpaces = react.useCallback(() => {
|
|
475
509
|
const wrapper = listWrapperRef.current;
|
|
476
510
|
if (!wrapper) {
|
|
@@ -485,10 +519,26 @@ const ZDropListWrapper = (props) => {
|
|
|
485
519
|
return;
|
|
486
520
|
}
|
|
487
521
|
const elementVerticalSpacing = getWrapperVerticalSpacing();
|
|
488
|
-
const
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
522
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
523
|
+
const referenceEl = referenceElementClassName
|
|
524
|
+
? anchor.closest(`.${referenceElementClassName}`)
|
|
525
|
+
: null;
|
|
526
|
+
const refRect = referenceEl
|
|
527
|
+
? referenceEl.getBoundingClientRect()
|
|
528
|
+
: { top: reference.top, bottom: reference.bottom };
|
|
529
|
+
let refContentTop = refRect.top;
|
|
530
|
+
let refContentBottom = refRect.bottom;
|
|
531
|
+
if (referenceEl) {
|
|
532
|
+
const cs = window.getComputedStyle(referenceEl);
|
|
533
|
+
const paddingTop = parseFloat(cs.paddingTop || "0") || 0;
|
|
534
|
+
const paddingBottom = parseFloat(cs.paddingBottom || "0") || 0;
|
|
535
|
+
const borderTop = parseFloat(cs.borderTopWidth || "0") || 0;
|
|
536
|
+
const borderBottom = parseFloat(cs.borderBottomWidth || "0") || 0;
|
|
537
|
+
refContentTop = refRect.top + borderTop + paddingTop;
|
|
538
|
+
refContentBottom = refRect.bottom - borderBottom - paddingBottom;
|
|
539
|
+
}
|
|
540
|
+
const above = Math.max(anchorRect.top - refContentTop - elementVerticalSpacing, 0);
|
|
541
|
+
const below = Math.max(refContentBottom - anchorRect.bottom - elementVerticalSpacing, 0);
|
|
492
542
|
if (lastAboveRef.current !== above) {
|
|
493
543
|
lastAboveRef.current = above;
|
|
494
544
|
setMaxSpaceAbove(above);
|
|
@@ -498,16 +548,55 @@ const ZDropListWrapper = (props) => {
|
|
|
498
548
|
setMaxSpaceBelow(below);
|
|
499
549
|
}
|
|
500
550
|
}, [referenceElementClassName, getWrapperVerticalSpacing]);
|
|
551
|
+
const runMeasureTick = react.useCallback(() => {
|
|
552
|
+
updateMaxSpaces();
|
|
553
|
+
const next = measureContentHeightPx();
|
|
554
|
+
if (lastMeasuredContentHeightRef.current !== next) {
|
|
555
|
+
lastMeasuredContentHeightRef.current = next;
|
|
556
|
+
setMeasuredContentHeight(next);
|
|
557
|
+
}
|
|
558
|
+
}, [updateMaxSpaces, measureContentHeightPx]);
|
|
559
|
+
react.useLayoutEffect(() => {
|
|
560
|
+
const wrapper = listWrapperRef.current;
|
|
561
|
+
if (!wrapper) {
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
let rafId = 0;
|
|
565
|
+
const schedule = () => {
|
|
566
|
+
cancelAnimationFrame(rafId);
|
|
567
|
+
rafId = requestAnimationFrame(() => {
|
|
568
|
+
runMeasureTick();
|
|
569
|
+
});
|
|
570
|
+
};
|
|
571
|
+
let ro = null;
|
|
572
|
+
let mo = null;
|
|
573
|
+
const attachResizeObserver = () => {
|
|
574
|
+
var _a;
|
|
575
|
+
ro === null || ro === void 0 ? void 0 : ro.disconnect();
|
|
576
|
+
ro = new ResizeObserver(() => schedule());
|
|
577
|
+
const target = (_a = wrapper.firstElementChild) !== null && _a !== void 0 ? _a : wrapper;
|
|
578
|
+
ro.observe(target);
|
|
579
|
+
};
|
|
580
|
+
mo = new MutationObserver(() => {
|
|
581
|
+
attachResizeObserver();
|
|
582
|
+
schedule();
|
|
583
|
+
});
|
|
584
|
+
mo.observe(wrapper, { childList: true, subtree: true });
|
|
585
|
+
attachResizeObserver();
|
|
586
|
+
schedule();
|
|
587
|
+
return () => {
|
|
588
|
+
cancelAnimationFrame(rafId);
|
|
589
|
+
ro === null || ro === void 0 ? void 0 : ro.disconnect();
|
|
590
|
+
mo === null || mo === void 0 ? void 0 : mo.disconnect();
|
|
591
|
+
};
|
|
592
|
+
}, [runMeasureTick]);
|
|
501
593
|
react.useLayoutEffect(() => {
|
|
502
594
|
resetLocalCachesAndGuards();
|
|
503
595
|
let raf1 = 0;
|
|
504
596
|
let raf2 = 0;
|
|
505
597
|
raf1 = requestAnimationFrame(() => {
|
|
506
598
|
raf2 = requestAnimationFrame(() => {
|
|
507
|
-
|
|
508
|
-
const nextHeight = measureContentHeightPx();
|
|
509
|
-
lastMeasuredContentHeightRef.current = nextHeight;
|
|
510
|
-
setMeasuredContentHeight(nextHeight);
|
|
599
|
+
runMeasureTick();
|
|
511
600
|
});
|
|
512
601
|
});
|
|
513
602
|
return () => {
|
|
@@ -517,8 +606,9 @@ const ZDropListWrapper = (props) => {
|
|
|
517
606
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
518
607
|
}, []);
|
|
519
608
|
react.useLayoutEffect(() => {
|
|
520
|
-
if (!listWrapperRef.current)
|
|
609
|
+
if (!listWrapperRef.current) {
|
|
521
610
|
return;
|
|
611
|
+
}
|
|
522
612
|
const previousCount = previousOptionsCountRef.current;
|
|
523
613
|
previousOptionsCountRef.current = optionsCount;
|
|
524
614
|
const isSwitchingBetweenListAndFallback = (previousCount > 0 && optionsCount === 0) ||
|
|
@@ -526,47 +616,43 @@ const ZDropListWrapper = (props) => {
|
|
|
526
616
|
cachedListItemHeightRef.current = null;
|
|
527
617
|
let raf1 = 0;
|
|
528
618
|
let raf2 = 0;
|
|
529
|
-
|
|
530
|
-
const next = measureContentHeightPx();
|
|
531
|
-
if (lastMeasuredContentHeightRef.current !== next) {
|
|
532
|
-
lastMeasuredContentHeightRef.current = next;
|
|
533
|
-
setMeasuredContentHeight(next);
|
|
534
|
-
}
|
|
535
|
-
};
|
|
619
|
+
let raf3 = 0;
|
|
536
620
|
raf1 = requestAnimationFrame(() => {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
621
|
+
runMeasureTick();
|
|
622
|
+
raf2 = requestAnimationFrame(() => {
|
|
623
|
+
if (isSwitchingBetweenListAndFallback)
|
|
624
|
+
runMeasureTick();
|
|
625
|
+
raf3 = requestAnimationFrame(() => {
|
|
626
|
+
if (isSwitchingBetweenListAndFallback)
|
|
627
|
+
runMeasureTick();
|
|
628
|
+
});
|
|
629
|
+
});
|
|
543
630
|
});
|
|
544
631
|
return () => {
|
|
545
632
|
cancelAnimationFrame(raf1);
|
|
546
633
|
cancelAnimationFrame(raf2);
|
|
634
|
+
cancelAnimationFrame(raf3);
|
|
547
635
|
};
|
|
548
|
-
}, [optionsCount,
|
|
636
|
+
}, [optionsCount, runMeasureTick]);
|
|
549
637
|
react.useLayoutEffect(() => {
|
|
550
|
-
if (!listWrapperRef.current)
|
|
638
|
+
if (!listWrapperRef.current) {
|
|
551
639
|
return;
|
|
552
|
-
|
|
640
|
+
}
|
|
641
|
+
if (optionsCount > 0) {
|
|
553
642
|
return;
|
|
643
|
+
}
|
|
554
644
|
let raf1 = 0;
|
|
555
645
|
let raf2 = 0;
|
|
556
646
|
raf1 = requestAnimationFrame(() => {
|
|
557
647
|
raf2 = requestAnimationFrame(() => {
|
|
558
|
-
|
|
559
|
-
if (lastMeasuredContentHeightRef.current !== next) {
|
|
560
|
-
lastMeasuredContentHeightRef.current = next;
|
|
561
|
-
setMeasuredContentHeight(next);
|
|
562
|
-
}
|
|
648
|
+
runMeasureTick();
|
|
563
649
|
});
|
|
564
650
|
});
|
|
565
651
|
return () => {
|
|
566
652
|
cancelAnimationFrame(raf1);
|
|
567
653
|
cancelAnimationFrame(raf2);
|
|
568
654
|
};
|
|
569
|
-
}, [children, optionsCount,
|
|
655
|
+
}, [children, optionsCount, runMeasureTick]);
|
|
570
656
|
const hasTopSpace = maxSpaceAbove > minUsableHeight;
|
|
571
657
|
const hasBottomSpace = maxSpaceBelow > minUsableHeight;
|
|
572
658
|
let finalPosition;
|
|
@@ -590,7 +676,7 @@ const ZDropListWrapper = (props) => {
|
|
|
590
676
|
const heightForTop = calculateHeightForTop(measuredContentHeight, listMaxHeightLimiter !== null && listMaxHeightLimiter !== void 0 ? listMaxHeightLimiter : maxSpaceAbove, maxSpaceAbove);
|
|
591
677
|
const finalHeight = finalPosition === "top" ? heightForTop : heightForBottom;
|
|
592
678
|
react.useLayoutEffect(() => {
|
|
593
|
-
const nextHeightPx = Math.max(0,
|
|
679
|
+
const nextHeightPx = Math.max(0, finalHeight);
|
|
594
680
|
if (lastAnimatedHeightRef.current !== nextHeightPx) {
|
|
595
681
|
lastAnimatedHeightRef.current = nextHeightPx;
|
|
596
682
|
setAnimatedWrapperHeightPx(nextHeightPx);
|
|
@@ -627,20 +713,12 @@ const checkIsValueEqualToSelectedValue = (value, selectedValue) => {
|
|
|
627
713
|
return keysA.every((key) => checkIsValueEqualToSelectedValue(value[key], selectedValue[key]));
|
|
628
714
|
};
|
|
629
715
|
|
|
630
|
-
const getAvailableSpace = (element) => {
|
|
631
|
-
if (!element)
|
|
632
|
-
return { top: 0, bottom: 0 };
|
|
633
|
-
const rect = element.getBoundingClientRect();
|
|
634
|
-
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
635
|
-
const spaceTop = Math.max(0, rect.top);
|
|
636
|
-
const spaceBottom = Math.max(0, viewportHeight - rect.bottom);
|
|
637
|
-
return {
|
|
638
|
-
top: spaceTop,
|
|
639
|
-
bottom: spaceBottom,
|
|
640
|
-
};
|
|
641
|
-
};
|
|
642
|
-
|
|
643
716
|
const edgeDistance = 10;
|
|
717
|
+
const shallowEqualPos = (prev, next) => {
|
|
718
|
+
var _a, _b, _c, _d;
|
|
719
|
+
return ((_a = prev === null || prev === void 0 ? void 0 : prev.top) !== null && _a !== void 0 ? _a : undefined) === ((_b = next === null || next === void 0 ? void 0 : next.top) !== null && _b !== void 0 ? _b : undefined) &&
|
|
720
|
+
((_c = prev === null || prev === void 0 ? void 0 : prev.bottom) !== null && _c !== void 0 ? _c : undefined) === ((_d = next === null || next === void 0 ? void 0 : next.bottom) !== null && _d !== void 0 ? _d : undefined);
|
|
721
|
+
};
|
|
644
722
|
const ZDropListAutoHeightWrapper = (props) => {
|
|
645
723
|
const { containerRef, position = "bottom", className, optionsCount, children, } = props;
|
|
646
724
|
const wrapperRef = react.useRef(null);
|
|
@@ -649,131 +727,193 @@ const ZDropListAutoHeightWrapper = (props) => {
|
|
|
649
727
|
const [maxAllowedHeightPx, setMaxAllowedHeightPx] = react.useState(0);
|
|
650
728
|
const [measuredContentHeightPx, setMeasuredContentHeightPx] = react.useState(0);
|
|
651
729
|
const wrapperClasses = classNames(styles["zd__list"], styles["zd__list-auto-height-wrapper"], className);
|
|
652
|
-
const
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
730
|
+
const setForcedPositionYIfChanged = react.useCallback((next) => {
|
|
731
|
+
setForcedPositionY((prev) => (shallowEqualPos(prev, next) ? prev : next));
|
|
732
|
+
}, []);
|
|
733
|
+
const setMaxAllowedHeightIfChanged = react.useCallback((next) => {
|
|
734
|
+
setMaxAllowedHeightPx((prev) => (prev === next ? prev : next));
|
|
735
|
+
}, []);
|
|
736
|
+
const measureVisualContentHeightPx = react.useCallback(() => {
|
|
737
|
+
const el = wrapperRef.current;
|
|
738
|
+
if (!el) {
|
|
739
|
+
return 0;
|
|
740
|
+
}
|
|
741
|
+
const bordersPx = getElementVerticalBorders(el);
|
|
742
|
+
const prevHeight = el.style.height;
|
|
743
|
+
const prevMaxHeight = el.style.maxHeight;
|
|
744
|
+
el.style.height = "auto";
|
|
745
|
+
el.style.maxHeight = "none";
|
|
746
|
+
el.offsetHeight;
|
|
747
|
+
const wrapperRect = el.getBoundingClientRect();
|
|
748
|
+
const childrenElements = Array.from(el.children);
|
|
749
|
+
if (childrenElements.length === 0) {
|
|
750
|
+
const height = (el.scrollHeight || 0) + bordersPx;
|
|
751
|
+
el.style.height = prevHeight;
|
|
752
|
+
el.style.maxHeight = prevMaxHeight;
|
|
753
|
+
return Math.max(0, height);
|
|
754
|
+
}
|
|
755
|
+
let minTop = Number.POSITIVE_INFINITY;
|
|
756
|
+
let maxBottom = Number.NEGATIVE_INFINITY;
|
|
757
|
+
let topMostEl = null;
|
|
758
|
+
let bottomMostEl = null;
|
|
759
|
+
let topMostTop = Number.POSITIVE_INFINITY;
|
|
760
|
+
let bottomMostBottom = Number.NEGATIVE_INFINITY;
|
|
761
|
+
for (const child of childrenElements) {
|
|
762
|
+
const rect = child.getBoundingClientRect();
|
|
763
|
+
const topRel = rect.top - wrapperRect.top;
|
|
764
|
+
const bottomRel = rect.bottom - wrapperRect.top;
|
|
765
|
+
if (topRel < minTop) {
|
|
766
|
+
minTop = topRel;
|
|
666
767
|
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
availableBottomPx < minimumApprovedHeightPx) {
|
|
670
|
-
return;
|
|
768
|
+
if (bottomRel > maxBottom) {
|
|
769
|
+
maxBottom = bottomRel;
|
|
671
770
|
}
|
|
672
|
-
if (
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
return;
|
|
771
|
+
if (rect.top < topMostTop) {
|
|
772
|
+
topMostTop = rect.top;
|
|
773
|
+
topMostEl = child;
|
|
676
774
|
}
|
|
677
|
-
if (
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
setForcedPositionY({ top: "100%", bottom: "auto" });
|
|
681
|
-
return;
|
|
775
|
+
if (rect.bottom > bottomMostBottom) {
|
|
776
|
+
bottomMostBottom = rect.bottom;
|
|
777
|
+
bottomMostEl = child;
|
|
682
778
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
779
|
+
}
|
|
780
|
+
let topMarginPx = 0;
|
|
781
|
+
let bottomMarginPx = 0;
|
|
782
|
+
if (topMostEl) {
|
|
783
|
+
const cs = window.getComputedStyle(topMostEl);
|
|
784
|
+
topMarginPx = parseFloat(cs.marginTop || "0") || 0;
|
|
785
|
+
}
|
|
786
|
+
if (bottomMostEl) {
|
|
787
|
+
const cs = window.getComputedStyle(bottomMostEl);
|
|
788
|
+
bottomMarginPx = parseFloat(cs.marginBottom || "0") || 0;
|
|
789
|
+
}
|
|
790
|
+
const unionHeight = Math.max(0, maxBottom - minTop);
|
|
791
|
+
const total = unionHeight + topMarginPx + bottomMarginPx + bordersPx;
|
|
792
|
+
el.style.height = prevHeight;
|
|
793
|
+
el.style.maxHeight = prevMaxHeight;
|
|
794
|
+
return Math.max(0, total);
|
|
795
|
+
}, []);
|
|
796
|
+
const calculateContentHeight = react.useCallback(() => {
|
|
797
|
+
if (!wrapperRef.current || !(containerRef === null || containerRef === void 0 ? void 0 : containerRef.current)) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
const triggerRect = containerRef.current.getBoundingClientRect();
|
|
801
|
+
const viewportH = window.innerHeight || document.documentElement.clientHeight;
|
|
802
|
+
const availableTopPx = Math.max(0, triggerRect.top - edgeDistance);
|
|
803
|
+
const availableBottomPx = Math.max(0, viewportH - triggerRect.bottom - edgeDistance);
|
|
804
|
+
const preferTop = position.includes("top");
|
|
805
|
+
if (optionsCount === 0) {
|
|
806
|
+
const preferSpace = preferTop ? availableTopPx : availableBottomPx;
|
|
807
|
+
const otherSpace = preferTop ? availableBottomPx : availableTopPx;
|
|
808
|
+
const minUsable = 20;
|
|
809
|
+
if (preferSpace >= minUsable || otherSpace < minUsable) {
|
|
810
|
+
setMaxAllowedHeightIfChanged(preferSpace);
|
|
811
|
+
setForcedPositionYIfChanged(undefined);
|
|
686
812
|
return;
|
|
687
813
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
814
|
+
setMaxAllowedHeightIfChanged(otherSpace);
|
|
815
|
+
setForcedPositionYIfChanged(preferTop
|
|
816
|
+
? { top: "100%", bottom: "auto" }
|
|
817
|
+
: { top: "auto", bottom: "100%" });
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
let liHeight = cachedListItemHeightRef.current;
|
|
821
|
+
if (!liHeight) {
|
|
822
|
+
const li = wrapperRef.current.querySelector("li");
|
|
823
|
+
const height = (li === null || li === void 0 ? void 0 : li.getBoundingClientRect().height) || 0;
|
|
824
|
+
if (height > 0) {
|
|
825
|
+
liHeight = height;
|
|
826
|
+
cachedListItemHeightRef.current = height;
|
|
693
827
|
}
|
|
694
|
-
setForcedPositionY(undefined);
|
|
695
828
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
return;
|
|
700
|
-
const dropdownHeightPx = containerRef.current.scrollHeight;
|
|
701
|
-
const dropdownPositionYPx = containerRef.current.getBoundingClientRect().y;
|
|
702
|
-
const viewportHeightPx = window.innerHeight || document.documentElement.clientHeight;
|
|
703
|
-
const isOverflowingTop = dropdownPositionYPx < wrapperRef.current.scrollHeight;
|
|
704
|
-
const isOverflowingBottom = dropdownPositionYPx + dropdownHeightPx + wrapperRef.current.clientHeight >
|
|
705
|
-
viewportHeightPx;
|
|
706
|
-
if (!isOverflowingTop && !isOverflowingBottom && !maxAllowedHeightPx) {
|
|
707
|
-
calculateContentHeight();
|
|
829
|
+
if (!liHeight) {
|
|
830
|
+
setMaxAllowedHeightIfChanged(preferTop ? availableTopPx : availableBottomPx);
|
|
831
|
+
setForcedPositionYIfChanged(undefined);
|
|
708
832
|
return;
|
|
709
833
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
834
|
+
const min2 = liHeight * 2;
|
|
835
|
+
const isTopOk = availableTopPx >= min2;
|
|
836
|
+
const isBottomOk = availableBottomPx >= min2;
|
|
837
|
+
if (!isTopOk && !isBottomOk) {
|
|
838
|
+
setMaxAllowedHeightIfChanged(preferTop ? availableTopPx : availableBottomPx);
|
|
839
|
+
setForcedPositionYIfChanged(undefined);
|
|
713
840
|
return;
|
|
714
841
|
}
|
|
715
|
-
if (
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
842
|
+
if (preferTop) {
|
|
843
|
+
if (isTopOk) {
|
|
844
|
+
setMaxAllowedHeightIfChanged(availableTopPx);
|
|
845
|
+
setForcedPositionYIfChanged(undefined);
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
setMaxAllowedHeightIfChanged(availableBottomPx);
|
|
849
|
+
setForcedPositionYIfChanged({ top: "100%", bottom: "auto" });
|
|
850
|
+
}
|
|
719
851
|
}
|
|
720
|
-
|
|
721
|
-
|
|
852
|
+
else {
|
|
853
|
+
if (isBottomOk) {
|
|
854
|
+
setMaxAllowedHeightIfChanged(availableBottomPx);
|
|
855
|
+
setForcedPositionYIfChanged(undefined);
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
setMaxAllowedHeightIfChanged(availableTopPx);
|
|
859
|
+
setForcedPositionYIfChanged({ top: "auto", bottom: "100%" });
|
|
860
|
+
}
|
|
722
861
|
}
|
|
723
|
-
}, [
|
|
862
|
+
}, [
|
|
863
|
+
containerRef,
|
|
864
|
+
position,
|
|
865
|
+
optionsCount,
|
|
866
|
+
setForcedPositionYIfChanged,
|
|
867
|
+
setMaxAllowedHeightIfChanged,
|
|
868
|
+
]);
|
|
869
|
+
const preventFromOverflowY = react.useCallback(() => {
|
|
870
|
+
if (!(containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) || !wrapperRef.current)
|
|
871
|
+
return;
|
|
872
|
+
calculateContentHeight();
|
|
873
|
+
}, [containerRef, calculateContentHeight]);
|
|
724
874
|
const reCalcHeightFromContent = react.useCallback(() => {
|
|
725
875
|
const wrapperElement = wrapperRef.current;
|
|
726
|
-
if (!wrapperElement)
|
|
876
|
+
if (!wrapperElement) {
|
|
727
877
|
return;
|
|
728
|
-
const wrapperVerticalBordersPx = getElementVerticalBorders(wrapperElement);
|
|
729
|
-
const firstListItemElement = wrapperElement.querySelector("li");
|
|
730
|
-
const isListRenderedInDom = !!firstListItemElement;
|
|
731
|
-
if (!isListRenderedInDom) {
|
|
732
|
-
cachedListItemHeightRef.current = null;
|
|
733
878
|
}
|
|
879
|
+
const bordersPx = getElementVerticalBorders(wrapperElement);
|
|
734
880
|
let calculatedContentHeight;
|
|
735
|
-
if (
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
if (
|
|
741
|
-
|
|
881
|
+
if (optionsCount > 0) {
|
|
882
|
+
const firstLi = wrapperElement.querySelector("li");
|
|
883
|
+
let liHeight = cachedListItemHeightRef.current;
|
|
884
|
+
if (!liHeight && firstLi) {
|
|
885
|
+
const h = firstLi.getBoundingClientRect().height || 0;
|
|
886
|
+
if (h > 0) {
|
|
887
|
+
liHeight = h;
|
|
888
|
+
cachedListItemHeightRef.current = h;
|
|
742
889
|
}
|
|
743
890
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
: wrapperVerticalBordersPx;
|
|
747
|
-
}
|
|
748
|
-
else {
|
|
749
|
-
const firstChildElement = wrapperElement.firstElementChild;
|
|
750
|
-
if (!firstChildElement) {
|
|
751
|
-
calculatedContentHeight = wrapperVerticalBordersPx;
|
|
891
|
+
if (liHeight && liHeight > 0) {
|
|
892
|
+
calculatedContentHeight = liHeight * optionsCount + bordersPx;
|
|
752
893
|
}
|
|
753
894
|
else {
|
|
754
|
-
const
|
|
755
|
-
const
|
|
895
|
+
const prevHeight = wrapperElement.style.height;
|
|
896
|
+
const prevMaxHeight = wrapperElement.style.maxHeight;
|
|
756
897
|
wrapperElement.style.height = "auto";
|
|
757
898
|
wrapperElement.style.maxHeight = "none";
|
|
758
899
|
wrapperElement.offsetHeight;
|
|
759
|
-
const firstChildRectHeight = firstChildElement.getBoundingClientRect().height || 0;
|
|
760
|
-
wrapperElement.style.height = previousHeight;
|
|
761
|
-
wrapperElement.style.maxHeight = previousMaxHeight;
|
|
762
|
-
const firstChildComputedStyles = window.getComputedStyle(firstChildElement);
|
|
763
|
-
const marginTopPx = parseFloat(firstChildComputedStyles.marginTop || "0") || 0;
|
|
764
|
-
const marginBottomPx = parseFloat(firstChildComputedStyles.marginBottom || "0") || 0;
|
|
765
900
|
calculatedContentHeight =
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
wrapperVerticalBordersPx;
|
|
901
|
+
(wrapperElement.scrollHeight || 0) + bordersPx;
|
|
902
|
+
wrapperElement.style.height = prevHeight;
|
|
903
|
+
wrapperElement.style.maxHeight = prevMaxHeight;
|
|
770
904
|
}
|
|
771
905
|
}
|
|
772
|
-
|
|
906
|
+
else {
|
|
907
|
+
calculatedContentHeight = measureVisualContentHeightPx();
|
|
908
|
+
}
|
|
909
|
+
const clamped = maxAllowedHeightPx > 0
|
|
773
910
|
? Math.min(calculatedContentHeight, maxAllowedHeightPx)
|
|
774
911
|
: calculatedContentHeight;
|
|
775
|
-
setMeasuredContentHeightPx(
|
|
776
|
-
|
|
912
|
+
setMeasuredContentHeightPx((prev) => {
|
|
913
|
+
const next = Math.max(0, Math.round(clamped));
|
|
914
|
+
return prev === next ? prev : next;
|
|
915
|
+
});
|
|
916
|
+
}, [optionsCount, maxAllowedHeightPx, measureVisualContentHeightPx]);
|
|
777
917
|
react.useLayoutEffect(() => {
|
|
778
918
|
preventFromOverflowY();
|
|
779
919
|
requestAnimationFrame(() => {
|
|
@@ -783,46 +923,56 @@ const ZDropListAutoHeightWrapper = (props) => {
|
|
|
783
923
|
}, [preventFromOverflowY, reCalcHeightFromContent]);
|
|
784
924
|
react.useLayoutEffect(() => {
|
|
785
925
|
cachedListItemHeightRef.current = null;
|
|
786
|
-
setForcedPositionY(undefined);
|
|
787
926
|
let raf1 = 0;
|
|
788
927
|
let raf2 = 0;
|
|
928
|
+
let raf3 = 0;
|
|
929
|
+
preventFromOverflowY();
|
|
930
|
+
reCalcHeightFromContent();
|
|
789
931
|
raf1 = requestAnimationFrame(() => {
|
|
932
|
+
preventFromOverflowY();
|
|
933
|
+
reCalcHeightFromContent();
|
|
790
934
|
raf2 = requestAnimationFrame(() => {
|
|
791
935
|
preventFromOverflowY();
|
|
792
936
|
reCalcHeightFromContent();
|
|
937
|
+
raf3 = requestAnimationFrame(() => {
|
|
938
|
+
preventFromOverflowY();
|
|
939
|
+
reCalcHeightFromContent();
|
|
940
|
+
});
|
|
793
941
|
});
|
|
794
942
|
});
|
|
795
943
|
return () => {
|
|
796
944
|
cancelAnimationFrame(raf1);
|
|
797
945
|
cancelAnimationFrame(raf2);
|
|
946
|
+
cancelAnimationFrame(raf3);
|
|
798
947
|
};
|
|
799
948
|
}, [optionsCount, preventFromOverflowY, reCalcHeightFromContent]);
|
|
800
949
|
react.useLayoutEffect(() => {
|
|
801
|
-
let
|
|
950
|
+
let rafId = 0;
|
|
802
951
|
const onResize = () => {
|
|
803
952
|
cachedListItemHeightRef.current = null;
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
resizeTimeoutId = setTimeout(() => {
|
|
953
|
+
cancelAnimationFrame(rafId);
|
|
954
|
+
rafId = requestAnimationFrame(() => {
|
|
807
955
|
preventFromOverflowY();
|
|
808
956
|
reCalcHeightFromContent();
|
|
809
|
-
}
|
|
957
|
+
});
|
|
810
958
|
};
|
|
811
959
|
window.addEventListener("resize", onResize);
|
|
812
960
|
return () => {
|
|
813
|
-
|
|
961
|
+
cancelAnimationFrame(rafId);
|
|
814
962
|
window.removeEventListener("resize", onResize);
|
|
815
963
|
};
|
|
816
964
|
}, [preventFromOverflowY, reCalcHeightFromContent]);
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
965
|
+
const baseY = position.includes("top")
|
|
966
|
+
? { top: "auto", bottom: "100%" }
|
|
967
|
+
: { top: "100%", bottom: "auto" };
|
|
820
968
|
const positionStyles = {
|
|
821
969
|
position: "absolute",
|
|
822
|
-
...
|
|
823
|
-
...(forcedPositionY &&
|
|
824
|
-
...(maxAllowedHeightPx
|
|
825
|
-
|
|
970
|
+
...baseY,
|
|
971
|
+
...(forcedPositionY !== null && forcedPositionY !== void 0 ? forcedPositionY : {}),
|
|
972
|
+
...(maxAllowedHeightPx ? { maxHeight: `${maxAllowedHeightPx}px` } : {}),
|
|
973
|
+
...(measuredContentHeightPx > 0
|
|
974
|
+
? { height: `${measuredContentHeightPx}px` }
|
|
975
|
+
: {}),
|
|
826
976
|
overflowY: "auto",
|
|
827
977
|
};
|
|
828
978
|
return (jsxRuntime.jsx("div", { className: wrapperClasses, style: positionStyles, ref: wrapperRef, children: children }));
|
|
@@ -1173,7 +1323,6 @@ const ZDropField = (props) => {
|
|
|
1173
1323
|
exports.ZDrop = ZDrop;
|
|
1174
1324
|
exports.ZDropField = ZDropField;
|
|
1175
1325
|
exports.classNames = classNames;
|
|
1176
|
-
exports.getAvailableSpace = getAvailableSpace;
|
|
1177
1326
|
exports.getElementVerticalBorders = getElementVerticalBorders;
|
|
1178
1327
|
exports.useOutsideClose = useOutsideClose;
|
|
1179
|
-
//# sourceMappingURL=index-
|
|
1328
|
+
//# sourceMappingURL=index-8z2jr57w.js.map
|