MultipleSelector.js 6.84 KB
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import * as React from 'react';
import { useState } from 'react';
import classNames from 'classnames';
import pickAttrs from "rc-util/es/pickAttrs";
import { CSSMotionList } from 'rc-motion';
import TransBtn from '../TransBtn';
import Input from './Input';
import useLayoutEffect from '../hooks/useLayoutEffect';
var REST_TAG_KEY = '__RC_SELECT_MAX_REST_COUNT__';

var SelectSelector = function SelectSelector(props) {
  var id = props.id,
      prefixCls = props.prefixCls,
      values = props.values,
      open = props.open,
      searchValue = props.searchValue,
      inputRef = props.inputRef,
      placeholder = props.placeholder,
      disabled = props.disabled,
      mode = props.mode,
      showSearch = props.showSearch,
      autoFocus = props.autoFocus,
      autoComplete = props.autoComplete,
      accessibilityIndex = props.accessibilityIndex,
      tabIndex = props.tabIndex,
      removeIcon = props.removeIcon,
      choiceTransitionName = props.choiceTransitionName,
      maxTagCount = props.maxTagCount,
      maxTagTextLength = props.maxTagTextLength,
      _props$maxTagPlacehol = props.maxTagPlaceholder,
      maxTagPlaceholder = _props$maxTagPlacehol === void 0 ? function (omittedValues) {
    return "+ ".concat(omittedValues.length, " ...");
  } : _props$maxTagPlacehol,
      tagRender = props.tagRender,
      onSelect = props.onSelect,
      onInputChange = props.onInputChange,
      onInputPaste = props.onInputPaste,
      onInputKeyDown = props.onInputKeyDown,
      onInputMouseDown = props.onInputMouseDown,
      onInputCompositionStart = props.onInputCompositionStart,
      onInputCompositionEnd = props.onInputCompositionEnd;

  var _useState = useState(false),
      _useState2 = _slicedToArray(_useState, 2),
      motionAppear = _useState2[0],
      setMotionAppear = _useState2[1];

  var measureRef = React.useRef(null);

  var _useState3 = useState(0),
      _useState4 = _slicedToArray(_useState3, 2),
      inputWidth = _useState4[0],
      setInputWidth = _useState4[1];

  var _useState5 = useState(false),
      _useState6 = _slicedToArray(_useState5, 2),
      focused = _useState6[0],
      setFocused = _useState6[1]; // ===================== Motion ======================


  React.useEffect(function () {
    setMotionAppear(true);
  }, []); // ===================== Search ======================

  var inputValue = open || mode === 'tags' ? searchValue : '';
  var inputEditable = mode === 'tags' || showSearch && (open || focused); // We measure width and set to the input immediately

  useLayoutEffect(function () {
    setInputWidth(measureRef.current.scrollWidth);
  }, [inputValue]); // ==================== Selection ====================

  var displayValues = values; // Cut by `maxTagCount`

  var restCount;

  if (typeof maxTagCount === 'number') {
    restCount = values.length - maxTagCount;
    displayValues = values.slice(0, maxTagCount);
  } // Update by `maxTagTextLength`


  if (typeof maxTagTextLength === 'number') {
    displayValues = displayValues.map(function (_ref) {
      var label = _ref.label,
          rest = _objectWithoutProperties(_ref, ["label"]);

      var displayLabel = label;

      if (typeof label === 'string' || typeof label === 'number') {
        var strLabel = String(displayLabel);

        if (strLabel.length > maxTagTextLength) {
          displayLabel = "".concat(strLabel.slice(0, maxTagTextLength), "...");
        }
      }

      return _objectSpread(_objectSpread({}, rest), {}, {
        label: displayLabel
      });
    });
  } // Fill rest


  if (restCount > 0) {
    displayValues.push({
      key: REST_TAG_KEY,
      label: typeof maxTagPlaceholder === 'function' ? maxTagPlaceholder(values.slice(maxTagCount)) : maxTagPlaceholder
    });
  }

  var selectionNode = React.createElement(CSSMotionList, {
    component: false,
    keys: displayValues,
    motionName: choiceTransitionName,
    motionAppear: motionAppear
  }, function (_ref2) {
    var key = _ref2.key,
        label = _ref2.label,
        value = _ref2.value,
        itemDisabled = _ref2.disabled,
        className = _ref2.className,
        style = _ref2.style;
    var mergedKey = key || value;
    var closable = !disabled && key !== REST_TAG_KEY && !itemDisabled;

    var onMouseDown = function onMouseDown(event) {
      event.preventDefault();
      event.stopPropagation();
    };

    var onClose = function onClose(event) {
      if (event) event.stopPropagation();
      onSelect(value, {
        selected: false
      });
    };

    return typeof tagRender === 'function' ? React.createElement("span", {
      key: mergedKey,
      onMouseDown: onMouseDown,
      className: className,
      style: style
    }, tagRender({
      label: label,
      value: value,
      disabled: itemDisabled,
      closable: closable,
      onClose: onClose
    })) : React.createElement("span", {
      key: mergedKey,
      className: classNames(className, "".concat(prefixCls, "-selection-item"), _defineProperty({}, "".concat(prefixCls, "-selection-item-disabled"), itemDisabled)),
      style: style
    }, React.createElement("span", {
      className: "".concat(prefixCls, "-selection-item-content")
    }, label), closable && React.createElement(TransBtn, {
      className: "".concat(prefixCls, "-selection-item-remove"),
      onMouseDown: onMouseDown,
      onClick: onClose,
      customizeIcon: removeIcon
    }, "\xD7"));
  });
  return React.createElement(React.Fragment, null, selectionNode, React.createElement("span", {
    className: "".concat(prefixCls, "-selection-search"),
    style: {
      width: inputWidth
    },
    onFocus: function onFocus() {
      setFocused(true);
    },
    onBlur: function onBlur() {
      setFocused(false);
    }
  }, React.createElement(Input, {
    ref: inputRef,
    open: open,
    prefixCls: prefixCls,
    id: id,
    inputElement: null,
    disabled: disabled,
    autoFocus: autoFocus,
    autoComplete: autoComplete,
    editable: inputEditable,
    accessibilityIndex: accessibilityIndex,
    value: inputValue,
    onKeyDown: onInputKeyDown,
    onMouseDown: onInputMouseDown,
    onChange: onInputChange,
    onPaste: onInputPaste,
    onCompositionStart: onInputCompositionStart,
    onCompositionEnd: onInputCompositionEnd,
    tabIndex: tabIndex,
    attrs: pickAttrs(props, true)
  }), React.createElement("span", {
    ref: measureRef,
    className: "".concat(prefixCls, "-selection-search-mirror"),
    "aria-hidden": true
  }, inputValue, "\xA0")), !values.length && !inputValue && React.createElement("span", {
    className: "".concat(prefixCls, "-selection-placeholder")
  }, placeholder));
};

export default SelectSelector;