use-dialog.mjs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import { getCurrentInstance, ref, computed, watch, nextTick, onMounted } from 'vue';
  2. import { useTimeoutFn, isClient } from '@vueuse/core';
  3. import { isUndefined } from 'lodash-unified';
  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 { UPDATE_MODEL_EVENT } from '../../../constants/event.mjs';
  11. const useDialog = (props, targetRef) => {
  12. var _a;
  13. const instance = getCurrentInstance();
  14. const emit = instance.emit;
  15. const { nextZIndex } = useZIndex();
  16. let lastPosition = "";
  17. const titleId = useId();
  18. const bodyId = useId();
  19. const visible = ref(false);
  20. const closed = ref(false);
  21. const rendered = ref(false);
  22. const zIndex = ref((_a = props.zIndex) != null ? _a : nextZIndex());
  23. let openTimer = void 0;
  24. let closeTimer = void 0;
  25. const namespace = useGlobalConfig("namespace", defaultNamespace);
  26. const style = computed(() => {
  27. const style2 = {};
  28. const varPrefix = `--${namespace.value}-dialog`;
  29. if (!props.fullscreen) {
  30. if (props.top) {
  31. style2[`${varPrefix}-margin-top`] = props.top;
  32. }
  33. if (props.width) {
  34. style2[`${varPrefix}-width`] = addUnit(props.width);
  35. }
  36. }
  37. return style2;
  38. });
  39. const overlayDialogStyle = computed(() => {
  40. if (props.alignCenter) {
  41. return { display: "flex" };
  42. }
  43. return {};
  44. });
  45. function afterEnter() {
  46. emit("opened");
  47. }
  48. function afterLeave() {
  49. emit("closed");
  50. emit(UPDATE_MODEL_EVENT, false);
  51. if (props.destroyOnClose) {
  52. rendered.value = false;
  53. }
  54. }
  55. function beforeLeave() {
  56. emit("close");
  57. }
  58. function open() {
  59. closeTimer == null ? void 0 : closeTimer();
  60. openTimer == null ? void 0 : openTimer();
  61. if (props.openDelay && props.openDelay > 0) {
  62. ({ stop: openTimer } = useTimeoutFn(() => doOpen(), props.openDelay));
  63. } else {
  64. doOpen();
  65. }
  66. }
  67. function close() {
  68. openTimer == null ? void 0 : openTimer();
  69. closeTimer == null ? void 0 : closeTimer();
  70. if (props.closeDelay && props.closeDelay > 0) {
  71. ({ stop: closeTimer } = useTimeoutFn(() => doClose(), props.closeDelay));
  72. } else {
  73. doClose();
  74. }
  75. }
  76. function handleClose() {
  77. function hide(shouldCancel) {
  78. if (shouldCancel)
  79. return;
  80. closed.value = true;
  81. visible.value = false;
  82. }
  83. if (props.beforeClose) {
  84. props.beforeClose(hide);
  85. } else {
  86. close();
  87. }
  88. }
  89. function onModalClick() {
  90. if (props.closeOnClickModal) {
  91. handleClose();
  92. }
  93. }
  94. function doOpen() {
  95. if (!isClient)
  96. return;
  97. visible.value = true;
  98. }
  99. function doClose() {
  100. visible.value = false;
  101. }
  102. function onOpenAutoFocus() {
  103. emit("openAutoFocus");
  104. }
  105. function onCloseAutoFocus() {
  106. emit("closeAutoFocus");
  107. }
  108. function onFocusoutPrevented(event) {
  109. var _a2;
  110. if (((_a2 = event.detail) == null ? void 0 : _a2.focusReason) === "pointer") {
  111. event.preventDefault();
  112. }
  113. }
  114. if (props.lockScroll) {
  115. useLockscreen(visible);
  116. }
  117. function onCloseRequested() {
  118. if (props.closeOnPressEscape) {
  119. handleClose();
  120. }
  121. }
  122. watch(() => props.modelValue, (val) => {
  123. if (val) {
  124. closed.value = false;
  125. open();
  126. rendered.value = true;
  127. zIndex.value = isUndefined(props.zIndex) ? nextZIndex() : zIndex.value++;
  128. nextTick(() => {
  129. emit("open");
  130. if (targetRef.value) {
  131. targetRef.value.parentElement.scrollTop = 0;
  132. targetRef.value.parentElement.scrollLeft = 0;
  133. targetRef.value.scrollTop = 0;
  134. }
  135. });
  136. } else {
  137. if (visible.value) {
  138. close();
  139. }
  140. }
  141. });
  142. watch(() => props.fullscreen, (val) => {
  143. if (!targetRef.value)
  144. return;
  145. if (val) {
  146. lastPosition = targetRef.value.style.transform;
  147. targetRef.value.style.transform = "";
  148. } else {
  149. targetRef.value.style.transform = lastPosition;
  150. }
  151. });
  152. onMounted(() => {
  153. if (props.modelValue) {
  154. visible.value = true;
  155. rendered.value = true;
  156. open();
  157. }
  158. });
  159. return {
  160. afterEnter,
  161. afterLeave,
  162. beforeLeave,
  163. handleClose,
  164. onModalClick,
  165. close,
  166. doClose,
  167. onOpenAutoFocus,
  168. onCloseAutoFocus,
  169. onCloseRequested,
  170. onFocusoutPrevented,
  171. titleId,
  172. bodyId,
  173. closed,
  174. style,
  175. overlayDialogStyle,
  176. rendered,
  177. visible,
  178. zIndex
  179. };
  180. };
  181. export { useDialog };
  182. //# sourceMappingURL=use-dialog.mjs.map