usePickerInput.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import { onBeforeUnmount, onMounted, watch, ref, computed } from 'vue';
  2. import KeyCode from '../../_util/KeyCode';
  3. import { addGlobalMousedownEvent, getTargetFromEvent } from '../utils/uiUtil';
  4. import raf from '../../_util/raf';
  5. export default function usePickerInput(_ref) {
  6. var open = _ref.open,
  7. value = _ref.value,
  8. isClickOutside = _ref.isClickOutside,
  9. triggerOpen = _ref.triggerOpen,
  10. forwardKeydown = _ref.forwardKeydown,
  11. _onKeydown = _ref.onKeydown,
  12. blurToCancel = _ref.blurToCancel,
  13. onSubmit = _ref.onSubmit,
  14. onCancel = _ref.onCancel,
  15. _onFocus = _ref.onFocus,
  16. _onBlur = _ref.onBlur;
  17. var typing = ref(false);
  18. var focused = ref(false);
  19. /**
  20. * We will prevent blur to handle open event when user click outside,
  21. * since this will repeat trigger `onOpenChange` event.
  22. */
  23. var preventBlurRef = ref(false);
  24. var valueChangedRef = ref(false);
  25. var preventDefaultRef = ref(false);
  26. var inputProps = computed(function () {
  27. return {
  28. onMousedown: function onMousedown() {
  29. typing.value = true;
  30. triggerOpen(true);
  31. },
  32. onKeydown: function onKeydown(e) {
  33. var preventDefault = function preventDefault() {
  34. preventDefaultRef.value = true;
  35. };
  36. _onKeydown(e, preventDefault);
  37. if (preventDefaultRef.value) return;
  38. switch (e.which) {
  39. case KeyCode.ENTER:
  40. {
  41. if (!open.value) {
  42. triggerOpen(true);
  43. } else if (onSubmit() !== false) {
  44. typing.value = true;
  45. }
  46. e.preventDefault();
  47. return;
  48. }
  49. case KeyCode.TAB:
  50. {
  51. if (typing.value && open.value && !e.shiftKey) {
  52. typing.value = false;
  53. e.preventDefault();
  54. } else if (!typing.value && open.value) {
  55. if (!forwardKeydown(e) && e.shiftKey) {
  56. typing.value = true;
  57. e.preventDefault();
  58. }
  59. }
  60. return;
  61. }
  62. case KeyCode.ESC:
  63. {
  64. typing.value = true;
  65. onCancel();
  66. return;
  67. }
  68. }
  69. if (!open.value && ![KeyCode.SHIFT].includes(e.which)) {
  70. triggerOpen(true);
  71. } else if (!typing.value) {
  72. // Let popup panel handle keyboard
  73. forwardKeydown(e);
  74. }
  75. },
  76. onFocus: function onFocus(e) {
  77. typing.value = true;
  78. focused.value = true;
  79. if (_onFocus) {
  80. _onFocus(e);
  81. }
  82. },
  83. onBlur: function onBlur(e) {
  84. if (preventBlurRef.value || !isClickOutside(document.activeElement)) {
  85. preventBlurRef.value = false;
  86. return;
  87. }
  88. if (blurToCancel.value) {
  89. setTimeout(function () {
  90. var _document = document,
  91. activeElement = _document.activeElement;
  92. while (activeElement && activeElement.shadowRoot) {
  93. activeElement = activeElement.shadowRoot.activeElement;
  94. }
  95. if (isClickOutside(activeElement)) {
  96. onCancel();
  97. }
  98. }, 0);
  99. } else if (open.value) {
  100. triggerOpen(false);
  101. if (valueChangedRef.value) {
  102. onSubmit();
  103. }
  104. }
  105. focused.value = false;
  106. if (_onBlur) {
  107. _onBlur(e);
  108. }
  109. }
  110. };
  111. });
  112. // check if value changed
  113. watch(open, function () {
  114. valueChangedRef.value = false;
  115. });
  116. watch(value, function () {
  117. valueChangedRef.value = true;
  118. });
  119. var globalMousedownEvent = ref();
  120. // Global click handler
  121. onMounted(function () {
  122. globalMousedownEvent.value = addGlobalMousedownEvent(function (e) {
  123. var target = getTargetFromEvent(e);
  124. if (open.value) {
  125. var clickedOutside = isClickOutside(target);
  126. if (!clickedOutside) {
  127. preventBlurRef.value = true;
  128. // Always set back in case `onBlur` prevented by user
  129. raf(function () {
  130. preventBlurRef.value = false;
  131. });
  132. } else if (!focused.value || clickedOutside) {
  133. triggerOpen(false);
  134. }
  135. }
  136. });
  137. });
  138. onBeforeUnmount(function () {
  139. globalMousedownEvent.value && globalMousedownEvent.value();
  140. });
  141. return [inputProps, {
  142. focused: focused,
  143. typing: typing
  144. }];
  145. }