Files
dbx/apps/desktop/src/components/ui/dialog/DialogScrollContent.vue
T

55 lines
1.9 KiB
Vue

<script setup lang="ts">
import type { DialogContentEmits, DialogContentProps } from "reka-ui";
import type { HTMLAttributes } from "vue";
import { reactiveOmit } from "@vueuse/core";
import { XIcon } from "@lucide/vue";
import { DialogClose, DialogContent, DialogDescription, DialogPortal, VisuallyHidden, useForwardPropsEmits } from "reka-ui";
import DialogOverlay from "./DialogOverlay.vue";
import { cn } from "@/lib/common/utils";
defineOptions({
inheritAttrs: false,
});
const props = defineProps<DialogContentProps & { class?: HTMLAttributes["class"] }>();
const emits = defineEmits<DialogContentEmits>();
const delegatedProps = reactiveOmit(props, "class");
const forwarded = useForwardPropsEmits(delegatedProps, emits);
</script>
<template>
<DialogPortal>
<DialogOverlay />
<div class="fixed inset-0 z-50 grid place-items-center p-4 pointer-events-none">
<DialogContent
data-slot="dialog-content"
:class="cn('relative z-50 grid max-h-[calc(var(--dbx-viewport-height)-6rem)] w-full max-w-lg my-8 gap-4 rounded-lg border border-border bg-background p-4 shadow-lg duration-200 md:w-full pointer-events-auto', props.class)"
v-bind="{ ...$attrs, ...forwarded }"
@pointer-down-outside="
(event) => {
const originalEvent = event.detail.originalEvent;
const target = originalEvent.target as HTMLElement;
if (originalEvent.offsetX > target.clientWidth || originalEvent.offsetY > target.clientHeight) {
event.preventDefault();
}
}
"
>
<VisuallyHidden as-child>
<DialogDescription />
</VisuallyHidden>
<slot />
<DialogClose class="absolute top-4 right-4 rounded-md p-0.5 transition-colors hover:bg-secondary">
<XIcon class="w-4 h-4" />
<span class="sr-only">Close</span>
</DialogClose>
</DialogContent>
</div>
</DialogPortal>
</template>