Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@
>
<LoadingButton
:loading="props.loading"
@click="emit('event', 'confirm')"
type="submit"
class="w-full sm:w-fit"
@click="emit('event', 'confirm')"
>
{{ props.data.buttonText ?? "Confirm" }}
</LoadingButton>
<button
ref="cancelButtonRef"
type="button"
class="mt-3 inline-flex w-full justify-center rounded-md bg-zinc-800 px-3 py-2 text-sm font-semibold text-zinc-100 shadow-sm ring-1 ring-inset ring-zinc-700 hover:bg-zinc-900 sm:mt-0 sm:w-auto"
@click="emit('event', 'cancel')"
ref="cancelButtonRef"
>
Cancel
</button>
Expand All @@ -50,12 +50,6 @@
</template>

<script setup lang="ts">
import {
Dialog,
DialogTitle,
TransitionChild,
TransitionRoot,
} from "@headlessui/vue";
import type {
ModalDatas,
ModalEvents,
Expand Down
File renamed without changes.
50 changes: 29 additions & 21 deletions components/ModalStack.vue → app/components/ModalStack.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<template>
<TransitionGroup name="modal">
<component
:is="modal.component"
v-for="(modal, modalIdx) in stack"
:key="modal.data"
:is="modal.component"
:z-height="(modalIdx + 1) * 50"
:loading="modal.loading"
:data="modal.data"
Expand All @@ -15,31 +15,20 @@
<div id="modalstack"></div>
</template>

<style>
.modal-enter-active,
.modal-leave-active {
transition: all 0.2s ease;
}
.modal-enter-from {
opacity: 0;
}
.modal-enter-to {
opacity: 100;
}
.modal-leave-from {
opacity: 100;
}
.modal-leave-to {
opacity: 0;
}
</style>

<script setup lang="ts">
const stack = useModalStack();

async function handleCallback(modalIdx: number, event: string, args: any[]) {
async function handleCallback(
modalIdx: number,
event: string,
args: unknown[]
) {
const modal = stack.value[modalIdx];
console.log(modal);
if (!modal) {
console.error("modal is undefined");
return;
}
const close = () => {
stack.value.splice(modalIdx, 1);
};
Expand All @@ -54,3 +43,22 @@ async function handleCallback(modalIdx: number, event: string, args: any[]) {
}
}
</script>

<style>
.modal-enter-active,
.modal-leave-active {
transition: all 0.2s ease;
}
.modal-enter-from {
opacity: 0;
}
.modal-enter-to {
opacity: 100;
}
.modal-leave-from {
opacity: 100;
}
.modal-leave-to {
opacity: 0;
}
</style>
19 changes: 8 additions & 11 deletions components/ModalTemplate.vue → app/components/ModalTemplate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
leave-from="opacity-100"
leave-to="opacity-0"
>
<div
class="fixed inset-0 bg-zinc-950/75 transition-opacity"
/>
<div class="fixed inset-0 bg-zinc-950/75 transition-opacity" />
</TransitionChild>

<div class="fixed inset-0 z-10 w-screen overflow-y-auto">
Expand All @@ -29,7 +27,10 @@
leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div
:class="['relative transform rounded-lg bg-zinc-900 text-left shadow-xl transition-all sm:my-8 sm:w-full', props.sizeClass ?? 'sm:max-w-lg']"
:class="[
'relative transform rounded-lg bg-zinc-900 text-left shadow-xl transition-all sm:my-8 sm:w-full',
props.sizeClass ?? 'sm:max-w-lg',
]"
>
<div class="px-4 pb-4 pt-5 space-y-4 sm:p-6 sm:pb-4">
<slot />
Expand All @@ -48,15 +49,11 @@
</template>

<script setup lang="ts">
import {
Dialog,
DialogTitle,
TransitionChild,
TransitionRoot,
} from "@headlessui/vue";
import { Dialog, TransitionChild, TransitionRoot } from "@headlessui/vue";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const open: Ref<boolean> = defineModel<boolean>() as any;
const props = defineProps<{sizeClass?: string}>();
const props = defineProps<{ sizeClass?: string }>();

function close() {
open.value = false;
Expand Down
59 changes: 59 additions & 0 deletions app/components/NotificationModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<template>
<div class="relative z-50" @close="emit('event', 'close')">
<div class="fixed inset-0 bg-zinc-950/75" />

<div class="fixed inset-0 z-10 w-screen overflow-y-auto">
<div
class="flex min-h-full items-start justify-center p-4 text-center sm:items-center sm:p-0"
>
<div
class="relative transform rounded-lg bg-zinc-900 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg"
>
<div class="px-4 pb-4 pt-5 space-y-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div class="mt-3 text-center sm:mt-0 sm:text-left">
<h3 class="text-base font-semibold text-zinc-100">
{{ props.data.title }}
</h3>
<div class="mt-2">
<p class="text-sm text-zinc-400">
{{ props.data.description }}
</p>
</div>
</div>
</div>
</div>
<div
class="rounded-b-lg bg-zinc-800 px-4 py-3 sm:flex sm:gap-x-2 sm:flex-row-reverse sm:px-6"
>
<LoadingButton
:loading="props.loading"
type="submit"
class="w-full sm:w-fit"
@click="emit('event', 'close')"
>
{{ props.data.buttonText ?? "Close" }}
</LoadingButton>
</div>
</div>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import type {
ModalDatas,
ModalEvents,
ModalType,
} from "../composables/modal-stack";

const props = defineProps<{
zHeight: number;
loading: boolean;
data: ModalDatas[ModalType.Notification];
}>();
const emit = defineEmits<{
(e: "event", v: ModalEvents[ModalType.Notification]): void;
}>();
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@
>
<LoadingButton
:loading="props.loading"
@click="emit('event', 'submit', v)"
type="submit"
class="w-full sm:w-fit"
@click="emit('event', 'submit', v)"
>
{{ props.data.buttonText ?? "Submit" }}
</LoadingButton>
<button
ref="cancelButtonRef"
type="button"
class="mt-3 inline-flex w-full justify-center rounded-md bg-zinc-800 px-3 py-2 text-sm font-semibold text-zinc-100 shadow-sm ring-1 ring-inset ring-zinc-700 hover:bg-zinc-900 sm:mt-0 sm:w-auto"
@click="emit('event', 'cancel')"
ref="cancelButtonRef"
>
Cancel
</button>
Expand All @@ -62,12 +62,6 @@
</template>

<script setup lang="ts">
import {
Dialog,
DialogTitle,
TransitionChild,
TransitionRoot,
} from "@headlessui/vue";
import type {
ModalDatas,
ModalEvents,
Expand Down
22 changes: 12 additions & 10 deletions composables/modal-stack.ts → app/composables/modal-stack.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { Component } from "vue";
import { ref, type Component, type Ref } from "vue";
import ConfirmationModal from "../components/ConfirmationModal.vue";
import NotificationModal from "../components/NotificationModal.vue";
import TextInputModal from "../components/TextInputModal.vue";
import { useState } from "nuxt/app";

export type ModalCallbackType<T extends ModalType> = (
event: ModalEvents[T],
close: () => void,
...args: any[]
...args: unknown[]
) => Promise<void> | void;

export interface ModalStackElement<T extends ModalType> {
Expand All @@ -20,13 +21,13 @@ export interface ModalStackElement<T extends ModalType> {
export enum ModalType {
Confirmation,
Notification,
TextInput
TextInput,
}

export type ModalEvents = {
[ModalType.Confirmation]: "confirm" | "cancel";
[ModalType.Notification]: "close";
[ModalType.TextInput]: "cancel" | "submit"
[ModalType.TextInput]: "cancel" | "submit";
};

export type ModalDatas = {
Expand All @@ -41,12 +42,12 @@ export type ModalDatas = {
buttonText?: string;
};
[ModalType.TextInput]: {
title: string,
description: string,
buttonText?: string,
dft?: string,
placeholder?: string,
}
title: string;
description: string;
buttonText?: string;
dft?: string;
placeholder?: string;
};
};

const modalComponents: { [key in ModalType]: Component } = {
Expand All @@ -71,4 +72,5 @@ export function createModal<T extends ModalType>(
}

export const useModalStack = () =>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
useState<Array<ModalStackElement<any>>>("modal-stack", () => []);
68 changes: 0 additions & 68 deletions components/NotificationModal.vue

This file was deleted.

3 changes: 0 additions & 3 deletions eslint.config.js

This file was deleted.

Loading