Skip to content

Commit

Permalink
DatePicker: Add today button in month and year mode (#2099)
Browse files Browse the repository at this point in the history
* add today button in month and year mode

* add tests for today button

* mionr refactoring

* lint fix

* lint fix
  • Loading branch information
farhanlatheef authored Feb 28, 2024
1 parent 2a4763c commit fe6547d
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 8 deletions.
44 changes: 41 additions & 3 deletions src/components/DatePicker.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { forwardRef } from "react";
import React, { forwardRef, useState } from "react";

import { DatePicker as AntDatePicker, ConfigProvider } from "antd";
import classnames from "classnames";
Expand Down Expand Up @@ -27,6 +27,18 @@ const IconOverride = ({ icon: Icon }) => (
</span>
);

const Today = ({ onClick }) => (
<div className="text-center">
<button
{...{ onClick }}
className="neeto-ui-rounded-md hover:neeto-ui-bg-gray-200 px-2 py-1 text-xs font-medium transition duration-300 ease-in-out"
data-cy="year-month-mode-today"
>
Today
</button>
</div>
);

const DatePicker = forwardRef(
(
{
Expand All @@ -40,6 +52,7 @@ const DatePicker = forwardRef(
onChange = noop,
onOk = noop,
picker = "date",
mode: inputMode = "date",
showTime = false,
type = "date",
nakedInput = false,
Expand All @@ -53,6 +66,7 @@ const DatePicker = forwardRef(
},
ref
) => {
const [mode, setMode] = useState(inputMode);
const id = useId(otherProps.id);
const datePickerRef = useSyncedRef(ref);

Expand All @@ -67,6 +81,21 @@ const DatePicker = forwardRef(
: onChange(date, dateString);
};

const renderExtraFooter = () => {
if (type === "range" || mode === "date") return null;

return (
<Today
onClick={() => {
setMode("date");
setTimeout(() => {
document.querySelector(".ant-picker-today-btn").click();
});
}}
/>
);
};

return (
<ConfigProvider
theme={{
Expand Down Expand Up @@ -125,7 +154,6 @@ const DatePicker = forwardRef(
<div className="neeto-ui-input__wrapper">
{label && <Label {...{ required, ...labelProps }}>{label}</Label>}
<Component
{...{ format, onOk, picker }}
data-cy={label ? `${hyphenize(label)}-input` : "picker-input"}
defaultValue={convertToDayjsObjects(defaultValue)}
ref={datePickerRef}
Expand All @@ -144,7 +172,17 @@ const DatePicker = forwardRef(
popupClassName,
])}
onChange={handleOnChange}
{...otherProps}
{...{
format,
onOk,
picker,
...otherProps,
...(type === "date" && {
mode,
renderExtraFooter,
onPanelChange: (_, mode) => setMode(mode),
}),
}}
nextIcon={<IconOverride icon={Right} />}
prevIcon={<IconOverride icon={Left} />}
suffixIcon={<Calendar size={16} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ const metadata = {
},
};

const DateInput = args => <DatePicker {...args} />;
const Default = args => <DatePicker {...args} />;

DateInput.storyName = "DatePicker";
DateInput.args = {
Default.storyName = "DatePicker";
Default.args = {
label: "Date",
type: "date",
picker: "date",
Expand Down Expand Up @@ -218,7 +218,7 @@ CSSCustomization.parameters = {
};

export {
DateInput,
Default,
RequiredDatePicker,
DatePickerWithRef,
DatePickerInModal,
Expand Down
24 changes: 23 additions & 1 deletion tests/DatePicker.test.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";

import { fireEvent, render, screen } from "@testing-library/react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import dayjs from "dayjs";

import DatePicker from "components/DatePicker";
Expand Down Expand Up @@ -117,4 +117,26 @@ describe("DatePicker", () => {
const asterisk = getByText("*");
expect(asterisk).toBeInTheDocument();
});

it("should show today button in month and year mode", () => {
const { getByText } = render(
<DatePicker open label="Input" mode="month" />
);
expect(getByText("Today")).toBeInTheDocument();
});

it("onChange should trigger with today date when today is clicked", async () => {
const onDateChange = jest.fn();
const { getByText } = render(
<DatePicker open label="Input" mode="month" onChange={onDateChange} />
);
fireEvent.click(getByText("Today"));
await waitFor(() => {
expect(onDateChange).toBeCalledWith(
expect.anything(),
// eslint-disable-next-line @bigbinary/neeto/use-standard-date-time-formats
dayjs().format("DD/MM/YYYY")
);
});
});
});

0 comments on commit fe6547d

Please sign in to comment.