Skip to content

Commit 5865d96

Browse files
authored
Merge pull request #9 from JefteCaro/master
[Fix] Missing button type attributes. [Feature] Pop up position & additional props
2 parents 7da9a50 + 9a7b7fd commit 5865d96

File tree

5 files changed

+69
-14
lines changed

5 files changed

+69
-14
lines changed

src/components/Calendar/Days.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ const Days: React.FC<Props> = ({
190190
<div className="grid grid-cols-7 gap-y-0.5 my-1">
191191
{calendarData.days.previous.map((item, index) => (
192192
<button
193+
type="button"
193194
key={index}
194195
className="flex items-center justify-center text-gray-400 w-full h-12 lg:w-10 lg:h-10"
195196
onClick={() => onClickPreviousDays(item)}
@@ -203,6 +204,7 @@ const Days: React.FC<Props> = ({
203204

204205
{calendarData.days.current.map((item, index) => (
205206
<button
207+
type="button"
206208
key={index}
207209
className={buttonCass(item)}
208210
onClick={() => {
@@ -218,6 +220,7 @@ const Days: React.FC<Props> = ({
218220

219221
{calendarData.days.next.map((item, index) => (
220222
<button
223+
type="button"
221224
key={index}
222225
className="flex items-center justify-center text-gray-400 w-full h-12 lg:w-10 lg:h-10"
223226
onClick={() => {

src/components/Datepicker.tsx

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ interface Props {
4343
separator?: string;
4444
startFrom?: Date | null;
4545
i18n?: string;
46+
disabled?: boolean;
47+
inputClassName?: string | null;
48+
containerClassName?: string | null;
4649
}
4750

4851
const Datepicker: React.FC<Props> = ({
@@ -57,7 +60,10 @@ const Datepicker: React.FC<Props> = ({
5760
placeholder = null,
5861
separator = "~",
5962
startFrom = null,
60-
i18n = "en"
63+
i18n = "en",
64+
disabled = false,
65+
inputClassName = null,
66+
containerClassName = null
6167
}) => {
6268
// Ref
6369
const containerRef = useRef<HTMLDivElement>(null);
@@ -87,14 +93,23 @@ const Datepicker: React.FC<Props> = ({
8793
// Functions
8894
const hideDatepicker = useCallback(() => {
8995
const div = calendarContainerRef.current;
90-
if (div && div.classList.contains("block")) {
96+
const arrow = arrowRef.current;
97+
if (arrow && div && div.classList.contains("block")) {
9198
div.classList.remove("block");
9299
div.classList.remove("translate-y-0");
93100
div.classList.remove("opacity-1");
94101
div.classList.add("translate-y-4");
95102
div.classList.add("opacity-0");
96103
setTimeout(() => {
104+
div.classList.remove("bottom-full");
97105
div.classList.add("hidden");
106+
div.classList.add("mb-2.5");
107+
div.classList.add("mt-2.5");
108+
arrow.classList.remove("-bottom-2");
109+
arrow.classList.remove("border-r");
110+
arrow.classList.remove("border-b");
111+
arrow.classList.add("border-l");
112+
arrow.classList.add("border-t");
98113
}, 300);
99114
}
100115
}, []);
@@ -177,6 +192,7 @@ const Datepicker: React.FC<Props> = ({
177192
const detail = container.getBoundingClientRect();
178193
const screenCenter = window.innerWidth / 2;
179194
const containerCenter = (detail.right - detail.x) / 2 + detail.x;
195+
180196
if (containerCenter > screenCenter) {
181197
arrow.classList.add("right-0");
182198
arrow.classList.add("mr-3.5");
@@ -224,6 +240,7 @@ const Datepicker: React.FC<Props> = ({
224240
primaryColor: colorPrimary,
225241
configs,
226242
calendarContainer: calendarContainerRef,
243+
arrowContainer: arrowRef,
227244
hideDatepicker,
228245
period,
229246
changePeriod: (newPeriod: Period) => setPeriod(newPeriod),
@@ -237,7 +254,10 @@ const Datepicker: React.FC<Props> = ({
237254
placeholder,
238255
separator,
239256
i18n,
240-
value
257+
value,
258+
disabled,
259+
inputClassName,
260+
containerClassName
241261
};
242262
}, [
243263
asSingle,
@@ -253,12 +273,18 @@ const Datepicker: React.FC<Props> = ({
253273
placeholder,
254274
separator,
255275
showFooter,
256-
value
276+
value,
277+
disabled,
278+
inputClassName,
279+
containerClassName
257280
]);
258281

259282
return (
260283
<DatepickerContext.Provider value={contextValues}>
261-
<div className="relative w-full text-gray-700" ref={containerRef}>
284+
<div
285+
className={`relative w-full text-gray-700 ${containerClassName}`}
286+
ref={containerRef}
287+
>
262288
<Input />
263289

264290
<div
@@ -272,7 +298,7 @@ const Datepicker: React.FC<Props> = ({
272298
{showShortcuts && <Shortcuts />}
273299

274300
<div
275-
className={`flex items-stretch flex-col md:flex-row items-center space-y-4 md:space-y-0 md:space-x-1.5 ${
301+
className={`flex items-stretch flex-col md:flex-row space-y-4 md:space-y-0 md:space-x-1.5 ${
276302
showShortcuts ? "md:pl-2" : "md:pl-1"
277303
} pr-2 lg:pr-1`}
278304
>

src/components/Input.tsx

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@ const Input: React.FC = () => {
1515
dayHover,
1616
changeDayHover,
1717
calendarContainer,
18+
arrowContainer,
1819
inputText,
1920
changeInputText,
2021
hideDatepicker,
2122
changeDatepickerValue,
2223
asSingle,
2324
placeholder,
24-
separator
25+
separator,
26+
disabled,
27+
inputClassName
2528
} = useContext(DatepickerContext);
2629

2730
// UseRefs
@@ -33,8 +36,9 @@ const Input: React.FC = () => {
3336
const border = BORDER_COLOR.focus[primaryColor as keyof typeof BORDER_COLOR.focus];
3437
const ring =
3538
RING_COLOR["second-focus"][primaryColor as keyof typeof RING_COLOR["second-focus"]];
36-
return `relative transition-all duration-300 py-2.5 pl-4 pr-14 w-full border-gray-300 dark:bg-slate-800 dark:text-white/80 dark:border-slate-600 rounded-lg tracking-wide font-light text-sm placeholder-gray-400 bg-white focus:ring ${border} ${ring}`;
37-
}, [primaryColor]);
39+
const classNameOverload = typeof inputClassName === "string" ? inputClassName : "";
40+
return `relative transition-all duration-300 py-2.5 pl-4 pr-14 w-full border-gray-300 dark:bg-slate-800 dark:text-white/80 dark:border-slate-600 rounded-lg tracking-wide font-light text-sm placeholder-gray-400 bg-white focus:ring disabled:opacity-40 disabled:cursor-not-allowed ${border} ${ring} ${classNameOverload}`;
41+
}, [primaryColor, inputClassName]);
3842

3943
const handleInputChange = useCallback(
4044
(e: React.ChangeEvent<HTMLInputElement>) => {
@@ -118,11 +122,22 @@ const Input: React.FC = () => {
118122
useEffect(() => {
119123
const div = calendarContainer?.current;
120124
const input = inputRef.current;
125+
const arrow = arrowContainer?.current;
121126

122127
function showCalendarContainer() {
123-
if (div && div.classList.contains("hidden")) {
128+
if (arrow && div && div.classList.contains("hidden")) {
124129
div.classList.remove("hidden");
125130
div.classList.add("block");
131+
if (window.screen.height - 100 < div.getBoundingClientRect().bottom) {
132+
div.classList.add("bottom-full");
133+
div.classList.add("mb-2.5");
134+
div.classList.remove("mt-2.5");
135+
arrow.classList.add("-bottom-2");
136+
arrow.classList.add("border-r");
137+
arrow.classList.add("border-b");
138+
arrow.classList.remove("border-l");
139+
arrow.classList.remove("border-t");
140+
}
126141
setTimeout(() => {
127142
div.classList.remove("translate-y-4");
128143
div.classList.remove("opacity-0");
@@ -141,14 +156,15 @@ const Input: React.FC = () => {
141156
input.removeEventListener("focus", showCalendarContainer);
142157
}
143158
};
144-
}, [calendarContainer]);
159+
}, [calendarContainer, arrowContainer]);
145160

146161
return (
147162
<>
148163
<input
149164
ref={inputRef}
150165
type="text"
151166
className={getClassName()}
167+
disabled={disabled}
152168
placeholder={
153169
placeholder
154170
? placeholder
@@ -159,8 +175,10 @@ const Input: React.FC = () => {
159175
/>
160176

161177
<button
178+
type="button"
162179
ref={buttonRef}
163-
className="absolute right-0 h-full px-3 text-gray-400 focus:outline-none"
180+
disabled={disabled}
181+
className="absolute right-0 h-full px-3 text-gray-400 focus:outline-none disabled:opacity-40 disabled:cursor-not-allowed"
164182
>
165183
{inputText ? <CloseIcon className="h-5 w-5" /> : <DateIcon className="h-5 w-5" />}
166184
</button>

src/components/utils.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ export const RoundedButton: React.FC<Button> = ({
222222
}, [padding, primaryColor, roundedFull]);
223223

224224
return (
225-
<button className={getClassName()} onClick={onClick}>
225+
<button type="button" className={getClassName()} onClick={onClick}>
226226
{children}
227227
</button>
228228
);

src/contexts/DatepickerContext.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface DatepickerStore {
1313
primaryColor: string;
1414
configs?: Configs | null;
1515
calendarContainer: React.RefObject<HTMLDivElement> | null;
16+
arrowContainer: React.RefObject<HTMLDivElement> | null;
1617
hideDatepicker: () => void;
1718
period: Period;
1819
changePeriod: (period: Period) => void;
@@ -27,11 +28,15 @@ interface DatepickerStore {
2728
separator?: string;
2829
i18n: string;
2930
value: DateRange;
31+
disabled?: boolean;
32+
inputClassName?: string | null;
33+
containerClassName?: string | null;
3034
}
3135

3236
const DatepickerContext = createContext<DatepickerStore>({
3337
primaryColor: "blue",
3438
calendarContainer: null,
39+
arrowContainer: null,
3540
// eslint-disable-next-line @typescript-eslint/no-empty-function
3641
hideDatepicker: () => {},
3742
period: { start: null, end: null },
@@ -49,7 +54,10 @@ const DatepickerContext = createContext<DatepickerStore>({
4954
changeDatepickerValue: value => {},
5055
showFooter: false,
5156
value: null,
52-
i18n: "en"
57+
i18n: "en",
58+
disabled: false,
59+
inputClassName: "",
60+
containerClassName: ""
5361
});
5462

5563
export default DatepickerContext;

0 commit comments

Comments
 (0)