* checkOffset - get the offset below/above and left/right element depending on screen position
(picker, input)
| 1022 | * checkOffset - get the offset below/above and left/right element depending on screen position |
| 1023 | */ |
| 1024 | function getOffset(picker, input) { |
| 1025 | let offsetElm = input[0] as HTMLElement; |
| 1026 | const pickerEl = picker[0] as HTMLElement; |
| 1027 | const rootElm = pickerEl.parentElement; |
| 1028 | const inputRect = offsetElm.getBoundingClientRect(); |
| 1029 | const pickerW = pickerEl.offsetWidth; |
| 1030 | const pickerH = pickerEl.offsetHeight; |
| 1031 | const offset = { |
| 1032 | top: 0, |
| 1033 | left: 0, |
| 1034 | width: offsetElm.offsetWidth, |
| 1035 | height: offsetElm.offsetHeight, |
| 1036 | }; |
| 1037 | |
| 1038 | while (offsetElm) { |
| 1039 | offset.top += offsetElm.offsetTop - offsetElm.scrollTop; |
| 1040 | offset.left += offsetElm.offsetLeft - offsetElm.scrollLeft; |
| 1041 | |
| 1042 | // Check if the current element in our root, or if the next offset parent is outside of the root |
| 1043 | if (offsetElm === rootElm || !rootElm.contains(offsetElm.offsetParent)) { |
| 1044 | break; |
| 1045 | } |
| 1046 | |
| 1047 | offsetElm = offsetElm.offsetParent; |
| 1048 | } |
| 1049 | |
| 1050 | // Input is to close to the right side of the screen to show picker |
| 1051 | if (inputRect.right + pickerW > window.innerWidth - window.scrollX && inputRect.right - pickerW > 0) { |
| 1052 | // Right align the picker to the input |
| 1053 | offset.left -= pickerW - offset.width; |
| 1054 | } |
| 1055 | |
| 1056 | // Input is to close to the bottom of the screen to show picker above |
| 1057 | if (inputRect.bottom + pickerH < window.innerHeight - window.scrollY) { |
| 1058 | offset.top += offset.height; |
| 1059 | } else { |
| 1060 | offset.top -= pickerH; |
| 1061 | } |
| 1062 | |
| 1063 | return offset; |
| 1064 | } |
| 1065 | |
| 1066 | /** |
| 1067 | * noop - do nothing |