feat: add VNode type to toast description

This commit is contained in:
Sadegh Barati 2023-10-30 22:36:00 +03:30
parent 247a57c9d7
commit 849596e870
12 changed files with 72 additions and 26 deletions

View File

@ -3,6 +3,7 @@ import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import { h } from 'vue'
import { Button } from '@/lib/registry/default/ui/button'
import {
FormControl,
@ -13,6 +14,7 @@ import {
FormMessage,
} from '@/lib/registry/default/ui/form'
import { Input } from '@/lib/registry/default/ui/input'
import { toast } from '@/lib/registry/default/ui/toast/use-toast'
const formSchema = toTypedSchema(z.object({
username: z.string().min(2).max(50),
@ -23,7 +25,10 @@ const { handleSubmit } = useForm({
})
const onSubmit = handleSubmit((values) => {
console.log('Form submitted!', values)
toast({
title: 'You submitted the following values:',
description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),
})
})
</script>

View File

@ -1,18 +1,24 @@
<script setup lang="ts">
import { ToastRoot, type ToastRootEmits, type ToastRootProps, useEmitAsProps } from 'radix-vue'
import { toastVariants } from '.'
import { cn } from '@/lib/utils'
<script lang="ts">
import type { ToastRootEmits, ToastRootProps } from 'radix-vue'
import type { VariantProps } from 'class-variance-authority'
interface ToastVariantProps extends VariantProps<typeof toastVariants> {}
export interface ToastProps extends ToastRootProps {
class?: string
variant?: ToastVariantProps['variant']
'onUpdate:open'?: ((value: boolean) => void) | undefined
};
</script>
<script setup lang="ts">
import { ToastRoot, useEmitAsProps } from 'radix-vue'
import { toastVariants } from '.'
import { cn } from '@/lib/utils'
const props = defineProps<ToastProps>()
const emits = defineEmits<ToastRootEmits>()
const emits = defineEmits<Omit<ToastRootEmits, 'update:open'>>()
</script>
<template>

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { ToastDescription, type ToastDescriptionProps } from 'radix-vue'
import { cn } from '@/lib/utils.ts'
import { cn } from '@/lib/utils'
const props = defineProps<ToastDescriptionProps & { class?: string }>()
</script>

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { isVNode } from 'vue'
import { useToast } from './use-toast'
import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from '.'
@ -12,9 +13,14 @@ const { toasts } = useToast()
<ToastTitle v-if="toast.title">
{{ toast.title }}
</ToastTitle>
<ToastDescription v-if="toast.description">
{{ toast.description }}
</ToastDescription>
<template v-if="toast.description">
<ToastDescription v-if="isVNode(toast.description)">
<component :is="toast.description" />
</ToastDescription>
<ToastDescription v-else>
{{ toast.description }}
</ToastDescription>
</template>
<ToastClose />
</div>
<component :is="toast.action" />

View File

@ -6,6 +6,7 @@ export { default as ToastClose } from './ToastClose.vue'
export { default as ToastTitle } from './ToastTitle.vue'
export { default as ToastDescription } from './ToastDescription.vue'
export { default as ToastProvider } from './ToastProvider.vue'
export { useToast } from './use-toast'
import { cva } from 'class-variance-authority'

View File

@ -1,14 +1,19 @@
import { computed, ref } from 'vue'
import type { Component } from 'vue'
import type { Component, VNode } from 'vue'
import type { ToastProps } from './Toast.vue'
const TOAST_LIMIT = 1
const TOAST_REMOVE_DELAY = 1000000
export type StringOrVNode =
| string
| VNode
| (() => VNode)
type ToasterToast = ToastProps & {
id: string
title?: string
description?: string
description?: StringOrVNode
action?: Component
}

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { h } from 'vue'
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
@ -13,6 +14,7 @@ import {
FormMessage,
} from '@/lib/registry/new-york/ui/form'
import { Input } from '@/lib/registry/new-york/ui/input'
import { toast } from '@/lib/registry/new-york/ui/toast/use-toast'
const formSchema = toTypedSchema(z.object({
username: z.string().min(2).max(50),
@ -23,7 +25,10 @@ const { isFieldDirty, handleSubmit } = useForm({
})
const onSubmit = handleSubmit((values) => {
console.log('Form submitted!', values)
toast({
title: 'You submitted the following values:',
description: h('pre', { class: 'mt-2 w-[340px] rounded-md bg-slate-950 p-4' }, h('code', { class: 'text-white' }, JSON.stringify(values, null, 2))),
})
})
</script>

View File

@ -1,18 +1,24 @@
<script setup lang="ts">
import { ToastRoot, type ToastRootEmits, type ToastRootProps, useEmitAsProps } from 'radix-vue'
import { toastVariants } from '.'
import { cn } from '@/lib/utils'
<script lang="ts">
import type { ToastRootEmits, ToastRootProps } from 'radix-vue'
import type { VariantProps } from 'class-variance-authority'
interface ToastVariantProps extends VariantProps<typeof toastVariants> {}
export interface ToastProps extends ToastRootProps {
class?: string
variant?: ToastVariantProps['variant']
'onUpdate:open'?: ((value: boolean) => void) | undefined
};
</script>
<script setup lang="ts">
import { ToastRoot, useEmitAsProps } from 'radix-vue'
import { toastVariants } from '.'
import { cn } from '@/lib/utils'
const props = defineProps<ToastProps>()
const emits = defineEmits<ToastRootEmits>()
const emits = defineEmits<Omit<ToastRootEmits, 'update:open'>>()
</script>
<template>

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { ToastDescription, type ToastDescriptionProps } from 'radix-vue'
import { cn } from '@/lib/utils.ts'
import { cn } from '@/lib/utils'
const props = defineProps<ToastDescriptionProps & { class?: string }>()
</script>

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import { isVNode } from 'vue'
import { useToast } from './use-toast'
import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from '.'
@ -12,9 +13,14 @@ const { toasts } = useToast()
<ToastTitle v-if="toast.title">
{{ toast.title }}
</ToastTitle>
<ToastDescription v-if="toast.description">
{{ toast.description }}
</ToastDescription>
<template v-if="toast.description">
<ToastDescription v-if="isVNode(toast.description)">
<component :is="toast.description" />
</ToastDescription>
<ToastDescription v-else>
{{ toast.description }}
</ToastDescription>
</template>
<ToastClose />
</div>
<component :is="toast.action" />

View File

@ -6,6 +6,7 @@ export { default as ToastClose } from './ToastClose.vue'
export { default as ToastTitle } from './ToastTitle.vue'
export { default as ToastDescription } from './ToastDescription.vue'
export { default as ToastProvider } from './ToastProvider.vue'
export { useToast } from './use-toast'
import { cva } from 'class-variance-authority'

View File

@ -1,14 +1,19 @@
import { computed, ref } from 'vue'
import type { Component } from 'vue'
import type { Component, VNode } from 'vue'
import type { ToastProps } from './Toast.vue'
const TOAST_LIMIT = 1
const TOAST_REMOVE_DELAY = 1000000
export type StringOrVNode =
| string
| VNode
| (() => VNode)
type ToasterToast = ToastProps & {
id: string
title?: string
description?: string
description?: StringOrVNode
action?: Component
}