From 945006f9e2c809e617d80bbe757197e4e850233a Mon Sep 17 00:00:00 2001 From: Kar Rui Lau Date: Tue, 20 Aug 2024 17:55:21 +0800 Subject: [PATCH] fix!(DatePicker): add `renderInputElement` prop (#745) * fix!(DatePicker): change `renderInputElement` prop to be a function This allows users to use datepicker hooks in their custom input component. Currently, if `useDatepicker` hook is used in the custom input element, react will throw (since the custom component is instantiated without a datepicker parent) * feat: ensure backwards compatibility for DatePicker inputElement prop --- react/src/DatePicker/DatePicker.stories.tsx | 4 ++-- react/src/DatePicker/DatePickerContext.tsx | 3 +++ react/src/DatePicker/components/DatePickerWrapper.tsx | 5 +++-- react/src/DatePicker/types.ts | 9 +++++++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/react/src/DatePicker/DatePicker.stories.tsx b/react/src/DatePicker/DatePicker.stories.tsx index 0fdef792..d659083b 100644 --- a/react/src/DatePicker/DatePicker.stories.tsx +++ b/react/src/DatePicker/DatePicker.stories.tsx @@ -96,12 +96,12 @@ const CustomInputButton = forwardRef((_props, ref) => { export const CustomInput = Template.bind({}) CustomInput.args = { - inputElement: , + renderInputElement: () => , } export const MobileCustomInput = Template.bind({}) MobileCustomInput.args = { - inputElement: , + renderInputElement: () => , } MobileCustomInput.parameters = getMobileViewParameters() diff --git a/react/src/DatePicker/DatePickerContext.tsx b/react/src/DatePicker/DatePickerContext.tsx index a1b676c5..a2f355f3 100644 --- a/react/src/DatePicker/DatePickerContext.tsx +++ b/react/src/DatePicker/DatePickerContext.tsx @@ -48,6 +48,7 @@ interface DatePickerContextReturn { colorScheme?: ThemingProps<'DatePicker'>['colorScheme'] size?: ThemingProps<'DatePicker'>['size'] disclosureProps: UseDisclosureReturn + renderInputElement?: () => React.ReactNode inputElement?: React.ReactNode innerRef?: React.Ref calendarProps: Pick< @@ -114,6 +115,7 @@ const useProvideDatePicker = ({ size, experimental_forceIosNumberKeyboard, inputElement, + renderInputElement, innerRef, ...props }: DatePickerProviderProps): DatePickerContextReturn => { @@ -287,6 +289,7 @@ const useProvideDatePicker = ({ calendarProps, inputPattern, inputElement, + renderInputElement, innerRef, } } diff --git a/react/src/DatePicker/components/DatePickerWrapper.tsx b/react/src/DatePicker/components/DatePickerWrapper.tsx index 110e27ff..476da762 100644 --- a/react/src/DatePicker/components/DatePickerWrapper.tsx +++ b/react/src/DatePicker/components/DatePickerWrapper.tsx @@ -12,12 +12,13 @@ export const DatePickerWrapper = ({ children }: PropsWithChildren) => { initialFocusRef, closeCalendarOnChange, isMobile, + renderInputElement, inputElement, } = useDatePicker() const inputToRender = useMemo(() => { - return inputElement ?? - }, [inputElement]) + return renderInputElement?.() ?? inputElement ?? + }, [inputElement, renderInputElement]) if (isMobile) { return ( diff --git a/react/src/DatePicker/types.ts b/react/src/DatePicker/types.ts index f7954dc5..f67917a1 100644 --- a/react/src/DatePicker/types.ts +++ b/react/src/DatePicker/types.ts @@ -48,5 +48,14 @@ export interface DatePickerBaseProps refocusOnClose?: boolean /** date-fns's Locale of the date to be applied if provided. */ locale?: Locale + /** + * @deprecated use `renderInputElement` instead. If `renderInputElement` is provided, + * that will take precedence over `inputElement`. + */ inputElement?: React.ReactElement + /** + * If provided, the value will be used instead of the default `DatePickerInput` component. + * @returns + */ + renderInputElement?: () => React.ReactElement }