import type { SetStateAction } from "react" import type { CalendarDate, CalendarDateTime, Time, ZonedDateTime } from "@internationalized/date" import { isNonNullable } from "deepsea-tools" import type { Field } from "soda-tanstack-form" import { type EmptyValue, getEmptyValue } from "@/components/FormProvider" import { type DefaultTime, getTimeValue } from "@/utils/getTimeValue" import { type ParseMode, parseTime } from "@/utils/parseTime" export type TimeValue = Date | number export type TimeValueMode = "date" | "timestamp" export type TimeValueModeMap = ValueMode extends "date" ? Date : ValueMode extends "timestamp" ? number : never export function getValue(value: Date | number | null | undefined, parseMode?: T) { return isNonNullable(value) ? parseTime(value.valueOf(), parseMode) : null } export function getFieldValue(field: Field, parseMode?: P) { return getValue(field.state.value, parseMode) } export interface GetUpdaterParams { value: CalendarDateTime | ZonedDateTime | Time | CalendarDate | CalendarDateTime | ZonedDateTime | null valueMode?: TimeValueMode emptyValue?: EmptyValue defaultTime?: DefaultTime | (() => DefaultTime) } export function getUpdater({ value, valueMode, emptyValue, defaultTime }: GetUpdaterParams): SetStateAction { const timestamp = getTimeValue(value, defaultTime) if (!isNonNullable(timestamp)) return getEmptyValue(emptyValue) if (valueMode === "timestamp") return timestamp return (prev: Date | number | null | undefined) => (prev instanceof Date && prev.valueOf() === timestamp ? prev : new Date(timestamp)) } export interface GetOnChangeParams { field: Field valueMode?: TimeValueMode emptyValue?: EmptyValue defaultTime?: DefaultTime | (() => DefaultTime) } export function getOnChange({ field, valueMode, emptyValue, defaultTime }: GetOnChangeParams) { return function onChange(value: CalendarDateTime | ZonedDateTime | Time | CalendarDate | CalendarDateTime | ZonedDateTime | null) { field.handleChange(getUpdater({ value, valueMode, emptyValue, defaultTime }) as SetStateAction) } }