@atlaskit/mention 24.2.17 → 24.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/components/MentionItem/index.js +12 -4
  3. package/dist/cjs/components/MentionList/index.js +60 -21
  4. package/dist/cjs/components/MentionPicker/index.js +2 -2
  5. package/dist/cjs/components/Popup/index.js +81 -23
  6. package/dist/cjs/components/Scrollable/index.js +14 -1
  7. package/dist/es2019/components/MentionItem/index.js +11 -3
  8. package/dist/es2019/components/MentionList/index.js +54 -21
  9. package/dist/es2019/components/MentionPicker/index.js +2 -2
  10. package/dist/es2019/components/Popup/index.js +77 -21
  11. package/dist/es2019/components/Scrollable/index.js +14 -1
  12. package/dist/esm/components/MentionItem/index.js +11 -3
  13. package/dist/esm/components/MentionList/index.js +58 -21
  14. package/dist/esm/components/MentionPicker/index.js +2 -2
  15. package/dist/esm/components/Popup/index.js +79 -23
  16. package/dist/esm/components/Scrollable/index.js +14 -1
  17. package/dist/types/components/MentionItem/index.d.ts +2 -0
  18. package/dist/types/components/MentionList/index.d.ts +3 -0
  19. package/dist/types/components/MentionPicker/index.d.ts +1 -1
  20. package/dist/types/components/Popup/index.d.ts +4 -1
  21. package/dist/types/components/Scrollable/index.d.ts +1 -0
  22. package/dist/types-ts4.5/components/MentionItem/index.d.ts +2 -0
  23. package/dist/types-ts4.5/components/MentionList/index.d.ts +3 -0
  24. package/dist/types-ts4.5/components/MentionPicker/index.d.ts +1 -1
  25. package/dist/types-ts4.5/components/Popup/index.d.ts +4 -1
  26. package/dist/types-ts4.5/components/Scrollable/index.d.ts +1 -0
  27. package/package.json +8 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/mention
2
2
 
3
+ ## 24.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`af63bbf99740e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/af63bbf99740e) -
8
+ Migrate deprecated react-dom APIs to React 19 compatible: findDOMNode and unmountComponentAtNode
9
+ behind FG(mentions-migrate-react-dom)
10
+
11
+ ## 24.2.18
12
+
13
+ ### Patch Changes
14
+
15
+ - [`56ac0cf74b37d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/56ac0cf74b37d) -
16
+ Migrated teams assets to new service
17
+
3
18
  ## 24.2.17
4
19
 
5
20
  ### Patch Changes
@@ -10,7 +10,8 @@ Object.defineProperty(exports, "MENTION_ITEM_HEIGHT", {
10
10
  return _styles.MENTION_ITEM_HEIGHT;
11
11
  }
12
12
  });
13
- exports.default = void 0;
13
+ exports.default = exports.MentionItemWithRef = void 0;
14
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
14
15
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
16
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
16
17
  var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
@@ -88,7 +89,8 @@ var MentionItem = exports.default = /*#__PURE__*/function (_React$PureComponent)
88
89
  value: function render() {
89
90
  var _this$props = this.props,
90
91
  mention = _this$props.mention,
91
- selected = _this$props.selected;
92
+ selected = _this$props.selected,
93
+ forwardedRef = _this$props.forwardedRef;
92
94
  var id = mention.id,
93
95
  highlight = mention.highlight,
94
96
  avatarUrl = mention.avatarUrl,
@@ -114,7 +116,8 @@ var MentionItem = exports.default = /*#__PURE__*/function (_React$PureComponent)
114
116
  "data-testid": "mention-item-".concat(id),
115
117
  "data-mention-id": id,
116
118
  "data-mention-name": mentionName,
117
- "data-selected": selected
119
+ "data-selected": selected,
120
+ ref: forwardedRef
118
121
  }, /*#__PURE__*/_react.default.createElement(_styles.RowStyle, null, /*#__PURE__*/_react.default.createElement(_styles.AvatarStyle, {
119
122
  restricted: restricted
120
123
  }, (0, _platformFeatureFlags.fg)('team-avatar-in-mention-picker') ? /*#__PURE__*/_react.default.createElement(_MentionAvatar.MentionAvatar, {
@@ -145,4 +148,9 @@ var MentionItem = exports.default = /*#__PURE__*/function (_React$PureComponent)
145
148
  }))));
146
149
  }
147
150
  }]);
148
- }(_react.default.PureComponent);
151
+ }(_react.default.PureComponent);
152
+ var MentionItemWithRef = exports.MentionItemWithRef = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
153
+ return /*#__PURE__*/_react.default.createElement(MentionItem, (0, _extends2.default)({}, props, {
154
+ forwardedRef: ref
155
+ }));
156
+ });
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
@@ -12,13 +13,15 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
12
13
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
13
14
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
15
  var _react = _interopRequireDefault(require("react"));
16
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
17
  var _logger = _interopRequireDefault(require("../../util/logger"));
16
18
  var _mouse = require("../../util/mouse");
17
- var _MentionItem = _interopRequireDefault(require("../MentionItem"));
19
+ var _MentionItem = _interopRequireWildcard(require("../MentionItem"));
18
20
  var _MentionListError = _interopRequireDefault(require("../MentionListError"));
19
21
  var _MessagesIntlProvider = _interopRequireDefault(require("../MessagesIntlProvider"));
20
22
  var _Scrollable = _interopRequireDefault(require("../Scrollable"));
21
23
  var _styles = require("./styles");
24
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
22
25
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
23
26
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
24
27
  function wrapIndex(mentions, index) {
@@ -109,11 +112,24 @@ var MentionList = exports.default = /*#__PURE__*/function (_React$PureComponent)
109
112
  (0, _defineProperty2.default)(_this, "handleScrollableRef", function (ref) {
110
113
  _this.scrollable = ref;
111
114
  });
115
+ _this.itemsRefs = new Map();
112
116
  _this.setDefaultSelectionState();
113
117
  return _this;
114
118
  }
115
119
  (0, _inherits2.default)(MentionList, _React$PureComponent);
116
120
  return (0, _createClass2.default)(MentionList, [{
121
+ key: "createItemRef",
122
+ value: function createItemRef(key) {
123
+ var itemRef = /*#__PURE__*/_react.default.createRef();
124
+ this.itemsRefs.set(key, itemRef);
125
+ return itemRef;
126
+ }
127
+ }, {
128
+ key: "getItemRef",
129
+ value: function getItemRef(key) {
130
+ return this.itemsRefs.get(key);
131
+ }
132
+ }, {
117
133
  key: "UNSAFE_componentWillReceiveProps",
118
134
  value: function UNSAFE_componentWillReceiveProps(nextProps) {
119
135
  // adjust selection
@@ -154,9 +170,16 @@ var MentionList = exports.default = /*#__PURE__*/function (_React$PureComponent)
154
170
  value:
155
171
  // Internal
156
172
  function revealItem(key) {
157
- var item = this.items[key];
158
- if (item && this.scrollable) {
159
- this.scrollable.reveal(item);
173
+ if ((0, _platformFeatureFlags.fg)('mentions-migrate-react-dom')) {
174
+ var itemRef = this.getItemRef(key);
175
+ if (itemRef && this.scrollable) {
176
+ itemRef && this.scrollable.revealRef(itemRef);
177
+ }
178
+ } else {
179
+ var item = this.items[key];
180
+ if (item && this.scrollable) {
181
+ this.scrollable.reveal(item);
182
+ }
160
183
  }
161
184
  }
162
185
 
@@ -180,24 +203,40 @@ var MentionList = exports.default = /*#__PURE__*/function (_React$PureComponent)
180
203
  this.items = {};
181
204
  return /*#__PURE__*/_react.default.createElement("div", null, this.props.initialHighlightElement, mentions.map(function (mention, idx) {
182
205
  var key = mention.id;
183
- var item = /*#__PURE__*/_react.default.createElement(_MentionItem.default, {
184
- mention: mention,
185
- selected: _this2.isSelectedMention(mention, idx),
186
- key: key,
187
- onMouseMove: _this2.selectIndexOnHover
188
- /* Cannot use onclick, as onblur will close the element, and prevent
189
- * onClick from firing.
190
- */,
191
- onSelection: _this2.itemSelected,
192
- ref: function ref(_ref) {
193
- if (_ref) {
194
- _this2.items[key] = _ref;
195
- } else {
196
- delete _this2.items[key];
206
+ var ref = _this2.createItemRef(key);
207
+ if ((0, _platformFeatureFlags.fg)('mentions-migrate-react-dom')) {
208
+ var item = /*#__PURE__*/_react.default.createElement(_MentionItem.MentionItemWithRef, {
209
+ mention: mention,
210
+ selected: _this2.isSelectedMention(mention, idx),
211
+ key: key,
212
+ onMouseMove: _this2.selectIndexOnHover
213
+ /* Cannot use onclick, as onblur will close the element, and prevent
214
+ * onClick from firing.
215
+ */,
216
+ onSelection: _this2.itemSelected,
217
+ ref: ref
218
+ });
219
+ return item;
220
+ } else {
221
+ var _item = /*#__PURE__*/_react.default.createElement(_MentionItem.default, {
222
+ mention: mention,
223
+ selected: _this2.isSelectedMention(mention, idx),
224
+ key: key,
225
+ onMouseMove: _this2.selectIndexOnHover
226
+ /* Cannot use onclick, as onblur will close the element, and prevent
227
+ * onClick from firing.
228
+ */,
229
+ onSelection: _this2.itemSelected,
230
+ ref: function ref(_ref) {
231
+ if (_ref) {
232
+ _this2.items[key] = _ref;
233
+ } else {
234
+ delete _this2.items[key];
235
+ }
197
236
  }
198
- }
199
- });
200
- return item;
237
+ });
238
+ return _item;
239
+ }
201
240
  }));
202
241
  }
203
242
  return null;
@@ -11,10 +11,10 @@ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime
11
11
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
12
12
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
13
13
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
- var _compiled = require("@atlaskit/primitives/compiled");
15
- var _withAnalyticsEvents = _interopRequireDefault(require("@atlaskit/analytics-next/withAnalyticsEvents"));
16
14
  var _react = _interopRequireDefault(require("react"));
17
15
  var _reactIntlNext = require("react-intl-next");
16
+ var _compiled = require("@atlaskit/primitives/compiled");
17
+ var _withAnalyticsEvents = _interopRequireDefault(require("@atlaskit/analytics-next/withAnalyticsEvents"));
18
18
  var _analytics = require("../../util/analytics");
19
19
  var _id = _interopRequireDefault(require("../../util/id"));
20
20
  var _logger = _interopRequireDefault(require("../../util/logger"));
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
5
  Object.defineProperty(exports, "__esModule", {
5
6
  value: true
6
7
  });
@@ -12,24 +13,44 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
12
13
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
13
14
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
15
  var _react = _interopRequireDefault(require("react"));
15
- var _reactDom = _interopRequireDefault(require("react-dom"));
16
+ var _reactDom = _interopRequireWildcard(require("react-dom"));
17
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
18
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
19
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
20
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
16
21
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
17
22
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
18
23
  /*
19
24
  * Simple implementation of popup while waiting for ak-inline-dialog
20
25
  */
21
26
  var Popup = exports.default = /*#__PURE__*/function (_React$PureComponent) {
22
- function Popup() {
27
+ function Popup(props) {
28
+ var _this;
23
29
  (0, _classCallCheck2.default)(this, Popup);
24
- return _callSuper(this, Popup, arguments);
30
+ _this = _callSuper(this, Popup, [props]);
31
+ _this.portalStyles = {
32
+ position: 'absolute',
33
+ top: null,
34
+ bottom: null,
35
+ left: null,
36
+ zIndex: null
37
+ };
38
+ return _this;
25
39
  }
26
40
  (0, _inherits2.default)(Popup, _React$PureComponent);
27
41
  return (0, _createClass2.default)(Popup, [{
42
+ key: "setPortalStyles",
43
+ value: function setPortalStyles(styles) {
44
+ this.portalStyles = _objectSpread(_objectSpread({}, this.portalStyles), styles);
45
+ }
46
+ }, {
28
47
  key: "componentDidMount",
29
48
  value: function componentDidMount() {
30
- this.popup = document.createElement('div');
31
- document.body.appendChild(this.popup);
32
- this.popup.style.position = 'absolute';
49
+ if (!(0, _platformFeatureFlags.fg)('mentions-migrate-react-dom')) {
50
+ this.popup = document.createElement('div');
51
+ document.body.appendChild(this.popup);
52
+ this.popup.style.position = 'absolute';
53
+ }
33
54
  this._applyAbsolutePosition();
34
55
  this._renderContent();
35
56
  }
@@ -41,9 +62,11 @@ var Popup = exports.default = /*#__PURE__*/function (_React$PureComponent) {
41
62
  }, {
42
63
  key: "componentWillUnmount",
43
64
  value: function componentWillUnmount() {
44
- if (this.popup) {
45
- _reactDom.default.unmountComponentAtNode(this.popup);
46
- document.body.removeChild(this.popup);
65
+ if (!(0, _platformFeatureFlags.fg)('mentions-migrate-react-dom')) {
66
+ if (this.popup) {
67
+ _reactDom.default.unmountComponentAtNode(this.popup);
68
+ document.body.removeChild(this.popup);
69
+ }
47
70
  }
48
71
  }
49
72
  }, {
@@ -54,10 +77,18 @@ var Popup = exports.default = /*#__PURE__*/function (_React$PureComponent) {
54
77
  var box = targetNode.getBoundingClientRect();
55
78
  var top = box.bottom + (this.props.offsetY || 0);
56
79
  var left = box.left + (this.props.offsetX || 0);
57
- if (this.popup) {
58
- this.popup.style.top = "".concat(top, "px");
59
- this.popup.style.bottom = '';
60
- this.popup.style.left = "".concat(left, "px");
80
+ if ((0, _platformFeatureFlags.fg)('mentions-migrate-react-dom')) {
81
+ this.setPortalStyles({
82
+ top: "".concat(top, "px"),
83
+ bottom: '',
84
+ left: "".concat(left, "px")
85
+ });
86
+ } else {
87
+ if (this.popup) {
88
+ this.popup.style.top = "".concat(top, "px");
89
+ this.popup.style.bottom = '';
90
+ this.popup.style.left = "".concat(left, "px");
91
+ }
61
92
  }
62
93
  }
63
94
  }
@@ -69,10 +100,18 @@ var Popup = exports.default = /*#__PURE__*/function (_React$PureComponent) {
69
100
  var box = targetNode.getBoundingClientRect();
70
101
  var bottom = window.innerHeight - box.top + (this.props.offsetY || 0);
71
102
  var left = box.left + (this.props.offsetX || 0);
72
- if (this.popup) {
73
- this.popup.style.top = '';
74
- this.popup.style.bottom = "".concat(bottom, "px");
75
- this.popup.style.left = "".concat(left, "px");
103
+ if ((0, _platformFeatureFlags.fg)('mentions-migrate-react-dom')) {
104
+ this.setPortalStyles({
105
+ top: '',
106
+ bottom: "".concat(bottom, "px"),
107
+ left: "".concat(left, "px")
108
+ });
109
+ } else {
110
+ if (this.popup) {
111
+ this.popup.style.top = '';
112
+ this.popup.style.bottom = "".concat(bottom, "px");
113
+ this.popup.style.left = "".concat(left, "px");
114
+ }
76
115
  }
77
116
  }
78
117
  }
@@ -95,22 +134,41 @@ var Popup = exports.default = /*#__PURE__*/function (_React$PureComponent) {
95
134
  }
96
135
  }
97
136
  }
98
- if (this.props.zIndex && this.popup) {
99
- this.popup.style.zIndex = "".concat(this.props.zIndex);
137
+ if ((0, _platformFeatureFlags.fg)('mentions-migrate-react-dom')) {
138
+ if (this.props.zIndex) {
139
+ this.setPortalStyles({
140
+ zIndex: this.props.zIndex
141
+ });
142
+ }
143
+ } else {
144
+ if (this.props.zIndex && this.popup) {
145
+ this.popup.style.zIndex = "".concat(this.props.zIndex);
146
+ }
100
147
  }
101
148
  }
102
149
  }, {
103
150
  key: "_renderContent",
104
151
  value: function _renderContent() {
105
- if (this.popup) {
106
- _reactDom.default.render(this.props.children, this.popup);
152
+ if (!(0, _platformFeatureFlags.fg)('mentions-migrate-react-dom')) {
153
+ if (this.popup) {
154
+ _reactDom.default.render(this.props.children, this.popup);
155
+ }
107
156
  }
108
157
  }
109
158
  }, {
110
159
  key: "render",
111
160
  value: function render() {
112
- // Placeholder element for react to render inplace
113
- return /*#__PURE__*/_react.default.createElement("div", null);
161
+ if ((0, _platformFeatureFlags.fg)('mentions-migrate-react-dom')) {
162
+ // https://atlassian.design/components/eslint-plugin-ui-styling-standard/migration-guide#dynamic-styles
163
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
164
+ var content = /*#__PURE__*/_react.default.createElement("div", {
165
+ style: this.portalStyles
166
+ }, this.props.children);
167
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/(0, _reactDom.createPortal)(content, document.body));
168
+ } else {
169
+ // Placeholder element for react to render inplace
170
+ /*#__PURE__*/_react.default.createElement("div", null);
171
+ }
114
172
  }
115
173
  }]);
116
174
  }(_react.default.PureComponent);
@@ -24,7 +24,7 @@ var Scrollable = exports.default = /*#__PURE__*/function (_React$PureComponent)
24
24
  args[_key] = arguments[_key];
25
25
  }
26
26
  _this = _callSuper(this, Scrollable, [].concat(args));
27
- // API
27
+ // Cleanup when removing mentions-migrate-react-dom
28
28
  (0, _defineProperty2.default)(_this, "reveal", function (child) {
29
29
  if (child && _this.scrollableDiv) {
30
30
  var childNode = (0, _reactDom.findDOMNode)(child);
@@ -39,6 +39,19 @@ var Scrollable = exports.default = /*#__PURE__*/function (_React$PureComponent)
39
39
  }
40
40
  }
41
41
  });
42
+ (0, _defineProperty2.default)(_this, "revealRef", function (ref) {
43
+ if (ref && ref.current && _this.scrollableDiv) {
44
+ // Not using Element.scrollIntoView as it scrolls even to top/bottom of view even if
45
+ // already visible
46
+ var scrollableRect = _this.scrollableDiv.getBoundingClientRect();
47
+ var elementRect = ref.current.getBoundingClientRect();
48
+ if (elementRect.top < scrollableRect.top) {
49
+ _this.scrollableDiv.scrollTop += elementRect.top - scrollableRect.top;
50
+ } else if (elementRect.bottom > scrollableRect.bottom) {
51
+ _this.scrollableDiv.scrollTop += elementRect.bottom - scrollableRect.bottom;
52
+ }
53
+ }
54
+ });
42
55
  (0, _defineProperty2.default)(_this, "handleRef", function (ref) {
43
56
  _this.scrollableDiv = ref;
44
57
  });
@@ -1,3 +1,4 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
1
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
3
  import Avatar from '@atlaskit/avatar';
3
4
  import Lozenge from '@atlaskit/lozenge';
@@ -61,7 +62,8 @@ export default class MentionItem extends React.PureComponent {
61
62
  render() {
62
63
  const {
63
64
  mention,
64
- selected
65
+ selected,
66
+ forwardedRef
65
67
  } = this.props;
66
68
  const {
67
69
  id,
@@ -91,7 +93,8 @@ export default class MentionItem extends React.PureComponent {
91
93
  "data-testid": `mention-item-${id}`,
92
94
  "data-mention-id": id,
93
95
  "data-mention-name": mentionName,
94
- "data-selected": selected
96
+ "data-selected": selected,
97
+ ref: forwardedRef
95
98
  }, /*#__PURE__*/React.createElement(RowStyle, null, /*#__PURE__*/React.createElement(AvatarStyle, {
96
99
  restricted: restricted
97
100
  }, fg('team-avatar-in-mention-picker') ? /*#__PURE__*/React.createElement(MentionAvatar, {
@@ -119,4 +122,9 @@ export default class MentionItem extends React.PureComponent {
119
122
  label: ''
120
123
  }))));
121
124
  }
122
- }
125
+ }
126
+ export const MentionItemWithRef = /*#__PURE__*/React.forwardRef((props, ref) => {
127
+ return /*#__PURE__*/React.createElement(MentionItem, _extends({}, props, {
128
+ forwardedRef: ref
129
+ }));
130
+ });
@@ -1,8 +1,9 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React from 'react';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
3
4
  import debug from '../../util/logger';
4
5
  import { actualMouseMove, mouseLocation } from '../../util/mouse';
5
- import MentionItem from '../MentionItem';
6
+ import MentionItem, { MentionItemWithRef } from '../MentionItem';
6
7
  import MentionListError from '../MentionListError';
7
8
  import MessagesIntlProvider from '../MessagesIntlProvider';
8
9
  import Scrollable from '../Scrollable';
@@ -102,8 +103,17 @@ export default class MentionList extends React.PureComponent {
102
103
  _defineProperty(this, "handleScrollableRef", ref => {
103
104
  this.scrollable = ref;
104
105
  });
106
+ this.itemsRefs = new Map();
105
107
  this.setDefaultSelectionState();
106
108
  }
109
+ createItemRef(key) {
110
+ const itemRef = /*#__PURE__*/React.createRef();
111
+ this.itemsRefs.set(key, itemRef);
112
+ return itemRef;
113
+ }
114
+ getItemRef(key) {
115
+ return this.itemsRefs.get(key);
116
+ }
107
117
  UNSAFE_componentWillReceiveProps(nextProps) {
108
118
  // adjust selection
109
119
  const {
@@ -147,9 +157,16 @@ export default class MentionList extends React.PureComponent {
147
157
 
148
158
  // Internal
149
159
  revealItem(key) {
150
- const item = this.items[key];
151
- if (item && this.scrollable) {
152
- this.scrollable.reveal(item);
160
+ if (fg('mentions-migrate-react-dom')) {
161
+ const itemRef = this.getItemRef(key);
162
+ if (itemRef && this.scrollable) {
163
+ itemRef && this.scrollable.revealRef(itemRef);
164
+ }
165
+ } else {
166
+ const item = this.items[key];
167
+ if (item && this.scrollable) {
168
+ this.scrollable.reveal(item);
169
+ }
153
170
  }
154
171
  }
155
172
 
@@ -170,24 +187,40 @@ export default class MentionList extends React.PureComponent {
170
187
  this.items = {};
171
188
  return /*#__PURE__*/React.createElement("div", null, this.props.initialHighlightElement, mentions.map((mention, idx) => {
172
189
  const key = mention.id;
173
- const item = /*#__PURE__*/React.createElement(MentionItem, {
174
- mention: mention,
175
- selected: this.isSelectedMention(mention, idx),
176
- key: key,
177
- onMouseMove: this.selectIndexOnHover
178
- /* Cannot use onclick, as onblur will close the element, and prevent
179
- * onClick from firing.
180
- */,
181
- onSelection: this.itemSelected,
182
- ref: ref => {
183
- if (ref) {
184
- this.items[key] = ref;
185
- } else {
186
- delete this.items[key];
190
+ const ref = this.createItemRef(key);
191
+ if (fg('mentions-migrate-react-dom')) {
192
+ const item = /*#__PURE__*/React.createElement(MentionItemWithRef, {
193
+ mention: mention,
194
+ selected: this.isSelectedMention(mention, idx),
195
+ key: key,
196
+ onMouseMove: this.selectIndexOnHover
197
+ /* Cannot use onclick, as onblur will close the element, and prevent
198
+ * onClick from firing.
199
+ */,
200
+ onSelection: this.itemSelected,
201
+ ref: ref
202
+ });
203
+ return item;
204
+ } else {
205
+ const item = /*#__PURE__*/React.createElement(MentionItem, {
206
+ mention: mention,
207
+ selected: this.isSelectedMention(mention, idx),
208
+ key: key,
209
+ onMouseMove: this.selectIndexOnHover
210
+ /* Cannot use onclick, as onblur will close the element, and prevent
211
+ * onClick from firing.
212
+ */,
213
+ onSelection: this.itemSelected,
214
+ ref: ref => {
215
+ if (ref) {
216
+ this.items[key] = ref;
217
+ } else {
218
+ delete this.items[key];
219
+ }
187
220
  }
188
- }
189
- });
190
- return item;
221
+ });
222
+ return item;
223
+ }
191
224
  }));
192
225
  }
193
226
  return null;
@@ -1,8 +1,8 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { Text } from '@atlaskit/primitives/compiled';
3
- import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
4
2
  import React from 'react';
5
3
  import { IntlProvider, injectIntl } from 'react-intl-next';
4
+ import { Text } from '@atlaskit/primitives/compiled';
5
+ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
6
6
  import { fireAnalyticsMentionTypeaheadEvent } from '../../util/analytics';
7
7
  import uniqueId from '../../util/id';
8
8
  import debug from '../../util/logger';
@@ -1,14 +1,33 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React from 'react';
3
- import ReactDOM from 'react-dom';
3
+ import ReactDOM, { createPortal } from 'react-dom';
4
+ import { fg } from '@atlaskit/platform-feature-flags';
4
5
  /*
5
6
  * Simple implementation of popup while waiting for ak-inline-dialog
6
7
  */
7
8
  export default class Popup extends React.PureComponent {
9
+ constructor(props) {
10
+ super(props);
11
+ this.portalStyles = {
12
+ position: 'absolute',
13
+ top: null,
14
+ bottom: null,
15
+ left: null,
16
+ zIndex: null
17
+ };
18
+ }
19
+ setPortalStyles(styles) {
20
+ this.portalStyles = {
21
+ ...this.portalStyles,
22
+ ...styles
23
+ };
24
+ }
8
25
  componentDidMount() {
9
- this.popup = document.createElement('div');
10
- document.body.appendChild(this.popup);
11
- this.popup.style.position = 'absolute';
26
+ if (!fg('mentions-migrate-react-dom')) {
27
+ this.popup = document.createElement('div');
28
+ document.body.appendChild(this.popup);
29
+ this.popup.style.position = 'absolute';
30
+ }
12
31
  this._applyAbsolutePosition();
13
32
  this._renderContent();
14
33
  }
@@ -16,9 +35,11 @@ export default class Popup extends React.PureComponent {
16
35
  this._renderContent();
17
36
  }
18
37
  componentWillUnmount() {
19
- if (this.popup) {
20
- ReactDOM.unmountComponentAtNode(this.popup);
21
- document.body.removeChild(this.popup);
38
+ if (!fg('mentions-migrate-react-dom')) {
39
+ if (this.popup) {
40
+ ReactDOM.unmountComponentAtNode(this.popup);
41
+ document.body.removeChild(this.popup);
42
+ }
22
43
  }
23
44
  }
24
45
  _applyBelowPosition() {
@@ -27,10 +48,18 @@ export default class Popup extends React.PureComponent {
27
48
  const box = targetNode.getBoundingClientRect();
28
49
  const top = box.bottom + (this.props.offsetY || 0);
29
50
  const left = box.left + (this.props.offsetX || 0);
30
- if (this.popup) {
31
- this.popup.style.top = `${top}px`;
32
- this.popup.style.bottom = '';
33
- this.popup.style.left = `${left}px`;
51
+ if (fg('mentions-migrate-react-dom')) {
52
+ this.setPortalStyles({
53
+ top: `${top}px`,
54
+ bottom: '',
55
+ left: `${left}px`
56
+ });
57
+ } else {
58
+ if (this.popup) {
59
+ this.popup.style.top = `${top}px`;
60
+ this.popup.style.bottom = '';
61
+ this.popup.style.left = `${left}px`;
62
+ }
34
63
  }
35
64
  }
36
65
  }
@@ -40,10 +69,18 @@ export default class Popup extends React.PureComponent {
40
69
  const box = targetNode.getBoundingClientRect();
41
70
  const bottom = window.innerHeight - box.top + (this.props.offsetY || 0);
42
71
  const left = box.left + (this.props.offsetX || 0);
43
- if (this.popup) {
44
- this.popup.style.top = '';
45
- this.popup.style.bottom = `${bottom}px`;
46
- this.popup.style.left = `${left}px`;
72
+ if (fg('mentions-migrate-react-dom')) {
73
+ this.setPortalStyles({
74
+ top: '',
75
+ bottom: `${bottom}px`,
76
+ left: `${left}px`
77
+ });
78
+ } else {
79
+ if (this.popup) {
80
+ this.popup.style.top = '';
81
+ this.popup.style.bottom = `${bottom}px`;
82
+ this.popup.style.left = `${left}px`;
83
+ }
47
84
  }
48
85
  }
49
86
  }
@@ -64,18 +101,37 @@ export default class Popup extends React.PureComponent {
64
101
  }
65
102
  }
66
103
  }
67
- if (this.props.zIndex && this.popup) {
68
- this.popup.style.zIndex = `${this.props.zIndex}`;
104
+ if (fg('mentions-migrate-react-dom')) {
105
+ if (this.props.zIndex) {
106
+ this.setPortalStyles({
107
+ zIndex: this.props.zIndex
108
+ });
109
+ }
110
+ } else {
111
+ if (this.props.zIndex && this.popup) {
112
+ this.popup.style.zIndex = `${this.props.zIndex}`;
113
+ }
69
114
  }
70
115
  }
71
116
  _renderContent() {
72
- if (this.popup) {
73
- ReactDOM.render(this.props.children, this.popup);
117
+ if (!fg('mentions-migrate-react-dom')) {
118
+ if (this.popup) {
119
+ ReactDOM.render(this.props.children, this.popup);
120
+ }
74
121
  }
75
122
  }
76
123
  render() {
77
- // Placeholder element for react to render inplace
78
- return /*#__PURE__*/React.createElement("div", null);
124
+ if (fg('mentions-migrate-react-dom')) {
125
+ // https://atlassian.design/components/eslint-plugin-ui-styling-standard/migration-guide#dynamic-styles
126
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
127
+ const content = /*#__PURE__*/React.createElement("div", {
128
+ style: this.portalStyles
129
+ }, this.props.children);
130
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/createPortal(content, document.body));
131
+ } else {
132
+ // Placeholder element for react to render inplace
133
+ /*#__PURE__*/React.createElement("div", null);
134
+ }
79
135
  }
80
136
  }
81
137
  _defineProperty(Popup, "defaultProps", {
@@ -5,7 +5,7 @@ import { ScrollableStyle } from './styles';
5
5
  export default class Scrollable extends React.PureComponent {
6
6
  constructor(...args) {
7
7
  super(...args);
8
- // API
8
+ // Cleanup when removing mentions-migrate-react-dom
9
9
  _defineProperty(this, "reveal", child => {
10
10
  if (child && this.scrollableDiv) {
11
11
  const childNode = findDOMNode(child);
@@ -20,6 +20,19 @@ export default class Scrollable extends React.PureComponent {
20
20
  }
21
21
  }
22
22
  });
23
+ _defineProperty(this, "revealRef", ref => {
24
+ if (ref && ref.current && this.scrollableDiv) {
25
+ // Not using Element.scrollIntoView as it scrolls even to top/bottom of view even if
26
+ // already visible
27
+ const scrollableRect = this.scrollableDiv.getBoundingClientRect();
28
+ const elementRect = ref.current.getBoundingClientRect();
29
+ if (elementRect.top < scrollableRect.top) {
30
+ this.scrollableDiv.scrollTop += elementRect.top - scrollableRect.top;
31
+ } else if (elementRect.bottom > scrollableRect.bottom) {
32
+ this.scrollableDiv.scrollTop += elementRect.bottom - scrollableRect.bottom;
33
+ }
34
+ }
35
+ });
23
36
  _defineProperty(this, "handleRef", ref => {
24
37
  this.scrollableDiv = ref;
25
38
  });
@@ -1,3 +1,4 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
1
2
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
3
  import _createClass from "@babel/runtime/helpers/createClass";
3
4
  import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
@@ -76,7 +77,8 @@ var MentionItem = /*#__PURE__*/function (_React$PureComponent) {
76
77
  value: function render() {
77
78
  var _this$props = this.props,
78
79
  mention = _this$props.mention,
79
- selected = _this$props.selected;
80
+ selected = _this$props.selected,
81
+ forwardedRef = _this$props.forwardedRef;
80
82
  var id = mention.id,
81
83
  highlight = mention.highlight,
82
84
  avatarUrl = mention.avatarUrl,
@@ -102,7 +104,8 @@ var MentionItem = /*#__PURE__*/function (_React$PureComponent) {
102
104
  "data-testid": "mention-item-".concat(id),
103
105
  "data-mention-id": id,
104
106
  "data-mention-name": mentionName,
105
- "data-selected": selected
107
+ "data-selected": selected,
108
+ ref: forwardedRef
106
109
  }, /*#__PURE__*/React.createElement(RowStyle, null, /*#__PURE__*/React.createElement(AvatarStyle, {
107
110
  restricted: restricted
108
111
  }, fg('team-avatar-in-mention-picker') ? /*#__PURE__*/React.createElement(MentionAvatar, {
@@ -134,4 +137,9 @@ var MentionItem = /*#__PURE__*/function (_React$PureComponent) {
134
137
  }
135
138
  }]);
136
139
  }(React.PureComponent);
137
- export { MentionItem as default };
140
+ export { MentionItem as default };
141
+ export var MentionItemWithRef = /*#__PURE__*/React.forwardRef(function (props, ref) {
142
+ return /*#__PURE__*/React.createElement(MentionItem, _extends({}, props, {
143
+ forwardedRef: ref
144
+ }));
145
+ });
@@ -7,9 +7,10 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
7
7
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
8
8
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
9
9
  import React from 'react';
10
+ import { fg } from '@atlaskit/platform-feature-flags';
10
11
  import debug from '../../util/logger';
11
12
  import { actualMouseMove, mouseLocation } from '../../util/mouse';
12
- import MentionItem from '../MentionItem';
13
+ import MentionItem, { MentionItemWithRef } from '../MentionItem';
13
14
  import MentionListError from '../MentionListError';
14
15
  import MessagesIntlProvider from '../MessagesIntlProvider';
15
16
  import Scrollable from '../Scrollable';
@@ -102,11 +103,24 @@ var MentionList = /*#__PURE__*/function (_React$PureComponent) {
102
103
  _defineProperty(_this, "handleScrollableRef", function (ref) {
103
104
  _this.scrollable = ref;
104
105
  });
106
+ _this.itemsRefs = new Map();
105
107
  _this.setDefaultSelectionState();
106
108
  return _this;
107
109
  }
108
110
  _inherits(MentionList, _React$PureComponent);
109
111
  return _createClass(MentionList, [{
112
+ key: "createItemRef",
113
+ value: function createItemRef(key) {
114
+ var itemRef = /*#__PURE__*/React.createRef();
115
+ this.itemsRefs.set(key, itemRef);
116
+ return itemRef;
117
+ }
118
+ }, {
119
+ key: "getItemRef",
120
+ value: function getItemRef(key) {
121
+ return this.itemsRefs.get(key);
122
+ }
123
+ }, {
110
124
  key: "UNSAFE_componentWillReceiveProps",
111
125
  value: function UNSAFE_componentWillReceiveProps(nextProps) {
112
126
  // adjust selection
@@ -147,9 +161,16 @@ var MentionList = /*#__PURE__*/function (_React$PureComponent) {
147
161
  value:
148
162
  // Internal
149
163
  function revealItem(key) {
150
- var item = this.items[key];
151
- if (item && this.scrollable) {
152
- this.scrollable.reveal(item);
164
+ if (fg('mentions-migrate-react-dom')) {
165
+ var itemRef = this.getItemRef(key);
166
+ if (itemRef && this.scrollable) {
167
+ itemRef && this.scrollable.revealRef(itemRef);
168
+ }
169
+ } else {
170
+ var item = this.items[key];
171
+ if (item && this.scrollable) {
172
+ this.scrollable.reveal(item);
173
+ }
153
174
  }
154
175
  }
155
176
 
@@ -173,24 +194,40 @@ var MentionList = /*#__PURE__*/function (_React$PureComponent) {
173
194
  this.items = {};
174
195
  return /*#__PURE__*/React.createElement("div", null, this.props.initialHighlightElement, mentions.map(function (mention, idx) {
175
196
  var key = mention.id;
176
- var item = /*#__PURE__*/React.createElement(MentionItem, {
177
- mention: mention,
178
- selected: _this2.isSelectedMention(mention, idx),
179
- key: key,
180
- onMouseMove: _this2.selectIndexOnHover
181
- /* Cannot use onclick, as onblur will close the element, and prevent
182
- * onClick from firing.
183
- */,
184
- onSelection: _this2.itemSelected,
185
- ref: function ref(_ref) {
186
- if (_ref) {
187
- _this2.items[key] = _ref;
188
- } else {
189
- delete _this2.items[key];
197
+ var ref = _this2.createItemRef(key);
198
+ if (fg('mentions-migrate-react-dom')) {
199
+ var item = /*#__PURE__*/React.createElement(MentionItemWithRef, {
200
+ mention: mention,
201
+ selected: _this2.isSelectedMention(mention, idx),
202
+ key: key,
203
+ onMouseMove: _this2.selectIndexOnHover
204
+ /* Cannot use onclick, as onblur will close the element, and prevent
205
+ * onClick from firing.
206
+ */,
207
+ onSelection: _this2.itemSelected,
208
+ ref: ref
209
+ });
210
+ return item;
211
+ } else {
212
+ var _item = /*#__PURE__*/React.createElement(MentionItem, {
213
+ mention: mention,
214
+ selected: _this2.isSelectedMention(mention, idx),
215
+ key: key,
216
+ onMouseMove: _this2.selectIndexOnHover
217
+ /* Cannot use onclick, as onblur will close the element, and prevent
218
+ * onClick from firing.
219
+ */,
220
+ onSelection: _this2.itemSelected,
221
+ ref: function ref(_ref) {
222
+ if (_ref) {
223
+ _this2.items[key] = _ref;
224
+ } else {
225
+ delete _this2.items[key];
226
+ }
190
227
  }
191
- }
192
- });
193
- return item;
228
+ });
229
+ return _item;
230
+ }
194
231
  }));
195
232
  }
196
233
  return null;
@@ -6,10 +6,10 @@ import _inherits from "@babel/runtime/helpers/inherits";
6
6
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
7
7
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
8
8
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
9
- import { Text } from '@atlaskit/primitives/compiled';
10
- import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
11
9
  import React from 'react';
12
10
  import { IntlProvider, injectIntl } from 'react-intl-next';
11
+ import { Text } from '@atlaskit/primitives/compiled';
12
+ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
13
13
  import { fireAnalyticsMentionTypeaheadEvent } from '../../util/analytics';
14
14
  import uniqueId from '../../util/id';
15
15
  import debug from '../../util/logger';
@@ -4,25 +4,44 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
4
4
  import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
5
5
  import _inherits from "@babel/runtime/helpers/inherits";
6
6
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
7
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
8
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
9
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
8
10
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
9
11
  import React from 'react';
10
- import ReactDOM from 'react-dom';
12
+ import ReactDOM, { createPortal } from 'react-dom';
13
+ import { fg } from '@atlaskit/platform-feature-flags';
11
14
  /*
12
15
  * Simple implementation of popup while waiting for ak-inline-dialog
13
16
  */
14
17
  var Popup = /*#__PURE__*/function (_React$PureComponent) {
15
- function Popup() {
18
+ function Popup(props) {
19
+ var _this;
16
20
  _classCallCheck(this, Popup);
17
- return _callSuper(this, Popup, arguments);
21
+ _this = _callSuper(this, Popup, [props]);
22
+ _this.portalStyles = {
23
+ position: 'absolute',
24
+ top: null,
25
+ bottom: null,
26
+ left: null,
27
+ zIndex: null
28
+ };
29
+ return _this;
18
30
  }
19
31
  _inherits(Popup, _React$PureComponent);
20
32
  return _createClass(Popup, [{
33
+ key: "setPortalStyles",
34
+ value: function setPortalStyles(styles) {
35
+ this.portalStyles = _objectSpread(_objectSpread({}, this.portalStyles), styles);
36
+ }
37
+ }, {
21
38
  key: "componentDidMount",
22
39
  value: function componentDidMount() {
23
- this.popup = document.createElement('div');
24
- document.body.appendChild(this.popup);
25
- this.popup.style.position = 'absolute';
40
+ if (!fg('mentions-migrate-react-dom')) {
41
+ this.popup = document.createElement('div');
42
+ document.body.appendChild(this.popup);
43
+ this.popup.style.position = 'absolute';
44
+ }
26
45
  this._applyAbsolutePosition();
27
46
  this._renderContent();
28
47
  }
@@ -34,9 +53,11 @@ var Popup = /*#__PURE__*/function (_React$PureComponent) {
34
53
  }, {
35
54
  key: "componentWillUnmount",
36
55
  value: function componentWillUnmount() {
37
- if (this.popup) {
38
- ReactDOM.unmountComponentAtNode(this.popup);
39
- document.body.removeChild(this.popup);
56
+ if (!fg('mentions-migrate-react-dom')) {
57
+ if (this.popup) {
58
+ ReactDOM.unmountComponentAtNode(this.popup);
59
+ document.body.removeChild(this.popup);
60
+ }
40
61
  }
41
62
  }
42
63
  }, {
@@ -47,10 +68,18 @@ var Popup = /*#__PURE__*/function (_React$PureComponent) {
47
68
  var box = targetNode.getBoundingClientRect();
48
69
  var top = box.bottom + (this.props.offsetY || 0);
49
70
  var left = box.left + (this.props.offsetX || 0);
50
- if (this.popup) {
51
- this.popup.style.top = "".concat(top, "px");
52
- this.popup.style.bottom = '';
53
- this.popup.style.left = "".concat(left, "px");
71
+ if (fg('mentions-migrate-react-dom')) {
72
+ this.setPortalStyles({
73
+ top: "".concat(top, "px"),
74
+ bottom: '',
75
+ left: "".concat(left, "px")
76
+ });
77
+ } else {
78
+ if (this.popup) {
79
+ this.popup.style.top = "".concat(top, "px");
80
+ this.popup.style.bottom = '';
81
+ this.popup.style.left = "".concat(left, "px");
82
+ }
54
83
  }
55
84
  }
56
85
  }
@@ -62,10 +91,18 @@ var Popup = /*#__PURE__*/function (_React$PureComponent) {
62
91
  var box = targetNode.getBoundingClientRect();
63
92
  var bottom = window.innerHeight - box.top + (this.props.offsetY || 0);
64
93
  var left = box.left + (this.props.offsetX || 0);
65
- if (this.popup) {
66
- this.popup.style.top = '';
67
- this.popup.style.bottom = "".concat(bottom, "px");
68
- this.popup.style.left = "".concat(left, "px");
94
+ if (fg('mentions-migrate-react-dom')) {
95
+ this.setPortalStyles({
96
+ top: '',
97
+ bottom: "".concat(bottom, "px"),
98
+ left: "".concat(left, "px")
99
+ });
100
+ } else {
101
+ if (this.popup) {
102
+ this.popup.style.top = '';
103
+ this.popup.style.bottom = "".concat(bottom, "px");
104
+ this.popup.style.left = "".concat(left, "px");
105
+ }
69
106
  }
70
107
  }
71
108
  }
@@ -88,22 +125,41 @@ var Popup = /*#__PURE__*/function (_React$PureComponent) {
88
125
  }
89
126
  }
90
127
  }
91
- if (this.props.zIndex && this.popup) {
92
- this.popup.style.zIndex = "".concat(this.props.zIndex);
128
+ if (fg('mentions-migrate-react-dom')) {
129
+ if (this.props.zIndex) {
130
+ this.setPortalStyles({
131
+ zIndex: this.props.zIndex
132
+ });
133
+ }
134
+ } else {
135
+ if (this.props.zIndex && this.popup) {
136
+ this.popup.style.zIndex = "".concat(this.props.zIndex);
137
+ }
93
138
  }
94
139
  }
95
140
  }, {
96
141
  key: "_renderContent",
97
142
  value: function _renderContent() {
98
- if (this.popup) {
99
- ReactDOM.render(this.props.children, this.popup);
143
+ if (!fg('mentions-migrate-react-dom')) {
144
+ if (this.popup) {
145
+ ReactDOM.render(this.props.children, this.popup);
146
+ }
100
147
  }
101
148
  }
102
149
  }, {
103
150
  key: "render",
104
151
  value: function render() {
105
- // Placeholder element for react to render inplace
106
- return /*#__PURE__*/React.createElement("div", null);
152
+ if (fg('mentions-migrate-react-dom')) {
153
+ // https://atlassian.design/components/eslint-plugin-ui-styling-standard/migration-guide#dynamic-styles
154
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
155
+ var content = /*#__PURE__*/React.createElement("div", {
156
+ style: this.portalStyles
157
+ }, this.props.children);
158
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/createPortal(content, document.body));
159
+ } else {
160
+ // Placeholder element for react to render inplace
161
+ /*#__PURE__*/React.createElement("div", null);
162
+ }
107
163
  }
108
164
  }]);
109
165
  }(React.PureComponent);
@@ -17,7 +17,7 @@ var Scrollable = /*#__PURE__*/function (_React$PureComponent) {
17
17
  args[_key] = arguments[_key];
18
18
  }
19
19
  _this = _callSuper(this, Scrollable, [].concat(args));
20
- // API
20
+ // Cleanup when removing mentions-migrate-react-dom
21
21
  _defineProperty(_this, "reveal", function (child) {
22
22
  if (child && _this.scrollableDiv) {
23
23
  var childNode = findDOMNode(child);
@@ -32,6 +32,19 @@ var Scrollable = /*#__PURE__*/function (_React$PureComponent) {
32
32
  }
33
33
  }
34
34
  });
35
+ _defineProperty(_this, "revealRef", function (ref) {
36
+ if (ref && ref.current && _this.scrollableDiv) {
37
+ // Not using Element.scrollIntoView as it scrolls even to top/bottom of view even if
38
+ // already visible
39
+ var scrollableRect = _this.scrollableDiv.getBoundingClientRect();
40
+ var elementRect = ref.current.getBoundingClientRect();
41
+ if (elementRect.top < scrollableRect.top) {
42
+ _this.scrollableDiv.scrollTop += elementRect.top - scrollableRect.top;
43
+ } else if (elementRect.bottom > scrollableRect.bottom) {
44
+ _this.scrollableDiv.scrollTop += elementRect.bottom - scrollableRect.bottom;
45
+ }
46
+ }
47
+ });
35
48
  _defineProperty(_this, "handleRef", function (ref) {
36
49
  _this.scrollableDiv = ref;
37
50
  });
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { type MentionDescription, type OnMentionEvent } from '../../types';
3
3
  export { MENTION_ITEM_HEIGHT } from './styles';
4
4
  export interface Props {
5
+ forwardedRef?: React.Ref<HTMLDivElement>;
5
6
  mention: MentionDescription;
6
7
  onMouseEnter?: OnMentionEvent;
7
8
  onMouseMove?: OnMentionEvent;
@@ -14,3 +15,4 @@ export default class MentionItem extends React.PureComponent<Props, {}> {
14
15
  private onMentionMenuItemMouseEnter;
15
16
  render(): React.JSX.Element;
16
17
  }
18
+ export declare const MentionItemWithRef: React.ForwardRefExoticComponent<Omit<Props, "forwardedRef"> & React.RefAttributes<HTMLDivElement>>;
@@ -18,7 +18,10 @@ export default class MentionList extends React.PureComponent<Props, State> {
18
18
  private lastMousePosition;
19
19
  private scrollable?;
20
20
  private items;
21
+ private itemsRefs;
21
22
  constructor(props: Props);
23
+ createItemRef(key: string): React.RefObject<HTMLDivElement>;
24
+ getItemRef(key: string): React.RefObject<HTMLDivElement> | undefined;
22
25
  UNSAFE_componentWillReceiveProps(nextProps: Props): void;
23
26
  componentDidUpdate(): void;
24
27
  selectNext: () => void;
@@ -1,6 +1,6 @@
1
- import { type WithAnalyticsEventsProps } from '@atlaskit/analytics-next/withAnalyticsEvents';
2
1
  import React from 'react';
3
2
  import { type IntlShape } from 'react-intl-next';
3
+ import { type WithAnalyticsEventsProps } from '@atlaskit/analytics-next/withAnalyticsEvents';
4
4
  import { type MentionProvider } from '../../api/MentionResource';
5
5
  import { type PresenceProvider } from '../../api/PresenceResource';
6
6
  import { type OnMentionEvent } from '../../types';
@@ -9,6 +9,9 @@ export interface Props {
9
9
  }
10
10
  export default class Popup extends React.PureComponent<Props, {}> {
11
11
  private popup?;
12
+ private portalStyles;
13
+ constructor(props: Props);
14
+ setPortalStyles(styles: Record<string, string | number | null>): void;
12
15
  static defaultProps: {
13
16
  relativePosition: string;
14
17
  offsetX: number;
@@ -22,5 +25,5 @@ export default class Popup extends React.PureComponent<Props, {}> {
22
25
  _applyAbovePosition(): void;
23
26
  _applyAbsolutePosition(): void;
24
27
  _renderContent(): void;
25
- render(): React.JSX.Element;
28
+ render(): React.JSX.Element | undefined;
26
29
  }
@@ -6,6 +6,7 @@ export interface Props {
6
6
  export default class Scrollable extends React.PureComponent<Props, {}> {
7
7
  private scrollableDiv?;
8
8
  reveal: (child: MentionItem) => void;
9
+ revealRef: (ref: React.RefObject<HTMLDivElement>) => void;
9
10
  private handleRef;
10
11
  render(): React.JSX.Element;
11
12
  }
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import { type MentionDescription, type OnMentionEvent } from '../../types';
3
3
  export { MENTION_ITEM_HEIGHT } from './styles';
4
4
  export interface Props {
5
+ forwardedRef?: React.Ref<HTMLDivElement>;
5
6
  mention: MentionDescription;
6
7
  onMouseEnter?: OnMentionEvent;
7
8
  onMouseMove?: OnMentionEvent;
@@ -14,3 +15,4 @@ export default class MentionItem extends React.PureComponent<Props, {}> {
14
15
  private onMentionMenuItemMouseEnter;
15
16
  render(): React.JSX.Element;
16
17
  }
18
+ export declare const MentionItemWithRef: React.ForwardRefExoticComponent<Omit<Props, "forwardedRef"> & React.RefAttributes<HTMLDivElement>>;
@@ -18,7 +18,10 @@ export default class MentionList extends React.PureComponent<Props, State> {
18
18
  private lastMousePosition;
19
19
  private scrollable?;
20
20
  private items;
21
+ private itemsRefs;
21
22
  constructor(props: Props);
23
+ createItemRef(key: string): React.RefObject<HTMLDivElement>;
24
+ getItemRef(key: string): React.RefObject<HTMLDivElement> | undefined;
22
25
  UNSAFE_componentWillReceiveProps(nextProps: Props): void;
23
26
  componentDidUpdate(): void;
24
27
  selectNext: () => void;
@@ -1,6 +1,6 @@
1
- import { type WithAnalyticsEventsProps } from '@atlaskit/analytics-next/withAnalyticsEvents';
2
1
  import React from 'react';
3
2
  import { type IntlShape } from 'react-intl-next';
3
+ import { type WithAnalyticsEventsProps } from '@atlaskit/analytics-next/withAnalyticsEvents';
4
4
  import { type MentionProvider } from '../../api/MentionResource';
5
5
  import { type PresenceProvider } from '../../api/PresenceResource';
6
6
  import { type OnMentionEvent } from '../../types';
@@ -9,6 +9,9 @@ export interface Props {
9
9
  }
10
10
  export default class Popup extends React.PureComponent<Props, {}> {
11
11
  private popup?;
12
+ private portalStyles;
13
+ constructor(props: Props);
14
+ setPortalStyles(styles: Record<string, string | number | null>): void;
12
15
  static defaultProps: {
13
16
  relativePosition: string;
14
17
  offsetX: number;
@@ -22,5 +25,5 @@ export default class Popup extends React.PureComponent<Props, {}> {
22
25
  _applyAbovePosition(): void;
23
26
  _applyAbsolutePosition(): void;
24
27
  _renderContent(): void;
25
- render(): React.JSX.Element;
28
+ render(): React.JSX.Element | undefined;
26
29
  }
@@ -6,6 +6,7 @@ export interface Props {
6
6
  export default class Scrollable extends React.PureComponent<Props, {}> {
7
7
  private scrollableDiv?;
8
8
  reveal: (child: MentionItem) => void;
9
+ revealRef: (ref: React.RefObject<HTMLDivElement>) => void;
9
10
  private handleRef;
10
11
  render(): React.JSX.Element;
11
12
  }
package/package.json CHANGED
@@ -22,17 +22,17 @@
22
22
  "@atlaskit/afm-i18n-platform-elements-mention": "2.7.0",
23
23
  "@atlaskit/analytics-gas-types": "^5.1.0",
24
24
  "@atlaskit/analytics-next": "^11.1.0",
25
- "@atlaskit/avatar": "^25.1.0",
25
+ "@atlaskit/avatar": "^25.3.0",
26
26
  "@atlaskit/focus-ring": "^3.0.0",
27
27
  "@atlaskit/heading": "^5.2.0",
28
- "@atlaskit/icon": "^28.2.0",
28
+ "@atlaskit/icon": "^28.5.0",
29
29
  "@atlaskit/lozenge": "^13.0.0",
30
30
  "@atlaskit/platform-feature-flags": "^1.1.0",
31
31
  "@atlaskit/primitives": "^14.15.0",
32
32
  "@atlaskit/teams-avatar": "^2.3.0",
33
33
  "@atlaskit/theme": "^21.0.0",
34
- "@atlaskit/tokens": "^6.3.0",
35
- "@atlaskit/tooltip": "^20.4.0",
34
+ "@atlaskit/tokens": "^6.4.0",
35
+ "@atlaskit/tooltip": "^20.5.0",
36
36
  "@atlaskit/ufo": "^0.4.0",
37
37
  "@atlaskit/util-service-support": "^6.3.0",
38
38
  "@babel/runtime": "^7.0.0",
@@ -78,6 +78,9 @@
78
78
  "platform-feature-flags": {
79
79
  "team-avatar-in-mention-picker": {
80
80
  "type": "boolean"
81
+ },
82
+ "mentions-migrate-react-dom": {
83
+ "type": "boolean"
81
84
  }
82
85
  },
83
86
  "publishConfig": {
@@ -105,5 +108,5 @@
105
108
  ]
106
109
  }
107
110
  },
108
- "version": "24.2.17"
111
+ "version": "24.3.0"
109
112
  }