Files
flvx/vite-frontend/src/shadcn-bridge/heroui/date-picker.tsx
T
sagit 66de566a00 fix(frontend): stabilize multiselect behavior and UI spacing (#154)
* fix(frontend): left-align announcement logo in homepage banner

* fix(frontend): keep multiselect panels floating and preserve summaries

* fix(frontend): rebalance config card header spacing

* fix(frontend): normalize formatting and fix multiselect modal behavior

* fix(frontend): restore config divider spacing on desktop
2026-02-19 20:50:12 +08:00

95 lines
2.0 KiB
TypeScript

import * as React from "react";
import { FieldContainer, type FieldMetaProps } from "./shared";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";
interface CalendarDateLike {
day: number;
month: number;
year: number;
}
export interface DatePickerProps extends FieldMetaProps {
className?: string;
isDisabled?: boolean;
isRequired?: boolean;
onChange?: (value: CalendarDateLike | null) => void;
showMonthAndYearPickers?: boolean;
value?: CalendarDateLike | null;
}
function formatDateValue(value: CalendarDateLike | null | undefined) {
if (!value) {
return "";
}
const month = String(value.month).padStart(2, "0");
const day = String(value.day).padStart(2, "0");
return `${value.year}-${month}-${day}`;
}
export function DatePicker({
className,
description,
errorMessage,
isDisabled,
isInvalid,
isRequired,
label,
onChange,
value,
}: DatePickerProps) {
const id = React.useId();
return (
<FieldContainer
description={description}
errorMessage={errorMessage}
id={id}
isInvalid={isInvalid}
isRequired={isRequired}
label={label}
>
<Input
aria-invalid={isInvalid}
className={cn(className)}
disabled={isDisabled}
id={id}
required={isRequired}
type="date"
value={formatDateValue(value)}
onChange={(event) => {
if (!onChange) {
return;
}
if (!event.target.value) {
onChange(null);
return;
}
const [yearText, monthText, dayText] = event.target.value.split("-");
const year = Number(yearText);
const month = Number(monthText);
const day = Number(dayText);
if (
!Number.isFinite(year) ||
!Number.isFinite(month) ||
!Number.isFinite(day)
) {
onChange(null);
return;
}
onChange({ day, month, year });
}}
/>
</FieldContainer>
);
}