Compare commits

...

12 Commits

Author SHA1 Message Date
Raunak Bhagat
7ec8f0c766 Memoize years array in InputDatePicker to prevent infinite re-renders
- Use useMemo to cache the years array between renders
- Prevents recreating the array on every render which was causing infinite loops
- Dependencies: currYear and validStartYear
2025-12-25 01:47:42 -07:00
Raunak Bhagat
066220ef39 Fix controlled vs uncontrolled detection in InputDatePicker
- Component is now controlled only when setSelectedDate callback is provided
- Prevents infinite loop when selectedDate prop changes without callback
- Initialize internal state with selectedDateProp for better default handling
2025-12-25 01:44:48 -07:00
Raunak Bhagat
6b14872ed1 Fix InputDatePicker to support uncontrolled mode
- Make selectedDate prop optional
- Add internal state management when setSelectedDate is not provided
- Use handleDateChange to update both internal state and call callback
- Prevents infinite loop when component is used without callback
2025-12-25 01:43:31 -07:00
Raunak Bhagat
163e12548b Make setSelectedDate optional in InputDatePicker 2025-12-25 01:33:05 -07:00
Raunak Bhagat
aeb7b78c32 Merge branch 'main' into feat/input-date-picker 2025-12-25 01:32:31 -07:00
Raunak Bhagat
450b675b37 Update stylings 2025-12-24 23:20:37 -07:00
Raunak Bhagat
ba8a55a91e Move Calendar component to refresh-components 2025-12-24 20:54:14 -07:00
Raunak Bhagat
3140843d60 Update calendar + date-picker component 2025-12-24 20:51:51 -07:00
Raunak Bhagat
93773f28dd Update usage of calendar 2025-12-24 09:54:07 -07:00
Raunak Bhagat
f54556a85b Update calendar 2025-12-24 09:54:04 -07:00
Raunak Bhagat
ae44317220 Edit trigger button style 2025-12-24 09:54:00 -07:00
Raunak Bhagat
bf95dd066b Add new input-date-picker component 2025-12-24 09:53:57 -07:00

View File

@@ -1,3 +1,5 @@
"use client";
import Button from "@/refresh-components/buttons/Button";
import Calendar from "@/refresh-components/Calendar";
import {
@@ -6,12 +8,12 @@ import {
PopoverTrigger,
} from "@/components/ui/popover";
import InputSelect from "@/refresh-components/inputs/InputSelect";
import { useState } from "react";
import { useState, useMemo } from "react";
import { SvgCalendar } from "@opal/icons";
export interface InputDatePickerProps {
selectedDate: Date | null;
setSelectedDate: (date: Date | null) => void;
selectedDate?: Date | null;
setSelectedDate?: (date: Date | null) => void;
startYear?: number;
disabled?: boolean;
}
@@ -21,20 +23,39 @@ function extractYear(date: Date | null): number {
}
export default function InputDatePicker({
selectedDate,
selectedDate: selectedDateProp,
setSelectedDate,
startYear = 1970,
disabled = false,
}: InputDatePickerProps) {
const validStartYear = Math.max(startYear, 1970);
const currYear = extractYear(new Date());
const years = Array(currYear - validStartYear + 1)
.fill(currYear)
.map((currYear, index) => currYear - index);
const [open, setOpen] = useState(false);
const [displayedMonth, setDisplayedMonth] = useState<Date>(
selectedDate ?? new Date()
const years = useMemo(
() =>
Array(currYear - validStartYear + 1)
.fill(currYear)
.map((currYear, index) => currYear - index),
[currYear, validStartYear]
);
const [open, setOpen] = useState(false);
const [internalDate, setInternalDate] = useState<Date | null>(
selectedDateProp ?? null
);
const [displayedMonth, setDisplayedMonth] = useState<Date>(
selectedDateProp ?? new Date()
);
// Component is controlled only if setSelectedDate is provided
const isControlled = setSelectedDate !== undefined;
const selectedDate = isControlled ? selectedDateProp ?? null : internalDate;
const handleDateChange = (date: Date | null) => {
if (isControlled) {
setSelectedDate(date);
} else {
setInternalDate(date);
}
};
return (
<Popover open={open} onOpenChange={setOpen}>
@@ -64,7 +85,7 @@ export default function InputDatePicker({
<Button
onClick={() => {
const now = new Date();
setSelectedDate(now);
handleDateChange(now);
setDisplayedMonth(now);
}}
>
@@ -76,7 +97,7 @@ export default function InputDatePicker({
selected={selectedDate ?? undefined}
onSelect={(date) => {
if (date) {
setSelectedDate(date);
handleDateChange(date);
setOpen(false);
}
}}