Files
dbx/apps/desktop/src/components/ui/sheet/SheetContent.vue
T

60 lines
2.7 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, DialogPortal, useForwardPropsEmits } from "reka-ui";
import { cn } from "@/lib/common/utils";
import { Button } from "@/components/ui/button";
import SheetOverlay from "./SheetOverlay.vue";
interface SheetContentProps extends DialogContentProps {
class?: HTMLAttributes["class"];
side?: "top" | "right" | "bottom" | "left";
showCloseButton?: boolean;
}
defineOptions({
inheritAttrs: false,
});
const props = withDefaults(defineProps<SheetContentProps>(), {
side: "right",
showCloseButton: true,
});
const emits = defineEmits<DialogContentEmits>();
const delegatedProps = reactiveOmit(props, "class", "side", "showCloseButton");
const forwarded = useForwardPropsEmits(delegatedProps, emits);
</script>
<template>
<DialogPortal>
<DialogClose as-child>
<SheetOverlay />
</DialogClose>
<DialogContent
data-slot="sheet-content"
:data-side="side"
:class="
cn(
'bg-popover text-popover-foreground fixed z-50 flex flex-col gap-4 bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10',
props.class,
)
"
v-bind="{ ...$attrs, ...forwarded }"
>
<slot />
<DialogClose v-if="showCloseButton" data-slot="sheet-close" as-child>
<Button variant="ghost" class="absolute top-3 right-3" size="icon-sm">
<XIcon />
<span class="sr-only">Close</span>
</Button>
</DialogClose>
</DialogContent>
</DialogPortal>
</template>