Skip to content

Commit 94ac94c

Browse files
authored
Fixed popup scroll positioning (#1507)
Signed-off-by: Andrey Sobolev <[email protected]>
1 parent d47b35d commit 94ac94c

File tree

1 file changed

+54
-41
lines changed

1 file changed

+54
-41
lines changed

Diff for: packages/ui/src/popups.ts

+54-41
Original file line numberDiff line numberDiff line change
@@ -113,44 +113,53 @@ export function closeDatePopup (): void {
113113
*
114114
* return boolean to show or not modal overlay.
115115
*/
116-
export function fitPopupPositionedElement (modalHTML: HTMLElement, alignment: PopupPositionElement): boolean {
116+
export function fitPopupPositionedElement (modalHTML: HTMLElement, alignment: PopupPositionElement, newProps: Record<string, string|number>): boolean {
117117
const rect = alignment.getBoundingClientRect()
118118
const rectPopup = modalHTML.getBoundingClientRect()
119-
modalHTML.style.left = modalHTML.style.right = modalHTML.style.top = modalHTML.style.bottom = ''
120-
modalHTML.style.maxHeight = modalHTML.style.height = ''
121-
modalHTML.style.maxWidth = modalHTML.style.width = ''
119+
newProps.left = newProps.right = newProps.top = newProps.bottom = ''
120+
newProps.maxHeight = newProps.height = ''
121+
newProps.maxWidth = newProps.width = ''
122122
if (alignment.position !== undefined) {
123123
if (alignment.position.v === 'top') {
124-
modalHTML.style.top = `${rect.top}px`
124+
newProps.top = `${rect.top}px`
125125
} else if (alignment.position.v === 'bottom') {
126-
modalHTML.style.top = `${rect.bottom - rectPopup.height}px`
126+
newProps.top = `${rect.bottom - rectPopup.height}px`
127127
}
128128

129129
if (alignment.position.h === 'right') {
130-
modalHTML.style.left = `calc(${rect.right}px + .125rem)`
130+
newProps.left = `calc(${rect.right}px + .125rem)`
131131
} else if (alignment.position.h === 'left') {
132-
modalHTML.style.left = `calc(${rect.left - rectPopup.width}px - .125rem)`
132+
newProps.left = `calc(${rect.left - rectPopup.width}px - .125rem)`
133133
}
134134
} else {
135135
// Vertical
136136
if (rect.bottom + rectPopup.height + 28 <= document.body.clientHeight) {
137-
modalHTML.style.top = `calc(${rect.bottom}px + .125rem)`
137+
newProps.top = `calc(${rect.bottom}px + .125rem)`
138138
} else if (rectPopup.height + 28 < rect.top) {
139-
modalHTML.style.bottom = `calc(${document.body.clientHeight - rect.y}px + .125rem)`
139+
newProps.bottom = `calc(${document.body.clientHeight - rect.y}px + .125rem)`
140140
} else {
141-
modalHTML.style.top = modalHTML.style.bottom = '1rem'
141+
newProps.top = modalHTML.style.bottom = '1rem'
142142
}
143143

144144
// Horizontal
145145
if (rect.left + rectPopup.width + 16 > document.body.clientWidth) {
146-
modalHTML.style.right = `${document.body.clientWidth - rect.right}px`
146+
newProps.right = `${document.body.clientWidth - rect.right}px`
147147
} else {
148-
modalHTML.style.left = `${rect.left}px`
148+
newProps.left = `${rect.left}px`
149149
}
150150
}
151151
return false
152152
}
153153

154+
function applyStyle (values: Record<string, string| number>, modalHTML: HTMLElement): void {
155+
for (const [k, v] of Object.entries(values)) {
156+
const old = (modalHTML.style as any)[k]
157+
if (old !== v) {
158+
(modalHTML.style as any)[k] = v
159+
}
160+
}
161+
}
162+
154163
/**
155164
* @public
156165
*
@@ -160,57 +169,61 @@ export function fitPopupPositionedElement (modalHTML: HTMLElement, alignment: Po
160169
*/
161170
export function fitPopupElement (modalHTML: HTMLElement, element?: PopupAlignment, contentPanel?: HTMLElement): boolean {
162171
let show = true
172+
const newProps: Record<string, string|number> = {}
163173
if (element != null) {
164174
show = false
165-
modalHTML.style.left = modalHTML.style.right = modalHTML.style.top = modalHTML.style.bottom = ''
166-
modalHTML.style.maxHeight = modalHTML.style.height = ''
175+
newProps.left = newProps.right = newProps.top = newProps.bottom = ''
176+
newProps.maxHeight = newProps.height = ''
167177
if (typeof element !== 'string') {
168-
return fitPopupPositionedElement(modalHTML, element)
178+
const result = fitPopupPositionedElement(modalHTML, element, newProps)
179+
applyStyle(newProps, modalHTML)
180+
return result
169181
} else if (element === 'right' && contentPanel !== undefined) {
170182
const rect = contentPanel.getBoundingClientRect()
171-
modalHTML.style.top = `calc(${rect.top}px + 0.5rem)`
172-
modalHTML.style.bottom = '0.75rem'
173-
modalHTML.style.right = '0.75rem'
174-
modalHTML.style.maxWidth = '50%'
183+
newProps.top = `calc(${rect.top}px + 0.5rem)`
184+
newProps.bottom = '0.75rem'
185+
newProps.right = '0.75rem'
186+
newProps.maxWidth = '50%'
175187
show = true
176188
} else if (element === 'top') {
177-
modalHTML.style.top = '15vh'
178-
modalHTML.style.left = '50%'
179-
modalHTML.style.transform = 'translateX(-50%)'
189+
newProps.top = '15vh'
190+
newProps.left = '50%'
191+
newProps.transform = 'translateX(-50%)'
180192
show = true
181193
} else if (element === 'account') {
182-
modalHTML.style.bottom = '2.75rem'
183-
modalHTML.style.left = '5rem'
194+
newProps.bottom = '2.75rem'
195+
newProps.left = '5rem'
184196
} else if (element === 'full' && contentPanel !== undefined) {
185197
const rect = contentPanel.getBoundingClientRect()
186-
modalHTML.style.top = `calc(${rect.top}px + 0.25rem)`
187-
modalHTML.style.bottom = '0.25rem'
188-
modalHTML.style.left = '0.25rem'
189-
modalHTML.style.right = '0.25rem'
198+
newProps.top = `calc(${rect.top}px + 0.25rem)`
199+
newProps.bottom = '0.25rem'
200+
newProps.left = '0.25rem'
201+
newProps.right = '0.25rem'
190202
show = true
191203
} else if (element === 'content' && contentPanel !== undefined) {
192204
const rect = contentPanel.getBoundingClientRect()
193-
modalHTML.style.top = `${rect.top + 1}px`
194-
modalHTML.style.height = `${Math.min(rect.height - 1, window.innerHeight - rect.top - 1)}px`
195-
modalHTML.style.left = `${rect.left + 1}px`
196-
modalHTML.style.width = `${Math.min(rect.width - 1, window.innerWidth - rect.left - 1)}px`
205+
newProps.top = `${rect.top + 1}px`
206+
newProps.height = `${Math.min(rect.height - 1, window.innerHeight - rect.top - 1)}px`
207+
newProps.left = `${rect.left + 1}px`
208+
newProps.width = `${Math.min(rect.width - 1, window.innerWidth - rect.left - 1)}px`
197209
} else if (element === 'middle') {
198210
if (contentPanel !== undefined) {
199211
const rect = contentPanel.getBoundingClientRect()
200-
modalHTML.style.top = `calc(${rect.top}px)`
212+
newProps.top = `calc(${rect.top}px)`
201213
} else {
202-
modalHTML.style.top = '15%'
214+
newProps.top = '15%'
203215
}
204-
modalHTML.style.bottom = '0.75rem'
205-
modalHTML.style.left = '50%'
206-
modalHTML.style.transform = 'translateX(-50%)'
216+
newProps.bottom = '0.75rem'
217+
newProps.left = '50%'
218+
newProps.transform = 'translateX(-50%)'
207219
}
208220
} else {
209-
modalHTML.style.top = '50%'
210-
modalHTML.style.left = '50%'
211-
modalHTML.style.transform = 'translate(-50%, -50%)'
221+
newProps.top = '50%'
222+
newProps.left = '50%'
223+
newProps.transform = 'translate(-50%, -50%)'
212224
show = true
213225
}
226+
applyStyle(newProps, modalHTML)
214227
return show
215228
}
216229

0 commit comments

Comments
 (0)