@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.
- package/CHANGELOG.md +26 -0
- package/__perf__/utils/perf-example.tsx +1 -1
- package/__perf__/utils/product-integration/notifications-popup.tsx +2 -0
- package/dist/cjs/common/hooks/use-is-sidebar-dragging.js +3 -0
- package/dist/cjs/components/resize-control/index.js +84 -28
- package/dist/cjs/components/resize-control/resize-button.js +5 -5
- package/dist/cjs/components/resize-control/shadow.js +2 -0
- package/dist/cjs/components/skip-links/skip-link-components.js +4 -1
- package/dist/cjs/components/slots/banner-slot.js +2 -0
- package/dist/cjs/components/slots/internal/left-sidebar-inner.js +2 -0
- package/dist/cjs/components/slots/main.js +1 -1
- package/dist/cjs/components/slots/right-sidebar.js +2 -0
- package/dist/cjs/components/slots/top-navigation.js +3 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/common/hooks/use-is-sidebar-dragging.js +3 -0
- package/dist/es2019/components/resize-control/index.js +74 -23
- package/dist/es2019/components/resize-control/resize-button.js +5 -5
- package/dist/es2019/components/resize-control/shadow.js +2 -0
- package/dist/es2019/components/skip-links/skip-link-components.js +4 -1
- package/dist/es2019/components/slots/banner-slot.js +2 -0
- package/dist/es2019/components/slots/internal/left-sidebar-inner.js +2 -0
- package/dist/es2019/components/slots/main.js +1 -1
- package/dist/es2019/components/slots/right-sidebar.js +2 -0
- package/dist/es2019/components/slots/top-navigation.js +3 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/common/hooks/use-is-sidebar-dragging.js +3 -0
- package/dist/esm/components/resize-control/index.js +86 -30
- package/dist/esm/components/resize-control/resize-button.js +5 -5
- package/dist/esm/components/resize-control/shadow.js +2 -0
- package/dist/esm/components/skip-links/skip-link-components.js +4 -1
- package/dist/esm/components/slots/banner-slot.js +2 -0
- package/dist/esm/components/slots/internal/left-sidebar-inner.js +2 -0
- package/dist/esm/components/slots/main.js +1 -1
- package/dist/esm/components/slots/right-sidebar.js +2 -0
- package/dist/esm/components/slots/top-navigation.js +3 -0
- package/dist/esm/version.json +1 -1
- 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:
|
|
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:
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
-
|
|
265
|
+
var _updatedLeftSidebarSt;
|
|
212
266
|
setIsGrabAreaFocused(false);
|
|
213
|
-
|
|
214
|
-
|
|
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: -
|
|
22
|
-
right: -
|
|
23
|
-
bottom: -
|
|
24
|
-
left: -
|
|
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:
|
|
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:
|
|
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
|
|
package/dist/cjs/version.json
CHANGED
|
@@ -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:
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
260
|
+
var _updatedLeftSidebarSt;
|
|
212
261
|
setIsGrabAreaFocused(false);
|
|
213
|
-
|
|
214
|
-
|
|
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: -
|
|
13
|
-
right: -
|
|
14
|
-
bottom: -
|
|
15
|
-
left: -
|
|
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:
|
|
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:
|
|
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
|
|
package/dist/es2019/version.json
CHANGED
|
@@ -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:
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
261
|
+
var _updatedLeftSidebarSt;
|
|
208
262
|
setIsGrabAreaFocused(false);
|
|
209
|
-
|
|
210
|
-
|
|
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: -
|
|
16
|
-
right: -
|
|
17
|
-
bottom: -
|
|
18
|
-
left: -
|
|
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:
|
|
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:
|
|
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
|
|
package/dist/esm/version.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/page-layout",
|
|
3
|
-
"version": "1.6.
|
|
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.
|
|
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"
|