/* Copyright 2026 Marimo. All rights reserved. */
import { CalendarIcon } from "lucide-react";
import { useState } from "react";
import {
Button as AriaButton,
DatePicker as AriaDatePicker,
type DatePickerProps as AriaDatePickerProps,
DateRangePicker as AriaDateRangePicker,
type DateRangePickerProps as AriaDateRangePickerProps,
type DateValue as AriaDateValue,
Dialog as AriaDialog,
type DialogProps as AriaDialogProps,
type PopoverProps as AriaPopoverProps,
type ValidationResult as AriaValidationResult,
composeRenderProps,
Text,
} from "react-aria-components";
import { cn } from "@/utils/cn";
import { Popover } from "./aria-popover";
import { buttonVariants } from "./button";
import {
Calendar,
CalendarCell,
CalendarGrid,
CalendarGridBody,
CalendarGridHeader,
CalendarHeaderCell,
CalendarHeading,
RangeCalendar,
} from "./calendar";
import { DateInput } from "./date-input";
import { FieldError, FieldGroup, Label } from "./field";
const DatePickerContent = ({
className,
popoverClassName,
...props
}: AriaDialogProps & { popoverClassName?: AriaPopoverProps["className"] }) => (
cn("w-auto p-3", className),
)}
>
);
interface DatePickerProps<
T extends AriaDateValue,
> extends AriaDatePickerProps {
label?: string;
description?: string;
errorMessage?: string | ((validation: AriaValidationResult) => string);
}
const DatePicker = ({
label,
description,
errorMessage,
className,
...props
}: DatePickerProps) => {
const [open, setOpen] = useState(false);
return (
cn("group flex flex-col gap-2", className),
)}
onOpenChange={(open) => {
setOpen(open);
}}
{...props}
>
{label && }
{
setOpen(true);
}}
className={cn(
buttonVariants({ variant: "text", size: "icon" }),
"ml-1 size-6 data-focus-visible:ring-offset-0",
)}
>
{description && (
{description}
)}
{errorMessage}
{(day) => {day}}
{(date) => }
);
};
interface DateRangePickerProps<
T extends AriaDateValue,
> extends AriaDateRangePickerProps {
label?: string;
description?: string;
errorMessage?: string | ((validation: AriaValidationResult) => string);
}
const DateRangePicker = ({
label,
description,
errorMessage,
className,
...props
}: DateRangePickerProps) => {
const [open, setOpen] = useState(false);
return (
cn("group flex flex-col gap-2", className),
)}
onOpenChange={(open) => {
setOpen(open);
}}
{...props}
>
{label && }
-
{
setOpen(true);
}}
className={cn(
buttonVariants({ variant: "text", size: "icon" }),
"ml-1 size-6 data-focus-visible:ring-offset-0",
)}
>
{description && (
{description}
)}
{errorMessage}
{(day) => {day}}
{(date) => }
);
};
export { DatePicker, DatePickerContent, DateRangePicker };
export type { DatePickerProps, DateRangePickerProps };