function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import * as React from 'react';
import { CompositeDecorator, EditorState } from 'draft-js';
import noop from 'lodash/noop';
import DraftJSMentionSelectorCore from './DraftJSMentionSelectorCore';
import DraftMentionItem from './DraftMentionItem';
import FormInput from '../form/FormInput';
import * as messages from '../input-messages';
import Toggle from '../../toggle/Toggle';

/**
 * Scans a Draft ContentBlock for entity ranges, so they can be annotated
 * @see docs at {@link https://draftjs.org/docs/advanced-topics-decorators.html#compositedecorator}
 * @param {ContentBlock} contentBlock
 * @param {function} callback
 * @param {ContentState} contentState
 */
const mentionStrategy = (contentBlock, callback, contentState) => {
  contentBlock.findEntityRanges(character => {
    const entityKey = character.getEntity();
    const ret = entityKey !== null && contentState.getEntity(entityKey).getType() === 'MENTION';
    return ret;
  }, callback);
};
class DraftJSMentionSelector extends React.Component {
  constructor(props) {
    super(props);
    /**
     * Event handler called on blur. Triggers validation
     * @param {SyntheticFocusEvent} event The event object
     * @returns {void}
     */
    _defineProperty(this, "handleBlur", event => {
      if (this.props.validateOnBlur && this.containerEl && event.relatedTarget instanceof Node && !this.containerEl.contains(event.relatedTarget)) {
        this.checkValidity();
      }
    });
    _defineProperty(this, "handleFocus", event => {
      const {
        onFocus
      } = this.props;
      if (onFocus) {
        onFocus(event);
      }
    });
    /**
     * Updates editorState, rechecks validity
     * @param {EditorState} nextEditorState The new editor state to set in the state
     * @returns {void}
     */
    _defineProperty(this, "handleChange", nextEditorState => {
      const {
        internalEditorState
      } = this.state;
      const {
        onChange
      } = this.props;
      onChange(nextEditorState);
      if (internalEditorState) {
        this.setState({
          internalEditorState: nextEditorState
        });
      }
    });
    _defineProperty(this, "handleValidityStateUpdateHandler", () => {
      const {
        isTouched
      } = this.state;
      if (!isTouched) {
        return;
      }
      const error = this.getErrorFromValidityState();
      this.setState({
        error
      });
    });
    _defineProperty(this, "checkValidity", () => {
      this.handleValidityStateUpdateHandler();
    });
    const mentionDecorator = new CompositeDecorator([{
      strategy: mentionStrategy,
      component: DraftMentionItem
    }]);

    // @NOTE:
    // This component might be either own its EditorState (in which case it lives in `this.state.internalEditorState`)
    // or be a controlled component whose EditorState is passed in via the `editorState` prop.
    // If `props.editorState` is set, `internalEditorState` is `null`,
    // otherwise we initialize it here
    this.state = {
      contacts: [],
      isTouched: false,
      internalEditorState: props.editorState ? null : EditorState.createEmpty(mentionDecorator),
      error: null
    };
  }
  static getDerivedStateFromProps(nextProps) {
    const {
      contacts
    } = nextProps;
    return contacts ? {
      contacts
    } : null;
  }
  componentDidUpdate(prevProps, prevState) {
    const {
      internalEditorState: prevInternalEditorState
    } = prevState;
    const {
      internalEditorState
    } = this.state;
    const {
      editorState: prevEditorStateFromProps
    } = prevProps;
    const {
      editorState
    } = this.props;

    // Determine whether we're working with the internal editor state or
    // external editor state passed in from props
    const prevEditorState = prevInternalEditorState || prevEditorStateFromProps;
    const currentEditorState = internalEditorState || editorState;

    // Only handle isTouched state transitions and check validity if the
    // editorState references are different. This is to avoid getting stuck
    // in an infinite loop of checking validity because checkValidity always
    // calls setState({ error })
    if (prevEditorState && currentEditorState && prevEditorState !== currentEditorState) {
      const newState = this.getDerivedStateFromEditorState(currentEditorState, prevEditorState);
      if (newState) {
        this.setState(newState, this.checkValidityIfAllowed);
      } else {
        this.checkValidityIfAllowed();
      }
    }
  }
  getDerivedStateFromEditorState(currentEditorState, previousEditorState) {
    const isPreviousEditorStateEmpty = this.isEditorStateEmpty(previousEditorState);
    const isCurrentEditorStateEmpty = this.isEditorStateEmpty(currentEditorState);
    const isNewEditorState = isCurrentEditorStateEmpty && !isPreviousEditorStateEmpty;
    const isEditorStateDirty = isPreviousEditorStateEmpty && !isCurrentEditorStateEmpty;
    let newState = null;
    // Detect case where controlled EditorState is created anew and empty.
    // If next editorState is empty and the current editorState is not empty
    // that means it is a new empty state and this component should not be marked dirty
    if (isNewEditorState) {
      newState = {
        isTouched: false,
        error: null
      };
    } else if (isEditorStateDirty) {
      // Detect case where controlled EditorState has been made dirty
      // If the current editorState is empty and the next editorState is not
      // empty then this is the first interaction so mark this component dirty
      newState = {
        isTouched: true
      };
    }
    return newState;
  }
  checkValidityIfAllowed() {
    const {
      validateOnBlur
    } = this.props;
    if (!validateOnBlur) {
      this.checkValidity();
    }
  }
  isEditorStateEmpty(editorState) {
    const text = editorState.getCurrentContent().getPlainText().trim();
    const lastChangeType = editorState.getLastChangeType();
    return text.length === 0 && lastChangeType === null;
  }

  /**
   * @returns {string}
   */
  getErrorFromValidityState() {
    const {
      editorState: externalEditorState,
      isRequired,
      maxLength,
      minLength
    } = this.props;
    const {
      internalEditorState
    } = this.state;

    // manually check for content length if isRequired is true
    const editorState = internalEditorState || externalEditorState;
    const {
      length
    } = editorState.getCurrentContent().getPlainText().trim();
    if (isRequired && !length) {
      return messages.valueMissing();
    }
    if (typeof minLength !== 'undefined' && length < minLength) {
      return messages.tooShort(minLength);
    }
    if (typeof maxLength !== 'undefined' && length > maxLength) {
      return messages.tooLong(maxLength);
    }
    return null;
  }
  render() {
    const {
      className = '',
      contactsLoaded,
      editorState: externalEditorState,
      hideLabel,
      isDisabled,
      isRequired,
      label,
      description,
      mentionTriggers,
      name,
      onMention,
      placeholder,
      selectorRow,
      startMentionMessage,
      onReturn,
      timestampLabel
    } = this.props;
    const {
      contacts,
      internalEditorState,
      error
    } = this.state;
    const {
      handleBlur,
      handleChange,
      handleFocus
    } = this;
    const editorState = internalEditorState || externalEditorState;
    return /*#__PURE__*/React.createElement("div", {
      ref: containerEl => {
        this.containerEl = containerEl;
      },
      className: className
    }, /*#__PURE__*/React.createElement(FormInput, {
      name: name,
      onValidityStateUpdate: this.handleValidityStateUpdateHandler
    }, /*#__PURE__*/React.createElement(DraftJSMentionSelectorCore, {
      contacts: contacts,
      contactsLoaded: contactsLoaded,
      editorState: editorState,
      error: error,
      hideLabel: hideLabel,
      isDisabled: isDisabled,
      isRequired: isRequired,
      label: label,
      description: description,
      mentionTriggers: mentionTriggers,
      onBlur: handleBlur,
      onChange: handleChange,
      onFocus: handleFocus,
      onMention: onMention,
      onReturn: onReturn,
      placeholder: placeholder,
      selectorRow: selectorRow,
      startMentionMessage: startMentionMessage
    }), isRequired && timestampLabel && /*#__PURE__*/React.createElement(Toggle, {
      className: "bcs-CommentTimestamp-toggle",
      label: timestampLabel,
      onChange: noop
    })));
  }
}
_defineProperty(DraftJSMentionSelector, "defaultProps", {
  isRequired: false,
  onChange: noop,
  validateOnBlur: true
});
export default DraftJSMentionSelector;
//# sourceMappingURL=DraftJSMentionSelector.js.map