fix: add missing emits event
This commit is contained in:
parent
81197d1e02
commit
fd0eb2f5e8
|
|
@ -20,7 +20,7 @@ import { Label } from '@/registry/default/ui/label'
|
|||
Edit Profile
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent class="sm:max-w-[425px]">
|
||||
<DialogContent class="sm:max-w-[425px]" @escape-key-down.prevent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Edit profile</DialogTitle>
|
||||
<DialogDescription>
|
||||
|
|
|
|||
|
|
@ -2,14 +2,16 @@ import { defineComponent, h } from 'vue'
|
|||
import {
|
||||
AlertDialogAction as AlertDialogActionPrimitive, type AlertDialogActionProps,
|
||||
AlertDialogCancel as AlertDialogCancelPrimitive, type AlertDialogCancelProps,
|
||||
AlertDialogContent as AlertDialogContentPrimitive, type AlertDialogContentProps,
|
||||
type AlertDialogContentEmits, AlertDialogContent as AlertDialogContentPrimitive, type AlertDialogContentProps,
|
||||
AlertDialogDescription as AlertDialogDescriptionPrimitive, type AlertDialogDescriptionProps,
|
||||
AlertDialogOverlay as AlertDialogOverlayPrimitive, type AlertDialogOverlayProps,
|
||||
AlertDialogPortal as AlertDialogPortalPrimitive,
|
||||
AlertDialogRoot, AlertDialogTitle as AlertDialogTitlePrimitive,
|
||||
type AlertDialogTitleProps, AlertDialogTrigger as AlertDialogTriggerPrimitive,
|
||||
|
||||
} from 'radix-vue'
|
||||
import { cn } from '@/utils'
|
||||
import type { ParseEmits } from '@/utils'
|
||||
import { cn, useEmitAsProps } from '@/utils'
|
||||
import { buttonVariants } from '@/registry/default/ui/button'
|
||||
|
||||
export const AlertDialog = AlertDialogRoot
|
||||
|
|
@ -25,16 +27,19 @@ export const AlertDialogOverlay = defineComponent<AlertDialogOverlayProps>(
|
|||
}, { name: 'AlertDialogOverlay' },
|
||||
)
|
||||
|
||||
export const AlertDialogContent = defineComponent<AlertDialogContentProps>(
|
||||
(props, { attrs, slots }) => {
|
||||
export const AlertDialogContent = defineComponent<AlertDialogContentProps, ParseEmits<AlertDialogContentEmits>>(
|
||||
(props, { emit, attrs, slots }) => {
|
||||
const emitsAsProps = useEmitAsProps(emit)
|
||||
|
||||
return () => h(AlertDialogPortal, () => [
|
||||
h(AlertDialogOverlay),
|
||||
h(AlertDialogContentPrimitive, {
|
||||
class: cn('fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full', attrs.class ?? ''),
|
||||
...props,
|
||||
...emitsAsProps,
|
||||
}, slots),
|
||||
])
|
||||
}, { name: 'AlertDialogContent' },
|
||||
}, { name: 'AlertDialogContent', emits: AlertDialogContentPrimitive.emits },
|
||||
)
|
||||
|
||||
export const AlertDialogHeader = defineComponent(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { defineComponent, h } from 'vue'
|
||||
import {
|
||||
DialogClose, DialogContent as DialogContentPrimitive, type DialogContentProps,
|
||||
DialogClose, type DialogContentEmits, DialogContent as DialogContentPrimitive, type DialogContentProps,
|
||||
DialogDescription as DialogDescriptionPrimitive, type DialogDescriptionProps,
|
||||
DialogOverlay as DialogOverlayPrimitive, type DialogOverlayProps,
|
||||
DialogPortal as DialogPortalPrimitive, DialogRoot,
|
||||
|
|
@ -8,7 +8,8 @@ import {
|
|||
DialogTrigger as DialogTriggerPrimitive,
|
||||
} from 'radix-vue'
|
||||
import { X } from 'lucide-vue-next'
|
||||
import { cn } from '@/utils'
|
||||
import type { ParseEmits } from '@/utils'
|
||||
import { cn, useEmitAsProps } from '@/utils'
|
||||
|
||||
export const Dialog = DialogRoot
|
||||
export const DialogTrigger = DialogTriggerPrimitive
|
||||
|
|
@ -23,13 +24,16 @@ export const DialogOverlay = defineComponent<DialogOverlayProps>(
|
|||
}, { name: 'DialogOverlay' },
|
||||
)
|
||||
|
||||
export const DialogContent = defineComponent<DialogContentProps>(
|
||||
(props, { attrs, slots }) => {
|
||||
export const DialogContent = defineComponent<DialogContentProps, ParseEmits<DialogContentEmits>>(
|
||||
(props, { emit, attrs, slots }) => {
|
||||
const emitsAsProps = useEmitAsProps(emit)
|
||||
|
||||
return () => h(DialogPortal, () => [
|
||||
h(DialogOverlay),
|
||||
h(DialogContentPrimitive, {
|
||||
class: cn('fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full', attrs.class ?? ''),
|
||||
...props,
|
||||
...emitsAsProps,
|
||||
}, () => [
|
||||
slots.default(),
|
||||
h(DialogClose,
|
||||
|
|
@ -38,7 +42,7 @@ export const DialogContent = defineComponent<DialogContentProps>(
|
|||
),
|
||||
]),
|
||||
])
|
||||
}, { name: 'DialogContent' },
|
||||
}, { name: 'DialogContent', emits: DialogContentPrimitive.emits },
|
||||
)
|
||||
|
||||
export const DialogHeader = defineComponent(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { ClassValue } from 'clsx'
|
||||
import { clsx } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { camelize, getCurrentInstance, toHandlerKey } from 'vue'
|
||||
|
||||
export type ParseEmits<T extends Record<string, any>> = {
|
||||
[K in keyof T]: (...args: T[K]) => void;
|
||||
|
|
@ -9,3 +10,24 @@ export type ParseEmits<T extends Record<string, any>> = {
|
|||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
|
||||
// Vue doesn't have emits forwarding, in order to bind the emits we have to convert events into `onXXX` handlers
|
||||
// issue: https://github.com/vuejs/core/issues/5917
|
||||
export function useEmitAsProps<Name extends string>(
|
||||
emit: (name: Name, ...args: any[]) => void,
|
||||
) {
|
||||
const vm = getCurrentInstance()
|
||||
|
||||
const events = vm?.type.emits as Name[]
|
||||
const result: Record<string, any> = {}
|
||||
if (!events?.length) {
|
||||
console.warn(
|
||||
`No emitted event found. Please check component: ${vm?.type.__name}`,
|
||||
)
|
||||
}
|
||||
|
||||
events?.forEach((ev) => {
|
||||
result[toHandlerKey(camelize(ev))] = (...arg: any) => emit(ev, ...arg)
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user