+ "content": "import type { Component, JSX } from \"solid-js\"\nimport { Match, splitProps, Switch } from \"solid-js\"\nimport { Portal } from \"solid-js/web\"\n\nimport { toaster, Toast as ToastPrimitive } from \"@kobalte/core\"\nimport type { VariantProps } from \"class-variance-authority\"\nimport { cva } from \"class-variance-authority\"\n\nimport { cn } from \"~/lib/utils\"\n\nconst Toaster: Component<ToastPrimitive.ToastListProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <Portal>\n <ToastPrimitive.Region>\n <ToastPrimitive.List\n class={cn(\n \"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]\",\n props.class\n )}\n {...rest}\n />\n </ToastPrimitive.Region>\n </Portal>\n )\n}\n\nconst toastVariants = cva(\n \"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(--kb-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--kb-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[opened]:animate-in data-[closed]:animate-out data-[swipe=end]:animate-out data-[closed]:fade-out-80 data-[closed]:slide-out-to-right-full data-[opened]:slide-in-from-top-full data-[opened]:sm:slide-in-from-bottom-full\",\n {\n variants: {\n variant: {\n default: \"border bg-background text-foreground\",\n destructive:\n \"destructive group border-destructive bg-destructive text-destructive-foreground\",\n success: \"success border-success-foreground bg-success text-success-foreground\",\n warning: \"warning border-warning-foreground bg-warning text-warning-foreground\",\n error: \"error border-error-foreground bg-error text-error-foreground\"\n }\n },\n defaultVariants: {\n variant: \"default\"\n }\n }\n)\ntype ToastVariant = NonNullable<VariantProps<typeof toastVariants>[\"variant\"]>\n\nexport interface ToastProps\n extends ToastPrimitive.ToastRootProps,\n VariantProps<typeof toastVariants> {}\n\nconst Toast: Component<ToastProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\", \"variant\"])\n return (\n <ToastPrimitive.Root\n class={cn(toastVariants({ variant: props.variant }), props.class)}\n {...rest}\n />\n )\n}\n\nconst ToastClose: Component<ToastPrimitive.ToastCloseButtonProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return (\n <ToastPrimitive.CloseButton\n class={cn(\n \"absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-destructive-foreground group-[.error]:text-error-foreground group-[.success]:text-success-foreground group-[.warning]:text-warning-foreground\",\n props.class\n )}\n {...rest}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"size-4\"\n >\n <path d=\"M18 6l-12 12\" />\n <path d=\"M6 6l12 12\" />\n </svg>\n </ToastPrimitive.CloseButton>\n )\n}\n\nconst ToastTitle: Component<ToastPrimitive.ToastTitleProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return <ToastPrimitive.Title class={cn(\"text-sm font-semibold\", props.class)} {...rest} />\n}\n\nconst ToastDescription: Component<ToastPrimitive.ToastDescriptionProps> = (props) => {\n const [, rest] = splitProps(props, [\"class\"])\n return <ToastPrimitive.Description class={cn(\"text-sm opacity-90\", props.class)} {...rest} />\n}\n\nfunction showToast(props: {\n title?: JSX.Element\n description?: JSX.Element\n variant?: ToastVariant\n duration?: number\n}) {\n toaster.show((data) => (\n <Toast toastId={data.toastId} variant={props.variant} duration={props.duration}>\n <div class=\"grid gap-1\">\n {props.title && <ToastTitle>{props.title}</ToastTitle>}\n {props.description && <ToastDescription>{props.description}</ToastDescription>}\n </div>\n <ToastClose />\n </Toast>\n ))\n}\n\nfunction showToastPromise<T, U>(\n promise: Promise<T> | (() => Promise<T>),\n options: {\n loading?: JSX.Element\n success?: (data: T) => JSX.Element\n error?: (error: U) => JSX.Element\n duration?: number\n }\n) {\n const variant: { [key in ToastPrimitive.ToastPromiseState]: ToastVariant } = {\n pending: \"default\",\n fulfilled: \"success\",\n rejected: \"error\"\n }\n return toaster.promise<T, U>(promise, (props) => (\n <Toast toastId={props.toastId} variant={variant[props.state]} duration={options.duration}>\n <Switch>\n <Match when={props.state === \"pending\"}>{options.loading}</Match>\n <Match when={props.state === \"fulfilled\"}>{options.success?.(props.data!)}</Match>\n <Match when={props.state === \"rejected\"}>{options.error?.(props.error!)}</Match>\n </Switch>\n </Toast>\n ))\n}\n\nexport { Toaster, Toast, ToastClose, ToastTitle, ToastDescription, showToast, showToastPromise }\n"
0 commit comments