Skip to content

Commit 2f775fc

Browse files
committed
Update popover direction & refactoring
1 parent 74c2d11 commit 2f775fc

File tree

5 files changed

+61
-64
lines changed

5 files changed

+61
-64
lines changed

pages/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ export default function Playground() {
126126
// }}
127127
/>
128128
</div>
129-
130129
<div className="py-4 max-w-3xl mx-auto flex flex-row flex-wrap">
131130
<div className="w-full sm:w-1/3 pr-2 flex flex-row flex-wrap sm:flex-col">
132131
<div className="mb-2 w-1/2 sm:w-full">

src/components/Datepicker.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,14 +303,14 @@ const Datepicker: React.FC<DatepickerType> = ({
303303
popoverDirection
304304
]);
305305

306-
const defaultContainerClassName = "relative w-full text-gray-700";
307-
308-
const containerClassNameOverload =
309-
typeof containerClassName === "function"
306+
const containerClassNameOverload = useMemo(() => {
307+
const defaultContainerClassName = "relative w-full text-gray-700";
308+
return typeof containerClassName === "function"
310309
? containerClassName(defaultContainerClassName)
311310
: typeof containerClassName === "string" && containerClassName !== ""
312311
? containerClassName
313312
: defaultContainerClassName;
313+
}, [containerClassName]);
314314

315315
return (
316316
<DatepickerContext.Provider value={contextValues}>

src/components/Input.tsx

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React, { useCallback, useContext, useEffect, useRef } from "react";
44
import { BORDER_COLOR, DATE_FORMAT, RING_COLOR } from "../constants";
55
import DatepickerContext from "../contexts/DatepickerContext";
66
import { dateIsValid } from "../helpers";
7+
import { PopoverDirectionType } from "../types";
78

89
import ToggleButton from "./ToggleButton";
910

@@ -43,12 +44,6 @@ const Input: React.FC<Props> = (e: Props) => {
4344
const buttonRef = useRef<HTMLButtonElement>(null);
4445
const inputRef = useRef<HTMLInputElement>(null);
4546

46-
useEffect(() => {
47-
if (inputRef && e.setContextRef && typeof e.setContextRef === "function") {
48-
e.setContextRef(inputRef);
49-
}
50-
}, [e, inputRef]);
51-
5247
// Functions
5348
const getClassName = useCallback(() => {
5449
const input = inputRef.current;
@@ -108,7 +103,45 @@ const Input: React.FC<Props> = (e: Props) => {
108103
[changeDatepickerValue, changeDayHover, changeInputText, hideDatepicker]
109104
);
110105

106+
const renderToggleIcon = useCallback(
107+
(isEmpty: boolean) => {
108+
return typeof toggleIcon === "undefined" ? (
109+
<ToggleButton isEmpty={isEmpty} />
110+
) : (
111+
toggleIcon(isEmpty)
112+
);
113+
},
114+
[toggleIcon]
115+
);
116+
117+
const getToggleClassName = useCallback(() => {
118+
const button = buttonRef.current;
119+
120+
if (
121+
button &&
122+
typeof classNames !== "undefined" &&
123+
typeof classNames?.toggleButton === "function"
124+
) {
125+
return classNames.toggleButton(button);
126+
}
127+
128+
const defaultToggleClassName =
129+
"absolute right-0 h-full px-3 text-gray-400 focus:outline-none disabled:opacity-40 disabled:cursor-not-allowed";
130+
131+
return typeof toggleClassName === "function"
132+
? toggleClassName(defaultToggleClassName)
133+
: typeof toggleClassName === "string" && toggleClassName !== ""
134+
? toggleClassName
135+
: defaultToggleClassName;
136+
}, [toggleClassName, buttonRef, classNames]);
137+
111138
// UseEffects && UseLayoutEffect
139+
useEffect(() => {
140+
if (inputRef && e.setContextRef && typeof e.setContextRef === "function") {
141+
e.setContextRef(inputRef);
142+
}
143+
}, [e, inputRef]);
144+
112145
useEffect(() => {
113146
const button = buttonRef?.current;
114147

@@ -163,20 +196,18 @@ const Input: React.FC<Props> = (e: Props) => {
163196
const arrow = arrowContainer?.current;
164197

165198
function showCalendarContainer() {
166-
function setContainerPosition(
167-
direction: string | undefined,
168-
div: HTMLDivElement,
169-
arrow: HTMLDivElement
170-
) {
171-
if (direction === "down") {
172-
return;
173-
}
199+
if (arrow && div && div.classList.contains("hidden")) {
200+
div.classList.remove("hidden");
201+
div.classList.add("block");
174202

175203
// window.innerWidth === 767
204+
const popoverOnUp = popoverDirection == PopoverDirectionType.up;
205+
const popoverOnDown = popoverDirection === PopoverDirectionType.down;
176206
if (
177-
direction === "up" ||
207+
popoverOnUp ||
178208
(window.innerWidth > 767 &&
179-
window.screen.height - 100 < div.getBoundingClientRect().bottom)
209+
window.screen.height - 100 < div.getBoundingClientRect().bottom &&
210+
!popoverOnDown)
180211
) {
181212
div.classList.add("bottom-full");
182213
div.classList.add("mb-2.5");
@@ -187,13 +218,6 @@ const Input: React.FC<Props> = (e: Props) => {
187218
arrow.classList.remove("border-l");
188219
arrow.classList.remove("border-t");
189220
}
190-
}
191-
192-
if (arrow && div && div.classList.contains("hidden")) {
193-
div.classList.remove("hidden");
194-
div.classList.add("block");
195-
196-
setContainerPosition(popoverDirection, div, arrow);
197221

198222
setTimeout(() => {
199223
div.classList.remove("translate-y-4");
@@ -215,38 +239,6 @@ const Input: React.FC<Props> = (e: Props) => {
215239
};
216240
}, [calendarContainer, arrowContainer, popoverDirection]);
217241

218-
const renderToggleIcon = useCallback(
219-
(isEmpty: boolean) => {
220-
return typeof toggleIcon === "undefined" ? (
221-
<ToggleButton isEmpty={isEmpty} />
222-
) : (
223-
toggleIcon(isEmpty)
224-
);
225-
},
226-
[toggleIcon]
227-
);
228-
229-
const getToggleClassName = useCallback(() => {
230-
const button = buttonRef.current;
231-
232-
if (
233-
button &&
234-
typeof classNames !== "undefined" &&
235-
typeof classNames?.toggleButton === "function"
236-
) {
237-
return classNames.toggleButton(button);
238-
}
239-
240-
const defaultToggleClassName =
241-
"absolute right-0 h-full px-3 text-gray-400 focus:outline-none disabled:opacity-40 disabled:cursor-not-allowed";
242-
243-
return typeof toggleClassName === "function"
244-
? toggleClassName(defaultToggleClassName)
245-
: typeof toggleClassName === "string" && toggleClassName !== ""
246-
? toggleClassName
247-
: defaultToggleClassName;
248-
}, [toggleClassName, buttonRef, classNames]);
249-
250242
return (
251243
<>
252244
<input
@@ -274,7 +266,7 @@ const Input: React.FC<Props> = (e: Props) => {
274266
disabled={disabled}
275267
className={getToggleClassName()}
276268
>
277-
{renderToggleIcon(inputText == null || (inputText != null && !inputText.length))}
269+
{renderToggleIcon(inputText == null || !inputText?.length)}
278270
</button>
279271
</>
280272
);

src/contexts/DatepickerContext.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
DateValueType,
99
DateType,
1010
DateRangeType,
11-
ClassNamesTypeProp
11+
ClassNamesTypeProp,
12+
PopoverDirectionType
1213
} from "../types";
1314

1415
interface DatepickerStore {
@@ -46,7 +47,7 @@ interface DatepickerStore {
4647
inputId?: string;
4748
inputName?: string;
4849
classNames?: ClassNamesTypeProp;
49-
popoverDirection?: string;
50+
popoverDirection?: PopoverDirectionType;
5051
}
5152

5253
const DatepickerContext = createContext<DatepickerStore>({

src/types/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ export type ClassNamesTypeProp = {
4444
footer?: (p?: object | null | undefined) => string | undefined;
4545
};
4646

47+
export enum PopoverDirectionType {
48+
up = "up",
49+
down = "down"
50+
}
51+
4752
export interface DatepickerType {
4853
primaryColor?: string;
4954
value: DateValueType;
@@ -71,5 +76,5 @@ export interface DatepickerType {
7176
maxDate?: DateType | null;
7277
disabledDates?: DateRangeType[] | null;
7378
startWeekOn?: string | null;
74-
popoverDirection?: string | undefined;
79+
popoverDirection?: PopoverDirectionType;
7580
}

0 commit comments

Comments
 (0)