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; export const useConfirmationModal = defineStore("confirmationModal", { state: () => ({ isOpen: false, text: "", onConfirm: null as (() => void) | null, onCancel: null as (() => void) | null, onClosed: null as ((choice: "confirm" | "cancel") => void) | null, offsetY: MODAL_MAX_Y_OFFSET, buttonsYOffset: 0, modalButtonsYOffset: BUTTONS_MAX_Y_OFFSET, isVisible: false, isClosing: false, }), actions: { open(options: { text: string; onCancel?: () => void; onConfirm?: () => void; onClosed?: (choice: "confirm" | "cancel") => void; timeout?: number; }) { gsap.killTweensOf(this); this.text = options.text; this.onConfirm = options.onConfirm ?? null; this.onCancel = options.onCancel ?? null; this.onClosed = options.onClosed ?? null; this.isVisible = true; this.isClosing = false; this.isOpen = true; gsap .timeline() // standard buttons down .fromTo( this, { buttonsYOffset: 0 }, { buttonsYOffset: BUTTONS_MAX_Y_OFFSET, duration: BUTTONS_TIME, ease: "none", }, ) // modal up .fromTo( this, { offsetY: MODAL_MAX_Y_OFFSET }, { offsetY: 0, duration: MODAL_TIME, ease: "none" }, ) // modal buttons up .fromTo( this, { modalButtonsYOffset: BUTTONS_MAX_Y_OFFSET }, { modalButtonsYOffset: 0, duration: BUTTONS_TIME, ease: "none" }, ) .call(() => { if (options.timeout) { setTimeout(() => { this.close("cancel"); }, options.timeout); } }); }, close(choice: "confirm" | "cancel") { if (!this.isVisible || this.isClosing) return; this.isClosing = true; gsap .timeline() // modal buttons down .to(this, { modalButtonsYOffset: BUTTONS_MAX_Y_OFFSET, duration: BUTTONS_TIME, ease: "none", }) // modal down .to(this, { offsetY: MODAL_MAX_Y_OFFSET, duration: MODAL_TIME, ease: "none", }) // standard buttons up .to(this, { buttonsYOffset: 0, duration: BUTTONS_TIME, ease: "none", }) .call(() => { const closedCallback = this.onClosed; this.$reset(); closedCallback?.(choice); }); }, }, });