{"version":3,"file":"basic-quarter-table.mjs","names":[],"sources":["../../../../../../../packages/components/date-picker-panel/src/date-picker-com/basic-quarter-table.vue"],"sourcesContent":["<template>\n  <table\n    role=\"grid\"\n    :aria-label=\"t('el.datepicker.quarterTablePrompt')\"\n    :class=\"ns.b()\"\n    @click=\"handleQuarterTableClick\"\n    @mousemove=\"handleRangeHover\"\n    @mouseleave=\"handleTableMouseLeave\"\n  >\n    <tbody ref=\"tbodyRef\">\n      <tr>\n        <td\n          v-for=\"(cell, key) in columns\"\n          :key=\"key\"\n          :ref=\"(el) => cell.isSelected && (currentCellRef = el as HTMLElement)\"\n          class=\"available\"\n          :class=\"getCellStyle(cell)\"\n          :aria-selected=\"!!cell.isSelected\"\n          :aria-label=\"`Q${cell.text + 1}`\"\n          :tabindex=\"cell.isSelected ? 0 : -1\"\n          @keydown.space.prevent.stop=\"handleQuarterTableClick\"\n          @keydown.enter.prevent.stop=\"handleQuarterTableClick\"\n        >\n          <el-date-picker-cell\n            :cell=\"{\n              ...cell,\n              renderText: `Q${cell.text + 1}`,\n            }\"\n          />\n        </td>\n      </tr>\n    </tbody>\n  </table>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, nextTick, ref, watch } from 'vue'\nimport dayjs from 'dayjs'\nimport { useLocale, useNamespace } from '@element-plus/hooks'\nimport { castArray, hasClass } from '@element-plus/utils'\nimport { basicQuarterTableProps } from '../props/basic-quarter-table'\nimport { datesInQuarter, normalizeQuarterDate } from '../utils'\nimport ElDatePickerCell from './basic-cell-render'\n\nimport type { Dayjs, OpUnitType } from 'dayjs'\n\nconst QUARTER_UNIT = 'quarter' as OpUnitType\nconst COL_COUNT = 4\n\ntype QuarterCell = {\n  column: number\n  customClass: string | undefined\n  disabled: boolean\n  end: boolean\n  inRange: boolean\n  row: number\n  selected: Dayjs | undefined\n  isCurrent: boolean | undefined\n  isSelected: boolean\n  start: boolean\n  text: number\n  renderText: string | undefined\n  timestamp: number | undefined\n  date: Date | undefined\n  dayjs: Dayjs | undefined\n  type: 'normal' | 'today'\n}\n\nconst props = defineProps(basicQuarterTableProps)\nconst emit = defineEmits(['changerange', 'pick', 'select'])\n\nconst ns = useNamespace('quarter-table')\n\nconst { t, lang } = useLocale()\nconst tbodyRef = ref<HTMLElement>()\nconst currentCellRef = ref<HTMLElement>()\nconst tableColumns = ref<QuarterCell[]>([])\nlet lastQuarter: number | undefined\n\nconst resolveQuarterDate = (quarter: number) =>\n  normalizeQuarterDate(\n    props.date.startOf('year').add(quarter, 'quarter'),\n    lang.value,\n    props.disabledDate\n  )\n\nconst isSelectedCell = (cell: QuarterCell) => {\n  const year = props.date.year()\n  const quarter = cell.text\n  return castArray(props.date).some(\n    (date) => date.year() === year && date.quarter() - 1 === quarter\n  )\n}\n\nconst createQuarterCell = (column: number): QuarterCell => ({\n  row: 0,\n  column,\n  type: 'normal',\n  inRange: false,\n  start: false,\n  end: false,\n  text: -1,\n  disabled: false,\n  isSelected: false,\n  customClass: undefined,\n  date: undefined,\n  dayjs: undefined,\n  isCurrent: undefined,\n  selected: undefined,\n  renderText: undefined,\n  timestamp: undefined,\n})\n\nconst resolveRangeEndDate = () =>\n  props.rangeState.endDate ||\n  props.maxDate ||\n  (props.rangeState.selecting && props.minDate) ||\n  null\n\nconst isQuarterDisabled = (quarter: number) =>\n  props.disabled ||\n  (props.disabledDate\n    ? datesInQuarter(props.date, props.date.year(), quarter, lang.value).every(\n        props.disabledDate\n      )\n    : false)\n\nconst updateQuarterCell = (\n  cell: QuarterCell,\n  col: number,\n  now: Dayjs,\n  calEndDate: Dayjs | null\n) => {\n  cell.type = 'normal'\n\n  const calTime = props.date.startOf('year').add(col, 'quarter')\n\n  cell.inRange =\n    !!(\n      props.minDate &&\n      calTime.isSameOrAfter(props.minDate, QUARTER_UNIT) &&\n      calEndDate &&\n      calTime.isSameOrBefore(calEndDate, QUARTER_UNIT)\n    ) ||\n    !!(\n      props.minDate &&\n      calTime.isSameOrBefore(props.minDate, QUARTER_UNIT) &&\n      calEndDate &&\n      calTime.isSameOrAfter(calEndDate, QUARTER_UNIT)\n    )\n\n  if (props.minDate?.isSameOrAfter(calEndDate, QUARTER_UNIT)) {\n    cell.start = !!(calEndDate && calTime.isSame(calEndDate, QUARTER_UNIT))\n    cell.end = !!(props.minDate && calTime.isSame(props.minDate, QUARTER_UNIT))\n  } else {\n    cell.start = !!(\n      props.minDate && calTime.isSame(props.minDate, QUARTER_UNIT)\n    )\n    cell.end = !!(calEndDate && calTime.isSame(calEndDate, QUARTER_UNIT))\n  }\n\n  if (now.isSame(calTime)) {\n    cell.type = 'today'\n  }\n\n  const cellDate = calTime.toDate()\n  cell.text = col\n  cell.disabled = isQuarterDisabled(col)\n  cell.date = cellDate\n  cell.customClass = props.cellClassName?.(cellDate)\n  cell.dayjs = calTime\n  cell.timestamp = calTime.valueOf()\n  cell.isSelected = isSelectedCell(cell)\n}\n\nconst columns = computed<QuarterCell[]>(() => {\n  const cells = tableColumns.value\n  const now = dayjs().locale(lang.value).startOf('quarter')\n  const calEndDate = resolveRangeEndDate()\n\n  for (let col = 0; col < COL_COUNT; col++) {\n    const cell = (cells[col] ||= createQuarterCell(col))\n    updateQuarterCell(cell, col, now, calEndDate)\n  }\n  return cells\n})\n\nconst focus = () => {\n  currentCellRef.value?.focus()\n}\n\nconst getCellStyle = (cell: QuarterCell) => {\n  const style = {} as any\n  const year = props.date.year()\n  const today = dayjs().locale(lang.value)\n  const quarter = cell.text\n\n  style.disabled = isQuarterDisabled(quarter)\n  style.current = castArray(props.parsedValue).some(\n    (date) =>\n      dayjs.isDayjs(date) &&\n      date.year() === year &&\n      date.quarter() - 1 === quarter\n  )\n  style.today = today.year() === year && today.quarter() - 1 === quarter\n\n  if (cell.customClass) {\n    style[cell.customClass] = true\n  }\n  if (cell.inRange) {\n    style['in-range'] = true\n\n    if (cell.start) {\n      style['start-date'] = true\n    }\n\n    if (cell.end) {\n      style['end-date'] = true\n    }\n  }\n  return style\n}\n\nconst handleRangeHover = (event: MouseEvent) => {\n  if (!props.rangeState.selecting) return\n\n  const target = (event.target as HTMLElement)?.closest(\n    'td'\n  ) as HTMLTableCellElement\n  if (target?.tagName !== 'TD') return\n\n  const quarter = target.cellIndex\n  // can not select disabled date\n  if (columns.value[quarter].disabled) return\n\n  if (quarter !== lastQuarter) {\n    lastQuarter = quarter\n    emit('changerange', {\n      selecting: true,\n      endDate: props.date.startOf('year').add(quarter, 'quarter'),\n    })\n  }\n}\n\nconst handleTableMouseLeave = () => {\n  lastQuarter = undefined\n}\n\nconst handleQuarterTableClick = (event: MouseEvent | KeyboardEvent) => {\n  if (props.disabled) return\n  const target = (event.target as HTMLElement)?.closest(\n    'td'\n  ) as HTMLTableCellElement\n  if (target?.tagName !== 'TD' || hasClass(target, 'disabled')) return\n\n  const quarter = target.cellIndex\n  if (props.selectionMode === 'range') {\n    const newDate = resolveQuarterDate(quarter)\n    if (!props.rangeState.selecting) {\n      emit('pick', { minDate: newDate, maxDate: null })\n      emit('select', true)\n      return\n    }\n    if (props.minDate && newDate >= props.minDate) {\n      emit('pick', { minDate: props.minDate, maxDate: newDate })\n    } else {\n      emit('pick', { minDate: newDate, maxDate: props.minDate })\n    }\n    emit('select', false)\n    return\n  }\n\n  if (props.selectionMode === 'quarters') {\n    const newQuarter = resolveQuarterDate(quarter)\n    const newValue = hasClass(target, 'current')\n      ? castArray(props.parsedValue).filter(\n          (d) => d?.year() !== newQuarter.year() || d.quarter() - 1 !== quarter\n        )\n      : castArray(props.parsedValue).concat([newQuarter])\n    emit('pick', newValue)\n    return\n  }\n\n  emit('pick', quarter)\n}\n\nwatch(\n  () => props.date,\n  async () => {\n    if (tbodyRef.value?.contains(document.activeElement)) {\n      await nextTick()\n      currentCellRef.value?.focus()\n    }\n  }\n)\n\ndefineExpose({\n  /**\n   * @description focus current cell\n   */\n  focus,\n})\n</script>\n"],"mappings":""}