useKeyboard.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = void 0;
  7. var _vue = require("vue");
  8. var _vcSelect = require("../../vc-select");
  9. var _KeyCode = _interopRequireDefault(require("../../_util/KeyCode"));
  10. var _useSearchOptions = require("../hooks/useSearchOptions");
  11. var _default = (context, options, fieldNames, activeValueCells, setActiveValueCells,
  12. // containerRef: Ref<HTMLElement>,
  13. onKeyBoardSelect) => {
  14. const baseProps = (0, _vcSelect.useBaseProps)();
  15. const rtl = (0, _vue.computed)(() => baseProps.direction === 'rtl');
  16. const [validActiveValueCells, lastActiveIndex, lastActiveOptions] = [(0, _vue.ref)([]), (0, _vue.ref)(), (0, _vue.ref)([])];
  17. (0, _vue.watchEffect)(() => {
  18. let activeIndex = -1;
  19. let currentOptions = options.value;
  20. const mergedActiveIndexes = [];
  21. const mergedActiveValueCells = [];
  22. const len = activeValueCells.value.length;
  23. // Fill validate active value cells and index
  24. for (let i = 0; i < len && currentOptions; i += 1) {
  25. // Mark the active index for current options
  26. const nextActiveIndex = currentOptions.findIndex(option => option[fieldNames.value.value] === activeValueCells.value[i]);
  27. if (nextActiveIndex === -1) {
  28. break;
  29. }
  30. activeIndex = nextActiveIndex;
  31. mergedActiveIndexes.push(activeIndex);
  32. mergedActiveValueCells.push(activeValueCells.value[i]);
  33. currentOptions = currentOptions[activeIndex][fieldNames.value.children];
  34. }
  35. // Fill last active options
  36. let activeOptions = options.value;
  37. for (let i = 0; i < mergedActiveIndexes.length - 1; i += 1) {
  38. activeOptions = activeOptions[mergedActiveIndexes[i]][fieldNames.value.children];
  39. }
  40. [validActiveValueCells.value, lastActiveIndex.value, lastActiveOptions.value] = [mergedActiveValueCells, activeIndex, activeOptions];
  41. });
  42. // Update active value cells and scroll to target element
  43. const internalSetActiveValueCells = next => {
  44. setActiveValueCells(next);
  45. };
  46. // Same options offset
  47. const offsetActiveOption = offset => {
  48. const len = lastActiveOptions.value.length;
  49. let currentIndex = lastActiveIndex.value;
  50. if (currentIndex === -1 && offset < 0) {
  51. currentIndex = len;
  52. }
  53. for (let i = 0; i < len; i += 1) {
  54. currentIndex = (currentIndex + offset + len) % len;
  55. const option = lastActiveOptions.value[currentIndex];
  56. if (option && !option.disabled) {
  57. const value = option[fieldNames.value.value];
  58. const nextActiveCells = validActiveValueCells.value.slice(0, -1).concat(value);
  59. internalSetActiveValueCells(nextActiveCells);
  60. return;
  61. }
  62. }
  63. };
  64. // Different options offset
  65. const prevColumn = () => {
  66. if (validActiveValueCells.value.length > 1) {
  67. const nextActiveCells = validActiveValueCells.value.slice(0, -1);
  68. internalSetActiveValueCells(nextActiveCells);
  69. } else {
  70. baseProps.toggleOpen(false);
  71. }
  72. };
  73. const nextColumn = () => {
  74. var _a;
  75. const nextOptions = ((_a = lastActiveOptions.value[lastActiveIndex.value]) === null || _a === void 0 ? void 0 : _a[fieldNames.value.children]) || [];
  76. const nextOption = nextOptions.find(option => !option.disabled);
  77. if (nextOption) {
  78. const nextActiveCells = [...validActiveValueCells.value, nextOption[fieldNames.value.value]];
  79. internalSetActiveValueCells(nextActiveCells);
  80. }
  81. };
  82. context.expose({
  83. // scrollTo: treeRef.current?.scrollTo,
  84. onKeydown: event => {
  85. const {
  86. which
  87. } = event;
  88. switch (which) {
  89. // >>> Arrow keys
  90. case _KeyCode.default.UP:
  91. case _KeyCode.default.DOWN:
  92. {
  93. let offset = 0;
  94. if (which === _KeyCode.default.UP) {
  95. offset = -1;
  96. } else if (which === _KeyCode.default.DOWN) {
  97. offset = 1;
  98. }
  99. if (offset !== 0) {
  100. offsetActiveOption(offset);
  101. }
  102. break;
  103. }
  104. case _KeyCode.default.LEFT:
  105. {
  106. if (rtl.value) {
  107. nextColumn();
  108. } else {
  109. prevColumn();
  110. }
  111. break;
  112. }
  113. case _KeyCode.default.RIGHT:
  114. {
  115. if (rtl.value) {
  116. prevColumn();
  117. } else {
  118. nextColumn();
  119. }
  120. break;
  121. }
  122. case _KeyCode.default.BACKSPACE:
  123. {
  124. if (!baseProps.searchValue) {
  125. prevColumn();
  126. }
  127. break;
  128. }
  129. // >>> Select
  130. case _KeyCode.default.ENTER:
  131. {
  132. if (validActiveValueCells.value.length) {
  133. const option = lastActiveOptions.value[lastActiveIndex.value];
  134. // Search option should revert back of origin options
  135. const originOptions = (option === null || option === void 0 ? void 0 : option[_useSearchOptions.SEARCH_MARK]) || [];
  136. if (originOptions.length) {
  137. onKeyBoardSelect(originOptions.map(opt => opt[fieldNames.value.value]), originOptions[originOptions.length - 1]);
  138. } else {
  139. onKeyBoardSelect(validActiveValueCells.value, option);
  140. }
  141. }
  142. break;
  143. }
  144. // >>> Close
  145. case _KeyCode.default.ESC:
  146. {
  147. baseProps.toggleOpen(false);
  148. if (open) {
  149. event.stopPropagation();
  150. }
  151. }
  152. }
  153. },
  154. onKeyup: () => {}
  155. });
  156. };
  157. exports.default = _default;