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

View File

@ -83,7 +83,9 @@
options.props.maxHeight = '100vh' options.props.maxHeight = '100vh'
if (!modalHTML.classList.contains('fullsize')) modalHTML.classList.add('fullsize') if (!modalHTML.classList.contains('fullsize')) modalHTML.classList.add('fullsize')
} else { } 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') if (modalHTML.classList.contains('fullsize')) modalHTML.classList.remove('fullsize')
} }
options.fullSize = 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 { export function fitPopupInstance (): void {
if (modalHTML) { if (modalHTML) {
fitPopup(modalHTML, element, contentPanel) fitPopup(modalHTML, element, contentPanel)
@ -148,7 +160,7 @@
<div <div
class="popup {testing ? 'endShow' : showing === undefined ? 'endShow' : !showing ? 'preShow' : 'startShow'}" class="popup {testing ? 'endShow' : showing === undefined ? 'endShow' : !showing ? 'preShow' : 'startShow'}"
class:testing class:testing
class:anim={(element === 'float' || element === 'centered') && !testing} class:anim={(element === 'float' || element === 'centered') && !testing && !drag}
bind:this={modalHTML} bind:this={modalHTML}
style={`z-index: ${zIndex + 1};`} style={`z-index: ${zIndex + 1};`}
style:top={options?.props?.top} style:top={options?.props?.top}
@ -167,6 +179,22 @@
clientHeight = element.clientHeight clientHeight = element.clientHeight
fitPopupInstance() 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 <svelte:component
this={is} this={is}
@ -189,15 +217,24 @@
/> />
</div> </div>
{#if overlay} {#if overlay || drag}
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div <div
class="modal-overlay" class="modal-overlay"
class:testing class:testing
class:antiOverlay={options?.showOverlay} class:antiOverlay={options?.showOverlay && !drag}
style={`z-index: ${zIndex};`} style={`z-index: ${zIndex};`}
on:click={handleOverlayClick} on:click={handleOverlayClick}
on:keydown|stopPropagation|preventDefault={() => {}} 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} {/if}

View File

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