{"version":3,"sources":["../../../../src/components/Calendar/CalendarYear/useCalendarYear.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Enter, Space } from '@fluentui/keyboard-keys';\nimport { getIntrinsicElementProps, mergeCallbacks, slot } from '@fluentui/react-utilities';\nimport { useCalendarContext } from '../calendarContext';\nimport { createDate } from '../utils/dateMath';\nimport { mergeProps } from '../../../utils/mergeProps';\nimport { getCalendarEventType, resolveCalendarNavigationButton } from '../utils/calendarNavigation';\nimport { getCalendarPickerCellProps, getCalendarPickerRows, useCalendarPickerGrid } from '../hooks/useCalendarGrid';\nimport type {\n  CalendarYearProps,\n  CalendarYearState,\n  CalendarYearCellData,\n  CalendarYearRange,\n} from './CalendarYear.types';\n\nconst CELL_COUNT = 12;\n\ntype ButtonEvent = React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>;\n\nfunction useYearRangeState({\n  selectedYear,\n  navigatedYear,\n  onNavigateDate,\n  currentYear,\n}: Pick<CalendarYearProps, 'navigatedYear' | 'onNavigateDate'> & {\n  selectedYear?: number | null;\n  currentYear: number;\n}) {\n  const rangeYear = React.useMemo(\n    () => navigatedYear ?? selectedYear ?? Math.floor(currentYear / 10) * 10,\n    [currentYear, navigatedYear, selectedYear],\n  );\n\n  const [fromYear, setFromYear] = React.useState<number>(rangeYear);\n\n  const onNavigate = (ev: ButtonEvent, offset: number) => {\n    const newFromYear = fromYear + offset;\n    setFromYear(newFromYear);\n    onNavigateDate?.(ev, { event: ev, type: getCalendarEventType(ev), year: newFromYear });\n  };\n\n  React.useEffect(() => {\n    // eslint-disable-next-line react-hooks/set-state-in-effect\n    setFromYear(rangeYear);\n  }, [rangeYear]);\n\n  return [fromYear, fromYear + CELL_COUNT - 1, onNavigate] as const;\n}\n\n/**\n * Create the state required to render CalendarYear.\n * Calendar owns selection, directional navigation and roving focus.\n */\nexport const useCalendarYear = (props: CalendarYearProps, ref: React.Ref<HTMLDivElement>): CalendarYearState => {\n  const {\n    allFocusable,\n    calendarYearColumns,\n    today: contextToday,\n    formatters,\n    maxDate,\n    minDate,\n    value,\n  } = useCalendarContext();\n  const { grid, header, navigation, nextRangeButton, onHeaderSelect, onSelectYear, previousRangeButton, heading } =\n    props;\n\n  const today = contextToday ?? new Date();\n  const currentYear = today.getFullYear();\n  const selectedYear = props.selectedYear !== undefined ? props.selectedYear : value?.getFullYear();\n  const minYear = minDate ? minDate.getFullYear() : undefined;\n  const maxYear = maxDate ? maxDate.getFullYear() : undefined;\n  const [fromYear, toYear, onNavigate] = useYearRangeState({ ...props, currentYear, selectedYear });\n\n  const firstFocusableYear = allFocusable ? fromYear : Math.max(fromYear, minYear ?? fromYear);\n  const lastFocusableYear = allFocusable ? toYear : Math.min(toYear, maxYear ?? toYear);\n  const focusYear = Math.min(\n    lastFocusableYear,\n    Math.max(firstFocusableYear, props.navigatedYear ?? selectedYear ?? currentYear),\n  );\n\n  const formatYear = (year: number) => formatters.dateTime({ date: createDate(year, 0, 1), format: 'year' });\n  const isYearDisabled = (year: number) =>\n    (minYear !== undefined && year < minYear) || (maxYear !== undefined && year > maxYear);\n\n  const yearCells: CalendarYearCellData[] = Array.from({ length: CELL_COUNT }, (_, index) => {\n    const year = fromYear + index;\n    return {\n      year,\n      label: formatYear(year),\n      isCurrent: year === currentYear,\n      isSelected: year === selectedYear,\n      isNavigated: year === focusYear,\n      isDisabled: isYearDisabled(year),\n    };\n  });\n  const yearRows = getCalendarPickerRows(yearCells, calendarYearColumns);\n  const range = { fromYear, toYear };\n  const rangeLabel = `${formatYear(fromYear)} - ${formatYear(toYear)}`;\n  const [gridSlot, getCell, tabStop, activeCellIndex] = useCalendarPickerGrid(\n    grid,\n    rangeLabel,\n    index => !isYearDisabled(fromYear + index),\n    (ev, index) => onSelectYear?.(ev, { event: ev, type: getCalendarEventType(ev), year: fromYear + index }),\n    {\n      columns: calendarYearColumns,\n      allFocusable,\n      defaultTabStop: focusYear >= fromYear && focusYear <= toYear ? focusYear - fromYear : undefined,\n      resetKey: `${fromYear}:${calendarYearColumns}`,\n    },\n  );\n  const getYearCellProps: CalendarYearState['getYearCellProps'] = year => {\n    const cellProps = getCalendarPickerCellProps(\n      allFocusable,\n      year.isDisabled,\n      year.isSelected,\n      year.isCurrent,\n      year.year - fromYear === tabStop,\n      year.year - fromYear === activeCellIndex,\n    );\n    const overrides = props.getCellProps?.(year);\n    return {\n      root: mergeProps(cellProps.root, overrides?.root),\n      button: mergeProps({ ...cellProps.button, children: year.label }, overrides?.button),\n    };\n  };\n  const getYearRowProps: CalendarYearState['getYearRowProps'] = row => ({\n    root: mergeProps({ role: 'row' }, props.getRowProps?.(row).root),\n  });\n\n  const prevDisabled = minYear !== undefined && fromYear <= minYear;\n  const nextDisabled = maxYear !== undefined && fromYear + CELL_COUNT > maxYear;\n\n  const formatRange = (yearRange: CalendarYearRange) =>\n    `${formatYear(yearRange.fromYear)} - ${formatYear(yearRange.toYear)}`;\n  const prevRange = { fromYear: fromYear - CELL_COUNT, toYear: toYear - CELL_COUNT };\n  const nextRange = { fromYear: fromYear + CELL_COUNT, toYear: toYear + CELL_COUNT };\n\n  const titleElementType = onHeaderSelect ? 'button' : 'div';\n\n  React.useImperativeHandle(props.imperativeRef, () => ({\n    focus(options?: FocusOptions) {\n      if (focusYear >= fromYear && focusYear <= toYear) {\n        getCell(focusYear - fromYear)?.focus(options);\n      }\n    },\n  }));\n\n  const headingSlot = slot.always(heading, {\n    defaultProps: {\n      as: titleElementType,\n      'aria-label': onHeaderSelect\n        ? formatters.yearRangePickerHeaderLabel({ ...range, formattedRange: rangeLabel })\n        : undefined,\n      children: onHeaderSelect ? (\n        <span aria-live=\"assertive\" aria-atomic=\"true\">\n          {rangeLabel}\n        </span>\n      ) : (\n        rangeLabel\n      ),\n      type: onHeaderSelect ? 'button' : undefined,\n    },\n    elementType: titleElementType,\n  });\n  if (onHeaderSelect) {\n    headingSlot.onClick = mergeCallbacks(\n      headingSlot.onClick as React.MouseEventHandler<HTMLElement> | undefined,\n      ev => {\n        if (!ev.isDefaultPrevented()) {\n          onHeaderSelect(ev, { event: ev, type: 'click', focus: true });\n        }\n      },\n    );\n    headingSlot.onKeyDown = mergeCallbacks(\n      headingSlot.onKeyDown as React.KeyboardEventHandler<HTMLElement> | undefined,\n      ev => {\n        if (ev.isDefaultPrevented() || (ev.key !== Enter && ev.key !== Space)) {\n          return;\n        }\n        ev.preventDefault();\n        onHeaderSelect(ev, { event: ev, type: 'keydown', focus: true });\n      },\n    );\n  }\n\n  return {\n    yearRows,\n    getYearCellProps,\n    getYearRowProps,\n    components: {\n      root: 'div',\n      header: 'div',\n      heading: titleElementType,\n      navigation: 'div',\n      previousRangeButton: 'button',\n      nextRangeButton: 'button',\n      grid: 'div',\n    },\n    root: slot.always(getIntrinsicElementProps('div', { ...props, ref }), { elementType: 'div' }),\n    header: slot.always(header, { elementType: 'div' }),\n    heading: headingSlot,\n    navigation: slot.always(navigation, { elementType: 'div' }),\n    previousRangeButton: resolveCalendarNavigationButton(\n      previousRangeButton,\n      !prevDisabled,\n      allFocusable,\n      formatters.previousYearRangeLabel({ ...prevRange, formattedRange: formatRange(prevRange) }),\n      ev => onNavigate(ev, -CELL_COUNT),\n    ),\n    nextRangeButton: resolveCalendarNavigationButton(\n      nextRangeButton,\n      !nextDisabled,\n      allFocusable,\n      formatters.nextYearRangeLabel({ ...nextRange, formattedRange: formatRange(nextRange) }),\n      ev => onNavigate(ev, CELL_COUNT),\n    ),\n    grid: gridSlot,\n  };\n};\n"],"names":["useCalendarYear","CELL_COUNT","useYearRangeState","selectedYear","navigatedYear","onNavigateDate","currentYear","rangeYear","React","useMemo","Math","floor","fromYear","setFromYear","useState","onNavigate","ev","offset","newFromYear","event","type","getCalendarEventType","year","useEffect","props","ref","allFocusable","calendarYearColumns","today","contextToday","formatters","maxDate","minDate","value","useCalendarContext","grid","header","navigation","nextRangeButton","onHeaderSelect","onSelectYear","previousRangeButton","heading","Date","getFullYear","undefined","minYear","maxYear","toYear","firstFocusableYear","max","lastFocusableYear","min","focusYear","formatYear","dateTime","date","createDate","format","isYearDisabled","yearCells","Array","from","length","_","index","label","isCurrent","isSelected","isNavigated","isDisabled","yearRows","getCalendarPickerRows","range","rangeLabel","gridSlot","getCell","tabStop","activeCellIndex","useCalendarPickerGrid","columns","defaultTabStop","resetKey","getYearCellProps","cellProps","getCalendarPickerCellProps","overrides","getCellProps","root","mergeProps","button","children","getYearRowProps","row","role","getRowProps","prevDisabled","nextDisabled","formatRange","yearRange","prevRange","nextRange","titleElementType","useImperativeHandle","imperativeRef","focus","options","headingSlot","slot","always","defaultProps","as","yearRangePickerHeaderLabel","formattedRange","span","aria-live","aria-atomic","elementType","onClick","mergeCallbacks","isDefaultPrevented","onKeyDown","key","Enter","Space","preventDefault","components","getIntrinsicElementProps","resolveCalendarNavigationButton","previousYearRangeLabel","nextYearRangeLabel"],"mappings":"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"}