use-dialog.mjs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. import { getCurrentInstance, ref, computed, watch, nextTick, onMounted } from 'vue';
  2. import { useTimeoutFn, isClient } from '@vueuse/core';
  3. import { DEFAULT_DIALOG_TRANSITION } from './constants.mjs';
  4. import { useLockscreen } from '../../../hooks/use-lockscreen/index.mjs';
  5. import { useZIndex } from '../../../hooks/use-z-index/index.mjs';
  6. import { useId } from '../../../hooks/use-id/index.mjs';
  7. import { useGlobalConfig } from '../../config-provider/src/hooks/use-global-config.mjs';
  8. import { defaultNamespace } from '../../../hooks/use-namespace/index.mjs';
  9. import { addUnit } from '../../../utils/dom/style.mjs';
  10. import { isObject, isArray, isFunction } from '@vue/shared';
  11. import { debugWarn } from '../../../utils/error.mjs';
  12. import { UPDATE_MODEL_EVENT } from '../../../constants/event.mjs';
  13. const COMPONENT_NAME = "ElDialog";
  14. const useDialog = (props, targetRef) => {
  15. var _a;
  16. const instance = getCurrentInstance();
  17. const emit = instance.emit;
  18. const { nextZIndex } = useZIndex();
  19. let lastPosition = "";
  20. const titleId = useId();
  21. const bodyId = useId();
  22. const visible = ref(false);
  23. const closed = ref(false);
  24. const rendered = ref(false);
  25. const zIndex = ref((_a = props.zIndex) != null ? _a : nextZIndex());
  26. const closing = ref(false);
  27. let openTimer = void 0;
  28. let closeTimer = void 0;
  29. const config = useGlobalConfig();
  30. const namespace = computed(() => {
  31. var _a2, _b;
  32. return (_b = (_a2 = config.value) == null ? void 0 : _a2.namespace) != null ? _b : defaultNamespace;
  33. });
  34. const globalConfig = computed(() => {
  35. var _a2;
  36. return (_a2 = config.value) == null ? void 0 : _a2.dialog;
  37. });
  38. const style = computed(() => {
  39. const style2 = {};
  40. const varPrefix = `--${namespace.value}-dialog`;
  41. if (!props.fullscreen) {
  42. if (props.top) {
  43. style2[`${varPrefix}-margin-top`] = props.top;
  44. }
  45. const width = addUnit(props.width);
  46. if (width) {
  47. style2[`${varPrefix}-width`] = width;
  48. }
  49. }
  50. return style2;
  51. });
  52. const _draggable = computed(
  53. () => {
  54. var _a2, _b, _c;
  55. return ((_c = (_b = props.draggable) != null ? _b : (_a2 = globalConfig.value) == null ? void 0 : _a2.draggable) != null ? _c : false) && !props.fullscreen;
  56. }
  57. );
  58. const _alignCenter = computed(
  59. () => {
  60. var _a2, _b, _c;
  61. return (_c = (_b = props.alignCenter) != null ? _b : (_a2 = globalConfig.value) == null ? void 0 : _a2.alignCenter) != null ? _c : false;
  62. }
  63. );
  64. const _overflow = computed(
  65. () => {
  66. var _a2, _b, _c;
  67. return (_c = (_b = props.overflow) != null ? _b : (_a2 = globalConfig.value) == null ? void 0 : _a2.overflow) != null ? _c : false;
  68. }
  69. );
  70. const overlayDialogStyle = computed(() => {
  71. if (_alignCenter.value) {
  72. return { display: "flex" };
  73. }
  74. return {};
  75. });
  76. const transitionConfig = computed(() => {
  77. var _a2, _b, _c;
  78. const transition = (_c = (_b = props.transition) != null ? _b : (_a2 = globalConfig.value) == null ? void 0 : _a2.transition) != null ? _c : DEFAULT_DIALOG_TRANSITION;
  79. const baseConfig = {
  80. name: transition,
  81. onAfterEnter: afterEnter,
  82. onBeforeLeave: beforeLeave,
  83. onAfterLeave: afterLeave
  84. };
  85. if (isObject(transition)) {
  86. const config2 = { ...transition };
  87. const _mergeHook = (userHook, defaultHook) => {
  88. return (el) => {
  89. if (isArray(userHook)) {
  90. userHook.forEach((fn) => {
  91. if (isFunction(fn))
  92. fn(el);
  93. });
  94. } else if (isFunction(userHook)) {
  95. userHook(el);
  96. }
  97. defaultHook();
  98. };
  99. };
  100. config2.onAfterEnter = _mergeHook(config2.onAfterEnter, afterEnter);
  101. config2.onBeforeLeave = _mergeHook(config2.onBeforeLeave, beforeLeave);
  102. config2.onAfterLeave = _mergeHook(config2.onAfterLeave, afterLeave);
  103. if (!config2.name) {
  104. config2.name = DEFAULT_DIALOG_TRANSITION;
  105. debugWarn(
  106. COMPONENT_NAME,
  107. `transition.name is missing when using object syntax, fallback to '${DEFAULT_DIALOG_TRANSITION}'`
  108. );
  109. }
  110. return config2;
  111. }
  112. return baseConfig;
  113. });
  114. function afterEnter() {
  115. emit("opened");
  116. }
  117. function afterLeave() {
  118. emit("closed");
  119. emit(UPDATE_MODEL_EVENT, false);
  120. if (props.destroyOnClose) {
  121. rendered.value = false;
  122. }
  123. closing.value = false;
  124. }
  125. function beforeLeave() {
  126. closing.value = true;
  127. emit("close");
  128. }
  129. function open() {
  130. closeTimer == null ? void 0 : closeTimer();
  131. openTimer == null ? void 0 : openTimer();
  132. if (props.openDelay && props.openDelay > 0) {
  133. ({ stop: openTimer } = useTimeoutFn(() => doOpen(), props.openDelay));
  134. } else {
  135. doOpen();
  136. }
  137. }
  138. function close() {
  139. openTimer == null ? void 0 : openTimer();
  140. closeTimer == null ? void 0 : closeTimer();
  141. if (props.closeDelay && props.closeDelay > 0) {
  142. ({ stop: closeTimer } = useTimeoutFn(() => doClose(), props.closeDelay));
  143. } else {
  144. doClose();
  145. }
  146. }
  147. function handleClose() {
  148. function hide(shouldCancel) {
  149. if (shouldCancel)
  150. return;
  151. closed.value = true;
  152. visible.value = false;
  153. }
  154. if (props.beforeClose) {
  155. props.beforeClose(hide);
  156. } else {
  157. close();
  158. }
  159. }
  160. function onModalClick() {
  161. if (props.closeOnClickModal) {
  162. handleClose();
  163. }
  164. }
  165. function doOpen() {
  166. if (!isClient)
  167. return;
  168. visible.value = true;
  169. }
  170. function doClose() {
  171. visible.value = false;
  172. }
  173. function onOpenAutoFocus() {
  174. emit("openAutoFocus");
  175. }
  176. function onCloseAutoFocus() {
  177. emit("closeAutoFocus");
  178. }
  179. function onFocusoutPrevented(event) {
  180. var _a2;
  181. if (((_a2 = event.detail) == null ? void 0 : _a2.focusReason) === "pointer") {
  182. event.preventDefault();
  183. }
  184. }
  185. if (props.lockScroll) {
  186. useLockscreen(visible);
  187. }
  188. function onCloseRequested() {
  189. if (props.closeOnPressEscape) {
  190. handleClose();
  191. }
  192. }
  193. watch(
  194. () => props.zIndex,
  195. () => {
  196. var _a2;
  197. zIndex.value = (_a2 = props.zIndex) != null ? _a2 : nextZIndex();
  198. }
  199. );
  200. watch(
  201. () => props.modelValue,
  202. (val) => {
  203. var _a2;
  204. if (val) {
  205. closed.value = false;
  206. closing.value = false;
  207. open();
  208. rendered.value = true;
  209. zIndex.value = (_a2 = props.zIndex) != null ? _a2 : nextZIndex();
  210. nextTick(() => {
  211. emit("open");
  212. if (targetRef.value) {
  213. targetRef.value.parentElement.scrollTop = 0;
  214. targetRef.value.parentElement.scrollLeft = 0;
  215. targetRef.value.scrollTop = 0;
  216. }
  217. });
  218. } else {
  219. if (visible.value) {
  220. close();
  221. }
  222. }
  223. }
  224. );
  225. watch(
  226. () => props.fullscreen,
  227. (val) => {
  228. if (!targetRef.value)
  229. return;
  230. if (val) {
  231. lastPosition = targetRef.value.style.transform;
  232. targetRef.value.style.transform = "";
  233. } else {
  234. targetRef.value.style.transform = lastPosition;
  235. }
  236. }
  237. );
  238. onMounted(() => {
  239. if (props.modelValue) {
  240. visible.value = true;
  241. rendered.value = true;
  242. open();
  243. }
  244. });
  245. return {
  246. afterEnter,
  247. afterLeave,
  248. beforeLeave,
  249. handleClose,
  250. onModalClick,
  251. close,
  252. doClose,
  253. onOpenAutoFocus,
  254. onCloseAutoFocus,
  255. onCloseRequested,
  256. onFocusoutPrevented,
  257. titleId,
  258. bodyId,
  259. closed,
  260. style,
  261. overlayDialogStyle,
  262. rendered,
  263. visible,
  264. zIndex,
  265. transitionConfig,
  266. _draggable,
  267. _alignCenter,
  268. _overflow,
  269. closing
  270. };
  271. };
  272. export { useDialog };
  273. //# sourceMappingURL=use-dialog.mjs.map