{"version":3,"file":"handle-month-view-key-down.cjs","names":[],"sources":["../../../src/components/MonthView/handle-month-view-key-down.ts"],"sourcesContent":["import { RefObject } from 'react';\n\n/** Reference to a 2D array of day buttons: [weekIndex][dayIndex] */\nexport type MonthViewControlsRef = RefObject<HTMLButtonElement[][]>;\n\ntype Direction = 'up' | 'down' | 'left' | 'right';\n\ninterface DayPosition {\n  weekIndex: number;\n  dayIndex: number;\n}\n\nfunction getDirection(key: KeyboardEvent['key']): Direction | null {\n  switch (key) {\n    case 'ArrowDown':\n      return 'down';\n    case 'ArrowUp':\n      return 'up';\n    case 'ArrowRight':\n      return 'right';\n    case 'ArrowLeft':\n      return 'left';\n    default:\n      return null;\n  }\n}\n\nfunction getControlsSize(controlsRef: MonthViewControlsRef): number[] | null {\n  if (!controlsRef.current) {\n    return null;\n  }\n  return controlsRef.current.map((week) => (week ? week.length : 0));\n}\n\ninterface GetNextPositionInput {\n  direction: Direction;\n  weekIndex: number;\n  dayIndex: number;\n  size: number[];\n}\n\nfunction getNextPosition({\n  direction,\n  weekIndex,\n  dayIndex,\n  size,\n}: GetNextPositionInput): DayPosition | null {\n  const currentWeekSize = size[weekIndex];\n  if (!currentWeekSize) {\n    return null;\n  }\n\n  switch (direction) {\n    case 'up': {\n      if (weekIndex === 0) {\n        return null;\n      }\n\n      const prevWeekSize = size[weekIndex - 1];\n      const clampedDayIndex = Math.min(dayIndex, prevWeekSize - 1);\n      return {\n        weekIndex: weekIndex - 1,\n        dayIndex: clampedDayIndex,\n      };\n    }\n\n    case 'down': {\n      if (weekIndex === size.length - 1) {\n        return null;\n      }\n\n      const nextWeekSize = size[weekIndex + 1];\n      const clampedDayIndex = Math.min(dayIndex, nextWeekSize - 1);\n      return {\n        weekIndex: weekIndex + 1,\n        dayIndex: clampedDayIndex,\n      };\n    }\n\n    case 'left': {\n      if (dayIndex === 0) {\n        if (weekIndex === 0) {\n          return null;\n        }\n\n        return {\n          weekIndex: weekIndex - 1,\n          dayIndex: size[weekIndex - 1] - 1,\n        };\n      }\n\n      return {\n        weekIndex,\n        dayIndex: dayIndex - 1,\n      };\n    }\n\n    case 'right': {\n      if (dayIndex === currentWeekSize - 1) {\n        if (weekIndex === size.length - 1) {\n          return null;\n        }\n\n        return {\n          weekIndex: weekIndex + 1,\n          dayIndex: 0,\n        };\n      }\n\n      return {\n        weekIndex,\n        dayIndex: dayIndex + 1,\n      };\n    }\n\n    default:\n      return null;\n  }\n}\n\ninterface FocusOnNextControlInput {\n  controlsRef: MonthViewControlsRef;\n  direction: Direction;\n  weekIndex: number;\n  dayIndex: number;\n  size: number[];\n}\n\nfunction focusOnNextFocusableControl({\n  controlsRef,\n  direction,\n  weekIndex,\n  dayIndex,\n  size,\n}: FocusOnNextControlInput): void {\n  const nextPosition = getNextPosition({\n    direction,\n    weekIndex,\n    dayIndex,\n    size,\n  });\n\n  if (!nextPosition) {\n    return;\n  }\n\n  const controlToFocus = controlsRef.current?.[nextPosition.weekIndex]?.[nextPosition.dayIndex];\n\n  if (!controlToFocus) {\n    return;\n  }\n\n  if (\n    controlToFocus.disabled ||\n    controlToFocus.getAttribute('data-hidden') ||\n    controlToFocus.getAttribute('data-day-placeholder')\n  ) {\n    focusOnNextFocusableControl({\n      controlsRef,\n      direction,\n      weekIndex: nextPosition.weekIndex,\n      dayIndex: nextPosition.dayIndex,\n      size,\n    });\n  } else {\n    controlToFocus.focus();\n  }\n}\n\nexport interface HandleMonthViewKeyDownInput {\n  controlsRef: MonthViewControlsRef;\n  weekIndex: number;\n  dayIndex: number;\n  event: React.KeyboardEvent<HTMLButtonElement>;\n}\n\nexport function handleMonthViewKeyDown({\n  controlsRef,\n  weekIndex,\n  dayIndex,\n  event,\n}: HandleMonthViewKeyDownInput): void {\n  const direction = getDirection(event.key);\n\n  if (direction) {\n    event.preventDefault();\n\n    const size = getControlsSize(controlsRef);\n\n    if (!size) {\n      return;\n    }\n\n    focusOnNextFocusableControl({\n      controlsRef,\n      direction,\n      weekIndex,\n      dayIndex,\n      size,\n    });\n  }\n}\n"],"mappings":";;AAYA,SAAS,aAAa,KAA6C;CACjE,QAAQ,KAAR;EACE,KAAK,aACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,KAAK,cACH,OAAO;EACT,KAAK,aACH,OAAO;EACT,SACE,OAAO;CACX;AACF;AAEA,SAAS,gBAAgB,aAAoD;CAC3E,IAAI,CAAC,YAAY,SACf,OAAO;CAET,OAAO,YAAY,QAAQ,KAAK,SAAU,OAAO,KAAK,SAAS,CAAE;AACnE;AASA,SAAS,gBAAgB,EACvB,WACA,WACA,UACA,QAC2C;CAC3C,MAAM,kBAAkB,KAAK;CAC7B,IAAI,CAAC,iBACH,OAAO;CAGT,QAAQ,WAAR;EACE,KAAK,MAAM;GACT,IAAI,cAAc,GAChB,OAAO;GAGT,MAAM,eAAe,KAAK,YAAY;GACtC,MAAM,kBAAkB,KAAK,IAAI,UAAU,eAAe,CAAC;GAC3D,OAAO;IACL,WAAW,YAAY;IACvB,UAAU;GACZ;EACF;EAEA,KAAK,QAAQ;GACX,IAAI,cAAc,KAAK,SAAS,GAC9B,OAAO;GAGT,MAAM,eAAe,KAAK,YAAY;GACtC,MAAM,kBAAkB,KAAK,IAAI,UAAU,eAAe,CAAC;GAC3D,OAAO;IACL,WAAW,YAAY;IACvB,UAAU;GACZ;EACF;EAEA,KAAK;GACH,IAAI,aAAa,GAAG;IAClB,IAAI,cAAc,GAChB,OAAO;IAGT,OAAO;KACL,WAAW,YAAY;KACvB,UAAU,KAAK,YAAY,KAAK;IAClC;GACF;GAEA,OAAO;IACL;IACA,UAAU,WAAW;GACvB;EAGF,KAAK;GACH,IAAI,aAAa,kBAAkB,GAAG;IACpC,IAAI,cAAc,KAAK,SAAS,GAC9B,OAAO;IAGT,OAAO;KACL,WAAW,YAAY;KACvB,UAAU;IACZ;GACF;GAEA,OAAO;IACL;IACA,UAAU,WAAW;GACvB;EAGF,SACE,OAAO;CACX;AACF;AAUA,SAAS,4BAA4B,EACnC,aACA,WACA,WACA,UACA,QACgC;CAChC,MAAM,eAAe,gBAAgB;EACnC;EACA;EACA;EACA;CACF,CAAC;CAED,IAAI,CAAC,cACH;CAGF,MAAM,iBAAiB,YAAY,UAAU,aAAa,UAAU,GAAG,aAAa;CAEpF,IAAI,CAAC,gBACH;CAGF,IACE,eAAe,YACf,eAAe,aAAa,aAAa,KACzC,eAAe,aAAa,sBAAsB,GAElD,4BAA4B;EAC1B;EACA;EACA,WAAW,aAAa;EACxB,UAAU,aAAa;EACvB;CACF,CAAC;MAED,eAAe,MAAM;AAEzB;AASA,SAAgB,uBAAuB,EACrC,aACA,WACA,UACA,SACoC;CACpC,MAAM,YAAY,aAAa,MAAM,GAAG;CAExC,IAAI,WAAW;EACb,MAAM,eAAe;EAErB,MAAM,OAAO,gBAAgB,WAAW;EAExC,IAAI,CAAC,MACH;EAGF,4BAA4B;GAC1B;GACA;GACA;GACA;GACA;EACF,CAAC;CACH;AACF"}