Dialog.mjs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import { mergeProps as _mergeProps, createVNode as _createVNode } from "vue";
  2. import { ref, reactive, withKeys, defineComponent } from "vue";
  3. import { noop, pick, extend, addUnit, truthProp, isFunction, BORDER_TOP, BORDER_LEFT, unknownProp, numericProp, makeStringProp, callInterceptor, createNamespace } from "../utils/index.mjs";
  4. import { popupSharedProps, popupSharedPropKeys } from "../popup/shared.mjs";
  5. import { Popup } from "../popup/index.mjs";
  6. import { Button } from "../button/index.mjs";
  7. import { ActionBar } from "../action-bar/index.mjs";
  8. import { ActionBarButton } from "../action-bar-button/index.mjs";
  9. const [name, bem, t] = createNamespace("dialog");
  10. const dialogProps = extend({}, popupSharedProps, {
  11. title: String,
  12. theme: String,
  13. width: numericProp,
  14. message: [String, Function],
  15. callback: Function,
  16. allowHtml: Boolean,
  17. className: unknownProp,
  18. transition: makeStringProp("van-dialog-bounce"),
  19. messageAlign: String,
  20. closeOnPopstate: truthProp,
  21. showCancelButton: Boolean,
  22. cancelButtonText: String,
  23. cancelButtonColor: String,
  24. cancelButtonDisabled: Boolean,
  25. confirmButtonText: String,
  26. confirmButtonColor: String,
  27. confirmButtonDisabled: Boolean,
  28. showConfirmButton: truthProp,
  29. closeOnClickOverlay: Boolean
  30. });
  31. const popupInheritKeys = [...popupSharedPropKeys, "transition", "closeOnPopstate"];
  32. var stdin_default = defineComponent({
  33. name,
  34. props: dialogProps,
  35. emits: ["confirm", "cancel", "keydown", "update:show"],
  36. setup(props, {
  37. emit,
  38. slots
  39. }) {
  40. const root = ref();
  41. const loading = reactive({
  42. confirm: false,
  43. cancel: false
  44. });
  45. const updateShow = (value) => emit("update:show", value);
  46. const close = (action) => {
  47. var _a;
  48. updateShow(false);
  49. (_a = props.callback) == null ? void 0 : _a.call(props, action);
  50. };
  51. const getActionHandler = (action) => () => {
  52. if (!props.show) {
  53. return;
  54. }
  55. emit(action);
  56. if (props.beforeClose) {
  57. loading[action] = true;
  58. callInterceptor(props.beforeClose, {
  59. args: [action],
  60. done() {
  61. close(action);
  62. loading[action] = false;
  63. },
  64. canceled() {
  65. loading[action] = false;
  66. }
  67. });
  68. } else {
  69. close(action);
  70. }
  71. };
  72. const onCancel = getActionHandler("cancel");
  73. const onConfirm = getActionHandler("confirm");
  74. const onKeydown = withKeys((event) => {
  75. var _a, _b;
  76. if (event.target !== ((_b = (_a = root.value) == null ? void 0 : _a.popupRef) == null ? void 0 : _b.value)) {
  77. return;
  78. }
  79. const onEventType = {
  80. Enter: props.showConfirmButton ? onConfirm : noop,
  81. Escape: props.showCancelButton ? onCancel : noop
  82. };
  83. onEventType[event.key]();
  84. emit("keydown", event);
  85. }, ["enter", "esc"]);
  86. const renderTitle = () => {
  87. const title = slots.title ? slots.title() : props.title;
  88. if (title) {
  89. return _createVNode("div", {
  90. "class": bem("header", {
  91. isolated: !props.message && !slots.default
  92. })
  93. }, [title]);
  94. }
  95. };
  96. const renderMessage = (hasTitle) => {
  97. const {
  98. message,
  99. allowHtml,
  100. messageAlign
  101. } = props;
  102. const classNames = bem("message", {
  103. "has-title": hasTitle,
  104. [messageAlign]: messageAlign
  105. });
  106. const content = isFunction(message) ? message() : message;
  107. if (allowHtml && typeof content === "string") {
  108. return _createVNode("div", {
  109. "class": classNames,
  110. "innerHTML": content
  111. }, null);
  112. }
  113. return _createVNode("div", {
  114. "class": classNames
  115. }, [content]);
  116. };
  117. const renderContent = () => {
  118. if (slots.default) {
  119. return _createVNode("div", {
  120. "class": bem("content")
  121. }, [slots.default()]);
  122. }
  123. const {
  124. title,
  125. message,
  126. allowHtml
  127. } = props;
  128. if (message) {
  129. const hasTitle = !!(title || slots.title);
  130. return _createVNode("div", {
  131. "key": allowHtml ? 1 : 0,
  132. "class": bem("content", {
  133. isolated: !hasTitle
  134. })
  135. }, [renderMessage(hasTitle)]);
  136. }
  137. };
  138. const renderButtons = () => _createVNode("div", {
  139. "class": [BORDER_TOP, bem("footer")]
  140. }, [props.showCancelButton && _createVNode(Button, {
  141. "size": "large",
  142. "text": props.cancelButtonText || t("cancel"),
  143. "class": bem("cancel"),
  144. "style": {
  145. color: props.cancelButtonColor
  146. },
  147. "loading": loading.cancel,
  148. "disabled": props.cancelButtonDisabled,
  149. "onClick": onCancel
  150. }, null), props.showConfirmButton && _createVNode(Button, {
  151. "size": "large",
  152. "text": props.confirmButtonText || t("confirm"),
  153. "class": [bem("confirm"), {
  154. [BORDER_LEFT]: props.showCancelButton
  155. }],
  156. "style": {
  157. color: props.confirmButtonColor
  158. },
  159. "loading": loading.confirm,
  160. "disabled": props.confirmButtonDisabled,
  161. "onClick": onConfirm
  162. }, null)]);
  163. const renderRoundButtons = () => _createVNode(ActionBar, {
  164. "class": bem("footer")
  165. }, {
  166. default: () => [props.showCancelButton && _createVNode(ActionBarButton, {
  167. "type": "warning",
  168. "text": props.cancelButtonText || t("cancel"),
  169. "class": bem("cancel"),
  170. "color": props.cancelButtonColor,
  171. "loading": loading.cancel,
  172. "disabled": props.cancelButtonDisabled,
  173. "onClick": onCancel
  174. }, null), props.showConfirmButton && _createVNode(ActionBarButton, {
  175. "type": "danger",
  176. "text": props.confirmButtonText || t("confirm"),
  177. "class": bem("confirm"),
  178. "color": props.confirmButtonColor,
  179. "loading": loading.confirm,
  180. "disabled": props.confirmButtonDisabled,
  181. "onClick": onConfirm
  182. }, null)]
  183. });
  184. const renderFooter = () => {
  185. if (slots.footer) {
  186. return slots.footer();
  187. }
  188. return props.theme === "round-button" ? renderRoundButtons() : renderButtons();
  189. };
  190. return () => {
  191. const {
  192. width,
  193. title,
  194. theme,
  195. message,
  196. className
  197. } = props;
  198. return _createVNode(Popup, _mergeProps({
  199. "ref": root,
  200. "role": "dialog",
  201. "class": [bem([theme]), className],
  202. "style": {
  203. width: addUnit(width)
  204. },
  205. "tabindex": 0,
  206. "aria-labelledby": title || message,
  207. "onKeydown": onKeydown,
  208. "onUpdate:show": updateShow
  209. }, pick(props, popupInheritKeys)), {
  210. default: () => [renderTitle(), renderContent(), renderFooter()]
  211. });
  212. };
  213. }
  214. });
  215. export {
  216. stdin_default as default
  217. };