index.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import { createNamespace } from '../utils';
  2. import { stopPropagation } from '../utils/dom/event';
  3. import { PortalMixin } from '../mixins/portal';
  4. import { BindEventMixin } from '../mixins/bind-event';
  5. import Key from './Key';
  6. var _createNamespace = createNamespace('number-keyboard'),
  7. createComponent = _createNamespace[0],
  8. bem = _createNamespace[1];
  9. export default createComponent({
  10. mixins: [PortalMixin(), BindEventMixin(function (bind) {
  11. if (this.hideOnClickOutside) {
  12. bind(document.body, 'touchstart', this.onBlur);
  13. }
  14. })],
  15. model: {
  16. event: 'update:value'
  17. },
  18. props: {
  19. show: Boolean,
  20. title: String,
  21. zIndex: [Number, String],
  22. randomKeyOrder: Boolean,
  23. closeButtonText: String,
  24. deleteButtonText: String,
  25. closeButtonLoading: Boolean,
  26. theme: {
  27. type: String,
  28. default: 'default'
  29. },
  30. value: {
  31. type: String,
  32. default: ''
  33. },
  34. extraKey: {
  35. type: [String, Array],
  36. default: ''
  37. },
  38. maxlength: {
  39. type: [Number, String],
  40. default: Number.MAX_VALUE
  41. },
  42. transition: {
  43. type: Boolean,
  44. default: true
  45. },
  46. showDeleteKey: {
  47. type: Boolean,
  48. default: true
  49. },
  50. hideOnClickOutside: {
  51. type: Boolean,
  52. default: true
  53. },
  54. safeAreaInsetBottom: {
  55. type: Boolean,
  56. default: true
  57. }
  58. },
  59. watch: {
  60. show: function show(val) {
  61. if (!this.transition) {
  62. this.$emit(val ? 'show' : 'hide');
  63. }
  64. }
  65. },
  66. computed: {
  67. keys: function keys() {
  68. if (this.theme === 'custom') {
  69. return this.genCustomKeys();
  70. }
  71. return this.genDefaultKeys();
  72. }
  73. },
  74. methods: {
  75. genBasicKeys: function genBasicKeys() {
  76. var keys = [];
  77. for (var i = 1; i <= 9; i++) {
  78. keys.push({
  79. text: i
  80. });
  81. }
  82. if (this.randomKeyOrder) {
  83. keys.sort(function () {
  84. return Math.random() > 0.5 ? 1 : -1;
  85. });
  86. }
  87. return keys;
  88. },
  89. genDefaultKeys: function genDefaultKeys() {
  90. return [].concat(this.genBasicKeys(), [{
  91. text: this.extraKey,
  92. type: 'extra'
  93. }, {
  94. text: 0
  95. }, {
  96. text: this.showDeleteKey ? this.deleteButtonText : '',
  97. type: this.showDeleteKey ? 'delete' : ''
  98. }]);
  99. },
  100. genCustomKeys: function genCustomKeys() {
  101. var keys = this.genBasicKeys();
  102. var extraKey = this.extraKey;
  103. var extraKeys = Array.isArray(extraKey) ? extraKey : [extraKey];
  104. if (extraKeys.length === 1) {
  105. keys.push({
  106. text: 0,
  107. wider: true
  108. }, {
  109. text: extraKeys[0],
  110. type: 'extra'
  111. });
  112. } else if (extraKeys.length === 2) {
  113. keys.push({
  114. text: extraKeys[0],
  115. type: 'extra'
  116. }, {
  117. text: 0
  118. }, {
  119. text: extraKeys[1],
  120. type: 'extra'
  121. });
  122. }
  123. return keys;
  124. },
  125. onBlur: function onBlur() {
  126. this.show && this.$emit('blur');
  127. },
  128. onClose: function onClose() {
  129. this.$emit('close');
  130. this.onBlur();
  131. },
  132. onAnimationEnd: function onAnimationEnd() {
  133. this.$emit(this.show ? 'show' : 'hide');
  134. },
  135. onPress: function onPress(text, type) {
  136. if (text === '') {
  137. if (type === 'extra') {
  138. this.onBlur();
  139. }
  140. return;
  141. }
  142. var value = this.value;
  143. if (type === 'delete') {
  144. this.$emit('delete');
  145. this.$emit('update:value', value.slice(0, value.length - 1));
  146. } else if (type === 'close') {
  147. this.onClose();
  148. } else if (value.length < this.maxlength) {
  149. this.$emit('input', text);
  150. this.$emit('update:value', value + text);
  151. }
  152. },
  153. genTitle: function genTitle() {
  154. var h = this.$createElement;
  155. var title = this.title,
  156. theme = this.theme,
  157. closeButtonText = this.closeButtonText;
  158. var titleLeft = this.slots('title-left');
  159. var showClose = closeButtonText && theme === 'default';
  160. var showTitle = title || showClose || titleLeft;
  161. if (!showTitle) {
  162. return;
  163. }
  164. return h("div", {
  165. "class": bem('header')
  166. }, [titleLeft && h("span", {
  167. "class": bem('title-left')
  168. }, [titleLeft]), title && h("h2", {
  169. "class": bem('title')
  170. }, [title]), showClose && h("button", {
  171. "attrs": {
  172. "type": "button"
  173. },
  174. "class": bem('close'),
  175. "on": {
  176. "click": this.onClose
  177. }
  178. }, [closeButtonText])]);
  179. },
  180. genKeys: function genKeys() {
  181. var _this = this;
  182. var h = this.$createElement;
  183. return this.keys.map(function (key) {
  184. return h(Key, {
  185. "key": key.text,
  186. "attrs": {
  187. "text": key.text,
  188. "type": key.type,
  189. "wider": key.wider,
  190. "color": key.color
  191. },
  192. "on": {
  193. "press": _this.onPress
  194. }
  195. }, [key.type === 'delete' && _this.slots('delete'), key.type === 'extra' && _this.slots('extra-key')]);
  196. });
  197. },
  198. genSidebar: function genSidebar() {
  199. var h = this.$createElement;
  200. if (this.theme === 'custom') {
  201. return h("div", {
  202. "class": bem('sidebar')
  203. }, [this.showDeleteKey && h(Key, {
  204. "attrs": {
  205. "large": true,
  206. "text": this.deleteButtonText,
  207. "type": "delete"
  208. },
  209. "on": {
  210. "press": this.onPress
  211. }
  212. }, [this.slots('delete')]), h(Key, {
  213. "attrs": {
  214. "large": true,
  215. "text": this.closeButtonText,
  216. "type": "close",
  217. "color": "blue",
  218. "loading": this.closeButtonLoading
  219. },
  220. "on": {
  221. "press": this.onPress
  222. }
  223. })]);
  224. }
  225. }
  226. },
  227. render: function render() {
  228. var h = arguments[0];
  229. var Title = this.genTitle();
  230. return h("transition", {
  231. "attrs": {
  232. "name": this.transition ? 'van-slide-up' : ''
  233. }
  234. }, [h("div", {
  235. "directives": [{
  236. name: "show",
  237. value: this.show
  238. }],
  239. "style": {
  240. zIndex: this.zIndex
  241. },
  242. "class": bem({
  243. unfit: !this.safeAreaInsetBottom,
  244. 'with-title': Title
  245. }),
  246. "on": {
  247. "touchstart": stopPropagation,
  248. "animationend": this.onAnimationEnd,
  249. "webkitAnimationEnd": this.onAnimationEnd
  250. }
  251. }, [Title, h("div", {
  252. "class": bem('body')
  253. }, [h("div", {
  254. "class": bem('keys')
  255. }, [this.genKeys()]), this.genSidebar()])])]);
  256. }
  257. });