@atlaskit/page-layout 1.3.10 → 1.5.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 +28 -0
- package/dist/cjs/components/resize-control/grab-area.js +1 -0
- package/dist/cjs/components/resize-control/index.js +74 -19
- package/dist/cjs/components/resize-control/resize-button.js +1 -0
- package/dist/cjs/components/skip-links/skip-link-components.js +1 -1
- package/dist/cjs/components/slots/left-sidebar.js +1 -1
- package/dist/cjs/controllers/sidebar-resize-controller.js +98 -29
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/components/resize-control/index.js +74 -19
- package/dist/es2019/controllers/sidebar-resize-controller.js +100 -31
- package/dist/es2019/version.json +1 -1
- package/dist/esm/components/resize-control/index.js +73 -18
- package/dist/esm/controllers/sidebar-resize-controller.js +100 -31
- package/dist/esm/version.json +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @atlaskit/page-layout
|
|
2
2
|
|
|
3
|
+
## 1.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`2a9f6f800ef`](https://bitbucket.org/atlassian/atlassian-frontend/commits/2a9f6f800ef) - **Fixes**
|
|
8
|
+
|
|
9
|
+
- `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
|
|
10
|
+
- 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)
|
|
11
|
+
- `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)
|
|
12
|
+
|
|
13
|
+
**Improvements**
|
|
14
|
+
|
|
15
|
+
- no longer possible to trigger the collapse of the sidebar when it is already collapsed
|
|
16
|
+
- no longer possible to trigger an expand of the sidebar when it is already expanded
|
|
17
|
+
- triggering an expand while the sidebar is collapsing will now flush the pending `onLeftSidebarExpand`
|
|
18
|
+
- triggering an collapse while the sidebar is expanding will now flush the pending `onLeftSidebarCollapse`
|
|
19
|
+
- only adding the event listener for `"transitionend"` when the sidebar is expanding or collapsing.
|
|
20
|
+
- removing `"transitionend"` event listener when `<LeftSidebar />` is unmounted
|
|
21
|
+
- explicitly aborting pending collapse / expand actions when `<LeftSidebar />` is unmounted while collapsing / expanding.
|
|
22
|
+
|
|
23
|
+
## 1.4.0
|
|
24
|
+
|
|
25
|
+
### Minor Changes
|
|
26
|
+
|
|
27
|
+
- [`955ee3ea8fe`](https://bitbucket.org/atlassian/atlassian-frontend/commits/955ee3ea8fe) - [ux] **fix**: if a `"mousedown"`, `"click"`, `"resize"` or `"visibilitychange"` event occurs while the sidebar is being resized, then the resizing operation will end
|
|
28
|
+
|
|
29
|
+
[ux] **new**: if a user presses the `"Escape"` key while the sidebar is being resized, then the resizing operation will end
|
|
30
|
+
|
|
3
31
|
## 1.3.10
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
|
@@ -12,6 +12,7 @@ var _react = require("@emotion/react");
|
|
|
12
12
|
var _colors = require("@atlaskit/theme/colors");
|
|
13
13
|
var _constants = require("../../common/constants");
|
|
14
14
|
var _excluded = ["testId", "isLeftSidebarCollapsed"];
|
|
15
|
+
/** @jsx jsx */
|
|
15
16
|
/**
|
|
16
17
|
* Determines the color of the grab line.
|
|
17
18
|
*
|
|
@@ -19,7 +19,7 @@ var _grabArea = _interopRequireDefault(require("./grab-area"));
|
|
|
19
19
|
var _resizeButton2 = _interopRequireDefault(require("./resize-button"));
|
|
20
20
|
var _shadow = _interopRequireDefault(require("./shadow"));
|
|
21
21
|
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; }
|
|
22
|
-
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) { (0, _defineProperty2.default)(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; }
|
|
22
|
+
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) { (0, _defineProperty2.default)(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; } /** @jsx jsx */ /* import useUpdateCssVar from '../../controllers/use-update-css-vars'; */
|
|
23
23
|
var cssSelector = (0, _defineProperty2.default)({}, _constants.RESIZE_CONTROL_SELECTOR, true);
|
|
24
24
|
var resizeControlStyles = (0, _react2.css)({
|
|
25
25
|
position: 'absolute',
|
|
@@ -47,7 +47,7 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
47
47
|
setLeftSidebarState = _useContext.setLeftSidebarState;
|
|
48
48
|
var isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed,
|
|
49
49
|
isResizing = leftSidebarState.isResizing;
|
|
50
|
-
var
|
|
50
|
+
var sidebarWidth = (0, _react.useRef)(leftSidebarState[_constants.VAR_LEFT_SIDEBAR_WIDTH]);
|
|
51
51
|
// Distance of mouse from left sidebar onMouseDown
|
|
52
52
|
var offset = (0, _react.useRef)(0);
|
|
53
53
|
var keyboardEventTimeout = (0, _react.useRef)();
|
|
@@ -77,13 +77,67 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
77
77
|
if (isLeftSidebarCollapsed) {
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
// TODO: should only a primary pointer be able to start a resize?
|
|
82
|
+
// Keeping as is for now, but worth considering
|
|
83
|
+
|
|
84
|
+
// It is possible for a mousedown to fire during a resize
|
|
85
|
+
// Example: the user presses another pointer button while dragging
|
|
86
|
+
if (leftSidebarState.isResizing) {
|
|
87
|
+
// the resize will be cancelled by our global event listeners
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
80
90
|
offset.current = event.clientX - leftSidebarState[_constants.VAR_LEFT_SIDEBAR_WIDTH] - (0, _utils.getLeftPanelWidth)();
|
|
81
|
-
unbindEvents.current = (0, _bindEventListener.bindAll)(
|
|
91
|
+
unbindEvents.current = (0, _bindEventListener.bindAll)(window, [{
|
|
82
92
|
type: 'mousemove',
|
|
83
|
-
listener:
|
|
93
|
+
listener: onUpdateResize
|
|
84
94
|
}, {
|
|
85
95
|
type: 'mouseup',
|
|
86
|
-
listener:
|
|
96
|
+
listener: onFinishResizing
|
|
97
|
+
}, {
|
|
98
|
+
type: 'mousedown',
|
|
99
|
+
// this mousedown event listener is being added in the bubble phase
|
|
100
|
+
// on a higher event target than the resize handle.
|
|
101
|
+
// This means that the original mousedown event that triggers a resize
|
|
102
|
+
// can hit this mousedown handler. To get around that, we only call
|
|
103
|
+
// `onFinishResizing` after an animation frame so we don't pick up the original event
|
|
104
|
+
// Alternatives:
|
|
105
|
+
// 1. Add the window 'mousedown' event listener in the capture phase
|
|
106
|
+
// 👎 A 'mousedown' during a resize would trigger a new resize to start
|
|
107
|
+
// 2. Do 1. and call `event.preventDefault()`, then check for `event.defaultPrevented` inside
|
|
108
|
+
// the grab handle `onMouseDown`
|
|
109
|
+
// 👎 Not ideal to cancel events if we don't have to
|
|
110
|
+
listener: function () {
|
|
111
|
+
var hasFramePassed = false;
|
|
112
|
+
requestAnimationFrame(function () {
|
|
113
|
+
hasFramePassed = true;
|
|
114
|
+
});
|
|
115
|
+
return function listener() {
|
|
116
|
+
if (hasFramePassed) {
|
|
117
|
+
onFinishResizing();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}()
|
|
121
|
+
}, {
|
|
122
|
+
type: 'visibilitychange',
|
|
123
|
+
listener: onFinishResizing
|
|
124
|
+
},
|
|
125
|
+
// A 'click' event should never be hit as the 'mouseup' will come first and cause
|
|
126
|
+
// these event listeners to be unbound. I just added 'click' for extreme safety (paranoia)
|
|
127
|
+
{
|
|
128
|
+
type: 'click',
|
|
129
|
+
listener: onFinishResizing
|
|
130
|
+
}, {
|
|
131
|
+
type: 'keydown',
|
|
132
|
+
listener: function listener(event) {
|
|
133
|
+
// Can cancel resizing by pressing "Escape"
|
|
134
|
+
// Will return sidebar to the same size it was before the resizing started
|
|
135
|
+
if (event.key === 'Escape') {
|
|
136
|
+
sidebarWidth.current = Math.max(leftSidebarState.lastLeftSidebarWidth, _constants.COLLAPSED_LEFT_SIDEBAR_WIDTH);
|
|
137
|
+
document.documentElement.style.setProperty("--".concat(_constants.VAR_LEFT_SIDEBAR_WIDTH), "".concat(sidebarWidth.current, "px"));
|
|
138
|
+
onFinishResizing();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
87
141
|
}]);
|
|
88
142
|
document.documentElement.setAttribute(_constants.IS_SIDEBAR_DRAGGING, 'true');
|
|
89
143
|
var newLeftbarState = _objectSpread(_objectSpread({}, leftSidebarState), {}, {
|
|
@@ -92,37 +146,38 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
92
146
|
setLeftSidebarState(newLeftbarState);
|
|
93
147
|
onResizeStart && onResizeStart(newLeftbarState);
|
|
94
148
|
};
|
|
95
|
-
var
|
|
149
|
+
var onResizeOffLeftOfScreen = function onResizeOffLeftOfScreen() {
|
|
96
150
|
var _unbindEvents$current;
|
|
97
|
-
|
|
151
|
+
onUpdateResize.cancel();
|
|
98
152
|
(_unbindEvents$current = unbindEvents.current) === null || _unbindEvents$current === void 0 ? void 0 : _unbindEvents$current.call(unbindEvents);
|
|
99
153
|
unbindEvents.current = null;
|
|
100
154
|
document.documentElement.removeAttribute(_constants.IS_SIDEBAR_DRAGGING);
|
|
101
155
|
offset.current = 0;
|
|
102
156
|
collapseLeftSidebar(undefined, true);
|
|
103
157
|
};
|
|
104
|
-
var
|
|
158
|
+
var onUpdateResize = (0, _rafSchd.default)(function (event) {
|
|
105
159
|
// Allow the sidebar to be 50% of the available page width
|
|
106
160
|
var maxWidth = Math.round(window.innerWidth / 2);
|
|
107
161
|
var leftPanelWidth = (0, _utils.getLeftPanelWidth)();
|
|
108
162
|
var leftSidebarWidth = leftSidebarState.leftSidebarWidth;
|
|
109
|
-
var
|
|
110
|
-
if (
|
|
111
|
-
|
|
163
|
+
var hasResizedOffLeftOfScreen = event.clientX < 0;
|
|
164
|
+
if (hasResizedOffLeftOfScreen) {
|
|
165
|
+
onResizeOffLeftOfScreen();
|
|
166
|
+
return;
|
|
112
167
|
}
|
|
113
168
|
var delta = Math.max(Math.min(event.clientX - leftSidebarWidth - leftPanelWidth, maxWidth - leftSidebarWidth - leftPanelWidth), _constants.COLLAPSED_LEFT_SIDEBAR_WIDTH - leftSidebarWidth - leftPanelWidth);
|
|
114
|
-
|
|
115
|
-
document.documentElement.style.setProperty("--".concat(_constants.VAR_LEFT_SIDEBAR_WIDTH), "".concat(
|
|
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"));
|
|
116
171
|
});
|
|
117
172
|
var cleanupAfterResize = function cleanupAfterResize() {
|
|
118
173
|
var _unbindEvents$current2;
|
|
119
|
-
|
|
174
|
+
sidebarWidth.current = 0;
|
|
120
175
|
offset.current = 0;
|
|
121
176
|
(_unbindEvents$current2 = unbindEvents.current) === null || _unbindEvents$current2 === void 0 ? void 0 : _unbindEvents$current2.call(unbindEvents);
|
|
122
177
|
unbindEvents.current = null;
|
|
123
178
|
};
|
|
124
179
|
var updatedLeftSidebarState = {};
|
|
125
|
-
var
|
|
180
|
+
var onFinishResizing = function onFinishResizing() {
|
|
126
181
|
if (isLeftSidebarCollapsed) {
|
|
127
182
|
return;
|
|
128
183
|
}
|
|
@@ -130,14 +185,14 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
130
185
|
|
|
131
186
|
// If it is dragged to below the threshold,
|
|
132
187
|
// collapse the navigation
|
|
133
|
-
if (
|
|
188
|
+
if (sidebarWidth.current < _constants.MIN_LEFT_SIDEBAR_DRAG_THRESHOLD) {
|
|
134
189
|
document.documentElement.style.setProperty("--".concat(_constants.VAR_LEFT_SIDEBAR_WIDTH), "".concat(_constants.COLLAPSED_LEFT_SIDEBAR_WIDTH, "px"));
|
|
135
190
|
collapseLeftSidebar(undefined, true);
|
|
136
191
|
}
|
|
137
192
|
// If it is dragged to position in between the
|
|
138
193
|
// min threshold and default width
|
|
139
194
|
// expand the nav to the default width
|
|
140
|
-
else if (
|
|
195
|
+
else if (sidebarWidth.current > _constants.MIN_LEFT_SIDEBAR_DRAG_THRESHOLD && sidebarWidth.current < _constants.DEFAULT_LEFT_SIDEBAR_WIDTH) {
|
|
141
196
|
var _objectSpread2;
|
|
142
197
|
document.documentElement.style.setProperty("--".concat(_constants.VAR_LEFT_SIDEBAR_WIDTH), "".concat(_constants.DEFAULT_LEFT_SIDEBAR_WIDTH, "px"));
|
|
143
198
|
updatedLeftSidebarState = _objectSpread(_objectSpread({}, leftSidebarState), {}, (_objectSpread2 = {
|
|
@@ -149,11 +204,11 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
149
204
|
// otherwise resize it to the desired width
|
|
150
205
|
updatedLeftSidebarState = _objectSpread(_objectSpread({}, leftSidebarState), {}, (_objectSpread3 = {
|
|
151
206
|
isResizing: false
|
|
152
|
-
}, (0, _defineProperty2.default)(_objectSpread3, _constants.VAR_LEFT_SIDEBAR_WIDTH,
|
|
207
|
+
}, (0, _defineProperty2.default)(_objectSpread3, _constants.VAR_LEFT_SIDEBAR_WIDTH, sidebarWidth.current), (0, _defineProperty2.default)(_objectSpread3, "lastLeftSidebarWidth", sidebarWidth.current), _objectSpread3));
|
|
153
208
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
154
209
|
}
|
|
155
210
|
requestAnimationFrame(function () {
|
|
156
|
-
|
|
211
|
+
onUpdateResize.cancel();
|
|
157
212
|
setIsGrabAreaFocused(false);
|
|
158
213
|
onResizeEnd && onResizeEnd(updatedLeftSidebarState);
|
|
159
214
|
cleanupAfterResize();
|
|
@@ -15,6 +15,7 @@ var _durations = require("@atlaskit/motion/durations");
|
|
|
15
15
|
var _colors = require("@atlaskit/theme/colors");
|
|
16
16
|
var _constants = require("../../common/constants");
|
|
17
17
|
var _excluded = ["isLeftSidebarCollapsed", "label", "testId"];
|
|
18
|
+
/** @jsx jsx */
|
|
18
19
|
var increaseHitAreaStyles = (0, _react.css)({
|
|
19
20
|
position: 'absolute',
|
|
20
21
|
top: -8,
|
|
@@ -13,7 +13,7 @@ var _colors = require("@atlaskit/theme/colors");
|
|
|
13
13
|
var _constants = require("../../common/constants");
|
|
14
14
|
var _controllers = require("../../controllers");
|
|
15
15
|
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; }
|
|
16
|
-
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) { (0, _defineProperty2.default)(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; }
|
|
16
|
+
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) { (0, _defineProperty2.default)(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; } /* eslint-disable @repo/internal/dom-events/no-unsafe-event-listeners */ /** @jsx jsx */
|
|
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)({
|
|
@@ -17,7 +17,7 @@ var _leftSidebarOuter = _interopRequireDefault(require("./internal/left-sidebar-
|
|
|
17
17
|
var _resizableChildrenWrapper = _interopRequireDefault(require("./internal/resizable-children-wrapper"));
|
|
18
18
|
var _slotDimensions = _interopRequireDefault(require("./slot-dimensions"));
|
|
19
19
|
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; }
|
|
20
|
-
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) { (0, _defineProperty2.default)(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; }
|
|
20
|
+
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) { (0, _defineProperty2.default)(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; } /* eslint-disable @repo/internal/dom-events/no-unsafe-event-listeners */ /** @jsx jsx */
|
|
21
21
|
/**
|
|
22
22
|
* __Left sidebar__
|
|
23
23
|
*
|
|
@@ -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,34 +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
|
-
var transitionEventHandler = (0, _react.useCallback)(function (event) {
|
|
46
|
-
if (event.propertyName === 'width' && event.target && event.target.matches(leftSidebarSelector)) {
|
|
47
|
-
var $leftSidebarResizeController = document.querySelector("[".concat(_constants.GRAB_AREA_SELECTOR, "]"));
|
|
48
|
-
var isCollapsed = !!$leftSidebarResizeController && $leftSidebarResizeController.hasAttribute('disabled');
|
|
49
|
-
handleDataAttributesAndCb(isCollapsed ? onCollapse : onExpand, isCollapsed, leftSidebarState);
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
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
|
+
});
|
|
57
52
|
(0, _react.useEffect)(function () {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
stableRef.current = {
|
|
54
|
+
onExpand: onExpand,
|
|
55
|
+
onCollapse: onCollapse
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
var transition = (0, _react.useRef)(null);
|
|
64
59
|
var expandLeftSidebar = (0, _react.useCallback)(function () {
|
|
60
|
+
var _transition$current, _transition$current2;
|
|
65
61
|
var lastLeftSidebarWidth = leftSidebarState.lastLeftSidebarWidth,
|
|
66
62
|
isResizing = leftSidebarState.isResizing,
|
|
67
63
|
flyoutLockCount = leftSidebarState.flyoutLockCount,
|
|
68
|
-
isFixed = leftSidebarState.isFixed
|
|
69
|
-
|
|
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') {
|
|
70
69
|
return;
|
|
71
70
|
}
|
|
71
|
+
|
|
72
|
+
// flush existing transition
|
|
73
|
+
(_transition$current2 = transition.current) === null || _transition$current2 === void 0 ? void 0 : _transition$current2.complete();
|
|
72
74
|
var width = Math.max(lastLeftSidebarWidth, _constants.DEFAULT_LEFT_SIDEBAR_WIDTH);
|
|
73
75
|
var updatedLeftSidebarState = {
|
|
74
76
|
isLeftSidebarCollapsed: false,
|
|
@@ -80,22 +82,55 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
80
82
|
isFixed: isFixed
|
|
81
83
|
};
|
|
82
84
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
83
|
-
|
|
85
|
+
function finish() {
|
|
86
|
+
handleDataAttributesAndCb(stableRef.current.onExpand, false,
|
|
87
|
+
// isCollapsed
|
|
88
|
+
updatedLeftSidebarState);
|
|
89
|
+
}
|
|
90
|
+
var sidebar = document.querySelector(leftSidebarSelector);
|
|
84
91
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
85
|
-
if ((0, _motion.isReducedMotion)()) {
|
|
86
|
-
|
|
92
|
+
if ((0, _motion.isReducedMotion)() || !sidebar) {
|
|
93
|
+
finish();
|
|
94
|
+
return;
|
|
87
95
|
}
|
|
88
|
-
|
|
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]);
|
|
89
118
|
var collapseLeftSidebar = (0, _react.useCallback)(function (event, collapseWithoutTransition) {
|
|
119
|
+
var _transition$current4, _transition$current5;
|
|
90
120
|
var leftSidebarWidth = leftSidebarState.leftSidebarWidth,
|
|
91
121
|
isResizing = leftSidebarState.isResizing,
|
|
92
122
|
flyoutLockCount = leftSidebarState.flyoutLockCount,
|
|
93
123
|
isFixed = leftSidebarState.isFixed,
|
|
94
124
|
isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed;
|
|
95
|
-
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') {
|
|
96
128
|
return;
|
|
97
129
|
}
|
|
98
130
|
|
|
131
|
+
// flush existing transition
|
|
132
|
+
(_transition$current5 = transition.current) === null || _transition$current5 === void 0 ? void 0 : _transition$current5.complete();
|
|
133
|
+
|
|
99
134
|
// data-attribute is used as a CSS selector to sync the hiding/showing
|
|
100
135
|
// of the nav contents with expand/collapse animation
|
|
101
136
|
document.documentElement.setAttribute(_constants.IS_SIDEBAR_COLLAPSING, 'true');
|
|
@@ -109,12 +144,46 @@ var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
109
144
|
isFixed: isFixed
|
|
110
145
|
};
|
|
111
146
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
147
|
+
function finish() {
|
|
148
|
+
handleDataAttributesAndCb(stableRef.current.onCollapse, true, updatedLeftSidebarState);
|
|
149
|
+
}
|
|
150
|
+
var sidebar = document.querySelector(leftSidebarSelector);
|
|
112
151
|
|
|
113
152
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
114
|
-
if (collapseWithoutTransition || (0, _motion.isReducedMotion)()) {
|
|
115
|
-
|
|
153
|
+
if (collapseWithoutTransition || (0, _motion.isReducedMotion)() || !sidebar) {
|
|
154
|
+
finish();
|
|
155
|
+
return;
|
|
116
156
|
}
|
|
117
|
-
|
|
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
|
+
}, []);
|
|
118
187
|
var context = (0, _react.useMemo)(function () {
|
|
119
188
|
return {
|
|
120
189
|
isLeftSidebarCollapsed: isLeftSidebarCollapsed,
|
package/dist/cjs/version.json
CHANGED
|
@@ -43,7 +43,7 @@ const ResizeControl = ({
|
|
|
43
43
|
isLeftSidebarCollapsed,
|
|
44
44
|
isResizing
|
|
45
45
|
} = leftSidebarState;
|
|
46
|
-
const
|
|
46
|
+
const sidebarWidth = useRef(leftSidebarState[VAR_LEFT_SIDEBAR_WIDTH]);
|
|
47
47
|
// Distance of mouse from left sidebar onMouseDown
|
|
48
48
|
const offset = useRef(0);
|
|
49
49
|
const keyboardEventTimeout = useRef();
|
|
@@ -70,13 +70,67 @@ const ResizeControl = ({
|
|
|
70
70
|
if (isLeftSidebarCollapsed) {
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
|
+
|
|
74
|
+
// TODO: should only a primary pointer be able to start a resize?
|
|
75
|
+
// Keeping as is for now, but worth considering
|
|
76
|
+
|
|
77
|
+
// It is possible for a mousedown to fire during a resize
|
|
78
|
+
// Example: the user presses another pointer button while dragging
|
|
79
|
+
if (leftSidebarState.isResizing) {
|
|
80
|
+
// the resize will be cancelled by our global event listeners
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
73
83
|
offset.current = event.clientX - leftSidebarState[VAR_LEFT_SIDEBAR_WIDTH] - getLeftPanelWidth();
|
|
74
|
-
unbindEvents.current = bindAll(
|
|
84
|
+
unbindEvents.current = bindAll(window, [{
|
|
75
85
|
type: 'mousemove',
|
|
76
|
-
listener:
|
|
86
|
+
listener: onUpdateResize
|
|
77
87
|
}, {
|
|
78
88
|
type: 'mouseup',
|
|
79
|
-
listener:
|
|
89
|
+
listener: onFinishResizing
|
|
90
|
+
}, {
|
|
91
|
+
type: 'mousedown',
|
|
92
|
+
// this mousedown event listener is being added in the bubble phase
|
|
93
|
+
// on a higher event target than the resize handle.
|
|
94
|
+
// This means that the original mousedown event that triggers a resize
|
|
95
|
+
// can hit this mousedown handler. To get around that, we only call
|
|
96
|
+
// `onFinishResizing` after an animation frame so we don't pick up the original event
|
|
97
|
+
// Alternatives:
|
|
98
|
+
// 1. Add the window 'mousedown' event listener in the capture phase
|
|
99
|
+
// 👎 A 'mousedown' during a resize would trigger a new resize to start
|
|
100
|
+
// 2. Do 1. and call `event.preventDefault()`, then check for `event.defaultPrevented` inside
|
|
101
|
+
// the grab handle `onMouseDown`
|
|
102
|
+
// 👎 Not ideal to cancel events if we don't have to
|
|
103
|
+
listener: (() => {
|
|
104
|
+
let hasFramePassed = false;
|
|
105
|
+
requestAnimationFrame(() => {
|
|
106
|
+
hasFramePassed = true;
|
|
107
|
+
});
|
|
108
|
+
return function listener() {
|
|
109
|
+
if (hasFramePassed) {
|
|
110
|
+
onFinishResizing();
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
})()
|
|
114
|
+
}, {
|
|
115
|
+
type: 'visibilitychange',
|
|
116
|
+
listener: onFinishResizing
|
|
117
|
+
},
|
|
118
|
+
// A 'click' event should never be hit as the 'mouseup' will come first and cause
|
|
119
|
+
// these event listeners to be unbound. I just added 'click' for extreme safety (paranoia)
|
|
120
|
+
{
|
|
121
|
+
type: 'click',
|
|
122
|
+
listener: onFinishResizing
|
|
123
|
+
}, {
|
|
124
|
+
type: 'keydown',
|
|
125
|
+
listener: event => {
|
|
126
|
+
// Can cancel resizing by pressing "Escape"
|
|
127
|
+
// Will return sidebar to the same size it was before the resizing started
|
|
128
|
+
if (event.key === 'Escape') {
|
|
129
|
+
sidebarWidth.current = Math.max(leftSidebarState.lastLeftSidebarWidth, COLLAPSED_LEFT_SIDEBAR_WIDTH);
|
|
130
|
+
document.documentElement.style.setProperty(`--${VAR_LEFT_SIDEBAR_WIDTH}`, `${sidebarWidth.current}px`);
|
|
131
|
+
onFinishResizing();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
80
134
|
}]);
|
|
81
135
|
document.documentElement.setAttribute(IS_SIDEBAR_DRAGGING, 'true');
|
|
82
136
|
const newLeftbarState = {
|
|
@@ -86,39 +140,40 @@ const ResizeControl = ({
|
|
|
86
140
|
setLeftSidebarState(newLeftbarState);
|
|
87
141
|
onResizeStart && onResizeStart(newLeftbarState);
|
|
88
142
|
};
|
|
89
|
-
const
|
|
143
|
+
const onResizeOffLeftOfScreen = () => {
|
|
90
144
|
var _unbindEvents$current;
|
|
91
|
-
|
|
145
|
+
onUpdateResize.cancel();
|
|
92
146
|
(_unbindEvents$current = unbindEvents.current) === null || _unbindEvents$current === void 0 ? void 0 : _unbindEvents$current.call(unbindEvents);
|
|
93
147
|
unbindEvents.current = null;
|
|
94
148
|
document.documentElement.removeAttribute(IS_SIDEBAR_DRAGGING);
|
|
95
149
|
offset.current = 0;
|
|
96
150
|
collapseLeftSidebar(undefined, true);
|
|
97
151
|
};
|
|
98
|
-
const
|
|
152
|
+
const onUpdateResize = rafSchd(event => {
|
|
99
153
|
// Allow the sidebar to be 50% of the available page width
|
|
100
154
|
const maxWidth = Math.round(window.innerWidth / 2);
|
|
101
155
|
const leftPanelWidth = getLeftPanelWidth();
|
|
102
156
|
const {
|
|
103
157
|
leftSidebarWidth
|
|
104
158
|
} = leftSidebarState;
|
|
105
|
-
const
|
|
106
|
-
if (
|
|
107
|
-
|
|
159
|
+
const hasResizedOffLeftOfScreen = event.clientX < 0;
|
|
160
|
+
if (hasResizedOffLeftOfScreen) {
|
|
161
|
+
onResizeOffLeftOfScreen();
|
|
162
|
+
return;
|
|
108
163
|
}
|
|
109
164
|
const delta = Math.max(Math.min(event.clientX - leftSidebarWidth - leftPanelWidth, maxWidth - leftSidebarWidth - leftPanelWidth), COLLAPSED_LEFT_SIDEBAR_WIDTH - leftSidebarWidth - leftPanelWidth);
|
|
110
|
-
|
|
111
|
-
document.documentElement.style.setProperty(`--${VAR_LEFT_SIDEBAR_WIDTH}`, `${
|
|
165
|
+
sidebarWidth.current = Math.max(leftSidebarWidth + delta - offset.current, COLLAPSED_LEFT_SIDEBAR_WIDTH);
|
|
166
|
+
document.documentElement.style.setProperty(`--${VAR_LEFT_SIDEBAR_WIDTH}`, `${sidebarWidth.current}px`);
|
|
112
167
|
});
|
|
113
168
|
const cleanupAfterResize = () => {
|
|
114
169
|
var _unbindEvents$current2;
|
|
115
|
-
|
|
170
|
+
sidebarWidth.current = 0;
|
|
116
171
|
offset.current = 0;
|
|
117
172
|
(_unbindEvents$current2 = unbindEvents.current) === null || _unbindEvents$current2 === void 0 ? void 0 : _unbindEvents$current2.call(unbindEvents);
|
|
118
173
|
unbindEvents.current = null;
|
|
119
174
|
};
|
|
120
175
|
let updatedLeftSidebarState = {};
|
|
121
|
-
const
|
|
176
|
+
const onFinishResizing = () => {
|
|
122
177
|
if (isLeftSidebarCollapsed) {
|
|
123
178
|
return;
|
|
124
179
|
}
|
|
@@ -126,14 +181,14 @@ const ResizeControl = ({
|
|
|
126
181
|
|
|
127
182
|
// If it is dragged to below the threshold,
|
|
128
183
|
// collapse the navigation
|
|
129
|
-
if (
|
|
184
|
+
if (sidebarWidth.current < MIN_LEFT_SIDEBAR_DRAG_THRESHOLD) {
|
|
130
185
|
document.documentElement.style.setProperty(`--${VAR_LEFT_SIDEBAR_WIDTH}`, `${COLLAPSED_LEFT_SIDEBAR_WIDTH}px`);
|
|
131
186
|
collapseLeftSidebar(undefined, true);
|
|
132
187
|
}
|
|
133
188
|
// If it is dragged to position in between the
|
|
134
189
|
// min threshold and default width
|
|
135
190
|
// expand the nav to the default width
|
|
136
|
-
else if (
|
|
191
|
+
else if (sidebarWidth.current > MIN_LEFT_SIDEBAR_DRAG_THRESHOLD && sidebarWidth.current < DEFAULT_LEFT_SIDEBAR_WIDTH) {
|
|
137
192
|
document.documentElement.style.setProperty(`--${VAR_LEFT_SIDEBAR_WIDTH}`, `${DEFAULT_LEFT_SIDEBAR_WIDTH}px`);
|
|
138
193
|
updatedLeftSidebarState = {
|
|
139
194
|
...leftSidebarState,
|
|
@@ -147,13 +202,13 @@ const ResizeControl = ({
|
|
|
147
202
|
updatedLeftSidebarState = {
|
|
148
203
|
...leftSidebarState,
|
|
149
204
|
isResizing: false,
|
|
150
|
-
[VAR_LEFT_SIDEBAR_WIDTH]:
|
|
151
|
-
lastLeftSidebarWidth:
|
|
205
|
+
[VAR_LEFT_SIDEBAR_WIDTH]: sidebarWidth.current,
|
|
206
|
+
lastLeftSidebarWidth: sidebarWidth.current
|
|
152
207
|
};
|
|
153
208
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
154
209
|
}
|
|
155
210
|
requestAnimationFrame(() => {
|
|
156
|
-
|
|
211
|
+
onUpdateResize.cancel();
|
|
157
212
|
setIsGrabAreaFocused(false);
|
|
158
213
|
onResizeEnd && onResizeEnd(updatedLeftSidebarState);
|
|
159
214
|
cleanupAfterResize();
|
|
@@ -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,36 +28,37 @@ export const SidebarResizeController = ({
|
|
|
27
28
|
const {
|
|
28
29
|
isLeftSidebarCollapsed
|
|
29
30
|
} = leftSidebarState;
|
|
30
|
-
const leftSidebarSelector = getPageLayoutSlotCSSSelector('left-sidebar');
|
|
31
|
-
const transitionEventHandler = useCallback(event => {
|
|
32
|
-
if (event.propertyName === 'width' && event.target && event.target.matches(leftSidebarSelector)) {
|
|
33
|
-
const $leftSidebarResizeController = document.querySelector(`[${GRAB_AREA_SELECTOR}]`);
|
|
34
|
-
const isCollapsed = !!$leftSidebarResizeController && $leftSidebarResizeController.hasAttribute('disabled');
|
|
35
|
-
handleDataAttributesAndCb(isCollapsed ? onCollapse : onExpand, isCollapsed, leftSidebarState);
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
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
|
+
});
|
|
43
38
|
useEffect(() => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
stableRef.current = {
|
|
40
|
+
onExpand,
|
|
41
|
+
onCollapse
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
const transition = useRef(null);
|
|
50
45
|
const expandLeftSidebar = useCallback(() => {
|
|
46
|
+
var _transition$current, _transition$current2;
|
|
51
47
|
const {
|
|
52
48
|
lastLeftSidebarWidth,
|
|
53
49
|
isResizing,
|
|
54
50
|
flyoutLockCount,
|
|
55
|
-
isFixed
|
|
51
|
+
isFixed,
|
|
52
|
+
isLeftSidebarCollapsed
|
|
56
53
|
} = leftSidebarState;
|
|
57
|
-
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') {
|
|
58
57
|
return;
|
|
59
58
|
}
|
|
59
|
+
|
|
60
|
+
// flush existing transition
|
|
61
|
+
(_transition$current2 = transition.current) === null || _transition$current2 === void 0 ? void 0 : _transition$current2.complete();
|
|
60
62
|
const width = Math.max(lastLeftSidebarWidth, DEFAULT_LEFT_SIDEBAR_WIDTH);
|
|
61
63
|
const updatedLeftSidebarState = {
|
|
62
64
|
isLeftSidebarCollapsed: false,
|
|
@@ -68,13 +70,41 @@ export const SidebarResizeController = ({
|
|
|
68
70
|
isFixed
|
|
69
71
|
};
|
|
70
72
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
71
|
-
|
|
73
|
+
function finish() {
|
|
74
|
+
handleDataAttributesAndCb(stableRef.current.onExpand, false,
|
|
75
|
+
// isCollapsed
|
|
76
|
+
updatedLeftSidebarState);
|
|
77
|
+
}
|
|
78
|
+
const sidebar = document.querySelector(leftSidebarSelector);
|
|
72
79
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
73
|
-
if (isReducedMotion()) {
|
|
74
|
-
|
|
80
|
+
if (isReducedMotion() || !sidebar) {
|
|
81
|
+
finish();
|
|
82
|
+
return;
|
|
75
83
|
}
|
|
76
|
-
|
|
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]);
|
|
77
106
|
const collapseLeftSidebar = useCallback((event, collapseWithoutTransition) => {
|
|
107
|
+
var _transition$current4, _transition$current5;
|
|
78
108
|
const {
|
|
79
109
|
leftSidebarWidth,
|
|
80
110
|
isResizing,
|
|
@@ -82,10 +112,15 @@ export const SidebarResizeController = ({
|
|
|
82
112
|
isFixed,
|
|
83
113
|
isLeftSidebarCollapsed
|
|
84
114
|
} = leftSidebarState;
|
|
85
|
-
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') {
|
|
86
118
|
return;
|
|
87
119
|
}
|
|
88
120
|
|
|
121
|
+
// flush existing transition
|
|
122
|
+
(_transition$current5 = transition.current) === null || _transition$current5 === void 0 ? void 0 : _transition$current5.complete();
|
|
123
|
+
|
|
89
124
|
// data-attribute is used as a CSS selector to sync the hiding/showing
|
|
90
125
|
// of the nav contents with expand/collapse animation
|
|
91
126
|
document.documentElement.setAttribute(IS_SIDEBAR_COLLAPSING, 'true');
|
|
@@ -99,12 +134,46 @@ export const SidebarResizeController = ({
|
|
|
99
134
|
isFixed
|
|
100
135
|
};
|
|
101
136
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
137
|
+
function finish() {
|
|
138
|
+
handleDataAttributesAndCb(stableRef.current.onCollapse, true, updatedLeftSidebarState);
|
|
139
|
+
}
|
|
140
|
+
const sidebar = document.querySelector(leftSidebarSelector);
|
|
102
141
|
|
|
103
142
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
104
|
-
if (collapseWithoutTransition || isReducedMotion()) {
|
|
105
|
-
|
|
143
|
+
if (collapseWithoutTransition || isReducedMotion() || !sidebar) {
|
|
144
|
+
finish();
|
|
145
|
+
return;
|
|
106
146
|
}
|
|
107
|
-
|
|
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
|
+
}, []);
|
|
108
177
|
const context = useMemo(() => ({
|
|
109
178
|
isLeftSidebarCollapsed,
|
|
110
179
|
expandLeftSidebar,
|
package/dist/es2019/version.json
CHANGED
|
@@ -43,7 +43,7 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
43
43
|
setLeftSidebarState = _useContext.setLeftSidebarState;
|
|
44
44
|
var isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed,
|
|
45
45
|
isResizing = leftSidebarState.isResizing;
|
|
46
|
-
var
|
|
46
|
+
var sidebarWidth = useRef(leftSidebarState[VAR_LEFT_SIDEBAR_WIDTH]);
|
|
47
47
|
// Distance of mouse from left sidebar onMouseDown
|
|
48
48
|
var offset = useRef(0);
|
|
49
49
|
var keyboardEventTimeout = useRef();
|
|
@@ -73,13 +73,67 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
73
73
|
if (isLeftSidebarCollapsed) {
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
+
|
|
77
|
+
// TODO: should only a primary pointer be able to start a resize?
|
|
78
|
+
// Keeping as is for now, but worth considering
|
|
79
|
+
|
|
80
|
+
// It is possible for a mousedown to fire during a resize
|
|
81
|
+
// Example: the user presses another pointer button while dragging
|
|
82
|
+
if (leftSidebarState.isResizing) {
|
|
83
|
+
// the resize will be cancelled by our global event listeners
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
76
86
|
offset.current = event.clientX - leftSidebarState[VAR_LEFT_SIDEBAR_WIDTH] - getLeftPanelWidth();
|
|
77
|
-
unbindEvents.current = bindAll(
|
|
87
|
+
unbindEvents.current = bindAll(window, [{
|
|
78
88
|
type: 'mousemove',
|
|
79
|
-
listener:
|
|
89
|
+
listener: onUpdateResize
|
|
80
90
|
}, {
|
|
81
91
|
type: 'mouseup',
|
|
82
|
-
listener:
|
|
92
|
+
listener: onFinishResizing
|
|
93
|
+
}, {
|
|
94
|
+
type: 'mousedown',
|
|
95
|
+
// this mousedown event listener is being added in the bubble phase
|
|
96
|
+
// on a higher event target than the resize handle.
|
|
97
|
+
// This means that the original mousedown event that triggers a resize
|
|
98
|
+
// can hit this mousedown handler. To get around that, we only call
|
|
99
|
+
// `onFinishResizing` after an animation frame so we don't pick up the original event
|
|
100
|
+
// Alternatives:
|
|
101
|
+
// 1. Add the window 'mousedown' event listener in the capture phase
|
|
102
|
+
// 👎 A 'mousedown' during a resize would trigger a new resize to start
|
|
103
|
+
// 2. Do 1. and call `event.preventDefault()`, then check for `event.defaultPrevented` inside
|
|
104
|
+
// the grab handle `onMouseDown`
|
|
105
|
+
// 👎 Not ideal to cancel events if we don't have to
|
|
106
|
+
listener: function () {
|
|
107
|
+
var hasFramePassed = false;
|
|
108
|
+
requestAnimationFrame(function () {
|
|
109
|
+
hasFramePassed = true;
|
|
110
|
+
});
|
|
111
|
+
return function listener() {
|
|
112
|
+
if (hasFramePassed) {
|
|
113
|
+
onFinishResizing();
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}()
|
|
117
|
+
}, {
|
|
118
|
+
type: 'visibilitychange',
|
|
119
|
+
listener: onFinishResizing
|
|
120
|
+
},
|
|
121
|
+
// A 'click' event should never be hit as the 'mouseup' will come first and cause
|
|
122
|
+
// these event listeners to be unbound. I just added 'click' for extreme safety (paranoia)
|
|
123
|
+
{
|
|
124
|
+
type: 'click',
|
|
125
|
+
listener: onFinishResizing
|
|
126
|
+
}, {
|
|
127
|
+
type: 'keydown',
|
|
128
|
+
listener: function listener(event) {
|
|
129
|
+
// Can cancel resizing by pressing "Escape"
|
|
130
|
+
// Will return sidebar to the same size it was before the resizing started
|
|
131
|
+
if (event.key === 'Escape') {
|
|
132
|
+
sidebarWidth.current = Math.max(leftSidebarState.lastLeftSidebarWidth, COLLAPSED_LEFT_SIDEBAR_WIDTH);
|
|
133
|
+
document.documentElement.style.setProperty("--".concat(VAR_LEFT_SIDEBAR_WIDTH), "".concat(sidebarWidth.current, "px"));
|
|
134
|
+
onFinishResizing();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
83
137
|
}]);
|
|
84
138
|
document.documentElement.setAttribute(IS_SIDEBAR_DRAGGING, 'true');
|
|
85
139
|
var newLeftbarState = _objectSpread(_objectSpread({}, leftSidebarState), {}, {
|
|
@@ -88,37 +142,38 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
88
142
|
setLeftSidebarState(newLeftbarState);
|
|
89
143
|
onResizeStart && onResizeStart(newLeftbarState);
|
|
90
144
|
};
|
|
91
|
-
var
|
|
145
|
+
var onResizeOffLeftOfScreen = function onResizeOffLeftOfScreen() {
|
|
92
146
|
var _unbindEvents$current;
|
|
93
|
-
|
|
147
|
+
onUpdateResize.cancel();
|
|
94
148
|
(_unbindEvents$current = unbindEvents.current) === null || _unbindEvents$current === void 0 ? void 0 : _unbindEvents$current.call(unbindEvents);
|
|
95
149
|
unbindEvents.current = null;
|
|
96
150
|
document.documentElement.removeAttribute(IS_SIDEBAR_DRAGGING);
|
|
97
151
|
offset.current = 0;
|
|
98
152
|
collapseLeftSidebar(undefined, true);
|
|
99
153
|
};
|
|
100
|
-
var
|
|
154
|
+
var onUpdateResize = rafSchd(function (event) {
|
|
101
155
|
// Allow the sidebar to be 50% of the available page width
|
|
102
156
|
var maxWidth = Math.round(window.innerWidth / 2);
|
|
103
157
|
var leftPanelWidth = getLeftPanelWidth();
|
|
104
158
|
var leftSidebarWidth = leftSidebarState.leftSidebarWidth;
|
|
105
|
-
var
|
|
106
|
-
if (
|
|
107
|
-
|
|
159
|
+
var hasResizedOffLeftOfScreen = event.clientX < 0;
|
|
160
|
+
if (hasResizedOffLeftOfScreen) {
|
|
161
|
+
onResizeOffLeftOfScreen();
|
|
162
|
+
return;
|
|
108
163
|
}
|
|
109
164
|
var delta = Math.max(Math.min(event.clientX - leftSidebarWidth - leftPanelWidth, maxWidth - leftSidebarWidth - leftPanelWidth), COLLAPSED_LEFT_SIDEBAR_WIDTH - leftSidebarWidth - leftPanelWidth);
|
|
110
|
-
|
|
111
|
-
document.documentElement.style.setProperty("--".concat(VAR_LEFT_SIDEBAR_WIDTH), "".concat(
|
|
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"));
|
|
112
167
|
});
|
|
113
168
|
var cleanupAfterResize = function cleanupAfterResize() {
|
|
114
169
|
var _unbindEvents$current2;
|
|
115
|
-
|
|
170
|
+
sidebarWidth.current = 0;
|
|
116
171
|
offset.current = 0;
|
|
117
172
|
(_unbindEvents$current2 = unbindEvents.current) === null || _unbindEvents$current2 === void 0 ? void 0 : _unbindEvents$current2.call(unbindEvents);
|
|
118
173
|
unbindEvents.current = null;
|
|
119
174
|
};
|
|
120
175
|
var updatedLeftSidebarState = {};
|
|
121
|
-
var
|
|
176
|
+
var onFinishResizing = function onFinishResizing() {
|
|
122
177
|
if (isLeftSidebarCollapsed) {
|
|
123
178
|
return;
|
|
124
179
|
}
|
|
@@ -126,14 +181,14 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
126
181
|
|
|
127
182
|
// If it is dragged to below the threshold,
|
|
128
183
|
// collapse the navigation
|
|
129
|
-
if (
|
|
184
|
+
if (sidebarWidth.current < MIN_LEFT_SIDEBAR_DRAG_THRESHOLD) {
|
|
130
185
|
document.documentElement.style.setProperty("--".concat(VAR_LEFT_SIDEBAR_WIDTH), "".concat(COLLAPSED_LEFT_SIDEBAR_WIDTH, "px"));
|
|
131
186
|
collapseLeftSidebar(undefined, true);
|
|
132
187
|
}
|
|
133
188
|
// If it is dragged to position in between the
|
|
134
189
|
// min threshold and default width
|
|
135
190
|
// expand the nav to the default width
|
|
136
|
-
else if (
|
|
191
|
+
else if (sidebarWidth.current > MIN_LEFT_SIDEBAR_DRAG_THRESHOLD && sidebarWidth.current < DEFAULT_LEFT_SIDEBAR_WIDTH) {
|
|
137
192
|
var _objectSpread2;
|
|
138
193
|
document.documentElement.style.setProperty("--".concat(VAR_LEFT_SIDEBAR_WIDTH), "".concat(DEFAULT_LEFT_SIDEBAR_WIDTH, "px"));
|
|
139
194
|
updatedLeftSidebarState = _objectSpread(_objectSpread({}, leftSidebarState), {}, (_objectSpread2 = {
|
|
@@ -145,11 +200,11 @@ var ResizeControl = function ResizeControl(_ref) {
|
|
|
145
200
|
// otherwise resize it to the desired width
|
|
146
201
|
updatedLeftSidebarState = _objectSpread(_objectSpread({}, leftSidebarState), {}, (_objectSpread3 = {
|
|
147
202
|
isResizing: false
|
|
148
|
-
}, _defineProperty(_objectSpread3, VAR_LEFT_SIDEBAR_WIDTH,
|
|
203
|
+
}, _defineProperty(_objectSpread3, VAR_LEFT_SIDEBAR_WIDTH, sidebarWidth.current), _defineProperty(_objectSpread3, "lastLeftSidebarWidth", sidebarWidth.current), _objectSpread3));
|
|
149
204
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
150
205
|
}
|
|
151
206
|
requestAnimationFrame(function () {
|
|
152
|
-
|
|
207
|
+
onUpdateResize.cancel();
|
|
153
208
|
setIsGrabAreaFocused(false);
|
|
154
209
|
onResizeEnd && onResizeEnd(updatedLeftSidebarState);
|
|
155
210
|
cleanupAfterResize();
|
|
@@ -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,34 +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
|
-
var transitionEventHandler = useCallback(function (event) {
|
|
36
|
-
if (event.propertyName === 'width' && event.target && event.target.matches(leftSidebarSelector)) {
|
|
37
|
-
var $leftSidebarResizeController = document.querySelector("[".concat(GRAB_AREA_SELECTOR, "]"));
|
|
38
|
-
var isCollapsed = !!$leftSidebarResizeController && $leftSidebarResizeController.hasAttribute('disabled');
|
|
39
|
-
handleDataAttributesAndCb(isCollapsed ? onCollapse : onExpand, isCollapsed, leftSidebarState);
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
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
|
+
});
|
|
47
42
|
useEffect(function () {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
stableRef.current = {
|
|
44
|
+
onExpand: onExpand,
|
|
45
|
+
onCollapse: onCollapse
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
var transition = useRef(null);
|
|
54
49
|
var expandLeftSidebar = useCallback(function () {
|
|
50
|
+
var _transition$current, _transition$current2;
|
|
55
51
|
var lastLeftSidebarWidth = leftSidebarState.lastLeftSidebarWidth,
|
|
56
52
|
isResizing = leftSidebarState.isResizing,
|
|
57
53
|
flyoutLockCount = leftSidebarState.flyoutLockCount,
|
|
58
|
-
isFixed = leftSidebarState.isFixed
|
|
59
|
-
|
|
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') {
|
|
60
59
|
return;
|
|
61
60
|
}
|
|
61
|
+
|
|
62
|
+
// flush existing transition
|
|
63
|
+
(_transition$current2 = transition.current) === null || _transition$current2 === void 0 ? void 0 : _transition$current2.complete();
|
|
62
64
|
var width = Math.max(lastLeftSidebarWidth, DEFAULT_LEFT_SIDEBAR_WIDTH);
|
|
63
65
|
var updatedLeftSidebarState = {
|
|
64
66
|
isLeftSidebarCollapsed: false,
|
|
@@ -70,22 +72,55 @@ export var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
70
72
|
isFixed: isFixed
|
|
71
73
|
};
|
|
72
74
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
73
|
-
|
|
75
|
+
function finish() {
|
|
76
|
+
handleDataAttributesAndCb(stableRef.current.onExpand, false,
|
|
77
|
+
// isCollapsed
|
|
78
|
+
updatedLeftSidebarState);
|
|
79
|
+
}
|
|
80
|
+
var sidebar = document.querySelector(leftSidebarSelector);
|
|
74
81
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
75
|
-
if (isReducedMotion()) {
|
|
76
|
-
|
|
82
|
+
if (isReducedMotion() || !sidebar) {
|
|
83
|
+
finish();
|
|
84
|
+
return;
|
|
77
85
|
}
|
|
78
|
-
|
|
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]);
|
|
79
108
|
var collapseLeftSidebar = useCallback(function (event, collapseWithoutTransition) {
|
|
109
|
+
var _transition$current4, _transition$current5;
|
|
80
110
|
var leftSidebarWidth = leftSidebarState.leftSidebarWidth,
|
|
81
111
|
isResizing = leftSidebarState.isResizing,
|
|
82
112
|
flyoutLockCount = leftSidebarState.flyoutLockCount,
|
|
83
113
|
isFixed = leftSidebarState.isFixed,
|
|
84
114
|
isLeftSidebarCollapsed = leftSidebarState.isLeftSidebarCollapsed;
|
|
85
|
-
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') {
|
|
86
118
|
return;
|
|
87
119
|
}
|
|
88
120
|
|
|
121
|
+
// flush existing transition
|
|
122
|
+
(_transition$current5 = transition.current) === null || _transition$current5 === void 0 ? void 0 : _transition$current5.complete();
|
|
123
|
+
|
|
89
124
|
// data-attribute is used as a CSS selector to sync the hiding/showing
|
|
90
125
|
// of the nav contents with expand/collapse animation
|
|
91
126
|
document.documentElement.setAttribute(IS_SIDEBAR_COLLAPSING, 'true');
|
|
@@ -99,12 +134,46 @@ export var SidebarResizeController = function SidebarResizeController(_ref) {
|
|
|
99
134
|
isFixed: isFixed
|
|
100
135
|
};
|
|
101
136
|
setLeftSidebarState(updatedLeftSidebarState);
|
|
137
|
+
function finish() {
|
|
138
|
+
handleDataAttributesAndCb(stableRef.current.onCollapse, true, updatedLeftSidebarState);
|
|
139
|
+
}
|
|
140
|
+
var sidebar = document.querySelector(leftSidebarSelector);
|
|
102
141
|
|
|
103
142
|
// onTransitionEnd isn't triggered when a user prefers reduced motion
|
|
104
|
-
if (collapseWithoutTransition || isReducedMotion()) {
|
|
105
|
-
|
|
143
|
+
if (collapseWithoutTransition || isReducedMotion() || !sidebar) {
|
|
144
|
+
finish();
|
|
145
|
+
return;
|
|
106
146
|
}
|
|
107
|
-
|
|
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
|
+
}, []);
|
|
108
177
|
var context = useMemo(function () {
|
|
109
178
|
return {
|
|
110
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.5.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/"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@atlaskit/ds-lib": "^2.1.0",
|
|
29
29
|
"@atlaskit/icon": "^21.11.0",
|
|
30
30
|
"@atlaskit/motion": "^1.3.0",
|
|
31
|
-
"@atlaskit/theme": "^12.
|
|
31
|
+
"@atlaskit/theme": "^12.4.0",
|
|
32
32
|
"@atlaskit/tokens": "^1.2.0",
|
|
33
33
|
"@babel/runtime": "^7.0.0",
|
|
34
34
|
"@emotion/react": "^11.7.1",
|
|
@@ -40,17 +40,17 @@
|
|
|
40
40
|
"react-dom": "^16.8.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@atlaskit/atlassian-navigation": "^2.
|
|
43
|
+
"@atlaskit/atlassian-navigation": "^2.4.0",
|
|
44
44
|
"@atlaskit/atlassian-notifications": "^0.3.0",
|
|
45
|
-
"@atlaskit/button": "^16.
|
|
45
|
+
"@atlaskit/button": "^16.6.0",
|
|
46
46
|
"@atlaskit/docs": "*",
|
|
47
47
|
"@atlaskit/drawer": "^7.4.0",
|
|
48
48
|
"@atlaskit/icon": "*",
|
|
49
|
-
"@atlaskit/logo": "^13.
|
|
49
|
+
"@atlaskit/logo": "^13.13.0",
|
|
50
50
|
"@atlaskit/menu": "^1.5.0",
|
|
51
51
|
"@atlaskit/notification-indicator": "^9.0.0",
|
|
52
52
|
"@atlaskit/notification-log-client": "^6.0.0",
|
|
53
|
-
"@atlaskit/onboarding": "^10.
|
|
53
|
+
"@atlaskit/onboarding": "^10.7.0",
|
|
54
54
|
"@atlaskit/popup": "^1.5.0",
|
|
55
55
|
"@atlaskit/section-message": "^6.3.0",
|
|
56
56
|
"@atlaskit/side-navigation": "^1.6.0",
|