index.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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 _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  9. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  10. var _KeyCode = _interopRequireDefault(require("../../_util/KeyCode"));
  11. var _MultipleSelector = _interopRequireDefault(require("./MultipleSelector"));
  12. var _SingleSelector = _interopRequireDefault(require("./SingleSelector"));
  13. var _keyUtil = require("../utils/keyUtil");
  14. var _useLock3 = _interopRequireDefault(require("../hooks/useLock"));
  15. var _createRef = _interopRequireDefault(require("../../_util/createRef"));
  16. var _vueTypes = _interopRequireDefault(require("../../_util/vue-types"));
  17. /**
  18. * Cursor rule:
  19. * 1. Only `showSearch` enabled
  20. * 2. Only `open` is `true`
  21. * 3. When typing, set `open` to `true` which hit rule of 2
  22. *
  23. * Accessibility:
  24. * - https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
  25. */
  26. var Selector = (0, _vue.defineComponent)({
  27. name: 'Selector',
  28. inheritAttrs: false,
  29. props: {
  30. id: String,
  31. prefixCls: String,
  32. showSearch: {
  33. type: Boolean,
  34. default: undefined
  35. },
  36. open: {
  37. type: Boolean,
  38. default: undefined
  39. },
  40. /** Display in the Selector value, it's not same as `value` prop */
  41. values: _vueTypes.default.array,
  42. multiple: {
  43. type: Boolean,
  44. default: undefined
  45. },
  46. mode: String,
  47. searchValue: String,
  48. activeValue: String,
  49. inputElement: _vueTypes.default.any,
  50. autofocus: {
  51. type: Boolean,
  52. default: undefined
  53. },
  54. activeDescendantId: String,
  55. tabindex: _vueTypes.default.oneOfType([_vueTypes.default.number, _vueTypes.default.string]),
  56. disabled: {
  57. type: Boolean,
  58. default: undefined
  59. },
  60. placeholder: _vueTypes.default.any,
  61. removeIcon: _vueTypes.default.any,
  62. // Tags
  63. maxTagCount: _vueTypes.default.oneOfType([_vueTypes.default.number, _vueTypes.default.string]),
  64. maxTagTextLength: Number,
  65. maxTagPlaceholder: _vueTypes.default.any,
  66. tagRender: Function,
  67. optionLabelRender: Function,
  68. /** Check if `tokenSeparators` contains `\n` or `\r\n` */
  69. tokenWithEnter: {
  70. type: Boolean,
  71. default: undefined
  72. },
  73. // Motion
  74. choiceTransitionName: String,
  75. onToggleOpen: {
  76. type: Function
  77. },
  78. /** `onSearch` returns go next step boolean to check if need do toggle open */
  79. onSearch: Function,
  80. onSearchSubmit: Function,
  81. onRemove: Function,
  82. onInputKeyDown: {
  83. type: Function
  84. },
  85. /**
  86. * @private get real dom for trigger align.
  87. * This may be removed after React provides replacement of `findDOMNode`
  88. */
  89. domRef: Function
  90. },
  91. setup: function setup(props, _ref) {
  92. var expose = _ref.expose;
  93. var inputRef = (0, _createRef.default)();
  94. var compositionStatus = false;
  95. // ====================== Input ======================
  96. var _useLock = (0, _useLock3.default)(0),
  97. _useLock2 = (0, _slicedToArray2.default)(_useLock, 2),
  98. getInputMouseDown = _useLock2[0],
  99. setInputMouseDown = _useLock2[1];
  100. var onInternalInputKeyDown = function onInternalInputKeyDown(event) {
  101. var which = event.which;
  102. if (which === _KeyCode.default.UP || which === _KeyCode.default.DOWN) {
  103. event.preventDefault();
  104. }
  105. if (props.onInputKeyDown) {
  106. props.onInputKeyDown(event);
  107. }
  108. if (which === _KeyCode.default.ENTER && props.mode === 'tags' && !compositionStatus && !props.open) {
  109. // When menu isn't open, OptionList won't trigger a value change
  110. // So when enter is pressed, the tag's input value should be emitted here to let selector know
  111. props.onSearchSubmit(event.target.value);
  112. }
  113. if ((0, _keyUtil.isValidateOpenKey)(which)) {
  114. props.onToggleOpen(true);
  115. }
  116. };
  117. /**
  118. * We can not use `findDOMNode` sine it will get warning,
  119. * have to use timer to check if is input element.
  120. */
  121. var onInternalInputMouseDown = function onInternalInputMouseDown() {
  122. setInputMouseDown(true);
  123. };
  124. // When paste come, ignore next onChange
  125. var pastedText = null;
  126. var triggerOnSearch = function triggerOnSearch(value) {
  127. if (props.onSearch(value, true, compositionStatus) !== false) {
  128. props.onToggleOpen(true);
  129. }
  130. };
  131. var onInputCompositionStart = function onInputCompositionStart() {
  132. compositionStatus = true;
  133. };
  134. var onInputCompositionEnd = function onInputCompositionEnd(e) {
  135. compositionStatus = false;
  136. // Trigger search again to support `tokenSeparators` with typewriting
  137. if (props.mode !== 'combobox') {
  138. triggerOnSearch(e.target.value);
  139. }
  140. };
  141. var onInputChange = function onInputChange(event) {
  142. var value = event.target.value;
  143. // Pasted text should replace back to origin content
  144. if (props.tokenWithEnter && pastedText && /[\r\n]/.test(pastedText)) {
  145. // CRLF will be treated as a single space for input element
  146. var replacedText = pastedText.replace(/[\r\n]+$/, '').replace(/\r\n/g, ' ').replace(/[\r\n]/g, ' ');
  147. value = value.replace(replacedText, pastedText);
  148. }
  149. pastedText = null;
  150. triggerOnSearch(value);
  151. };
  152. var onInputPaste = function onInputPaste(e) {
  153. var clipboardData = e.clipboardData;
  154. var value = clipboardData.getData('text');
  155. pastedText = value;
  156. };
  157. var onClick = function onClick(_ref2) {
  158. var target = _ref2.target;
  159. if (target !== inputRef.current) {
  160. // Should focus input if click the selector
  161. var isIE = document.body.style.msTouchAction !== undefined;
  162. if (isIE) {
  163. setTimeout(function () {
  164. inputRef.current.focus();
  165. });
  166. } else {
  167. inputRef.current.focus();
  168. }
  169. }
  170. };
  171. var onMousedown = function onMousedown(event) {
  172. var inputMouseDown = getInputMouseDown();
  173. if (event.target !== inputRef.current && !inputMouseDown) {
  174. event.preventDefault();
  175. }
  176. if (props.mode !== 'combobox' && (!props.showSearch || !inputMouseDown) || !props.open) {
  177. if (props.open) {
  178. props.onSearch('', true, false);
  179. }
  180. props.onToggleOpen();
  181. }
  182. };
  183. expose({
  184. focus: function focus() {
  185. inputRef.current.focus();
  186. },
  187. blur: function blur() {
  188. inputRef.current.blur();
  189. }
  190. });
  191. return function () {
  192. var prefixCls = props.prefixCls,
  193. domRef = props.domRef,
  194. mode = props.mode;
  195. var sharedProps = {
  196. inputRef: inputRef,
  197. onInputKeyDown: onInternalInputKeyDown,
  198. onInputMouseDown: onInternalInputMouseDown,
  199. onInputChange: onInputChange,
  200. onInputPaste: onInputPaste,
  201. onInputCompositionStart: onInputCompositionStart,
  202. onInputCompositionEnd: onInputCompositionEnd
  203. };
  204. var selectNode = mode === 'multiple' || mode === 'tags' ? (0, _vue.createVNode)(_MultipleSelector.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, props), sharedProps), null) : (0, _vue.createVNode)(_SingleSelector.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, props), sharedProps), null);
  205. return (0, _vue.createVNode)("div", {
  206. "ref": domRef,
  207. "class": "".concat(prefixCls, "-selector"),
  208. "onClick": onClick,
  209. "onMousedown": onMousedown
  210. }, [selectNode]);
  211. };
  212. }
  213. });
  214. var _default = Selector;
  215. exports.default = _default;