@atlaskit/page-layout 1.6.2 → 1.6.4

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 (37) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/__perf__/utils/perf-example.tsx +1 -1
  3. package/__perf__/utils/product-integration/notifications-popup.tsx +2 -0
  4. package/dist/cjs/common/hooks/use-is-sidebar-dragging.js +3 -0
  5. package/dist/cjs/components/resize-control/index.js +84 -28
  6. package/dist/cjs/components/resize-control/resize-button.js +5 -5
  7. package/dist/cjs/components/resize-control/shadow.js +2 -0
  8. package/dist/cjs/components/skip-links/skip-link-components.js +4 -1
  9. package/dist/cjs/components/slots/banner-slot.js +2 -0
  10. package/dist/cjs/components/slots/internal/left-sidebar-inner.js +2 -0
  11. package/dist/cjs/components/slots/main.js +1 -1
  12. package/dist/cjs/components/slots/right-sidebar.js +2 -0
  13. package/dist/cjs/components/slots/top-navigation.js +3 -0
  14. package/dist/cjs/version.json +1 -1
  15. package/dist/es2019/common/hooks/use-is-sidebar-dragging.js +3 -0
  16. package/dist/es2019/components/resize-control/index.js +74 -23
  17. package/dist/es2019/components/resize-control/resize-button.js +5 -5
  18. package/dist/es2019/components/resize-control/shadow.js +2 -0
  19. package/dist/es2019/components/skip-links/skip-link-components.js +4 -1
  20. package/dist/es2019/components/slots/banner-slot.js +2 -0
  21. package/dist/es2019/components/slots/internal/left-sidebar-inner.js +2 -0
  22. package/dist/es2019/components/slots/main.js +1 -1
  23. package/dist/es2019/components/slots/right-sidebar.js +2 -0
  24. package/dist/es2019/components/slots/top-navigation.js +3 -0
  25. package/dist/es2019/version.json +1 -1
  26. package/dist/esm/common/hooks/use-is-sidebar-dragging.js +3 -0
  27. package/dist/esm/components/resize-control/index.js +86 -30
  28. package/dist/esm/components/resize-control/resize-button.js +5 -5
  29. package/dist/esm/components/resize-control/shadow.js +2 -0
  30. package/dist/esm/components/skip-links/skip-link-components.js +4 -1
  31. package/dist/esm/components/slots/banner-slot.js +2 -0
  32. package/dist/esm/components/slots/internal/left-sidebar-inner.js +2 -0
  33. package/dist/esm/components/slots/main.js +1 -1
  34. package/dist/esm/components/slots/right-sidebar.js +2 -0
  35. package/dist/esm/components/slots/top-navigation.js +3 -0
  36. package/dist/esm/version.json +1 -1
  37. package/package.json +4 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @atlaskit/page-layout
2
2
 
3
+ ## 1.6.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`b1bdec7cce2`](https://bitbucket.org/atlassian/atlassian-frontend/commits/b1bdec7cce2) - Internal change to enforce token usage for spacing properties. There is no expected visual or behaviour change.
8
+
9
+ ## 1.6.3
10
+
11
+ ### Patch Changes
12
+
13
+ - [`4bbc131de00`](https://bitbucket.org/atlassian/atlassian-frontend/commits/4bbc131de00) - #### Fix: Resizing pages with `<iframe>`s
14
+
15
+ Pages that contain `<iframe>` elements will now have a smoother resizing experience. `<iframe>` elements consume user events (eg `mousemove`) when the user is over the top of them. This is problematic for resizing as we need to have the latest user pointer movements to resize the sidebar. Now, while a resize is happening, `pointer-events` are blocked on `<iframe>` elements to prevent the `<iframe>` consuming user events.
16
+
17
+ #### Fix: User cursor while resizing
18
+
19
+ While resizing the users cursor will now always be `ew-resize`. Previously the cursor could change depending on what element the users pointer was over
20
+
21
+ #### Fix: Resizing will no longer change user selection
22
+
23
+ A user can select parts of a page (eg select a paragraph of text). Previously, in some cases, a user's selection could change due to a resizing operation. This has been fixed so that a resizing operation will no longer change a user's selection
24
+
25
+ #### Fix: `onResizeEnd`
26
+
27
+ `onResizeEnd` will no longer incorrectly get an empty object `{}` if the user resized into the collapsed state
28
+
3
29
  ## 1.6.2
4
30
 
5
31
  ### Patch Changes
@@ -18,7 +18,7 @@ import Sidebar from './product-integration/side-navigation';
18
18
  const wrapperStyles = css({
19
19
  boxSizing: 'border-box',
20
20
  height: '100%',
21
- padding: 8,
21
+ padding: token('space.100', '8px'),
22
22
  backgroundColor: token('color.background.neutral.subtle', 'white'),
23
23
  outlineOffset: -4,
24
24
  overflowY: 'auto',
@@ -13,7 +13,9 @@ const wrapperStyles = css({
13
13
  display: 'flex',
14
14
  width: 540,
15
15
  height: 'calc(100vh - 200px)',
16
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
16
17
  paddingTop: 18,
18
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
17
19
  paddingLeft: 18,
18
20
  });
19
21
 
@@ -15,6 +15,9 @@ var getIsDragging = function getIsDragging() {
15
15
  }
16
16
  return document.documentElement.getAttribute(_constants.IS_SIDEBAR_DRAGGING) === 'true';
17
17
  };
18
+
19
+ // TODO: I think this should be derived from the sidebar state,
20
+ // and not indirectly from observing an attribute change
18
21
  var useIsSidebarDragging = function useIsSidebarDragging() {
19
22
  var _useState = (0, _react.useState)(getIsDragging),
20
23
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
@@ -25,12 +25,40 @@ var resizeControlStyles = (0, _react2.css)({
25
25
  position: 'absolute',
26
26
  top: 0,
27
27
  bottom: 0,
28
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
28
29
  left: '100%',
29
30
  outline: 'none'
30
31
  });
31
32
  var showResizeButtonStyles = (0, _react2.css)({
32
33
  '--ds--resize-button--opacity': 1
33
34
  });
35
+
36
+ // @ts-expect-error adding `!important` to style rules is currently a type error
37
+ var globalResizingStyles = (0, _react2.css)({
38
+ // eslint-disable-next-line @repo/internal/styles/no-nested-styles
39
+ '*': {
40
+ // Setting the cursor to be `ew-resize` on all elements so that even if the user
41
+ // pointer slips off the resize handle, the cursor will still be the resize cursor
42
+ cursor: 'ew-resize !important',
43
+ // Blocking selection while resizing
44
+ // Notes:
45
+ // - This prevents a user selection being caused by resizing
46
+ // - Safari + Firefox → all good
47
+ // - Chrome → This will undo the current selection while resizing (not ideal)
48
+ // - The current selection will resume after resizing
49
+ userSelect: 'none !important'
50
+ },
51
+ // eslint-disable-next-line @repo/internal/styles/no-nested-styles
52
+ iframe: {
53
+ // Disabling pointer events on iframes when resizing
54
+ // as iframes will swallower user events when the user is over them
55
+ pointerEvents: 'none !important'
56
+ }
57
+ // Note: We _could_ also disable `pointer-events` on all elements during resizing.
58
+ // However, to minimize risk we are just disabling `pointer-events` on iframes
59
+ // as that change is actually needed to fix resizing with iframes
60
+ });
61
+
34
62
  var ResizeControl = function ResizeControl(_ref) {
35
63
  var testId = _ref.testId,
36
64
  overrides = _ref.overrides,
@@ -56,6 +84,13 @@ var ResizeControl = function ResizeControl(_ref) {
56
84
  isGrabAreaFocused = _useState2[0],
57
85
  setIsGrabAreaFocused = _useState2[1];
58
86
  var unbindEvents = (0, _react.useRef)(null);
87
+
88
+ // Used in some cases to ensure function references don't have to change
89
+ // TODO: more functions could use `stableSidebarState` rather than `leftSidebarState`
90
+ var stableSidebarState = (0, _react.useRef)(leftSidebarState);
91
+ (0, _react.useEffect)(function () {
92
+ stableSidebarState.current = leftSidebarState;
93
+ }, [leftSidebarState]);
59
94
  var toggleSideBar = function toggleSideBar(e) {
60
95
  if (isResizing) {
61
96
  return;
@@ -90,7 +125,11 @@ var ResizeControl = function ResizeControl(_ref) {
90
125
  offset.current = event.clientX - leftSidebarState[_constants.VAR_LEFT_SIDEBAR_WIDTH] - (0, _utils.getLeftPanelWidth)();
91
126
  unbindEvents.current = (0, _bindEventListener.bindAll)(window, [{
92
127
  type: 'mousemove',
93
- listener: onUpdateResize
128
+ listener: function listener(event) {
129
+ onUpdateResize({
130
+ clientX: event.clientX
131
+ });
132
+ }
94
133
  }, {
95
134
  type: 'mouseup',
96
135
  listener: onFinishResizing
@@ -155,37 +194,45 @@ var ResizeControl = function ResizeControl(_ref) {
155
194
  offset.current = 0;
156
195
  collapseLeftSidebar(undefined, true);
157
196
  };
158
- var onUpdateResize = (0, _rafSchd.default)(function (event) {
159
- // Allow the sidebar to be 50% of the available page width
160
- var maxWidth = Math.round(window.innerWidth / 2);
161
- var leftPanelWidth = (0, _utils.getLeftPanelWidth)();
162
- var leftSidebarWidth = leftSidebarState.leftSidebarWidth;
163
- var hasResizedOffLeftOfScreen = event.clientX < 0;
164
- if (hasResizedOffLeftOfScreen) {
165
- onResizeOffLeftOfScreen();
166
- return;
167
- }
168
- var delta = Math.max(Math.min(event.clientX - leftSidebarWidth - leftPanelWidth, maxWidth - leftSidebarWidth - leftPanelWidth), _constants.COLLAPSED_LEFT_SIDEBAR_WIDTH - leftSidebarWidth - leftPanelWidth);
169
- sidebarWidth.current = Math.max(leftSidebarWidth + delta - offset.current, _constants.COLLAPSED_LEFT_SIDEBAR_WIDTH);
170
- document.documentElement.style.setProperty("--".concat(_constants.VAR_LEFT_SIDEBAR_WIDTH), "".concat(sidebarWidth.current, "px"));
171
- });
172
- var cleanupAfterResize = function cleanupAfterResize() {
173
- var _unbindEvents$current2;
174
- sidebarWidth.current = 0;
175
- offset.current = 0;
176
- (_unbindEvents$current2 = unbindEvents.current) === null || _unbindEvents$current2 === void 0 ? void 0 : _unbindEvents$current2.call(unbindEvents);
177
- unbindEvents.current = null;
178
- };
179
- var updatedLeftSidebarState = {};
197
+
198
+ // It is important that `onUpdateResize` is a stable function reference, so that:
199
+ // 1. we ensure we are correctly throttling with `requestAnimationFrame`
200
+ // 2. that a `onUpdateResize` will cancel the one and only pending frame
201
+ // To help ensure `onUpdateResize` is stable, we are putting the last state into a ref
202
+ var _useState3 = (0, _react.useState)(function () {
203
+ return (0, _rafSchd.default)(function (_ref2) {
204
+ var clientX = _ref2.clientX;
205
+ // Allow the sidebar to be 50% of the available page width
206
+ var maxWidth = Math.round(window.innerWidth / 2);
207
+ var leftPanelWidth = (0, _utils.getLeftPanelWidth)();
208
+ var leftSidebarWidth = stableSidebarState.current.leftSidebarWidth;
209
+ var hasResizedOffLeftOfScreen = clientX < 0;
210
+ if (hasResizedOffLeftOfScreen) {
211
+ onResizeOffLeftOfScreen();
212
+ return;
213
+ }
214
+ var delta = Math.max(Math.min(clientX - leftSidebarWidth - leftPanelWidth, maxWidth - leftSidebarWidth - leftPanelWidth), _constants.COLLAPSED_LEFT_SIDEBAR_WIDTH - leftSidebarWidth - leftPanelWidth);
215
+ sidebarWidth.current = Math.max(leftSidebarWidth + delta - offset.current, _constants.COLLAPSED_LEFT_SIDEBAR_WIDTH);
216
+ document.documentElement.style.setProperty("--".concat(_constants.VAR_LEFT_SIDEBAR_WIDTH), "".concat(sidebarWidth.current, "px"));
217
+ });
218
+ }),
219
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 1),
220
+ onUpdateResize = _useState4[0];
180
221
  var onFinishResizing = function onFinishResizing() {
222
+ var _unbindEvents$current2;
181
223
  if (isLeftSidebarCollapsed) {
182
224
  return;
183
225
  }
184
226
  document.documentElement.removeAttribute(_constants.IS_SIDEBAR_DRAGGING);
185
227
 
228
+ // TODO: the control flow is pretty strange as the first codepath which calls `collapseLeftSidebar()`
229
+ // does not return an updated state snapshot.
230
+ var updatedLeftSidebarState = null;
231
+
186
232
  // If it is dragged to below the threshold,
187
233
  // collapse the navigation
188
234
  if (sidebarWidth.current < _constants.MIN_LEFT_SIDEBAR_DRAG_THRESHOLD) {
235
+ // TODO: for this codepath, `onCollapse` occurs before `onResizeEnd` which seems wrong
189
236
  document.documentElement.style.setProperty("--".concat(_constants.VAR_LEFT_SIDEBAR_WIDTH), "".concat(_constants.COLLAPSED_LEFT_SIDEBAR_WIDTH, "px"));
190
237
  collapseLeftSidebar(undefined, true);
191
238
  }
@@ -207,11 +254,18 @@ var ResizeControl = function ResizeControl(_ref) {
207
254
  }, (0, _defineProperty2.default)(_objectSpread3, _constants.VAR_LEFT_SIDEBAR_WIDTH, sidebarWidth.current), (0, _defineProperty2.default)(_objectSpread3, "lastLeftSidebarWidth", sidebarWidth.current), _objectSpread3));
208
255
  setLeftSidebarState(updatedLeftSidebarState);
209
256
  }
257
+ (_unbindEvents$current2 = unbindEvents.current) === null || _unbindEvents$current2 === void 0 ? void 0 : _unbindEvents$current2.call(unbindEvents);
258
+ unbindEvents.current = null;
259
+ onUpdateResize.cancel();
260
+ sidebarWidth.current = 0;
261
+ offset.current = 0;
262
+
263
+ // TODO: no idea why this is in an animation frame
210
264
  requestAnimationFrame(function () {
211
- onUpdateResize.cancel();
265
+ var _updatedLeftSidebarSt;
212
266
  setIsGrabAreaFocused(false);
213
- onResizeEnd && onResizeEnd(updatedLeftSidebarState);
214
- cleanupAfterResize();
267
+ // Note: the `collapseSidebar` codepath does not return state, so we need to pull it from the ref
268
+ onResizeEnd === null || onResizeEnd === void 0 ? void 0 : onResizeEnd((_updatedLeftSidebarSt = updatedLeftSidebarState) !== null && _updatedLeftSidebarSt !== void 0 ? _updatedLeftSidebarSt : stableSidebarState.current);
215
269
  });
216
270
  };
217
271
  var onKeyDown = function onKeyDown(event) {
@@ -281,7 +335,7 @@ var ResizeControl = function ResizeControl(_ref) {
281
335
  var leftSidebarPercentageExpanded = (0, _utils.getLeftSidebarPercentage)(leftSidebarState.leftSidebarWidth, maxAriaWidth);
282
336
 
283
337
  /* eslint-disable jsx-a11y/role-supports-aria-props */
284
- return (0, _react2.jsx)("div", (0, _extends2.default)({}, cssSelector, {
338
+ return (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)("div", (0, _extends2.default)({}, cssSelector, {
285
339
  css: [resizeControlStyles, (isGrabAreaFocused || isLeftSidebarCollapsed) && showResizeButtonStyles]
286
340
  }), (0, _react2.jsx)(_shadow.default, {
287
341
  testId: testId && "".concat(testId, "-shadow")
@@ -304,7 +358,9 @@ var ResizeControl = function ResizeControl(_ref) {
304
358
  label: resizeButtonLabel,
305
359
  onClick: toggleSideBar,
306
360
  testId: testId && "".concat(testId, "-resize-button")
307
- }));
361
+ })), leftSidebarState.isResizing ? (0, _react2.jsx)(_react2.Global, {
362
+ styles: globalResizingStyles
363
+ }) : null);
308
364
  /* eslint-enable jsx-a11y/role-supports-aria-props */
309
365
  };
310
366
 
@@ -18,17 +18,17 @@ var _excluded = ["isLeftSidebarCollapsed", "label", "testId"];
18
18
  /** @jsx jsx */
19
19
  var increaseHitAreaStyles = (0, _react.css)({
20
20
  position: 'absolute',
21
- top: -8,
22
- right: -12,
23
- bottom: -8,
24
- left: -8
21
+ top: "calc(-1 * ".concat("var(--ds-space-100, 8px)", ")"),
22
+ right: "calc(-1 * ".concat("var(--ds-space-150, 12px)", ")"),
23
+ bottom: "calc(-1 * ".concat("var(--ds-space-100, 8px)", ")"),
24
+ left: "calc(-1 * ".concat("var(--ds-space-100, 8px)", ")")
25
25
  });
26
26
  var resizeIconButtonStyles = (0, _react.css)({
27
27
  width: 24,
28
28
  height: 24,
29
29
  padding: 0,
30
30
  position: 'absolute',
31
- top: 32,
31
+ top: "var(--ds-space-400, 32px)",
32
32
  left: 0,
33
33
  backgroundColor: "var(--ds-surface-overlay, ".concat(_colors.N0, ")"),
34
34
  border: 0,
@@ -17,6 +17,7 @@ var shadowStyles = (0, _react.css)({
17
17
  position: 'absolute',
18
18
  top: 0,
19
19
  bottom: 0,
20
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
20
21
  left: -1,
21
22
  background: "var(--ds-border, ".concat("linear-gradient(".concat(direction, ", ").concat(colorStops, ")"), ")"),
22
23
  opacity: 0.5,
@@ -27,6 +28,7 @@ var shadowStyles = (0, _react.css)({
27
28
  });
28
29
  var draggingStyles = (0, _react.css)({
29
30
  width: 6,
31
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
30
32
  left: -6,
31
33
  background: "var(--ds-background-neutral-subtle, ".concat("linear-gradient(".concat(direction, ", ").concat(colorStops, ")"), ")"),
32
34
  opacity: 0.8
@@ -17,10 +17,13 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
17
17
  // eslint-disable-next-line @repo/internal/react/consistent-css-prop-usage
18
18
  var prefersReducedMotionStyles = (0, _react.css)((0, _motion.prefersReducedMotion)());
19
19
  var skipLinkStyles = (0, _react.css)({
20
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
20
21
  margin: 10,
22
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
21
23
  padding: '0.8rem 1rem',
22
24
  position: 'fixed',
23
25
  zIndex: -1,
26
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
24
27
  left: -999999,
25
28
  background: "var(--ds-surface-overlay, white)",
26
29
  border: 'none',
@@ -45,7 +48,7 @@ var skipLinkHeadingStyles = (0, _react.css)({
45
48
  fontWeight: 600
46
49
  });
47
50
  var skipLinkListStyles = (0, _react.css)({
48
- marginTop: 4,
51
+ marginTop: "var(--ds-space-050, 4px)",
49
52
  paddingLeft: 0,
50
53
  listStylePosition: 'outside',
51
54
  listStyleType: 'none'
@@ -24,7 +24,9 @@ var bannerFixedStyles = (0, _react2.css)({
24
24
  position: 'fixed',
25
25
  zIndex: 2,
26
26
  top: 0,
27
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
27
28
  right: _constants.RIGHT_PANEL_WIDTH,
29
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
28
30
  left: _constants.LEFT_PANEL_WIDTH
29
31
  });
30
32
 
@@ -22,8 +22,10 @@ var prefersReducedMotionStyles = (0, _react.css)((0, _motion.prefersReducedMotio
22
22
  var fixedInnerStyles = (0, _react.css)({
23
23
  width: "".concat(_constants.LEFT_SIDEBAR_WIDTH),
24
24
  position: 'fixed',
25
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
25
26
  top: "calc(".concat(_constants.BANNER_HEIGHT, " + ").concat(_constants.TOP_NAVIGATION_HEIGHT, ")"),
26
27
  bottom: 0,
28
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
27
29
  left: "".concat(_constants.LEFT_PANEL_WIDTH),
28
30
  transition: "width ".concat(_constants.TRANSITION_DURATION, "ms ").concat(_motion.easeOut, " 0s")
29
31
  });
@@ -28,7 +28,6 @@ var mainStyles = (0, _react2.css)({
28
28
  transition: "margin-left ".concat(_constants.TRANSITION_DURATION, "ms ").concat(_curves.easeOut, " 0s")
29
29
  });
30
30
  var draggingStyles = (0, _react2.css)({
31
- cursor: 'ew-resize',
32
31
  // Make sure drag to resize remains snappy.
33
32
  transition: 'none'
34
33
  });
@@ -40,6 +39,7 @@ var draggingStyles = (0, _react2.css)({
40
39
  * while main remains in place.
41
40
  */
42
41
  var flyoutStyles = (0, _react2.css)({
42
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
43
43
  marginLeft: "calc(-1 * var(--".concat(_constants.VAR_LEFT_SIDEBAR_FLYOUT, ", ").concat(_constants.DEFAULT_LEFT_SIDEBAR_FLYOUT_WIDTH, "px) + ").concat(_constants.COLLAPSED_LEFT_SIDEBAR_WIDTH, "px)")
44
44
  });
45
45
 
@@ -29,7 +29,9 @@ var fixedInnerStyles = (0, _react2.css)({
29
29
  */
30
30
  width: _constants.RIGHT_SIDEBAR_WIDTH,
31
31
  position: 'fixed',
32
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
32
33
  top: "calc(".concat(_constants.BANNER_HEIGHT, " + ").concat(_constants.TOP_NAVIGATION_HEIGHT, ")"),
34
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
33
35
  right: "calc(".concat(_constants.RIGHT_PANEL_WIDTH, ")"),
34
36
  bottom: 0
35
37
  });
@@ -23,8 +23,11 @@ var topNavigationStyles = (0, _react2.css)({
23
23
  var fixedStyles = (0, _react2.css)({
24
24
  position: 'fixed',
25
25
  zIndex: 2,
26
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
26
27
  top: _constants.BANNER_HEIGHT,
28
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
27
29
  right: _constants.RIGHT_PANEL_WIDTH,
30
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
28
31
  left: _constants.LEFT_PANEL_WIDTH
29
32
  });
30
33
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/page-layout",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "sideEffects": false
5
5
  }
@@ -7,6 +7,9 @@ const getIsDragging = () => {
7
7
  }
8
8
  return document.documentElement.getAttribute(IS_SIDEBAR_DRAGGING) === 'true';
9
9
  };
10
+
11
+ // TODO: I think this should be derived from the sidebar state,
12
+ // and not indirectly from observing an attribute change
10
13
  const useIsSidebarDragging = () => {
11
14
  const [isDragging, setIsDragging] = useState(getIsDragging);
12
15
  useEffect(() => {
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  /** @jsx jsx */
3
- import { useCallback, useContext, useMemo, useRef, useState } from 'react';
4
- import { css, jsx } from '@emotion/react';
3
+ import { Fragment, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
4
+ import { css, Global, jsx } from '@emotion/react';
5
5
  import { bindAll } from 'bind-event-listener';
6
6
  import rafSchd from 'raf-schd';
7
7
  import { COLLAPSED_LEFT_SIDEBAR_WIDTH, DEFAULT_LEFT_SIDEBAR_WIDTH, IS_SIDEBAR_DRAGGING, MIN_LEFT_SIDEBAR_DRAG_THRESHOLD, RESIZE_BUTTON_SELECTOR, RESIZE_CONTROL_SELECTOR, VAR_LEFT_SIDEBAR_WIDTH } from '../../common/constants';
@@ -19,12 +19,40 @@ const resizeControlStyles = css({
19
19
  position: 'absolute',
20
20
  top: 0,
21
21
  bottom: 0,
22
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
22
23
  left: '100%',
23
24
  outline: 'none'
24
25
  });
25
26
  const showResizeButtonStyles = css({
26
27
  '--ds--resize-button--opacity': 1
27
28
  });
29
+
30
+ // @ts-expect-error adding `!important` to style rules is currently a type error
31
+ const globalResizingStyles = css({
32
+ // eslint-disable-next-line @repo/internal/styles/no-nested-styles
33
+ '*': {
34
+ // Setting the cursor to be `ew-resize` on all elements so that even if the user
35
+ // pointer slips off the resize handle, the cursor will still be the resize cursor
36
+ cursor: 'ew-resize !important',
37
+ // Blocking selection while resizing
38
+ // Notes:
39
+ // - This prevents a user selection being caused by resizing
40
+ // - Safari + Firefox → all good
41
+ // - Chrome → This will undo the current selection while resizing (not ideal)
42
+ // - The current selection will resume after resizing
43
+ userSelect: 'none !important'
44
+ },
45
+ // eslint-disable-next-line @repo/internal/styles/no-nested-styles
46
+ iframe: {
47
+ // Disabling pointer events on iframes when resizing
48
+ // as iframes will swallower user events when the user is over them
49
+ pointerEvents: 'none !important'
50
+ }
51
+ // Note: We _could_ also disable `pointer-events` on all elements during resizing.
52
+ // However, to minimize risk we are just disabling `pointer-events` on iframes
53
+ // as that change is actually needed to fix resizing with iframes
54
+ });
55
+
28
56
  const ResizeControl = ({
29
57
  testId,
30
58
  overrides,
@@ -49,6 +77,13 @@ const ResizeControl = ({
49
77
  const keyboardEventTimeout = useRef();
50
78
  const [isGrabAreaFocused, setIsGrabAreaFocused] = useState(false);
51
79
  const unbindEvents = useRef(null);
80
+
81
+ // Used in some cases to ensure function references don't have to change
82
+ // TODO: more functions could use `stableSidebarState` rather than `leftSidebarState`
83
+ const stableSidebarState = useRef(leftSidebarState);
84
+ useEffect(() => {
85
+ stableSidebarState.current = leftSidebarState;
86
+ }, [leftSidebarState]);
52
87
  const toggleSideBar = e => {
53
88
  if (isResizing) {
54
89
  return;
@@ -83,7 +118,11 @@ const ResizeControl = ({
83
118
  offset.current = event.clientX - leftSidebarState[VAR_LEFT_SIDEBAR_WIDTH] - getLeftPanelWidth();
84
119
  unbindEvents.current = bindAll(window, [{
85
120
  type: 'mousemove',
86
- listener: onUpdateResize
121
+ listener: function (event) {
122
+ onUpdateResize({
123
+ clientX: event.clientX
124
+ });
125
+ }
87
126
  }, {
88
127
  type: 'mouseup',
89
128
  listener: onFinishResizing
@@ -149,39 +188,42 @@ const ResizeControl = ({
149
188
  offset.current = 0;
150
189
  collapseLeftSidebar(undefined, true);
151
190
  };
152
- const onUpdateResize = rafSchd(event => {
191
+
192
+ // It is important that `onUpdateResize` is a stable function reference, so that:
193
+ // 1. we ensure we are correctly throttling with `requestAnimationFrame`
194
+ // 2. that a `onUpdateResize` will cancel the one and only pending frame
195
+ // To help ensure `onUpdateResize` is stable, we are putting the last state into a ref
196
+ const [onUpdateResize] = useState(() => rafSchd(({
197
+ clientX
198
+ }) => {
153
199
  // Allow the sidebar to be 50% of the available page width
154
200
  const maxWidth = Math.round(window.innerWidth / 2);
155
201
  const leftPanelWidth = getLeftPanelWidth();
156
- const {
157
- leftSidebarWidth
158
- } = leftSidebarState;
159
- const hasResizedOffLeftOfScreen = event.clientX < 0;
202
+ const leftSidebarWidth = stableSidebarState.current.leftSidebarWidth;
203
+ const hasResizedOffLeftOfScreen = clientX < 0;
160
204
  if (hasResizedOffLeftOfScreen) {
161
205
  onResizeOffLeftOfScreen();
162
206
  return;
163
207
  }
164
- const delta = Math.max(Math.min(event.clientX - leftSidebarWidth - leftPanelWidth, maxWidth - leftSidebarWidth - leftPanelWidth), COLLAPSED_LEFT_SIDEBAR_WIDTH - leftSidebarWidth - leftPanelWidth);
208
+ const delta = Math.max(Math.min(clientX - leftSidebarWidth - leftPanelWidth, maxWidth - leftSidebarWidth - leftPanelWidth), COLLAPSED_LEFT_SIDEBAR_WIDTH - leftSidebarWidth - leftPanelWidth);
165
209
  sidebarWidth.current = Math.max(leftSidebarWidth + delta - offset.current, COLLAPSED_LEFT_SIDEBAR_WIDTH);
166
210
  document.documentElement.style.setProperty(`--${VAR_LEFT_SIDEBAR_WIDTH}`, `${sidebarWidth.current}px`);
167
- });
168
- const cleanupAfterResize = () => {
169
- var _unbindEvents$current2;
170
- sidebarWidth.current = 0;
171
- offset.current = 0;
172
- (_unbindEvents$current2 = unbindEvents.current) === null || _unbindEvents$current2 === void 0 ? void 0 : _unbindEvents$current2.call(unbindEvents);
173
- unbindEvents.current = null;
174
- };
175
- let updatedLeftSidebarState = {};
211
+ }));
176
212
  const onFinishResizing = () => {
213
+ var _unbindEvents$current2;
177
214
  if (isLeftSidebarCollapsed) {
178
215
  return;
179
216
  }
180
217
  document.documentElement.removeAttribute(IS_SIDEBAR_DRAGGING);
181
218
 
219
+ // TODO: the control flow is pretty strange as the first codepath which calls `collapseLeftSidebar()`
220
+ // does not return an updated state snapshot.
221
+ let updatedLeftSidebarState = null;
222
+
182
223
  // If it is dragged to below the threshold,
183
224
  // collapse the navigation
184
225
  if (sidebarWidth.current < MIN_LEFT_SIDEBAR_DRAG_THRESHOLD) {
226
+ // TODO: for this codepath, `onCollapse` occurs before `onResizeEnd` which seems wrong
185
227
  document.documentElement.style.setProperty(`--${VAR_LEFT_SIDEBAR_WIDTH}`, `${COLLAPSED_LEFT_SIDEBAR_WIDTH}px`);
186
228
  collapseLeftSidebar(undefined, true);
187
229
  }
@@ -207,11 +249,18 @@ const ResizeControl = ({
207
249
  };
208
250
  setLeftSidebarState(updatedLeftSidebarState);
209
251
  }
252
+ (_unbindEvents$current2 = unbindEvents.current) === null || _unbindEvents$current2 === void 0 ? void 0 : _unbindEvents$current2.call(unbindEvents);
253
+ unbindEvents.current = null;
254
+ onUpdateResize.cancel();
255
+ sidebarWidth.current = 0;
256
+ offset.current = 0;
257
+
258
+ // TODO: no idea why this is in an animation frame
210
259
  requestAnimationFrame(() => {
211
- onUpdateResize.cancel();
260
+ var _updatedLeftSidebarSt;
212
261
  setIsGrabAreaFocused(false);
213
- onResizeEnd && onResizeEnd(updatedLeftSidebarState);
214
- cleanupAfterResize();
262
+ // Note: the `collapseSidebar` codepath does not return state, so we need to pull it from the ref
263
+ onResizeEnd === null || onResizeEnd === void 0 ? void 0 : onResizeEnd((_updatedLeftSidebarSt = updatedLeftSidebarState) !== null && _updatedLeftSidebarSt !== void 0 ? _updatedLeftSidebarSt : stableSidebarState.current);
215
264
  });
216
265
  };
217
266
  const onKeyDown = event => {
@@ -287,7 +336,7 @@ const ResizeControl = ({
287
336
  const leftSidebarPercentageExpanded = getLeftSidebarPercentage(leftSidebarState.leftSidebarWidth, maxAriaWidth);
288
337
 
289
338
  /* eslint-disable jsx-a11y/role-supports-aria-props */
290
- return jsx("div", _extends({}, cssSelector, {
339
+ return jsx(Fragment, null, jsx("div", _extends({}, cssSelector, {
291
340
  css: [resizeControlStyles, (isGrabAreaFocused || isLeftSidebarCollapsed) && showResizeButtonStyles]
292
341
  }), jsx(Shadow, {
293
342
  testId: testId && `${testId}-shadow`
@@ -310,7 +359,9 @@ const ResizeControl = ({
310
359
  label: resizeButtonLabel,
311
360
  onClick: toggleSideBar,
312
361
  testId: testId && `${testId}-resize-button`
313
- }));
362
+ })), leftSidebarState.isResizing ? jsx(Global, {
363
+ styles: globalResizingStyles
364
+ }) : null);
314
365
  /* eslint-enable jsx-a11y/role-supports-aria-props */
315
366
  };
316
367
 
@@ -9,17 +9,17 @@ import { B100, B200, N0, N200, N30A } from '@atlaskit/theme/colors';
9
9
  import { RESIZE_BUTTON_SELECTOR } from '../../common/constants';
10
10
  const increaseHitAreaStyles = css({
11
11
  position: 'absolute',
12
- top: -8,
13
- right: -12,
14
- bottom: -8,
15
- left: -8
12
+ top: `calc(-1 * ${"var(--ds-space-100, 8px)"})`,
13
+ right: `calc(-1 * ${"var(--ds-space-150, 12px)"})`,
14
+ bottom: `calc(-1 * ${"var(--ds-space-100, 8px)"})`,
15
+ left: `calc(-1 * ${"var(--ds-space-100, 8px)"})`
16
16
  });
17
17
  const resizeIconButtonStyles = css({
18
18
  width: 24,
19
19
  height: 24,
20
20
  padding: 0,
21
21
  position: 'absolute',
22
- top: 32,
22
+ top: "var(--ds-space-400, 32px)",
23
23
  left: 0,
24
24
  backgroundColor: `var(--ds-surface-overlay, ${N0})`,
25
25
  border: 0,
@@ -16,6 +16,7 @@ const shadowStyles = css({
16
16
  position: 'absolute',
17
17
  top: 0,
18
18
  bottom: 0,
19
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
19
20
  left: -1,
20
21
  background: `var(--ds-border, ${`linear-gradient(${direction}, ${colorStops})`})`,
21
22
  opacity: 0.5,
@@ -26,6 +27,7 @@ const shadowStyles = css({
26
27
  });
27
28
  const draggingStyles = css({
28
29
  width: 6,
30
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
29
31
  left: -6,
30
32
  background: `var(--ds-background-neutral-subtle, ${`linear-gradient(${direction}, ${colorStops})`})`,
31
33
  opacity: 0.8
@@ -9,10 +9,13 @@ import { useSkipLinks } from '../../controllers';
9
9
  // eslint-disable-next-line @repo/internal/react/consistent-css-prop-usage
10
10
  const prefersReducedMotionStyles = css(prefersReducedMotion());
11
11
  const skipLinkStyles = css({
12
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
12
13
  margin: 10,
14
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
13
15
  padding: '0.8rem 1rem',
14
16
  position: 'fixed',
15
17
  zIndex: -1,
18
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
16
19
  left: -999999,
17
20
  background: "var(--ds-surface-overlay, white)",
18
21
  border: 'none',
@@ -37,7 +40,7 @@ const skipLinkHeadingStyles = css({
37
40
  fontWeight: 600
38
41
  });
39
42
  const skipLinkListStyles = css({
40
- marginTop: 4,
43
+ marginTop: "var(--ds-space-050, 4px)",
41
44
  paddingLeft: 0,
42
45
  listStylePosition: 'outside',
43
46
  listStyleType: 'none'
@@ -15,7 +15,9 @@ const bannerFixedStyles = css({
15
15
  position: 'fixed',
16
16
  zIndex: 2,
17
17
  top: 0,
18
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
18
19
  right: RIGHT_PANEL_WIDTH,
20
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
19
21
  left: LEFT_PANEL_WIDTH
20
22
  });
21
23
 
@@ -16,8 +16,10 @@ const prefersReducedMotionStyles = css(prefersReducedMotion());
16
16
  const fixedInnerStyles = css({
17
17
  width: `${LEFT_SIDEBAR_WIDTH}`,
18
18
  position: 'fixed',
19
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
19
20
  top: `calc(${BANNER_HEIGHT} + ${TOP_NAVIGATION_HEIGHT})`,
20
21
  bottom: 0,
22
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
21
23
  left: `${LEFT_PANEL_WIDTH}`,
22
24
  transition: `width ${TRANSITION_DURATION}ms ${easeOut} 0s`
23
25
  });
@@ -21,7 +21,6 @@ const mainStyles = css({
21
21
  transition: `margin-left ${TRANSITION_DURATION}ms ${easeOut} 0s`
22
22
  });
23
23
  const draggingStyles = css({
24
- cursor: 'ew-resize',
25
24
  // Make sure drag to resize remains snappy.
26
25
  transition: 'none'
27
26
  });
@@ -33,6 +32,7 @@ const draggingStyles = css({
33
32
  * while main remains in place.
34
33
  */
35
34
  const flyoutStyles = css({
35
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
36
36
  marginLeft: `calc(-1 * var(--${VAR_LEFT_SIDEBAR_FLYOUT}, ${DEFAULT_LEFT_SIDEBAR_FLYOUT_WIDTH}px) + ${COLLAPSED_LEFT_SIDEBAR_WIDTH}px)`
37
37
  });
38
38
 
@@ -21,7 +21,9 @@ const fixedInnerStyles = css({
21
21
  */
22
22
  width: RIGHT_SIDEBAR_WIDTH,
23
23
  position: 'fixed',
24
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
24
25
  top: `calc(${BANNER_HEIGHT} + ${TOP_NAVIGATION_HEIGHT})`,
26
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
25
27
  right: `calc(${RIGHT_PANEL_WIDTH})`,
26
28
  bottom: 0
27
29
  });
@@ -14,8 +14,11 @@ const topNavigationStyles = css({
14
14
  const fixedStyles = css({
15
15
  position: 'fixed',
16
16
  zIndex: 2,
17
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
17
18
  top: BANNER_HEIGHT,
19
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
18
20
  right: RIGHT_PANEL_WIDTH,
21
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
19
22
  left: LEFT_PANEL_WIDTH
20
23
  });
21
24
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/page-layout",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "sideEffects": false
5
5
  }
@@ -8,6 +8,9 @@ var getIsDragging = function getIsDragging() {
8
8
  }
9
9
  return document.documentElement.getAttribute(IS_SIDEBAR_DRAGGING) === 'true';
10
10
  };
11
+
12
+ // TODO: I think this should be derived from the sidebar state,
13
+ // and not indirectly from observing an attribute change
11
14
  var useIsSidebarDragging = function useIsSidebarDragging() {
12
15
  var _useState = useState(getIsDragging),
13
16
  _useState2 = _slicedToArray(_useState, 2),
@@ -4,8 +4,8 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
4
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
5
5
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
6
  /** @jsx jsx */
7
- import { useCallback, useContext, useMemo, useRef, useState } from 'react';
8
- import { css, jsx } from '@emotion/react';
7
+ import { Fragment, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
8
+ import { css, Global, jsx } from '@emotion/react';
9
9
  import { bindAll } from 'bind-event-listener';
10
10
  import rafSchd from 'raf-schd';
11
11
  import { COLLAPSED_LEFT_SIDEBAR_WIDTH, DEFAULT_LEFT_SIDEBAR_WIDTH, IS_SIDEBAR_DRAGGING, MIN_LEFT_SIDEBAR_DRAG_THRESHOLD, RESIZE_BUTTON_SELECTOR, RESIZE_CONTROL_SELECTOR, VAR_LEFT_SIDEBAR_WIDTH } from '../../common/constants';
@@ -21,12 +21,40 @@ var resizeControlStyles = css({
21
21
  position: 'absolute',
22
22
  top: 0,
23
23
  bottom: 0,
24
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
24
25
  left: '100%',
25
26
  outline: 'none'
26
27
  });
27
28
  var showResizeButtonStyles = css({
28
29
  '--ds--resize-button--opacity': 1
29
30
  });
31
+
32
+ // @ts-expect-error adding `!important` to style rules is currently a type error
33
+ var globalResizingStyles = css({
34
+ // eslint-disable-next-line @repo/internal/styles/no-nested-styles
35
+ '*': {
36
+ // Setting the cursor to be `ew-resize` on all elements so that even if the user
37
+ // pointer slips off the resize handle, the cursor will still be the resize cursor
38
+ cursor: 'ew-resize !important',
39
+ // Blocking selection while resizing
40
+ // Notes:
41
+ // - This prevents a user selection being caused by resizing
42
+ // - Safari + Firefox → all good
43
+ // - Chrome → This will undo the current selection while resizing (not ideal)
44
+ // - The current selection will resume after resizing
45
+ userSelect: 'none !important'
46
+ },
47
+ // eslint-disable-next-line @repo/internal/styles/no-nested-styles
48
+ iframe: {
49
+ // Disabling pointer events on iframes when resizing
50
+ // as iframes will swallower user events when the user is over them
51
+ pointerEvents: 'none !important'
52
+ }
53
+ // Note: We _could_ also disable `pointer-events` on all elements during resizing.
54
+ // However, to minimize risk we are just disabling `pointer-events` on iframes
55
+ // as that change is actually needed to fix resizing with iframes
56
+ });
57
+
30
58
  var ResizeControl = function ResizeControl(_ref) {
31
59
  var testId = _ref.testId,
32
60
  overrides = _ref.overrides,
@@ -52,6 +80,13 @@ var ResizeControl = function ResizeControl(_ref) {
52
80
  isGrabAreaFocused = _useState2[0],
53
81
  setIsGrabAreaFocused = _useState2[1];
54
82
  var unbindEvents = useRef(null);
83
+
84
+ // Used in some cases to ensure function references don't have to change
85
+ // TODO: more functions could use `stableSidebarState` rather than `leftSidebarState`
86
+ var stableSidebarState = useRef(leftSidebarState);
87
+ useEffect(function () {
88
+ stableSidebarState.current = leftSidebarState;
89
+ }, [leftSidebarState]);
55
90
  var toggleSideBar = function toggleSideBar(e) {
56
91
  if (isResizing) {
57
92
  return;
@@ -86,7 +121,11 @@ var ResizeControl = function ResizeControl(_ref) {
86
121
  offset.current = event.clientX - leftSidebarState[VAR_LEFT_SIDEBAR_WIDTH] - getLeftPanelWidth();
87
122
  unbindEvents.current = bindAll(window, [{
88
123
  type: 'mousemove',
89
- listener: onUpdateResize
124
+ listener: function listener(event) {
125
+ onUpdateResize({
126
+ clientX: event.clientX
127
+ });
128
+ }
90
129
  }, {
91
130
  type: 'mouseup',
92
131
  listener: onFinishResizing
@@ -151,37 +190,45 @@ var ResizeControl = function ResizeControl(_ref) {
151
190
  offset.current = 0;
152
191
  collapseLeftSidebar(undefined, true);
153
192
  };
154
- var onUpdateResize = rafSchd(function (event) {
155
- // Allow the sidebar to be 50% of the available page width
156
- var maxWidth = Math.round(window.innerWidth / 2);
157
- var leftPanelWidth = getLeftPanelWidth();
158
- var leftSidebarWidth = leftSidebarState.leftSidebarWidth;
159
- var hasResizedOffLeftOfScreen = event.clientX < 0;
160
- if (hasResizedOffLeftOfScreen) {
161
- onResizeOffLeftOfScreen();
162
- return;
163
- }
164
- var delta = Math.max(Math.min(event.clientX - leftSidebarWidth - leftPanelWidth, maxWidth - leftSidebarWidth - leftPanelWidth), COLLAPSED_LEFT_SIDEBAR_WIDTH - leftSidebarWidth - leftPanelWidth);
165
- sidebarWidth.current = Math.max(leftSidebarWidth + delta - offset.current, COLLAPSED_LEFT_SIDEBAR_WIDTH);
166
- document.documentElement.style.setProperty("--".concat(VAR_LEFT_SIDEBAR_WIDTH), "".concat(sidebarWidth.current, "px"));
167
- });
168
- var cleanupAfterResize = function cleanupAfterResize() {
169
- var _unbindEvents$current2;
170
- sidebarWidth.current = 0;
171
- offset.current = 0;
172
- (_unbindEvents$current2 = unbindEvents.current) === null || _unbindEvents$current2 === void 0 ? void 0 : _unbindEvents$current2.call(unbindEvents);
173
- unbindEvents.current = null;
174
- };
175
- var updatedLeftSidebarState = {};
193
+
194
+ // It is important that `onUpdateResize` is a stable function reference, so that:
195
+ // 1. we ensure we are correctly throttling with `requestAnimationFrame`
196
+ // 2. that a `onUpdateResize` will cancel the one and only pending frame
197
+ // To help ensure `onUpdateResize` is stable, we are putting the last state into a ref
198
+ var _useState3 = useState(function () {
199
+ return rafSchd(function (_ref2) {
200
+ var clientX = _ref2.clientX;
201
+ // Allow the sidebar to be 50% of the available page width
202
+ var maxWidth = Math.round(window.innerWidth / 2);
203
+ var leftPanelWidth = getLeftPanelWidth();
204
+ var leftSidebarWidth = stableSidebarState.current.leftSidebarWidth;
205
+ var hasResizedOffLeftOfScreen = clientX < 0;
206
+ if (hasResizedOffLeftOfScreen) {
207
+ onResizeOffLeftOfScreen();
208
+ return;
209
+ }
210
+ var delta = Math.max(Math.min(clientX - leftSidebarWidth - leftPanelWidth, maxWidth - leftSidebarWidth - leftPanelWidth), COLLAPSED_LEFT_SIDEBAR_WIDTH - leftSidebarWidth - leftPanelWidth);
211
+ sidebarWidth.current = Math.max(leftSidebarWidth + delta - offset.current, COLLAPSED_LEFT_SIDEBAR_WIDTH);
212
+ document.documentElement.style.setProperty("--".concat(VAR_LEFT_SIDEBAR_WIDTH), "".concat(sidebarWidth.current, "px"));
213
+ });
214
+ }),
215
+ _useState4 = _slicedToArray(_useState3, 1),
216
+ onUpdateResize = _useState4[0];
176
217
  var onFinishResizing = function onFinishResizing() {
218
+ var _unbindEvents$current2;
177
219
  if (isLeftSidebarCollapsed) {
178
220
  return;
179
221
  }
180
222
  document.documentElement.removeAttribute(IS_SIDEBAR_DRAGGING);
181
223
 
224
+ // TODO: the control flow is pretty strange as the first codepath which calls `collapseLeftSidebar()`
225
+ // does not return an updated state snapshot.
226
+ var updatedLeftSidebarState = null;
227
+
182
228
  // If it is dragged to below the threshold,
183
229
  // collapse the navigation
184
230
  if (sidebarWidth.current < MIN_LEFT_SIDEBAR_DRAG_THRESHOLD) {
231
+ // TODO: for this codepath, `onCollapse` occurs before `onResizeEnd` which seems wrong
185
232
  document.documentElement.style.setProperty("--".concat(VAR_LEFT_SIDEBAR_WIDTH), "".concat(COLLAPSED_LEFT_SIDEBAR_WIDTH, "px"));
186
233
  collapseLeftSidebar(undefined, true);
187
234
  }
@@ -203,11 +250,18 @@ var ResizeControl = function ResizeControl(_ref) {
203
250
  }, _defineProperty(_objectSpread3, VAR_LEFT_SIDEBAR_WIDTH, sidebarWidth.current), _defineProperty(_objectSpread3, "lastLeftSidebarWidth", sidebarWidth.current), _objectSpread3));
204
251
  setLeftSidebarState(updatedLeftSidebarState);
205
252
  }
253
+ (_unbindEvents$current2 = unbindEvents.current) === null || _unbindEvents$current2 === void 0 ? void 0 : _unbindEvents$current2.call(unbindEvents);
254
+ unbindEvents.current = null;
255
+ onUpdateResize.cancel();
256
+ sidebarWidth.current = 0;
257
+ offset.current = 0;
258
+
259
+ // TODO: no idea why this is in an animation frame
206
260
  requestAnimationFrame(function () {
207
- onUpdateResize.cancel();
261
+ var _updatedLeftSidebarSt;
208
262
  setIsGrabAreaFocused(false);
209
- onResizeEnd && onResizeEnd(updatedLeftSidebarState);
210
- cleanupAfterResize();
263
+ // Note: the `collapseSidebar` codepath does not return state, so we need to pull it from the ref
264
+ onResizeEnd === null || onResizeEnd === void 0 ? void 0 : onResizeEnd((_updatedLeftSidebarSt = updatedLeftSidebarState) !== null && _updatedLeftSidebarSt !== void 0 ? _updatedLeftSidebarSt : stableSidebarState.current);
211
265
  });
212
266
  };
213
267
  var onKeyDown = function onKeyDown(event) {
@@ -277,7 +331,7 @@ var ResizeControl = function ResizeControl(_ref) {
277
331
  var leftSidebarPercentageExpanded = getLeftSidebarPercentage(leftSidebarState.leftSidebarWidth, maxAriaWidth);
278
332
 
279
333
  /* eslint-disable jsx-a11y/role-supports-aria-props */
280
- return jsx("div", _extends({}, cssSelector, {
334
+ return jsx(Fragment, null, jsx("div", _extends({}, cssSelector, {
281
335
  css: [resizeControlStyles, (isGrabAreaFocused || isLeftSidebarCollapsed) && showResizeButtonStyles]
282
336
  }), jsx(Shadow, {
283
337
  testId: testId && "".concat(testId, "-shadow")
@@ -300,7 +354,9 @@ var ResizeControl = function ResizeControl(_ref) {
300
354
  label: resizeButtonLabel,
301
355
  onClick: toggleSideBar,
302
356
  testId: testId && "".concat(testId, "-resize-button")
303
- }));
357
+ })), leftSidebarState.isResizing ? jsx(Global, {
358
+ styles: globalResizingStyles
359
+ }) : null);
304
360
  /* eslint-enable jsx-a11y/role-supports-aria-props */
305
361
  };
306
362
 
@@ -12,17 +12,17 @@ import { B100, B200, N0, N200, N30A } from '@atlaskit/theme/colors';
12
12
  import { RESIZE_BUTTON_SELECTOR } from '../../common/constants';
13
13
  var increaseHitAreaStyles = css({
14
14
  position: 'absolute',
15
- top: -8,
16
- right: -12,
17
- bottom: -8,
18
- left: -8
15
+ top: "calc(-1 * ".concat("var(--ds-space-100, 8px)", ")"),
16
+ right: "calc(-1 * ".concat("var(--ds-space-150, 12px)", ")"),
17
+ bottom: "calc(-1 * ".concat("var(--ds-space-100, 8px)", ")"),
18
+ left: "calc(-1 * ".concat("var(--ds-space-100, 8px)", ")")
19
19
  });
20
20
  var resizeIconButtonStyles = css({
21
21
  width: 24,
22
22
  height: 24,
23
23
  padding: 0,
24
24
  position: 'absolute',
25
- top: 32,
25
+ top: "var(--ds-space-400, 32px)",
26
26
  left: 0,
27
27
  backgroundColor: "var(--ds-surface-overlay, ".concat(N0, ")"),
28
28
  border: 0,
@@ -11,6 +11,7 @@ var shadowStyles = css({
11
11
  position: 'absolute',
12
12
  top: 0,
13
13
  bottom: 0,
14
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
14
15
  left: -1,
15
16
  background: "var(--ds-border, ".concat("linear-gradient(".concat(direction, ", ").concat(colorStops, ")"), ")"),
16
17
  opacity: 0.5,
@@ -21,6 +22,7 @@ var shadowStyles = css({
21
22
  });
22
23
  var draggingStyles = css({
23
24
  width: 6,
25
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
24
26
  left: -6,
25
27
  background: "var(--ds-background-neutral-subtle, ".concat("linear-gradient(".concat(direction, ", ").concat(colorStops, ")"), ")"),
26
28
  opacity: 0.8
@@ -13,10 +13,13 @@ import { useSkipLinks } from '../../controllers';
13
13
  // eslint-disable-next-line @repo/internal/react/consistent-css-prop-usage
14
14
  var prefersReducedMotionStyles = css(prefersReducedMotion());
15
15
  var skipLinkStyles = css({
16
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
16
17
  margin: 10,
18
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
17
19
  padding: '0.8rem 1rem',
18
20
  position: 'fixed',
19
21
  zIndex: -1,
22
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
20
23
  left: -999999,
21
24
  background: "var(--ds-surface-overlay, white)",
22
25
  border: 'none',
@@ -41,7 +44,7 @@ var skipLinkHeadingStyles = css({
41
44
  fontWeight: 600
42
45
  });
43
46
  var skipLinkListStyles = css({
44
- marginTop: 4,
47
+ marginTop: "var(--ds-space-050, 4px)",
45
48
  paddingLeft: 0,
46
49
  listStylePosition: 'outside',
47
50
  listStyleType: 'none'
@@ -16,7 +16,9 @@ var bannerFixedStyles = css({
16
16
  position: 'fixed',
17
17
  zIndex: 2,
18
18
  top: 0,
19
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
19
20
  right: RIGHT_PANEL_WIDTH,
21
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
20
22
  left: LEFT_PANEL_WIDTH
21
23
  });
22
24
 
@@ -16,8 +16,10 @@ var prefersReducedMotionStyles = css(prefersReducedMotion());
16
16
  var fixedInnerStyles = css({
17
17
  width: "".concat(LEFT_SIDEBAR_WIDTH),
18
18
  position: 'fixed',
19
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
19
20
  top: "calc(".concat(BANNER_HEIGHT, " + ").concat(TOP_NAVIGATION_HEIGHT, ")"),
20
21
  bottom: 0,
22
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
21
23
  left: "".concat(LEFT_PANEL_WIDTH),
22
24
  transition: "width ".concat(TRANSITION_DURATION, "ms ").concat(easeOut, " 0s")
23
25
  });
@@ -21,7 +21,6 @@ var mainStyles = css({
21
21
  transition: "margin-left ".concat(TRANSITION_DURATION, "ms ").concat(easeOut, " 0s")
22
22
  });
23
23
  var draggingStyles = css({
24
- cursor: 'ew-resize',
25
24
  // Make sure drag to resize remains snappy.
26
25
  transition: 'none'
27
26
  });
@@ -33,6 +32,7 @@ var draggingStyles = css({
33
32
  * while main remains in place.
34
33
  */
35
34
  var flyoutStyles = css({
35
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
36
36
  marginLeft: "calc(-1 * var(--".concat(VAR_LEFT_SIDEBAR_FLYOUT, ", ").concat(DEFAULT_LEFT_SIDEBAR_FLYOUT_WIDTH, "px) + ").concat(COLLAPSED_LEFT_SIDEBAR_WIDTH, "px)")
37
37
  });
38
38
 
@@ -22,7 +22,9 @@ var fixedInnerStyles = css({
22
22
  */
23
23
  width: RIGHT_SIDEBAR_WIDTH,
24
24
  position: 'fixed',
25
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
25
26
  top: "calc(".concat(BANNER_HEIGHT, " + ").concat(TOP_NAVIGATION_HEIGHT, ")"),
27
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
26
28
  right: "calc(".concat(RIGHT_PANEL_WIDTH, ")"),
27
29
  bottom: 0
28
30
  });
@@ -15,8 +15,11 @@ var topNavigationStyles = css({
15
15
  var fixedStyles = css({
16
16
  position: 'fixed',
17
17
  zIndex: 2,
18
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
18
19
  top: BANNER_HEIGHT,
20
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
19
21
  right: RIGHT_PANEL_WIDTH,
22
+ // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
20
23
  left: LEFT_PANEL_WIDTH
21
24
  });
22
25
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/page-layout",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "sideEffects": false
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/page-layout",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "A collection of components which let you compose an application's page layout.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -48,7 +48,7 @@
48
48
  "react-dom": "^16.8.0"
49
49
  },
50
50
  "devDependencies": {
51
- "@atlaskit/atlassian-navigation": "^2.5.0",
51
+ "@atlaskit/atlassian-navigation": "^2.6.0",
52
52
  "@atlaskit/atlassian-notifications": "^0.4.0",
53
53
  "@atlaskit/button": "^16.7.0",
54
54
  "@atlaskit/docs": "*",
@@ -95,7 +95,8 @@
95
95
  "analytics-next"
96
96
  ],
97
97
  "design-tokens": [
98
- "color"
98
+ "color",
99
+ "spacing"
99
100
  ],
100
101
  "theming": [
101
102
  "react-context"