onKeyDown.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. var _excluded = ["event", "props", "refresh", "store"];
  2. function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
  3. function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
  4. function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  5. function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
  6. function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
  7. import { onInput } from './onInput';
  8. import { getActiveItem } from './utils';
  9. export function onKeyDown(_ref) {
  10. var event = _ref.event,
  11. props = _ref.props,
  12. refresh = _ref.refresh,
  13. store = _ref.store,
  14. setters = _objectWithoutProperties(_ref, _excluded);
  15. if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
  16. // eslint-disable-next-line no-inner-declarations
  17. var triggerScrollIntoView = function triggerScrollIntoView() {
  18. var nodeItem = props.environment.document.getElementById("".concat(props.id, "-item-").concat(store.getState().activeItemId));
  19. if (nodeItem) {
  20. if (nodeItem.scrollIntoViewIfNeeded) {
  21. nodeItem.scrollIntoViewIfNeeded(false);
  22. } else {
  23. nodeItem.scrollIntoView(false);
  24. }
  25. }
  26. }; // eslint-disable-next-line no-inner-declarations
  27. var triggerOnActive = function triggerOnActive() {
  28. var highlightedItem = getActiveItem(store.getState());
  29. if (store.getState().activeItemId !== null && highlightedItem) {
  30. var item = highlightedItem.item,
  31. itemInputValue = highlightedItem.itemInputValue,
  32. itemUrl = highlightedItem.itemUrl,
  33. source = highlightedItem.source;
  34. source.onActive(_objectSpread({
  35. event: event,
  36. item: item,
  37. itemInputValue: itemInputValue,
  38. itemUrl: itemUrl,
  39. refresh: refresh,
  40. source: source,
  41. state: store.getState()
  42. }, setters));
  43. }
  44. }; // Default browser behavior changes the caret placement on ArrowUp and
  45. // ArrowDown.
  46. event.preventDefault(); // When re-opening the panel, we need to split the logic to keep the actions
  47. // synchronized as `onInput` returns a promise.
  48. if (store.getState().isOpen === false && (props.openOnFocus || Boolean(store.getState().query))) {
  49. onInput(_objectSpread({
  50. event: event,
  51. props: props,
  52. query: store.getState().query,
  53. refresh: refresh,
  54. store: store
  55. }, setters)).then(function () {
  56. store.dispatch(event.key, {
  57. nextActiveItemId: props.defaultActiveItemId
  58. });
  59. triggerOnActive(); // Since we rely on the DOM, we need to wait for all the micro tasks to
  60. // finish (which include re-opening the panel) to make sure all the
  61. // elements are available.
  62. setTimeout(triggerScrollIntoView, 0);
  63. });
  64. } else {
  65. store.dispatch(event.key, {});
  66. triggerOnActive();
  67. triggerScrollIntoView();
  68. }
  69. } else if (event.key === 'Escape') {
  70. // This prevents the default browser behavior on `input[type="search"]`
  71. // from removing the query right away because we first want to close the
  72. // panel.
  73. event.preventDefault();
  74. store.dispatch(event.key, null); // Hitting the `Escape` key signals the end of a user interaction with the
  75. // autocomplete. At this point, we should ignore any requests that are still
  76. // pending and could reopen the panel once they resolve, because that would
  77. // result in an unsolicited UI behavior.
  78. store.pendingRequests.cancelAll();
  79. } else if (event.key === 'Enter') {
  80. // No active item, so we let the browser handle the native `onSubmit` form
  81. // event.
  82. if (store.getState().activeItemId === null || store.getState().collections.every(function (collection) {
  83. return collection.items.length === 0;
  84. })) {
  85. return;
  86. } // This prevents the `onSubmit` event to be sent because an item is
  87. // highlighted.
  88. event.preventDefault();
  89. var _ref2 = getActiveItem(store.getState()),
  90. item = _ref2.item,
  91. itemInputValue = _ref2.itemInputValue,
  92. itemUrl = _ref2.itemUrl,
  93. source = _ref2.source;
  94. if (event.metaKey || event.ctrlKey) {
  95. if (itemUrl !== undefined) {
  96. source.onSelect(_objectSpread({
  97. event: event,
  98. item: item,
  99. itemInputValue: itemInputValue,
  100. itemUrl: itemUrl,
  101. refresh: refresh,
  102. source: source,
  103. state: store.getState()
  104. }, setters));
  105. props.navigator.navigateNewTab({
  106. itemUrl: itemUrl,
  107. item: item,
  108. state: store.getState()
  109. });
  110. }
  111. } else if (event.shiftKey) {
  112. if (itemUrl !== undefined) {
  113. source.onSelect(_objectSpread({
  114. event: event,
  115. item: item,
  116. itemInputValue: itemInputValue,
  117. itemUrl: itemUrl,
  118. refresh: refresh,
  119. source: source,
  120. state: store.getState()
  121. }, setters));
  122. props.navigator.navigateNewWindow({
  123. itemUrl: itemUrl,
  124. item: item,
  125. state: store.getState()
  126. });
  127. }
  128. } else if (event.altKey) {// Keep native browser behavior
  129. } else {
  130. if (itemUrl !== undefined) {
  131. source.onSelect(_objectSpread({
  132. event: event,
  133. item: item,
  134. itemInputValue: itemInputValue,
  135. itemUrl: itemUrl,
  136. refresh: refresh,
  137. source: source,
  138. state: store.getState()
  139. }, setters));
  140. props.navigator.navigate({
  141. itemUrl: itemUrl,
  142. item: item,
  143. state: store.getState()
  144. });
  145. return;
  146. }
  147. onInput(_objectSpread({
  148. event: event,
  149. nextState: {
  150. isOpen: false
  151. },
  152. props: props,
  153. query: itemInputValue,
  154. refresh: refresh,
  155. store: store
  156. }, setters)).then(function () {
  157. source.onSelect(_objectSpread({
  158. event: event,
  159. item: item,
  160. itemInputValue: itemInputValue,
  161. itemUrl: itemUrl,
  162. refresh: refresh,
  163. source: source,
  164. state: store.getState()
  165. }, setters));
  166. });
  167. }
  168. }
  169. }