index.js 7.1 KB

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