Skip to content

Commit

Permalink
fix(date-picker): open and close datepicker after pressing selector b…
Browse files Browse the repository at this point in the history
…utton (#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
  • Loading branch information
wingkwong committed Jul 6, 2024
1 parent b4c046f commit a164c26
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 6 deletions.
6 changes: 6 additions & 0 deletions .changeset/sweet-parents-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@nextui-org/date-input": patch
"@nextui-org/date-picker": patch
---

Fixed date picker closing issue after pressing selector button (#3282)
11 changes: 8 additions & 3 deletions packages/components/date-input/src/use-date-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand All @@ -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. */
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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),
}),
};
};
Expand Down
22 changes: 22 additions & 0 deletions packages/components/date-picker/__tests__/date-picker.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
});
11 changes: 9 additions & 2 deletions packages/components/date-picker/src/use-date-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -101,6 +101,8 @@ export function useDatePicker<T extends DateValue>({
},
});

const popoverTriggerRef = useRef<HTMLDivElement>(null);

const baseStyles = clsx(classNames?.base, className);

const slots = useMemo(
Expand Down Expand Up @@ -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;
};
Expand Down Expand Up @@ -178,6 +183,7 @@ export function useDatePicker<T extends DateValue>({
state,
dialogProps,
...popoverProps,
triggerRef: popoverTriggerRef,
classNames: {
content: slots.popoverContent({
class: clsx(
Expand All @@ -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),
};
};

Expand All @@ -208,6 +214,7 @@ export function useDatePicker<T extends DateValue>({
return {
...buttonProps,
...selectorButtonProps,
onPress: state.toggle,
className: slots.selectorButton({class: classNames?.selectorButton}),
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down

0 comments on commit a164c26

Please sign in to comment.