Dialog.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import { resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue";
  3. import { defineComponent, onBeforeUnmount, ref, watch, watchEffect } from 'vue';
  4. import contains from '../vc-util/Dom/contains';
  5. import classNames from '../_util/classNames';
  6. import KeyCode from '../_util/KeyCode';
  7. import omit from '../_util/omit';
  8. import pickAttrs from '../_util/pickAttrs';
  9. import { initDefaultProps } from '../_util/props-util';
  10. import Content from './Content';
  11. import dialogPropTypes from './IDialogPropTypes';
  12. import Mask from './Mask';
  13. import { getMotionName, getUUID } from './util';
  14. export default defineComponent({
  15. compatConfig: {
  16. MODE: 3
  17. },
  18. name: 'Dialog',
  19. inheritAttrs: false,
  20. props: initDefaultProps(_objectSpread(_objectSpread({}, dialogPropTypes()), {}, {
  21. getOpenCount: Function,
  22. scrollLocker: Object
  23. }), {
  24. mask: true,
  25. visible: false,
  26. keyboard: true,
  27. closable: true,
  28. maskClosable: true,
  29. destroyOnClose: false,
  30. prefixCls: 'rc-dialog',
  31. getOpenCount: function getOpenCount() {
  32. return null;
  33. },
  34. focusTriggerAfterClose: true
  35. }),
  36. setup: function setup(props, _ref) {
  37. var attrs = _ref.attrs,
  38. slots = _ref.slots;
  39. var lastOutSideActiveElementRef = ref();
  40. var wrapperRef = ref();
  41. var contentRef = ref();
  42. var animatedVisible = ref(props.visible);
  43. var ariaIdRef = ref("vcDialogTitle".concat(getUUID()));
  44. // ========================= Events =========================
  45. var onDialogVisibleChanged = function onDialogVisibleChanged(newVisible) {
  46. if (newVisible) {
  47. // Try to focus
  48. if (!contains(wrapperRef.value, document.activeElement)) {
  49. var _contentRef$value;
  50. lastOutSideActiveElementRef.value = document.activeElement;
  51. (_contentRef$value = contentRef.value) === null || _contentRef$value === void 0 ? void 0 : _contentRef$value.focus();
  52. }
  53. } else {
  54. var preAnimatedVisible = animatedVisible.value;
  55. // Clean up scroll bar & focus back
  56. animatedVisible.value = false;
  57. if (props.mask && lastOutSideActiveElementRef.value && props.focusTriggerAfterClose) {
  58. try {
  59. lastOutSideActiveElementRef.value.focus({
  60. preventScroll: true
  61. });
  62. } catch (e) {
  63. // Do nothing
  64. }
  65. lastOutSideActiveElementRef.value = null;
  66. }
  67. // Trigger afterClose only when change visible from true to false
  68. if (preAnimatedVisible) {
  69. var _props$afterClose;
  70. (_props$afterClose = props.afterClose) === null || _props$afterClose === void 0 ? void 0 : _props$afterClose.call(props);
  71. }
  72. }
  73. };
  74. var onInternalClose = function onInternalClose(e) {
  75. var _props$onClose;
  76. (_props$onClose = props.onClose) === null || _props$onClose === void 0 ? void 0 : _props$onClose.call(props, e);
  77. };
  78. // >>> Content
  79. var contentClickRef = ref(false);
  80. var contentTimeoutRef = ref();
  81. // We need record content click incase content popup out of dialog
  82. var onContentMouseDown = function onContentMouseDown() {
  83. clearTimeout(contentTimeoutRef.value);
  84. contentClickRef.value = true;
  85. };
  86. var onContentMouseUp = function onContentMouseUp() {
  87. contentTimeoutRef.value = setTimeout(function () {
  88. contentClickRef.value = false;
  89. });
  90. };
  91. var onWrapperClick = function onWrapperClick(e) {
  92. if (!props.maskClosable) return null;
  93. if (contentClickRef.value) {
  94. contentClickRef.value = false;
  95. } else if (wrapperRef.value === e.target) {
  96. onInternalClose(e);
  97. }
  98. };
  99. var onWrapperKeyDown = function onWrapperKeyDown(e) {
  100. if (props.keyboard && e.keyCode === KeyCode.ESC) {
  101. e.stopPropagation();
  102. onInternalClose(e);
  103. return;
  104. }
  105. // keep focus inside dialog
  106. if (props.visible) {
  107. if (e.keyCode === KeyCode.TAB) {
  108. contentRef.value.changeActive(!e.shiftKey);
  109. }
  110. }
  111. };
  112. watch(function () {
  113. return props.visible;
  114. }, function () {
  115. if (props.visible) {
  116. animatedVisible.value = true;
  117. }
  118. }, {
  119. flush: 'post'
  120. });
  121. onBeforeUnmount(function () {
  122. var _props$scrollLocker;
  123. clearTimeout(contentTimeoutRef.value);
  124. (_props$scrollLocker = props.scrollLocker) === null || _props$scrollLocker === void 0 ? void 0 : _props$scrollLocker.unLock();
  125. });
  126. watchEffect(function () {
  127. var _props$scrollLocker2;
  128. (_props$scrollLocker2 = props.scrollLocker) === null || _props$scrollLocker2 === void 0 ? void 0 : _props$scrollLocker2.unLock();
  129. if (animatedVisible.value) {
  130. var _props$scrollLocker3;
  131. (_props$scrollLocker3 = props.scrollLocker) === null || _props$scrollLocker3 === void 0 ? void 0 : _props$scrollLocker3.lock();
  132. }
  133. });
  134. return function () {
  135. var prefixCls = props.prefixCls,
  136. mask = props.mask,
  137. visible = props.visible,
  138. maskTransitionName = props.maskTransitionName,
  139. maskAnimation = props.maskAnimation,
  140. zIndex = props.zIndex,
  141. wrapClassName = props.wrapClassName,
  142. rootClassName = props.rootClassName,
  143. wrapStyle = props.wrapStyle,
  144. closable = props.closable,
  145. maskProps = props.maskProps,
  146. maskStyle = props.maskStyle,
  147. transitionName = props.transitionName,
  148. animation = props.animation,
  149. wrapProps = props.wrapProps,
  150. _props$title = props.title,
  151. title = _props$title === void 0 ? slots.title : _props$title;
  152. var style = attrs.style,
  153. className = attrs.class;
  154. return _createVNode("div", _objectSpread({
  155. "class": ["".concat(prefixCls, "-root"), rootClassName]
  156. }, pickAttrs(props, {
  157. data: true
  158. })), [_createVNode(Mask, {
  159. "prefixCls": prefixCls,
  160. "visible": mask && visible,
  161. "motionName": getMotionName(prefixCls, maskTransitionName, maskAnimation),
  162. "style": _objectSpread({
  163. zIndex: zIndex
  164. }, maskStyle),
  165. "maskProps": maskProps
  166. }, null), _createVNode("div", _objectSpread({
  167. "tabIndex": -1,
  168. "onKeydown": onWrapperKeyDown,
  169. "class": classNames("".concat(prefixCls, "-wrap"), wrapClassName),
  170. "ref": wrapperRef,
  171. "onClick": onWrapperClick,
  172. "role": "dialog",
  173. "aria-labelledby": title ? ariaIdRef.value : null,
  174. "style": _objectSpread(_objectSpread({
  175. zIndex: zIndex
  176. }, wrapStyle), {}, {
  177. display: !animatedVisible.value ? 'none' : null
  178. })
  179. }, wrapProps), [_createVNode(Content, _objectSpread(_objectSpread({}, omit(props, ['scrollLocker'])), {}, {
  180. "style": style,
  181. "class": className,
  182. "onMousedown": onContentMouseDown,
  183. "onMouseup": onContentMouseUp,
  184. "ref": contentRef,
  185. "closable": closable,
  186. "ariaId": ariaIdRef.value,
  187. "prefixCls": prefixCls,
  188. "visible": visible,
  189. "onClose": onInternalClose,
  190. "onVisibleChanged": onDialogVisibleChanged,
  191. "motionName": getMotionName(prefixCls, transitionName, animation)
  192. }), slots)])]);
  193. };
  194. }
  195. });