{"version":3,"sources":["../../../src/components/DatePicker/useDatePickerDateState.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useControllableState, useEventCallback } from '@fluentui/react-utilities';\nimport type { DatePickerDateChangeData, DatePickerErrorType, DatePickerProps } from './DatePicker.types';\n\ntype DatePickerEvent = React.SyntheticEvent | Event;\n\ntype DatePickerDateStateOptions = Pick<\n  DatePickerProps,\n  'value' | 'defaultValue' | 'allowTextInput' | 'disabled' | 'required' | 'onDateChange' | 'onValidationResult'\n> & {\n  formatDate: (date: Date) => string;\n  parseDate: (text: string) => Date | null;\n  isDateUnavailable: (date: Date) => boolean;\n};\n\n/**\n * Committed value, pending text and validation state of a DatePicker.\n */\nexport type DatePickerDateState = {\n  value: Date | null;\n  text: string;\n  error: DatePickerErrorType | undefined;\n  setText: (text: string) => void;\n  validate: (event: DatePickerEvent) => void;\n  selectDate: (event: DatePickerEvent, date: Date) => void;\n};\n\nconst isValidDate = (date: Date | null | undefined): date is Date => !!date && Number.isFinite(date.getTime());\n\n/**\n * Owns the committed date and editable text without depending on the field or the Calendar.\n * Pending text is validated once per change: repeated blur or outside clicks neither change nor re-report the result.\n */\nexport const useDatePickerDateState = (options: DatePickerDateStateOptions): DatePickerDateState => {\n  const {\n    allowTextInput = false,\n    disabled = false,\n    required = false,\n    formatDate,\n    parseDate,\n    isDateUnavailable,\n    onDateChange,\n    onValidationResult,\n  } = options;\n\n  const [value, setValue] = useControllableState<Date | null>({\n    state: options.value,\n    defaultState: options.defaultValue,\n    initialState: null,\n  });\n  const committedValue = isValidDate(value) ? value : null;\n  const formattedValue = committedValue ? formatDate(committedValue) : '';\n\n  const [draft, setDraft] = React.useState({\n    text: formattedValue,\n    dirty: false,\n    formattedValue,\n    sourceValue: committedValue?.getTime() ?? null,\n  });\n  const [error, setError] = React.useState<DatePickerErrorType | undefined>(undefined);\n  // External value or formatter changes replace pending text.\n  if (draft.formattedValue !== formattedValue || draft.sourceValue !== (committedValue?.getTime() ?? null)) {\n    setDraft({\n      text: formattedValue,\n      dirty: false,\n      formattedValue,\n      sourceValue: committedValue?.getTime() ?? null,\n    });\n    setError(undefined);\n  }\n\n  const resetText = (text = formattedValue, sourceValue = committedValue?.getTime() ?? null) =>\n    setDraft({ text, dirty: false, formattedValue: text, sourceValue });\n\n  const report = (event: DatePickerEvent, nextError: DatePickerErrorType | undefined) => {\n    setError(nextError);\n    onValidationResult?.(event, { event, type: event.type, error: nextError });\n  };\n\n  const commit = (event: DatePickerEvent, date: Date | null, reason: DatePickerDateChangeData['reason']) => {\n    setValue(date);\n    resetText(date ? formatDate(date) : '', date?.getTime() ?? null);\n    onDateChange?.(event, { event, type: event.type, value: date, reason });\n  };\n\n  const validate = useEventCallback((event: DatePickerEvent) => {\n    if (disabled || !allowTextInput || !draft.dirty) {\n      return;\n    }\n\n    const text = draft.text.trim();\n    if (!text) {\n      if (committedValue) {\n        commit(event, null, 'clear');\n      } else {\n        resetText('');\n      }\n      report(event, required ? 'required-input' : undefined);\n      return;\n    }\n\n    // A custom formatter may produce text its parser cannot round-trip.\n    if (committedValue && text === formattedValue) {\n      resetText();\n      report(event, isDateUnavailable(committedValue) ? 'out-of-bounds' : undefined);\n      return;\n    }\n\n    const parsedDate = parseDate(text);\n    if (!isValidDate(parsedDate)) {\n      resetText();\n      report(event, 'invalid-input');\n      return;\n    }\n\n    if (isDateUnavailable(parsedDate)) {\n      resetText();\n      report(event, 'out-of-bounds');\n      return;\n    }\n\n    commit(event, parsedDate, 'input');\n    report(event, undefined);\n  });\n\n  const selectDate = useEventCallback((event: DatePickerEvent, date: Date) => {\n    if (disabled || !isValidDate(date) || isDateUnavailable(date)) {\n      return;\n    }\n\n    commit(event, date, 'calendar');\n    report(event, undefined);\n  });\n\n  const setText = useEventCallback((text: string) => {\n    if (allowTextInput && !disabled) {\n      setDraft({ text, dirty: true, formattedValue, sourceValue: committedValue?.getTime() ?? null });\n    }\n  });\n\n  return { value: committedValue, text: draft.text, error, setText, validate, selectDate };\n};\n"],"names":["useDatePickerDateState","isValidDate","date","Number","isFinite","getTime","options","allowTextInput","disabled","required","formatDate","parseDate","isDateUnavailable","onDateChange","onValidationResult","value","setValue","useControllableState","state","defaultState","defaultValue","initialState","committedValue","formattedValue","draft","setDraft","React","useState","text","dirty","sourceValue","error","setError","undefined","resetText","report","event","nextError","type","commit","reason","validate","useEventCallback","trim","parsedDate","selectDate","setText"],"mappings":"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"}