mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
fix(date-picker): open and close datepicker after pressing selector button (#3283)
* fix(date-picker): use trigger ref instead * fix(date-input): add innerWrapperProps * fix(date-picker): include popoverTriggerRef and add onPress to selector * feat(date-picker): add test * feat(changeset): add changeset * refactor(date-input): merge innerWrapperPropsProp & props and add cn
This commit is contained in:
parent
b4c046fe8b
commit
a164c26e96
6
.changeset/sweet-parents-chew.md
Normal file
6
.changeset/sweet-parents-chew.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"@nextui-org/date-input": patch
|
||||
"@nextui-org/date-picker": patch
|
||||
---
|
||||
|
||||
Fixed date picker closing issue after pressing selector button (#3282)
|
||||
@ -15,7 +15,7 @@ import {useDOMRef} from "@nextui-org/react-utils";
|
||||
import {useDateField as useAriaDateField} from "@react-aria/datepicker";
|
||||
import {useDateFieldState} from "@react-stately/datepicker";
|
||||
import {objectToDeps, clsx, dataAttr, getGregorianYearOffset} from "@nextui-org/shared-utils";
|
||||
import {dateInput} from "@nextui-org/theme";
|
||||
import {dateInput, cn} from "@nextui-org/theme";
|
||||
import {useMemo} from "react";
|
||||
|
||||
type NextUIBaseProps<T extends DateValue> = Omit<
|
||||
@ -34,6 +34,8 @@ interface Props<T extends DateValue> extends NextUIBaseProps<T> {
|
||||
labelProps?: DOMAttributes;
|
||||
/** Props for the date field. */
|
||||
fieldProps?: DOMAttributes;
|
||||
/** Props for the inner wrapper. */
|
||||
innerWrapperProps?: DOMAttributes;
|
||||
/** Props for the description element, if any. */
|
||||
descriptionProps?: DOMAttributes;
|
||||
/** Props for the error message element, if any. */
|
||||
@ -138,6 +140,7 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
|
||||
groupProps = {},
|
||||
labelProps: labelPropsProp,
|
||||
fieldProps: fieldPropsProp,
|
||||
innerWrapperProps: innerWrapperPropsProp,
|
||||
errorMessageProps: errorMessagePropsProp,
|
||||
descriptionProps: descriptionPropsProp,
|
||||
validationBehavior = globalContext?.validationBehavior ?? "aria",
|
||||
@ -251,11 +254,13 @@ export function useDateInput<T extends DateValue>(originalProps: UseDateInputPro
|
||||
};
|
||||
|
||||
const getInnerWrapperProps: PropGetter = (props) => {
|
||||
const innerWrapperProps = mergeProps(innerWrapperPropsProp, props);
|
||||
|
||||
return {
|
||||
...props,
|
||||
...innerWrapperProps,
|
||||
"data-slot": "inner-wrapper",
|
||||
className: slots.innerWrapper({
|
||||
class: classNames?.innerWrapper,
|
||||
class: cn(classNames?.innerWrapper, innerWrapperProps?.className),
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
@ -675,5 +675,27 @@ describe("DatePicker", () => {
|
||||
expect(month).toHaveAttribute("data-value", "6");
|
||||
expect(year).toHaveAttribute("data-value", "2567");
|
||||
});
|
||||
|
||||
it("should open and close popover after clicking selector button", () => {
|
||||
const {getByRole} = render(<DatePicker data-testid="datepicker" label="Date" />);
|
||||
|
||||
const selectorButton = getByRole("button");
|
||||
|
||||
expect(selectorButton).not.toBeNull();
|
||||
|
||||
// open the datepicker dialog by clicking selector button
|
||||
triggerPress(selectorButton);
|
||||
|
||||
let dialog = getByRole("dialog");
|
||||
|
||||
// assert that the datepicker dialog is open
|
||||
expect(dialog).toBeVisible();
|
||||
|
||||
// click the selector button again
|
||||
triggerPress(selectorButton);
|
||||
|
||||
// assert that the datepicker dialog is closed
|
||||
expect(dialog).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -9,7 +9,7 @@ import type {DOMAttributes} from "@nextui-org/system";
|
||||
import type {DatePickerSlots, SlotsToClasses} from "@nextui-org/theme";
|
||||
|
||||
import {useProviderContext} from "@nextui-org/system";
|
||||
import {useMemo} from "react";
|
||||
import {useMemo, useRef} from "react";
|
||||
import {datePicker} from "@nextui-org/theme";
|
||||
import {useDatePickerState} from "@react-stately/datepicker";
|
||||
import {AriaDatePickerProps, useDatePicker as useAriaDatePicker} from "@react-aria/datepicker";
|
||||
@ -101,6 +101,8 @@ export function useDatePicker<T extends DateValue>({
|
||||
},
|
||||
});
|
||||
|
||||
const popoverTriggerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const baseStyles = clsx(classNames?.base, className);
|
||||
|
||||
const slots = useMemo(
|
||||
@ -148,6 +150,9 @@ export function useDatePicker<T extends DateValue>({
|
||||
disableAnimation,
|
||||
}),
|
||||
className: slots.base({class: baseStyles}),
|
||||
innerWrapperProps: {
|
||||
ref: popoverTriggerRef,
|
||||
},
|
||||
"data-open": dataAttr(state.isOpen),
|
||||
} as DateInputProps;
|
||||
};
|
||||
@ -178,6 +183,7 @@ export function useDatePicker<T extends DateValue>({
|
||||
state,
|
||||
dialogProps,
|
||||
...popoverProps,
|
||||
triggerRef: popoverTriggerRef,
|
||||
classNames: {
|
||||
content: slots.popoverContent({
|
||||
class: clsx(
|
||||
@ -189,7 +195,7 @@ export function useDatePicker<T extends DateValue>({
|
||||
},
|
||||
shouldCloseOnInteractOutside: popoverProps?.shouldCloseOnInteractOutside
|
||||
? popoverProps.shouldCloseOnInteractOutside
|
||||
: (element: Element) => ariaShouldCloseOnInteractOutside(element, domRef, state),
|
||||
: (element: Element) => ariaShouldCloseOnInteractOutside(element, popoverTriggerRef, state),
|
||||
};
|
||||
};
|
||||
|
||||
@ -208,6 +214,7 @@ export function useDatePicker<T extends DateValue>({
|
||||
return {
|
||||
...buttonProps,
|
||||
...selectorButtonProps,
|
||||
onPress: state.toggle,
|
||||
className: slots.selectorButton({class: classNames?.selectorButton}),
|
||||
};
|
||||
};
|
||||
|
||||
@ -218,7 +218,7 @@ export function useDateRangePicker<T extends DateValue>({
|
||||
},
|
||||
shouldCloseOnInteractOutside: popoverProps?.shouldCloseOnInteractOutside
|
||||
? popoverProps.shouldCloseOnInteractOutside
|
||||
: (element: Element) => ariaShouldCloseOnInteractOutside(element, domRef, state),
|
||||
: (element: Element) => ariaShouldCloseOnInteractOutside(element, popoverTriggerRef, state),
|
||||
} as PopoverProps;
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user