Float popups (#5079)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2024-03-27 20:34:17 +05:00 committed by GitHub
parent 4bcdedfa06
commit 278252b435
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 63 additions and 24 deletions

View File

@ -30,20 +30,18 @@
{#if $modal.length > 0}
<slot name="popup-header" />
{/if}
{#each $modal as popup, i}
{#key popup.id}
<PopupInstance
bind:this={instances[i]}
is={popup.is}
props={popup.props}
element={popup.element}
onClose={popup.onClose}
onUpdate={popup.onUpdate}
zIndex={(i + 1) * 500}
top={$modal.length - 1 === i}
close={popup.close}
{contentPanel}
overlay={popup.options.overlay}
/>
{/key}
{#each $modal as popup, i (popup.id)}
<PopupInstance
bind:this={instances[i]}
is={popup.is}
props={popup.props}
element={popup.element}
onClose={popup.onClose}
onUpdate={popup.onUpdate}
zIndex={(i + 1) * 500}
top={$modal.length - 1 === i}
close={popup.close}
{contentPanel}
overlay={popup.options.overlay}
/>
{/each}

View File

@ -83,7 +83,9 @@
options.props.maxHeight = '100vh'
if (!modalHTML.classList.contains('fullsize')) modalHTML.classList.add('fullsize')
} else {
options = fitPopupElement(modalHTML, device, element, contentPanel, clientWidth, clientHeight)
if (element !== 'float' || options?.props?.top === undefined || options?.props?.top === '') {
options = fitPopupElement(modalHTML, device, element, contentPanel, clientWidth, clientHeight)
}
if (modalHTML.classList.contains('fullsize')) modalHTML.classList.remove('fullsize')
}
options.fullSize = fullSize
@ -126,6 +128,16 @@
)
}
let drag: boolean = false
const dragParams: {
x: number
y: number
} = {
x: 0,
y: 0
}
export function fitPopupInstance (): void {
if (modalHTML) {
fitPopup(modalHTML, element, contentPanel)
@ -148,7 +160,7 @@
<div
class="popup {testing ? 'endShow' : showing === undefined ? 'endShow' : !showing ? 'preShow' : 'startShow'}"
class:testing
class:anim={(element === 'float' || element === 'centered') && !testing}
class:anim={(element === 'float' || element === 'centered') && !testing && !drag}
bind:this={modalHTML}
style={`z-index: ${zIndex + 1};`}
style:top={options?.props?.top}
@ -167,6 +179,22 @@
clientHeight = element.clientHeight
fitPopupInstance()
}}
on:mousedown={(e) => {
if (element === 'float') {
dragParams.x = e.offsetX
dragParams.y = e.offsetY
drag = true
}
}}
on:mouseup={() => {
drag = false
}}
on:mousemove={(e) => {
if (element === 'float' && drag) {
options.props.top = `${e.clientY - dragParams.y}px`
options.props.left = `${e.clientX - dragParams.x}px`
}
}}
>
<svelte:component
this={is}
@ -189,15 +217,24 @@
/>
</div>
{#if overlay}
{#if overlay || drag}
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="modal-overlay"
class:testing
class:antiOverlay={options?.showOverlay}
class:antiOverlay={options?.showOverlay && !drag}
style={`z-index: ${zIndex};`}
on:click={handleOverlayClick}
on:keydown|stopPropagation|preventDefault={() => {}}
on:mouseup={() => {
drag = false
}}
on:mousemove={(e) => {
if (element === 'float' && drag) {
options.props.top = `${e.clientY - dragParams.y}px`
options.props.left = `${e.clientX - dragParams.x}px`
}
}}
/>
{/if}

View File

@ -228,10 +228,14 @@ export function fitPopupElement (
newProps.maxHeight = fullHeight ? 'calc(100vh - 2rem)' : '75vh'
show = true
} else if (element === 'float') {
newProps.top = 'calc(var(--status-bar-height) + 4px)'
newProps.bottom = '4px'
newProps.left = '60%'
newProps.right = '4px'
if (clientWidth !== undefined && clientHeight !== undefined) {
newProps.top = `calc(50% - ${clientHeight / 2}px`
newProps.left = `calc(50% - ${clientWidth / 2}px`
} else {
newProps.top = '50%'
newProps.left = '50%'
newProps.transform = 'translate(-50%, -50%)'
}
show = true
} else if (element === 'center') {
if (clientWidth !== undefined && clientHeight !== undefined) {