useCursor.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = useCursor;
  7. var _react = require("react");
  8. var _warning = _interopRequireDefault(require("rc-util/lib/warning"));
  9. /**
  10. * Keep input cursor in the correct position if possible.
  11. * Is this necessary since we have `formatter` which may mass the content?
  12. */
  13. function useCursor(input, focused) {
  14. var selectionRef = (0, _react.useRef)(null);
  15. function recordCursor() {
  16. // Record position
  17. try {
  18. var start = input.selectionStart,
  19. end = input.selectionEnd,
  20. value = input.value;
  21. var beforeTxt = value.substring(0, start);
  22. var afterTxt = value.substring(end);
  23. selectionRef.current = {
  24. start: start,
  25. end: end,
  26. value: value,
  27. beforeTxt: beforeTxt,
  28. afterTxt: afterTxt
  29. };
  30. } catch (e) {
  31. // Fix error in Chrome:
  32. // Failed to read the 'selectionStart' property from 'HTMLInputElement'
  33. // http://stackoverflow.com/q/21177489/3040605
  34. }
  35. }
  36. /**
  37. * Restore logic:
  38. * 1. back string same
  39. * 2. start string same
  40. */
  41. function restoreCursor() {
  42. if (input && selectionRef.current && focused) {
  43. try {
  44. var value = input.value;
  45. var _selectionRef$current = selectionRef.current,
  46. beforeTxt = _selectionRef$current.beforeTxt,
  47. afterTxt = _selectionRef$current.afterTxt,
  48. start = _selectionRef$current.start;
  49. var startPos = value.length;
  50. if (value.startsWith(beforeTxt)) {
  51. startPos = beforeTxt.length;
  52. } else if (value.endsWith(afterTxt)) {
  53. startPos = value.length - selectionRef.current.afterTxt.length;
  54. } else {
  55. var beforeLastChar = beforeTxt[start - 1];
  56. var newIndex = value.indexOf(beforeLastChar, start - 1);
  57. if (newIndex !== -1) {
  58. startPos = newIndex + 1;
  59. }
  60. }
  61. input.setSelectionRange(startPos, startPos);
  62. } catch (e) {
  63. (0, _warning.default)(false, "Something warning of cursor restore. Please fire issue about this: ".concat(e.message));
  64. }
  65. }
  66. }
  67. return [recordCursor, restoreCursor];
  68. }