index.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import { __assign, __spreadArray } from "tslib";
  2. import dayjs from 'dayjs';
  3. import { useComponent, useEvent, useReady, useState, } from 'functional-mini/component';
  4. import { mountComponent } from '../_util/component';
  5. import { useComponentEvent } from '../_util/hooks/useComponentEvent';
  6. import { hasValue, useMergedState } from '../_util/hooks/useMergedState';
  7. import { defaultLocaleText, } from './props';
  8. import { defaultMonthRange, getMonthListFromRange, getSelectionModeFromValue, renderCells, } from './utils';
  9. function getBoundingClientRect(instance, selector) {
  10. return new Promise(function (resolve, reject) {
  11. instance
  12. .createSelectorQuery()
  13. .select(selector)
  14. .boundingClientRect()
  15. .exec(function (ret) {
  16. if (ret && ret[0]) {
  17. resolve(ret[0]);
  18. }
  19. else {
  20. reject();
  21. }
  22. });
  23. });
  24. }
  25. var Calendar = function (props) {
  26. var _a, _b;
  27. var localeText = Object.assign({}, defaultLocaleText, props.localeText);
  28. var markItems = __spreadArray([], localeText.weekdayNames, true);
  29. var weekStartsOn = props.weekStartsOn;
  30. if (weekStartsOn === 'Sunday') {
  31. var item = markItems.pop();
  32. if (item)
  33. markItems.unshift(item);
  34. }
  35. var _c = useMergedState(props.defaultValue, {
  36. value: props.value,
  37. }), value = _c[0], setValue = _c[1];
  38. var selectionModeFromValue = getSelectionModeFromValue(value);
  39. var selectionMode = (_b = (_a = props.selectionMode) !== null && _a !== void 0 ? _a : selectionModeFromValue) !== null && _b !== void 0 ? _b : 'range';
  40. var triggerEvent = useComponentEvent(props).triggerEvent;
  41. function updateValue(newValue) {
  42. var isControl = hasValue(props.value);
  43. triggerEvent('change', newValue);
  44. if (!isControl) {
  45. setValue(newValue);
  46. }
  47. }
  48. useEvent('clickCell', function (e) {
  49. var time = e.currentTarget.dataset.time;
  50. var clickDate = dayjs(time.time);
  51. if (time.disabled) {
  52. return;
  53. }
  54. if (selectionMode === 'range') {
  55. if (Array.isArray(value)) {
  56. if (value.length === 1) {
  57. var current = value[0];
  58. if (dayjs(clickDate.toDate().getTime()).isBefore(dayjs(current))) {
  59. updateValue([clickDate.toDate().getTime()]);
  60. }
  61. else {
  62. updateValue([value[0], clickDate.toDate().getTime()]);
  63. }
  64. }
  65. else {
  66. updateValue([clickDate.toDate().getTime()]);
  67. }
  68. }
  69. else {
  70. updateValue([clickDate.toDate().getTime()]);
  71. }
  72. }
  73. else if (selectionMode === 'single') {
  74. updateValue(clickDate.toDate().getTime());
  75. }
  76. }, [selectionMode, value]);
  77. var monthList = getMonthListFromRange(dayjs(props.monthRange[0]), dayjs(props.monthRange[1])).map(function (p) {
  78. var cells = renderCells(p, weekStartsOn, value, localeText);
  79. if (props.onFormatter && typeof props.onFormatter === 'function') {
  80. cells = cells.map(function (o) {
  81. var _a;
  82. var time = o.time, top = o.top, bottom = o.bottom, disabled = o.disabled, isSelectedBegin = o.isSelectedBegin, isSelectedEnd = o.isSelectedEnd, isSelected = o.isSelected;
  83. var newState = (_a = props.onFormatter({
  84. time: time,
  85. top: top ? __assign({}, top) : undefined,
  86. bottom: bottom ? __assign({}, bottom) : undefined,
  87. disabled: disabled,
  88. isSelectedBegin: isSelectedBegin,
  89. isSelectedEnd: isSelectedEnd,
  90. isSelected: isSelected,
  91. }, value)) !== null && _a !== void 0 ? _a : {};
  92. var result = __assign({}, o);
  93. if (typeof newState === 'object') {
  94. // 只允许修改三个字段
  95. ['top', 'bottom', 'disabled'].forEach(function (key) {
  96. if (key in newState) {
  97. result[key] = newState[key];
  98. }
  99. });
  100. }
  101. return result;
  102. });
  103. }
  104. return {
  105. title: p.format(localeText.title),
  106. cells: cells,
  107. };
  108. });
  109. var _d = useState(0), headerState = _d[0], setHeaderState = _d[1];
  110. useEvent('setCurrentMonth', function (e) {
  111. setHeaderState(e.month);
  112. }, []);
  113. var _e = useState(null), elementSize = _e[0], setElementSize = _e[1];
  114. var componentInstance = useComponent();
  115. function measurement() {
  116. Promise.all([
  117. getBoundingClientRect(componentInstance, '.ant-calendar-body-container'),
  118. getBoundingClientRect(componentInstance, '.ant-calendar-cells'),
  119. getBoundingClientRect(componentInstance, '.ant-calendar-title-container'),
  120. ])
  121. .then(function (_a) {
  122. var bodyContainer = _a[0], cellContainer = _a[1], Title = _a[2];
  123. // 滚动的时候 top 和 bottom 等尺寸会变
  124. // 所以只能依赖 height 来计算
  125. var paddingHeight = bodyContainer.height - cellContainer.height - Title.height;
  126. var monthTitleHeight = Title.height + paddingHeight;
  127. var cellHight = cellContainer.height / (monthList[0].cells.length / 7);
  128. setElementSize({
  129. monthTitleHeight: monthTitleHeight,
  130. cellHight: cellHight,
  131. paddingHeight: paddingHeight,
  132. });
  133. })
  134. .catch(function () {
  135. setElementSize(null);
  136. });
  137. }
  138. useReady(function () {
  139. measurement();
  140. }, []);
  141. useEvent('measurement', function () {
  142. // 组件如果内嵌在 slot 里, 一定会被渲染出来, 但是此时 cellHight 为 0
  143. // 此时需要重新计算
  144. if (!elementSize || elementSize.cellHight === 0) {
  145. measurement();
  146. }
  147. }, [elementSize]);
  148. return {
  149. elementSize: elementSize,
  150. markItems: markItems,
  151. monthList: monthList,
  152. headerState: headerState,
  153. };
  154. };
  155. mountComponent(Calendar, {
  156. defaultValue: null,
  157. value: null,
  158. selectionMode: 'range',
  159. monthRange: defaultMonthRange(),
  160. weekStartsOn: 'Sunday',
  161. localeText: defaultLocaleText,
  162. onFormatter: null,
  163. });