@atlaskit/mention
Version:
A React component used to display user profiles in a list for 'Mention' functionality
232 lines (230 loc) • 9.04 kB
JavaScript
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
import React from 'react';
import { IntlProvider, injectIntl } from 'react-intl-next';
import { Text } from '@atlaskit/primitives/compiled';
import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
import { fireAnalyticsMentionTypeaheadEvent } from '../../util/analytics';
import uniqueId from '../../util/id';
import debug from '../../util/logger';
import Popup from '../Popup';
import ResourcedMentionList from '../ResourcedMentionList';
import { MentionPickerInfoStyle, MentionPickerStyle } from './styles';
/**
* @class MentionPicker
*/
export var MentionPicker = /*#__PURE__*/function (_React$PureComponent) {
function MentionPicker(props) {
var _this;
_classCallCheck(this, MentionPicker);
_this = _callSuper(this, MentionPicker, [props]);
_defineProperty(_this, "selectNext", function () {
if (_this.mentionListRef) {
_this.mentionListRef.selectNext();
}
});
_defineProperty(_this, "selectPrevious", function () {
if (_this.mentionListRef) {
_this.mentionListRef.selectPrevious();
}
});
_defineProperty(_this, "selectIndex", function (index, callback) {
if (_this.mentionListRef) {
_this.mentionListRef.selectIndex(index, callback);
}
});
_defineProperty(_this, "selectId", function (id, callback) {
if (_this.mentionListRef) {
_this.mentionListRef.selectId(id, callback);
}
});
_defineProperty(_this, "chooseCurrentSelection", function () {
if (_this.mentionListRef) {
_this.mentionListRef.chooseCurrentSelection();
}
});
_defineProperty(_this, "mentionsCount", function () {
if (_this.mentionListRef) {
return _this.mentionListRef.mentionsCount();
}
return 0;
});
/**
* Called after the 'visible' state is changed to decide whether the onOpen or onClose
* handlers should be called.
*
* It should be noted that the visible state of the component is not considered in
* this function. Instead the old state and new state should be passed as parameters.
*/
_defineProperty(_this, "onFilterVisibilityChange", function (oldVisibility, newVisibility) {
if (oldVisibility !== newVisibility) {
if (newVisibility) {
if (_this.props.onOpen) {
_this.props.onOpen();
}
} else {
if (_this.props.onClose) {
_this.props.onClose();
}
}
}
});
// internal, used for callbacks
_defineProperty(_this, "filterChange", function (mentions, query, stats) {
debug('ak-mention-picker.filterChange', mentions.length);
var wasVisible = _this.state.visible;
var visible = mentions.length > 0;
_this.setState({
visible: visible
});
_this.onFilterVisibilityChange(wasVisible, visible);
fireAnalyticsMentionTypeaheadEvent(_this.props)('rendered', stats && stats.duration, mentions.map(function (mention) {
return mention.id;
}), query);
});
_defineProperty(_this, "filterError", function (error) {
debug('ak-mention-picker.filterError', error);
var wasVisible = _this.state.visible;
_this.setState({
visible: true,
info: undefined
});
_this.onFilterVisibilityChange(wasVisible, true);
});
_defineProperty(_this, "filterInfo", function (info) {
debug('ak-mention-picker.filterInfo', info);
_this.setState({
info: info
});
});
_defineProperty(_this, "handleMentionListRef", function (ref) {
_this.mentionListRef = ref;
});
_this.subscriberKey = uniqueId('ak-mention-picker');
_this.state = {
visible: false
};
_this.applyPropChanges({}, props);
return _this;
}
_inherits(MentionPicker, _React$PureComponent);
return _createClass(MentionPicker, [{
key: "componentDidMount",
value: function componentDidMount() {
this.subscribeResourceProvider(this.props.resourceProvider);
}
}, {
key: "UNSAFE_componentWillReceiveProps",
value: function UNSAFE_componentWillReceiveProps(nextProps) {
this.applyPropChanges(this.props, nextProps);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.unsubscribeResourceProvider(this.props.resourceProvider);
}
}, {
key: "applyPropChanges",
value:
// Internal
function applyPropChanges(prevProps, nextProps) {
var oldResourceProvider = prevProps.resourceProvider;
var newResourceProvider = nextProps.resourceProvider;
var resourceProviderChanged = oldResourceProvider !== newResourceProvider;
// resource provider
if (resourceProviderChanged) {
this.unsubscribeResourceProvider(oldResourceProvider);
this.subscribeResourceProvider(newResourceProvider);
}
}
}, {
key: "subscribeResourceProvider",
value: function subscribeResourceProvider(resourceProvider) {
if (resourceProvider) {
resourceProvider.subscribe(this.subscriberKey, this.filterChange, this.filterError, this.filterInfo, undefined);
}
}
}, {
key: "unsubscribeResourceProvider",
value: function unsubscribeResourceProvider(resourceProvider) {
if (resourceProvider) {
resourceProvider.unsubscribe(this.subscriberKey);
}
}
}, {
key: "render",
value: function render() {
var _this$props = this.props,
resourceProvider = _this$props.resourceProvider,
presenceProvider = _this$props.presenceProvider,
onSelection = _this$props.onSelection,
query = _this$props.query,
target = _this$props.target,
position = _this$props.position,
zIndex = _this$props.zIndex,
offsetX = _this$props.offsetX,
offsetY = _this$props.offsetY,
intl = _this$props.intl;
var _this$state = this.state,
visible = _this$state.visible,
info = _this$state.info;
var resourceMentionList = /*#__PURE__*/React.createElement(ResourcedMentionList, {
resourceProvider: resourceProvider,
presenceProvider: presenceProvider,
onSelection: onSelection,
query: query,
ref: this.handleMentionListRef
});
var infoContent = info && !visible ? /*#__PURE__*/React.createElement(MentionPickerInfoStyle, null, /*#__PURE__*/React.createElement(Text, {
as: "p"
}, info)) : null;
var content;
if (position) {
debug('target, position', target, position);
if (target) {
content = /*#__PURE__*/React.createElement(Popup, {
target: target,
relativePosition: position,
zIndex: zIndex,
offsetX: offsetX,
offsetY: offsetY
}, /*#__PURE__*/React.createElement(IntlProvider, {
locale: (intl === null || intl === void 0 ? void 0 : intl.locale) || 'en'
}, /*#__PURE__*/React.createElement("div", null, resourceMentionList, infoContent)));
} else {
// don't show if we have a position, but no target yet
content = null;
}
} else {
content = /*#__PURE__*/React.createElement("div", null, resourceMentionList, infoContent);
}
return (
/*#__PURE__*/
/* old classnames are essential for Confluence tests */
React.createElement(MentionPickerStyle
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
, {
className: "ak-mention-picker",
visible: visible || info
}, content)
);
}
}]);
}(React.PureComponent);
_defineProperty(MentionPicker, "defaultProps", {
onSelection: function onSelection() {},
onOpen: function onOpen() {},
onClose: function onClose() {}
});
var MentionPickerWithIntl = injectIntl(MentionPicker, {
forwardRef: true
});
// @ts-ignore: [PIT-1685] Fails in post-office due to backwards incompatibility issue with React 18
export var MentionPickerWithAnalytics = withAnalyticsEvents({})(MentionPickerWithIntl);
export default MentionPickerWithAnalytics;