@atlaskit/popup 4.3.15 → 4.4.1

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,24 @@
1
1
  # @atlaskit/popup
2
2
 
3
+ ## 4.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`248faa32d4835`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/248faa32d4835) -
8
+ Internal changes to how borders are applied.
9
+ - Updated dependencies
10
+
11
+ ## 4.4.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [`02c6e19e8ac81`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/02c6e19e8ac81) -
16
+ Popup will now stay open when a click starts inside the popup but then moves outside the popup.
17
+ The `onClose` callback will not be called in this case. This aligns it with the behaviour of Modal
18
+ Dialog.
19
+
20
+ This change is behind a feature flag.
21
+
3
22
  ## 4.3.15
4
23
 
5
24
  ### Patch Changes
@@ -30,6 +30,7 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
30
30
  var _useAnimationFrame = (0, _useAnimationFrame2.useAnimationFrame)(),
31
31
  requestFrame = _useAnimationFrame.requestFrame,
32
32
  cancelAllFrames = _useAnimationFrame.cancelAllFrames;
33
+ var mouseDownTarget = (0, _react.useRef)(null);
33
34
  (0, _react.useEffect)(function () {
34
35
  if (!isOpen || !popupRef) {
35
36
  return _noop.default;
@@ -88,7 +89,8 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
88
89
  }
89
90
  var isClickOnPopup = popupRef && popupRef.contains(target);
90
91
  var isClickOnTrigger = triggerRef && triggerRef.contains(target);
91
- if (!isClickOnPopup && !isClickOnTrigger) {
92
+ var didClickStartInsidePopup = popupRef && mouseDownTarget.current instanceof Node && popupRef.contains(mouseDownTarget.current);
93
+ if (!isClickOnPopup && !isClickOnTrigger && ((0, _platformFeatureFlags.fg)('popup-onclose-fix-mouse-down-inside-popup') ? !didClickStartInsidePopup : true)) {
92
94
  closePopup(event);
93
95
  // If there was an outside click on a non-interactive element, the focus should be on the trigger.
94
96
  if (document.activeElement && !(0, _isElementInteractive.isInteractiveElement)(document.activeElement) && (0, _platformFeatureFlags.fg)('platform_dst_popup-disable-focuslock')) {
@@ -96,6 +98,19 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
96
98
  }
97
99
  }
98
100
  };
101
+ var onMouseDown = function onMouseDown(event) {
102
+ /**
103
+ * Tracking the target of the mouse down event.
104
+ * This is used to prevent the popup from closing when the user mouses down inside the popup, but then
105
+ * moves the mouse outside the popup before releasing the mouse button.
106
+ *
107
+ * This is a common user interaction - users may have mistakenly clicked on something, or changed their mind,
108
+ * so they try to cancel their click by moving their mouse away from what they had moused down on.
109
+ *
110
+ * Blanket uses the same technique.
111
+ */
112
+ mouseDownTarget.current = event.target;
113
+ };
99
114
  var onKeyDown = function onKeyDown(event) {
100
115
  if ((0, _platformFeatureFlags.fg)('platform_dst_popup-disable-focuslock')) {
101
116
  var key = event.key,
@@ -192,6 +207,9 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
192
207
  }, {
193
208
  type: 'keydown',
194
209
  listener: onKeyDown
210
+ }, {
211
+ type: 'mousedown',
212
+ listener: onMouseDown
195
213
  }]);
196
214
  }, 0);
197
215
  } else {
@@ -204,6 +222,9 @@ var useCloseManager = exports.useCloseManager = function useCloseManager(_ref) {
204
222
  }, {
205
223
  type: 'keydown',
206
224
  listener: onKeyDown
225
+ }, {
226
+ type: 'mousedown',
227
+ listener: onMouseDown
207
228
  }]);
208
229
  }
209
230
 
@@ -1,5 +1,5 @@
1
1
  // eslint-disable-next-line no-duplicate-imports
2
- import { useEffect } from 'react';
2
+ import { useEffect, useRef } from 'react';
3
3
  import { bind, bindAll } from 'bind-event-listener';
4
4
  import noop from '@atlaskit/ds-lib/noop';
5
5
  import { useLayering } from '@atlaskit/layering';
@@ -25,6 +25,7 @@ export const useCloseManager = ({
25
25
  requestFrame,
26
26
  cancelAllFrames
27
27
  } = useAnimationFrame();
28
+ const mouseDownTarget = useRef(null);
28
29
  useEffect(() => {
29
30
  if (!isOpen || !popupRef) {
30
31
  return noop;
@@ -85,7 +86,8 @@ export const useCloseManager = ({
85
86
  }
86
87
  const isClickOnPopup = popupRef && popupRef.contains(target);
87
88
  const isClickOnTrigger = triggerRef && triggerRef.contains(target);
88
- if (!isClickOnPopup && !isClickOnTrigger) {
89
+ const didClickStartInsidePopup = popupRef && mouseDownTarget.current instanceof Node && popupRef.contains(mouseDownTarget.current);
90
+ if (!isClickOnPopup && !isClickOnTrigger && (fg('popup-onclose-fix-mouse-down-inside-popup') ? !didClickStartInsidePopup : true)) {
89
91
  closePopup(event);
90
92
  // If there was an outside click on a non-interactive element, the focus should be on the trigger.
91
93
  if (document.activeElement && !isInteractiveElement(document.activeElement) && fg('platform_dst_popup-disable-focuslock')) {
@@ -93,6 +95,19 @@ export const useCloseManager = ({
93
95
  }
94
96
  }
95
97
  };
98
+ const onMouseDown = event => {
99
+ /**
100
+ * Tracking the target of the mouse down event.
101
+ * This is used to prevent the popup from closing when the user mouses down inside the popup, but then
102
+ * moves the mouse outside the popup before releasing the mouse button.
103
+ *
104
+ * This is a common user interaction - users may have mistakenly clicked on something, or changed their mind,
105
+ * so they try to cancel their click by moving their mouse away from what they had moused down on.
106
+ *
107
+ * Blanket uses the same technique.
108
+ */
109
+ mouseDownTarget.current = event.target;
110
+ };
96
111
  const onKeyDown = event => {
97
112
  if (fg('platform_dst_popup-disable-focuslock')) {
98
113
  const {
@@ -193,6 +208,9 @@ export const useCloseManager = ({
193
208
  }, {
194
209
  type: 'keydown',
195
210
  listener: onKeyDown
211
+ }, {
212
+ type: 'mousedown',
213
+ listener: onMouseDown
196
214
  }]);
197
215
  }, 0);
198
216
  } else {
@@ -205,6 +223,9 @@ export const useCloseManager = ({
205
223
  }, {
206
224
  type: 'keydown',
207
225
  listener: onKeyDown
226
+ }, {
227
+ type: 'mousedown',
228
+ listener: onMouseDown
208
229
  }]);
209
230
  }
210
231
 
@@ -1,5 +1,5 @@
1
1
  // eslint-disable-next-line no-duplicate-imports
2
- import { useEffect } from 'react';
2
+ import { useEffect, useRef } from 'react';
3
3
  import { bind, bindAll } from 'bind-event-listener';
4
4
  import noop from '@atlaskit/ds-lib/noop';
5
5
  import { useLayering } from '@atlaskit/layering';
@@ -22,6 +22,7 @@ export var useCloseManager = function useCloseManager(_ref) {
22
22
  var _useAnimationFrame = useAnimationFrame(),
23
23
  requestFrame = _useAnimationFrame.requestFrame,
24
24
  cancelAllFrames = _useAnimationFrame.cancelAllFrames;
25
+ var mouseDownTarget = useRef(null);
25
26
  useEffect(function () {
26
27
  if (!isOpen || !popupRef) {
27
28
  return noop;
@@ -80,7 +81,8 @@ export var useCloseManager = function useCloseManager(_ref) {
80
81
  }
81
82
  var isClickOnPopup = popupRef && popupRef.contains(target);
82
83
  var isClickOnTrigger = triggerRef && triggerRef.contains(target);
83
- if (!isClickOnPopup && !isClickOnTrigger) {
84
+ var didClickStartInsidePopup = popupRef && mouseDownTarget.current instanceof Node && popupRef.contains(mouseDownTarget.current);
85
+ if (!isClickOnPopup && !isClickOnTrigger && (fg('popup-onclose-fix-mouse-down-inside-popup') ? !didClickStartInsidePopup : true)) {
84
86
  closePopup(event);
85
87
  // If there was an outside click on a non-interactive element, the focus should be on the trigger.
86
88
  if (document.activeElement && !isInteractiveElement(document.activeElement) && fg('platform_dst_popup-disable-focuslock')) {
@@ -88,6 +90,19 @@ export var useCloseManager = function useCloseManager(_ref) {
88
90
  }
89
91
  }
90
92
  };
93
+ var onMouseDown = function onMouseDown(event) {
94
+ /**
95
+ * Tracking the target of the mouse down event.
96
+ * This is used to prevent the popup from closing when the user mouses down inside the popup, but then
97
+ * moves the mouse outside the popup before releasing the mouse button.
98
+ *
99
+ * This is a common user interaction - users may have mistakenly clicked on something, or changed their mind,
100
+ * so they try to cancel their click by moving their mouse away from what they had moused down on.
101
+ *
102
+ * Blanket uses the same technique.
103
+ */
104
+ mouseDownTarget.current = event.target;
105
+ };
91
106
  var onKeyDown = function onKeyDown(event) {
92
107
  if (fg('platform_dst_popup-disable-focuslock')) {
93
108
  var key = event.key,
@@ -184,6 +199,9 @@ export var useCloseManager = function useCloseManager(_ref) {
184
199
  }, {
185
200
  type: 'keydown',
186
201
  listener: onKeyDown
202
+ }, {
203
+ type: 'mousedown',
204
+ listener: onMouseDown
187
205
  }]);
188
206
  }, 0);
189
207
  } else {
@@ -196,6 +214,9 @@ export var useCloseManager = function useCloseManager(_ref) {
196
214
  }, {
197
215
  type: 'keydown',
198
216
  listener: onKeyDown
217
+ }, {
218
+ type: 'mousedown',
219
+ listener: onMouseDown
199
220
  }]);
200
221
  }
201
222
 
package/offerings.json ADDED
@@ -0,0 +1,34 @@
1
+ [
2
+ {
3
+ "name": "Popup",
4
+ "package": "@atlaskit/popup",
5
+ "import": {
6
+ "name": "Popup",
7
+ "package": "@atlaskit/popup",
8
+ "type": "default"
9
+ },
10
+ "keywords": ["popup", "overlay", "floating", "content", "trigger"],
11
+ "categories": ["overlay"],
12
+ "shortDescription": "A component for displaying popup content relative to a trigger element.",
13
+ "status": "general-availability",
14
+ "accessibilityGuidelines": [
15
+ "Provide appropriate focus management",
16
+ "Use clear trigger labels",
17
+ "Ensure keyboard navigation support",
18
+ "Provide escape key dismissal"
19
+ ],
20
+ "usageGuidelines": [
21
+ "Use for contextual content that appears on demand",
22
+ "Position appropriately relative to trigger",
23
+ "Consider dismissal behavior",
24
+ "Use appropriate content sizing"
25
+ ],
26
+ "contentGuidelines": [
27
+ "Keep popup content focused and relevant",
28
+ "Use clear, concise content",
29
+ "Provide appropriate actions when needed",
30
+ "Consider content hierarchy"
31
+ ],
32
+ "examples": ["./examples/ai/popup.tsx"]
33
+ }
34
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/popup",
3
- "version": "4.3.15",
3
+ "version": "4.4.1",
4
4
  "description": "A popup displays brief content in an overlay.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -57,10 +57,10 @@
57
57
  "@af/visual-regression": "workspace:^",
58
58
  "@atlaskit/button": "^23.4.0",
59
59
  "@atlaskit/code": "^17.2.0",
60
- "@atlaskit/docs": "^11.0.0",
61
- "@atlaskit/form": "^12.5.0",
60
+ "@atlaskit/docs": "^11.1.0",
61
+ "@atlaskit/form": "^12.7.0",
62
62
  "@atlaskit/heading": "^5.2.0",
63
- "@atlaskit/icon": "^28.1.0",
63
+ "@atlaskit/icon": "^28.2.0",
64
64
  "@atlaskit/link": "^3.2.0",
65
65
  "@atlaskit/modal-dialog": "^14.3.0",
66
66
  "@atlaskit/section-message": "^8.7.0",
@@ -117,6 +117,9 @@
117
117
  },
118
118
  "popup-onclose-fix": {
119
119
  "type": "boolean"
120
+ },
121
+ "popup-onclose-fix-mouse-down-inside-popup": {
122
+ "type": "boolean"
120
123
  }
121
124
  },
122
125
  "homepage": "https://atlassian.design/components/popup/"