@alfalab/core-components-bottom-sheet 6.5.0 → 6.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/component.js +102 -56
  2. package/components/footer/Component.js +1 -1
  3. package/components/footer/index.css +26 -26
  4. package/components/header/Component.d.ts +1 -0
  5. package/components/header/Component.js +4 -5
  6. package/components/header/index.css +13 -13
  7. package/cssm/component.js +101 -55
  8. package/cssm/components/header/Component.d.ts +1 -0
  9. package/cssm/components/header/Component.js +3 -4
  10. package/cssm/index.js +1 -0
  11. package/cssm/index.module.css +3 -0
  12. package/cssm/types.d.ts +30 -10
  13. package/cssm/utils.d.ts +3 -3
  14. package/cssm/utils.js +4 -4
  15. package/esm/component.js +103 -57
  16. package/esm/components/footer/Component.js +1 -1
  17. package/esm/components/footer/index.css +26 -26
  18. package/esm/components/header/Component.d.ts +1 -0
  19. package/esm/components/header/Component.js +4 -5
  20. package/esm/components/header/index.css +13 -13
  21. package/esm/index.css +44 -41
  22. package/esm/index.js +1 -0
  23. package/esm/types.d.ts +30 -10
  24. package/esm/utils.d.ts +3 -3
  25. package/esm/utils.js +4 -4
  26. package/index.css +44 -41
  27. package/index.js +1 -0
  28. package/modern/component.js +90 -44
  29. package/modern/components/footer/Component.js +1 -1
  30. package/modern/components/footer/index.css +26 -26
  31. package/modern/components/header/Component.d.ts +1 -0
  32. package/modern/components/header/Component.js +4 -5
  33. package/modern/components/header/index.css +13 -13
  34. package/modern/index.css +44 -41
  35. package/modern/index.js +1 -0
  36. package/modern/types.d.ts +30 -10
  37. package/modern/utils.d.ts +3 -3
  38. package/modern/utils.js +3 -4
  39. package/package.json +5 -4
  40. package/src/component.tsx +572 -0
  41. package/src/components/footer/Component.tsx +42 -0
  42. package/src/components/footer/index.module.css +24 -0
  43. package/src/components/header/Component.tsx +54 -0
  44. package/src/components/header/index.module.css +72 -0
  45. package/src/components/swipeable-backdrop/Component.tsx +41 -0
  46. package/src/index.module.css +136 -0
  47. package/src/index.ts +3 -0
  48. package/src/types.ts +318 -0
  49. package/src/utils.ts +30 -0
  50. package/types.d.ts +30 -10
  51. package/utils.d.ts +3 -3
  52. package/utils.js +4 -4
package/cssm/component.js CHANGED
@@ -9,6 +9,7 @@ var mergeRefs = require('react-merge-refs');
9
9
  var reactSwipeable = require('react-swipeable');
10
10
  var cn = require('classnames');
11
11
  var coreComponentsBaseModal = require('@alfalab/core-components-base-modal/cssm');
12
+ var coreComponentsShared = require('@alfalab/core-components-shared/cssm');
12
13
  var components_footer_Component = require('./components/footer/Component.js');
13
14
  var components_header_Component = require('./components/header/Component.js');
14
15
  var components_swipeableBackdrop_Component = require('./components/swipeable-backdrop/Component.js');
@@ -26,30 +27,29 @@ var mergeRefs__default = /*#__PURE__*/_interopDefaultCompat(mergeRefs);
26
27
  var cn__default = /*#__PURE__*/_interopDefaultCompat(cn);
27
28
  var styles__default = /*#__PURE__*/_interopDefaultCompat(styles);
28
29
 
29
- var getDataTestId = function (dataTestId, element) {
30
- var elementPart = element ? "-".concat(element.toLowerCase()) : '';
31
- return dataTestId ? "".concat(dataTestId).concat(elementPart) : undefined;
32
- };
33
-
34
30
  var BottomSheet = React.forwardRef(function (_a, ref) {
35
- var _b, _c, _d, _e;
36
- var open = _a.open, title = _a.title, container = _a.container, usePortal = _a.usePortal, backgroundColor = _a.backgroundColor, _f = _a.titleSize, titleSize = _f === void 0 ? 'default' : _f, subtitle = _a.subtitle, actionButton = _a.actionButton, contentClassName = _a.contentClassName, containerClassName = _a.containerClassName, containerProps = _a.containerProps, headerClassName = _a.headerClassName, footerClassName = _a.footerClassName, addonClassName = _a.addonClassName, closerClassName = _a.closerClassName, backerClassName = _a.backerClassName, modalClassName = _a.modalClassName, modalWrapperClassName = _a.modalWrapperClassName, className = _a.className, leftAddons = _a.leftAddons, rightAddons = _a.rightAddons, bottomAddons = _a.bottomAddons, hasCloser = _a.hasCloser, hasBacker = _a.hasBacker, _g = _a.titleAlign, titleAlign = _g === void 0 ? 'left' : _g, trimTitle = _a.trimTitle, stickyHeader = _a.stickyHeader, _h = _a.stickyFooter, stickyFooter = _h === void 0 ? true : _h, _j = _a.initialHeight, initialHeight = _j === void 0 ? 'default' : _j, hideOverlay = _a.hideOverlay, hideScrollbar = _a.hideScrollbar, hideHeader = _a.hideHeader, disableOverlayClick = _a.disableOverlayClick, disableBlockingScroll = _a.disableBlockingScroll, disableFocusLock = _a.disableFocusLock, children = _a.children, zIndex = _a.zIndex, _k = _a.transitionProps, transitionProps = _k === void 0 ? {} : _k, magneticAreasProp = _a.magneticAreas, initialActiveAreaIndex = _a.initialActiveAreaIndex, dataTestId = _a.dataTestId, _l = _a.swipeable, swipeable = _l === void 0 ? true : _l, scrollLockedProp = _a.scrollLocked, backdropProps = _a.backdropProps, _m = _a.scrollableContainerRef, scrollableContainerRef = _m === void 0 ? function () { return null; } : _m, bottomSheetInstanceRef = _a.bottomSheetInstanceRef, _o = _a.sheetContainerRef, sheetContainerRef = _o === void 0 ? function () { return null; } : _o, onClose = _a.onClose, onBack = _a.onBack, onMagnetize = _a.onMagnetize, disableRestoreFocus = _a.disableRestoreFocus, disableAutoFocus = _a.disableAutoFocus, disableEscapeKeyDown = _a.disableEscapeKeyDown, keepMounted = _a.keepMounted;
31
+ var _b, _c, _d, _e, _f;
32
+ var open = _a.open, title = _a.title, container = _a.container, usePortal = _a.usePortal, backgroundColor = _a.backgroundColor, _g = _a.titleSize, titleSize = _g === void 0 ? 'default' : _g, subtitle = _a.subtitle, actionButton = _a.actionButton, contentClassName = _a.contentClassName, containerClassName = _a.containerClassName, containerProps = _a.containerProps, headerClassName = _a.headerClassName, footerClassName = _a.footerClassName, addonClassName = _a.addonClassName, closerClassName = _a.closerClassName, backerClassName = _a.backerClassName, modalClassName = _a.modalClassName, modalWrapperClassName = _a.modalWrapperClassName, className = _a.className, leftAddons = _a.leftAddons, rightAddons = _a.rightAddons, bottomAddons = _a.bottomAddons, hasCloser = _a.hasCloser, hasBacker = _a.hasBacker, _h = _a.titleAlign, titleAlign = _h === void 0 ? 'left' : _h, trimTitle = _a.trimTitle, stickyHeader = _a.stickyHeader, _j = _a.stickyFooter, stickyFooter = _j === void 0 ? true : _j, _k = _a.initialHeight, initialHeight = _k === void 0 ? 'default' : _k, hideOverlay = _a.hideOverlay, hideScrollbar = _a.hideScrollbar, hideHeader = _a.hideHeader, disableOverlayClick = _a.disableOverlayClick, disableBlockingScroll = _a.disableBlockingScroll, disableFocusLock = _a.disableFocusLock, children = _a.children, zIndex = _a.zIndex, _l = _a.transitionProps, transitionProps = _l === void 0 ? {} : _l, magneticAreasProp = _a.magneticAreas, initialActiveAreaIndex = _a.initialActiveAreaIndex, dataTestId = _a.dataTestId, _m = _a.swipeable, swipeable = _m === void 0 ? true : _m, _o = _a.swipeableContent, swipeableContent = _o === void 0 ? true : _o, _p = _a.swipeThreshold, swipeThreshold = _p === void 0 ? 5 : _p, scrollLockedProp = _a.scrollLocked, backdropProps = _a.backdropProps, _q = _a.scrollableContainerRef, scrollableContainerRef = _q === void 0 ? function () { return null; } : _q, bottomSheetInstanceRef = _a.bottomSheetInstanceRef, _r = _a.sheetContainerRef, sheetContainerRef = _r === void 0 ? function () { return null; } : _r, _s = _a.headerOffset, headerOffset = _s === void 0 ? 24 : _s, onClose = _a.onClose, onBack = _a.onBack, onMagnetize = _a.onMagnetize, disableRestoreFocus = _a.disableRestoreFocus, disableAutoFocus = _a.disableAutoFocus, disableEscapeKeyDown = _a.disableEscapeKeyDown, keepMounted = _a.keepMounted, onMagnetizeEnd = _a.onMagnetizeEnd, onOffsetChange = _a.onOffsetChange;
37
33
  var hasInitialIdx = initialActiveAreaIndex !== undefined;
38
34
  var fullHeight = reactDiv100vh.use100vh() || 0;
39
35
  // Хук use100vh рассчитывает высоту вьюпорта в useEffect, поэтому на первый рендер всегда возвращает null.
40
36
  var isFirstRender = fullHeight === 0;
41
37
  var magneticAreas = React.useMemo(function () {
42
38
  if (magneticAreasProp) {
43
- return magneticAreasProp.map(function (area) { return utils.convertPercentToNumber(area, fullHeight); });
39
+ return magneticAreasProp.map(function (area) {
40
+ return utils.convertPercentToNumber(area, fullHeight, headerOffset);
41
+ });
44
42
  }
45
- return [0, fullHeight - utils.HEADER_OFFSET];
46
- }, [fullHeight, magneticAreasProp]);
43
+ return [0, fullHeight - headerOffset];
44
+ }, [fullHeight, headerOffset, magneticAreasProp]);
47
45
  var lastMagneticArea = magneticAreas[magneticAreas.length - 1];
48
- var _p = React.useState(0), sheetOffset = _p[0], setSheetOffset = _p[1];
49
- var _q = React.useState(1), backdropOpacity = _q[0], setBackdropOpacity = _q[1];
50
- var _r = React.useState(0), activeArea = _r[0], setActiveArea = _r[1];
51
- var swipingInProgress = React.useRef(null);
46
+ var _t = React.useState(0), sheetOffset = _t[0], setSheetOffset = _t[1];
47
+ var _u = React.useState(1), backdropOpacity = _u[0], setBackdropOpacity = _u[1];
48
+ var _v = React.useState(0), activeArea = _v[0], setActiveArea = _v[1];
49
+ var _w = React.useState(null), swipingInProgress = _w[0], setSwipingInProgress = _w[1];
50
+ var scrollOccurred = React.useRef(false);
52
51
  var headerRef = React.useRef(null);
52
+ var contentRef = React.useRef(null);
53
53
  var sheetHeight = React.useRef(0);
54
54
  var sheetRef = React.useRef(null);
55
55
  var scrollableContainer = React.useRef(null);
@@ -57,7 +57,7 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
57
57
  var titleIsReactElement = React__default.default.isValidElement(title);
58
58
  var headerProps = tslib.__assign(tslib.__assign({}, (titleIsReactElement
59
59
  ? { children: title }
60
- : { title: title ? title === null || title === void 0 ? void 0 : title.toString() : undefined })), { scrollableParentRef: scrollableContainer, headerRef: headerRef, className: headerClassName, addonClassName: addonClassName, closerClassName: closerClassName, backButtonClassName: backerClassName, leftAddons: leftAddons, rightAddons: rightAddons, bottomAddons: bottomAddons, hasCloser: hasCloser, hasBackButton: hasBacker, align: titleAlign, trim: trimTitle, sticky: stickyHeader, dataTestId: getDataTestId(dataTestId, 'header'), onBack: onBack, titleSize: titleSize, subtitle: subtitle, onClose: onClose });
60
+ : { title: title ? title === null || title === void 0 ? void 0 : title.toString() : undefined })), { scrollableParentRef: scrollableContainer, headerRef: headerRef, headerOffset: headerOffset, className: headerClassName, addonClassName: addonClassName, closerClassName: closerClassName, backButtonClassName: backerClassName, leftAddons: leftAddons, rightAddons: rightAddons, bottomAddons: bottomAddons, hasCloser: hasCloser, hasBackButton: hasBacker, align: titleAlign, trim: trimTitle, sticky: stickyHeader, dataTestId: coreComponentsShared.getDataTestId(dataTestId, 'header'), onBack: onBack, titleSize: titleSize, subtitle: subtitle, onClose: onClose });
61
61
  var getBackdropOpacity = function (offset) {
62
62
  var canClose = magneticAreas[0] === 0;
63
63
  var secondArea = magneticAreas[1];
@@ -82,8 +82,14 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
82
82
  sheetHeight.current = sheetRef.current.getBoundingClientRect().height - sheetOffset;
83
83
  }
84
84
  };
85
+ var handleTransitionEnd = function (event) {
86
+ setSheetHeight();
87
+ if (event.propertyName === 'transform' && event.target === event.currentTarget) {
88
+ onMagnetizeEnd === null || onMagnetizeEnd === void 0 ? void 0 : onMagnetizeEnd();
89
+ }
90
+ };
85
91
  var scrollToArea = function (idx) {
86
- swipingInProgress.current = false;
92
+ setSwipingInProgress(false);
87
93
  var nextArea = magneticAreas[idx];
88
94
  if (nextArea === 0) {
89
95
  onClose();
@@ -92,11 +98,12 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
92
98
  if (nextArea) {
93
99
  setActiveArea(nextArea);
94
100
  setSheetOffset(lastMagneticArea - nextArea);
101
+ onMagnetize === null || onMagnetize === void 0 ? void 0 : onMagnetize(getActiveAreaIndex(nextArea));
95
102
  }
96
103
  };
97
- var magnetize = function (dir, velocity, deltaY) {
98
- var shouldMagnetizeDownByVelocity = dir === 'Down' && velocity >= utils.SWIPE_VELOCITY;
99
- var shouldMagnetizeUpByVelocity = dir === 'Up' && velocity >= utils.SWIPE_VELOCITY;
104
+ var magnetize = function (velocity, deltaY) {
105
+ var shouldMagnetizeDownByVelocity = deltaY >= 0 && velocity >= utils.SWIPE_VELOCITY;
106
+ var shouldMagnetizeUpByVelocity = deltaY < 0 && velocity >= utils.SWIPE_VELOCITY;
100
107
  if (shouldMagnetizeDownByVelocity) {
101
108
  var nextArea_1 = magneticAreas
102
109
  .slice()
@@ -111,6 +118,9 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
111
118
  : lastMagneticArea - activeArea;
112
119
  setSheetOffset(offset_1);
113
120
  setActiveArea(function (prevState) { return nextArea_1 !== null && nextArea_1 !== void 0 ? nextArea_1 : prevState; });
121
+ if (nextArea_1) {
122
+ onMagnetize === null || onMagnetize === void 0 ? void 0 : onMagnetize(getActiveAreaIndex(nextArea_1));
123
+ }
114
124
  return;
115
125
  }
116
126
  if (shouldMagnetizeUpByVelocity) {
@@ -118,13 +128,16 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
118
128
  var offset_2 = nextArea_2 ? lastMagneticArea - nextArea_2 : 0;
119
129
  setSheetOffset(offset_2);
120
130
  setActiveArea(function (prevState) { return nextArea_2 !== null && nextArea_2 !== void 0 ? nextArea_2 : prevState; });
131
+ if (nextArea_2) {
132
+ onMagnetize === null || onMagnetize === void 0 ? void 0 : onMagnetize(getActiveAreaIndex(nextArea_2));
133
+ }
121
134
  return;
122
135
  }
123
136
  var offset = getSheetOffset(deltaY);
124
137
  var currentSheetHeight = lastMagneticArea - offset;
125
138
  var secondArea = magneticAreas[1];
126
139
  var isSecondArea = activeArea === secondArea;
127
- var canClose = magneticAreas[0] === 0 && dir === 'Down';
140
+ var canClose = magneticAreas[0] === 0 && deltaY >= 0;
128
141
  var shouldCloseByOffset = isSecondArea && canClose && 1 - currentSheetHeight / activeArea > utils.CLOSE_OFFSET;
129
142
  if (shouldCloseByOffset) {
130
143
  onClose();
@@ -147,16 +160,21 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
147
160
  setSheetOffset(lastMagneticArea - nearestArea);
148
161
  setActiveArea(nearestArea);
149
162
  setBackdropOpacity(1);
163
+ onMagnetize === null || onMagnetize === void 0 ? void 0 : onMagnetize(getActiveAreaIndex(nearestArea));
150
164
  }
151
165
  };
152
166
  /**
153
167
  * Если контент внутри шторки скроллится - то шторка не должна свайпаться
154
168
  * Если шапка внутри шторки зафиксирована - то шторка должна свайпаться только в области шапки
155
169
  */
156
- var shouldSkipSwiping = function (dir, startY) {
170
+ var shouldSkipSwiping = function (deltaY, startY, event) {
171
+ var _a;
157
172
  if (!swipeable)
158
173
  return true;
159
- if (scrollLockedProp || swipingInProgress.current)
174
+ if (!swipeableContent && ((_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target))) {
175
+ return true;
176
+ }
177
+ if (scrollLockedProp || swipingInProgress)
160
178
  return false;
161
179
  var scrollableNode = scrollableContainer.current;
162
180
  // Точка верхней границы (y координата)
@@ -168,35 +186,43 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
168
186
  Math.abs(bottomSheetTopY - startY) <= headerRef.current.clientHeight)) {
169
187
  return false;
170
188
  }
171
- return dir === 'Down'
189
+ var shouldScroll = deltaY >= 0
172
190
  ? scrollableNode.scrollTop > 0
173
191
  : scrollableNode.scrollHeight -
174
192
  scrollableNode.scrollTop -
175
193
  scrollableNode.clientHeight >
176
194
  utils.SCROLL_OFFSET;
195
+ if (!scrollOccurred.current && shouldScroll) {
196
+ scrollOccurred.current = true;
197
+ }
198
+ return shouldScroll;
177
199
  };
178
200
  var handleSheetSwipe = function (_a) {
179
- var dir = _a.dir, initial = _a.initial, velocity = _a.velocity, deltaY = _a.deltaY;
180
- if (shouldSkipSwiping(dir, initial[1])) {
201
+ var initial = _a.initial, velocity = _a.velocity, deltaY = _a.deltaY, event = _a.event;
202
+ if (scrollOccurred.current || shouldSkipSwiping(deltaY, initial[1], event)) {
181
203
  return;
182
204
  }
183
- magnetize(dir, velocity, deltaY);
205
+ magnetize(velocity, deltaY);
184
206
  };
185
207
  var handleSheetSwipeStart = function (_a) {
186
- var dir = _a.dir, initial = _a.initial;
187
- if (shouldSkipSwiping(dir, initial[1])) {
208
+ var deltaY = _a.deltaY, initial = _a.initial, event = _a.event;
209
+ if (shouldSkipSwiping(deltaY, initial[1], event)) {
188
210
  return;
189
211
  }
190
- swipingInProgress.current = true;
212
+ setSwipingInProgress(true);
191
213
  };
192
- var handleSheetSwiped = function () {
193
- swipingInProgress.current = false;
214
+ var handleTouchEnd = function () {
215
+ setSwipingInProgress(false);
216
+ scrollOccurred.current = false;
194
217
  };
195
218
  var handleSheetSwiping = function (_a) {
196
- var initial = _a.initial, deltaY = _a.deltaY, dir = _a.dir;
197
- if (shouldSkipSwiping(dir, initial[1])) {
219
+ var initial = _a.initial, deltaY = _a.deltaY, event = _a.event;
220
+ if (scrollOccurred.current || shouldSkipSwiping(deltaY, initial[1], event)) {
198
221
  return;
199
222
  }
223
+ if (!swipingInProgress) {
224
+ setSwipingInProgress(true);
225
+ }
200
226
  var offset = getSheetOffset(deltaY);
201
227
  var opacity = getBackdropOpacity(offset);
202
228
  setSheetOffset(offset);
@@ -205,26 +231,40 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
205
231
  var sheetSwipeableHandlers = reactSwipeable.useSwipeable({
206
232
  onSwipeStart: handleSheetSwipeStart,
207
233
  onSwiping: handleSheetSwiping,
208
- onSwipedDown: handleSheetSwipe,
209
- onSwipedUp: handleSheetSwipe,
210
- onSwiped: handleSheetSwiped,
234
+ onSwiped: handleSheetSwipe,
235
+ onTouchEndOrOnMouseUp: handleTouchEnd,
211
236
  trackMouse: swipeable,
212
- delta: 5,
237
+ delta: swipeThreshold,
213
238
  });
214
239
  var handleExited = function (node) {
215
240
  var idx = initialActiveAreaIndex;
241
+ var nextArea = hasInitialIdx ? magneticAreas[idx] : lastMagneticArea;
216
242
  setBackdropOpacity(1);
217
243
  setSheetOffset(hasInitialIdx ? lastMagneticArea - magneticAreas[idx] : magneticAreas[0]);
218
- setActiveArea(hasInitialIdx ? magneticAreas[idx] : lastMagneticArea);
244
+ setActiveArea(nextArea);
245
+ onMagnetizeEnd === null || onMagnetizeEnd === void 0 ? void 0 : onMagnetizeEnd();
219
246
  if (transitionProps.onExited) {
220
247
  transitionProps.onExited(node);
221
248
  }
222
249
  };
250
+ var handleEnter = function (node, isAppearing) {
251
+ onMagnetize === null || onMagnetize === void 0 ? void 0 : onMagnetize(initialActiveAreaIndex || magneticAreas.length - 1);
252
+ if (transitionProps.onEnter) {
253
+ transitionProps.onEnter(node, isAppearing);
254
+ }
255
+ };
256
+ var handleExit = function (node) {
257
+ onMagnetize === null || onMagnetize === void 0 ? void 0 : onMagnetize(0);
258
+ if (transitionProps.onExit) {
259
+ transitionProps.onExit(node);
260
+ }
261
+ };
223
262
  var handleEntered = function (node, isAppearing) {
224
263
  setBackdropOpacity(1);
225
264
  setSheetHeight();
226
265
  // Ready for swiping
227
- swipingInProgress.current = false;
266
+ setSwipingInProgress(false);
267
+ onMagnetizeEnd === null || onMagnetizeEnd === void 0 ? void 0 : onMagnetizeEnd();
228
268
  if (transitionProps.onEntered) {
229
269
  transitionProps.onEntered(node, isAppearing);
230
270
  }
@@ -238,9 +278,13 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
238
278
  // eslint-disable-next-line react-hooks/exhaustive-deps
239
279
  }, [isFirstRender]);
240
280
  React.useEffect(function () {
241
- onMagnetize === null || onMagnetize === void 0 ? void 0 : onMagnetize(open ? getActiveAreaIndex(activeArea) : 0);
242
- // eslint-disable-next-line react-hooks/exhaustive-deps
243
- }, [activeArea, open]);
281
+ if (!sheetRef.current)
282
+ return;
283
+ var maxOffset = fullHeight - headerOffset;
284
+ var offset = open ? sheetOffset : maxOffset;
285
+ var percent = (offset / maxOffset) * 100;
286
+ onOffsetChange === null || onOffsetChange === void 0 ? void 0 : onOffsetChange(offset, percent);
287
+ }, [fullHeight, headerOffset, onOffsetChange, open, sheetOffset]);
244
288
  React.useImperativeHandle(bottomSheetInstanceRef, function () { return ({
245
289
  scrollToArea: scrollToArea,
246
290
  }); });
@@ -254,21 +298,23 @@ var BottomSheet = React.forwardRef(function (_a, ref) {
254
298
  var bgClassName = backgroundColor && styles__default.default["background-".concat(backgroundColor)];
255
299
  return (React__default.default.createElement(coreComponentsBaseModal.BaseModal, { open: open, ref: ref, container: container, dataTestId: dataTestId, zIndex: zIndex, onClose: onClose, usePortal: usePortal, scrollHandler: scrollableContainer, Backdrop: components_swipeableBackdrop_Component.SwipeableBackdrop, backdropProps: tslib.__assign(tslib.__assign({}, backdropProps), { className: styles__default.default.disabledPointerEvents, opacity: backdropOpacity, opacityTimeout: utils.TIMEOUT, invisible: hideOverlay }), disableBackdropClick: hideOverlay ? true : disableOverlayClick, className: cn__default.default(styles__default.default.modal, modalClassName), wrapperClassName: cn__default.default(modalWrapperClassName, (_b = {},
256
300
  _b[styles__default.default.disabledPointerEvents] = hideOverlay,
257
- _b)), disableBlockingScroll: disableBlockingScroll, disableFocusLock: disableFocusLock, transitionProps: tslib.__assign(tslib.__assign({ appear: true, timeout: utils.TIMEOUT, classNames: styles__default.default }, transitionProps), { onExited: handleExited, onEntered: handleEntered }), disableAutoFocus: disableAutoFocus, disableEscapeKeyDown: disableEscapeKeyDown, disableRestoreFocus: disableRestoreFocus, keepMounted: keepMounted },
258
- React__default.default.createElement("div", { style: tslib.__assign({}, getHeightStyles()), className: styles__default.default.wrapper, onTransitionEnd: setSheetHeight },
259
- React__default.default.createElement("div", tslib.__assign({ className: cn__default.default(styles__default.default.component, bgClassName, className, (_c = {},
260
- _c[styles__default.default.withTransition] = swipingInProgress.current === false,
261
- _c)), style: tslib.__assign(tslib.__assign({}, getSwipeStyles()), getHeightStyles()) }, sheetSwipeableHandlers, { ref: mergeRefs__default.default([sheetRef, sheetContainerRef, sheetSwipeableHandlers.ref]), onTransitionEnd: setSheetHeight }),
262
- React__default.default.createElement("div", tslib.__assign({}, containerProps, { className: cn__default.default(styles__default.default.scrollableContainer, containerProps === null || containerProps === void 0 ? void 0 : containerProps.className, containerClassName, (_d = {},
263
- _d[styles__default.default.scrollLocked] = scrollLockedProp || swipingInProgress.current,
264
- _d[styles__default.default.hiddenScrollbar] = hideScrollbar,
265
- _d)), ref: mergeRefs__default.default([scrollableContainer, scrollableContainerRef]) }),
301
+ _b)), disableBlockingScroll: disableBlockingScroll, disableFocusLock: disableFocusLock, transitionProps: tslib.__assign(tslib.__assign({ appear: true, timeout: utils.TIMEOUT, classNames: styles__default.default }, transitionProps), { onExited: handleExited, onEntered: handleEntered, onEnter: handleEnter, onExit: handleExit }), disableAutoFocus: disableAutoFocus, disableEscapeKeyDown: disableEscapeKeyDown, disableRestoreFocus: disableRestoreFocus, keepMounted: keepMounted },
302
+ React__default.default.createElement("div", { style: tslib.__assign({}, getHeightStyles()), className: cn__default.default(styles__default.default.wrapper, (_c = {},
303
+ _c[styles__default.default.fullscreen] = headerOffset === 0 && sheetOffset === 0,
304
+ _c)), onTransitionEnd: setSheetHeight },
305
+ React__default.default.createElement("div", tslib.__assign({ className: cn__default.default(styles__default.default.component, bgClassName, className, (_d = {},
306
+ _d[styles__default.default.withTransition] = swipingInProgress === false,
307
+ _d)), style: tslib.__assign(tslib.__assign({}, getSwipeStyles()), getHeightStyles()) }, sheetSwipeableHandlers, { ref: mergeRefs__default.default([sheetRef, sheetContainerRef, sheetSwipeableHandlers.ref]), onTransitionEnd: handleTransitionEnd }),
308
+ React__default.default.createElement("div", tslib.__assign({}, containerProps, { className: cn__default.default(styles__default.default.scrollableContainer, containerProps === null || containerProps === void 0 ? void 0 : containerProps.className, containerClassName, (_e = {},
309
+ _e[styles__default.default.scrollLocked] = scrollLockedProp || swipingInProgress,
310
+ _e[styles__default.default.hiddenScrollbar] = hideScrollbar,
311
+ _e)), ref: mergeRefs__default.default([scrollableContainer, scrollableContainerRef]) }),
266
312
  swipeable && React__default.default.createElement("div", { className: cn__default.default(styles__default.default.marker) }),
267
313
  !hideHeader && !emptyHeader && React__default.default.createElement(components_header_Component.Header, tslib.__assign({}, headerProps)),
268
- React__default.default.createElement("div", { className: cn__default.default(styles__default.default.content, contentClassName, (_e = {},
269
- _e[styles__default.default.noHeader] = hideHeader || emptyHeader,
270
- _e[styles__default.default.noFooter] = !actionButton,
271
- _e)) }, children),
314
+ React__default.default.createElement("div", { ref: contentRef, className: cn__default.default(styles__default.default.content, contentClassName, (_f = {},
315
+ _f[styles__default.default.noHeader] = hideHeader || emptyHeader,
316
+ _f[styles__default.default.noFooter] = !actionButton,
317
+ _f)) }, children),
272
318
  actionButton && (React__default.default.createElement(components_footer_Component.Footer, { sticky: stickyFooter, className: cn__default.default(bgClassName, footerClassName) }, actionButton)))))));
273
319
  });
274
320
 
@@ -2,6 +2,7 @@ import { FC, RefObject } from 'react';
2
2
  import { NavigationBarProps } from "@alfalab/core-components-navigation-bar";
3
3
  type HeaderProps = Omit<NavigationBarProps, 'view' | 'size'> & {
4
4
  headerRef: RefObject<HTMLDivElement>;
5
+ headerOffset: number;
5
6
  };
6
7
  declare const Header: FC<HeaderProps>;
7
8
  export { HeaderProps, Header };
@@ -7,7 +7,6 @@ var React = require('react');
7
7
  var cn = require('classnames');
8
8
  var coreComponentsBaseModal = require('@alfalab/core-components-base-modal/cssm');
9
9
  var coreComponentsNavigationBar = require('@alfalab/core-components-navigation-bar/cssm');
10
- var utils = require('../../utils.js');
11
10
  var styles = require('./index.module.css');
12
11
 
13
12
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
@@ -18,11 +17,11 @@ var styles__default = /*#__PURE__*/_interopDefaultCompat(styles);
18
17
 
19
18
  var Header = function (_a) {
20
19
  var _b;
21
- var className = _a.className, sticky = _a.sticky, headerRef = _a.headerRef, title = _a.title, children = _a.children, restProps = tslib.__rest(_a, ["className", "sticky", "headerRef", "title", "children"]);
20
+ var className = _a.className, sticky = _a.sticky, headerRef = _a.headerRef, headerOffset = _a.headerOffset, title = _a.title, children = _a.children, restProps = tslib.__rest(_a, ["className", "sticky", "headerRef", "headerOffset", "title", "children"]);
22
21
  var _c = React.useContext(coreComponentsBaseModal.BaseModalContext), setHeaderOffset = _c.setHeaderOffset, setHasHeader = _c.setHasHeader, headerHighlighted = _c.headerHighlighted, onClose = _c.onClose;
23
22
  React.useEffect(function () {
24
- setHeaderOffset(utils.HEADER_OFFSET);
25
- }, [setHeaderOffset]);
23
+ setHeaderOffset(headerOffset);
24
+ }, [headerOffset, setHeaderOffset]);
26
25
  React.useEffect(function () {
27
26
  setHasHeader(true);
28
27
  }, [setHasHeader]);
package/cssm/index.js CHANGED
@@ -11,6 +11,7 @@ require('react-merge-refs');
11
11
  require('react-swipeable');
12
12
  require('classnames');
13
13
  require('@alfalab/core-components-base-modal/cssm');
14
+ require('@alfalab/core-components-shared/cssm');
14
15
  require('./components/footer/Component.js');
15
16
  require('./components/footer/index.module.css');
16
17
  require('./components/header/Component.js');
@@ -57,6 +57,9 @@
57
57
  pointer-events: none;
58
58
  border-top-right-radius: var(--border-radius-xl);
59
59
  border-top-left-radius: var(--border-radius-xl);
60
+ transition: border-radius 0.3s ease;
61
+ } .fullscreen {
62
+ border-radius: 0;
60
63
  } .component {
61
64
  overflow: hidden;
62
65
  position: relative;
package/cssm/types.d.ts CHANGED
@@ -105,6 +105,14 @@ type BottomSheetProps = {
105
105
  * @default true
106
106
  */
107
107
  swipeable?: boolean;
108
+ /**
109
+ * Будет ли свайпаться контент
110
+ */
111
+ swipeableContent?: boolean;
112
+ /**
113
+ * Порог свайпа
114
+ */
115
+ swipeThreshold?: number;
108
116
  /**
109
117
  * Слот слева
110
118
  */
@@ -208,17 +216,9 @@ type BottomSheetProps = {
208
216
  */
209
217
  hideScrollbar?: boolean;
210
218
  /**
211
- * Обработчик закрытия
212
- */
213
- onClose: () => void;
214
- /**
215
- * Обработчик нажатия на стрелку назад
219
+ * Верхний отступ шторки, если она открыта на максимальную высоту
216
220
  */
217
- onBack?: () => void;
218
- /**
219
- * Вызывается после притягивания к одной из `magneticAreas`
220
- */
221
- onMagnetize?: (index: number) => void;
221
+ headerOffset?: number;
222
222
  /**
223
223
  * Содержимое bottom-sheet всегда в DOM
224
224
  */
@@ -235,5 +235,25 @@ type BottomSheetProps = {
235
235
  * Отключает вызов `onClose` при нажатии Escape
236
236
  */
237
237
  disableEscapeKeyDown?: boolean;
238
+ /**
239
+ * Обработчик закрытия
240
+ */
241
+ onClose: () => void;
242
+ /**
243
+ * Обработчик нажатия на стрелку назад
244
+ */
245
+ onBack?: () => void;
246
+ /**
247
+ * Вызывается в начале анимации притягивания к одной из `magneticAreas`
248
+ */
249
+ onMagnetize?: (index: number) => void;
250
+ /**
251
+ * Вызывается после окончания анимации притягивания
252
+ */
253
+ onMagnetizeEnd?: () => void;
254
+ /**
255
+ * Вызывается при изменении положения шторки
256
+ */
257
+ onOffsetChange?: (offset: number, percent: number) => void;
238
258
  };
239
259
  export { BottomSheetTitleAlign, BottomSheetProps };
package/cssm/utils.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  declare const TIMEOUT = 500;
2
2
  declare const SWIPE_VELOCITY = 0.4;
3
3
  declare const MARKER_HEIGHT = 24;
4
- declare const HEADER_OFFSET = 24;
5
4
  declare const CLOSE_OFFSET = 0.2;
6
5
  declare const SCROLL_OFFSET = 1;
7
- declare const convertPercentToNumber: (value: string | number, fullHeight: number) => number;
8
- export { TIMEOUT, SWIPE_VELOCITY, MARKER_HEIGHT, HEADER_OFFSET, CLOSE_OFFSET, SCROLL_OFFSET, convertPercentToNumber };
6
+ declare const HEADER_OFFSET = 24;
7
+ declare const convertPercentToNumber: (value: string | number, fullHeight: number, headerOffset?: number) => number;
8
+ export { TIMEOUT, SWIPE_VELOCITY, MARKER_HEIGHT, CLOSE_OFFSET, SCROLL_OFFSET, HEADER_OFFSET, convertPercentToNumber };
package/cssm/utils.js CHANGED
@@ -5,12 +5,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var TIMEOUT = 500;
6
6
  var SWIPE_VELOCITY = 0.4;
7
7
  var MARKER_HEIGHT = 24;
8
- /* Верхний отступ шторки, если она открыта на максимальную высоту */
9
- var HEADER_OFFSET = 24;
10
8
  var CLOSE_OFFSET = 0.2;
11
9
  var SCROLL_OFFSET = 1;
12
- var convertPercentToNumber = function (value, fullHeight) {
13
- var maxHeight = fullHeight - HEADER_OFFSET;
10
+ var HEADER_OFFSET = 24;
11
+ var convertPercentToNumber = function (value, fullHeight, headerOffset) {
12
+ if (headerOffset === void 0) { headerOffset = HEADER_OFFSET; }
13
+ var maxHeight = fullHeight - headerOffset;
14
14
  if (typeof value === 'string') {
15
15
  var percent = parseFloat(value) / 100;
16
16
  if (percent < 0) {