Align.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = exports.alignProps = void 0;
  7. var _vue = require("vue");
  8. var _domAlign = require("dom-align");
  9. var _addEventListener = _interopRequireDefault(require("../vc-util/Dom/addEventListener"));
  10. var _vnode = require("../_util/vnode");
  11. var _isVisible = _interopRequireDefault(require("../vc-util/Dom/isVisible"));
  12. var _util = require("./util");
  13. var _useBuffer = _interopRequireDefault(require("./hooks/useBuffer"));
  14. var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
  15. const alignProps = exports.alignProps = {
  16. align: Object,
  17. target: [Object, Function],
  18. onAlign: Function,
  19. monitorBufferTime: Number,
  20. monitorWindowResize: Boolean,
  21. disabled: Boolean
  22. };
  23. function getElement(func) {
  24. if (typeof func !== 'function') return null;
  25. return func();
  26. }
  27. function getPoint(point) {
  28. if (typeof point !== 'object' || !point) return null;
  29. return point;
  30. }
  31. var _default = exports.default = (0, _vue.defineComponent)({
  32. compatConfig: {
  33. MODE: 3
  34. },
  35. name: 'Align',
  36. props: alignProps,
  37. emits: ['align'],
  38. setup(props, _ref) {
  39. let {
  40. expose,
  41. slots
  42. } = _ref;
  43. const cacheRef = (0, _vue.ref)({});
  44. const nodeRef = (0, _vue.ref)();
  45. const [forceAlign, cancelForceAlign] = (0, _useBuffer.default)(() => {
  46. const {
  47. disabled: latestDisabled,
  48. target: latestTarget,
  49. align: latestAlign,
  50. onAlign: latestOnAlign
  51. } = props;
  52. if (!latestDisabled && latestTarget && nodeRef.value) {
  53. const source = nodeRef.value;
  54. let result;
  55. const element = getElement(latestTarget);
  56. const point = getPoint(latestTarget);
  57. cacheRef.value.element = element;
  58. cacheRef.value.point = point;
  59. cacheRef.value.align = latestAlign;
  60. // IE lose focus after element realign
  61. // We should record activeElement and restore later
  62. const {
  63. activeElement
  64. } = document;
  65. // We only align when element is visible
  66. if (element && (0, _isVisible.default)(element)) {
  67. result = (0, _domAlign.alignElement)(source, element, latestAlign);
  68. } else if (point) {
  69. result = (0, _domAlign.alignPoint)(source, point, latestAlign);
  70. }
  71. (0, _util.restoreFocus)(activeElement, source);
  72. if (latestOnAlign && result) {
  73. latestOnAlign(source, result);
  74. }
  75. return true;
  76. }
  77. return false;
  78. }, (0, _vue.computed)(() => props.monitorBufferTime));
  79. // ===================== Effect =====================
  80. // Listen for target updated
  81. const resizeMonitor = (0, _vue.ref)({
  82. cancel: () => {}
  83. });
  84. // Listen for source updated
  85. const sourceResizeMonitor = (0, _vue.ref)({
  86. cancel: () => {}
  87. });
  88. const goAlign = () => {
  89. const target = props.target;
  90. const element = getElement(target);
  91. const point = getPoint(target);
  92. if (nodeRef.value !== sourceResizeMonitor.value.element) {
  93. sourceResizeMonitor.value.cancel();
  94. sourceResizeMonitor.value.element = nodeRef.value;
  95. sourceResizeMonitor.value.cancel = (0, _util.monitorResize)(nodeRef.value, forceAlign);
  96. }
  97. if (cacheRef.value.element !== element || !(0, _util.isSamePoint)(cacheRef.value.point, point) || !(0, _isEqual.default)(cacheRef.value.align, props.align)) {
  98. forceAlign();
  99. // Add resize observer
  100. if (resizeMonitor.value.element !== element) {
  101. resizeMonitor.value.cancel();
  102. resizeMonitor.value.element = element;
  103. resizeMonitor.value.cancel = (0, _util.monitorResize)(element, forceAlign);
  104. }
  105. }
  106. };
  107. (0, _vue.onMounted)(() => {
  108. (0, _vue.nextTick)(() => {
  109. goAlign();
  110. });
  111. });
  112. (0, _vue.onUpdated)(() => {
  113. (0, _vue.nextTick)(() => {
  114. goAlign();
  115. });
  116. });
  117. // Listen for disabled change
  118. (0, _vue.watch)(() => props.disabled, disabled => {
  119. if (!disabled) {
  120. forceAlign();
  121. } else {
  122. cancelForceAlign();
  123. }
  124. }, {
  125. immediate: true,
  126. flush: 'post'
  127. });
  128. // Listen for window resize
  129. const winResizeRef = (0, _vue.ref)(null);
  130. (0, _vue.watch)(() => props.monitorWindowResize, monitorWindowResize => {
  131. if (monitorWindowResize) {
  132. if (!winResizeRef.value) {
  133. winResizeRef.value = (0, _addEventListener.default)(window, 'resize', forceAlign);
  134. }
  135. } else if (winResizeRef.value) {
  136. winResizeRef.value.remove();
  137. winResizeRef.value = null;
  138. }
  139. }, {
  140. flush: 'post'
  141. });
  142. (0, _vue.onUnmounted)(() => {
  143. resizeMonitor.value.cancel();
  144. sourceResizeMonitor.value.cancel();
  145. if (winResizeRef.value) winResizeRef.value.remove();
  146. cancelForceAlign();
  147. });
  148. expose({
  149. forceAlign: () => forceAlign(true)
  150. });
  151. return () => {
  152. const child = slots === null || slots === void 0 ? void 0 : slots.default();
  153. if (child) {
  154. return (0, _vnode.cloneElement)(child[0], {
  155. ref: nodeRef
  156. }, true, true);
  157. }
  158. return null;
  159. };
  160. }
  161. });