From 94ac94c1a477340df9c056a02e8ed8c9ad72cd35 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Sun, 24 Apr 2022 23:41:09 +0700 Subject: [PATCH] Fixed popup scroll positioning (#1507) Signed-off-by: Andrey Sobolev --- packages/ui/src/popups.ts | 95 ++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 41 deletions(-) diff --git a/packages/ui/src/popups.ts b/packages/ui/src/popups.ts index 0f8588bd85..7cca618d2e 100644 --- a/packages/ui/src/popups.ts +++ b/packages/ui/src/popups.ts @@ -113,44 +113,53 @@ export function closeDatePopup (): void { * * return boolean to show or not modal overlay. */ -export function fitPopupPositionedElement (modalHTML: HTMLElement, alignment: PopupPositionElement): boolean { +export function fitPopupPositionedElement (modalHTML: HTMLElement, alignment: PopupPositionElement, newProps: Record): boolean { const rect = alignment.getBoundingClientRect() const rectPopup = modalHTML.getBoundingClientRect() - modalHTML.style.left = modalHTML.style.right = modalHTML.style.top = modalHTML.style.bottom = '' - modalHTML.style.maxHeight = modalHTML.style.height = '' - modalHTML.style.maxWidth = modalHTML.style.width = '' + newProps.left = newProps.right = newProps.top = newProps.bottom = '' + newProps.maxHeight = newProps.height = '' + newProps.maxWidth = newProps.width = '' if (alignment.position !== undefined) { if (alignment.position.v === 'top') { - modalHTML.style.top = `${rect.top}px` + newProps.top = `${rect.top}px` } else if (alignment.position.v === 'bottom') { - modalHTML.style.top = `${rect.bottom - rectPopup.height}px` + newProps.top = `${rect.bottom - rectPopup.height}px` } if (alignment.position.h === 'right') { - modalHTML.style.left = `calc(${rect.right}px + .125rem)` + newProps.left = `calc(${rect.right}px + .125rem)` } else if (alignment.position.h === 'left') { - modalHTML.style.left = `calc(${rect.left - rectPopup.width}px - .125rem)` + newProps.left = `calc(${rect.left - rectPopup.width}px - .125rem)` } } else { // Vertical if (rect.bottom + rectPopup.height + 28 <= document.body.clientHeight) { - modalHTML.style.top = `calc(${rect.bottom}px + .125rem)` + newProps.top = `calc(${rect.bottom}px + .125rem)` } else if (rectPopup.height + 28 < rect.top) { - modalHTML.style.bottom = `calc(${document.body.clientHeight - rect.y}px + .125rem)` + newProps.bottom = `calc(${document.body.clientHeight - rect.y}px + .125rem)` } else { - modalHTML.style.top = modalHTML.style.bottom = '1rem' + newProps.top = modalHTML.style.bottom = '1rem' } // Horizontal if (rect.left + rectPopup.width + 16 > document.body.clientWidth) { - modalHTML.style.right = `${document.body.clientWidth - rect.right}px` + newProps.right = `${document.body.clientWidth - rect.right}px` } else { - modalHTML.style.left = `${rect.left}px` + newProps.left = `${rect.left}px` } } return false } +function applyStyle (values: Record, modalHTML: HTMLElement): void { + for (const [k, v] of Object.entries(values)) { + const old = (modalHTML.style as any)[k] + if (old !== v) { + (modalHTML.style as any)[k] = v + } + } +} + /** * @public * @@ -160,57 +169,61 @@ export function fitPopupPositionedElement (modalHTML: HTMLElement, alignment: Po */ export function fitPopupElement (modalHTML: HTMLElement, element?: PopupAlignment, contentPanel?: HTMLElement): boolean { let show = true + const newProps: Record = {} if (element != null) { show = false - modalHTML.style.left = modalHTML.style.right = modalHTML.style.top = modalHTML.style.bottom = '' - modalHTML.style.maxHeight = modalHTML.style.height = '' + newProps.left = newProps.right = newProps.top = newProps.bottom = '' + newProps.maxHeight = newProps.height = '' if (typeof element !== 'string') { - return fitPopupPositionedElement(modalHTML, element) + const result = fitPopupPositionedElement(modalHTML, element, newProps) + applyStyle(newProps, modalHTML) + return result } else if (element === 'right' && contentPanel !== undefined) { const rect = contentPanel.getBoundingClientRect() - modalHTML.style.top = `calc(${rect.top}px + 0.5rem)` - modalHTML.style.bottom = '0.75rem' - modalHTML.style.right = '0.75rem' - modalHTML.style.maxWidth = '50%' + newProps.top = `calc(${rect.top}px + 0.5rem)` + newProps.bottom = '0.75rem' + newProps.right = '0.75rem' + newProps.maxWidth = '50%' show = true } else if (element === 'top') { - modalHTML.style.top = '15vh' - modalHTML.style.left = '50%' - modalHTML.style.transform = 'translateX(-50%)' + newProps.top = '15vh' + newProps.left = '50%' + newProps.transform = 'translateX(-50%)' show = true } else if (element === 'account') { - modalHTML.style.bottom = '2.75rem' - modalHTML.style.left = '5rem' + newProps.bottom = '2.75rem' + newProps.left = '5rem' } else if (element === 'full' && contentPanel !== undefined) { const rect = contentPanel.getBoundingClientRect() - modalHTML.style.top = `calc(${rect.top}px + 0.25rem)` - modalHTML.style.bottom = '0.25rem' - modalHTML.style.left = '0.25rem' - modalHTML.style.right = '0.25rem' + newProps.top = `calc(${rect.top}px + 0.25rem)` + newProps.bottom = '0.25rem' + newProps.left = '0.25rem' + newProps.right = '0.25rem' show = true } else if (element === 'content' && contentPanel !== undefined) { const rect = contentPanel.getBoundingClientRect() - modalHTML.style.top = `${rect.top + 1}px` - modalHTML.style.height = `${Math.min(rect.height - 1, window.innerHeight - rect.top - 1)}px` - modalHTML.style.left = `${rect.left + 1}px` - modalHTML.style.width = `${Math.min(rect.width - 1, window.innerWidth - rect.left - 1)}px` + newProps.top = `${rect.top + 1}px` + newProps.height = `${Math.min(rect.height - 1, window.innerHeight - rect.top - 1)}px` + newProps.left = `${rect.left + 1}px` + newProps.width = `${Math.min(rect.width - 1, window.innerWidth - rect.left - 1)}px` } else if (element === 'middle') { if (contentPanel !== undefined) { const rect = contentPanel.getBoundingClientRect() - modalHTML.style.top = `calc(${rect.top}px)` + newProps.top = `calc(${rect.top}px)` } else { - modalHTML.style.top = '15%' + newProps.top = '15%' } - modalHTML.style.bottom = '0.75rem' - modalHTML.style.left = '50%' - modalHTML.style.transform = 'translateX(-50%)' + newProps.bottom = '0.75rem' + newProps.left = '50%' + newProps.transform = 'translateX(-50%)' } } else { - modalHTML.style.top = '50%' - modalHTML.style.left = '50%' - modalHTML.style.transform = 'translate(-50%, -50%)' + newProps.top = '50%' + newProps.left = '50%' + newProps.transform = 'translate(-50%, -50%)' show = true } + applyStyle(newProps, modalHTML) return show }