@alfalab/core-components-navigation-bar-private 0.1.10 → 0.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 (43) hide show
  1. package/Component.js +1 -1
  2. package/components/back-arrow-addon/Component.js +1 -1
  3. package/components/back-arrow-addon/index.css +12 -12
  4. package/components/closer/Component.js +1 -1
  5. package/components/closer/index.css +6 -6
  6. package/esm/Component.js +1 -1
  7. package/esm/components/back-arrow-addon/Component.js +1 -1
  8. package/esm/components/back-arrow-addon/index.css +12 -12
  9. package/esm/components/closer/Component.js +1 -1
  10. package/esm/components/closer/index.css +6 -6
  11. package/esm/index.css +27 -27
  12. package/index.css +27 -27
  13. package/modern/Component.js +1 -1
  14. package/modern/components/back-arrow-addon/Component.js +1 -1
  15. package/modern/components/back-arrow-addon/index.css +12 -12
  16. package/modern/components/closer/Component.js +1 -1
  17. package/modern/components/closer/index.css +6 -6
  18. package/modern/index.css +27 -27
  19. package/moderncssm/Component.d.ts +5 -0
  20. package/moderncssm/Component.js +159 -0
  21. package/moderncssm/components/back-arrow-addon/Component.d.ts +26 -0
  22. package/moderncssm/components/back-arrow-addon/Component.js +21 -0
  23. package/moderncssm/components/back-arrow-addon/index.d.ts +1 -0
  24. package/moderncssm/components/back-arrow-addon/index.js +1 -0
  25. package/moderncssm/components/back-arrow-addon/index.module.css +62 -0
  26. package/moderncssm/components/closer/Component.d.ts +35 -0
  27. package/moderncssm/components/closer/Component.js +18 -0
  28. package/moderncssm/components/closer/index.d.ts +1 -0
  29. package/moderncssm/components/closer/index.js +1 -0
  30. package/moderncssm/components/closer/index.module.css +33 -0
  31. package/moderncssm/index.d.ts +2 -0
  32. package/moderncssm/index.js +1 -0
  33. package/moderncssm/index.module.css +131 -0
  34. package/moderncssm/shared/index.d.ts +2 -0
  35. package/moderncssm/shared/index.js +2 -0
  36. package/moderncssm/types.d.ts +118 -0
  37. package/moderncssm/types.js +1 -0
  38. package/moderncssm/vars.css +7 -0
  39. package/package.json +6 -6
  40. package/src/components/back-arrow-addon/index.module.css +1 -1
  41. package/src/components/closer/index.module.css +1 -1
  42. package/src/index.module.css +1 -1
  43. package/src/vars.css +1 -1
@@ -1,4 +1,4 @@
1
- /* hash: 1vp5x */
1
+ /* hash: 1jkoy */
2
2
  :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
3
3
  } /* deprecated */ :root {
4
4
  --color-light-neutral-translucent-100: rgba(38, 55, 88, 0.06);
@@ -35,48 +35,48 @@
35
35
 
36
36
  /* back-arrow */
37
37
  --navigation-bar-back-arrow-mobile-fill: var(--color-light-neutral-translucent-700);
38
- } .navigation-bar-private__component_1dcgz {
38
+ } .navigation-bar-private__component_1sneo {
39
39
  height: 100%;
40
40
  background: var(--color-light-bg-primary-alpha-40);
41
41
  -webkit-backdrop-filter: blur(10px);
42
42
  backdrop-filter: blur(10px);
43
43
  border-radius: var(--border-radius-pill);
44
44
  min-width: 48px
45
- } .navigation-bar-private__component_1dcgz svg > path {
45
+ } .navigation-bar-private__component_1sneo svg > path {
46
46
  transition: fill 0.2s ease;
47
47
  fill: var(--color-light-neutral-translucent-1300);
48
- } .navigation-bar-private__component_1dcgz:hover svg > path {
48
+ } .navigation-bar-private__component_1sneo:hover svg > path {
49
49
  fill: var(--color-light-neutral-translucent-1300-hover);
50
- } .navigation-bar-private__component_1dcgz:active svg > path {
50
+ } .navigation-bar-private__component_1sneo:active svg > path {
51
51
  fill: var(--color-light-neutral-translucent-1300-press);
52
- } .navigation-bar-private__mobileComponent_1dcgz {
52
+ } .navigation-bar-private__mobileComponent_1sneo {
53
53
  height: 32px;
54
54
  min-width: 32px;
55
55
  margin: 0 var(--gap-8);
56
56
  -webkit-backdrop-filter: none;
57
57
  backdrop-filter: none;
58
58
  background: none;
59
- } .navigation-bar-private__flex_1dcgz {
59
+ } .navigation-bar-private__flex_1sneo {
60
60
  display: flex;
61
61
  align-items: center;
62
- } .navigation-bar-private__iconWrapper_1dcgz {
62
+ } .navigation-bar-private__iconWrapper_1sneo {
63
63
  display: inline-flex;
64
64
  align-items: center;
65
65
  justify-content: center;
66
66
  height: 48px;
67
67
  margin: 0 var(--gap-8) 0 var(--gap-12);
68
68
  border-radius: var(--border-radius-circle)
69
- } .navigation-bar-private__iconWrapper_1dcgz + .navigation-bar-private__text_1dcgz {
69
+ } .navigation-bar-private__iconWrapper_1sneo + .navigation-bar-private__text_1sneo {
70
70
  margin-right: var(--gap-12);
71
- } .navigation-bar-private__mobileWrapper_1dcgz {
71
+ } .navigation-bar-private__mobileWrapper_1sneo {
72
72
  width: 32px;
73
73
  height: 32px;
74
74
  background: var(--color-light-neutral-translucent-100);
75
75
  -webkit-backdrop-filter: blur(10px);
76
76
  backdrop-filter: blur(10px);
77
77
  margin: 0
78
- } .navigation-bar-private__mobileWrapper_1dcgz + .navigation-bar-private__text_1dcgz {
78
+ } .navigation-bar-private__mobileWrapper_1sneo + .navigation-bar-private__text_1sneo {
79
79
  margin: 0 var(--gap-12) 0 var(--gap-8);
80
- } .navigation-bar-private__mobileWrapper_1dcgz svg > path {
80
+ } .navigation-bar-private__mobileWrapper_1sneo svg > path {
81
81
  fill: var(--navigation-bar-back-arrow-mobile-fill);
82
82
  }
@@ -4,7 +4,7 @@ import { IconButton } from '@alfalab/core-components-icon-button/modern';
4
4
  import { CrossHeavyMIcon } from '@alfalab/icons-glyph/CrossHeavyMIcon';
5
5
  import { CrossMIcon } from '@alfalab/icons-glyph/CrossMIcon';
6
6
 
7
- const styles = {"closer":"navigation-bar-private__closer_1fz4f","button":"navigation-bar-private__button_1fz4f","mobile":"navigation-bar-private__mobile_1fz4f","sticky":"navigation-bar-private__sticky_1fz4f"};
7
+ const styles = {"closer":"navigation-bar-private__closer_216hm","button":"navigation-bar-private__button_216hm","mobile":"navigation-bar-private__mobile_216hm","sticky":"navigation-bar-private__sticky_216hm"};
8
8
  require('./index.css')
9
9
 
10
10
  const Closer = ({ view, className, sticky, icon = view === 'desktop' ? CrossHeavyMIcon : CrossMIcon, dataTestId, onClose, ...restProps }) => {
@@ -1,4 +1,4 @@
1
- /* hash: h3q07 */
1
+ /* hash: 1gpbm */
2
2
  :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
3
3
  } /* deprecated */ :root {
4
4
  --color-light-neutral-translucent-100: rgba(38, 55, 88, 0.06);
@@ -28,7 +28,7 @@
28
28
  --navigation-bar-closer-mobile-color: var(--color-light-neutral-translucent-700);
29
29
 
30
30
  /* back-arrow */
31
- } .navigation-bar-private__closer_1fz4f {
31
+ } .navigation-bar-private__closer_216hm {
32
32
  flex-shrink: 0;
33
33
  width: 48px;
34
34
  height: 48px;
@@ -36,17 +36,17 @@
36
36
  display: flex;
37
37
  align-items: center;
38
38
  justify-content: center;
39
- } .navigation-bar-private__button_1fz4f {
39
+ } .navigation-bar-private__button_216hm {
40
40
  background: var(--color-light-bg-primary-alpha-40);
41
41
  -webkit-backdrop-filter: blur(10px);
42
42
  backdrop-filter: blur(10px);
43
43
  color: var(--color-light-neutral-translucent-1300)
44
- } .navigation-bar-private__button_1fz4f.navigation-bar-private__mobile_1fz4f {
44
+ } .navigation-bar-private__button_216hm.navigation-bar-private__mobile_216hm {
45
45
  background: var(--color-light-neutral-translucent-100);
46
46
  color: var(--navigation-bar-closer-mobile-color);
47
- } .navigation-bar-private__button_1fz4f.navigation-bar-private__button_1fz4f {
47
+ } .navigation-bar-private__button_216hm.navigation-bar-private__button_216hm {
48
48
  border-radius: var(--border-radius-circle);
49
- } .navigation-bar-private__sticky_1fz4f {
49
+ } .navigation-bar-private__sticky_216hm {
50
50
  position: sticky;
51
51
  top: 0;
52
52
  }
package/modern/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /* hash: 1k3jt */
1
+ /* hash: 1mj0b */
2
2
  :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
3
3
  } /* deprecated */ :root {
4
4
  --color-light-text-primary: rgba(3, 3, 6, 0.88);
@@ -24,26 +24,26 @@
24
24
  --gap-12: var(--gap-s);
25
25
  } :root {
26
26
  } :root {
27
- } .navigation-bar-private__header_1ov37 {
27
+ } .navigation-bar-private__header_8xzyw {
28
28
  width: 100%;
29
29
  box-sizing: border-box;
30
30
  transition: box-shadow 0.2s ease, background 0.2s ease
31
- } .navigation-bar-private__header_1ov37.navigation-bar-private__header_1ov37.navigation-bar-private__backgroundImage_1ov37 {
31
+ } .navigation-bar-private__header_8xzyw.navigation-bar-private__header_8xzyw.navigation-bar-private__backgroundImage_8xzyw {
32
32
  background-repeat: no-repeat;
33
33
  background-position: center;
34
34
  background-size: cover;
35
- } .navigation-bar-private__mainLine_1ov37 {
35
+ } .navigation-bar-private__mainLine_8xzyw {
36
36
  display: flex;
37
37
  align-items: stretch;
38
38
  justify-content: space-between;
39
39
  z-index: 1;
40
40
  background-color: inherit;
41
- } .navigation-bar-private__mainLineSticky_1ov37 {
41
+ } .navigation-bar-private__mainLineSticky_8xzyw {
42
42
  position: sticky;
43
43
  top: 0;
44
- } .navigation-bar-private__mainLineWithImageBg_1ov37 {
44
+ } .navigation-bar-private__mainLineWithImageBg_8xzyw {
45
45
  background-color: initial;
46
- } .navigation-bar-private__content_1ov37 {
46
+ } .navigation-bar-private__content_8xzyw {
47
47
  color: var(--color-light-text-primary);
48
48
  display: flex;
49
49
  flex-flow: column nowrap;
@@ -52,27 +52,27 @@
52
52
  align-self: baseline;
53
53
  box-sizing: border-box;
54
54
  min-height: 48px
55
- } .navigation-bar-private__content_1ov37.navigation-bar-private__withBothAddons_1ov37,
56
- .navigation-bar-private__content_1ov37.navigation-bar-private__withCompactTitle_1ov37 {
55
+ } .navigation-bar-private__content_8xzyw.navigation-bar-private__withBothAddons_8xzyw,
56
+ .navigation-bar-private__content_8xzyw.navigation-bar-private__withCompactTitle_8xzyw {
57
57
  font-size: 16px;
58
58
  line-height: 20px;
59
59
  font-weight: 500;
60
60
  align-self: center;
61
61
  padding-top: var(--gap-4);
62
62
  padding-bottom: var(--gap-4)
63
- } .navigation-bar-private__content_1ov37.navigation-bar-private__withBothAddons_1ov37 > .navigation-bar-private__children_1ov37,
64
- .navigation-bar-private__content_1ov37.navigation-bar-private__withBothAddons_1ov37 > .navigation-bar-private__title_1ov37,
65
- .navigation-bar-private__content_1ov37.navigation-bar-private__withCompactTitle_1ov37 > .navigation-bar-private__children_1ov37,
66
- .navigation-bar-private__content_1ov37.navigation-bar-private__withCompactTitle_1ov37 > .navigation-bar-private__title_1ov37 {
63
+ } .navigation-bar-private__content_8xzyw.navigation-bar-private__withBothAddons_8xzyw > .navigation-bar-private__children_8xzyw,
64
+ .navigation-bar-private__content_8xzyw.navigation-bar-private__withBothAddons_8xzyw > .navigation-bar-private__title_8xzyw,
65
+ .navigation-bar-private__content_8xzyw.navigation-bar-private__withCompactTitle_8xzyw > .navigation-bar-private__children_8xzyw,
66
+ .navigation-bar-private__content_8xzyw.navigation-bar-private__withCompactTitle_8xzyw > .navigation-bar-private__title_8xzyw {
67
67
  -webkit-line-clamp: 1;
68
68
  word-break: break-all;
69
- } .navigation-bar-private__content_1ov37.navigation-bar-private__contentOnBotDesktop_1ov37.navigation-bar-private__contentOnBotDesktop_1ov37 {
69
+ } .navigation-bar-private__content_8xzyw.navigation-bar-private__contentOnBotDesktop_8xzyw.navigation-bar-private__contentOnBotDesktop_8xzyw {
70
70
  padding-top: var(--gap-12);
71
- } .navigation-bar-private__content_1ov37.navigation-bar-private__contentOnBotMobile_1ov37.navigation-bar-private__contentOnBotMobile_1ov37 {
71
+ } .navigation-bar-private__content_8xzyw.navigation-bar-private__contentOnBotMobile_8xzyw.navigation-bar-private__contentOnBotMobile_8xzyw {
72
72
  padding-top: var(--gap-12);
73
- } .navigation-bar-private__title_1ov37 {
73
+ } .navigation-bar-private__title_8xzyw {
74
74
  word-break: break-word;
75
- } .navigation-bar-private__subtitle_1ov37 {
75
+ } .navigation-bar-private__subtitle_8xzyw {
76
76
  font-size: 14px;
77
77
  line-height: 20px;
78
78
  font-weight: 400;
@@ -83,11 +83,11 @@
83
83
 
84
84
  color: var(--color-light-text-secondary);
85
85
  word-break: break-all;
86
- } .navigation-bar-private__addonsWrapper_1ov37 {
86
+ } .navigation-bar-private__addonsWrapper_8xzyw {
87
87
  display: flex;
88
- } .navigation-bar-private__rightAddons_1ov37 {
88
+ } .navigation-bar-private__rightAddons_8xzyw {
89
89
  margin-left: auto;
90
- } .navigation-bar-private__addon_1ov37 {
90
+ } .navigation-bar-private__addon_8xzyw {
91
91
  min-width: 48px;
92
92
  height: 48px;
93
93
  display: flex;
@@ -95,18 +95,18 @@
95
95
  align-items: center;
96
96
  flex-shrink: 0;
97
97
  pointer-events: all;
98
- } .navigation-bar-private__bottomAddons_1ov37 {
98
+ } .navigation-bar-private__bottomAddons_8xzyw {
99
99
  pointer-events: all;
100
- } .navigation-bar-private__closer_1ov37 {
100
+ } .navigation-bar-private__closer_8xzyw {
101
101
  margin-left: auto;
102
- } .navigation-bar-private__left_1ov37 {
102
+ } .navigation-bar-private__left_8xzyw {
103
103
  text-align: left;
104
- } .navigation-bar-private__center_1ov37 {
104
+ } .navigation-bar-private__center_8xzyw {
105
105
  text-align: center;
106
- } .navigation-bar-private__trim_1ov37 {
106
+ } .navigation-bar-private__trim_8xzyw {
107
107
  overflow: hidden
108
- } .navigation-bar-private__trim_1ov37 .navigation-bar-private__title_1ov37,
109
- .navigation-bar-private__trim_1ov37 .navigation-bar-private__children_1ov37 {
108
+ } .navigation-bar-private__trim_8xzyw .navigation-bar-private__title_8xzyw,
109
+ .navigation-bar-private__trim_8xzyw .navigation-bar-private__children_8xzyw {
110
110
  -webkit-line-clamp: 2;
111
111
  display: -webkit-box;
112
112
  -webkit-box-orient: vertical;
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ import React from 'react';
3
+ import { NavigationBarPrivateProps } from "./types";
4
+ declare const NavigationBarPrivate: React.ForwardRefExoticComponent<NavigationBarPrivateProps & React.RefAttributes<HTMLDivElement>>;
5
+ export { NavigationBarPrivate };
@@ -0,0 +1,159 @@
1
+ import React, { forwardRef, useState, useRef, useEffect } from 'react';
2
+ import mergeRefs from 'react-merge-refs';
3
+ import cn from 'classnames';
4
+ import { getDataTestId } from '@alfalab/core-components-shared/moderncssm';
5
+ import { useLayoutEffect_SAFE_FOR_SSR } from '@alfalab/hooks';
6
+ import { BackArrowAddon } from './components/back-arrow-addon/Component.js';
7
+ import { Closer } from './components/closer/Component.js';
8
+ import styles from './index.module.css';
9
+
10
+ /* eslint-disable complexity */
11
+ const ADDONS_HEIGHT = 48;
12
+ const NavigationBarPrivate = forwardRef(({ addonClassName, className, contentClassName, closerClassName, leftAddons, rightAddons, bottomAddons, bottomAddonsClassName, children, align = 'left', trim = true, title, titleSize = 'default', subtitle, hasCloser, hasBackButton, backButtonClassName, backButtonProps, dataTestId, imageUrl, closerIcon, onClose, view, scrollableParentRef, sticky, onBack, }, ref) => {
13
+ const [scrollTop, setScrollTop] = useState(0);
14
+ const [titleMargin, setTitleMargin] = useState({ left: 0, right: 0 });
15
+ const bottomContentRef = useRef(null);
16
+ const headerRef = useRef(null);
17
+ const mainLinePaddingTopRef = useRef('0px');
18
+ const leftAddonsRef = useRef(null);
19
+ const rightAddonsRef = useRef(null);
20
+ const compactTitle = view === 'mobile' && titleSize === 'compact';
21
+ const hasLeftPart = Boolean(leftAddons || hasBackButton);
22
+ const hasRightPart = Boolean(rightAddons || hasCloser);
23
+ const hasContent = Boolean(title || children);
24
+ const withAnimation = Boolean(view === 'mobile' && hasLeftPart && sticky && !compactTitle);
25
+ const showContentOnTop = hasContent && (compactTitle || !hasLeftPart);
26
+ const showContentOnBot = hasContent && !compactTitle && hasLeftPart;
27
+ const showStaticContentOnTop = !withAnimation && showContentOnTop;
28
+ const showStaticContentOnBot = !withAnimation && showContentOnBot;
29
+ const showAnimatedContentOnTop = withAnimation && showContentOnBot && scrollTop > ADDONS_HEIGHT;
30
+ const showAnimatedContentOnBot = withAnimation && showContentOnBot;
31
+ const headerPaddingTop = mainLinePaddingTopRef.current;
32
+ useLayoutEffect_SAFE_FOR_SSR(() => {
33
+ if (align === 'center' && (showStaticContentOnTop || showAnimatedContentOnTop)) {
34
+ const leftAddonsWidth = leftAddonsRef.current?.offsetWidth || 0;
35
+ const rightAddonsWidth = rightAddonsRef.current?.offsetWidth || 0;
36
+ const marginSize = Math.abs(rightAddonsWidth - leftAddonsWidth);
37
+ const shouldAddLeftMargin = rightAddonsWidth - leftAddonsWidth > 0;
38
+ setTitleMargin((prev) => {
39
+ const newState = shouldAddLeftMargin
40
+ ? { left: marginSize, right: 0 }
41
+ : { left: 0, right: marginSize };
42
+ const isStateChanged = prev.left !== newState.left || prev.right !== newState.right;
43
+ return isStateChanged ? newState : prev;
44
+ });
45
+ }
46
+ }, [
47
+ align,
48
+ showStaticContentOnTop,
49
+ showAnimatedContentOnTop,
50
+ leftAddons,
51
+ rightAddons,
52
+ hasBackButton,
53
+ hasCloser,
54
+ ]);
55
+ useEffect(() => {
56
+ const parent = scrollableParentRef?.current;
57
+ const handleScroll = (ev) => {
58
+ const divElement = ev.target;
59
+ setScrollTop(divElement.scrollTop);
60
+ };
61
+ if (withAnimation && headerRef.current) {
62
+ mainLinePaddingTopRef.current = getComputedStyle(headerRef.current).paddingTop;
63
+ }
64
+ if (withAnimation && parent) {
65
+ parent.addEventListener('scroll', handleScroll);
66
+ }
67
+ return () => parent?.removeEventListener('scroll', handleScroll);
68
+ }, [scrollableParentRef, withAnimation]);
69
+ const renderBackButton = () => {
70
+ let textOpacity = 1;
71
+ if (withAnimation) {
72
+ const height = hasContent ? ADDONS_HEIGHT : ADDONS_HEIGHT / 2;
73
+ textOpacity = Math.max(0, 1 - scrollTop / height);
74
+ }
75
+ else if (compactTitle) {
76
+ textOpacity = 0;
77
+ }
78
+ return (React.createElement("div", { className: cn(styles.addon, backButtonClassName) },
79
+ React.createElement(BackArrowAddon, { "data-test-id": getDataTestId(dataTestId, 'back-button'), ...backButtonProps, textOpacity: textOpacity, view: view, onClick: onBack })));
80
+ };
81
+ const renderContent = (args = {}) => {
82
+ const { extraClassName, wrapperRef, style, hidden } = args;
83
+ return (React.createElement("div", { style: { ...style, visibility: hidden ? 'hidden' : 'visible' }, ref: wrapperRef, className: cn(styles.content, extraClassName, contentClassName, styles[align], {
84
+ [styles.trim]: trim,
85
+ [styles.withCompactTitle]: view === 'mobile' && compactTitle && hasContent,
86
+ }), "aria-hidden": hidden },
87
+ children && React.createElement("div", { className: styles.children }, children),
88
+ title && (React.createElement("div", { className: styles.title, "data-test-id": hidden ? undefined : getDataTestId(dataTestId, 'title') }, title)),
89
+ compactTitle && subtitle && React.createElement("div", { className: styles.subtitle }, subtitle)));
90
+ };
91
+ const renderCloser = () => (React.createElement("div", { className: cn(styles.addon, styles.closer, closerClassName) },
92
+ React.createElement(Closer, { view: view, icon: closerIcon, dataTestId: getDataTestId(dataTestId, 'closer'), onClose: onClose })));
93
+ return (React.createElement("div", { ref: mergeRefs([ref, headerRef]), className: cn(styles.header, className, { [styles.backgroundImage]: imageUrl }), "data-test-id": getDataTestId(dataTestId), style: {
94
+ ...(imageUrl && { backgroundImage: `url(${imageUrl})` }),
95
+ ...(withAnimation &&
96
+ bottomContentRef.current && {
97
+ top: -bottomContentRef.current.scrollHeight,
98
+ }),
99
+ } },
100
+ React.createElement("div", { className: cn(styles.mainLine, {
101
+ [styles.mainLineSticky]: withAnimation,
102
+ [styles.mainLineWithImageBg]: imageUrl,
103
+ }), style: {
104
+ ...(withAnimation
105
+ ? {
106
+ marginTop: `-${headerPaddingTop}`,
107
+ paddingTop: headerPaddingTop,
108
+ }
109
+ : null),
110
+ } },
111
+ hasLeftPart && (React.createElement("div", { className: styles.addonsWrapper, ref: leftAddonsRef },
112
+ hasBackButton && renderBackButton(),
113
+ leftAddons && (React.createElement("div", { className: cn(styles.addon, addonClassName) }, leftAddons)))),
114
+ showStaticContentOnTop &&
115
+ renderContent({
116
+ ...(align === 'center'
117
+ ? {
118
+ style: {
119
+ marginLeft: titleMargin.left,
120
+ marginRight: titleMargin.right,
121
+ },
122
+ }
123
+ : null),
124
+ }),
125
+ showAnimatedContentOnTop &&
126
+ renderContent({
127
+ extraClassName: styles.withBothAddons,
128
+ style: {
129
+ opacity: Math.min(1, (scrollTop - ADDONS_HEIGHT) / ADDONS_HEIGHT),
130
+ ...(align === 'center'
131
+ ? {
132
+ marginLeft: titleMargin.left,
133
+ marginRight: titleMargin.right,
134
+ }
135
+ : null),
136
+ },
137
+ }),
138
+ hasRightPart && (React.createElement("div", { className: cn(styles.addonsWrapper, styles.rightAddons), ref: rightAddonsRef },
139
+ rightAddons && (React.createElement("div", { className: cn(styles.addon, addonClassName) }, rightAddons)),
140
+ hasCloser && renderCloser()))),
141
+ showAnimatedContentOnBot &&
142
+ renderContent({
143
+ wrapperRef: bottomContentRef,
144
+ extraClassName: styles.underAddons,
145
+ style: { opacity: Math.max(0, 1 - scrollTop / ADDONS_HEIGHT) },
146
+ hidden: scrollTop / ADDONS_HEIGHT > 1,
147
+ }),
148
+ showStaticContentOnBot &&
149
+ renderContent({
150
+ extraClassName: cn({
151
+ [styles.contentOnBotDesktop]: view === 'desktop',
152
+ [styles.contentOnBotMobile]: view === 'mobile',
153
+ }),
154
+ }),
155
+ bottomAddons && (React.createElement("div", { className: cn(styles.bottomAddons, bottomAddonsClassName) }, bottomAddons))));
156
+ });
157
+ NavigationBarPrivate.displayName = 'NavigationBarPrivate';
158
+
159
+ export { NavigationBarPrivate };
@@ -0,0 +1,26 @@
1
+ /// <reference types="react" />
2
+ import React from 'react';
3
+ interface BackArrowAddonProps extends React.HTMLAttributes<HTMLButtonElement> {
4
+ /**
5
+ * Текст после иконки
6
+ */
7
+ text?: string | null;
8
+ /**
9
+ * Дополнительный класс
10
+ */
11
+ className?: string;
12
+ /**
13
+ * Вид компонента
14
+ */
15
+ view: 'mobile' | 'desktop';
16
+ /**
17
+ * Прозрачность текста
18
+ */
19
+ textOpacity?: number;
20
+ /**
21
+ * Обработчик клика
22
+ */
23
+ onClick?: () => void;
24
+ }
25
+ declare const BackArrowAddon: React.FC<BackArrowAddonProps>;
26
+ export { BackArrowAddonProps, BackArrowAddon };
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import cn from 'classnames';
3
+ import { ButtonDesktop } from '@alfalab/core-components-button/moderncssm/desktop';
4
+ import { Typography } from '@alfalab/core-components-typography/moderncssm';
5
+ import { ArrowLeftMediumMIcon } from '@alfalab/icons-glyph/ArrowLeftMediumMIcon';
6
+ import { ArrowLeftMIcon } from '@alfalab/icons-glyph/ArrowLeftMIcon';
7
+ import styles from './index.module.css';
8
+
9
+ const BackArrowAddon = ({ text = 'Назад', onClick, className, textOpacity = 1, view, ...htmlAttributes }) => {
10
+ const Icon = view === 'desktop' ? ArrowLeftMediumMIcon : ArrowLeftMIcon;
11
+ const isMobileView = view === 'mobile';
12
+ return (React.createElement(ButtonDesktop, { view: 'text', size: isMobileView ? 'xxs' : 's', onClick: onClick, "aria-label": '\u043D\u0430\u0437\u0430\u0434', className: cn(styles.component, { [styles.mobileComponent]: isMobileView }, className), ...htmlAttributes },
13
+ React.createElement("div", { className: styles.flex },
14
+ React.createElement("div", { className: cn(styles.iconWrapper, {
15
+ [styles.mobileWrapper]: isMobileView,
16
+ }) },
17
+ React.createElement(Icon, null)),
18
+ textOpacity > 0 && text && (React.createElement(Typography.Text, { className: styles.text, view: view === 'desktop' ? 'primary-large' : 'component', weight: 'medium', style: { opacity: textOpacity } }, text)))));
19
+ };
20
+
21
+ export { BackArrowAddon };
@@ -0,0 +1 @@
1
+ export * from "./Component";
@@ -0,0 +1 @@
1
+ export { BackArrowAddon } from './Component.js';
@@ -0,0 +1,62 @@
1
+ /* */
2
+ :root {
3
+ /* closer-mobile */
4
+
5
+ /* back-arrow */
6
+ --navigation-bar-back-arrow-mobile-fill: var(--color-light-neutral-translucent-700);
7
+ }
8
+ .component {
9
+ height: 100%;
10
+ background: var(--color-light-bg-primary-alpha-40);
11
+ -webkit-backdrop-filter: blur(10px);
12
+ backdrop-filter: blur(10px);
13
+ border-radius: var(--border-radius-pill);
14
+ min-width: 48px
15
+ }
16
+ .component svg > path {
17
+ transition: fill 0.2s ease;
18
+ fill: var(--color-light-neutral-translucent-1300);
19
+ }
20
+ .component:hover svg > path {
21
+ fill: var(--color-light-neutral-translucent-1300-hover);
22
+ }
23
+ .component:active svg > path {
24
+ fill: var(--color-light-neutral-translucent-1300-press);
25
+ }
26
+ .mobileComponent {
27
+ height: 32px;
28
+ min-width: 32px;
29
+ margin: 0 var(--gap-8);
30
+ -webkit-backdrop-filter: none;
31
+ backdrop-filter: none;
32
+ background: none;
33
+ }
34
+ .flex {
35
+ display: flex;
36
+ align-items: center;
37
+ }
38
+ .iconWrapper {
39
+ display: inline-flex;
40
+ align-items: center;
41
+ justify-content: center;
42
+ height: 48px;
43
+ margin: 0 var(--gap-8) 0 var(--gap-12);
44
+ border-radius: var(--border-radius-circle)
45
+ }
46
+ .iconWrapper + .text {
47
+ margin-right: var(--gap-12);
48
+ }
49
+ .mobileWrapper {
50
+ width: 32px;
51
+ height: 32px;
52
+ background: var(--color-light-neutral-translucent-100);
53
+ -webkit-backdrop-filter: blur(10px);
54
+ backdrop-filter: blur(10px);
55
+ margin: 0
56
+ }
57
+ .mobileWrapper + .text {
58
+ margin: 0 var(--gap-12) 0 var(--gap-8);
59
+ }
60
+ .mobileWrapper svg > path {
61
+ fill: var(--navigation-bar-back-arrow-mobile-fill);
62
+ }
@@ -0,0 +1,35 @@
1
+ /// <reference types="react" />
2
+ import React from 'react';
3
+ import { ButtonHTMLAttributes, ElementType, FC } from "react";
4
+ interface CloserProps extends ButtonHTMLAttributes<HTMLButtonElement> {
5
+ /**
6
+ * Вид компонента
7
+ */
8
+ view: 'desktop' | 'mobile';
9
+ /**
10
+ * Дополнительный класс
11
+ */
12
+ className?: string;
13
+ /**
14
+ * Позиция крестика
15
+ */
16
+ align?: 'left' | 'right';
17
+ /**
18
+ * Фиксирует крестик
19
+ */
20
+ sticky?: boolean;
21
+ /**
22
+ * Иконка
23
+ */
24
+ icon?: ElementType;
25
+ /**
26
+ * Идентификатор для систем автоматизированного тестирования
27
+ */
28
+ dataTestId?: string;
29
+ /**
30
+ * Коллбэк закрытия.
31
+ */
32
+ onClose?: (event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, reason?: 'backdropClick' | 'escapeKeyDown' | 'closerClick') => void;
33
+ }
34
+ declare const Closer: FC<CloserProps>;
35
+ export { CloserProps, Closer };
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import cn from 'classnames';
3
+ import { IconButton } from '@alfalab/core-components-icon-button/moderncssm';
4
+ import { CrossHeavyMIcon } from '@alfalab/icons-glyph/CrossHeavyMIcon';
5
+ import { CrossMIcon } from '@alfalab/icons-glyph/CrossMIcon';
6
+ import styles from './index.module.css';
7
+
8
+ const Closer = ({ view, className, sticky, icon = view === 'desktop' ? CrossHeavyMIcon : CrossMIcon, dataTestId, onClose, ...restProps }) => {
9
+ const handleClick = (event) => {
10
+ onClose?.(event, 'closerClick');
11
+ };
12
+ return (React.createElement("div", { className: cn(styles.closer, className, {
13
+ [styles.sticky]: sticky,
14
+ }) },
15
+ React.createElement(IconButton, { size: view === 'desktop' ? 's' : 'xs', className: cn(styles.button, { [styles.mobile]: view === 'mobile' }), "aria-label": '\u0437\u0430\u043A\u0440\u044B\u0442\u044C', onClick: handleClick, icon: icon, dataTestId: dataTestId, ...restProps })));
16
+ };
17
+
18
+ export { Closer };
@@ -0,0 +1 @@
1
+ export * from "./Component";
@@ -0,0 +1 @@
1
+ export { Closer } from './Component.js';
@@ -0,0 +1,33 @@
1
+ /* */
2
+ :root {
3
+ /* closer-mobile */
4
+ --navigation-bar-closer-mobile-color: var(--color-light-neutral-translucent-700);
5
+
6
+ /* back-arrow */
7
+ }
8
+ .closer {
9
+ flex-shrink: 0;
10
+ width: 48px;
11
+ height: 48px;
12
+ margin-left: auto;
13
+ display: flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ }
17
+ .button {
18
+ background: var(--color-light-bg-primary-alpha-40);
19
+ -webkit-backdrop-filter: blur(10px);
20
+ backdrop-filter: blur(10px);
21
+ color: var(--color-light-neutral-translucent-1300)
22
+ }
23
+ .button.mobile {
24
+ background: var(--color-light-neutral-translucent-100);
25
+ color: var(--navigation-bar-closer-mobile-color);
26
+ }
27
+ .button.button {
28
+ border-radius: var(--border-radius-circle);
29
+ }
30
+ .sticky {
31
+ position: sticky;
32
+ top: 0;
33
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./Component";
2
+ export type { NavigationBarPrivateProps } from "./types";
@@ -0,0 +1 @@
1
+ export { NavigationBarPrivate } from './Component.js';