@alfalab/core-components-bottom-sheet 6.1.0 → 6.2.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.
Files changed (62) hide show
  1. package/component.d.ts +5 -0
  2. package/component.js +256 -13
  3. package/components/footer/Component.js +1 -1
  4. package/components/footer/index.css +26 -26
  5. package/components/header/Component.d.ts +7 -0
  6. package/components/header/Component.js +31 -13
  7. package/components/header/index.css +13 -13
  8. package/components/swipeable-backdrop/Component.d.ts +1 -1
  9. package/cssm/component.d.ts +5 -0
  10. package/cssm/component.js +256 -15
  11. package/cssm/components/header/Component.d.ts +7 -0
  12. package/cssm/components/header/Component.js +30 -16
  13. package/cssm/components/swipeable-backdrop/Component.d.ts +1 -1
  14. package/cssm/index.d.ts +3 -1
  15. package/cssm/index.js +7 -5
  16. package/cssm/index.module.css +23 -10
  17. package/{component-b5d23e5e.d.ts → cssm/types.d.ts} +36 -15
  18. package/cssm/types.js +2 -0
  19. package/cssm/utils.d.ts +8 -0
  20. package/cssm/utils.js +33 -0
  21. package/esm/component.d.ts +5 -0
  22. package/esm/component.js +253 -10
  23. package/esm/components/footer/Component.js +1 -1
  24. package/esm/components/footer/index.css +26 -26
  25. package/esm/components/header/Component.d.ts +7 -0
  26. package/esm/components/header/Component.js +29 -12
  27. package/esm/components/header/index.css +13 -13
  28. package/esm/components/swipeable-backdrop/Component.d.ts +1 -1
  29. package/esm/index.css +55 -42
  30. package/esm/index.d.ts +3 -1
  31. package/esm/index.js +3 -1
  32. package/esm/{component-612e671f.d.ts → types.d.ts} +36 -15
  33. package/esm/types.js +1 -0
  34. package/esm/utils.d.ts +8 -0
  35. package/esm/utils.js +23 -0
  36. package/index.css +55 -42
  37. package/index.d.ts +3 -1
  38. package/index.js +6 -4
  39. package/modern/component.d.ts +5 -0
  40. package/modern/component.js +284 -9
  41. package/modern/components/footer/Component.js +1 -1
  42. package/modern/components/footer/index.css +26 -26
  43. package/modern/components/header/Component.d.ts +7 -0
  44. package/modern/components/header/Component.js +26 -11
  45. package/modern/components/header/index.css +13 -13
  46. package/modern/components/swipeable-backdrop/Component.d.ts +1 -1
  47. package/modern/index.css +55 -42
  48. package/modern/index.d.ts +3 -1
  49. package/modern/index.js +3 -1
  50. package/{cssm/component-517950e0.d.ts → modern/types.d.ts} +36 -15
  51. package/modern/types.js +1 -0
  52. package/modern/utils.d.ts +8 -0
  53. package/modern/utils.js +23 -0
  54. package/package.json +5 -5
  55. package/{modern/component-1cd1bc34.d.ts → types.d.ts} +36 -15
  56. package/types.js +2 -0
  57. package/utils.d.ts +8 -0
  58. package/utils.js +33 -0
  59. package/component-b5d23e5e.js +0 -204
  60. package/cssm/component-517950e0.js +0 -202
  61. package/esm/component-612e671f.js +0 -193
  62. package/modern/component-1cd1bc34.js +0 -221
package/cssm/component.js CHANGED
@@ -2,24 +2,265 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- require('tslib');
6
- require('react');
7
- require('react-div-100vh');
8
- require('react-merge-refs');
9
- require('react-swipeable');
10
- require('classnames');
11
- require('@alfalab/core-components-base-modal/cssm');
12
- var components_header_Component = require('./component-517950e0.js');
13
- require('./components/footer/Component.js');
14
- require('./components/swipeable-backdrop/Component.js');
15
- require('./index.module.css');
5
+ var tslib = require('tslib');
6
+ var React = require('react');
7
+ var reactDiv100vh = require('react-div-100vh');
8
+ var mergeRefs = require('react-merge-refs');
9
+ var reactSwipeable = require('react-swipeable');
10
+ var cn = require('classnames');
11
+ var coreComponentsBaseModal = require('@alfalab/core-components-base-modal/cssm');
12
+ var components_footer_Component = require('./components/footer/Component.js');
13
+ var components_header_Component = require('./components/header/Component.js');
14
+ var components_swipeableBackdrop_Component = require('./components/swipeable-backdrop/Component.js');
15
+ var utils = require('./utils.js');
16
+ var styles = require('./index.module.css');
17
+ require('./components/footer/index.module.css');
16
18
  require('@alfalab/core-components-navigation-bar/cssm');
17
19
  require('./components/header/index.module.css');
18
- require('./components/footer/index.module.css');
19
20
  require('@alfalab/core-components-backdrop/cssm');
20
21
 
22
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
23
+
24
+ var React__default = /*#__PURE__*/_interopDefaultCompat(React);
25
+ var mergeRefs__default = /*#__PURE__*/_interopDefaultCompat(mergeRefs);
26
+ var cn__default = /*#__PURE__*/_interopDefaultCompat(cn);
27
+ var styles__default = /*#__PURE__*/_interopDefaultCompat(styles);
28
+
29
+ var getDataTestId = function (dataTestId, element) {
30
+ var elementPart = element ? "-".concat(element.toLowerCase()) : '';
31
+ return dataTestId ? "".concat(dataTestId).concat(elementPart) : undefined;
32
+ };
33
+
34
+ var isClient = function () { return typeof window !== 'undefined'; };
21
35
 
36
+ var BottomSheet = React.forwardRef(function (_a, ref) {
37
+ var _b, _c, _d, _e;
38
+ var open = _a.open, title = _a.title, container = _a.container, 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, 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;
39
+ var hasInitialIdx = initialActiveAreaIndex !== undefined;
40
+ var fullHeight = reactDiv100vh.use100vh() || isClient() ? window.innerHeight : 0;
41
+ var magneticAreas = React.useMemo(function () {
42
+ if (magneticAreasProp) {
43
+ return magneticAreasProp.map(function (area) { return utils.convertPercentToNumber(area, fullHeight); });
44
+ }
45
+ return [0, fullHeight - utils.HEADER_OFFSET];
46
+ }, [fullHeight, magneticAreasProp]);
47
+ var lastMagneticArea = magneticAreas[magneticAreas.length - 1];
48
+ var _p = React.useState(hasInitialIdx
49
+ ? lastMagneticArea - magneticAreas[initialActiveAreaIndex]
50
+ : magneticAreas[0]), sheetOffset = _p[0], setSheetOffset = _p[1];
51
+ var _q = React.useState(1), backdropOpacity = _q[0], setBackdropOpacity = _q[1];
52
+ var _r = React.useState(hasInitialIdx ? magneticAreas[initialActiveAreaIndex] : lastMagneticArea), activeArea = _r[0], setActiveArea = _r[1];
53
+ var swipingInProgress = React.useRef(false);
54
+ var headerRef = React.useRef(null);
55
+ var sheetHeight = React.useRef(0);
56
+ var sheetRef = React.useRef(null);
57
+ var scrollableContainer = React.useRef(null);
58
+ var emptyHeader = !hasCloser && !leftAddons && !title && !hasBacker && !rightAddons;
59
+ var titleIsReactElement = React__default.default.isValidElement(title);
60
+ var headerProps = tslib.__assign(tslib.__assign({}, (titleIsReactElement
61
+ ? { children: title }
62
+ : { 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 });
63
+ var getBackdropOpacity = function (offset) {
64
+ var canClose = magneticAreas[0] === 0;
65
+ var secondArea = magneticAreas[1];
66
+ var isSecondArea = secondArea === activeArea;
67
+ if (canClose && isSecondArea && sheetOffset > lastMagneticArea - secondArea) {
68
+ var opacity = 1 - (offset - (lastMagneticArea - secondArea)) / secondArea;
69
+ return Math.max(0, Number(opacity.toFixed(2)));
70
+ }
71
+ return 1;
72
+ };
73
+ var getSheetOffset = function (deltaY) {
74
+ var offset = lastMagneticArea - activeArea + deltaY;
75
+ var maxOffset = magneticAreas[0] === 0 ? 0 : lastMagneticArea - magneticAreas[0];
76
+ if (maxOffset) {
77
+ offset = Math.min(maxOffset, offset);
78
+ }
79
+ return Math.max(0, Math.round(offset));
80
+ };
81
+ var getActiveAreaIndex = function (area) { return magneticAreas.findIndex(function (a) { return a === area; }); };
82
+ var setSheetHeight = function () {
83
+ if (sheetRef.current) {
84
+ sheetHeight.current = sheetRef.current.getBoundingClientRect().height - sheetOffset;
85
+ }
86
+ };
87
+ var scrollToArea = function (idx) {
88
+ var nextArea = magneticAreas[idx];
89
+ if (nextArea === 0) {
90
+ onClose();
91
+ return;
92
+ }
93
+ if (nextArea) {
94
+ setActiveArea(nextArea);
95
+ setSheetOffset(lastMagneticArea - nextArea);
96
+ }
97
+ };
98
+ var magnetize = function (dir, velocity, deltaY) {
99
+ var shouldMagnetizeDownByVelocity = dir === 'Down' && velocity >= utils.SWIPE_VELOCITY;
100
+ var shouldMagnetizeUpByVelocity = dir === 'Up' && velocity >= utils.SWIPE_VELOCITY;
101
+ if (shouldMagnetizeDownByVelocity) {
102
+ var nextArea_1 = magneticAreas
103
+ .slice()
104
+ .reverse()
105
+ .find(function (area) { return area < activeArea; });
106
+ if (nextArea_1 === 0) {
107
+ onClose();
108
+ return;
109
+ }
110
+ var offset_1 = nextArea_1
111
+ ? lastMagneticArea - nextArea_1
112
+ : lastMagneticArea - activeArea;
113
+ setSheetOffset(offset_1);
114
+ setActiveArea(function (prevState) { return nextArea_1 !== null && nextArea_1 !== void 0 ? nextArea_1 : prevState; });
115
+ return;
116
+ }
117
+ if (shouldMagnetizeUpByVelocity) {
118
+ var nextArea_2 = magneticAreas.find(function (area) { return area > activeArea; });
119
+ var offset_2 = nextArea_2 ? lastMagneticArea - nextArea_2 : 0;
120
+ setSheetOffset(offset_2);
121
+ setActiveArea(function (prevState) { return nextArea_2 !== null && nextArea_2 !== void 0 ? nextArea_2 : prevState; });
122
+ return;
123
+ }
124
+ var offset = getSheetOffset(deltaY);
125
+ var currentSheetHeight = lastMagneticArea - offset;
126
+ var secondArea = magneticAreas[1];
127
+ var isSecondArea = activeArea === secondArea;
128
+ var canClose = magneticAreas[0] === 0 && dir === 'Down';
129
+ var shouldCloseByOffset = isSecondArea && canClose && 1 - currentSheetHeight / activeArea > utils.CLOSE_OFFSET;
130
+ if (shouldCloseByOffset) {
131
+ onClose();
132
+ return;
133
+ }
134
+ var nearestArea = magneticAreas.reduceRight(function (res, area) {
135
+ if (Math.abs(area - currentSheetHeight) < res.minOffset) {
136
+ res.minOffset = area - currentSheetHeight;
137
+ res.nearestArea = area;
138
+ }
139
+ return res;
140
+ }, {
141
+ nearestArea: lastMagneticArea,
142
+ minOffset: lastMagneticArea,
143
+ }).nearestArea;
144
+ if (nearestArea === 0) {
145
+ onClose();
146
+ }
147
+ else {
148
+ setSheetOffset(lastMagneticArea - nearestArea);
149
+ setActiveArea(nearestArea);
150
+ setBackdropOpacity(1);
151
+ }
152
+ };
153
+ /**
154
+ * Если контент внутри шторки скроллится - то шторка не должна свайпаться
155
+ * Если шапка внутри шторки зафиксирована - то шторка должна свайпаться только в области шапки
156
+ */
157
+ var shouldSkipSwiping = function (dir, startY) {
158
+ if (!swipeable)
159
+ return true;
160
+ if (scrollLockedProp || swipingInProgress.current)
161
+ return false;
162
+ var scrollableNode = scrollableContainer.current;
163
+ // Точка верхней границы (y координата)
164
+ var bottomSheetTopY = fullHeight - sheetHeight.current;
165
+ if (!scrollableNode ||
166
+ (!stickyHeader && Math.abs(bottomSheetTopY - startY) <= utils.MARKER_HEIGHT) ||
167
+ (stickyHeader &&
168
+ headerRef.current &&
169
+ Math.abs(bottomSheetTopY - startY) <= headerRef.current.clientHeight)) {
170
+ return false;
171
+ }
172
+ return dir === 'Down'
173
+ ? scrollableNode.scrollTop > 0
174
+ : scrollableNode.scrollHeight -
175
+ scrollableNode.scrollTop -
176
+ scrollableNode.clientHeight >
177
+ utils.SCROLL_OFFSET;
178
+ };
179
+ var handleSheetSwipe = function (_a) {
180
+ var dir = _a.dir, initial = _a.initial, velocity = _a.velocity, deltaY = _a.deltaY;
181
+ if (shouldSkipSwiping(dir, initial[1])) {
182
+ return;
183
+ }
184
+ magnetize(dir, velocity, deltaY);
185
+ };
186
+ var handleSheetSwipeStart = function (_a) {
187
+ var dir = _a.dir, initial = _a.initial;
188
+ if (shouldSkipSwiping(dir, initial[1])) {
189
+ return;
190
+ }
191
+ swipingInProgress.current = true;
192
+ };
193
+ var handleSheetSwiped = function () {
194
+ swipingInProgress.current = false;
195
+ };
196
+ var handleSheetSwiping = function (_a) {
197
+ var initial = _a.initial, deltaY = _a.deltaY, dir = _a.dir;
198
+ if (shouldSkipSwiping(dir, initial[1])) {
199
+ return;
200
+ }
201
+ var offset = getSheetOffset(deltaY);
202
+ var opacity = getBackdropOpacity(offset);
203
+ setSheetOffset(offset);
204
+ setBackdropOpacity(opacity);
205
+ };
206
+ var sheetSwipeableHandlers = reactSwipeable.useSwipeable({
207
+ onSwipeStart: handleSheetSwipeStart,
208
+ onSwiping: handleSheetSwiping,
209
+ onSwipedDown: handleSheetSwipe,
210
+ onSwipedUp: handleSheetSwipe,
211
+ onSwiped: handleSheetSwiped,
212
+ trackMouse: swipeable,
213
+ delta: 5,
214
+ });
215
+ var handleExited = function (node) {
216
+ var idx = initialActiveAreaIndex;
217
+ setBackdropOpacity(1);
218
+ setSheetOffset(hasInitialIdx ? lastMagneticArea - magneticAreas[idx] : magneticAreas[0]);
219
+ setActiveArea(hasInitialIdx ? magneticAreas[idx] : lastMagneticArea);
220
+ if (transitionProps.onExited) {
221
+ transitionProps.onExited(node);
222
+ }
223
+ };
224
+ var handleEntered = function (node, isAppearing) {
225
+ setBackdropOpacity(1);
226
+ setSheetHeight();
227
+ if (transitionProps.onEntered) {
228
+ transitionProps.onEntered(node, isAppearing);
229
+ }
230
+ };
231
+ React.useEffect(function () {
232
+ onMagnetize === null || onMagnetize === void 0 ? void 0 : onMagnetize(open ? getActiveAreaIndex(activeArea) : 0);
233
+ // eslint-disable-next-line react-hooks/exhaustive-deps
234
+ }, [activeArea, open]);
235
+ React.useImperativeHandle(bottomSheetInstanceRef, function () { return ({
236
+ scrollToArea: scrollToArea,
237
+ }); });
238
+ var getSwipeStyles = function () { return ({
239
+ transform: sheetOffset ? "translateY(".concat(sheetOffset, "px)") : '',
240
+ }); };
241
+ var getHeightStyles = function () { return ({
242
+ height: initialHeight === 'full' ? "".concat(lastMagneticArea, "px") : 'unset',
243
+ maxHeight: "".concat(lastMagneticArea, "px"),
244
+ }); };
245
+ var bgClassName = backgroundColor && styles__default.default["background-".concat(backgroundColor)];
246
+ return (React__default.default.createElement(coreComponentsBaseModal.BaseModal, { open: open, ref: ref, container: container, dataTestId: dataTestId, zIndex: zIndex, onClose: onClose, 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 = {},
247
+ _b[styles__default.default.disabledPointerEvents] = hideOverlay,
248
+ _b)), disableBlockingScroll: disableBlockingScroll, transitionProps: tslib.__assign(tslib.__assign({ appear: true, timeout: utils.TIMEOUT, classNames: styles__default.default }, transitionProps), { onExited: handleExited, onEntered: handleEntered }) },
249
+ React__default.default.createElement("div", { style: tslib.__assign({}, getHeightStyles()), className: styles__default.default.wrapper, onTransitionEnd: setSheetHeight },
250
+ React__default.default.createElement("div", tslib.__assign({ className: cn__default.default(styles__default.default.component, bgClassName, className, (_c = {},
251
+ _c[styles__default.default.withTransition] = !swipingInProgress.current,
252
+ _c)), style: tslib.__assign(tslib.__assign({}, getSwipeStyles()), getHeightStyles()) }, sheetSwipeableHandlers, { ref: mergeRefs__default.default([sheetRef, sheetContainerRef, sheetSwipeableHandlers.ref]), onTransitionEnd: setSheetHeight }),
253
+ 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 = {},
254
+ _d[styles__default.default.scrollLocked] = scrollLockedProp || swipingInProgress.current,
255
+ _d[styles__default.default.hiddenScrollbar] = hideScrollbar,
256
+ _d)), ref: mergeRefs__default.default([scrollableContainer, scrollableContainerRef]) }),
257
+ swipeable && React__default.default.createElement("div", { className: cn__default.default(styles__default.default.marker) }),
258
+ !hideHeader && !emptyHeader && React__default.default.createElement(components_header_Component.Header, tslib.__assign({}, headerProps)),
259
+ React__default.default.createElement("div", { className: cn__default.default(styles__default.default.content, contentClassName, (_e = {},
260
+ _e[styles__default.default.noHeader] = hideHeader || emptyHeader,
261
+ _e[styles__default.default.noFooter] = !actionButton,
262
+ _e)) }, children),
263
+ actionButton && (React__default.default.createElement(components_footer_Component.Footer, { sticky: stickyFooter, className: cn__default.default(bgClassName, footerClassName) }, actionButton)))))));
264
+ });
22
265
 
23
- exports.BottomSheet = components_header_Component.BottomSheet;
24
- exports.CLOSE_OFFSET = components_header_Component.CLOSE_OFFSET;
25
- exports.HEADER_OFFSET = components_header_Component.HEADER_OFFSET;
266
+ exports.BottomSheet = BottomSheet;
@@ -0,0 +1,7 @@
1
+ import { FC, RefObject } from 'react';
2
+ import { NavigationBarProps } from "@alfalab/core-components-navigation-bar";
3
+ type HeaderProps = Omit<NavigationBarProps, 'view' | 'size'> & {
4
+ headerRef: RefObject<HTMLDivElement>;
5
+ };
6
+ declare const Header: FC<HeaderProps>;
7
+ export { HeaderProps, Header };
@@ -2,22 +2,36 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- require('tslib');
6
- require('react');
7
- require('classnames');
8
- require('@alfalab/core-components-base-modal/cssm');
9
- require('@alfalab/core-components-navigation-bar/cssm');
10
- var components_header_Component = require('../../component-517950e0.js');
11
- require('./index.module.css');
12
- require('react-div-100vh');
13
- require('react-merge-refs');
14
- require('react-swipeable');
15
- require('../footer/Component.js');
16
- require('../footer/index.module.css');
17
- require('../swipeable-backdrop/Component.js');
18
- require('@alfalab/core-components-backdrop/cssm');
19
- require('../../index.module.css');
5
+ var tslib = require('tslib');
6
+ var React = require('react');
7
+ var cn = require('classnames');
8
+ var coreComponentsBaseModal = require('@alfalab/core-components-base-modal/cssm');
9
+ var coreComponentsNavigationBar = require('@alfalab/core-components-navigation-bar/cssm');
10
+ var utils = require('../../utils.js');
11
+ var styles = require('./index.module.css');
20
12
 
13
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
21
14
 
15
+ var React__default = /*#__PURE__*/_interopDefaultCompat(React);
16
+ var cn__default = /*#__PURE__*/_interopDefaultCompat(cn);
17
+ var styles__default = /*#__PURE__*/_interopDefaultCompat(styles);
22
18
 
23
- exports.Header = components_header_Component.Header;
19
+ var Header = function (_a) {
20
+ 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"]);
22
+ var _c = React.useContext(coreComponentsBaseModal.BaseModalContext), setHeaderOffset = _c.setHeaderOffset, setHasHeader = _c.setHasHeader, headerHighlighted = _c.headerHighlighted, onClose = _c.onClose;
23
+ React.useEffect(function () {
24
+ setHeaderOffset(utils.HEADER_OFFSET);
25
+ }, [setHeaderOffset]);
26
+ React.useEffect(function () {
27
+ setHasHeader(true);
28
+ }, [setHasHeader]);
29
+ var hasContent = Boolean(title || children);
30
+ return (React__default.default.createElement(coreComponentsNavigationBar.NavigationBar, tslib.__assign({}, restProps, { ref: headerRef, title: title, onClose: onClose, sticky: sticky, view: 'mobile', className: cn__default.default(styles__default.default.headerWrapper, className, (_b = {},
31
+ _b[styles__default.default.highlighted] = hasContent && headerHighlighted && sticky,
32
+ _b[styles__default.default.sticky] = sticky,
33
+ _b[styles__default.default.hasContent] = hasContent,
34
+ _b)), contentClassName: cn__default.default(styles__default.default.title) }), children));
35
+ };
36
+
37
+ exports.Header = Header;
@@ -1,5 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { SwipeableHandlers } from 'react-swipeable/types';
2
+ import { SwipeableHandlers } from 'react-swipeable';
3
3
  import { BackdropProps } from "@alfalab/core-components-backdrop";
4
4
  type SwipeableBackdropProps = BackdropProps & {
5
5
  /**
package/cssm/index.d.ts CHANGED
@@ -1 +1,3 @@
1
- export * from "./component-517950e0";
1
+ export * from "./component";
2
+ export type { BottomSheetProps, BottomSheetTitleAlign } from "./types";
3
+ export { CLOSE_OFFSET, HEADER_OFFSET } from "./utils";
package/cssm/index.js CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var components_header_Component = require('./component-517950e0.js');
5
+ var component = require('./component.js');
6
+ var utils = require('./utils.js');
6
7
  require('tslib');
7
8
  require('react');
8
9
  require('react-div-100vh');
@@ -12,14 +13,15 @@ require('classnames');
12
13
  require('@alfalab/core-components-base-modal/cssm');
13
14
  require('./components/footer/Component.js');
14
15
  require('./components/footer/index.module.css');
16
+ require('./components/header/Component.js');
15
17
  require('@alfalab/core-components-navigation-bar/cssm');
18
+ require('./components/header/index.module.css');
16
19
  require('./components/swipeable-backdrop/Component.js');
17
20
  require('@alfalab/core-components-backdrop/cssm');
18
21
  require('./index.module.css');
19
- require('./components/header/index.module.css');
20
22
 
21
23
 
22
24
 
23
- exports.BottomSheet = components_header_Component.BottomSheet;
24
- exports.CLOSE_OFFSET = components_header_Component.CLOSE_OFFSET;
25
- exports.HEADER_OFFSET = components_header_Component.HEADER_OFFSET;
25
+ exports.BottomSheet = component.BottomSheet;
26
+ exports.CLOSE_OFFSET = utils.CLOSE_OFFSET;
27
+ exports.HEADER_OFFSET = utils.HEADER_OFFSET;
@@ -42,23 +42,29 @@
42
42
  } :root {
43
43
  } :root {
44
44
  } :root {
45
- --bottom-sheet-in-transition: 0.5s cubic-bezier(0.09, 0.91, 0.18, 0.99);
46
- --bottom-sheet-out-transition: 0.3s ease;
45
+ --bottom-sheet-in-transition: transform 0.5s cubic-bezier(0.09, 0.91, 0.18, 0.99);
46
+ --bottom-sheet-out-transition: transform 0.3s ease;
47
47
  } .modal {
48
48
  background-color: transparent;
49
49
  position: fixed;
50
50
  bottom: 0;
51
51
  width: 100%;
52
52
  max-width: 600px;
53
+ pointer-events: none;
54
+ } .wrapper {
55
+ transform: translateY(100%);
56
+ overflow: hidden;
57
+ pointer-events: none;
58
+ border-top-right-radius: var(--border-radius-xl);
59
+ border-top-left-radius: var(--border-radius-xl);
53
60
  } .component {
54
61
  overflow: hidden;
55
62
  position: relative;
56
63
  display: flex;
57
64
  flex-direction: column;
58
- border-top-right-radius: var(--border-radius-xl);
59
- border-top-left-radius: var(--border-radius-xl);
65
+ border-radius: inherit;
60
66
  background-color: var(--color-light-bg-primary);
61
- transform: translateY(100%);
67
+ pointer-events: all;
62
68
  } .withTransition {
63
69
  transition: var(--bottom-sheet-out-transition);
64
70
  } .scrollableContainer {
@@ -93,16 +99,23 @@
93
99
  padding-bottom: var(--gap-m);
94
100
  } .scrollLocked {
95
101
  overflow: hidden;
96
- } .appear .component, .enter .component {
102
+ } .hiddenScrollbar {
103
+ scrollbar-width: none
104
+ } .hiddenScrollbar::-webkit-scrollbar {
105
+ width: 0;
106
+ height: 0;
107
+ } .disabledPointerEvents {
108
+ pointer-events: none;
109
+ } .appear .wrapper, .enter .wrapper {
97
110
  transition: none;
98
- } .appearActive .component, .enterActive .component {
111
+ } .appearActive .wrapper, .enterActive .wrapper {
99
112
  transition: var(--bottom-sheet-in-transition);
100
113
  transform: translateY(0);
101
- } .enterDone .component, .appearDone .component {
114
+ } .enterDone .wrapper, .appearDone .wrapper {
102
115
  transform: translateY(0);
103
- } .exit .component {
116
+ } .exit .wrapper {
104
117
  transform: translateY(0);
105
- } .exitActive .component {
118
+ } .exitActive .wrapper {
106
119
  transition: var(--bottom-sheet-out-transition);
107
120
  transform: translateY(100%);
108
121
  } .background-accent {
@@ -1,18 +1,9 @@
1
1
  /// <reference types="react-transition-group" />
2
- /// <reference types="react" />
3
- import React from "react";
4
- import { FC, HTMLAttributes, ReactNode, RefObject } from "react";
5
- import { NavigationBarProps } from "@alfalab/core-components-navigation-bar";
2
+ import { HTMLAttributes, ReactNode, RefObject } from 'react';
6
3
  import { TransitionProps } from 'react-transition-group/Transition';
7
4
  import { BaseModalProps } from "@alfalab/core-components-base-modal";
8
- type HeaderProps = Omit<NavigationBarProps, "view" | "size">;
9
- declare const Header: FC<HeaderProps>;
10
- declare const getDataTestId: (dataTestId?: string, element?: string) => string | undefined;
5
+ import { NavigationBarProps } from "@alfalab/core-components-navigation-bar";
11
6
  type BackgroundColorType = "accent" | "info" | "attention-muted" | "positive-muted" | "negative-muted" | "primary" | "primary-inverted" | "secondary" | "secondary-inverted" | "tertiary" | "tertiary-inverted" | "quaternary" | "quaternary-inverted" | "specialbg-component" | "specialbg-component-inverted" | "specialbg-primary-grouped" | "specialbg-secondary-grouped" | "specialbg-tertiary-grouped" | "specialbg-secondary-transparent" | "specialbg-secondary-transparent-inverted" | "specialbg-tertiary-transparent" | "specialbg-tertiary-transparent-inverted";
12
- type BorderColorType = "accent" | "key" | "key-inverted" | "link" | "primary" | "primary-inverted" | "secondary" | "secondary-inverted" | "tertiary" | "tertiary-inverted" | "underline" | "underline-inverted" | "graphic-attention" | "graphic-link" | "graphic-negative" | "graphic-positive" | "specialbg-secondary-transparent" | "specialbg-secondary-transparent-inverted" | "specialbg-tertiary-transparent" | "specialbg-tertiary-transparent-inverted";
13
- type ShadowType = "shadow-xs" | "shadow-s" | "shadow-m" | "shadow-l" | "shadow-xl" | "shadow-xs-hard" | "shadow-s-hard" | "shadow-m-hard" | "shadow-l-hard" | "shadow-xl-hard" | "shadow-xs-up" | "shadow-s-up" | "shadow-m-up" | "shadow-l-up" | "shadow-xl-up" | "shadow-xs-hard-up" | "shadow-s-hard-up" | "shadow-m-hard-up" | "shadow-l-hard-up" | "shadow-xl-hard-up";
14
- type GapType = "3xs" | "2xs" | "xs" | "s" | "m" | "l" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl" | "8xl";
15
- declare const isClient: () => boolean;
16
7
  type BottomSheetTitleAlign = 'center' | 'left';
17
8
  type BottomSheetProps = {
18
9
  /**
@@ -179,6 +170,35 @@ type BottomSheetProps = {
179
170
  * Реф на контейнер, в котором происходит скролл
180
171
  */
181
172
  scrollableContainerRef?: RefObject<HTMLElement>;
173
+ /**
174
+ * Реф для управления компонентом.
175
+ */
176
+ bottomSheetInstanceRef?: RefObject<{
177
+ scrollToArea: (idx: number) => void;
178
+ }>;
179
+ /**
180
+ * Реф на контейнер, в котором находится шторка
181
+ */
182
+ sheetContainerRef?: RefObject<HTMLElement>;
183
+ /**
184
+ * Магнитные области видимой высоты шторки.
185
+ * Можно использовать значения в пикселях - 10(число), либо в процентах - 10%(строка).
186
+ * По-умолчанию -[0, window.innerHeight - '24px']
187
+ * массив должен состоять минимум из 2 элементов
188
+ */
189
+ magneticAreas?: number[];
190
+ /**
191
+ * Индекс точки из magneticAreas, к которому нужно примагнититься при первом открытии шторки.
192
+ */
193
+ initialActiveAreaIndex?: number;
194
+ /**
195
+ * Отключает скролл контентной области.
196
+ */
197
+ scrollLocked?: boolean;
198
+ /**
199
+ * Скрыть скроллбар внутри шторки
200
+ */
201
+ hideScrollbar?: boolean;
182
202
  /**
183
203
  * Обработчик закрытия
184
204
  */
@@ -187,8 +207,9 @@ type BottomSheetProps = {
187
207
  * Обработчик нажатия на стрелку назад
188
208
  */
189
209
  onBack?: () => void;
210
+ /**
211
+ * Вызывается после притягивания к одной из `magneticAreas`
212
+ */
213
+ onMagnetize?: (index: number) => void;
190
214
  };
191
- declare const HEADER_OFFSET = 24;
192
- declare const CLOSE_OFFSET = 0.2;
193
- declare const BottomSheet: React.ForwardRefExoticComponent<BottomSheetProps & React.RefAttributes<HTMLDivElement>>;
194
- export { HeaderProps, Header, getDataTestId, BackgroundColorType, BorderColorType, ShadowType, GapType, isClient, BottomSheetTitleAlign, BottomSheetProps, HEADER_OFFSET, CLOSE_OFFSET, BottomSheet };
215
+ export { BottomSheetTitleAlign, BottomSheetProps };
package/cssm/types.js ADDED
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+
@@ -0,0 +1,8 @@
1
+ declare const TIMEOUT = 500;
2
+ declare const SWIPE_VELOCITY = 0.4;
3
+ declare const MARKER_HEIGHT = 24;
4
+ declare const HEADER_OFFSET = 24;
5
+ declare const CLOSE_OFFSET = 0.2;
6
+ 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 };
package/cssm/utils.js ADDED
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var TIMEOUT = 500;
6
+ var SWIPE_VELOCITY = 0.4;
7
+ var MARKER_HEIGHT = 24;
8
+ /* Верхний отступ шторки, если она открыта на максимальную высоту */
9
+ var HEADER_OFFSET = 24;
10
+ var CLOSE_OFFSET = 0.2;
11
+ var SCROLL_OFFSET = 1;
12
+ var convertPercentToNumber = function (value, fullHeight) {
13
+ var maxHeight = fullHeight - HEADER_OFFSET;
14
+ if (typeof value === 'string') {
15
+ var percent = parseFloat(value) / 100;
16
+ if (percent < 0) {
17
+ return Math.min(maxHeight, fullHeight + fullHeight * percent);
18
+ }
19
+ return Math.min(maxHeight, fullHeight * percent);
20
+ }
21
+ if (value < 0) {
22
+ return Math.max(0, fullHeight + value);
23
+ }
24
+ return Math.min(maxHeight, value);
25
+ };
26
+
27
+ exports.CLOSE_OFFSET = CLOSE_OFFSET;
28
+ exports.HEADER_OFFSET = HEADER_OFFSET;
29
+ exports.MARKER_HEIGHT = MARKER_HEIGHT;
30
+ exports.SCROLL_OFFSET = SCROLL_OFFSET;
31
+ exports.SWIPE_VELOCITY = SWIPE_VELOCITY;
32
+ exports.TIMEOUT = TIMEOUT;
33
+ exports.convertPercentToNumber = convertPercentToNumber;
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import React from 'react';
3
+ import { BottomSheetProps } from "./types";
4
+ declare const BottomSheet: React.ForwardRefExoticComponent<BottomSheetProps & React.RefAttributes<HTMLDivElement>>;
5
+ export { BottomSheet };