diff --git a/.changeset/fast-ways-hang.md b/.changeset/fast-ways-hang.md new file mode 100644 index 0000000000..31c13e162c --- /dev/null +++ b/.changeset/fast-ways-hang.md @@ -0,0 +1,6 @@ +--- +"@heroui/shared-icons": patch +"@heroui/toast": patch +--- + +support render icons by function in Toast diff --git a/packages/components/toast/src/toast.tsx b/packages/components/toast/src/toast.tsx index 273ef89e65..1c855550d4 100644 --- a/packages/components/toast/src/toast.tsx +++ b/packages/components/toast/src/toast.tsx @@ -1,3 +1,5 @@ +import type {ReactElement} from "react"; + import {forwardRef} from "@heroui/system"; import {Button, ButtonProps} from "@heroui/button"; import { @@ -56,12 +58,19 @@ const Toast = forwardRef<"div", ToastProps>((props, ref) => { ref, }); - const customIcon = icon && isValidElement(icon) ? cloneElement(icon, getIconProps()) : null; + const customIcon = + typeof icon === "function" + ? icon(getIconProps()) + : isValidElement(icon) && cloneElement(icon as ReactElement, getIconProps()); + const IconComponent = severity ? iconMap[severity] : iconMap[color] || iconMap.default; + const customLoadingIcon = - loadingIcon && isValidElement(loadingIcon) - ? cloneElement(loadingIcon, getLoadingIconProps()) - : null; + typeof loadingIcon === "function" + ? loadingIcon(getLoadingIconProps()) + : isValidElement(loadingIcon) && + cloneElement(loadingIcon as ReactElement, getLoadingIconProps()); + const loadingIconComponent = isLoading ? customLoadingIcon || ( ((props, ref) => { : null; const customCloseIcon = - closeIcon && isValidElement(closeIcon) ? cloneElement(closeIcon, {}) : null; + typeof closeIcon === "function" + ? closeIcon({}) + : isValidElement(closeIcon) && cloneElement(closeIcon as ReactElement, {}); const toastContent = ( diff --git a/packages/components/toast/src/use-toast.ts b/packages/components/toast/src/use-toast.ts index 6c015ccc7e..ddfc4650d4 100644 --- a/packages/components/toast/src/use-toast.ts +++ b/packages/components/toast/src/use-toast.ts @@ -1,4 +1,5 @@ import type {SlotsToClasses, ToastSlots, ToastVariantProps} from "@heroui/theme"; +import type {DOMAttributes} from "react"; import {HTMLHeroUIProps, PropGetter, mapPropsVariants, useProviderContext} from "@heroui/system"; import {toast as toastTheme} from "@heroui/theme"; @@ -67,15 +68,15 @@ export interface ToastProps extends ToastVariantProps { /** * Icon to be displayed in the toast - overrides the default icon */ - icon?: ReactNode; + icon?: ReactNode | ((props: DOMAttributes) => ReactNode); /** * Icon to be displayed in the close button - overrides the default close icon */ - closeIcon?: ReactNode | ((props: any) => ReactNode); + closeIcon?: ReactNode | ((props: DOMAttributes) => ReactNode); /** * Icon to be displayed in the loading toast - overrides the loading icon */ - loadingIcon?: ReactNode; + loadingIcon?: ReactNode | ((props: DOMAttributes) => ReactNode); /** * Whether the toast-icon should be hidden. * @default false @@ -157,6 +158,7 @@ export function useToast(originalProps: UseToastProps) timeout = 6000, shouldShowTimeoutProgress = false, icon, + loadingIcon, onClose, severity, maxVisibleToasts, @@ -261,7 +263,6 @@ export function useToast(originalProps: UseToastProps) ]); const Component = as || "div"; - const loadingIcon: ReactNode = icon; const domRef = useDOMRef(ref); const baseStyles = clsx(className, classNames?.base); diff --git a/packages/components/toast/stories/toast.stories.tsx b/packages/components/toast/stories/toast.stories.tsx index ec56ed3268..c1f2f347c9 100644 --- a/packages/components/toast/stories/toast.stories.tsx +++ b/packages/components/toast/stories/toast.stories.tsx @@ -11,6 +11,7 @@ import { useDisclosure, } from "@heroui/modal"; import {Drawer, DrawerContent} from "@heroui/drawer"; +import {LoadingIcon, AvatarIcon, CloseIcon} from "@heroui/shared-icons"; import {Toast, ToastProps, ToastProvider, addToast, closeAll} from "../src"; @@ -352,7 +353,7 @@ const CustomToastTemplate = (args) => { ); }; -const CustomCloseButtonTemplate = (args) => { +const CustomCloseIconTemplate = (args) => { return ( <> {