refactor(popup): Refactored Modals + Popups and made them respect animation + transition durations
This commit is contained in:
parent
ea715f15bb
commit
5b25e50ab8
2 changed files with 34 additions and 67 deletions
|
|
@ -4,7 +4,7 @@ import type {
|
|||
ParentProps,
|
||||
Setter,
|
||||
} from 'solid-js';
|
||||
import { For, Show, createEffect, createSignal, mergeProps } from 'solid-js';
|
||||
import { For, mergeProps } from 'solid-js';
|
||||
import { Portal } from 'solid-js/web';
|
||||
import Button from '../base/Button';
|
||||
|
||||
|
|
@ -34,52 +34,35 @@ type ModalProps = {
|
|||
} & ParentProps;
|
||||
|
||||
function Modal(props: ModalProps) {
|
||||
const [localVisible, setLocalVisible] = createSignal(false);
|
||||
const [animate, setAnimate] = createSignal('animate-fade-in');
|
||||
const merged: ModalProps = mergeProps({ buttons: ['Ok'] }, props);
|
||||
|
||||
createEffect(() => {
|
||||
if (props.visible()) {
|
||||
setAnimate('animate-fade-in');
|
||||
setLocalVisible(true);
|
||||
}
|
||||
else {
|
||||
setAnimate('animate-fade-out');
|
||||
setTimeout(() => {
|
||||
setLocalVisible(false);
|
||||
}, 150);
|
||||
}
|
||||
});
|
||||
|
||||
function onBackdropClick() {
|
||||
props.setVisible(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<Show when={localVisible()}>
|
||||
<Portal>
|
||||
<div class={`fixed z-[1000] top-0 left-0 w-screen h-screen bg-black/60 backdrop-blur-sm backdrop-grayscale ${animate()}`}>
|
||||
<div class="absolute w-full h-full" onClick={() => onBackdropClick()} />
|
||||
<Portal>
|
||||
<div class={`fixed z-[1000] top-0 left-0 w-screen h-screen bg-black/60 backdrop-blur-sm backdrop-grayscale transition-all ${props.visible() ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}`}>
|
||||
<div class="absolute w-full h-full" onClick={() => onBackdropClick()} />
|
||||
|
||||
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<div class="bg-primary border border-white/5 p-4 rounded-lg text-center flex flex-col gap-y-2">
|
||||
<h2>{props.title}</h2>
|
||||
<div class="flex flex-col">
|
||||
{props.children}
|
||||
</div>
|
||||
<div class="flex flex-row gap-x-4 [&>*]:flex-1">
|
||||
<For each={merged.buttons}>
|
||||
{button => (
|
||||
<ModalButton props={button} />
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<div class="bg-primary border border-white/5 p-4 rounded-lg text-center flex flex-col gap-y-2">
|
||||
<h2>{props.title}</h2>
|
||||
<div class="flex flex-col">
|
||||
{props.children}
|
||||
</div>
|
||||
<div class="flex flex-row gap-x-4 [&>*]:flex-1">
|
||||
<For each={merged.buttons}>
|
||||
{button => (
|
||||
<ModalButton props={button} />
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</Portal>
|
||||
</Show>
|
||||
|
||||
</div>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
import { mergeRefs } from '@solid-primitives/refs';
|
||||
import {
|
||||
Show,
|
||||
createEffect,
|
||||
createSignal } from 'solid-js';
|
||||
import { createEffect } from 'solid-js';
|
||||
import type {
|
||||
Accessor,
|
||||
JSX,
|
||||
|
|
@ -22,14 +19,11 @@ declare namespace Popup {
|
|||
}
|
||||
|
||||
function Popup(props: Popup.PopupProps) {
|
||||
const [localVisible, setLocalVisible] = createSignal(false);
|
||||
const [animate, setAnimate] = createSignal('animate-fade-in');
|
||||
|
||||
let popupRef!: HTMLDivElement;
|
||||
|
||||
function onMouseDown(e: MouseEvent) {
|
||||
e.stopPropagation();
|
||||
if (!popupRef || !localVisible())
|
||||
if (!popupRef || !props.visible())
|
||||
return;
|
||||
|
||||
const clicked = e.target === popupRef || popupRef.contains(e.target as Node);
|
||||
|
|
@ -38,34 +32,24 @@ function Popup(props: Popup.PopupProps) {
|
|||
}
|
||||
|
||||
createEffect(() => {
|
||||
if (props.visible()) {
|
||||
if (props.visible())
|
||||
document.addEventListener('mousedown', onMouseDown);
|
||||
setAnimate('animate-fade-in');
|
||||
setLocalVisible(true);
|
||||
}
|
||||
else {
|
||||
else
|
||||
document.removeEventListener('mousedown', onMouseDown);
|
||||
setAnimate('animate-fade-out');
|
||||
setTimeout(() => {
|
||||
setLocalVisible(false);
|
||||
}, 150);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Show when={localVisible()}>
|
||||
<Portal
|
||||
mount={props.mount || document.body}
|
||||
ref={mergeRefs((el) => {
|
||||
el.classList.add('absolute', 'z-[1000]');
|
||||
return el;
|
||||
}, props.ref)}
|
||||
>
|
||||
<div ref={popupRef} style={props.style || ''} class={`${animate()} ${props.class || ''}`}>
|
||||
{props.children}
|
||||
</div>
|
||||
</Portal>
|
||||
</Show>
|
||||
<Portal
|
||||
mount={props.mount || document.body}
|
||||
ref={mergeRefs((el) => {
|
||||
el.classList.add('absolute', 'z-[1000]', 'pointer-events-none');
|
||||
return el;
|
||||
}, props.ref)}
|
||||
>
|
||||
<div ref={popupRef} style={props.style || ''} class={`transition-opacity ${props.visible() ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'} ${props.class || ''}`}>
|
||||
{props.children}
|
||||
</div>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue