index.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var vue = require('vue');
  4. var index$1 = require('../../button/index.js');
  5. var index$2 = require('../../input/index.js');
  6. var index$3 = require('../../overlay/index.js');
  7. var index$4 = require('../../icon/index.js');
  8. var iconsVue = require('@element-plus/icons-vue');
  9. var focusTrap = require('../../focus-trap/src/focus-trap.js');
  10. var pluginVue_exportHelper = require('../../../_virtual/plugin-vue_export-helper.js');
  11. var index = require('../../../directives/trap-focus/index.js');
  12. var icon = require('../../../utils/vue/icon.js');
  13. var validator = require('../../../utils/vue/validator.js');
  14. var useGlobalConfig = require('../../config-provider/src/hooks/use-global-config.js');
  15. var index$5 = require('../../../hooks/use-id/index.js');
  16. var index$6 = require('../../../hooks/use-draggable/index.js');
  17. var shared = require('@vue/shared');
  18. var index$7 = require('../../../hooks/use-lockscreen/index.js');
  19. var index$8 = require('../../../hooks/use-same-target/index.js');
  20. const _sfc_main = vue.defineComponent({
  21. name: "ElMessageBox",
  22. directives: {
  23. TrapFocus: index["default"]
  24. },
  25. components: {
  26. ElButton: index$1.ElButton,
  27. ElFocusTrap: focusTrap["default"],
  28. ElInput: index$2.ElInput,
  29. ElOverlay: index$3.ElOverlay,
  30. ElIcon: index$4.ElIcon,
  31. ...icon.TypeComponents
  32. },
  33. inheritAttrs: false,
  34. props: {
  35. buttonSize: {
  36. type: String,
  37. validator: validator.isValidComponentSize
  38. },
  39. modal: {
  40. type: Boolean,
  41. default: true
  42. },
  43. lockScroll: {
  44. type: Boolean,
  45. default: true
  46. },
  47. showClose: {
  48. type: Boolean,
  49. default: true
  50. },
  51. closeOnClickModal: {
  52. type: Boolean,
  53. default: true
  54. },
  55. closeOnPressEscape: {
  56. type: Boolean,
  57. default: true
  58. },
  59. closeOnHashChange: {
  60. type: Boolean,
  61. default: true
  62. },
  63. center: Boolean,
  64. draggable: Boolean,
  65. overflow: Boolean,
  66. roundButton: {
  67. default: false,
  68. type: Boolean
  69. },
  70. container: {
  71. type: String,
  72. default: "body"
  73. },
  74. boxType: {
  75. type: String,
  76. default: ""
  77. }
  78. },
  79. emits: ["vanish", "action"],
  80. setup(props, { emit }) {
  81. const {
  82. locale,
  83. zIndex,
  84. ns,
  85. size: btnSize
  86. } = useGlobalConfig.useGlobalComponentSettings("message-box", vue.computed(() => props.buttonSize));
  87. const { t } = locale;
  88. const { nextZIndex } = zIndex;
  89. const visible = vue.ref(false);
  90. const state = vue.reactive({
  91. autofocus: true,
  92. beforeClose: null,
  93. callback: null,
  94. cancelButtonText: "",
  95. cancelButtonClass: "",
  96. confirmButtonText: "",
  97. confirmButtonClass: "",
  98. customClass: "",
  99. customStyle: {},
  100. dangerouslyUseHTMLString: false,
  101. distinguishCancelAndClose: false,
  102. icon: "",
  103. closeIcon: "",
  104. inputPattern: null,
  105. inputPlaceholder: "",
  106. inputType: "text",
  107. inputValue: "",
  108. inputValidator: void 0,
  109. inputErrorMessage: "",
  110. message: "",
  111. modalFade: true,
  112. modalClass: "",
  113. showCancelButton: false,
  114. showConfirmButton: true,
  115. type: "",
  116. title: void 0,
  117. showInput: false,
  118. action: "",
  119. confirmButtonLoading: false,
  120. cancelButtonLoading: false,
  121. confirmButtonLoadingIcon: vue.markRaw(iconsVue.Loading),
  122. cancelButtonLoadingIcon: vue.markRaw(iconsVue.Loading),
  123. confirmButtonDisabled: false,
  124. editorErrorMessage: "",
  125. validateError: false,
  126. zIndex: nextZIndex()
  127. });
  128. const typeClass = vue.computed(() => {
  129. const type = state.type;
  130. return { [ns.bm("icon", type)]: type && icon.TypeComponentsMap[type] };
  131. });
  132. const contentId = index$5.useId();
  133. const inputId = index$5.useId();
  134. const iconComponent = vue.computed(() => {
  135. const type = state.type;
  136. return state.icon || type && icon.TypeComponentsMap[type] || "";
  137. });
  138. const hasMessage = vue.computed(() => !!state.message);
  139. const rootRef = vue.ref();
  140. const headerRef = vue.ref();
  141. const focusStartRef = vue.ref();
  142. const inputRef = vue.ref();
  143. const confirmRef = vue.ref();
  144. const confirmButtonClasses = vue.computed(() => state.confirmButtonClass);
  145. vue.watch(() => state.inputValue, async (val) => {
  146. await vue.nextTick();
  147. if (props.boxType === "prompt" && val) {
  148. validate();
  149. }
  150. }, { immediate: true });
  151. vue.watch(() => visible.value, (val) => {
  152. var _a, _b;
  153. if (val) {
  154. if (props.boxType !== "prompt") {
  155. if (state.autofocus) {
  156. focusStartRef.value = (_b = (_a = confirmRef.value) == null ? void 0 : _a.$el) != null ? _b : rootRef.value;
  157. } else {
  158. focusStartRef.value = rootRef.value;
  159. }
  160. }
  161. state.zIndex = nextZIndex();
  162. }
  163. if (props.boxType !== "prompt")
  164. return;
  165. if (val) {
  166. vue.nextTick().then(() => {
  167. var _a2;
  168. if (inputRef.value && inputRef.value.$el) {
  169. if (state.autofocus) {
  170. focusStartRef.value = (_a2 = getInputElement()) != null ? _a2 : rootRef.value;
  171. } else {
  172. focusStartRef.value = rootRef.value;
  173. }
  174. }
  175. });
  176. } else {
  177. state.editorErrorMessage = "";
  178. state.validateError = false;
  179. }
  180. });
  181. const draggable = vue.computed(() => props.draggable);
  182. const overflow = vue.computed(() => props.overflow);
  183. index$6.useDraggable(rootRef, headerRef, draggable, overflow);
  184. vue.onMounted(async () => {
  185. await vue.nextTick();
  186. if (props.closeOnHashChange) {
  187. window.addEventListener("hashchange", doClose);
  188. }
  189. });
  190. vue.onBeforeUnmount(() => {
  191. if (props.closeOnHashChange) {
  192. window.removeEventListener("hashchange", doClose);
  193. }
  194. });
  195. function doClose() {
  196. if (!visible.value)
  197. return;
  198. visible.value = false;
  199. vue.nextTick(() => {
  200. if (state.action)
  201. emit("action", state.action);
  202. });
  203. }
  204. const handleWrapperClick = () => {
  205. if (props.closeOnClickModal) {
  206. handleAction(state.distinguishCancelAndClose ? "close" : "cancel");
  207. }
  208. };
  209. const overlayEvent = index$8.useSameTarget(handleWrapperClick);
  210. const handleInputEnter = (e) => {
  211. if (state.inputType !== "textarea") {
  212. e.preventDefault();
  213. return handleAction("confirm");
  214. }
  215. };
  216. const handleAction = (action) => {
  217. var _a;
  218. if (props.boxType === "prompt" && action === "confirm" && !validate()) {
  219. return;
  220. }
  221. state.action = action;
  222. if (state.beforeClose) {
  223. (_a = state.beforeClose) == null ? void 0 : _a.call(state, action, state, doClose);
  224. } else {
  225. doClose();
  226. }
  227. };
  228. const validate = () => {
  229. if (props.boxType === "prompt") {
  230. const inputPattern = state.inputPattern;
  231. if (inputPattern && !inputPattern.test(state.inputValue || "")) {
  232. state.editorErrorMessage = state.inputErrorMessage || t("el.messagebox.error");
  233. state.validateError = true;
  234. return false;
  235. }
  236. const inputValidator = state.inputValidator;
  237. if (shared.isFunction(inputValidator)) {
  238. const validateResult = inputValidator(state.inputValue);
  239. if (validateResult === false) {
  240. state.editorErrorMessage = state.inputErrorMessage || t("el.messagebox.error");
  241. state.validateError = true;
  242. return false;
  243. }
  244. if (shared.isString(validateResult)) {
  245. state.editorErrorMessage = validateResult;
  246. state.validateError = true;
  247. return false;
  248. }
  249. }
  250. }
  251. state.editorErrorMessage = "";
  252. state.validateError = false;
  253. return true;
  254. };
  255. const getInputElement = () => {
  256. var _a, _b;
  257. const inputRefs = (_a = inputRef.value) == null ? void 0 : _a.$refs;
  258. return (_b = inputRefs == null ? void 0 : inputRefs.input) != null ? _b : inputRefs == null ? void 0 : inputRefs.textarea;
  259. };
  260. const handleClose = () => {
  261. handleAction("close");
  262. };
  263. const onCloseRequested = () => {
  264. if (props.closeOnPressEscape) {
  265. handleClose();
  266. }
  267. };
  268. if (props.lockScroll) {
  269. index$7.useLockscreen(visible);
  270. }
  271. return {
  272. ...vue.toRefs(state),
  273. ns,
  274. overlayEvent,
  275. visible,
  276. hasMessage,
  277. typeClass,
  278. contentId,
  279. inputId,
  280. btnSize,
  281. iconComponent,
  282. confirmButtonClasses,
  283. rootRef,
  284. focusStartRef,
  285. headerRef,
  286. inputRef,
  287. confirmRef,
  288. doClose,
  289. handleClose,
  290. onCloseRequested,
  291. handleWrapperClick,
  292. handleInputEnter,
  293. handleAction,
  294. t
  295. };
  296. }
  297. });
  298. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  299. const _component_el_icon = vue.resolveComponent("el-icon");
  300. const _component_el_input = vue.resolveComponent("el-input");
  301. const _component_el_button = vue.resolveComponent("el-button");
  302. const _component_el_focus_trap = vue.resolveComponent("el-focus-trap");
  303. const _component_el_overlay = vue.resolveComponent("el-overlay");
  304. return vue.openBlock(), vue.createBlock(vue.Transition, {
  305. name: "fade-in-linear",
  306. onAfterLeave: ($event) => _ctx.$emit("vanish"),
  307. persisted: ""
  308. }, {
  309. default: vue.withCtx(() => [
  310. vue.withDirectives(vue.createVNode(_component_el_overlay, {
  311. "z-index": _ctx.zIndex,
  312. "overlay-class": [_ctx.ns.is("message-box"), _ctx.modalClass],
  313. mask: _ctx.modal
  314. }, {
  315. default: vue.withCtx(() => [
  316. vue.createElementVNode("div", {
  317. role: "dialog",
  318. "aria-label": _ctx.title,
  319. "aria-modal": "true",
  320. "aria-describedby": !_ctx.showInput ? _ctx.contentId : void 0,
  321. class: vue.normalizeClass(`${_ctx.ns.namespace.value}-overlay-message-box`),
  322. onClick: _ctx.overlayEvent.onClick,
  323. onMousedown: _ctx.overlayEvent.onMousedown,
  324. onMouseup: _ctx.overlayEvent.onMouseup
  325. }, [
  326. vue.createVNode(_component_el_focus_trap, {
  327. loop: "",
  328. trapped: _ctx.visible,
  329. "focus-trap-el": _ctx.rootRef,
  330. "focus-start-el": _ctx.focusStartRef,
  331. onReleaseRequested: _ctx.onCloseRequested
  332. }, {
  333. default: vue.withCtx(() => [
  334. vue.createElementVNode("div", {
  335. ref: "rootRef",
  336. class: vue.normalizeClass([
  337. _ctx.ns.b(),
  338. _ctx.customClass,
  339. _ctx.ns.is("draggable", _ctx.draggable),
  340. { [_ctx.ns.m("center")]: _ctx.center }
  341. ]),
  342. style: vue.normalizeStyle(_ctx.customStyle),
  343. tabindex: "-1",
  344. onClick: vue.withModifiers(() => {
  345. }, ["stop"])
  346. }, [
  347. _ctx.title !== null && _ctx.title !== void 0 ? (vue.openBlock(), vue.createElementBlock("div", {
  348. key: 0,
  349. ref: "headerRef",
  350. class: vue.normalizeClass([_ctx.ns.e("header"), { "show-close": _ctx.showClose }])
  351. }, [
  352. vue.createElementVNode("div", {
  353. class: vue.normalizeClass(_ctx.ns.e("title"))
  354. }, [
  355. _ctx.iconComponent && _ctx.center ? (vue.openBlock(), vue.createBlock(_component_el_icon, {
  356. key: 0,
  357. class: vue.normalizeClass([_ctx.ns.e("status"), _ctx.typeClass])
  358. }, {
  359. default: vue.withCtx(() => [
  360. (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.iconComponent)))
  361. ]),
  362. _: 1
  363. }, 8, ["class"])) : vue.createCommentVNode("v-if", true),
  364. vue.createElementVNode("span", null, vue.toDisplayString(_ctx.title), 1)
  365. ], 2),
  366. _ctx.showClose ? (vue.openBlock(), vue.createElementBlock("button", {
  367. key: 0,
  368. type: "button",
  369. class: vue.normalizeClass(_ctx.ns.e("headerbtn")),
  370. "aria-label": _ctx.t("el.messagebox.close"),
  371. onClick: ($event) => _ctx.handleAction(_ctx.distinguishCancelAndClose ? "close" : "cancel"),
  372. onKeydown: vue.withKeys(vue.withModifiers(($event) => _ctx.handleAction(_ctx.distinguishCancelAndClose ? "close" : "cancel"), ["prevent"]), ["enter"])
  373. }, [
  374. vue.createVNode(_component_el_icon, {
  375. class: vue.normalizeClass(_ctx.ns.e("close"))
  376. }, {
  377. default: vue.withCtx(() => [
  378. (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.closeIcon || "close")))
  379. ]),
  380. _: 1
  381. }, 8, ["class"])
  382. ], 42, ["aria-label", "onClick", "onKeydown"])) : vue.createCommentVNode("v-if", true)
  383. ], 2)) : vue.createCommentVNode("v-if", true),
  384. vue.createElementVNode("div", {
  385. id: _ctx.contentId,
  386. class: vue.normalizeClass(_ctx.ns.e("content"))
  387. }, [
  388. vue.createElementVNode("div", {
  389. class: vue.normalizeClass(_ctx.ns.e("container"))
  390. }, [
  391. _ctx.iconComponent && !_ctx.center && _ctx.hasMessage ? (vue.openBlock(), vue.createBlock(_component_el_icon, {
  392. key: 0,
  393. class: vue.normalizeClass([_ctx.ns.e("status"), _ctx.typeClass])
  394. }, {
  395. default: vue.withCtx(() => [
  396. (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.iconComponent)))
  397. ]),
  398. _: 1
  399. }, 8, ["class"])) : vue.createCommentVNode("v-if", true),
  400. _ctx.hasMessage ? (vue.openBlock(), vue.createElementBlock("div", {
  401. key: 1,
  402. class: vue.normalizeClass(_ctx.ns.e("message"))
  403. }, [
  404. vue.renderSlot(_ctx.$slots, "default", {}, () => [
  405. !_ctx.dangerouslyUseHTMLString ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.showInput ? "label" : "p"), {
  406. key: 0,
  407. for: _ctx.showInput ? _ctx.inputId : void 0
  408. }, {
  409. default: vue.withCtx(() => [
  410. vue.createTextVNode(vue.toDisplayString(!_ctx.dangerouslyUseHTMLString ? _ctx.message : ""), 1)
  411. ]),
  412. _: 1
  413. }, 8, ["for"])) : (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.showInput ? "label" : "p"), {
  414. key: 1,
  415. for: _ctx.showInput ? _ctx.inputId : void 0,
  416. innerHTML: _ctx.message
  417. }, null, 8, ["for", "innerHTML"]))
  418. ])
  419. ], 2)) : vue.createCommentVNode("v-if", true)
  420. ], 2),
  421. vue.withDirectives(vue.createElementVNode("div", {
  422. class: vue.normalizeClass(_ctx.ns.e("input"))
  423. }, [
  424. vue.createVNode(_component_el_input, {
  425. id: _ctx.inputId,
  426. ref: "inputRef",
  427. modelValue: _ctx.inputValue,
  428. "onUpdate:modelValue": ($event) => _ctx.inputValue = $event,
  429. type: _ctx.inputType,
  430. placeholder: _ctx.inputPlaceholder,
  431. "aria-invalid": _ctx.validateError,
  432. class: vue.normalizeClass({ invalid: _ctx.validateError }),
  433. onKeydown: vue.withKeys(_ctx.handleInputEnter, ["enter"])
  434. }, null, 8, ["id", "modelValue", "onUpdate:modelValue", "type", "placeholder", "aria-invalid", "class", "onKeydown"]),
  435. vue.createElementVNode("div", {
  436. class: vue.normalizeClass(_ctx.ns.e("errormsg")),
  437. style: vue.normalizeStyle({
  438. visibility: !!_ctx.editorErrorMessage ? "visible" : "hidden"
  439. })
  440. }, vue.toDisplayString(_ctx.editorErrorMessage), 7)
  441. ], 2), [
  442. [vue.vShow, _ctx.showInput]
  443. ])
  444. ], 10, ["id"]),
  445. vue.createElementVNode("div", {
  446. class: vue.normalizeClass(_ctx.ns.e("btns"))
  447. }, [
  448. _ctx.showCancelButton ? (vue.openBlock(), vue.createBlock(_component_el_button, {
  449. key: 0,
  450. loading: _ctx.cancelButtonLoading,
  451. "loading-icon": _ctx.cancelButtonLoadingIcon,
  452. class: vue.normalizeClass([_ctx.cancelButtonClass]),
  453. round: _ctx.roundButton,
  454. size: _ctx.btnSize,
  455. onClick: ($event) => _ctx.handleAction("cancel"),
  456. onKeydown: vue.withKeys(vue.withModifiers(($event) => _ctx.handleAction("cancel"), ["prevent"]), ["enter"])
  457. }, {
  458. default: vue.withCtx(() => [
  459. vue.createTextVNode(vue.toDisplayString(_ctx.cancelButtonText || _ctx.t("el.messagebox.cancel")), 1)
  460. ]),
  461. _: 1
  462. }, 8, ["loading", "loading-icon", "class", "round", "size", "onClick", "onKeydown"])) : vue.createCommentVNode("v-if", true),
  463. vue.withDirectives(vue.createVNode(_component_el_button, {
  464. ref: "confirmRef",
  465. type: "primary",
  466. loading: _ctx.confirmButtonLoading,
  467. "loading-icon": _ctx.confirmButtonLoadingIcon,
  468. class: vue.normalizeClass([_ctx.confirmButtonClasses]),
  469. round: _ctx.roundButton,
  470. disabled: _ctx.confirmButtonDisabled,
  471. size: _ctx.btnSize,
  472. onClick: ($event) => _ctx.handleAction("confirm"),
  473. onKeydown: vue.withKeys(vue.withModifiers(($event) => _ctx.handleAction("confirm"), ["prevent"]), ["enter"])
  474. }, {
  475. default: vue.withCtx(() => [
  476. vue.createTextVNode(vue.toDisplayString(_ctx.confirmButtonText || _ctx.t("el.messagebox.confirm")), 1)
  477. ]),
  478. _: 1
  479. }, 8, ["loading", "loading-icon", "class", "round", "disabled", "size", "onClick", "onKeydown"]), [
  480. [vue.vShow, _ctx.showConfirmButton]
  481. ])
  482. ], 2)
  483. ], 14, ["onClick"])
  484. ]),
  485. _: 3
  486. }, 8, ["trapped", "focus-trap-el", "focus-start-el", "onReleaseRequested"])
  487. ], 42, ["aria-label", "aria-describedby", "onClick", "onMousedown", "onMouseup"])
  488. ]),
  489. _: 3
  490. }, 8, ["z-index", "overlay-class", "mask"]), [
  491. [vue.vShow, _ctx.visible]
  492. ])
  493. ]),
  494. _: 3
  495. }, 8, ["onAfterLeave"]);
  496. }
  497. var MessageBoxConstructor = /* @__PURE__ */ pluginVue_exportHelper["default"](_sfc_main, [["render", _sfc_render], ["__file", "index.vue"]]);
  498. exports["default"] = MessageBoxConstructor;
  499. //# sourceMappingURL=index.js.map