From d40c744f46f14c2212bd4c9ba116bb866c368426 Mon Sep 17 00:00:00 2001 From: Vishv Salvi <82429084+Vishvsalvi@users.noreply.github.com> Date: Tue, 27 May 2025 03:42:32 +0530 Subject: [PATCH 01/29] fix(date-picker): error state (#5317) * fix(date-range-picker): fixed the error state in preset * Update giant-sloths-shop.md * Removed if statement * chore(date-picker): prettier --------- Co-authored-by: WK Wong --- .changeset/giant-sloths-shop.md | 5 +++++ .../components/date-picker/src/use-date-range-picker.ts | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 .changeset/giant-sloths-shop.md diff --git a/.changeset/giant-sloths-shop.md b/.changeset/giant-sloths-shop.md new file mode 100644 index 0000000000..e7b63ce25d --- /dev/null +++ b/.changeset/giant-sloths-shop.md @@ -0,0 +1,5 @@ +--- +"@heroui/date-picker": patch +--- + +fix date-range-picker error state (#5309) diff --git a/packages/components/date-picker/src/use-date-range-picker.ts b/packages/components/date-picker/src/use-date-range-picker.ts index c1174ab086..87a4afaaad 100644 --- a/packages/components/date-picker/src/use-date-range-picker.ts +++ b/packages/components/date-picker/src/use-date-range-picker.ts @@ -14,7 +14,7 @@ import type {DateRangePickerSlots, SlotsToClasses} from "@heroui/theme"; import type {DateInputProps} from "@heroui/date-input"; import {useLabelPlacement, useProviderContext} from "@heroui/system"; -import {useMemo, useRef} from "react"; +import {useMemo, useRef, useEffect} from "react"; import {useDateRangePickerState} from "@react-stately/datepicker"; import {useDateRangePicker as useAriaDateRangePicker} from "@react-aria/datepicker"; import {clsx, dataAttr, objectToDeps} from "@heroui/shared-utils"; @@ -125,6 +125,13 @@ export function useDateRangePicker({ isInvalid: isAriaInvalid, } = useAriaDateRangePicker({...originalProps, validationBehavior}, state, domRef); + // Force revalidation when value changes programmatically + useEffect(() => { + // Trigger revalidation to sync React Aria's internal validation state + // with the new programmatically set value + state.commitValidation(); + }, [state.value, state.commitValidation]); + const isInvalid = isInvalidProp || isAriaInvalid; const slots = useMemo( From ee4d2ebe257319ce1dd14dd96b545f27bd92d56c Mon Sep 17 00:00:00 2001 From: Vishv Salvi <82429084+Vishvsalvi@users.noreply.github.com> Date: Sun, 1 Jun 2025 22:19:17 +0530 Subject: [PATCH 02/29] fix(theme): clear button in mobile (#5252) * fix(toast): fixed close button hover position * fix(input): fixed the clear button rendering on smaller devices * Delete .changeset/soft-spoons-march.md * Update input.ts * Undo unrelated toast changes --- .changeset/kind-dolphins-listen.md | 5 +++++ packages/core/theme/src/components/input.ts | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 .changeset/kind-dolphins-listen.md diff --git a/.changeset/kind-dolphins-listen.md b/.changeset/kind-dolphins-listen.md new file mode 100644 index 0000000000..77ae0ad118 --- /dev/null +++ b/.changeset/kind-dolphins-listen.md @@ -0,0 +1,5 @@ +--- +"@heroui/theme": patch +--- + +Fixed the clear button rendering for smaller devices (#5069) diff --git a/packages/core/theme/src/components/input.ts b/packages/core/theme/src/components/input.ts index 91652b6b1c..922c623237 100644 --- a/packages/core/theme/src/components/input.ts +++ b/packages/core/theme/src/components/input.ts @@ -61,7 +61,6 @@ const input = tv({ "outline-none", "select-none", "opacity-0", - "hover:!opacity-100", "cursor-pointer", "active:!opacity-70", "rounded-full", @@ -143,13 +142,13 @@ const input = tv({ md: { inputWrapper: "h-10 min-h-10 rounded-medium", input: "text-small", - clearButton: "text-large", + clearButton: "text-large hover:!opacity-100", }, lg: { label: "text-medium", inputWrapper: "h-12 min-h-12 rounded-large", input: "text-medium", - clearButton: "text-large", + clearButton: "text-large hover:!opacity-100", }, }, radius: { From 8df9716dfa29926237682b73df59e8018843e9c0 Mon Sep 17 00:00:00 2001 From: WK Date: Mon, 2 Jun 2025 00:50:43 +0800 Subject: [PATCH 03/29] fix(toast): icons (#5246) * feat(shared-icons): add loading icon * fix(toast): icons * chore(toast): revise types for icons * chore(changeset): add changeset --- .changeset/fast-ways-hang.md | 6 ++ packages/components/toast/src/toast.tsx | 21 ++++-- packages/components/toast/src/use-toast.ts | 9 ++- .../toast/stories/toast.stories.tsx | 73 +++++++------------ packages/utilities/shared-icons/src/index.ts | 1 + .../utilities/shared-icons/src/loading.tsx | 39 ++++++++++ 6 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 .changeset/fast-ways-hang.md create mode 100644 packages/utilities/shared-icons/src/loading.tsx 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 ( <> {