monthFoundation.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import BaseFoundation, { DefaultAdapter } from '../base/foundation';
  2. // import { cssClasses, strings } from './constants';
  3. import getMonthTable, { WeekStartNumber } from './_utils/getMonthTable';
  4. import getDayOfWeek from './_utils/getDayOfWeek';
  5. import { format } from 'date-fns';
  6. import isNullOrUndefined from '../utils/isNullOrUndefined';
  7. export interface MonthFoundationProps {
  8. forwardRef: any;
  9. month: Date;
  10. selected: Set<string>;
  11. rangeStart: string;
  12. rangeEnd: string;
  13. offsetRangeStart: string;
  14. offsetRangeEnd: string;
  15. onDayClick: (day: MonthDayInfo) => void;
  16. onDayHover: (day: MonthDayInfo) => void;
  17. weekStartsOn: WeekStartNumber;
  18. disabledDate: (day: Date, options?: { rangeStart: string; rangeEnd: string }) => boolean;
  19. weeksRowNum: number;
  20. onWeeksRowNumChange: (weeksRowNum: number) => void;
  21. renderDate: () => void;
  22. renderFullDate: () => void;
  23. hoverDay: string; // Real-time hover date
  24. startDateOffset: () => void;
  25. endDateOffset: () => void;
  26. rangeInputFocus: string | boolean;
  27. focusRecordsRef: any;
  28. locale: any;
  29. localeCode: string;
  30. }
  31. export type MonthDayInfo = {
  32. dayNumber: number;
  33. dayNumberFull?: string;
  34. fullDate: string;
  35. } | {
  36. dayNumber: string;
  37. dayNumberFull?: string;
  38. fullDate: string;
  39. };
  40. export interface MonthInfo {
  41. weeks: Array<MonthDayInfo[]>;
  42. monthText: string ;
  43. month?: Date;
  44. }
  45. export interface MonthFoundationState {
  46. weekdays: string[];
  47. month: MonthInfo;
  48. todayText: string;
  49. weeksRowNum: number;
  50. }
  51. export interface MonthTable {
  52. monthText: string;
  53. weeks: unknown;
  54. month: unknown;
  55. }
  56. export interface MonthAdapter extends DefaultAdapter<MonthFoundationProps, MonthFoundationState>{
  57. updateToday: (todayText: string) => void;
  58. setWeekDays: (weekdays: string[]) => void;
  59. setWeeksRowNum: (weeksRowNum: number, callback?: () => void) => void;
  60. updateMonthTable: (month: MonthInfo) => void;
  61. notifyDayClick: MonthFoundationProps['onDayClick'];
  62. notifyDayHover: MonthFoundationProps['onDayHover'];
  63. notifyWeeksRowNumChange: MonthFoundationProps['onWeeksRowNumChange'];
  64. }
  65. export default class CalendarMonthFoundation extends BaseFoundation<MonthAdapter> {
  66. constructor(adapter: MonthAdapter) {
  67. super({ ...adapter });
  68. }
  69. init() {
  70. this._getToday();
  71. this.getMonthTable();
  72. }
  73. _getToday() {
  74. const today = new Date();
  75. const todayText = format(today, 'yyyy-MM-dd');
  76. this._adapter.updateToday(todayText);
  77. }
  78. getMonthTable() {
  79. const month: Date = this._adapter.getProp('month');
  80. const weeksRowNum = this.getState('weeksRowNum');
  81. if (month) {
  82. this.updateWeekDays();
  83. const weekStartsOn: WeekStartNumber = this._adapter.getProp('weekStartsOn');
  84. const monthTable = getMonthTable(month, weekStartsOn);
  85. const { weeks } = monthTable;
  86. this._adapter.updateMonthTable(monthTable);
  87. if (isNullOrUndefined(weeksRowNum)) {
  88. this._adapter.setWeeksRowNum(weeks.length);
  89. } else if (Array.isArray(weeks) && weeks.length !== weeksRowNum) {
  90. this._adapter.setWeeksRowNum(weeks.length, () => {
  91. this._adapter.notifyWeeksRowNumChange(weeks.length);
  92. });
  93. }
  94. }
  95. }
  96. updateWeekDays() {
  97. const weekStartsOn = this._adapter.getProp('weekStartsOn');
  98. const weekdays = getDayOfWeek({ weekStartsOn });
  99. this._adapter.setWeekDays(weekdays);
  100. }
  101. // eslint-disable-next-line @typescript-eslint/no-empty-function
  102. destroy() {}
  103. handleClick(day: MonthDayInfo) {
  104. this._adapter.notifyDayClick(day);
  105. }
  106. handleHover(day?: MonthDayInfo) {
  107. this._adapter.notifyDayHover(day);
  108. }
  109. }