@atlaskit/page-layout 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/cjs/controllers/sidebar-resize-controller.js +98 -51
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/controllers/sidebar-resize-controller.js +100 -53
- package/dist/es2019/version.json +1 -1
- package/dist/esm/controllers/sidebar-resize-controller.js +100 -53
- package/dist/esm/version.json +1 -1
- package/package.json +18 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @atlaskit/page-layout
|
|
2
2
|
|
|
3
|
+
## 1.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`56507598609`](https://bitbucket.org/atlassian/atlassian-frontend/commits/56507598609) - Skip minor dependency bump
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
|
|
13
|
+
## 1.5.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- [`2a9f6f800ef`](https://bitbucket.org/atlassian/atlassian-frontend/commits/2a9f6f800ef) - **Fixes**
|
|
18
|
+
|
|
19
|
+
- `onLeftSidebarExpand` is no longer called when the sidebar is already open. `onLeftSidebarExpand` oculd previously be incorrectly called if a user resized an expanded sidebar to slightly smaller than the default sidebar width, or when the user cancelled a sidebar resizing operation with the `"Escape"` key
|
|
20
|
+
- the latest provided `onLeftSidebarCollapse` and `onLeftSidebarExpand` functions are now called when collapsing / expanding respectively. Previously, only the initial `onLeftSidebarCollapse` and `onLeftSidebarExpand` were called (due to a stale closure)
|
|
21
|
+
- `onLeftSidebarCollapse` and `onLeftSidebarExpand` are now called with the latest state values. Previously there were only ever called with the initial left sidebar state value (due to a stale closure)
|
|
22
|
+
|
|
23
|
+
**Improvements**
|
|
24
|
+
|
|
25
|
+
- no longer possible to trigger the collapse of the sidebar when it is already collapsed
|
|
26
|
+
- no longer possible to trigger an expand of the sidebar when it is already expanded
|
|
27
|
+
- triggering an expand while the sidebar is collapsing will now flush the pending `onLeftSidebarExpand`
|
|
28
|
+
- triggering an collapse while the sidebar is expanding will now flush the pending `onLeftSidebarCollapse`
|
|
29
|
+
- only adding the event listener for `"transitionend"` when the sidebar is expanding or collapsing.
|
|
30
|
+
- removing `"transitionend"` event listener when `<LeftSidebar />` is unmounted
|
|
31
|
+
- explicitly aborting pending collapse / expand actions when `<LeftSidebar />` is unmounted while collapsing / expanding.
|
|
32
|
+
|
|
3
33
|
## 1.4.0
|
|
4
34
|
|
|
5
35
|
### Minor Changes
|
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
exports.SidebarResizeController = void 0;
|
|
9
9
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
+
var _bindEventListener = require("bind-event-listener");
|
|
11
12
|
var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
|
|
12
13
|
var _motion = require("@atlaskit/motion");
|
|
13
14
|
var _constants = require("../common/constants");
|
|
@@ -22,7 +23,7 @@ var handleDataAttributesAndCb = function handleDataAttributesAndCb() {
|
|
|
22
23
|
document.documentElement.removeAttribute(_constants.IS_SIDEBAR_COLLAPSING);
|
|
23
24
|
callback(leftSidebarState);
|
|
24
25
|
};
|
|
25
|
-
|
|
26
|
+
var leftSidebarSelector = (0, _utils.getPageLayoutSlotCSSSelector)('left-sidebar');
|
|
26
27
|
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
27
28
|
var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
28
29
|
var children = _ref.children,
|
|
@@ -41,56 +42,35 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
41
42
|
leftSidebarState = _useState2[0],
|
|
42
43
|
setLeftSidebarState = _useState2[1];
|
|
43
44
|
var isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed;
|
|
44
|
-
var leftSidebarSelector = (0, _utils.getPageLayoutSlotCSSSelector)('left-sidebar');
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Bug: this function will cause `onExpand` / `onCollapse` when any
|
|
48
|
-
* `width` transition occurs (eg when cancelling a resizing)
|
|
49
|
-
* This
|
|
50
|
-
*/
|
|
51
|
-
var transitionEventHandler = (0, _react.useCallback)(function (event) {
|
|
52
|
-
if (event.propertyName === 'width' && event.target && event.target.matches(leftSidebarSelector)) {
|
|
53
|
-
var $leftSidebarResizeController = document.querySelector("[".concat(_constants.GRAB_AREA_SELECTOR, "]"));
|
|
54
|
-
var isCollapsed = !!$leftSidebarResizeController && $leftSidebarResizeController.hasAttribute('disabled');
|
|
55
|
-
handleDataAttributesAndCb(
|
|
56
|
-
/**
|
|
57
|
-
* Bug: `onCollapse` and `onExpand` are stale after the first render
|
|
58
|
-
*/
|
|
59
|
-
isCollapsed ? onCollapse : onExpand, isCollapsed,
|
|
60
|
-
/**
|
|
61
|
-
* Bug: `leftSidebarState` is stale after the first render
|
|
62
|
-
*/
|
|
63
|
-
leftSidebarState);
|
|
64
45
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
73
|
-
}, []);
|
|
46
|
+
// We put the latest callbacks into a ref so we can always have the latest
|
|
47
|
+
// functions in our transitionend listeners
|
|
48
|
+
var stableRef = (0, _react.useRef)({
|
|
49
|
+
onExpand: onExpand,
|
|
50
|
+
onCollapse: onCollapse
|
|
51
|
+
});
|
|
74
52
|
(0, _react.useEffect)(function () {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
*/
|
|
82
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
83
|
-
$leftSidebar.addEventListener('transitionend', transitionEventHandler);
|
|
84
|
-
}
|
|
85
|
-
}, [isLeftSidebarCollapsed, leftSidebarSelector, leftSidebarState, onCollapse, onExpand, transitionEventHandler]);
|
|
53
|
+
stableRef.current = {
|
|
54
|
+
onExpand: onExpand,
|
|
55
|
+
onCollapse: onCollapse
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
var transition = (0, _react.useRef)(null);
|
|
86
59
|
var expandLeftSidebar = (0, _react.useCallback)(function () {
|
|
60
|
+
var _transition$current, _transition$current2;
|
|
87
61
|
var lastLeftSidebarWidth = leftSidebarState.lastLeftSidebarWidth,
|
|
88
62
|
isResizing = leftSidebarState.isResizing,
|
|
89
63
|
flyoutLockCount = leftSidebarState.flyoutLockCount,
|
|
90
|
-
isFixed = leftSidebarState.isFixed
|
|
91
|
-
|
|
64
|
+
isFixed = leftSidebarState.isFixed,
|
|
65
|
+
isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed;
|
|
66
|
+
if (isResizing || !isLeftSidebarCollapsed ||
|
|
67
|
+
// already expanding
|
|
68
|
+
((_transition$current = transition.current) === null || _transition$current === void 0 ? void 0 : _transition$current.action) === 'expand') {
|
|
92
69
|
return;
|
|
93
70
|
}
|
|
71
|
+
|
|
72
|
+
// flush existing transition
|
|
73
|
+
(_transition$current2 = transition.current) === null || _transition$current2 === void 0 ? void 0 : _transition$current2.complete();
|
|
94
74
|
var width = Math.max(lastLeftSidebarWidth, _constants.DEFAULT_LEFT_SIDEBAR_WIDTH);
|
|
95
75
|
var updatedLeftSidebarState = {
|
|
96
76
|
isLeftSidebarCollapsed: false,
|
|
@@ -102,22 +82,55 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
102
82
|
isFixed: isFixed
|
|
103
83
|
};
|
|
104
84
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
105
|
-
|
|
85
|
+
function finish() {
|
|
86
|
+
handleDataAttributesAndCb(stableRef.current.onExpand, false,
|
|
87
|
+
// isCollapsed
|
|
88
|
+
updatedLeftSidebarState);
|
|
89
|
+
}
|
|
90
|
+
var sidebar = document.querySelector(leftSidebarSelector);
|
|
106
91
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
107
|
-
if ((0, _motion.isReducedMotion)()) {
|
|
108
|
-
|
|
92
|
+
if ((0, _motion.isReducedMotion)() || !sidebar) {
|
|
93
|
+
finish();
|
|
94
|
+
return;
|
|
109
95
|
}
|
|
110
|
-
|
|
96
|
+
var unbindEvent = (0, _bindEventListener.bind)(sidebar, {
|
|
97
|
+
type: 'transitionend',
|
|
98
|
+
listener: function listener(event) {
|
|
99
|
+
if (event.target === sidebar && event.propertyName === 'width') {
|
|
100
|
+
var _transition$current3;
|
|
101
|
+
(_transition$current3 = transition.current) === null || _transition$current3 === void 0 ? void 0 : _transition$current3.complete();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
var value = {
|
|
106
|
+
action: 'expand',
|
|
107
|
+
complete: function complete() {
|
|
108
|
+
value.abort();
|
|
109
|
+
finish();
|
|
110
|
+
},
|
|
111
|
+
abort: function abort() {
|
|
112
|
+
unbindEvent();
|
|
113
|
+
transition.current = null;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
transition.current = value;
|
|
117
|
+
}, [leftSidebarState]);
|
|
111
118
|
var collapseLeftSidebar = (0, _react.useCallback)(function (event, collapseWithoutTransition) {
|
|
119
|
+
var _transition$current4, _transition$current5;
|
|
112
120
|
var leftSidebarWidth = leftSidebarState.leftSidebarWidth,
|
|
113
121
|
isResizing = leftSidebarState.isResizing,
|
|
114
122
|
flyoutLockCount = leftSidebarState.flyoutLockCount,
|
|
115
123
|
isFixed = leftSidebarState.isFixed,
|
|
116
124
|
isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed;
|
|
117
|
-
if (isResizing || isLeftSidebarCollapsed
|
|
125
|
+
if (isResizing || isLeftSidebarCollapsed ||
|
|
126
|
+
// already collapsing
|
|
127
|
+
((_transition$current4 = transition.current) === null || _transition$current4 === void 0 ? void 0 : _transition$current4.action) === 'collapse') {
|
|
118
128
|
return;
|
|
119
129
|
}
|
|
120
130
|
|
|
131
|
+
// flush existing transition
|
|
132
|
+
(_transition$current5 = transition.current) === null || _transition$current5 === void 0 ? void 0 : _transition$current5.complete();
|
|
133
|
+
|
|
121
134
|
// data-attribute is used as a CSS selector to sync the hiding/showing
|
|
122
135
|
// of the nav contents with expand/collapse animation
|
|
123
136
|
document.documentElement.setAttribute(_constants.IS_SIDEBAR_COLLAPSING, 'true');
|
|
@@ -131,12 +144,46 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
131
144
|
isFixed: isFixed
|
|
132
145
|
};
|
|
133
146
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
147
|
+
function finish() {
|
|
148
|
+
handleDataAttributesAndCb(stableRef.current.onCollapse, true, updatedLeftSidebarState);
|
|
149
|
+
}
|
|
150
|
+
var sidebar = document.querySelector(leftSidebarSelector);
|
|
134
151
|
|
|
135
152
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
136
|
-
if (collapseWithoutTransition || (0, _motion.isReducedMotion)()) {
|
|
137
|
-
|
|
153
|
+
if (collapseWithoutTransition || (0, _motion.isReducedMotion)() || !sidebar) {
|
|
154
|
+
finish();
|
|
155
|
+
return;
|
|
138
156
|
}
|
|
139
|
-
|
|
157
|
+
var unbindEvent = (0, _bindEventListener.bind)(sidebar, {
|
|
158
|
+
type: 'transitionend',
|
|
159
|
+
listener: function listener(event) {
|
|
160
|
+
if (sidebar === event.target && event.propertyName === 'width') {
|
|
161
|
+
var _transition$current6;
|
|
162
|
+
(_transition$current6 = transition.current) === null || _transition$current6 === void 0 ? void 0 : _transition$current6.complete();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
var value = {
|
|
167
|
+
action: 'collapse',
|
|
168
|
+
complete: function complete() {
|
|
169
|
+
value.abort();
|
|
170
|
+
finish();
|
|
171
|
+
},
|
|
172
|
+
abort: function abort() {
|
|
173
|
+
unbindEvent();
|
|
174
|
+
transition.current = null;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
transition.current = value;
|
|
178
|
+
}, [leftSidebarState]);
|
|
179
|
+
|
|
180
|
+
// Make sure we finish any lingering transitions when unmounting
|
|
181
|
+
(0, _react.useEffect)(function mount() {
|
|
182
|
+
return function unmount() {
|
|
183
|
+
var _transition$current7;
|
|
184
|
+
(_transition$current7 = transition.current) === null || _transition$current7 === void 0 ? void 0 : _transition$current7.abort();
|
|
185
|
+
};
|
|
186
|
+
}, []);
|
|
140
187
|
var context = (0, _react.useMemo)(function () {
|
|
141
188
|
return {
|
|
142
189
|
isLeftSidebarCollapsed: isLeftSidebarCollapsed,
|
package/dist/cjs/version.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { bind } from 'bind-event-listener';
|
|
2
3
|
import noop from '@atlaskit/ds-lib/noop';
|
|
3
4
|
import { isReducedMotion } from '@atlaskit/motion';
|
|
4
|
-
import { COLLAPSED_LEFT_SIDEBAR_WIDTH, DEFAULT_LEFT_SIDEBAR_WIDTH,
|
|
5
|
+
import { COLLAPSED_LEFT_SIDEBAR_WIDTH, DEFAULT_LEFT_SIDEBAR_WIDTH, IS_SIDEBAR_COLLAPSING } from '../common/constants';
|
|
5
6
|
import { getPageLayoutSlotCSSSelector } from '../common/utils';
|
|
6
7
|
import { SidebarResizeContext } from './sidebar-resize-context';
|
|
7
8
|
const handleDataAttributesAndCb = (callback = noop, isLeftSidebarCollapsed, leftSidebarState) => {
|
|
8
9
|
document.documentElement.removeAttribute(IS_SIDEBAR_COLLAPSING);
|
|
9
10
|
callback(leftSidebarState);
|
|
10
11
|
};
|
|
11
|
-
|
|
12
|
+
const leftSidebarSelector = getPageLayoutSlotCSSSelector('left-sidebar');
|
|
12
13
|
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
13
14
|
export const SidebarResizeController = ({
|
|
14
15
|
children,
|
|
@@ -27,58 +28,37 @@ export const SidebarResizeController = ({
|
|
|
27
28
|
const {
|
|
28
29
|
isLeftSidebarCollapsed
|
|
29
30
|
} = leftSidebarState;
|
|
30
|
-
const leftSidebarSelector = getPageLayoutSlotCSSSelector('left-sidebar');
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Bug: this function will cause `onExpand` / `onCollapse` when any
|
|
34
|
-
* `width` transition occurs (eg when cancelling a resizing)
|
|
35
|
-
* This
|
|
36
|
-
*/
|
|
37
|
-
const transitionEventHandler = useCallback(event => {
|
|
38
|
-
if (event.propertyName === 'width' && event.target && event.target.matches(leftSidebarSelector)) {
|
|
39
|
-
const $leftSidebarResizeController = document.querySelector(`[${GRAB_AREA_SELECTOR}]`);
|
|
40
|
-
const isCollapsed = !!$leftSidebarResizeController && $leftSidebarResizeController.hasAttribute('disabled');
|
|
41
|
-
handleDataAttributesAndCb(
|
|
42
|
-
/**
|
|
43
|
-
* Bug: `onCollapse` and `onExpand` are stale after the first render
|
|
44
|
-
*/
|
|
45
|
-
isCollapsed ? onCollapse : onExpand, isCollapsed,
|
|
46
|
-
/**
|
|
47
|
-
* Bug: `leftSidebarState` is stale after the first render
|
|
48
|
-
*/
|
|
49
|
-
leftSidebarState);
|
|
50
31
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
59
|
-
}, []);
|
|
32
|
+
// We put the latest callbacks into a ref so we can always have the latest
|
|
33
|
+
// functions in our transitionend listeners
|
|
34
|
+
const stableRef = useRef({
|
|
35
|
+
onExpand,
|
|
36
|
+
onCollapse
|
|
37
|
+
});
|
|
60
38
|
useEffect(() => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*/
|
|
68
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
69
|
-
$leftSidebar.addEventListener('transitionend', transitionEventHandler);
|
|
70
|
-
}
|
|
71
|
-
}, [isLeftSidebarCollapsed, leftSidebarSelector, leftSidebarState, onCollapse, onExpand, transitionEventHandler]);
|
|
39
|
+
stableRef.current = {
|
|
40
|
+
onExpand,
|
|
41
|
+
onCollapse
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
const transition = useRef(null);
|
|
72
45
|
const expandLeftSidebar = useCallback(() => {
|
|
46
|
+
var _transition$current, _transition$current2;
|
|
73
47
|
const {
|
|
74
48
|
lastLeftSidebarWidth,
|
|
75
49
|
isResizing,
|
|
76
50
|
flyoutLockCount,
|
|
77
|
-
isFixed
|
|
51
|
+
isFixed,
|
|
52
|
+
isLeftSidebarCollapsed
|
|
78
53
|
} = leftSidebarState;
|
|
79
|
-
if (isResizing
|
|
54
|
+
if (isResizing || !isLeftSidebarCollapsed ||
|
|
55
|
+
// already expanding
|
|
56
|
+
((_transition$current = transition.current) === null || _transition$current === void 0 ? void 0 : _transition$current.action) === 'expand') {
|
|
80
57
|
return;
|
|
81
58
|
}
|
|
59
|
+
|
|
60
|
+
// flush existing transition
|
|
61
|
+
(_transition$current2 = transition.current) === null || _transition$current2 === void 0 ? void 0 : _transition$current2.complete();
|
|
82
62
|
const width = Math.max(lastLeftSidebarWidth, DEFAULT_LEFT_SIDEBAR_WIDTH);
|
|
83
63
|
const updatedLeftSidebarState = {
|
|
84
64
|
isLeftSidebarCollapsed: false,
|
|
@@ -90,13 +70,41 @@ export const SidebarResizeController = ({
|
|
|
90
70
|
isFixed
|
|
91
71
|
};
|
|
92
72
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
93
|
-
|
|
73
|
+
function finish() {
|
|
74
|
+
handleDataAttributesAndCb(stableRef.current.onExpand, false,
|
|
75
|
+
// isCollapsed
|
|
76
|
+
updatedLeftSidebarState);
|
|
77
|
+
}
|
|
78
|
+
const sidebar = document.querySelector(leftSidebarSelector);
|
|
94
79
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
95
|
-
if (isReducedMotion()) {
|
|
96
|
-
|
|
80
|
+
if (isReducedMotion() || !sidebar) {
|
|
81
|
+
finish();
|
|
82
|
+
return;
|
|
97
83
|
}
|
|
98
|
-
|
|
84
|
+
const unbindEvent = bind(sidebar, {
|
|
85
|
+
type: 'transitionend',
|
|
86
|
+
listener(event) {
|
|
87
|
+
if (event.target === sidebar && event.propertyName === 'width') {
|
|
88
|
+
var _transition$current3;
|
|
89
|
+
(_transition$current3 = transition.current) === null || _transition$current3 === void 0 ? void 0 : _transition$current3.complete();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
const value = {
|
|
94
|
+
action: 'expand',
|
|
95
|
+
complete: () => {
|
|
96
|
+
value.abort();
|
|
97
|
+
finish();
|
|
98
|
+
},
|
|
99
|
+
abort: () => {
|
|
100
|
+
unbindEvent();
|
|
101
|
+
transition.current = null;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
transition.current = value;
|
|
105
|
+
}, [leftSidebarState]);
|
|
99
106
|
const collapseLeftSidebar = useCallback((event, collapseWithoutTransition) => {
|
|
107
|
+
var _transition$current4, _transition$current5;
|
|
100
108
|
const {
|
|
101
109
|
leftSidebarWidth,
|
|
102
110
|
isResizing,
|
|
@@ -104,10 +112,15 @@ export const SidebarResizeController = ({
|
|
|
104
112
|
isFixed,
|
|
105
113
|
isLeftSidebarCollapsed
|
|
106
114
|
} = leftSidebarState;
|
|
107
|
-
if (isResizing || isLeftSidebarCollapsed
|
|
115
|
+
if (isResizing || isLeftSidebarCollapsed ||
|
|
116
|
+
// already collapsing
|
|
117
|
+
((_transition$current4 = transition.current) === null || _transition$current4 === void 0 ? void 0 : _transition$current4.action) === 'collapse') {
|
|
108
118
|
return;
|
|
109
119
|
}
|
|
110
120
|
|
|
121
|
+
// flush existing transition
|
|
122
|
+
(_transition$current5 = transition.current) === null || _transition$current5 === void 0 ? void 0 : _transition$current5.complete();
|
|
123
|
+
|
|
111
124
|
// data-attribute is used as a CSS selector to sync the hiding/showing
|
|
112
125
|
// of the nav contents with expand/collapse animation
|
|
113
126
|
document.documentElement.setAttribute(IS_SIDEBAR_COLLAPSING, 'true');
|
|
@@ -121,12 +134,46 @@ export const SidebarResizeController = ({
|
|
|
121
134
|
isFixed
|
|
122
135
|
};
|
|
123
136
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
137
|
+
function finish() {
|
|
138
|
+
handleDataAttributesAndCb(stableRef.current.onCollapse, true, updatedLeftSidebarState);
|
|
139
|
+
}
|
|
140
|
+
const sidebar = document.querySelector(leftSidebarSelector);
|
|
124
141
|
|
|
125
142
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
126
|
-
if (collapseWithoutTransition || isReducedMotion()) {
|
|
127
|
-
|
|
143
|
+
if (collapseWithoutTransition || isReducedMotion() || !sidebar) {
|
|
144
|
+
finish();
|
|
145
|
+
return;
|
|
128
146
|
}
|
|
129
|
-
|
|
147
|
+
const unbindEvent = bind(sidebar, {
|
|
148
|
+
type: 'transitionend',
|
|
149
|
+
listener(event) {
|
|
150
|
+
if (sidebar === event.target && event.propertyName === 'width') {
|
|
151
|
+
var _transition$current6;
|
|
152
|
+
(_transition$current6 = transition.current) === null || _transition$current6 === void 0 ? void 0 : _transition$current6.complete();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
const value = {
|
|
157
|
+
action: 'collapse',
|
|
158
|
+
complete: () => {
|
|
159
|
+
value.abort();
|
|
160
|
+
finish();
|
|
161
|
+
},
|
|
162
|
+
abort: () => {
|
|
163
|
+
unbindEvent();
|
|
164
|
+
transition.current = null;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
transition.current = value;
|
|
168
|
+
}, [leftSidebarState]);
|
|
169
|
+
|
|
170
|
+
// Make sure we finish any lingering transitions when unmounting
|
|
171
|
+
useEffect(function mount() {
|
|
172
|
+
return function unmount() {
|
|
173
|
+
var _transition$current7;
|
|
174
|
+
(_transition$current7 = transition.current) === null || _transition$current7 === void 0 ? void 0 : _transition$current7.abort();
|
|
175
|
+
};
|
|
176
|
+
}, []);
|
|
130
177
|
const context = useMemo(() => ({
|
|
131
178
|
isLeftSidebarCollapsed,
|
|
132
179
|
expandLeftSidebar,
|
package/dist/es2019/version.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
-
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { bind } from 'bind-event-listener';
|
|
3
4
|
import noop from '@atlaskit/ds-lib/noop';
|
|
4
5
|
import { isReducedMotion } from '@atlaskit/motion';
|
|
5
|
-
import { COLLAPSED_LEFT_SIDEBAR_WIDTH, DEFAULT_LEFT_SIDEBAR_WIDTH,
|
|
6
|
+
import { COLLAPSED_LEFT_SIDEBAR_WIDTH, DEFAULT_LEFT_SIDEBAR_WIDTH, IS_SIDEBAR_COLLAPSING } from '../common/constants';
|
|
6
7
|
import { getPageLayoutSlotCSSSelector } from '../common/utils';
|
|
7
8
|
import { SidebarResizeContext } from './sidebar-resize-context';
|
|
8
9
|
var handleDataAttributesAndCb = function handleDataAttributesAndCb() {
|
|
@@ -12,7 +13,7 @@ var handleDataAttributesAndCb = function handleDataAttributesAndCb() {
|
|
|
12
13
|
document.documentElement.removeAttribute(IS_SIDEBAR_COLLAPSING);
|
|
13
14
|
callback(leftSidebarState);
|
|
14
15
|
};
|
|
15
|
-
|
|
16
|
+
var leftSidebarSelector = getPageLayoutSlotCSSSelector('left-sidebar');
|
|
16
17
|
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
17
18
|
export var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
18
19
|
var children = _ref.children,
|
|
@@ -31,56 +32,35 @@ export var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
31
32
|
leftSidebarState = _useState2[0],
|
|
32
33
|
setLeftSidebarState = _useState2[1];
|
|
33
34
|
var isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed;
|
|
34
|
-
var leftSidebarSelector = getPageLayoutSlotCSSSelector('left-sidebar');
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Bug: this function will cause `onExpand` / `onCollapse` when any
|
|
38
|
-
* `width` transition occurs (eg when cancelling a resizing)
|
|
39
|
-
* This
|
|
40
|
-
*/
|
|
41
|
-
var transitionEventHandler = useCallback(function (event) {
|
|
42
|
-
if (event.propertyName === 'width' && event.target && event.target.matches(leftSidebarSelector)) {
|
|
43
|
-
var $leftSidebarResizeController = document.querySelector("[".concat(GRAB_AREA_SELECTOR, "]"));
|
|
44
|
-
var isCollapsed = !!$leftSidebarResizeController && $leftSidebarResizeController.hasAttribute('disabled');
|
|
45
|
-
handleDataAttributesAndCb(
|
|
46
|
-
/**
|
|
47
|
-
* Bug: `onCollapse` and `onExpand` are stale after the first render
|
|
48
|
-
*/
|
|
49
|
-
isCollapsed ? onCollapse : onExpand, isCollapsed,
|
|
50
|
-
/**
|
|
51
|
-
* Bug: `leftSidebarState` is stale after the first render
|
|
52
|
-
*/
|
|
53
|
-
leftSidebarState);
|
|
54
35
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
63
|
-
}, []);
|
|
36
|
+
// We put the latest callbacks into a ref so we can always have the latest
|
|
37
|
+
// functions in our transitionend listeners
|
|
38
|
+
var stableRef = useRef({
|
|
39
|
+
onExpand: onExpand,
|
|
40
|
+
onCollapse: onCollapse
|
|
41
|
+
});
|
|
64
42
|
useEffect(function () {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
*/
|
|
72
|
-
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
73
|
-
$leftSidebar.addEventListener('transitionend', transitionEventHandler);
|
|
74
|
-
}
|
|
75
|
-
}, [isLeftSidebarCollapsed, leftSidebarSelector, leftSidebarState, onCollapse, onExpand, transitionEventHandler]);
|
|
43
|
+
stableRef.current = {
|
|
44
|
+
onExpand: onExpand,
|
|
45
|
+
onCollapse: onCollapse
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
var transition = useRef(null);
|
|
76
49
|
var expandLeftSidebar = useCallback(function () {
|
|
50
|
+
var _transition$current, _transition$current2;
|
|
77
51
|
var lastLeftSidebarWidth = leftSidebarState.lastLeftSidebarWidth,
|
|
78
52
|
isResizing = leftSidebarState.isResizing,
|
|
79
53
|
flyoutLockCount = leftSidebarState.flyoutLockCount,
|
|
80
|
-
isFixed = leftSidebarState.isFixed
|
|
81
|
-
|
|
54
|
+
isFixed = leftSidebarState.isFixed,
|
|
55
|
+
isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed;
|
|
56
|
+
if (isResizing || !isLeftSidebarCollapsed ||
|
|
57
|
+
// already expanding
|
|
58
|
+
((_transition$current = transition.current) === null || _transition$current === void 0 ? void 0 : _transition$current.action) === 'expand') {
|
|
82
59
|
return;
|
|
83
60
|
}
|
|
61
|
+
|
|
62
|
+
// flush existing transition
|
|
63
|
+
(_transition$current2 = transition.current) === null || _transition$current2 === void 0 ? void 0 : _transition$current2.complete();
|
|
84
64
|
var width = Math.max(lastLeftSidebarWidth, DEFAULT_LEFT_SIDEBAR_WIDTH);
|
|
85
65
|
var updatedLeftSidebarState = {
|
|
86
66
|
isLeftSidebarCollapsed: false,
|
|
@@ -92,22 +72,55 @@ export var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
92
72
|
isFixed: isFixed
|
|
93
73
|
};
|
|
94
74
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
95
|
-
|
|
75
|
+
function finish() {
|
|
76
|
+
handleDataAttributesAndCb(stableRef.current.onExpand, false,
|
|
77
|
+
// isCollapsed
|
|
78
|
+
updatedLeftSidebarState);
|
|
79
|
+
}
|
|
80
|
+
var sidebar = document.querySelector(leftSidebarSelector);
|
|
96
81
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
97
|
-
if (isReducedMotion()) {
|
|
98
|
-
|
|
82
|
+
if (isReducedMotion() || !sidebar) {
|
|
83
|
+
finish();
|
|
84
|
+
return;
|
|
99
85
|
}
|
|
100
|
-
|
|
86
|
+
var unbindEvent = bind(sidebar, {
|
|
87
|
+
type: 'transitionend',
|
|
88
|
+
listener: function listener(event) {
|
|
89
|
+
if (event.target === sidebar && event.propertyName === 'width') {
|
|
90
|
+
var _transition$current3;
|
|
91
|
+
(_transition$current3 = transition.current) === null || _transition$current3 === void 0 ? void 0 : _transition$current3.complete();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
var value = {
|
|
96
|
+
action: 'expand',
|
|
97
|
+
complete: function complete() {
|
|
98
|
+
value.abort();
|
|
99
|
+
finish();
|
|
100
|
+
},
|
|
101
|
+
abort: function abort() {
|
|
102
|
+
unbindEvent();
|
|
103
|
+
transition.current = null;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
transition.current = value;
|
|
107
|
+
}, [leftSidebarState]);
|
|
101
108
|
var collapseLeftSidebar = useCallback(function (event, collapseWithoutTransition) {
|
|
109
|
+
var _transition$current4, _transition$current5;
|
|
102
110
|
var leftSidebarWidth = leftSidebarState.leftSidebarWidth,
|
|
103
111
|
isResizing = leftSidebarState.isResizing,
|
|
104
112
|
flyoutLockCount = leftSidebarState.flyoutLockCount,
|
|
105
113
|
isFixed = leftSidebarState.isFixed,
|
|
106
114
|
isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed;
|
|
107
|
-
if (isResizing || isLeftSidebarCollapsed
|
|
115
|
+
if (isResizing || isLeftSidebarCollapsed ||
|
|
116
|
+
// already collapsing
|
|
117
|
+
((_transition$current4 = transition.current) === null || _transition$current4 === void 0 ? void 0 : _transition$current4.action) === 'collapse') {
|
|
108
118
|
return;
|
|
109
119
|
}
|
|
110
120
|
|
|
121
|
+
// flush existing transition
|
|
122
|
+
(_transition$current5 = transition.current) === null || _transition$current5 === void 0 ? void 0 : _transition$current5.complete();
|
|
123
|
+
|
|
111
124
|
// data-attribute is used as a CSS selector to sync the hiding/showing
|
|
112
125
|
// of the nav contents with expand/collapse animation
|
|
113
126
|
document.documentElement.setAttribute(IS_SIDEBAR_COLLAPSING, 'true');
|
|
@@ -121,12 +134,46 @@ export var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
121
134
|
isFixed: isFixed
|
|
122
135
|
};
|
|
123
136
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
137
|
+
function finish() {
|
|
138
|
+
handleDataAttributesAndCb(stableRef.current.onCollapse, true, updatedLeftSidebarState);
|
|
139
|
+
}
|
|
140
|
+
var sidebar = document.querySelector(leftSidebarSelector);
|
|
124
141
|
|
|
125
142
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
126
|
-
if (collapseWithoutTransition || isReducedMotion()) {
|
|
127
|
-
|
|
143
|
+
if (collapseWithoutTransition || isReducedMotion() || !sidebar) {
|
|
144
|
+
finish();
|
|
145
|
+
return;
|
|
128
146
|
}
|
|
129
|
-
|
|
147
|
+
var unbindEvent = bind(sidebar, {
|
|
148
|
+
type: 'transitionend',
|
|
149
|
+
listener: function listener(event) {
|
|
150
|
+
if (sidebar === event.target && event.propertyName === 'width') {
|
|
151
|
+
var _transition$current6;
|
|
152
|
+
(_transition$current6 = transition.current) === null || _transition$current6 === void 0 ? void 0 : _transition$current6.complete();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
var value = {
|
|
157
|
+
action: 'collapse',
|
|
158
|
+
complete: function complete() {
|
|
159
|
+
value.abort();
|
|
160
|
+
finish();
|
|
161
|
+
},
|
|
162
|
+
abort: function abort() {
|
|
163
|
+
unbindEvent();
|
|
164
|
+
transition.current = null;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
transition.current = value;
|
|
168
|
+
}, [leftSidebarState]);
|
|
169
|
+
|
|
170
|
+
// Make sure we finish any lingering transitions when unmounting
|
|
171
|
+
useEffect(function mount() {
|
|
172
|
+
return function unmount() {
|
|
173
|
+
var _transition$current7;
|
|
174
|
+
(_transition$current7 = transition.current) === null || _transition$current7 === void 0 ? void 0 : _transition$current7.abort();
|
|
175
|
+
};
|
|
176
|
+
}, []);
|
|
130
177
|
var context = useMemo(function () {
|
|
131
178
|
return {
|
|
132
179
|
isLeftSidebarCollapsed: isLeftSidebarCollapsed,
|
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.
|
|
3
|
+
"version": "1.6.0",
|
|
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/"
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://atlassian.design/components/page-layout/",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@atlaskit/ds-lib": "^2.
|
|
29
|
-
"@atlaskit/icon": "^21.
|
|
30
|
-
"@atlaskit/motion": "^1.
|
|
31
|
-
"@atlaskit/theme": "^12.
|
|
32
|
-
"@atlaskit/tokens": "^1.
|
|
28
|
+
"@atlaskit/ds-lib": "^2.2.0",
|
|
29
|
+
"@atlaskit/icon": "^21.12.0",
|
|
30
|
+
"@atlaskit/motion": "^1.4.0",
|
|
31
|
+
"@atlaskit/theme": "^12.5.0",
|
|
32
|
+
"@atlaskit/tokens": "^1.3.0",
|
|
33
33
|
"@babel/runtime": "^7.0.0",
|
|
34
34
|
"@emotion/react": "^11.7.1",
|
|
35
35
|
"bind-event-listener": "^2.1.1",
|
|
@@ -40,20 +40,20 @@
|
|
|
40
40
|
"react-dom": "^16.8.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@atlaskit/atlassian-navigation": "^2.
|
|
44
|
-
"@atlaskit/atlassian-notifications": "^0.
|
|
45
|
-
"@atlaskit/button": "^16.
|
|
43
|
+
"@atlaskit/atlassian-navigation": "^2.5.0",
|
|
44
|
+
"@atlaskit/atlassian-notifications": "^0.4.0",
|
|
45
|
+
"@atlaskit/button": "^16.7.0",
|
|
46
46
|
"@atlaskit/docs": "*",
|
|
47
|
-
"@atlaskit/drawer": "^7.
|
|
47
|
+
"@atlaskit/drawer": "^7.5.0",
|
|
48
48
|
"@atlaskit/icon": "*",
|
|
49
|
-
"@atlaskit/logo": "^13.
|
|
50
|
-
"@atlaskit/menu": "^1.
|
|
51
|
-
"@atlaskit/notification-indicator": "^9.
|
|
52
|
-
"@atlaskit/notification-log-client": "^6.
|
|
53
|
-
"@atlaskit/onboarding": "^10.
|
|
54
|
-
"@atlaskit/popup": "^1.
|
|
55
|
-
"@atlaskit/section-message": "^6.
|
|
56
|
-
"@atlaskit/side-navigation": "^1.
|
|
49
|
+
"@atlaskit/logo": "^13.14.0",
|
|
50
|
+
"@atlaskit/menu": "^1.6.0",
|
|
51
|
+
"@atlaskit/notification-indicator": "^9.1.0",
|
|
52
|
+
"@atlaskit/notification-log-client": "^6.1.0",
|
|
53
|
+
"@atlaskit/onboarding": "^10.8.0",
|
|
54
|
+
"@atlaskit/popup": "^1.6.0",
|
|
55
|
+
"@atlaskit/section-message": "^6.4.0",
|
|
56
|
+
"@atlaskit/side-navigation": "^1.7.0",
|
|
57
57
|
"@atlaskit/ssr": "*",
|
|
58
58
|
"@atlaskit/tooltip": "*",
|
|
59
59
|
"@atlaskit/visual-regression": "*",
|