MultipleSelector.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  2. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  3. import * as React from 'react';
  4. import { useState } from 'react';
  5. import classNames from 'classnames';
  6. import pickAttrs from "rc-util/es/pickAttrs";
  7. import Overflow from 'rc-overflow';
  8. import TransBtn from "../TransBtn";
  9. import Input from "./Input";
  10. import useLayoutEffect from "../hooks/useLayoutEffect";
  11. import { getTitle } from "../utils/commonUtil";
  12. function itemKey(value) {
  13. var _value$key;
  14. return (_value$key = value.key) !== null && _value$key !== void 0 ? _value$key : value.value;
  15. }
  16. var onPreventMouseDown = function onPreventMouseDown(event) {
  17. event.preventDefault();
  18. event.stopPropagation();
  19. };
  20. var SelectSelector = function SelectSelector(props) {
  21. var id = props.id,
  22. prefixCls = props.prefixCls,
  23. values = props.values,
  24. open = props.open,
  25. searchValue = props.searchValue,
  26. autoClearSearchValue = props.autoClearSearchValue,
  27. inputRef = props.inputRef,
  28. placeholder = props.placeholder,
  29. disabled = props.disabled,
  30. mode = props.mode,
  31. showSearch = props.showSearch,
  32. autoFocus = props.autoFocus,
  33. autoComplete = props.autoComplete,
  34. activeDescendantId = props.activeDescendantId,
  35. tabIndex = props.tabIndex,
  36. removeIcon = props.removeIcon,
  37. maxTagCount = props.maxTagCount,
  38. maxTagTextLength = props.maxTagTextLength,
  39. _props$maxTagPlacehol = props.maxTagPlaceholder,
  40. maxTagPlaceholder = _props$maxTagPlacehol === void 0 ? function (omittedValues) {
  41. return "+ ".concat(omittedValues.length, " ...");
  42. } : _props$maxTagPlacehol,
  43. tagRender = props.tagRender,
  44. onToggleOpen = props.onToggleOpen,
  45. onRemove = props.onRemove,
  46. onInputChange = props.onInputChange,
  47. onInputPaste = props.onInputPaste,
  48. onInputKeyDown = props.onInputKeyDown,
  49. onInputMouseDown = props.onInputMouseDown,
  50. onInputCompositionStart = props.onInputCompositionStart,
  51. onInputCompositionEnd = props.onInputCompositionEnd,
  52. onInputBlur = props.onInputBlur;
  53. var measureRef = React.useRef(null);
  54. var _useState = useState(0),
  55. _useState2 = _slicedToArray(_useState, 2),
  56. inputWidth = _useState2[0],
  57. setInputWidth = _useState2[1];
  58. var _useState3 = useState(false),
  59. _useState4 = _slicedToArray(_useState3, 2),
  60. focused = _useState4[0],
  61. setFocused = _useState4[1];
  62. var selectionPrefixCls = "".concat(prefixCls, "-selection");
  63. // ===================== Search ======================
  64. var inputValue = open || mode === 'multiple' && autoClearSearchValue === false || mode === 'tags' ? searchValue : '';
  65. var inputEditable = mode === 'tags' || mode === 'multiple' && autoClearSearchValue === false || showSearch && (open || focused);
  66. // We measure width and set to the input immediately
  67. useLayoutEffect(function () {
  68. setInputWidth(measureRef.current.scrollWidth);
  69. }, [inputValue]);
  70. // ===================== Render ======================
  71. // >>> Render Selector Node. Includes Item & Rest
  72. var defaultRenderSelector = function defaultRenderSelector(item, content, itemDisabled, closable, onClose) {
  73. return /*#__PURE__*/React.createElement("span", {
  74. title: getTitle(item),
  75. className: classNames("".concat(selectionPrefixCls, "-item"), _defineProperty({}, "".concat(selectionPrefixCls, "-item-disabled"), itemDisabled))
  76. }, /*#__PURE__*/React.createElement("span", {
  77. className: "".concat(selectionPrefixCls, "-item-content")
  78. }, content), closable && /*#__PURE__*/React.createElement(TransBtn, {
  79. className: "".concat(selectionPrefixCls, "-item-remove"),
  80. onMouseDown: onPreventMouseDown,
  81. onClick: onClose,
  82. customizeIcon: removeIcon
  83. }, "\xD7"));
  84. };
  85. var customizeRenderSelector = function customizeRenderSelector(value, content, itemDisabled, closable, onClose, isMaxTag) {
  86. var onMouseDown = function onMouseDown(e) {
  87. onPreventMouseDown(e);
  88. onToggleOpen(!open);
  89. };
  90. return /*#__PURE__*/React.createElement("span", {
  91. onMouseDown: onMouseDown
  92. }, tagRender({
  93. label: content,
  94. value: value,
  95. disabled: itemDisabled,
  96. closable: closable,
  97. onClose: onClose,
  98. isMaxTag: !!isMaxTag
  99. }));
  100. };
  101. var renderItem = function renderItem(valueItem) {
  102. var itemDisabled = valueItem.disabled,
  103. label = valueItem.label,
  104. value = valueItem.value;
  105. var closable = !disabled && !itemDisabled;
  106. var displayLabel = label;
  107. if (typeof maxTagTextLength === 'number') {
  108. if (typeof label === 'string' || typeof label === 'number') {
  109. var strLabel = String(displayLabel);
  110. if (strLabel.length > maxTagTextLength) {
  111. displayLabel = "".concat(strLabel.slice(0, maxTagTextLength), "...");
  112. }
  113. }
  114. }
  115. var onClose = function onClose(event) {
  116. if (event) {
  117. event.stopPropagation();
  118. }
  119. onRemove(valueItem);
  120. };
  121. return typeof tagRender === 'function' ? customizeRenderSelector(value, displayLabel, itemDisabled, closable, onClose) : defaultRenderSelector(valueItem, displayLabel, itemDisabled, closable, onClose);
  122. };
  123. var renderRest = function renderRest(omittedValues) {
  124. // https://github.com/ant-design/ant-design/issues/48930
  125. if (!values.length) {
  126. return null;
  127. }
  128. var content = typeof maxTagPlaceholder === 'function' ? maxTagPlaceholder(omittedValues) : maxTagPlaceholder;
  129. return typeof tagRender === 'function' ? customizeRenderSelector(undefined, content, false, false, undefined, true) : defaultRenderSelector({
  130. title: content
  131. }, content, false);
  132. };
  133. // >>> Input Node
  134. var inputNode = /*#__PURE__*/React.createElement("div", {
  135. className: "".concat(selectionPrefixCls, "-search"),
  136. style: {
  137. width: inputWidth
  138. },
  139. onFocus: function onFocus() {
  140. setFocused(true);
  141. },
  142. onBlur: function onBlur() {
  143. setFocused(false);
  144. }
  145. }, /*#__PURE__*/React.createElement(Input, {
  146. ref: inputRef,
  147. open: open,
  148. prefixCls: prefixCls,
  149. id: id,
  150. inputElement: null,
  151. disabled: disabled,
  152. autoFocus: autoFocus,
  153. autoComplete: autoComplete,
  154. editable: inputEditable,
  155. activeDescendantId: activeDescendantId,
  156. value: inputValue,
  157. onKeyDown: onInputKeyDown,
  158. onMouseDown: onInputMouseDown,
  159. onChange: onInputChange,
  160. onPaste: onInputPaste,
  161. onCompositionStart: onInputCompositionStart,
  162. onCompositionEnd: onInputCompositionEnd,
  163. onBlur: onInputBlur,
  164. tabIndex: tabIndex,
  165. attrs: pickAttrs(props, true)
  166. }), /*#__PURE__*/React.createElement("span", {
  167. ref: measureRef,
  168. className: "".concat(selectionPrefixCls, "-search-mirror"),
  169. "aria-hidden": true
  170. }, inputValue, "\xA0"));
  171. // >>> Selections
  172. var selectionNode = /*#__PURE__*/React.createElement(Overflow, {
  173. prefixCls: "".concat(selectionPrefixCls, "-overflow"),
  174. data: values,
  175. renderItem: renderItem,
  176. renderRest: renderRest,
  177. suffix: inputNode,
  178. itemKey: itemKey,
  179. maxCount: maxTagCount
  180. });
  181. return /*#__PURE__*/React.createElement("span", {
  182. className: "".concat(selectionPrefixCls, "-wrap")
  183. }, selectionNode, !values.length && !inputValue && /*#__PURE__*/React.createElement("span", {
  184. className: "".concat(selectionPrefixCls, "-placeholder")
  185. }, placeholder));
  186. };
  187. export default SelectSelector;