- TabsList scrolls horizontally instead of overflowing the page - DialogContent caps height with internal scroll; DialogScrollContent gets the mobile width gutter - SidebarTrigger tap target bumped to 36px
54 lines
2.1 KiB
Vue
54 lines
2.1 KiB
Vue
<script setup lang="ts">
|
|
import type { DialogContentEmits, DialogContentProps } from "reka-ui"
|
|
import type { HTMLAttributes } from "vue"
|
|
import { reactiveOmit } from "@vueuse/core"
|
|
import { IconX } from "@tabler/icons-vue"
|
|
import {
|
|
DialogClose,
|
|
DialogContent,
|
|
DialogPortal,
|
|
useForwardPropsEmits,
|
|
} from "reka-ui"
|
|
import { cn } from "@/lib/utils"
|
|
import DialogOverlay from "./DialogOverlay.vue"
|
|
|
|
defineOptions({
|
|
inheritAttrs: false,
|
|
})
|
|
|
|
const props = withDefaults(defineProps<DialogContentProps & { class?: HTMLAttributes["class"], showCloseButton?: boolean }>(), {
|
|
showCloseButton: true,
|
|
})
|
|
const emits = defineEmits<DialogContentEmits>()
|
|
|
|
const delegatedProps = reactiveOmit(props, "class")
|
|
|
|
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|
</script>
|
|
|
|
<template>
|
|
<DialogPortal>
|
|
<DialogOverlay />
|
|
<DialogContent
|
|
data-slot="dialog-content"
|
|
v-bind="{ ...$attrs, ...forwarded }"
|
|
:class="
|
|
cn(
|
|
'bg-card data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 max-h-[85dvh] overflow-y-auto rounded-2xl border-2 border-foreground p-6 shadow-lg duration-200 sm:max-w-lg',
|
|
props.class,
|
|
)"
|
|
>
|
|
<slot />
|
|
|
|
<DialogClose
|
|
v-if="showCloseButton"
|
|
data-slot="dialog-close"
|
|
:aria-label="$t('common.close')"
|
|
class="absolute top-3 right-3 inline-flex size-8 cursor-pointer items-center justify-center rounded-full border-2 border-foreground bg-card text-foreground shadow-2xs transition-all hover:-rotate-90 hover:bg-rose-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-foreground disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
>
|
|
<IconX class="size-4" stroke-width="2.5" />
|
|
<span class="sr-only">{{ $t('common.close') }}</span>
|
|
</DialogClose>
|
|
</DialogContent>
|
|
</DialogPortal>
|
|
</template>
|