@atlaskit/navigation-system 5.20.0 → 5.21.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @atlassian/navigation-system
2
2
 
3
+ ## 5.21.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`67075d80cdd6b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/67075d80cdd6b) -
8
+ Fixes a bug where the panel splitter would not be resizable when some browser extensions were
9
+ installed. This was caused by the `dragstart` event incorrectly returning `0` for the client's
10
+ cursor position (`clientX`).
11
+
12
+ This fix is behind the feature gate `platform-dst-panel-splitter-drag-start-client-x`.
13
+
3
14
  ## 5.20.0
4
15
 
5
16
  ### Minor Changes
@@ -4,12 +4,19 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.getWidthFromDragLocation = exports.getPixelWidth = void 0;
7
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
8
+ /**
9
+ * ⚠️ Note: We are not using the location.initial.input client locations because some browser extensions
10
+ * can cause the client locations (e.g. clientX) in the `dragstart` event to incorrectly return 0.
11
+ */
7
12
  var getWidthFromDragLocation = exports.getWidthFromDragLocation = function getWidthFromDragLocation(_ref) {
8
13
  var initialWidth = _ref.initialWidth,
9
14
  location = _ref.location,
15
+ initialClientX = _ref.initialClientX,
10
16
  direction = _ref.direction,
11
17
  position = _ref.position;
12
- var diffX = location.current.input.clientX - location.initial.input.clientX;
18
+ var diffX = location.current.input.clientX - ((0, _platformFeatureFlags.fg)('platform-dst-panel-splitter-drag-start-client-x') ? initialClientX : location.initial.input.clientX);
19
+
13
20
  // Resize line is positioned at the inline-end (right) of the element.
14
21
  // If the direction is left-to-right, the width will increase when the mouse is moved to the right, and vice versa.
15
22
  if (position === 'end') {
@@ -20,7 +27,6 @@ var getWidthFromDragLocation = exports.getWidthFromDragLocation = function getWi
20
27
  // If the direction is left-to-right, the width will decrease when the mouse is moved to the right, and vice versa.
21
28
  return direction === 'ltr' ? initialWidth - diffX : initialWidth + diffX;
22
29
  };
23
-
24
30
  /**
25
31
  * Returns the computed width of an element in pixels.
26
32
  */
@@ -19,6 +19,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
19
19
  var _bindEventListener = require("bind-event-listener");
20
20
  var _reactDom = require("react-dom");
21
21
  var _tinyInvariant = _interopRequireDefault(require("tiny-invariant"));
22
+ var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
22
23
  var _useId = require("@atlaskit/ds-lib/use-id");
23
24
  var _useStableRef = _interopRequireDefault(require("@atlaskit/ds-lib/use-stable-ref"));
24
25
  var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer");
@@ -147,12 +148,35 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
147
148
  * Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context can be removed.
148
149
  */
149
150
  var onDoubleClick = (0, _react.useContext)(_context.OnDoubleClickContext);
151
+
152
+ // Storing the initial `clientX` on `mousedown` events, to workaround a bug caused by some browser extensions
153
+ // where the `dragstart` event incorrectly returns `0` for the `clientX` location.
154
+ var initialClientXRef = (0, _react.useRef)(null);
150
155
  (0, _react.useEffect)(function () {
151
156
  var splitter = splitterRef.current;
152
157
  (0, _tinyInvariant.default)(splitter, 'Splitter ref must be set');
153
158
  return (0, _combine.combine)((0, _blockDraggingToIframes.blockDraggingToIFrames)({
154
159
  element: splitter
155
- }), (0, _adapter.draggable)({
160
+ }),
161
+ /**
162
+ * Capturing the initial `clientX` from the mousedown, before the drag starts.
163
+ *
164
+ * ⚠️ Note: We are not using pragmatic-drag-and-drop's `onDragStart` for this as some browser
165
+ * extensions can cause the client location (e.g. clientX) to incorrectly return 0 during the `dragstart` event.
166
+ *
167
+ * We are also not using pragmatic-drag-and-drop's `onDrag` here as it is throttled, which means
168
+ * fast mouse movements can cause the real first drag event to be missed, causing a different clientX
169
+ * to be captured.
170
+ *
171
+ * I also tried only binding an event listener inside pragmatic-drag-and-drop's `onDragStart`, which seemd to work
172
+ * but did not feel as robust, and might have timing issues as it happens slightly later.
173
+ */
174
+ (0, _platformFeatureFlags.fg)('platform-dst-panel-splitter-drag-start-client-x') ? (0, _bindEventListener.bind)(splitter, {
175
+ type: 'mousedown',
176
+ listener: function listener(event) {
177
+ initialClientXRef.current = event.clientX;
178
+ }
179
+ }) : _noop.default, (0, _adapter.draggable)({
156
180
  element: splitter,
157
181
  onGenerateDragPreview: function onGenerateDragPreview(_ref4) {
158
182
  var nativeSetDragImage = _ref4.nativeSetDragImage;
@@ -184,6 +208,10 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
184
208
  },
185
209
  onDragStart: function onDragStart(_ref5) {
186
210
  var source = _ref5.source;
211
+ /**
212
+ * ⚠️ Note: We are not using the client locations (e.g. clientX) during `onDragStart`
213
+ * because some browser extensions can cause the event properties to incorrectly return 0.
214
+ */
187
215
  (0, _tinyInvariant.default)(isPanelSplitterDragData(source.data));
188
216
  onResizeStart === null || onResizeStart === void 0 || onResizeStart({
189
217
  initialWidth: source.data.initialWidth
@@ -193,13 +221,21 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
193
221
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
194
222
  },
195
223
  onDrag: function onDrag(_ref6) {
224
+ var _initialClientXRef$cu;
196
225
  var location = _ref6.location,
197
226
  source = _ref6.source;
227
+ /**
228
+ * ⚠️ Note: We are not using the location.initial.input client locations because some browser extensions
229
+ * can cause the client locations (e.g. clientX) in the `dragstart` event to incorrectly return 0.
230
+ */
198
231
  (0, _tinyInvariant.default)(isPanelSplitterDragData(source.data));
199
232
  var _source$data = source.data,
200
233
  initialWidth = _source$data.initialWidth,
201
234
  resizeBounds = _source$data.resizeBounds,
202
235
  direction = _source$data.direction;
236
+ if ((0, _platformFeatureFlags.fg)('platform-dst-panel-splitter-drag-start-client-x')) {
237
+ (0, _tinyInvariant.default)(initialClientXRef.current !== null, 'initialClientX must be set');
238
+ }
203
239
 
204
240
  /**
205
241
  * How wide the element would be if there were no width constraints,
@@ -208,6 +244,8 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
208
244
  var targetWidth = (0, _getWidth.getWidthFromDragLocation)({
209
245
  initialWidth: initialWidth,
210
246
  location: location,
247
+ // The fallback of 0 won't be used due to the invariant, however we require one to satisfy the type.
248
+ initialClientX: (_initialClientXRef$cu = initialClientXRef.current) !== null && _initialClientXRef$cu !== void 0 ? _initialClientXRef$cu : 0,
211
249
  direction: direction,
212
250
  position: position
213
251
  });
@@ -1,10 +1,17 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+ /**
3
+ * ⚠️ Note: We are not using the location.initial.input client locations because some browser extensions
4
+ * can cause the client locations (e.g. clientX) in the `dragstart` event to incorrectly return 0.
5
+ */
1
6
  export const getWidthFromDragLocation = ({
2
7
  initialWidth,
3
8
  location,
9
+ initialClientX,
4
10
  direction,
5
11
  position
6
12
  }) => {
7
- const diffX = location.current.input.clientX - location.initial.input.clientX;
13
+ const diffX = location.current.input.clientX - (fg('platform-dst-panel-splitter-drag-start-client-x') ? initialClientX : location.initial.input.clientX);
14
+
8
15
  // Resize line is positioned at the inline-end (right) of the element.
9
16
  // If the direction is left-to-right, the width will increase when the mouse is moved to the right, and vice versa.
10
17
  if (position === 'end') {
@@ -15,7 +22,6 @@ export const getWidthFromDragLocation = ({
15
22
  // If the direction is left-to-right, the width will decrease when the mouse is moved to the right, and vice versa.
16
23
  return direction === 'ltr' ? initialWidth - diffX : initialWidth + diffX;
17
24
  };
18
-
19
25
  /**
20
26
  * Returns the computed width of an element in pixels.
21
27
  */
@@ -7,6 +7,7 @@ import { forwardRef, useCallback, useContext, useEffect, useMemo, useRef, useSta
7
7
  import { bind } from 'bind-event-listener';
8
8
  import { createPortal } from 'react-dom';
9
9
  import invariant from 'tiny-invariant';
10
+ import noop from '@atlaskit/ds-lib/noop';
10
11
  import { useId } from '@atlaskit/ds-lib/use-id';
11
12
  import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
12
13
  import { useOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
@@ -132,12 +133,35 @@ const PortaledPanelSplitter = ({
132
133
  * Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context can be removed.
133
134
  */
134
135
  const onDoubleClick = useContext(OnDoubleClickContext);
136
+
137
+ // Storing the initial `clientX` on `mousedown` events, to workaround a bug caused by some browser extensions
138
+ // where the `dragstart` event incorrectly returns `0` for the `clientX` location.
139
+ const initialClientXRef = useRef(null);
135
140
  useEffect(() => {
136
141
  const splitter = splitterRef.current;
137
142
  invariant(splitter, 'Splitter ref must be set');
138
143
  return combine(blockDraggingToIFrames({
139
144
  element: splitter
140
- }), draggable({
145
+ }),
146
+ /**
147
+ * Capturing the initial `clientX` from the mousedown, before the drag starts.
148
+ *
149
+ * ⚠️ Note: We are not using pragmatic-drag-and-drop's `onDragStart` for this as some browser
150
+ * extensions can cause the client location (e.g. clientX) to incorrectly return 0 during the `dragstart` event.
151
+ *
152
+ * We are also not using pragmatic-drag-and-drop's `onDrag` here as it is throttled, which means
153
+ * fast mouse movements can cause the real first drag event to be missed, causing a different clientX
154
+ * to be captured.
155
+ *
156
+ * I also tried only binding an event listener inside pragmatic-drag-and-drop's `onDragStart`, which seemd to work
157
+ * but did not feel as robust, and might have timing issues as it happens slightly later.
158
+ */
159
+ fg('platform-dst-panel-splitter-drag-start-client-x') ? bind(splitter, {
160
+ type: 'mousedown',
161
+ listener: event => {
162
+ initialClientXRef.current = event.clientX;
163
+ }
164
+ }) : noop, draggable({
141
165
  element: splitter,
142
166
  onGenerateDragPreview: ({
143
167
  nativeSetDragImage
@@ -171,6 +195,10 @@ const PortaledPanelSplitter = ({
171
195
  onDragStart({
172
196
  source
173
197
  }) {
198
+ /**
199
+ * ⚠️ Note: We are not using the client locations (e.g. clientX) during `onDragStart`
200
+ * because some browser extensions can cause the event properties to incorrectly return 0.
201
+ */
174
202
  invariant(isPanelSplitterDragData(source.data));
175
203
  onResizeStart === null || onResizeStart === void 0 ? void 0 : onResizeStart({
176
204
  initialWidth: source.data.initialWidth
@@ -183,12 +211,20 @@ const PortaledPanelSplitter = ({
183
211
  location,
184
212
  source
185
213
  }) {
214
+ var _initialClientXRef$cu;
215
+ /**
216
+ * ⚠️ Note: We are not using the location.initial.input client locations because some browser extensions
217
+ * can cause the client locations (e.g. clientX) in the `dragstart` event to incorrectly return 0.
218
+ */
186
219
  invariant(isPanelSplitterDragData(source.data));
187
220
  const {
188
221
  initialWidth,
189
222
  resizeBounds,
190
223
  direction
191
224
  } = source.data;
225
+ if (fg('platform-dst-panel-splitter-drag-start-client-x')) {
226
+ invariant(initialClientXRef.current !== null, 'initialClientX must be set');
227
+ }
192
228
 
193
229
  /**
194
230
  * How wide the element would be if there were no width constraints,
@@ -197,6 +233,8 @@ const PortaledPanelSplitter = ({
197
233
  const targetWidth = getWidthFromDragLocation({
198
234
  initialWidth,
199
235
  location,
236
+ // The fallback of 0 won't be used due to the invariant, however we require one to satisfy the type.
237
+ initialClientX: (_initialClientXRef$cu = initialClientXRef.current) !== null && _initialClientXRef$cu !== void 0 ? _initialClientXRef$cu : 0,
200
238
  direction,
201
239
  position
202
240
  });
@@ -1,9 +1,16 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+ /**
3
+ * ⚠️ Note: We are not using the location.initial.input client locations because some browser extensions
4
+ * can cause the client locations (e.g. clientX) in the `dragstart` event to incorrectly return 0.
5
+ */
1
6
  export var getWidthFromDragLocation = function getWidthFromDragLocation(_ref) {
2
7
  var initialWidth = _ref.initialWidth,
3
8
  location = _ref.location,
9
+ initialClientX = _ref.initialClientX,
4
10
  direction = _ref.direction,
5
11
  position = _ref.position;
6
- var diffX = location.current.input.clientX - location.initial.input.clientX;
12
+ var diffX = location.current.input.clientX - (fg('platform-dst-panel-splitter-drag-start-client-x') ? initialClientX : location.initial.input.clientX);
13
+
7
14
  // Resize line is positioned at the inline-end (right) of the element.
8
15
  // If the direction is left-to-right, the width will increase when the mouse is moved to the right, and vice versa.
9
16
  if (position === 'end') {
@@ -14,7 +21,6 @@ export var getWidthFromDragLocation = function getWidthFromDragLocation(_ref) {
14
21
  // If the direction is left-to-right, the width will decrease when the mouse is moved to the right, and vice versa.
15
22
  return direction === 'ltr' ? initialWidth - diffX : initialWidth + diffX;
16
23
  };
17
-
18
24
  /**
19
25
  * Returns the computed width of an element in pixels.
20
26
  */
@@ -13,6 +13,7 @@ import { forwardRef, useCallback, useContext, useEffect, useMemo, useRef, useSta
13
13
  import { bind } from 'bind-event-listener';
14
14
  import { createPortal } from 'react-dom';
15
15
  import invariant from 'tiny-invariant';
16
+ import noop from '@atlaskit/ds-lib/noop';
16
17
  import { useId } from '@atlaskit/ds-lib/use-id';
17
18
  import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
18
19
  import { useOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
@@ -137,12 +138,35 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
137
138
  * Once `PanelSplitter` supports an `onDoubleClick` prop directly, this context can be removed.
138
139
  */
139
140
  var onDoubleClick = useContext(OnDoubleClickContext);
141
+
142
+ // Storing the initial `clientX` on `mousedown` events, to workaround a bug caused by some browser extensions
143
+ // where the `dragstart` event incorrectly returns `0` for the `clientX` location.
144
+ var initialClientXRef = useRef(null);
140
145
  useEffect(function () {
141
146
  var splitter = splitterRef.current;
142
147
  invariant(splitter, 'Splitter ref must be set');
143
148
  return combine(blockDraggingToIFrames({
144
149
  element: splitter
145
- }), draggable({
150
+ }),
151
+ /**
152
+ * Capturing the initial `clientX` from the mousedown, before the drag starts.
153
+ *
154
+ * ⚠️ Note: We are not using pragmatic-drag-and-drop's `onDragStart` for this as some browser
155
+ * extensions can cause the client location (e.g. clientX) to incorrectly return 0 during the `dragstart` event.
156
+ *
157
+ * We are also not using pragmatic-drag-and-drop's `onDrag` here as it is throttled, which means
158
+ * fast mouse movements can cause the real first drag event to be missed, causing a different clientX
159
+ * to be captured.
160
+ *
161
+ * I also tried only binding an event listener inside pragmatic-drag-and-drop's `onDragStart`, which seemd to work
162
+ * but did not feel as robust, and might have timing issues as it happens slightly later.
163
+ */
164
+ fg('platform-dst-panel-splitter-drag-start-client-x') ? bind(splitter, {
165
+ type: 'mousedown',
166
+ listener: function listener(event) {
167
+ initialClientXRef.current = event.clientX;
168
+ }
169
+ }) : noop, draggable({
146
170
  element: splitter,
147
171
  onGenerateDragPreview: function onGenerateDragPreview(_ref4) {
148
172
  var nativeSetDragImage = _ref4.nativeSetDragImage;
@@ -174,6 +198,10 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
174
198
  },
175
199
  onDragStart: function onDragStart(_ref5) {
176
200
  var source = _ref5.source;
201
+ /**
202
+ * ⚠️ Note: We are not using the client locations (e.g. clientX) during `onDragStart`
203
+ * because some browser extensions can cause the event properties to incorrectly return 0.
204
+ */
177
205
  invariant(isPanelSplitterDragData(source.data));
178
206
  onResizeStart === null || onResizeStart === void 0 || onResizeStart({
179
207
  initialWidth: source.data.initialWidth
@@ -183,13 +211,21 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
183
211
  openLayerObserver === null || openLayerObserver === void 0 || openLayerObserver.closeLayers();
184
212
  },
185
213
  onDrag: function onDrag(_ref6) {
214
+ var _initialClientXRef$cu;
186
215
  var location = _ref6.location,
187
216
  source = _ref6.source;
217
+ /**
218
+ * ⚠️ Note: We are not using the location.initial.input client locations because some browser extensions
219
+ * can cause the client locations (e.g. clientX) in the `dragstart` event to incorrectly return 0.
220
+ */
188
221
  invariant(isPanelSplitterDragData(source.data));
189
222
  var _source$data = source.data,
190
223
  initialWidth = _source$data.initialWidth,
191
224
  resizeBounds = _source$data.resizeBounds,
192
225
  direction = _source$data.direction;
226
+ if (fg('platform-dst-panel-splitter-drag-start-client-x')) {
227
+ invariant(initialClientXRef.current !== null, 'initialClientX must be set');
228
+ }
193
229
 
194
230
  /**
195
231
  * How wide the element would be if there were no width constraints,
@@ -198,6 +234,8 @@ var PortaledPanelSplitter = function PortaledPanelSplitter(_ref3) {
198
234
  var targetWidth = getWidthFromDragLocation({
199
235
  initialWidth: initialWidth,
200
236
  location: location,
237
+ // The fallback of 0 won't be used due to the invariant, however we require one to satisfy the type.
238
+ initialClientX: (_initialClientXRef$cu = initialClientXRef.current) !== null && _initialClientXRef$cu !== void 0 ? _initialClientXRef$cu : 0,
201
239
  direction: direction,
202
240
  position: position
203
241
  });
@@ -1,7 +1,12 @@
1
1
  import type { DragLocationHistory } from '@atlaskit/pragmatic-drag-and-drop/types';
2
- export declare const getWidthFromDragLocation: ({ initialWidth, location, direction, position, }: {
2
+ /**
3
+ * ⚠️ Note: We are not using the location.initial.input client locations because some browser extensions
4
+ * can cause the client locations (e.g. clientX) in the `dragstart` event to incorrectly return 0.
5
+ */
6
+ export declare const getWidthFromDragLocation: ({ initialWidth, location, initialClientX, direction, position, }: {
3
7
  initialWidth: number;
4
8
  location: DragLocationHistory;
9
+ initialClientX: number;
5
10
  direction: "ltr" | "rtl";
6
11
  position: "start" | "end";
7
12
  }) => number;
@@ -1,7 +1,12 @@
1
1
  import type { DragLocationHistory } from '@atlaskit/pragmatic-drag-and-drop/types';
2
- export declare const getWidthFromDragLocation: ({ initialWidth, location, direction, position, }: {
2
+ /**
3
+ * ⚠️ Note: We are not using the location.initial.input client locations because some browser extensions
4
+ * can cause the client locations (e.g. clientX) in the `dragstart` event to incorrectly return 0.
5
+ */
6
+ export declare const getWidthFromDragLocation: ({ initialWidth, location, initialClientX, direction, position, }: {
3
7
  initialWidth: number;
4
8
  location: DragLocationHistory;
9
+ initialClientX: number;
5
10
  direction: "ltr" | "rtl";
6
11
  position: "start" | "end";
7
12
  }) => number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/navigation-system",
3
- "version": "5.20.0",
3
+ "version": "5.21.0",
4
4
  "description": "The latest navigation system for Atlassian apps.",
5
5
  "repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
6
6
  "author": "Atlassian Pty Ltd",
@@ -72,7 +72,7 @@
72
72
  "@atlaskit/css": "^0.19.0",
73
73
  "@atlaskit/ds-lib": "^5.3.0",
74
74
  "@atlaskit/heading": "^5.2.0",
75
- "@atlaskit/icon": "^29.3.0",
75
+ "@atlaskit/icon": "^29.4.0",
76
76
  "@atlaskit/layering": "^3.6.0",
77
77
  "@atlaskit/logo": "^19.9.0",
78
78
  "@atlaskit/platform-feature-flags": "^1.1.0",
@@ -193,6 +193,9 @@
193
193
  },
194
194
  "platform_dst_nav4_flyout_menu_slots_close_button": {
195
195
  "type": "boolean"
196
+ },
197
+ "platform-dst-panel-splitter-drag-start-client-x": {
198
+ "type": "boolean"
196
199
  }
197
200
  },
198
201
  "homepage": "https://atlassian.design/components/navigation-system"