Skip to content

Commit 927f058

Browse files
committed
Merge branch 'master' into parseCustomFormat
2 parents ea10120 + 5603305 commit 927f058

File tree

19 files changed

+521
-325
lines changed

19 files changed

+521
-325
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 Onesine
3+
Copyright (c) 2023 Onesine
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
- ✅ Date formatting
3535
- ✅ Disable specific dates
3636
- ✅ Minimum Date and Maximum Date
37-
- Custom shortcuts
37+
- Custom shortcuts
3838

3939
## Documentation
4040

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-tailwindcss-datepicker",
3-
"version": "1.4.2",
3+
"version": "1.6.0",
44
"description": "A modern React Datepicker using Tailwind CSS 3",
55
"main": "dist/index.cjs.js",
66
"module": "dist/index.esm.js",
@@ -40,10 +40,11 @@
4040
"react": "^17.0.2 || ^18.2.0"
4141
},
4242
"devDependencies": {
43-
"@rollup/plugin-commonjs": "^22.0.1",
44-
"@rollup/plugin-node-resolve": "^13.3.0",
45-
"@rollup/plugin-typescript": "^9.0.2",
43+
"@rollup/plugin-commonjs": "^24.0.1",
44+
"@rollup/plugin-node-resolve": "^15.0.1",
45+
"@rollup/plugin-typescript": "^11.0.0",
4646
"@tailwindcss/forms": "^0.5.3",
47+
"@types/node": "18.14.5",
4748
"@types/react": "^18.0.21",
4849
"@typescript-eslint/eslint-plugin": "^5.45.0",
4950
"@typescript-eslint/parser": "^5.45.0",

pages/index.js

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export default function Playground() {
1313
const [useRange, setUseRange] = useState(true);
1414
const [showFooter, setShowFooter] = useState(false);
1515
const [showShortcuts, setShowShortcuts] = useState(false);
16-
const [configs, setConfigs] = useState(null);
1716
const [asSingle, setAsSingle] = useState(false);
1817
const [placeholder, setPlaceholder] = useState("");
1918
const [separator, setSeparator] = useState("~");
@@ -34,6 +33,7 @@ export default function Playground() {
3433
const handleChange = (value, e) => {
3534
setValue(value);
3635
console.log(e);
36+
console.log("value", value);
3737
};
3838
return (
3939
<div className="px-4 py-8">
@@ -55,7 +55,40 @@ export default function Playground() {
5555
useRange={useRange}
5656
showFooter={showFooter}
5757
showShortcuts={showShortcuts}
58-
configs={configs}
58+
configs={{
59+
shortcuts: {
60+
today: "TText",
61+
yesterday: "YText",
62+
past: period => `P-${period} Text`,
63+
currentMonth: "CMText",
64+
pastMonth: "PMText",
65+
last3Days: {
66+
text: "Last 3 days",
67+
period: {
68+
start: new Date(new Date().setDate(new Date().getDate() - 3)),
69+
end: new Date()
70+
}
71+
},
72+
thisDay: {
73+
text: "This Day",
74+
period: {
75+
start: new Date(),
76+
end: new Date()
77+
}
78+
},
79+
next8Days: {
80+
text: "Next 8 days",
81+
period: {
82+
start: new Date(),
83+
end: new Date(new Date().setDate(new Date().getDate() + 8))
84+
}
85+
}
86+
},
87+
footer: {
88+
cancel: "CText",
89+
apply: "AText"
90+
}
91+
}}
5992
asSingle={asSingle}
6093
placeholder={placeholder}
6194
separator={separator}
@@ -76,6 +109,7 @@ export default function Playground() {
76109
toggleIcon={isEmpty => {
77110
return isEmpty ? "Select Date" : "Clear";
78111
}}
112+
popoverDirection={"down"}
79113
// classNames={{
80114
// input: ({ disabled, readOnly, className }) => {
81115
// if (disabled) {
@@ -92,7 +126,6 @@ export default function Playground() {
92126
// }}
93127
/>
94128
</div>
95-
96129
<div className="py-4 max-w-3xl mx-auto flex flex-row flex-wrap">
97130
<div className="w-full sm:w-1/3 pr-2 flex flex-row flex-wrap sm:flex-col">
98131
<div className="mb-2 w-1/2 sm:w-full">

rollup.config.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ module.exports = {
1212
file: packageJson.main,
1313
format: "cjs",
1414
exports: "auto",
15-
sourcemap: true
15+
sourcemap: true,
16+
inlineDynamicImports: true
1617
},
1718
{
1819
file: packageJson.module,
1920
format: "esm",
2021
exports: "auto",
21-
sourcemap: true
22+
sourcemap: true,
23+
inlineDynamicImports: true
2224
}
2325
],
2426
external: ["react", "dayjs"],

src/components/Calendar/Days.tsx

Lines changed: 108 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import React, { useCallback, useContext } from "react";
55
import { BG_COLOR, TEXT_COLOR } from "../../constants";
66
import DatepickerContext from "../../contexts/DatepickerContext";
77
import { formatDate, nextMonth, previousMonth, classNames as cn } from "../../helpers";
8+
import { Period } from "../../types";
89

910
dayjs.extend(isBetween);
1011

@@ -240,39 +241,127 @@ const Days: React.FC<Props> = ({
240241
[activeDateData, hoverClassByDay, isDateDisabled]
241242
);
242243

244+
const checkIfHoverPeriodContainsDisabledPeriod = useCallback(
245+
(hoverPeriod: Period) => {
246+
if (!Array.isArray(disabledDates)) {
247+
return false;
248+
}
249+
for (let i = 0; i < disabledDates.length; i++) {
250+
if (
251+
dayjs(hoverPeriod.start).isBefore(disabledDates[i].startDate) &&
252+
dayjs(hoverPeriod.end).isAfter(disabledDates[i].endDate)
253+
) {
254+
return true;
255+
}
256+
}
257+
return false;
258+
},
259+
[disabledDates]
260+
);
261+
262+
const getMetaData = useCallback(() => {
263+
return {
264+
previous: previousMonth(calendarData.date),
265+
current: calendarData.date,
266+
next: nextMonth(calendarData.date)
267+
};
268+
}, [calendarData.date]);
269+
243270
const hoverDay = useCallback(
244271
(day: number, type: string) => {
245-
const object = {
246-
previous: previousMonth(calendarData.date),
247-
current: calendarData.date,
248-
next: nextMonth(calendarData.date)
249-
};
272+
const object = getMetaData();
250273
const newDate = object[type as keyof typeof object];
251274
const newHover = `${newDate.year()}-${newDate.month() + 1}-${
252275
day >= 10 ? day : "0" + day
253276
}`;
254277

255278
if (period.start && !period.end) {
279+
const hoverPeriod = { ...period, end: newHover };
256280
if (dayjs(newHover).isBefore(dayjs(period.start))) {
257-
changePeriod({
258-
start: null,
259-
end: period.start
260-
});
281+
hoverPeriod.start = newHover;
282+
hoverPeriod.end = period.start;
283+
if (!checkIfHoverPeriodContainsDisabledPeriod(hoverPeriod)) {
284+
changePeriod({
285+
start: null,
286+
end: period.start
287+
});
288+
}
289+
}
290+
if (!checkIfHoverPeriodContainsDisabledPeriod(hoverPeriod)) {
291+
changeDayHover(newHover);
261292
}
262-
changeDayHover(newHover);
263293
}
264294

265295
if (!period.start && period.end) {
296+
const hoverPeriod = { ...period, start: newHover };
266297
if (dayjs(newHover).isAfter(dayjs(period.end))) {
267-
changePeriod({
268-
start: period.end,
269-
end: null
270-
});
298+
hoverPeriod.start = period.end;
299+
hoverPeriod.end = newHover;
300+
if (!checkIfHoverPeriodContainsDisabledPeriod(hoverPeriod)) {
301+
changePeriod({
302+
start: period.end,
303+
end: null
304+
});
305+
}
306+
}
307+
if (!checkIfHoverPeriodContainsDisabledPeriod(hoverPeriod)) {
308+
changeDayHover(newHover);
271309
}
272-
changeDayHover(newHover);
273310
}
274311
},
275-
[calendarData.date, changeDayHover, changePeriod, period.end, period.start]
312+
[
313+
changeDayHover,
314+
changePeriod,
315+
checkIfHoverPeriodContainsDisabledPeriod,
316+
getMetaData,
317+
period
318+
]
319+
);
320+
321+
const handleClickDay = useCallback(
322+
(day: number, type: "previous" | "current" | "next") => {
323+
function continueClick() {
324+
if (type === "previous") {
325+
onClickPreviousDays(day);
326+
}
327+
328+
if (type === "current") {
329+
onClickDay(day);
330+
}
331+
332+
if (type === "next") {
333+
onClickNextDays(day);
334+
}
335+
}
336+
337+
if (disabledDates?.length) {
338+
const object = getMetaData();
339+
const newDate = object[type as keyof typeof object];
340+
const clickDay = `${newDate.year()}-${newDate.month() + 1}-${
341+
day >= 10 ? day : "0" + day
342+
}`;
343+
344+
if (period.start && !period.end) {
345+
dayjs(clickDay).isSame(dayHover) && continueClick();
346+
} else if (!period.start && period.end) {
347+
dayjs(clickDay).isSame(dayHover) && continueClick();
348+
} else {
349+
continueClick();
350+
}
351+
} else {
352+
continueClick();
353+
}
354+
},
355+
[
356+
dayHover,
357+
disabledDates?.length,
358+
getMetaData,
359+
onClickDay,
360+
onClickNextDays,
361+
onClickPreviousDays,
362+
period.end,
363+
period.start
364+
]
276365
);
277366

278367
return (
@@ -283,7 +372,7 @@ const Days: React.FC<Props> = ({
283372
key={index}
284373
disabled={isDateDisabled(item, "previous")}
285374
className="flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10"
286-
onClick={() => onClickPreviousDays(item)}
375+
onClick={() => handleClickDay(item, "previous")}
287376
onMouseOver={() => {
288377
hoverDay(item, "previous");
289378
}}
@@ -298,9 +387,7 @@ const Days: React.FC<Props> = ({
298387
key={index}
299388
disabled={isDateDisabled(item, "current")}
300389
className={`${buttonClass(item, "current")}`}
301-
onClick={() => {
302-
onClickDay(item);
303-
}}
390+
onClick={() => handleClickDay(item, "current")}
304391
onMouseOver={() => {
305392
hoverDay(item, "current");
306393
}}
@@ -315,9 +402,7 @@ const Days: React.FC<Props> = ({
315402
key={index}
316403
disabled={isDateDisabled(index, "next")}
317404
className="flex items-center justify-center text-gray-400 h-12 w-12 lg:w-10 lg:h-10"
318-
onClick={() => {
319-
onClickNextDays(item);
320-
}}
405+
onClick={() => handleClickDay(item, "next")}
321406
onMouseOver={() => {
322407
hoverDay(item, "next");
323408
}}

src/components/Calendar/Months.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import dayjs from "dayjs";
22
import React, { useContext } from "react";
33

4+
import { MONTHS } from "../../constants";
45
import DatepickerContext from "../../contexts/DatepickerContext";
56
import { loadLanguageModule } from "../../helpers";
67
import { RoundedButton } from "../utils";
@@ -14,19 +15,15 @@ const Months: React.FC<Props> = ({ clickMonth }) => {
1415
loadLanguageModule(i18n);
1516
return (
1617
<div className="w-full grid grid-cols-2 gap-2 mt-2">
17-
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((item, index) => (
18+
{MONTHS.map(item => (
1819
<RoundedButton
19-
key={index}
20+
key={item}
2021
padding="py-3"
2122
onClick={() => {
22-
clickMonth(index + 1);
23+
clickMonth(item);
2324
}}
2425
>
25-
<>
26-
{dayjs(`2022-${1 + item}-01`)
27-
.locale(i18n)
28-
.format("MMM")}
29-
</>
26+
<>{dayjs(`2022-${item}-01`).locale(i18n).format("MMM")}</>
3027
</RoundedButton>
3128
))}
3229
</div>

0 commit comments

Comments
 (0)