@alfalab/core-components-bottom-sheet 6.1.0 → 6.2.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 (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
@@ -1,221 +0,0 @@
1
- import React, { useContext, useEffect, forwardRef, useState, useRef, useCallback } from 'react';
2
- import { use100vh } from 'react-div-100vh';
3
- import mergeRefs from 'react-merge-refs';
4
- import { useSwipeable } from 'react-swipeable';
5
- import cn from 'classnames';
6
- import { BaseModalContext, BaseModal } from '@alfalab/core-components-base-modal/modern';
7
- import { Footer } from './components/footer/Component.js';
8
- import { NavigationBar } from '@alfalab/core-components-navigation-bar/modern';
9
- import { SwipeableBackdrop } from './components/swipeable-backdrop/Component.js';
10
-
11
- const getDataTestId = (dataTestId, element) => {
12
- const elementPart = element ? `-${element.toLowerCase()}` : '';
13
- return dataTestId ? `${dataTestId}${elementPart}` : undefined;
14
- };
15
-
16
- const styles$1 = {"headerWrapper":"bottom-sheet__headerWrapper_1034c","hasContent":"bottom-sheet__hasContent_1034c","header":"bottom-sheet__header_1034c","sticky":"bottom-sheet__sticky_1034c","highlighted":"bottom-sheet__highlighted_1034c","justifyEnd":"bottom-sheet__justifyEnd_1034c","addon":"bottom-sheet__addon_1034c","addonFixed":"bottom-sheet__addonFixed_1034c","title":"bottom-sheet__title_1034c","titleCenter":"bottom-sheet__titleCenter_1034c","titleLeft":"bottom-sheet__titleLeft_1034c","trimTitle":"bottom-sheet__trimTitle_1034c"};
17
- require('./components/header/index.css')
18
-
19
- const Header = ({ className, sticky, title, children, ...restProps }) => {
20
- const { setHeaderOffset, setHasHeader, headerHighlighted, onClose } = useContext(BaseModalContext);
21
- useEffect(() => {
22
- setHeaderOffset(HEADER_OFFSET);
23
- }, [setHeaderOffset]);
24
- useEffect(() => {
25
- setHasHeader(true);
26
- }, [setHasHeader]);
27
- const hasContent = Boolean(title || children);
28
- return (React.createElement(NavigationBar, { ...restProps, title: title, onClose: onClose, sticky: sticky, view: 'mobile', className: cn(styles$1.headerWrapper, className, {
29
- [styles$1.highlighted]: hasContent && headerHighlighted && sticky,
30
- [styles$1.sticky]: sticky,
31
- [styles$1.hasContent]: hasContent,
32
- }), contentClassName: cn(styles$1.title) }, children));
33
- };
34
-
35
- const styles = {"modal":"bottom-sheet__modal_sul96","component":"bottom-sheet__component_sul96","withTransition":"bottom-sheet__withTransition_sul96","scrollableContainer":"bottom-sheet__scrollableContainer_sul96","marker":"bottom-sheet__marker_sul96","content":"bottom-sheet__content_sul96","noHeader":"bottom-sheet__noHeader_sul96","noFooter":"bottom-sheet__noFooter_sul96","scrollLocked":"bottom-sheet__scrollLocked_sul96","appear":"bottom-sheet__appear_sul96","enter":"bottom-sheet__enter_sul96","appearActive":"bottom-sheet__appearActive_sul96","enterActive":"bottom-sheet__enterActive_sul96","enterDone":"bottom-sheet__enterDone_sul96","appearDone":"bottom-sheet__appearDone_sul96","exit":"bottom-sheet__exit_sul96","exitActive":"bottom-sheet__exitActive_sul96","background-accent":"bottom-sheet__background-accent_sul96","background-info":"bottom-sheet__background-info_sul96","background-attention-muted":"bottom-sheet__background-attention-muted_sul96","background-positive-muted":"bottom-sheet__background-positive-muted_sul96","background-negative-muted":"bottom-sheet__background-negative-muted_sul96","background-primary":"bottom-sheet__background-primary_sul96","background-primary-inverted":"bottom-sheet__background-primary-inverted_sul96","background-secondary":"bottom-sheet__background-secondary_sul96","background-secondary-inverted":"bottom-sheet__background-secondary-inverted_sul96","background-tertiary":"bottom-sheet__background-tertiary_sul96","background-tertiary-inverted":"bottom-sheet__background-tertiary-inverted_sul96","background-quaternary":"bottom-sheet__background-quaternary_sul96","background-quaternary-inverted":"bottom-sheet__background-quaternary-inverted_sul96","background-specialbg-component":"bottom-sheet__background-specialbg-component_sul96","background-specialbg-component-inverted":"bottom-sheet__background-specialbg-component-inverted_sul96","background-specialbg-primary-grouped":"bottom-sheet__background-specialbg-primary-grouped_sul96","background-specialbg-secondary-grouped":"bottom-sheet__background-specialbg-secondary-grouped_sul96","background-specialbg-tertiary-grouped":"bottom-sheet__background-specialbg-tertiary-grouped_sul96","background-specialbg-secondary-transparent":"bottom-sheet__background-specialbg-secondary-transparent_sul96","background-specialbg-secondary-transparent-inverted":"bottom-sheet__background-specialbg-secondary-transparent-inverted_sul96","background-specialbg-tertiary-transparent":"bottom-sheet__background-specialbg-tertiary-transparent_sul96","background-specialbg-tertiary-transparent-inverted":"bottom-sheet__background-specialbg-tertiary-transparent-inverted_sul96"};
36
- require('./index.css')
37
-
38
- const TIMEOUT = 300;
39
- const SWIPE_CLOSE_VELOCITY = 0.4;
40
- const MIN_BACKDROP_OPACITY = 0.2;
41
- const HEADER_HEIGHT = 56;
42
- const MARKET_HEIGHT = 24;
43
- /* Верхний отступ шторки, если она открыта на максимальную высоту */
44
- const HEADER_OFFSET = 24;
45
- const CLOSE_OFFSET = 0.2;
46
- const BottomSheet = forwardRef(({ open, title, container, backgroundColor, titleSize = 'default', subtitle, actionButton, contentClassName, containerClassName, containerProps, headerClassName, footerClassName, addonClassName, closerClassName, backerClassName, modalClassName, modalWrapperClassName, className, leftAddons, rightAddons, bottomAddons, hasCloser, hasBacker, titleAlign = 'left', trimTitle, stickyHeader, stickyFooter = true, initialHeight = 'default', hideOverlay, hideHeader, disableOverlayClick, disableBlockingScroll, children, zIndex, transitionProps = {}, dataTestId, swipeable = true, backdropProps, scrollableContainerRef = () => null, onClose, onBack, }, ref) => {
47
- const [sheetOffset, setSheetOffset] = useState(0);
48
- const [backdropOpacity, setBackdropOpacity] = useState(1);
49
- const [scrollLocked, setScrollLocked] = useState(false);
50
- const sheetHeight = useRef(0);
51
- const scrollableContainer = useRef(null);
52
- const scrollableContainerScrollValue = useRef(0);
53
- const emptyHeader = !hasCloser && !leftAddons && !title && !hasBacker && !rightAddons;
54
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
55
- const fullHeight = use100vh();
56
- const targetHeight = `${fullHeight - HEADER_OFFSET}px`;
57
- const titleIsReactElement = React.isValidElement(title);
58
- const headerProps = {
59
- ...(titleIsReactElement
60
- ? { children: title }
61
- : { title: title ? title?.toString() : undefined }),
62
- scrollableParentRef: scrollableContainer,
63
- className: headerClassName,
64
- addonClassName,
65
- closerClassName,
66
- backButtonClassName: backerClassName,
67
- leftAddons,
68
- rightAddons,
69
- bottomAddons,
70
- hasCloser,
71
- hasBackButton: hasBacker,
72
- align: titleAlign,
73
- trim: trimTitle,
74
- sticky: stickyHeader,
75
- dataTestId: getDataTestId(dataTestId, 'header'),
76
- onBack,
77
- titleSize,
78
- subtitle,
79
- onClose,
80
- };
81
- const getBackdropOpacity = (offset) => {
82
- if (sheetHeight.current === 0)
83
- return MIN_BACKDROP_OPACITY;
84
- const opacity = 1 - (1 - MIN_BACKDROP_OPACITY) * (offset / sheetHeight.current);
85
- return Number(opacity.toFixed(2));
86
- };
87
- const getSheetOffset = (deltaY) => {
88
- let offset = deltaY > 0 ? 0 : -deltaY;
89
- offset -= scrollableContainerScrollValue.current;
90
- return Math.floor(Math.max(0, offset));
91
- };
92
- /**
93
- * Если контент внутри шторки скроллится - то шторка не должна свайпаться
94
- * Если шапка внутри шторки зафиксирована - то шторка должна свайпаться только в области шапки
95
- */
96
- const shouldSkipSwiping = (offsetY) => {
97
- if (!swipeable)
98
- return true;
99
- if (!scrollableContainer.current ||
100
- (stickyHeader && offsetY <= HEADER_HEIGHT + HEADER_OFFSET) ||
101
- (!stickyHeader && offsetY <= MARKET_HEIGHT + HEADER_OFFSET)) {
102
- return false;
103
- }
104
- if (!scrollableContainerScrollValue.current) {
105
- scrollableContainerScrollValue.current = Math.floor(scrollableContainer.current.scrollTop);
106
- }
107
- return scrollableContainer.current.scrollTop > 0;
108
- };
109
- const handleBackdropSwipedDown = ({ velocity }) => {
110
- if (velocity > SWIPE_CLOSE_VELOCITY) {
111
- onClose();
112
- }
113
- };
114
- const handleSheetSwipedDown = ({ velocity, initial }) => {
115
- const offsetY = initial[1];
116
- if (shouldSkipSwiping(offsetY)) {
117
- return;
118
- }
119
- const shouldClose = sheetOffset > sheetHeight.current * CLOSE_OFFSET || velocity > SWIPE_CLOSE_VELOCITY;
120
- if (shouldClose) {
121
- onClose();
122
- }
123
- else {
124
- setSheetOffset(0);
125
- setBackdropOpacity(1);
126
- }
127
- };
128
- const handleSheetSwiped = () => {
129
- setScrollLocked(false);
130
- scrollableContainerScrollValue.current = 0;
131
- };
132
- const handleSheetSwiping = ({ deltaY, initial }) => {
133
- const offsetY = initial[1];
134
- if (shouldSkipSwiping(offsetY)) {
135
- return;
136
- }
137
- const offset = getSheetOffset(deltaY);
138
- const opacity = getBackdropOpacity(offset);
139
- setSheetOffset(offset);
140
- setBackdropOpacity(opacity);
141
- /**
142
- * Если шторка начинает свайпаться, то блокируем скролл внутри нее
143
- */
144
- if (offset > 0) {
145
- setScrollLocked(true);
146
- }
147
- };
148
- const backdropSwipeablehandlers = useSwipeable({
149
- onSwipedDown: handleBackdropSwipedDown,
150
- delta: 100,
151
- trackMouse: swipeable,
152
- });
153
- const sheetSwipeablehandlers = useSwipeable({
154
- onSwiping: handleSheetSwiping,
155
- onSwipedDown: handleSheetSwipedDown,
156
- onSwiped: handleSheetSwiped,
157
- delta: 5,
158
- trackMouse: swipeable,
159
- });
160
- const handleExited = useCallback((node) => {
161
- setBackdropOpacity(1);
162
- if (transitionProps.onExited) {
163
- transitionProps.onExited(node);
164
- }
165
- }, [transitionProps]);
166
- const handleEntered = useCallback((node, isAppearing) => {
167
- if (!sheetHeight.current) {
168
- sheetHeight.current = node.getBoundingClientRect().height;
169
- }
170
- setBackdropOpacity(1);
171
- if (transitionProps.onEntered) {
172
- transitionProps.onEntered(node, isAppearing);
173
- }
174
- }, [transitionProps]);
175
- useEffect(() => {
176
- if (!open) {
177
- setSheetOffset(0);
178
- }
179
- }, [open]);
180
- const getSwipeStyles = () => ({
181
- transform: sheetOffset ? `translateY(${sheetOffset}px)` : '',
182
- });
183
- const getHeightStyles = () => ({
184
- height: initialHeight === 'full' ? targetHeight : 'unset',
185
- maxHeight: targetHeight,
186
- });
187
- const bgClassName = backgroundColor && styles[`background-${backgroundColor}`];
188
- return (React.createElement(BaseModal, { open: open, ref: ref, container: container, dataTestId: dataTestId, zIndex: zIndex, onClose: onClose, scrollHandler: scrollableContainer, Backdrop: SwipeableBackdrop, backdropProps: {
189
- ...backdropProps,
190
- opacity: backdropOpacity,
191
- handlers: swipeable ? backdropSwipeablehandlers : false,
192
- opacityTimeout: TIMEOUT,
193
- invisible: initialHeight === 'full' ? false : hideOverlay,
194
- }, disableBackdropClick: hideOverlay ? true : disableOverlayClick, className: cn(styles.modal, modalClassName), wrapperClassName: modalWrapperClassName, disableBlockingScroll: disableBlockingScroll, transitionProps: {
195
- appear: true,
196
- timeout: TIMEOUT,
197
- classNames: styles,
198
- ...transitionProps,
199
- onExited: handleExited,
200
- onEntered: handleEntered,
201
- } },
202
- React.createElement("div", { style: { ...getHeightStyles() } },
203
- React.createElement("div", { className: cn(styles.component, bgClassName, className, {
204
- [styles.withTransition]: !sheetOffset,
205
- }), style: {
206
- ...getSwipeStyles(),
207
- ...getHeightStyles(),
208
- }, ...sheetSwipeablehandlers },
209
- React.createElement("div", { ...containerProps, className: cn(styles.scrollableContainer, containerProps?.className, containerClassName, {
210
- [styles.scrollLocked]: scrollLocked,
211
- }), ref: mergeRefs([scrollableContainer, scrollableContainerRef]) },
212
- swipeable && React.createElement("div", { className: cn(styles.marker) }),
213
- !hideHeader && !emptyHeader && React.createElement(Header, { ...headerProps }),
214
- React.createElement("div", { className: cn(styles.content, contentClassName, {
215
- [styles.noHeader]: hideHeader || emptyHeader,
216
- [styles.noFooter]: !actionButton,
217
- }) }, children),
218
- actionButton && (React.createElement(Footer, { sticky: stickyFooter, className: cn(bgClassName, footerClassName) }, actionButton)))))));
219
- });
220
-
221
- export { BottomSheet as B, CLOSE_OFFSET as C, HEADER_OFFSET as H, Header as a };