NumberKeyboard.mjs 6.5 KB

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