Skip to content

Commit f90fb02

Browse files
committed
[React 19] Support for react 19 and refactoring
1 parent 5edf54e commit f90fb02

File tree

8 files changed

+64
-79
lines changed

8 files changed

+64
-79
lines changed

src/components/Calendar/index.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,12 @@ const Calendar = (props: Props) => {
101101
let newEnd = null;
102102

103103
function chosePeriod(start: Date, end: Date) {
104-
const ipt = input?.current;
105-
106104
changeDatepickerValue(
107105
{
108106
startDate: start,
109107
endDate: end
110108
},
111-
ipt
109+
input
112110
);
113111

114112
hideDatepicker();

src/components/Datepicker.tsx

+28-27
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
1+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
22

33
import Calendar from "../components/Calendar";
44
import Footer from "../components/Footer";
@@ -93,10 +93,10 @@ const Datepicker = (props: DatepickerType) => {
9393
});
9494
const [dayHover, setDayHover] = useState<DateType>(null);
9595
const [inputText, setInputText] = useState<string>("");
96-
const [inputRef, setInputRef] = useState(createRef<HTMLInputElement>());
96+
const [input, setInput] = useState<HTMLInputElement | null>(null);
9797

9898
// Custom Hooks use
99-
useOnClickOutside(containerRef, () => {
99+
useOnClickOutside(containerRef.current, () => {
100100
const container = containerRef.current;
101101
if (container) {
102102
hideDatepicker();
@@ -313,7 +313,8 @@ const Datepicker = (props: DatepickerType) => {
313313
displayFormat,
314314
hideDatepicker,
315315
i18n: i18n && i18n.length > 0 ? i18n : LANGUAGE,
316-
input: inputRef,
316+
input,
317+
setInput: (value: HTMLInputElement | null) => setInput(value),
317318
inputClassName,
318319
inputId,
319320
inputName,
@@ -336,37 +337,37 @@ const Datepicker = (props: DatepickerType) => {
336337
value
337338
};
338339
}, [
340+
minDate,
341+
maxDate,
342+
i18n,
339343
asSingle,
340-
safePrimaryColor,
341-
configs,
342-
hideDatepicker,
343-
period,
344-
dayHover,
345-
inputText,
346344
onChange,
347-
showFooter,
348-
placeholder,
349-
separator,
350-
i18n,
351-
value,
352-
disabled,
353-
inputClassName,
345+
classNames,
346+
configs,
354347
containerClassName,
355-
toggleClassName,
356-
toggleIcon,
357-
readOnly,
358-
displayFormat,
359-
minDate,
360-
maxDate,
361348
dateLooking,
349+
dayHover,
350+
disabled,
362351
disabledDates,
352+
displayFormat,
353+
hideDatepicker,
354+
input,
355+
inputClassName,
363356
inputId,
364357
inputName,
365-
startWeekOn,
366-
classNames,
367-
inputRef,
358+
inputText,
359+
period,
360+
placeholder,
368361
popoverDirection,
362+
safePrimaryColor,
363+
readOnly,
369364
required,
365+
separator,
366+
showFooter,
367+
startWeekOn,
368+
toggleClassName,
369+
toggleIcon,
370+
value,
370371
firstGotoDate
371372
]);
372373

@@ -392,7 +393,7 @@ const Datepicker = (props: DatepickerType) => {
392393
return (
393394
<DatepickerContext.Provider value={contextValues}>
394395
<div className={containerClassNameOverload} ref={containerRef}>
395-
<Input setContextRef={setInputRef} />
396+
<Input />
396397

397398
<div className={popupClassNameOverload} ref={calendarContainerRef}>
398399
<Arrow ref={arrowRef} />

src/components/Footer.tsx

+8-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import SecondaryButton from "./SecondaryButton";
77

88
const Footer = () => {
99
// Contexts
10-
const { hideDatepicker, period, changeDatepickerValue, configs, classNames } =
10+
const { hideDatepicker, period, changeDatepickerValue, configs, classNames, input } =
1111
useContext(DatepickerContext);
1212

1313
// Functions
@@ -33,10 +33,13 @@ const Footer = () => {
3333
<PrimaryButton
3434
onClick={() => {
3535
if (period.start && period.end) {
36-
changeDatepickerValue({
37-
startDate: period.start,
38-
endDate: period.end
39-
});
36+
changeDatepickerValue(
37+
{
38+
startDate: period.start,
39+
endDate: period.end
40+
},
41+
input
42+
);
4043
hideDatepicker();
4144
}
4245
}}

src/components/Input.tsx

+8-19
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
1-
import {
2-
ChangeEvent,
3-
KeyboardEvent,
4-
RefObject,
5-
useCallback,
6-
useContext,
7-
useEffect,
8-
useRef
9-
} from "react";
1+
import { ChangeEvent, KeyboardEvent, useCallback, useContext, useEffect, useRef } from "react";
102

113
import { BORDER_COLOR, RING_COLOR } from "../constants";
124
import DatepickerContext from "../contexts/DatepickerContext";
@@ -15,11 +7,7 @@ import { DateType } from "../types";
157

168
import ToggleButton from "./ToggleButton";
179

18-
type Props = {
19-
setContextRef?: (ref: RefObject<HTMLInputElement>) => void;
20-
};
21-
22-
const Input = (e: Props) => {
10+
const Input = () => {
2311
// Context
2412
const {
2513
primaryColor,
@@ -45,7 +33,9 @@ const Input = (e: Props) => {
4533
inputName,
4634
classNames,
4735
popoverDirection,
48-
required
36+
required,
37+
input,
38+
setInput
4939
} = useContext(DatepickerContext);
5040

5141
// UseRefs
@@ -80,7 +70,6 @@ const Input = (e: Props) => {
8070
const dates: Date[] = [];
8171

8272
if (asSingle) {
83-
// const date = parseFormattedDate(inputValue, displayFormat);
8473
const date = dateStringToDate(inputValue);
8574
if (date) {
8675
dates.push(date);
@@ -175,10 +164,10 @@ const Input = (e: Props) => {
175164

176165
// UseEffects && UseLayoutEffect
177166
useEffect(() => {
178-
if (inputRef && e.setContextRef && typeof e.setContextRef === "function") {
179-
e.setContextRef(inputRef);
167+
if (!input && inputRef?.current) {
168+
setInput(inputRef.current);
180169
}
181-
}, [e, inputRef]);
170+
}, [input, inputRef, setInput]);
182171

183172
useEffect(() => {
184173
const button = buttonRef?.current;

src/components/Shortcuts.tsx

+10-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const ItemTemplate = memo((props: ItemTemplateProps) => {
2121
dayHover,
2222
changeDayHover,
2323
hideDatepicker,
24-
changeDatepickerValue
24+
changeDatepickerValue,
25+
input
2526
} = useContext(DatepickerContext);
2627

2728
// Functions
@@ -43,10 +44,13 @@ const ItemTemplate = memo((props: ItemTemplateProps) => {
4344
});
4445
}
4546
changePeriod(item);
46-
changeDatepickerValue({
47-
startDate: item.start,
48-
endDate: item.end
49-
});
47+
changeDatepickerValue(
48+
{
49+
startDate: item.start,
50+
endDate: item.end
51+
},
52+
input
53+
);
5054

5155
if (item.start) updateFirstDate(item.start);
5256
hideDatepicker();
@@ -57,6 +61,7 @@ const ItemTemplate = memo((props: ItemTemplateProps) => {
5761
changePeriod,
5862
dayHover,
5963
hideDatepicker,
64+
input,
6065
period.end,
6166
period.start,
6267
updateFirstDate

src/contexts/DatepickerContext.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ import {
2222
} from "../types";
2323

2424
interface DatepickerStore {
25-
arrowContainer: RefObject<HTMLDivElement> | null;
25+
arrowContainer: RefObject<HTMLDivElement | null> | null;
2626
asSingle?: boolean;
2727

28-
calendarContainer: RefObject<HTMLDivElement> | null;
29-
changeDatepickerValue: (value: DateValueType, e?: HTMLInputElement | null | undefined) => void;
28+
calendarContainer: RefObject<HTMLDivElement | null> | null;
29+
changeDatepickerValue: (value: DateValueType, e?: HTMLInputElement | null) => void;
3030
changeDayHover: (day: DateType) => void;
3131
changeInputText: (text: string) => void;
3232
changePeriod: (period: Period) => void;
@@ -43,7 +43,7 @@ interface DatepickerStore {
4343
hideDatepicker: () => void;
4444

4545
i18n: string;
46-
input?: RefObject<HTMLInputElement>;
46+
input?: HTMLInputElement | null;
4747
inputClassName?: ((className: string) => string) | string | null;
4848
inputId?: string;
4949
inputName?: string;
@@ -63,6 +63,7 @@ interface DatepickerStore {
6363

6464
showFooter?: boolean;
6565
startWeekOn?: WeekStringType | null;
66+
setInput: (value: HTMLInputElement | null) => void;
6667

6768
toggleClassName?: ((className: string) => string) | string | null;
6869
toggleIcon?: (open: boolean) => ReactNode;
@@ -115,6 +116,7 @@ const DatepickerContext = createContext<DatepickerStore>({
115116
separator: DEFAULT_SEPARATOR,
116117
showFooter: false,
117118
startWeekOn: START_WEEK,
119+
setInput: () => {},
118120

119121
toggleClassName: "",
120122
toggleIcon: undefined,

src/hooks/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { RefObject, useEffect } from "react";
1+
import { useEffect } from "react";
22

33
export default function useOnClickOutside(
4-
ref: RefObject<HTMLDivElement>,
4+
ref: HTMLDivElement | null,
55
handler: (e?: MouseEvent | TouchEvent) => void
66
) {
77
useEffect(() => {
88
const listener = (event: MouseEvent | TouchEvent) => {
9-
if (!ref.current || ref.current.contains(event.target as Node)) {
9+
if (!ref || ref.contains(event.target as Node)) {
1010
return;
1111
}
1212

src/index.tsx

-13
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
import Datepicker from "./components/Datepicker";
22

3-
/*export type {
4-
ClassNamesTypeProp,
5-
Configs,
6-
ClassNameType,
7-
DateLookingType,
8-
DateRangeType,
9-
DateType,
10-
DateValueType,
11-
PopoverDirectionType,
12-
ColorKeys,
13-
WeekStringType
14-
} from "./types";*/
15-
163
// eslint-disable-next-line react-refresh/only-export-components
174
export * from "./types";
185
export default Datepicker;

0 commit comments

Comments
 (0)