All files / src/calendar/tables MonthTable.tsx

0% Statements 0/22
0% Branches 0/20
0% Functions 0/14
0% Lines 0/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117                                                                                                                                                                                                                                         
import React from "react";
import moment, { Moment, isMoment } from "moment";
import Table, { CellStatus } from "./BaseTable";
import { useTranslation } from "../../i18n";
import {
  RangeDateType,
  CalendarTableType,
  DateChangeContext,
} from "../DateProps";
 
export interface MonthTableProps {
  /**
   * 当前展示时间
   */
  current: Moment;
 
  /**
   * 允许选择的时间范围限制
   */
  range?: RangeDateType;
 
  cellStatus?: (date: Moment) => CellStatus;
 
  onSelect?: (value: Moment, context: DateChangeContext) => void;
 
  onTypeChange?: (type: CalendarTableType) => void;
 
  onCurrentChange?: (current: Moment) => void;
 
  hideCaption?: boolean;
}
 
export function MonthTable({
  current,
  onCurrentChange = () => null,
  range,
  onSelect = () => null,
  onTypeChange = () => null,
  cellStatus = () => CellStatus.Common,
  hideCaption,
}: MonthTableProps) {
  const t = useTranslation();
 
  const year = current.year();
 
  function genTable(): number[][] {
    return [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]];
  }
 
  function renderYear() {
    return (
      <a className="op-item" onClick={() => onTypeChange("year")}>
        {current.format(t.yearFormat)}
      </a>
    );
  }
 
  const [rangeMin, rangeMax] = range || [null, null];
 
  function isValid(date) {
    if (isMoment(rangeMin) && rangeMin.isAfter(date, "month")) {
      return false;
    }
    if (isMoment(rangeMax) && rangeMax.isBefore(date, "month")) {
      return false;
    }
    return true;
  }
 
  return (
    <Table
      type="month"
      caption={!hideCaption && renderYear()}
      jumperOptions={{
        onNext: () => onCurrentChange(moment(current).add(1, "year")),
        onPrev: () => onCurrentChange(moment(current).subtract(1, "year")),
        onCurrent: () => onCurrentChange(moment()),
        isCurrent: current.isSame(moment(), "year"),
        nextDisabled:
          isMoment(rangeMax) &&
          rangeMax.isBefore(
            moment({ year, month: 0, date: 1 }).add(1, "year"),
            "month"
          ),
        prevDisabled:
          isMoment(rangeMin) &&
          rangeMin.isAfter(
            moment({ year, month: 0, date: 1 }).subtract(1, "day"),
            "month"
          ),
        nextTitle: t.nextYear,
        prevTitle: t.prevYear,
        curTitle: t.curYear,
      }}
    >
      {genTable().map((row, index) => (
        <Table.Row key={index}>
          {row.map(month => {
            const m = moment({ year, month });
            return (
              <Table.Cell
                key={month}
                name={moment.monthsShort(month)}
                value={m}
                onSelect={onSelect}
                isNow={m.isSame(moment(), "month")}
                status={cellStatus(m)}
                disabled={!isValid(m)}
              />
            );
          })}
        </Table.Row>
      ))}
    </Table>
  );
}