feat(common): implement buttons and confirmation modal
This commit is contained in:
93
app/composables/useConfirmationModal.ts
Normal file
93
app/composables/useConfirmationModal.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
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),
|
||||
});
|
||||
Reference in New Issue
Block a user