94 lines
2.1 KiB
TypeScript
94 lines
2.1 KiB
TypeScript
import gsap from "gsap";
|
|
|
|
const MODAL_MAX_Y_OFFSET = 106;
|
|
const BUTTONS_MAX_Y_OFFSET = 20;
|
|
const BUTTONS_TIME = 0.1;
|
|
const MODAL_TIME = 0.225;
|
|
|
|
const state = useState("confirmationModal", () =>
|
|
reactive({
|
|
isOpen: false,
|
|
text: "",
|
|
onConfirm: null as (() => void) | null,
|
|
offsetY: MODAL_MAX_Y_OFFSET,
|
|
buttonsYOffset: 0,
|
|
modalButtonsYOffset: BUTTONS_MAX_Y_OFFSET,
|
|
isVisible: false,
|
|
isClosing: false,
|
|
}),
|
|
);
|
|
|
|
const open = (text: string, onConfirm?: (() => void) | null) => {
|
|
gsap.killTweensOf(state.value);
|
|
state.value.text = text;
|
|
state.value.onConfirm = onConfirm || null;
|
|
state.value.isVisible = true;
|
|
state.value.isClosing = false;
|
|
state.value.isOpen = true;
|
|
|
|
gsap
|
|
.timeline()
|
|
// standard buttons down
|
|
.fromTo(
|
|
state.value,
|
|
{ buttonsYOffset: 0 },
|
|
{
|
|
buttonsYOffset: BUTTONS_MAX_Y_OFFSET,
|
|
duration: BUTTONS_TIME,
|
|
ease: "none",
|
|
},
|
|
)
|
|
// modal up
|
|
.fromTo(
|
|
state.value,
|
|
{ offsetY: MODAL_MAX_Y_OFFSET },
|
|
{ offsetY: 0, duration: MODAL_TIME, ease: "none" },
|
|
)
|
|
// modal buttons up
|
|
.fromTo(
|
|
state.value,
|
|
{ modalButtonsYOffset: BUTTONS_MAX_Y_OFFSET },
|
|
{ modalButtonsYOffset: 0, duration: BUTTONS_TIME, ease: "none" },
|
|
);
|
|
};
|
|
|
|
const close = () => {
|
|
if (!state.value.isVisible || state.value.isClosing) return;
|
|
|
|
state.value.isClosing = true;
|
|
|
|
gsap
|
|
.timeline()
|
|
// modal buttons down
|
|
.to(state.value, {
|
|
modalButtonsYOffset: BUTTONS_MAX_Y_OFFSET,
|
|
duration: BUTTONS_TIME,
|
|
ease: "none",
|
|
})
|
|
// modal down
|
|
.to(state.value, {
|
|
offsetY: MODAL_MAX_Y_OFFSET,
|
|
duration: MODAL_TIME,
|
|
ease: "none",
|
|
})
|
|
// standard buttons up
|
|
.to(state.value, {
|
|
buttonsYOffset: 0,
|
|
duration: BUTTONS_TIME,
|
|
ease: "none",
|
|
})
|
|
.call(() => {
|
|
state.value.isVisible = false;
|
|
state.value.isClosing = false;
|
|
state.value.isOpen = false;
|
|
state.value.text = "";
|
|
state.value.onConfirm = null;
|
|
});
|
|
};
|
|
|
|
export const useConfirmationModal = () => ({
|
|
open,
|
|
close,
|
|
state: readonly(state),
|
|
});
|