NumberKeyboard.mjs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import { withDirectives as _withDirectives, vShow as _vShow, createVNode as _createVNode } from "vue";
  2. import { ref, watch, computed, Teleport, Transition, defineComponent } from "vue";
  3. import { truthProp, numericProp, getZIndexStyle, makeStringProp, makeNumericProp, stopPropagation, createNamespace, HAPTICS_FEEDBACK } from "../utils/index.mjs";
  4. import { useClickAway } from "@vant/use";
  5. import NumberKeyboardKey from "./NumberKeyboardKey.mjs";
  6. const [name, bem] = createNamespace("number-keyboard");
  7. const numberKeyboardProps = {
  8. show: Boolean,
  9. title: String,
  10. theme: makeStringProp("default"),
  11. zIndex: numericProp,
  12. teleport: [String, Object],
  13. maxlength: makeNumericProp(Infinity),
  14. modelValue: makeStringProp(""),
  15. transition: truthProp,
  16. blurOnClose: truthProp,
  17. showDeleteKey: truthProp,
  18. randomKeyOrder: Boolean,
  19. closeButtonText: String,
  20. deleteButtonText: String,
  21. closeButtonLoading: Boolean,
  22. hideOnClickOutside: truthProp,
  23. safeAreaInsetBottom: truthProp,
  24. extraKey: {
  25. type: [String, Array],
  26. default: ""
  27. }
  28. };
  29. function shuffle(array) {
  30. for (let i = array.length - 1; i > 0; i--) {
  31. const j = Math.floor(Math.random() * (i + 1));
  32. const temp = array[i];
  33. array[i] = array[j];
  34. array[j] = temp;
  35. }
  36. return array;
  37. }
  38. var stdin_default = defineComponent({
  39. name,
  40. props: numberKeyboardProps,
  41. emits: ["show", "hide", "blur", "input", "close", "delete", "update:modelValue"],
  42. setup(props, {
  43. emit,
  44. slots
  45. }) {
  46. const root = ref();
  47. const genBasicKeys = () => {
  48. const keys2 = Array(9).fill("").map((_, i) => ({
  49. text: i + 1
  50. }));
  51. if (props.randomKeyOrder) {
  52. shuffle(keys2);
  53. }
  54. return keys2;
  55. };
  56. const genDefaultKeys = () => [...genBasicKeys(), {
  57. text: props.extraKey,
  58. type: "extra"
  59. }, {
  60. text: 0
  61. }, {
  62. text: props.showDeleteKey ? props.deleteButtonText : "",
  63. type: props.showDeleteKey ? "delete" : ""
  64. }];
  65. const genCustomKeys = () => {
  66. const keys2 = genBasicKeys();
  67. const {
  68. extraKey
  69. } = props;
  70. const extraKeys = Array.isArray(extraKey) ? extraKey : [extraKey];
  71. if (extraKeys.length === 1) {
  72. keys2.push({
  73. text: 0,
  74. wider: true
  75. }, {
  76. text: extraKeys[0],
  77. type: "extra"
  78. });
  79. } else if (extraKeys.length === 2) {
  80. keys2.push({
  81. text: extraKeys[0],
  82. type: "extra"
  83. }, {
  84. text: 0
  85. }, {
  86. text: extraKeys[1],
  87. type: "extra"
  88. });
  89. }
  90. return keys2;
  91. };
  92. const keys = computed(() => props.theme === "custom" ? genCustomKeys() : genDefaultKeys());
  93. const onBlur = () => {
  94. if (props.show) {
  95. emit("blur");
  96. }
  97. };
  98. const onClose = () => {
  99. emit("close");
  100. if (props.blurOnClose) {
  101. onBlur();
  102. }
  103. };
  104. const onAnimationEnd = () => emit(props.show ? "show" : "hide");
  105. const onPress = (text, type) => {
  106. if (text === "") {
  107. if (type === "extra") {
  108. onBlur();
  109. }
  110. return;
  111. }
  112. const value = props.modelValue;
  113. if (type === "delete") {
  114. emit("delete");
  115. emit("update:modelValue", value.slice(0, value.length - 1));
  116. } else if (type === "close") {
  117. onClose();
  118. } else if (value.length < props.maxlength) {
  119. emit("input", text);
  120. emit("update:modelValue", value + text);
  121. }
  122. };
  123. const renderTitle = () => {
  124. const {
  125. title,
  126. theme,
  127. closeButtonText
  128. } = props;
  129. const leftSlot = slots["title-left"];
  130. const showClose = closeButtonText && theme === "default";
  131. const showTitle = title || showClose || leftSlot;
  132. if (!showTitle) {
  133. return;
  134. }
  135. return _createVNode("div", {
  136. "class": bem("header")
  137. }, [leftSlot && _createVNode("span", {
  138. "class": bem("title-left")
  139. }, [leftSlot()]), title && _createVNode("h2", {
  140. "class": bem("title")
  141. }, [title]), showClose && _createVNode("button", {
  142. "type": "button",
  143. "class": [bem("close"), HAPTICS_FEEDBACK],
  144. "onClick": onClose
  145. }, [closeButtonText])]);
  146. };
  147. const renderKeys = () => keys.value.map((key) => {
  148. const keySlots = {};
  149. if (key.type === "delete") {
  150. keySlots.default = slots.delete;
  151. }
  152. if (key.type === "extra") {
  153. keySlots.default = slots["extra-key"];
  154. }
  155. return _createVNode(NumberKeyboardKey, {
  156. "key": key.text,
  157. "text": key.text,
  158. "type": key.type,
  159. "wider": key.wider,
  160. "color": key.color,
  161. "onPress": onPress
  162. }, keySlots);
  163. });
  164. const renderSidebar = () => {
  165. if (props.theme === "custom") {
  166. return _createVNode("div", {
  167. "class": bem("sidebar")
  168. }, [props.showDeleteKey && _createVNode(NumberKeyboardKey, {
  169. "large": true,
  170. "text": props.deleteButtonText,
  171. "type": "delete",
  172. "onPress": onPress
  173. }, {
  174. delete: slots.delete
  175. }), _createVNode(NumberKeyboardKey, {
  176. "large": true,
  177. "text": props.closeButtonText,
  178. "type": "close",
  179. "color": "blue",
  180. "loading": props.closeButtonLoading,
  181. "onPress": onPress
  182. }, null)]);
  183. }
  184. };
  185. watch(() => props.show, (value) => {
  186. if (!props.transition) {
  187. emit(value ? "show" : "hide");
  188. }
  189. });
  190. if (props.hideOnClickOutside) {
  191. useClickAway(root, onBlur, {
  192. eventName: "touchstart"
  193. });
  194. }
  195. return () => {
  196. const Title = renderTitle();
  197. const Content = _createVNode(Transition, {
  198. "name": props.transition ? "van-slide-up" : ""
  199. }, {
  200. default: () => [_withDirectives(_createVNode("div", {
  201. "ref": root,
  202. "style": getZIndexStyle(props.zIndex),
  203. "class": bem({
  204. unfit: !props.safeAreaInsetBottom,
  205. "with-title": !!Title
  206. }),
  207. "onAnimationend": onAnimationEnd,
  208. "onTouchstartPassive": stopPropagation
  209. }, [Title, _createVNode("div", {
  210. "class": bem("body")
  211. }, [_createVNode("div", {
  212. "class": bem("keys")
  213. }, [renderKeys()]), renderSidebar()])]), [[_vShow, props.show]])]
  214. });
  215. if (props.teleport) {
  216. return _createVNode(Teleport, {
  217. "to": props.teleport
  218. }, {
  219. default: () => [Content]
  220. });
  221. }
  222. return Content;
  223. };
  224. }
  225. });
  226. export {
  227. stdin_default as default
  228. };