@atlaskit/react-select 2.3.0 → 2.4.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 +14 -0
- package/dist/cjs/components/menu.js +5 -225
- package/dist/cjs/emotion/components/internal/index.js +34 -0
- package/dist/cjs/emotion/components/internal/scroll-manager.js +59 -0
- package/dist/cjs/emotion/components/internal/use-scroll-capture.js +132 -0
- package/dist/cjs/emotion/components/internal/use-scroll-lock.js +149 -0
- package/dist/es2019/components/menu.js +4 -224
- package/dist/es2019/emotion/components/internal/index.js +4 -0
- package/dist/es2019/emotion/components/internal/scroll-manager.js +51 -0
- package/dist/es2019/emotion/components/internal/use-scroll-capture.js +128 -0
- package/dist/es2019/emotion/components/internal/use-scroll-lock.js +143 -0
- package/dist/esm/components/menu.js +6 -228
- package/dist/esm/emotion/components/internal/index.js +4 -0
- package/dist/esm/emotion/components/internal/scroll-manager.js +51 -0
- package/dist/esm/emotion/components/internal/use-scroll-capture.js +126 -0
- package/dist/esm/emotion/components/internal/use-scroll-lock.js +143 -0
- package/dist/types/components/menu.d.ts +1 -1
- package/dist/types/emotion/components/internal/index.d.ts +4 -0
- package/dist/types/emotion/components/internal/scroll-manager.d.ts +17 -0
- package/dist/types/emotion/components/internal/use-scroll-capture.d.ts +12 -0
- package/dist/types/emotion/components/internal/use-scroll-lock.d.ts +9 -0
- package/dist/types-ts4.5/components/menu.d.ts +1 -1
- package/dist/types-ts4.5/emotion/components/internal/index.d.ts +4 -0
- package/dist/types-ts4.5/emotion/components/internal/scroll-manager.d.ts +17 -0
- package/dist/types-ts4.5/emotion/components/internal/use-scroll-capture.d.ts +12 -0
- package/dist/types-ts4.5/emotion/components/internal/use-scroll-lock.d.ts +9 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/react-select
|
|
2
2
|
|
|
3
|
+
## 2.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#141922](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/141922)
|
|
8
|
+
[`a48b38cffa7e6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a48b38cffa7e6) -
|
|
9
|
+
Create a compiled select and use feature flag to toggle it
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#141922](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/141922)
|
|
14
|
+
[`a48b38cffa7e6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a48b38cffa7e6) -
|
|
15
|
+
Migrate emotion components to compiled components under compiled folder
|
|
16
|
+
|
|
3
17
|
## 2.3.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
|
@@ -7,245 +7,25 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
});
|
|
8
8
|
exports.noOptionsMessageCSS = exports.menuPortalCSS = exports.menuListCSS = exports.menuCSS = exports.loadingMessageCSS = exports.default = exports.NoOptionsMessage = exports.MenuPortal = exports.MenuPlacer = exports.MenuList = exports.LoadingMessage = void 0;
|
|
9
9
|
var _objectDestructuringEmpty2 = _interopRequireDefault(require("@babel/runtime/helpers/objectDestructuringEmpty"));
|
|
10
|
-
var
|
|
11
|
-
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
12
|
-
var _react = _interopRequireWildcard(require("react"));
|
|
13
|
-
var _useIsomorphicLayoutEffect = _interopRequireDefault(require("use-isomorphic-layout-effect"));
|
|
10
|
+
var _react = _interopRequireDefault(require("react"));
|
|
14
11
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
15
12
|
var _menu = _interopRequireWildcard(require("../compiled/components/menu"));
|
|
16
13
|
var _menu2 = _interopRequireWildcard(require("../emotion/components/menu"));
|
|
17
|
-
var _utils = require("../utils");
|
|
18
14
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
19
15
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
20
|
-
|
|
21
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /* eslint-disable @repo/internal/react/no-unsafe-spread-props */
|
|
22
|
-
// ==============================
|
|
23
|
-
// Menu
|
|
24
|
-
// ==============================
|
|
25
|
-
|
|
26
|
-
// Get Menu Placement
|
|
27
|
-
// ------------------------------
|
|
28
|
-
|
|
29
|
-
function getMenuPlacement(_ref) {
|
|
30
|
-
var preferredMaxHeight = _ref.maxHeight,
|
|
31
|
-
menuEl = _ref.menuEl,
|
|
32
|
-
minHeight = _ref.minHeight,
|
|
33
|
-
preferredPlacement = _ref.placement,
|
|
34
|
-
shouldScroll = _ref.shouldScroll,
|
|
35
|
-
isFixedPosition = _ref.isFixedPosition,
|
|
36
|
-
controlHeight = _ref.controlHeight;
|
|
37
|
-
var scrollParent = (0, _utils.getScrollParent)(menuEl);
|
|
38
|
-
var defaultState = {
|
|
39
|
-
placement: 'bottom',
|
|
40
|
-
maxHeight: preferredMaxHeight
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// something went wrong, return default state
|
|
44
|
-
if (!menuEl || !menuEl.offsetParent) {
|
|
45
|
-
return defaultState;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// we can't trust `scrollParent.scrollHeight` --> it may increase when
|
|
49
|
-
// the menu is rendered
|
|
50
|
-
var _scrollParent$getBoun = scrollParent.getBoundingClientRect(),
|
|
51
|
-
scrollHeight = _scrollParent$getBoun.height,
|
|
52
|
-
scrollParentTop = _scrollParent$getBoun.top;
|
|
53
|
-
var _menuEl$getBoundingCl = menuEl.getBoundingClientRect(),
|
|
54
|
-
menuBottom = _menuEl$getBoundingCl.bottom,
|
|
55
|
-
menuHeight = _menuEl$getBoundingCl.height,
|
|
56
|
-
menuTop = _menuEl$getBoundingCl.top;
|
|
57
|
-
var _menuEl$offsetParent$ = menuEl.offsetParent.getBoundingClientRect(),
|
|
58
|
-
containerTop = _menuEl$offsetParent$.top;
|
|
59
|
-
var viewHeight = isFixedPosition ? window.innerHeight : (0, _utils.normalizedHeight)(scrollParent);
|
|
60
|
-
var scrollTop = (0, _utils.getScrollTop)(scrollParent);
|
|
61
|
-
// use menuTop - scrollParentTop for the actual top space of menu in the scroll container
|
|
62
|
-
var menuTopFromParent = (0, _platformFeatureFlags.fg)('design-system-select-fix-placement') ? menuTop - scrollParentTop : menuTop;
|
|
63
|
-
var marginBottom = parseInt(getComputedStyle(menuEl).marginBottom, 10);
|
|
64
|
-
var marginTop = parseInt(getComputedStyle(menuEl).marginTop, 10);
|
|
65
|
-
var viewSpaceAbove = containerTop - marginTop;
|
|
66
|
-
var viewSpaceBelow = viewHeight - menuTopFromParent;
|
|
67
|
-
var scrollSpaceAbove = viewSpaceAbove + scrollTop;
|
|
68
|
-
var scrollSpaceBelow = scrollHeight - scrollTop - menuTopFromParent;
|
|
69
|
-
var scrollDown = menuBottom - viewHeight + scrollTop + marginBottom;
|
|
70
|
-
var scrollUp = scrollTop + menuTop - marginTop;
|
|
71
|
-
var scrollDuration = 160;
|
|
72
|
-
switch (preferredPlacement) {
|
|
73
|
-
case 'auto':
|
|
74
|
-
case 'bottom':
|
|
75
|
-
// 1: the menu will fit, do nothing
|
|
76
|
-
if (viewSpaceBelow >= menuHeight) {
|
|
77
|
-
return {
|
|
78
|
-
placement: 'bottom',
|
|
79
|
-
maxHeight: preferredMaxHeight
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// 2: the menu will fit, if scrolled
|
|
84
|
-
if (scrollSpaceBelow >= menuHeight && !isFixedPosition) {
|
|
85
|
-
if (shouldScroll) {
|
|
86
|
-
(0, _utils.animatedScrollTo)(scrollParent, scrollDown, scrollDuration);
|
|
87
|
-
}
|
|
88
|
-
return {
|
|
89
|
-
placement: 'bottom',
|
|
90
|
-
maxHeight: preferredMaxHeight
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// 3: the menu will fit, if constrained
|
|
95
|
-
if (!isFixedPosition && scrollSpaceBelow >= minHeight || isFixedPosition && viewSpaceBelow >= minHeight) {
|
|
96
|
-
if (shouldScroll) {
|
|
97
|
-
(0, _utils.animatedScrollTo)(scrollParent, scrollDown, scrollDuration);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// we want to provide as much of the menu as possible to the user,
|
|
101
|
-
// so give them whatever is available below rather than the minHeight.
|
|
102
|
-
var constrainedHeight = isFixedPosition ? viewSpaceBelow - marginBottom : scrollSpaceBelow - marginBottom;
|
|
103
|
-
return {
|
|
104
|
-
placement: 'bottom',
|
|
105
|
-
maxHeight: constrainedHeight
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// 4. Forked beviour when there isn't enough space below
|
|
110
|
-
|
|
111
|
-
// AUTO: flip the menu, render above
|
|
112
|
-
if (preferredPlacement === 'auto' || isFixedPosition) {
|
|
113
|
-
// may need to be constrained after flipping
|
|
114
|
-
var _constrainedHeight = preferredMaxHeight;
|
|
115
|
-
var spaceAbove = isFixedPosition ? viewSpaceAbove : scrollSpaceAbove;
|
|
116
|
-
if (spaceAbove >= minHeight) {
|
|
117
|
-
_constrainedHeight = Math.min(spaceAbove - marginBottom - controlHeight, preferredMaxHeight);
|
|
118
|
-
}
|
|
119
|
-
return {
|
|
120
|
-
placement: 'top',
|
|
121
|
-
maxHeight: _constrainedHeight
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// BOTTOM: allow browser to increase scrollable area and immediately set scroll
|
|
126
|
-
if (preferredPlacement === 'bottom') {
|
|
127
|
-
if (shouldScroll) {
|
|
128
|
-
(0, _utils.scrollTo)(scrollParent, scrollDown);
|
|
129
|
-
}
|
|
130
|
-
return {
|
|
131
|
-
placement: 'bottom',
|
|
132
|
-
maxHeight: preferredMaxHeight
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
break;
|
|
136
|
-
case 'top':
|
|
137
|
-
// 1: the menu will fit, do nothing
|
|
138
|
-
if (viewSpaceAbove >= menuHeight) {
|
|
139
|
-
return {
|
|
140
|
-
placement: 'top',
|
|
141
|
-
maxHeight: preferredMaxHeight
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// 2: the menu will fit, if scrolled
|
|
146
|
-
if (scrollSpaceAbove >= menuHeight && !isFixedPosition) {
|
|
147
|
-
if (shouldScroll) {
|
|
148
|
-
(0, _utils.animatedScrollTo)(scrollParent, scrollUp, scrollDuration);
|
|
149
|
-
}
|
|
150
|
-
return {
|
|
151
|
-
placement: 'top',
|
|
152
|
-
maxHeight: preferredMaxHeight
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// 3: the menu will fit, if constrained
|
|
157
|
-
if (!isFixedPosition && scrollSpaceAbove >= minHeight || isFixedPosition && viewSpaceAbove >= minHeight) {
|
|
158
|
-
var _constrainedHeight2 = preferredMaxHeight;
|
|
159
|
-
|
|
160
|
-
// we want to provide as much of the menu as possible to the user,
|
|
161
|
-
// so give them whatever is available below rather than the minHeight.
|
|
162
|
-
if (!isFixedPosition && scrollSpaceAbove >= minHeight || isFixedPosition && viewSpaceAbove >= minHeight) {
|
|
163
|
-
_constrainedHeight2 = isFixedPosition ? viewSpaceAbove - marginTop : scrollSpaceAbove - marginTop;
|
|
164
|
-
}
|
|
165
|
-
if (shouldScroll) {
|
|
166
|
-
(0, _utils.animatedScrollTo)(scrollParent, scrollUp, scrollDuration);
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
placement: 'top',
|
|
170
|
-
maxHeight: _constrainedHeight2
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// 4. not enough space, the browser WILL NOT increase scrollable area when
|
|
175
|
-
// absolutely positioned element rendered above the viewport (only below).
|
|
176
|
-
// Flip the menu, render below
|
|
177
|
-
return {
|
|
178
|
-
placement: 'bottom',
|
|
179
|
-
maxHeight: preferredMaxHeight
|
|
180
|
-
};
|
|
181
|
-
default:
|
|
182
|
-
throw new Error("Invalid placement provided \"".concat(preferredPlacement, "\"."));
|
|
183
|
-
}
|
|
184
|
-
return defaultState;
|
|
185
|
-
}
|
|
16
|
+
/* eslint-disable @repo/internal/react/no-unsafe-spread-props */
|
|
186
17
|
|
|
187
18
|
// Menu Component
|
|
188
19
|
// ------------------------------
|
|
189
20
|
|
|
190
|
-
var coercePlacement = function coercePlacement(p) {
|
|
191
|
-
return p === 'auto' ? 'bottom' : p;
|
|
192
|
-
};
|
|
193
21
|
var menuCSS = exports.menuCSS = function menuCSS(props) {
|
|
194
22
|
return (0, _platformFeatureFlags.fg)('compiled-react-select') ? (0, _menu.menuCSS)() : (0, _menu2.menuCSS)(props);
|
|
195
23
|
};
|
|
196
|
-
var PortalPlacementContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
197
24
|
|
|
198
25
|
// NOTE: internal only
|
|
199
26
|
// eslint-disable-next-line @repo/internal/react/require-jsdoc
|
|
200
27
|
var MenuPlacer = exports.MenuPlacer = function MenuPlacer(props) {
|
|
201
|
-
|
|
202
|
-
minMenuHeight = props.minMenuHeight,
|
|
203
|
-
maxMenuHeight = props.maxMenuHeight,
|
|
204
|
-
menuPlacement = props.menuPlacement,
|
|
205
|
-
menuPosition = props.menuPosition,
|
|
206
|
-
menuShouldScrollIntoView = props.menuShouldScrollIntoView;
|
|
207
|
-
var _ref2 = (0, _react.useContext)(PortalPlacementContext) || {},
|
|
208
|
-
setPortalPlacement = _ref2.setPortalPlacement;
|
|
209
|
-
var ref = (0, _react.useRef)(null);
|
|
210
|
-
var _useState = (0, _react.useState)(maxMenuHeight),
|
|
211
|
-
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
|
|
212
|
-
maxHeight = _useState2[0],
|
|
213
|
-
setMaxHeight = _useState2[1];
|
|
214
|
-
var _useState3 = (0, _react.useState)(null),
|
|
215
|
-
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
|
216
|
-
placement = _useState4[0],
|
|
217
|
-
setPlacement = _useState4[1];
|
|
218
|
-
// The minimum height of the control
|
|
219
|
-
var controlHeight = 38;
|
|
220
|
-
(0, _useIsomorphicLayoutEffect.default)(function () {
|
|
221
|
-
var menuEl = ref.current;
|
|
222
|
-
if (!menuEl) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// DO NOT scroll if position is fixed
|
|
227
|
-
var isFixedPosition = menuPosition === 'fixed';
|
|
228
|
-
var shouldScroll = menuShouldScrollIntoView && !isFixedPosition;
|
|
229
|
-
var state = getMenuPlacement({
|
|
230
|
-
maxHeight: maxMenuHeight,
|
|
231
|
-
menuEl: menuEl,
|
|
232
|
-
minHeight: minMenuHeight,
|
|
233
|
-
placement: menuPlacement,
|
|
234
|
-
shouldScroll: shouldScroll,
|
|
235
|
-
isFixedPosition: isFixedPosition,
|
|
236
|
-
controlHeight: controlHeight
|
|
237
|
-
});
|
|
238
|
-
setMaxHeight(state.maxHeight);
|
|
239
|
-
setPlacement(state.placement);
|
|
240
|
-
setPortalPlacement === null || setPortalPlacement === void 0 || setPortalPlacement(state.placement);
|
|
241
|
-
}, [maxMenuHeight, menuPlacement, menuPosition, menuShouldScrollIntoView, minMenuHeight, setPortalPlacement, controlHeight]);
|
|
242
|
-
return children({
|
|
243
|
-
ref: ref,
|
|
244
|
-
placerProps: _objectSpread(_objectSpread({}, props), {}, {
|
|
245
|
-
placement: placement || coercePlacement(menuPlacement),
|
|
246
|
-
maxHeight: maxHeight
|
|
247
|
-
})
|
|
248
|
-
});
|
|
28
|
+
return (0, _platformFeatureFlags.fg)('compiled-react-select') ? /*#__PURE__*/_react.default.createElement(_menu.MenuPlacer, props) : /*#__PURE__*/_react.default.createElement(_menu2.MenuPlacer, props);
|
|
249
29
|
};
|
|
250
30
|
var Menu = function Menu(props) {
|
|
251
31
|
return (0, _platformFeatureFlags.fg)('compiled-react-select') ? /*#__PURE__*/_react.default.createElement(_menu.default, props) : /*#__PURE__*/_react.default.createElement(_menu2.default, props);
|
|
@@ -268,8 +48,8 @@ var MenuList = exports.MenuList = function MenuList(props) {
|
|
|
268
48
|
// Menu Notices
|
|
269
49
|
// ==============================
|
|
270
50
|
|
|
271
|
-
var noticeCSS = function noticeCSS(
|
|
272
|
-
(0, _objectDestructuringEmpty2.default)(
|
|
51
|
+
var noticeCSS = function noticeCSS(_ref) {
|
|
52
|
+
(0, _objectDestructuringEmpty2.default)(_ref);
|
|
273
53
|
return {
|
|
274
54
|
textAlign: 'center',
|
|
275
55
|
padding: "var(--ds-space-100, 8px)".concat(" ", "var(--ds-space-150, 12px)")
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
Object.defineProperty(exports, "A11yText", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function get() {
|
|
10
|
+
return _a11yText.default;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(exports, "DummyInput", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function get() {
|
|
16
|
+
return _dummyInput.default;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "RequiredInput", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function get() {
|
|
22
|
+
return _requiredInput.default;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(exports, "ScrollManager", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function get() {
|
|
28
|
+
return _scrollManager.default;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
var _a11yText = _interopRequireDefault(require("./a11y-text"));
|
|
32
|
+
var _dummyInput = _interopRequireDefault(require("./dummy-input"));
|
|
33
|
+
var _scrollManager = _interopRequireDefault(require("./scroll-manager"));
|
|
34
|
+
var _requiredInput = _interopRequireDefault(require("./required-input"));
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = ScrollManager;
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
var _react2 = require("@emotion/react");
|
|
10
|
+
var _useScrollCapture = _interopRequireDefault(require("./use-scroll-capture"));
|
|
11
|
+
var _useScrollLock = _interopRequireDefault(require("./use-scroll-lock"));
|
|
12
|
+
/**
|
|
13
|
+
* @jsxRuntime classic
|
|
14
|
+
* @jsx jsx
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled
|
|
18
|
+
|
|
19
|
+
var styles = (0, _react2.css)({
|
|
20
|
+
position: 'fixed',
|
|
21
|
+
insetBlockEnd: 0,
|
|
22
|
+
insetBlockStart: 0,
|
|
23
|
+
insetInlineEnd: 0,
|
|
24
|
+
insetInlineStart: 0
|
|
25
|
+
});
|
|
26
|
+
var blurSelectInput = function blurSelectInput(event) {
|
|
27
|
+
var element = event.target;
|
|
28
|
+
return element.ownerDocument.activeElement && element.ownerDocument.activeElement.blur();
|
|
29
|
+
};
|
|
30
|
+
function ScrollManager(_ref) {
|
|
31
|
+
var children = _ref.children,
|
|
32
|
+
lockEnabled = _ref.lockEnabled,
|
|
33
|
+
_ref$captureEnabled = _ref.captureEnabled,
|
|
34
|
+
captureEnabled = _ref$captureEnabled === void 0 ? true : _ref$captureEnabled,
|
|
35
|
+
onBottomArrive = _ref.onBottomArrive,
|
|
36
|
+
onBottomLeave = _ref.onBottomLeave,
|
|
37
|
+
onTopArrive = _ref.onTopArrive,
|
|
38
|
+
onTopLeave = _ref.onTopLeave;
|
|
39
|
+
var setScrollCaptureTarget = (0, _useScrollCapture.default)({
|
|
40
|
+
isEnabled: captureEnabled,
|
|
41
|
+
onBottomArrive: onBottomArrive,
|
|
42
|
+
onBottomLeave: onBottomLeave,
|
|
43
|
+
onTopArrive: onTopArrive,
|
|
44
|
+
onTopLeave: onTopLeave
|
|
45
|
+
});
|
|
46
|
+
var setScrollLockTarget = (0, _useScrollLock.default)({
|
|
47
|
+
isEnabled: lockEnabled
|
|
48
|
+
});
|
|
49
|
+
var targetRef = function targetRef(element) {
|
|
50
|
+
setScrollCaptureTarget(element);
|
|
51
|
+
setScrollLockTarget(element);
|
|
52
|
+
};
|
|
53
|
+
return (0, _react2.jsx)(_react.Fragment, null, lockEnabled &&
|
|
54
|
+
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
|
|
55
|
+
(0, _react2.jsx)("div", {
|
|
56
|
+
onClick: blurSelectInput,
|
|
57
|
+
css: styles
|
|
58
|
+
}), children(targetRef));
|
|
59
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = useScrollCapture;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _utils = require("../../../utils");
|
|
9
|
+
var cancelScroll = function cancelScroll(event) {
|
|
10
|
+
if (event.cancelable) {
|
|
11
|
+
event.preventDefault();
|
|
12
|
+
}
|
|
13
|
+
event.stopPropagation();
|
|
14
|
+
};
|
|
15
|
+
// TODO: Fill in the hook {description}.
|
|
16
|
+
/**
|
|
17
|
+
* {description}.
|
|
18
|
+
*/
|
|
19
|
+
function useScrollCapture(_ref) {
|
|
20
|
+
var isEnabled = _ref.isEnabled,
|
|
21
|
+
onBottomArrive = _ref.onBottomArrive,
|
|
22
|
+
onBottomLeave = _ref.onBottomLeave,
|
|
23
|
+
onTopArrive = _ref.onTopArrive,
|
|
24
|
+
onTopLeave = _ref.onTopLeave;
|
|
25
|
+
var isBottom = (0, _react.useRef)(false);
|
|
26
|
+
var isTop = (0, _react.useRef)(false);
|
|
27
|
+
var touchStart = (0, _react.useRef)(0);
|
|
28
|
+
var scrollTarget = (0, _react.useRef)(null);
|
|
29
|
+
var handleEventDelta = (0, _react.useCallback)(function (event, delta) {
|
|
30
|
+
if (scrollTarget.current === null) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
var _scrollTarget$current = scrollTarget.current,
|
|
34
|
+
scrollTop = _scrollTarget$current.scrollTop,
|
|
35
|
+
scrollHeight = _scrollTarget$current.scrollHeight,
|
|
36
|
+
clientHeight = _scrollTarget$current.clientHeight;
|
|
37
|
+
var target = scrollTarget.current;
|
|
38
|
+
var isDeltaPositive = delta > 0;
|
|
39
|
+
var availableScroll = scrollHeight - clientHeight - scrollTop;
|
|
40
|
+
var shouldCancelScroll = false;
|
|
41
|
+
|
|
42
|
+
// reset bottom/top flags
|
|
43
|
+
if (availableScroll > delta && isBottom.current) {
|
|
44
|
+
if (onBottomLeave) {
|
|
45
|
+
onBottomLeave(event);
|
|
46
|
+
}
|
|
47
|
+
isBottom.current = false;
|
|
48
|
+
}
|
|
49
|
+
if (isDeltaPositive && isTop.current) {
|
|
50
|
+
if (onTopLeave) {
|
|
51
|
+
onTopLeave(event);
|
|
52
|
+
}
|
|
53
|
+
isTop.current = false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// bottom limit
|
|
57
|
+
if (isDeltaPositive && delta > availableScroll) {
|
|
58
|
+
if (onBottomArrive && !isBottom.current) {
|
|
59
|
+
onBottomArrive(event);
|
|
60
|
+
}
|
|
61
|
+
target.scrollTop = scrollHeight;
|
|
62
|
+
shouldCancelScroll = true;
|
|
63
|
+
isBottom.current = true;
|
|
64
|
+
|
|
65
|
+
// top limit
|
|
66
|
+
} else if (!isDeltaPositive && -delta > scrollTop) {
|
|
67
|
+
if (onTopArrive && !isTop.current) {
|
|
68
|
+
onTopArrive(event);
|
|
69
|
+
}
|
|
70
|
+
target.scrollTop = 0;
|
|
71
|
+
shouldCancelScroll = true;
|
|
72
|
+
isTop.current = true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// cancel scroll
|
|
76
|
+
if (shouldCancelScroll) {
|
|
77
|
+
cancelScroll(event);
|
|
78
|
+
}
|
|
79
|
+
}, [onBottomArrive, onBottomLeave, onTopArrive, onTopLeave]);
|
|
80
|
+
var onWheel = (0, _react.useCallback)(function (event) {
|
|
81
|
+
handleEventDelta(event, event.deltaY);
|
|
82
|
+
}, [handleEventDelta]);
|
|
83
|
+
var onTouchStart = (0, _react.useCallback)(function (event) {
|
|
84
|
+
// set touch start so we can calculate touchmove delta
|
|
85
|
+
touchStart.current = event.changedTouches[0].clientY;
|
|
86
|
+
}, []);
|
|
87
|
+
var onTouchMove = (0, _react.useCallback)(function (event) {
|
|
88
|
+
var deltaY = touchStart.current - event.changedTouches[0].clientY;
|
|
89
|
+
handleEventDelta(event, deltaY);
|
|
90
|
+
}, [handleEventDelta]);
|
|
91
|
+
var startListening = (0, _react.useCallback)(function (el) {
|
|
92
|
+
// bail early if no element is available to attach to
|
|
93
|
+
if (!el) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
var notPassive = _utils.supportsPassiveEvents ? {
|
|
97
|
+
passive: false
|
|
98
|
+
} : false;
|
|
99
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
100
|
+
el.addEventListener('wheel', onWheel, notPassive);
|
|
101
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
102
|
+
el.addEventListener('touchstart', onTouchStart, notPassive);
|
|
103
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
104
|
+
el.addEventListener('touchmove', onTouchMove, notPassive);
|
|
105
|
+
}, [onTouchMove, onTouchStart, onWheel]);
|
|
106
|
+
var stopListening = (0, _react.useCallback)(function (el) {
|
|
107
|
+
// bail early if no element is available to detach from
|
|
108
|
+
if (!el) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
113
|
+
el.removeEventListener('wheel', onWheel, false);
|
|
114
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
115
|
+
el.removeEventListener('touchstart', onTouchStart, false);
|
|
116
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
117
|
+
el.removeEventListener('touchmove', onTouchMove, false);
|
|
118
|
+
}, [onTouchMove, onTouchStart, onWheel]);
|
|
119
|
+
(0, _react.useEffect)(function () {
|
|
120
|
+
if (!isEnabled) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
var element = scrollTarget.current;
|
|
124
|
+
startListening(element);
|
|
125
|
+
return function () {
|
|
126
|
+
stopListening(element);
|
|
127
|
+
};
|
|
128
|
+
}, [isEnabled, startListening, stopListening]);
|
|
129
|
+
return function (element) {
|
|
130
|
+
scrollTarget.current = element;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = useScrollLock;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var STYLE_KEYS = ['boxSizing', 'height', 'overflow', 'paddingRight', 'position'];
|
|
9
|
+
var LOCK_STYLES = {
|
|
10
|
+
boxSizing: 'border-box',
|
|
11
|
+
// account for possible declaration `width: 100%;` on body
|
|
12
|
+
overflow: 'hidden',
|
|
13
|
+
position: 'relative',
|
|
14
|
+
height: '100%'
|
|
15
|
+
};
|
|
16
|
+
function preventTouchMove(e) {
|
|
17
|
+
e.preventDefault();
|
|
18
|
+
}
|
|
19
|
+
function allowTouchMove(e) {
|
|
20
|
+
e.stopPropagation();
|
|
21
|
+
}
|
|
22
|
+
function preventInertiaScroll() {
|
|
23
|
+
var top = this.scrollTop;
|
|
24
|
+
var totalScroll = this.scrollHeight;
|
|
25
|
+
var currentScroll = top + this.offsetHeight;
|
|
26
|
+
if (top === 0) {
|
|
27
|
+
this.scrollTop = 1;
|
|
28
|
+
} else if (currentScroll === totalScroll) {
|
|
29
|
+
this.scrollTop = top - 1;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// `ontouchstart` check works on most browsers
|
|
34
|
+
// `maxTouchPoints` works on IE10/11 and Surface
|
|
35
|
+
function isTouchDevice() {
|
|
36
|
+
// eslint-disable-next-line compat/compat
|
|
37
|
+
return 'ontouchstart' in window || navigator.maxTouchPoints;
|
|
38
|
+
}
|
|
39
|
+
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
|
|
40
|
+
var activeScrollLocks = 0;
|
|
41
|
+
var listenerOptions = {
|
|
42
|
+
capture: false,
|
|
43
|
+
passive: false
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// TODO: Fill in the hook {description}.
|
|
47
|
+
/**
|
|
48
|
+
* {description}.
|
|
49
|
+
*/
|
|
50
|
+
function useScrollLock(_ref) {
|
|
51
|
+
var isEnabled = _ref.isEnabled,
|
|
52
|
+
_ref$accountForScroll = _ref.accountForScrollbars,
|
|
53
|
+
accountForScrollbars = _ref$accountForScroll === void 0 ? true : _ref$accountForScroll;
|
|
54
|
+
var originalStyles = (0, _react.useRef)({});
|
|
55
|
+
var scrollTarget = (0, _react.useRef)(null);
|
|
56
|
+
var addScrollLock = (0, _react.useCallback)(function (touchScrollTarget) {
|
|
57
|
+
if (!canUseDOM) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
var target = document.body;
|
|
61
|
+
var targetStyle = target && target.style;
|
|
62
|
+
if (accountForScrollbars) {
|
|
63
|
+
// store any styles already applied to the body
|
|
64
|
+
STYLE_KEYS.forEach(function (key) {
|
|
65
|
+
var val = targetStyle && targetStyle[key];
|
|
66
|
+
originalStyles.current[key] = val;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// apply the lock styles and padding if this is the first scroll lock
|
|
71
|
+
if (accountForScrollbars && activeScrollLocks < 1) {
|
|
72
|
+
var currentPadding = parseInt(originalStyles.current.paddingRight, 10) || 0;
|
|
73
|
+
var clientWidth = document.body ? document.body.clientWidth : 0;
|
|
74
|
+
var adjustedPadding = window.innerWidth - clientWidth + currentPadding || 0;
|
|
75
|
+
Object.keys(LOCK_STYLES).forEach(function (key) {
|
|
76
|
+
var val = LOCK_STYLES[key];
|
|
77
|
+
if (targetStyle) {
|
|
78
|
+
targetStyle[key] = val;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
if (targetStyle) {
|
|
82
|
+
targetStyle.paddingRight = "".concat(adjustedPadding, "px");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// account for touch devices
|
|
87
|
+
if (target && isTouchDevice()) {
|
|
88
|
+
// Mobile Safari ignores { overflow: hidden } declaration on the body.
|
|
89
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
90
|
+
target.addEventListener('touchmove', preventTouchMove, listenerOptions);
|
|
91
|
+
|
|
92
|
+
// Allow scroll on provided target
|
|
93
|
+
if (touchScrollTarget) {
|
|
94
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
95
|
+
touchScrollTarget.addEventListener('touchstart', preventInertiaScroll, listenerOptions);
|
|
96
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
97
|
+
touchScrollTarget.addEventListener('touchmove', allowTouchMove, listenerOptions);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// increment active scroll locks
|
|
102
|
+
activeScrollLocks += 1;
|
|
103
|
+
}, [accountForScrollbars]);
|
|
104
|
+
var removeScrollLock = (0, _react.useCallback)(function (touchScrollTarget) {
|
|
105
|
+
if (!canUseDOM) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
var target = document.body;
|
|
109
|
+
var targetStyle = target && target.style;
|
|
110
|
+
|
|
111
|
+
// safely decrement active scroll locks
|
|
112
|
+
activeScrollLocks = Math.max(activeScrollLocks - 1, 0);
|
|
113
|
+
|
|
114
|
+
// reapply original body styles, if any
|
|
115
|
+
if (accountForScrollbars && activeScrollLocks < 1) {
|
|
116
|
+
STYLE_KEYS.forEach(function (key) {
|
|
117
|
+
var val = originalStyles.current[key];
|
|
118
|
+
if (targetStyle) {
|
|
119
|
+
targetStyle[key] = val;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// remove touch listeners
|
|
125
|
+
if (target && isTouchDevice()) {
|
|
126
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
127
|
+
target.removeEventListener('touchmove', preventTouchMove, listenerOptions);
|
|
128
|
+
if (touchScrollTarget) {
|
|
129
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
130
|
+
touchScrollTarget.removeEventListener('touchstart', preventInertiaScroll, listenerOptions);
|
|
131
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
132
|
+
touchScrollTarget.removeEventListener('touchmove', allowTouchMove, listenerOptions);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}, [accountForScrollbars]);
|
|
136
|
+
(0, _react.useEffect)(function () {
|
|
137
|
+
if (!isEnabled) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
var element = scrollTarget.current;
|
|
141
|
+
addScrollLock(element);
|
|
142
|
+
return function () {
|
|
143
|
+
removeScrollLock(element);
|
|
144
|
+
};
|
|
145
|
+
}, [isEnabled, addScrollLock, removeScrollLock]);
|
|
146
|
+
return function (element) {
|
|
147
|
+
scrollTarget.current = element;
|
|
148
|
+
};
|
|
149
|
+
}
|