uiUtil.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import isVisible from '../../vc-util/Dom/isVisible';
  2. import KeyCode from '../../_util/KeyCode';
  3. import raf from '../../_util/raf';
  4. const scrollIds = new Map();
  5. /** Trigger when element is visible in view */
  6. export function waitElementReady(element, callback) {
  7. let id;
  8. function tryOrNextFrame() {
  9. if (isVisible(element)) {
  10. callback();
  11. } else {
  12. id = raf(() => {
  13. tryOrNextFrame();
  14. });
  15. }
  16. }
  17. tryOrNextFrame();
  18. return () => {
  19. raf.cancel(id);
  20. };
  21. }
  22. /* eslint-disable no-param-reassign */
  23. export function scrollTo(element, to, duration) {
  24. if (scrollIds.get(element)) {
  25. raf.cancel(scrollIds.get(element));
  26. }
  27. // jump to target if duration zero
  28. if (duration <= 0) {
  29. scrollIds.set(element, raf(() => {
  30. element.scrollTop = to;
  31. }));
  32. return;
  33. }
  34. const difference = to - element.scrollTop;
  35. const perTick = difference / duration * 10;
  36. scrollIds.set(element, raf(() => {
  37. element.scrollTop += perTick;
  38. if (element.scrollTop !== to) {
  39. scrollTo(element, to, duration - 10);
  40. }
  41. }));
  42. }
  43. export function createKeydownHandler(event, _ref) {
  44. let {
  45. onLeftRight,
  46. onCtrlLeftRight,
  47. onUpDown,
  48. onPageUpDown,
  49. onEnter
  50. } = _ref;
  51. const {
  52. which,
  53. ctrlKey,
  54. metaKey
  55. } = event;
  56. switch (which) {
  57. case KeyCode.LEFT:
  58. if (ctrlKey || metaKey) {
  59. if (onCtrlLeftRight) {
  60. onCtrlLeftRight(-1);
  61. return true;
  62. }
  63. } else if (onLeftRight) {
  64. onLeftRight(-1);
  65. return true;
  66. }
  67. /* istanbul ignore next */
  68. break;
  69. case KeyCode.RIGHT:
  70. if (ctrlKey || metaKey) {
  71. if (onCtrlLeftRight) {
  72. onCtrlLeftRight(1);
  73. return true;
  74. }
  75. } else if (onLeftRight) {
  76. onLeftRight(1);
  77. return true;
  78. }
  79. /* istanbul ignore next */
  80. break;
  81. case KeyCode.UP:
  82. if (onUpDown) {
  83. onUpDown(-1);
  84. return true;
  85. }
  86. /* istanbul ignore next */
  87. break;
  88. case KeyCode.DOWN:
  89. if (onUpDown) {
  90. onUpDown(1);
  91. return true;
  92. }
  93. /* istanbul ignore next */
  94. break;
  95. case KeyCode.PAGE_UP:
  96. if (onPageUpDown) {
  97. onPageUpDown(-1);
  98. return true;
  99. }
  100. /* istanbul ignore next */
  101. break;
  102. case KeyCode.PAGE_DOWN:
  103. if (onPageUpDown) {
  104. onPageUpDown(1);
  105. return true;
  106. }
  107. /* istanbul ignore next */
  108. break;
  109. case KeyCode.ENTER:
  110. if (onEnter) {
  111. onEnter();
  112. return true;
  113. }
  114. /* istanbul ignore next */
  115. break;
  116. }
  117. return false;
  118. }
  119. // ===================== Format =====================
  120. export function getDefaultFormat(format, picker, showTime, use12Hours) {
  121. let mergedFormat = format;
  122. if (!mergedFormat) {
  123. switch (picker) {
  124. case 'time':
  125. mergedFormat = use12Hours ? 'hh:mm:ss a' : 'HH:mm:ss';
  126. break;
  127. case 'week':
  128. mergedFormat = 'gggg-wo';
  129. break;
  130. case 'month':
  131. mergedFormat = 'YYYY-MM';
  132. break;
  133. case 'quarter':
  134. mergedFormat = 'YYYY-[Q]Q';
  135. break;
  136. case 'year':
  137. mergedFormat = 'YYYY';
  138. break;
  139. default:
  140. mergedFormat = showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
  141. }
  142. }
  143. return mergedFormat;
  144. }
  145. export function getInputSize(picker, format, generateConfig) {
  146. const defaultSize = picker === 'time' ? 8 : 10;
  147. const length = typeof format === 'function' ? format(generateConfig.getNow()).length : format.length;
  148. return Math.max(defaultSize, length) + 2;
  149. }
  150. let globalClickFunc = null;
  151. const clickCallbacks = new Set();
  152. export function addGlobalMousedownEvent(callback) {
  153. if (!globalClickFunc && typeof window !== 'undefined' && window.addEventListener) {
  154. globalClickFunc = e => {
  155. // Clone a new list to avoid repeat trigger events
  156. [...clickCallbacks].forEach(queueFunc => {
  157. queueFunc(e);
  158. });
  159. };
  160. window.addEventListener('mousedown', globalClickFunc);
  161. }
  162. clickCallbacks.add(callback);
  163. return () => {
  164. clickCallbacks.delete(callback);
  165. if (clickCallbacks.size === 0) {
  166. window.removeEventListener('mousedown', globalClickFunc);
  167. globalClickFunc = null;
  168. }
  169. };
  170. }
  171. export function getTargetFromEvent(e) {
  172. var _a;
  173. const target = e.target;
  174. // get target if in shadow dom
  175. if (e.composed && target.shadowRoot) {
  176. return ((_a = e.composedPath) === null || _a === void 0 ? void 0 : _a.call(e)[0]) || target;
  177. }
  178. return target;
  179. }
  180. // ====================== Mode ======================
  181. const getYearNextMode = next => {
  182. if (next === 'month' || next === 'date') {
  183. return 'year';
  184. }
  185. return next;
  186. };
  187. const getMonthNextMode = next => {
  188. if (next === 'date') {
  189. return 'month';
  190. }
  191. return next;
  192. };
  193. const getQuarterNextMode = next => {
  194. if (next === 'month' || next === 'date') {
  195. return 'quarter';
  196. }
  197. return next;
  198. };
  199. const getWeekNextMode = next => {
  200. if (next === 'date') {
  201. return 'week';
  202. }
  203. return next;
  204. };
  205. export const PickerModeMap = {
  206. year: getYearNextMode,
  207. month: getMonthNextMode,
  208. quarter: getQuarterNextMode,
  209. week: getWeekNextMode,
  210. time: null,
  211. date: null
  212. };
  213. export function elementsContains(elements, target) {
  214. if (process.env.NODE_ENV === 'test') {
  215. return false;
  216. }
  217. return elements.some(ele => ele && ele.contains(target));
  218. }