@atlaskit/popup 1.11.4 → 1.11.5

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @atlaskit/popup
2
2
 
3
+ ## 1.11.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#40944](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/40944) [`c6b7d977655`](https://bitbucket.org/atlassian/atlassian-frontend/commits/c6b7d977655) - Memoize the Popup Trigger's ref to avoid unnecessary renders.
8
+
3
9
  ## 1.11.4
4
10
 
5
11
  ### Patch Changes
package/dist/cjs/popup.js CHANGED
@@ -8,6 +8,7 @@ exports.default = exports.Popup = void 0;
8
8
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
9
  var _react = require("react");
10
10
  var _react2 = require("@emotion/react");
11
+ var _memoizeOne = _interopRequireDefault(require("memoize-one"));
11
12
  var _layering = require("@atlaskit/layering");
12
13
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
14
  var _popper = require("@atlaskit/popper");
@@ -47,6 +48,33 @@ var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
47
48
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
48
49
  triggerRef = _useState2[0],
49
50
  setTriggerRef = _useState2[1];
51
+
52
+ /*
53
+ * Get a memoized functional ref for use within this Popup's Trigger.
54
+ * This is still very volatile to change as `prop.isOpen` will regularly change, but it's better than nothing.
55
+ * This is memoized within our component as to not be shared across all Popup instances, just this one.
56
+ *
57
+ * This is complex because the inputs are split across three different scopes:
58
+ * - `props.isOpen`
59
+ * - `useState.setTriggerRef`
60
+ * - `renderProps.ref`
61
+ */
62
+ var _useState3 = (0, _react.useState)(function () {
63
+ return (0, _memoizeOne.default)(function (ref, setTriggerRef, isOpen) {
64
+ return function (node) {
65
+ if (node && isOpen) {
66
+ if (typeof ref === 'function') {
67
+ ref(node);
68
+ } else if (ref) {
69
+ ref.current = node;
70
+ }
71
+ setTriggerRef(node);
72
+ }
73
+ };
74
+ });
75
+ }),
76
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 1),
77
+ getMergedTriggerRef = _useState4[0];
50
78
  var renderPopperWrapper = (0, _react2.jsx)(_layering.UNSAFE_LAYERING, {
51
79
  isDisabled: (0, _platformFeatureFlags.getBooleanFF)('platform.design-system-team.layering_popup_1cnzt') ? false : true
52
80
  }, (0, _react2.jsx)(_popperWrapper.default, {
@@ -68,18 +96,9 @@ var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
68
96
  triggerRef: triggerRef
69
97
  }));
70
98
  return (0, _react2.jsx)(_popper.Manager, null, (0, _react2.jsx)(_popper.Reference, null, function (_ref2) {
71
- var _ref3 = _ref2.ref;
99
+ var ref = _ref2.ref;
72
100
  return trigger({
73
- ref: function ref(node) {
74
- if (node && isOpen) {
75
- if (typeof _ref3 === 'function') {
76
- _ref3(node);
77
- } else {
78
- _ref3.current = node;
79
- }
80
- setTriggerRef(node);
81
- }
82
- },
101
+ ref: getMergedTriggerRef(ref, setTriggerRef, isOpen),
83
102
  'aria-controls': id,
84
103
  'aria-expanded': isOpen,
85
104
  'aria-haspopup': true
@@ -2,6 +2,7 @@
2
2
  /** @jsx jsx */
3
3
  import { memo, useState } from 'react';
4
4
  import { jsx } from '@emotion/react';
5
+ import memoizeOne from 'memoize-one';
5
6
  import { UNSAFE_LAYERING } from '@atlaskit/layering';
6
7
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
7
8
  import { Manager, Reference } from '@atlaskit/popper';
@@ -29,6 +30,29 @@ export const Popup = /*#__PURE__*/memo(({
29
30
  shouldRenderToParent = false
30
31
  }) => {
31
32
  const [triggerRef, setTriggerRef] = useState(null);
33
+
34
+ /*
35
+ * Get a memoized functional ref for use within this Popup's Trigger.
36
+ * This is still very volatile to change as `prop.isOpen` will regularly change, but it's better than nothing.
37
+ * This is memoized within our component as to not be shared across all Popup instances, just this one.
38
+ *
39
+ * This is complex because the inputs are split across three different scopes:
40
+ * - `props.isOpen`
41
+ * - `useState.setTriggerRef`
42
+ * - `renderProps.ref`
43
+ */
44
+ const [getMergedTriggerRef] = useState(() => memoizeOne((ref, setTriggerRef, isOpen) => {
45
+ return node => {
46
+ if (node && isOpen) {
47
+ if (typeof ref === 'function') {
48
+ ref(node);
49
+ } else if (ref) {
50
+ ref.current = node;
51
+ }
52
+ setTriggerRef(node);
53
+ }
54
+ };
55
+ }));
32
56
  const renderPopperWrapper = jsx(UNSAFE_LAYERING, {
33
57
  isDisabled: getBooleanFF('platform.design-system-team.layering_popup_1cnzt') ? false : true
34
58
  }, jsx(PopperWrapper, {
@@ -53,16 +77,7 @@ export const Popup = /*#__PURE__*/memo(({
53
77
  ref
54
78
  }) => {
55
79
  return trigger({
56
- ref: node => {
57
- if (node && isOpen) {
58
- if (typeof ref === 'function') {
59
- ref(node);
60
- } else {
61
- ref.current = node;
62
- }
63
- setTriggerRef(node);
64
- }
65
- },
80
+ ref: getMergedTriggerRef(ref, setTriggerRef, isOpen),
66
81
  'aria-controls': id,
67
82
  'aria-expanded': isOpen,
68
83
  'aria-haspopup': true
package/dist/esm/popup.js CHANGED
@@ -3,6 +3,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  /** @jsx jsx */
4
4
  import { memo, useState } from 'react';
5
5
  import { jsx } from '@emotion/react';
6
+ import memoizeOne from 'memoize-one';
6
7
  import { UNSAFE_LAYERING } from '@atlaskit/layering';
7
8
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
8
9
  import { Manager, Reference } from '@atlaskit/popper';
@@ -39,6 +40,33 @@ export var Popup = /*#__PURE__*/memo(function (_ref) {
39
40
  _useState2 = _slicedToArray(_useState, 2),
40
41
  triggerRef = _useState2[0],
41
42
  setTriggerRef = _useState2[1];
43
+
44
+ /*
45
+ * Get a memoized functional ref for use within this Popup's Trigger.
46
+ * This is still very volatile to change as `prop.isOpen` will regularly change, but it's better than nothing.
47
+ * This is memoized within our component as to not be shared across all Popup instances, just this one.
48
+ *
49
+ * This is complex because the inputs are split across three different scopes:
50
+ * - `props.isOpen`
51
+ * - `useState.setTriggerRef`
52
+ * - `renderProps.ref`
53
+ */
54
+ var _useState3 = useState(function () {
55
+ return memoizeOne(function (ref, setTriggerRef, isOpen) {
56
+ return function (node) {
57
+ if (node && isOpen) {
58
+ if (typeof ref === 'function') {
59
+ ref(node);
60
+ } else if (ref) {
61
+ ref.current = node;
62
+ }
63
+ setTriggerRef(node);
64
+ }
65
+ };
66
+ });
67
+ }),
68
+ _useState4 = _slicedToArray(_useState3, 1),
69
+ getMergedTriggerRef = _useState4[0];
42
70
  var renderPopperWrapper = jsx(UNSAFE_LAYERING, {
43
71
  isDisabled: getBooleanFF('platform.design-system-team.layering_popup_1cnzt') ? false : true
44
72
  }, jsx(PopperWrapper, {
@@ -60,18 +88,9 @@ export var Popup = /*#__PURE__*/memo(function (_ref) {
60
88
  triggerRef: triggerRef
61
89
  }));
62
90
  return jsx(Manager, null, jsx(Reference, null, function (_ref2) {
63
- var _ref3 = _ref2.ref;
91
+ var ref = _ref2.ref;
64
92
  return trigger({
65
- ref: function ref(node) {
66
- if (node && isOpen) {
67
- if (typeof _ref3 === 'function') {
68
- _ref3(node);
69
- } else {
70
- _ref3.current = node;
71
- }
72
- setTriggerRef(node);
73
- }
74
- },
93
+ ref: getMergedTriggerRef(ref, setTriggerRef, isOpen),
75
94
  'aria-controls': id,
76
95
  'aria-expanded': isOpen,
77
96
  'aria-haspopup': true
@@ -1,5 +1,5 @@
1
1
  /** @jsx jsx */
2
- import { FC } from 'react';
2
+ import { type FC } from 'react';
3
3
  import { PopupProps } from './types';
4
4
  export declare const Popup: FC<PopupProps>;
5
5
  export default Popup;
@@ -1,5 +1,5 @@
1
1
  /** @jsx jsx */
2
- import { FC } from 'react';
2
+ import { type FC } from 'react';
3
3
  import { PopupProps } from './types';
4
4
  export declare const Popup: FC<PopupProps>;
5
5
  export default Popup;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/popup",
3
- "version": "1.11.4",
3
+ "version": "1.11.5",
4
4
  "description": "A popup displays brief content in an overlay.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -48,7 +48,8 @@
48
48
  "@babel/runtime": "^7.0.0",
49
49
  "@emotion/react": "^11.7.1",
50
50
  "bind-event-listener": "^2.1.1",
51
- "focus-trap": "^2.4.5"
51
+ "focus-trap": "^2.4.5",
52
+ "memoize-one": "^6.0.0"
52
53
  },
53
54
  "peerDependencies": {
54
55
  "react": "^16.8.0",
@@ -57,8 +58,8 @@
57
58
  "devDependencies": {
58
59
  "@af/accessibility-testing": "*",
59
60
  "@af/visual-regression": "*",
60
- "@atlaskit/button": "^16.13.0",
61
- "@atlaskit/icon": "^21.12.0",
61
+ "@atlaskit/button": "^16.17.0",
62
+ "@atlaskit/icon": "^22.0.0",
62
63
  "@atlaskit/ssr": "*",
63
64
  "@atlaskit/visual-regression": "*",
64
65
  "@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1",