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
|
Edit Profile
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent class="sm:max-w-[425px]">
|
<DialogContent class="sm:max-w-[425px]" @escape-key-down.prevent>
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Edit profile</DialogTitle>
|
<DialogTitle>Edit profile</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,16 @@ import { defineComponent, h } from 'vue'
|
||||||
import {
|
import {
|
||||||
AlertDialogAction as AlertDialogActionPrimitive, type AlertDialogActionProps,
|
AlertDialogAction as AlertDialogActionPrimitive, type AlertDialogActionProps,
|
||||||
AlertDialogCancel as AlertDialogCancelPrimitive, type AlertDialogCancelProps,
|
AlertDialogCancel as AlertDialogCancelPrimitive, type AlertDialogCancelProps,
|
||||||
AlertDialogContent as AlertDialogContentPrimitive, type AlertDialogContentProps,
|
type AlertDialogContentEmits, AlertDialogContent as AlertDialogContentPrimitive, type AlertDialogContentProps,
|
||||||
AlertDialogDescription as AlertDialogDescriptionPrimitive, type AlertDialogDescriptionProps,
|
AlertDialogDescription as AlertDialogDescriptionPrimitive, type AlertDialogDescriptionProps,
|
||||||
AlertDialogOverlay as AlertDialogOverlayPrimitive, type AlertDialogOverlayProps,
|
AlertDialogOverlay as AlertDialogOverlayPrimitive, type AlertDialogOverlayProps,
|
||||||
AlertDialogPortal as AlertDialogPortalPrimitive,
|
AlertDialogPortal as AlertDialogPortalPrimitive,
|
||||||
AlertDialogRoot, AlertDialogTitle as AlertDialogTitlePrimitive,
|
AlertDialogRoot, AlertDialogTitle as AlertDialogTitlePrimitive,
|
||||||
type AlertDialogTitleProps, AlertDialogTrigger as AlertDialogTriggerPrimitive,
|
type AlertDialogTitleProps, AlertDialogTrigger as AlertDialogTriggerPrimitive,
|
||||||
|
|
||||||
} from 'radix-vue'
|
} from 'radix-vue'
|
||||||
import { cn } from '@/utils'
|
import type { ParseEmits } from '@/utils'
|
||||||
|
import { cn, useEmitAsProps } from '@/utils'
|
||||||
import { buttonVariants } from '@/registry/default/ui/button'
|
import { buttonVariants } from '@/registry/default/ui/button'
|
||||||
|
|
||||||
export const AlertDialog = AlertDialogRoot
|
export const AlertDialog = AlertDialogRoot
|
||||||
|
|
@ -25,16 +27,19 @@ export const AlertDialogOverlay = defineComponent<AlertDialogOverlayProps>(
|
||||||
}, { name: 'AlertDialogOverlay' },
|
}, { name: 'AlertDialogOverlay' },
|
||||||
)
|
)
|
||||||
|
|
||||||
export const AlertDialogContent = defineComponent<AlertDialogContentProps>(
|
export const AlertDialogContent = defineComponent<AlertDialogContentProps, ParseEmits<AlertDialogContentEmits>>(
|
||||||
(props, { attrs, slots }) => {
|
(props, { emit, attrs, slots }) => {
|
||||||
|
const emitsAsProps = useEmitAsProps(emit)
|
||||||
|
|
||||||
return () => h(AlertDialogPortal, () => [
|
return () => h(AlertDialogPortal, () => [
|
||||||
h(AlertDialogOverlay),
|
h(AlertDialogOverlay),
|
||||||
h(AlertDialogContentPrimitive, {
|
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 ?? ''),
|
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,
|
...props,
|
||||||
|
...emitsAsProps,
|
||||||
}, slots),
|
}, slots),
|
||||||
])
|
])
|
||||||
}, { name: 'AlertDialogContent' },
|
}, { name: 'AlertDialogContent', emits: AlertDialogContentPrimitive.emits },
|
||||||
)
|
)
|
||||||
|
|
||||||
export const AlertDialogHeader = defineComponent(
|
export const AlertDialogHeader = defineComponent(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { defineComponent, h } from 'vue'
|
import { defineComponent, h } from 'vue'
|
||||||
import {
|
import {
|
||||||
DialogClose, DialogContent as DialogContentPrimitive, type DialogContentProps,
|
DialogClose, type DialogContentEmits, DialogContent as DialogContentPrimitive, type DialogContentProps,
|
||||||
DialogDescription as DialogDescriptionPrimitive, type DialogDescriptionProps,
|
DialogDescription as DialogDescriptionPrimitive, type DialogDescriptionProps,
|
||||||
DialogOverlay as DialogOverlayPrimitive, type DialogOverlayProps,
|
DialogOverlay as DialogOverlayPrimitive, type DialogOverlayProps,
|
||||||
DialogPortal as DialogPortalPrimitive, DialogRoot,
|
DialogPortal as DialogPortalPrimitive, DialogRoot,
|
||||||
|
|
@ -8,7 +8,8 @@ import {
|
||||||
DialogTrigger as DialogTriggerPrimitive,
|
DialogTrigger as DialogTriggerPrimitive,
|
||||||
} from 'radix-vue'
|
} from 'radix-vue'
|
||||||
import { X } from 'lucide-vue-next'
|
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 Dialog = DialogRoot
|
||||||
export const DialogTrigger = DialogTriggerPrimitive
|
export const DialogTrigger = DialogTriggerPrimitive
|
||||||
|
|
@ -23,13 +24,16 @@ export const DialogOverlay = defineComponent<DialogOverlayProps>(
|
||||||
}, { name: 'DialogOverlay' },
|
}, { name: 'DialogOverlay' },
|
||||||
)
|
)
|
||||||
|
|
||||||
export const DialogContent = defineComponent<DialogContentProps>(
|
export const DialogContent = defineComponent<DialogContentProps, ParseEmits<DialogContentEmits>>(
|
||||||
(props, { attrs, slots }) => {
|
(props, { emit, attrs, slots }) => {
|
||||||
|
const emitsAsProps = useEmitAsProps(emit)
|
||||||
|
|
||||||
return () => h(DialogPortal, () => [
|
return () => h(DialogPortal, () => [
|
||||||
h(DialogOverlay),
|
h(DialogOverlay),
|
||||||
h(DialogContentPrimitive, {
|
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 ?? ''),
|
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,
|
...props,
|
||||||
|
...emitsAsProps,
|
||||||
}, () => [
|
}, () => [
|
||||||
slots.default(),
|
slots.default(),
|
||||||
h(DialogClose,
|
h(DialogClose,
|
||||||
|
|
@ -38,7 +42,7 @@ export const DialogContent = defineComponent<DialogContentProps>(
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
}, { name: 'DialogContent' },
|
}, { name: 'DialogContent', emits: DialogContentPrimitive.emits },
|
||||||
)
|
)
|
||||||
|
|
||||||
export const DialogHeader = defineComponent(
|
export const DialogHeader = defineComponent(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import type { ClassValue } from 'clsx'
|
import type { ClassValue } from 'clsx'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
import { camelize, getCurrentInstance, toHandlerKey } from 'vue'
|
||||||
|
|
||||||
export type ParseEmits<T extends Record<string, any>> = {
|
export type ParseEmits<T extends Record<string, any>> = {
|
||||||
[K in keyof T]: (...args: T[K]) => void;
|
[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[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs))
|
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