feat: add new york version
This commit is contained in:
parent
20306def54
commit
c10a67321b
|
|
@ -315,13 +315,11 @@ export const docsConfig: DocsConfig = {
|
||||||
href: '/docs/components/textarea',
|
href: '/docs/components/textarea',
|
||||||
items: [],
|
items: [],
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// title: "Toast",
|
title: 'Toast',
|
||||||
// href: "#",
|
href: '/docs/components/toast',
|
||||||
// label: "Soon",
|
items: [],
|
||||||
// disabled: true,
|
},
|
||||||
// items: []
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
title: 'Toggle',
|
title: 'Toggle',
|
||||||
href: '/docs/components/toggle',
|
href: '/docs/components/toggle',
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ import RadixIconsMoon from '~icons/radix-icons/moon'
|
||||||
import RadixIconsSun from '~icons/radix-icons/sun'
|
import RadixIconsSun from '~icons/radix-icons/sun'
|
||||||
import { useConfigStore } from '@/stores/config'
|
import { useConfigStore } from '@/stores/config'
|
||||||
import { Dialog, DialogContent } from '@/lib/registry/default/ui/dialog'
|
import { Dialog, DialogContent } from '@/lib/registry/default/ui/dialog'
|
||||||
import { Toaster } from '@/lib/registry/default/ui/toast'
|
import { Toaster as DefaultToaster } from '@/lib/registry/default/ui/toast'
|
||||||
|
import { Toaster as NewYorkToaster } from '@/lib/registry/new-york/ui/toast'
|
||||||
|
|
||||||
import File from '~icons/radix-icons/file'
|
import File from '~icons/radix-icons/file'
|
||||||
import Circle from '~icons/radix-icons/circle'
|
import Circle from '~icons/radix-icons/circle'
|
||||||
|
|
@ -276,6 +277,7 @@ watch(() => $route.path, (n) => {
|
||||||
</Command>
|
</Command>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<Toaster />
|
<DefaultToaster />
|
||||||
|
<NewYorkToaster />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,11 @@ import { ToastRoot, type ToastRootEmits, type ToastRootProps, useEmitAsProps } f
|
||||||
import { toastVariants } from '.'
|
import { toastVariants } from '.'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
interface ToastVariantProps extends VariantProps<typeof toastVariants> {}
|
||||||
|
|
||||||
export interface ToastProps extends ToastRootProps {
|
export interface ToastProps extends ToastRootProps {
|
||||||
class?: string
|
class?: string
|
||||||
variant?: NonNullable<Parameters<typeof toastVariants>[0]>['variant']
|
variant?: ToastVariantProps['variant']
|
||||||
};
|
};
|
||||||
|
|
||||||
const props = defineProps<ToastProps>()
|
const props = defineProps<ToastProps>()
|
||||||
|
|
|
||||||
19
apps/www/src/lib/registry/new-york/example/ToastDemo.vue
Normal file
19
apps/www/src/lib/registry/new-york/example/ToastDemo.vue
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { useToast } from '@/lib/registry/new-york/ui/toast/use-toast'
|
||||||
|
|
||||||
|
const { toast } = useToast()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Button
|
||||||
|
variant="outline" @click="() => {
|
||||||
|
toast({
|
||||||
|
title: 'Scheduled: Catch up',
|
||||||
|
description: 'Friday, February 10, 2023 at 5:57 PM',
|
||||||
|
});
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
Add to calander
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { useToast } from '@/lib/registry/new-york/ui/toast/use-toast'
|
||||||
|
import { ToastAction } from '@/lib/registry/new-york/ui/toast'
|
||||||
|
|
||||||
|
const { toast } = useToast()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Button
|
||||||
|
variant="outline" @click="() => {
|
||||||
|
toast({
|
||||||
|
title: 'Uh oh! Something went wrong.',
|
||||||
|
description: 'There was a problem with your request.',
|
||||||
|
variant: 'destructive',
|
||||||
|
action: h(ToastAction, {
|
||||||
|
altText: 'Try again',
|
||||||
|
}, {
|
||||||
|
default: () => 'Try again',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
Show Toast
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
18
apps/www/src/lib/registry/new-york/example/ToastSimple.vue
Normal file
18
apps/www/src/lib/registry/new-york/example/ToastSimple.vue
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { useToast } from '@/lib/registry/new-york/ui/toast/use-toast'
|
||||||
|
|
||||||
|
const { toast } = useToast()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Button
|
||||||
|
variant="outline" @click="() => {
|
||||||
|
toast({
|
||||||
|
description: 'Your message has been sent.',
|
||||||
|
});
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
Show Toast
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { useToast } from '@/lib/registry/new-york/ui/toast/use-toast'
|
||||||
|
import { ToastAction } from '@/lib/registry/new-york/ui/toast'
|
||||||
|
|
||||||
|
const { toast } = useToast()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Button
|
||||||
|
variant="outline" @click="() => {
|
||||||
|
toast({
|
||||||
|
title: 'Uh oh! Something went wrong.',
|
||||||
|
description: 'There was a problem with your request.',
|
||||||
|
action: h(ToastAction, {
|
||||||
|
altText: 'Try again',
|
||||||
|
}, {
|
||||||
|
default: () => 'Try again',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
Show Toast
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||||
|
import { useToast } from '@/lib/registry/new-york/ui/toast/use-toast'
|
||||||
|
|
||||||
|
const { toast } = useToast()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Button
|
||||||
|
variant="outline" @click="() => {
|
||||||
|
toast({
|
||||||
|
title: 'Uh oh! Something went wrong.',
|
||||||
|
description: 'There was a problem with your request.',
|
||||||
|
});
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
Show Toast
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
26
apps/www/src/lib/registry/new-york/ui/toast/Toast.vue
Normal file
26
apps/www/src/lib/registry/new-york/ui/toast/Toast.vue
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ToastRoot, type ToastRootEmits, type ToastRootProps, useEmitAsProps } from 'radix-vue'
|
||||||
|
|
||||||
|
import { toastVariants } from '.'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
interface ToastVariantProps extends VariantProps<typeof toastVariants> {}
|
||||||
|
|
||||||
|
export interface ToastProps extends ToastRootProps {
|
||||||
|
class?: string
|
||||||
|
variant?: ToastVariantProps['variant']
|
||||||
|
};
|
||||||
|
|
||||||
|
const props = defineProps<ToastProps>()
|
||||||
|
const emits = defineEmits<ToastRootEmits>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ToastRoot
|
||||||
|
v-bind="{ ...props, ...useEmitAsProps(emits) }" :class="cn(toastVariants({
|
||||||
|
variant: props.variant,
|
||||||
|
}), props.class)"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</ToastRoot>
|
||||||
|
</template>
|
||||||
12
apps/www/src/lib/registry/new-york/ui/toast/ToastAction.vue
Normal file
12
apps/www/src/lib/registry/new-york/ui/toast/ToastAction.vue
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ToastAction, type ToastActionProps } from 'radix-vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<ToastActionProps & { class?: string }>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ToastAction v-bind="props" :class="cn('inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive', props.class)">
|
||||||
|
<slot />
|
||||||
|
</ToastAction>
|
||||||
|
</template>
|
||||||
15
apps/www/src/lib/registry/new-york/ui/toast/ToastClose.vue
Normal file
15
apps/www/src/lib/registry/new-york/ui/toast/ToastClose.vue
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ToastClose } from 'radix-vue'
|
||||||
|
import { XIcon } from 'lucide-vue-next'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
class?: string
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ToastClose v-bind="props" :class="cn('absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600', props.class)">
|
||||||
|
<XIcon class="h-4 w-4" />
|
||||||
|
</ToastClose>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ToastDescription, type ToastDescriptionProps } from 'radix-vue'
|
||||||
|
import { cn } from '@/lib/utils.ts'
|
||||||
|
|
||||||
|
const props = defineProps<ToastDescriptionProps & { class?: string }>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ToastDescription :class="cn('text-sm opacity-90', props.class)" v-bind="props">
|
||||||
|
<slot />
|
||||||
|
</ToastDescription>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ToastProvider, type ToastProviderProps } from 'radix-vue'
|
||||||
|
|
||||||
|
const props = defineProps<ToastProviderProps>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ToastProvider v-bind="props">
|
||||||
|
<slot />
|
||||||
|
</ToastProvider>
|
||||||
|
</template>
|
||||||
12
apps/www/src/lib/registry/new-york/ui/toast/ToastTitle.vue
Normal file
12
apps/www/src/lib/registry/new-york/ui/toast/ToastTitle.vue
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ToastTitle, type ToastTitleProps } from 'radix-vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<ToastTitleProps & { class?: string }>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ToastTitle v-bind="props" :class="cn('text-sm font-semibold [&+div]:text-xs', props.class)">
|
||||||
|
<slot />
|
||||||
|
</ToastTitle>
|
||||||
|
</template>
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ToastViewport, type ToastViewportProps } from 'radix-vue'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
const props = defineProps<ToastViewportProps & { class?: string }>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ToastViewport v-bind="props" :class="cn('fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]', props.class)" />
|
||||||
|
</template>
|
||||||
24
apps/www/src/lib/registry/new-york/ui/toast/Toaster.vue
Normal file
24
apps/www/src/lib/registry/new-york/ui/toast/Toaster.vue
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useToast } from './use-toast'
|
||||||
|
import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from '.'
|
||||||
|
|
||||||
|
const { toasts } = useToast()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ToastProvider>
|
||||||
|
<Toast v-for="toast in toasts" :key="toast.id" v-bind="toast">
|
||||||
|
<div class="grid gap-1">
|
||||||
|
<ToastTitle v-if="toast.title">
|
||||||
|
{{ toast.title }}
|
||||||
|
</ToastTitle>
|
||||||
|
<ToastDescription v-if="toast.description">
|
||||||
|
{{ toast.description }}
|
||||||
|
</ToastDescription>
|
||||||
|
<ToastClose />
|
||||||
|
</div>
|
||||||
|
<component :is="toast.action" />
|
||||||
|
</Toast>
|
||||||
|
<ToastViewport />
|
||||||
|
</ToastProvider>
|
||||||
|
</template>
|
||||||
26
apps/www/src/lib/registry/new-york/ui/toast/index.ts
Normal file
26
apps/www/src/lib/registry/new-york/ui/toast/index.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
export { default as Toaster } from './Toaster.vue'
|
||||||
|
export { default as Toast } from './Toast.vue'
|
||||||
|
export { default as ToastViewport } from './ToastViewport.vue'
|
||||||
|
export { default as ToastAction } from './ToastAction.vue'
|
||||||
|
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'
|
||||||
|
|
||||||
|
import { cva } from 'class-variance-authority'
|
||||||
|
|
||||||
|
export const toastVariants = cva(
|
||||||
|
'group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default: 'border bg-background text-foreground',
|
||||||
|
destructive:
|
||||||
|
'destructive group border-destructive bg-destructive text-destructive-foreground',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: 'default',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
160
apps/www/src/lib/registry/new-york/ui/toast/use-toast.ts
Normal file
160
apps/www/src/lib/registry/new-york/ui/toast/use-toast.ts
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import type { Component } from 'vue'
|
||||||
|
import type { ToastProps } from './Toast.vue'
|
||||||
|
|
||||||
|
const TOAST_LIMIT = 1
|
||||||
|
const TOAST_REMOVE_DELAY = 1000000
|
||||||
|
|
||||||
|
type ToasterToast = ToastProps & {
|
||||||
|
id: string
|
||||||
|
title?: string
|
||||||
|
description?: string
|
||||||
|
action?: Component
|
||||||
|
}
|
||||||
|
|
||||||
|
const actionTypes = {
|
||||||
|
ADD_TOAST: 'ADD_TOAST',
|
||||||
|
UPDATE_TOAST: 'UPDATE_TOAST',
|
||||||
|
DISMISS_TOAST: 'DISMISS_TOAST',
|
||||||
|
REMOVE_TOAST: 'REMOVE_TOAST',
|
||||||
|
} as const
|
||||||
|
|
||||||
|
let count = 0
|
||||||
|
|
||||||
|
function genId() {
|
||||||
|
count = (count + 1) % Number.MAX_VALUE
|
||||||
|
return count.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
type ActionType = typeof actionTypes
|
||||||
|
|
||||||
|
type Action =
|
||||||
|
| {
|
||||||
|
type: ActionType['ADD_TOAST']
|
||||||
|
toast: ToasterToast
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: ActionType['UPDATE_TOAST']
|
||||||
|
toast: Partial<ToasterToast>
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: ActionType['DISMISS_TOAST']
|
||||||
|
toastId?: ToasterToast['id']
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: ActionType['REMOVE_TOAST']
|
||||||
|
toastId?: ToasterToast['id']
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
toasts: ToasterToast[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
|
||||||
|
|
||||||
|
function addToRemoveQueue(toastId: string) {
|
||||||
|
if (toastTimeouts.has(toastId))
|
||||||
|
return
|
||||||
|
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
toastTimeouts.delete(toastId)
|
||||||
|
dispatch({
|
||||||
|
type: actionTypes.REMOVE_TOAST,
|
||||||
|
toastId,
|
||||||
|
})
|
||||||
|
}, TOAST_REMOVE_DELAY)
|
||||||
|
|
||||||
|
toastTimeouts.set(toastId, timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = ref<State>({
|
||||||
|
toasts: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
function dispatch(action: Action) {
|
||||||
|
switch (action.type) {
|
||||||
|
case actionTypes.ADD_TOAST:
|
||||||
|
state.value.toasts = [action.toast, ...state.value.toasts].slice(0, TOAST_LIMIT)
|
||||||
|
break
|
||||||
|
|
||||||
|
case actionTypes.UPDATE_TOAST:
|
||||||
|
state.value.toasts = state.value.toasts.map(t =>
|
||||||
|
t.id === action.toast.id ? { ...t, ...action.toast } : t,
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
|
case actionTypes.DISMISS_TOAST: {
|
||||||
|
const { toastId } = action
|
||||||
|
|
||||||
|
if (toastId) {
|
||||||
|
addToRemoveQueue(toastId)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state.value.toasts.forEach((toast) => {
|
||||||
|
addToRemoveQueue(toast.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
state.value.toasts = state.value.toasts.map(t =>
|
||||||
|
t.id === toastId || toastId === undefined
|
||||||
|
? {
|
||||||
|
...t,
|
||||||
|
open: false,
|
||||||
|
}
|
||||||
|
: t,
|
||||||
|
)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
case actionTypes.REMOVE_TOAST:
|
||||||
|
if (action.toastId === undefined)
|
||||||
|
state.value.toasts = []
|
||||||
|
else
|
||||||
|
state.value.toasts = state.value.toasts.filter(t => t.id !== action.toastId)
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function useToast() {
|
||||||
|
return {
|
||||||
|
toasts: computed(() => state.value.toasts),
|
||||||
|
toast,
|
||||||
|
dismiss: (toastId?: string) => dispatch({ type: actionTypes.DISMISS_TOAST, toastId }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Toast = Omit<ToasterToast, 'id'>
|
||||||
|
|
||||||
|
function toast(props: Toast) {
|
||||||
|
const id = genId()
|
||||||
|
|
||||||
|
const update = (props: ToasterToast) =>
|
||||||
|
dispatch({
|
||||||
|
type: actionTypes.UPDATE_TOAST,
|
||||||
|
toast: { ...props, id },
|
||||||
|
})
|
||||||
|
|
||||||
|
const dismiss = () => dispatch({ type: actionTypes.DISMISS_TOAST, toastId: id })
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: actionTypes.ADD_TOAST,
|
||||||
|
toast: {
|
||||||
|
...props,
|
||||||
|
id,
|
||||||
|
'open': true,
|
||||||
|
'onUpdate:open': (open: boolean) => {
|
||||||
|
if (!open)
|
||||||
|
dismiss()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
dismiss,
|
||||||
|
update,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { toast, useToast }
|
||||||
Loading…
Reference in New Issue
Block a user