Dialog.mjs 6.7 KB

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