@alfalab/core-components-modal 8.1.3 → 9.0.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 (156) hide show
  1. package/Component.js +6 -6
  2. package/Component.responsive.d.ts +3 -2
  3. package/Component.responsive.js +9 -7
  4. package/browser-a216f694.d.ts +6 -0
  5. package/components/content/Component.js +7 -5
  6. package/components/content/desktop.css +7 -7
  7. package/components/content/index.css +4 -4
  8. package/components/content/mobile.css +3 -3
  9. package/components/controls/Component.d.ts +29 -0
  10. package/components/controls/Component.js +32 -0
  11. package/components/controls/index.css +4 -0
  12. package/components/controls/index.d.ts +1 -0
  13. package/components/controls/index.js +15 -0
  14. package/components/footer/Component.js +8 -9
  15. package/components/footer/desktop.css +9 -9
  16. package/components/footer/index.css +9 -9
  17. package/components/footer/layout.css +17 -35
  18. package/components/footer/mobile.css +3 -3
  19. package/components/header/Component.js +7 -5
  20. package/components/header/desktop.css +16 -16
  21. package/components/header/index.css +9 -9
  22. package/components/header/mobile.css +4 -4
  23. package/cssm/Component.js +3 -3
  24. package/cssm/Component.responsive.d.ts +3 -2
  25. package/cssm/Component.responsive.js +10 -8
  26. package/cssm/browser-a216f694.d.ts +6 -0
  27. package/cssm/components/content/Component.js +4 -2
  28. package/cssm/components/controls/Component.d.ts +29 -0
  29. package/cssm/components/controls/Component.js +32 -0
  30. package/cssm/components/controls/index.d.ts +1 -0
  31. package/cssm/components/controls/index.js +16 -0
  32. package/cssm/components/controls/index.module.css +3 -0
  33. package/cssm/components/footer/Component.js +4 -3
  34. package/cssm/components/footer/index.module.css +5 -5
  35. package/cssm/components/footer/layout.module.css +8 -26
  36. package/cssm/components/header/Component.js +4 -2
  37. package/cssm/components/header/desktop.module.css +1 -1
  38. package/cssm/components/header/index.module.css +5 -5
  39. package/cssm/desktop/Component.desktop.d.ts +5 -3
  40. package/cssm/desktop/Component.desktop.js +6 -1
  41. package/cssm/desktop/index.js +5 -1
  42. package/cssm/getDataTestId-5c876d98.d.ts +2 -0
  43. package/cssm/getDataTestId-5c876d98.js +8 -0
  44. package/cssm/index-a5b021bd.d.ts +70 -0
  45. package/cssm/index.js +6 -2
  46. package/cssm/mobile/Component.mobile.d.ts +2 -0
  47. package/cssm/mobile/Component.mobile.js +6 -1
  48. package/cssm/mobile/index.js +5 -1
  49. package/cssm/typings.d.ts +5 -0
  50. package/cssm/useCustomWebkitScrollbar-a216f694.d.ts +2 -0
  51. package/desktop/Component.desktop.d.ts +5 -3
  52. package/desktop/Component.desktop.js +5 -0
  53. package/desktop/desktop.css +9 -9
  54. package/desktop/index.js +4 -0
  55. package/esm/Component.js +6 -6
  56. package/esm/Component.responsive.d.ts +3 -2
  57. package/esm/Component.responsive.js +9 -7
  58. package/esm/browser-a216f694.d.ts +6 -0
  59. package/esm/components/content/Component.js +7 -5
  60. package/esm/components/content/desktop.css +7 -7
  61. package/esm/components/content/index.css +4 -4
  62. package/esm/components/content/mobile.css +3 -3
  63. package/esm/components/controls/Component.d.ts +29 -0
  64. package/esm/components/controls/Component.js +23 -0
  65. package/esm/components/controls/index.css +4 -0
  66. package/esm/components/controls/index.d.ts +1 -0
  67. package/esm/components/controls/index.js +7 -0
  68. package/esm/components/footer/Component.js +8 -9
  69. package/esm/components/footer/desktop.css +9 -9
  70. package/esm/components/footer/index.css +9 -9
  71. package/esm/components/footer/layout.css +17 -35
  72. package/esm/components/footer/mobile.css +3 -3
  73. package/esm/components/header/Component.js +7 -5
  74. package/esm/components/header/desktop.css +16 -16
  75. package/esm/components/header/index.css +9 -9
  76. package/esm/components/header/mobile.css +4 -4
  77. package/esm/desktop/Component.desktop.d.ts +5 -3
  78. package/esm/desktop/Component.desktop.js +5 -0
  79. package/esm/desktop/desktop.css +9 -9
  80. package/esm/desktop/index.js +4 -0
  81. package/esm/getDataTestId-143c099f.d.ts +2 -0
  82. package/esm/getDataTestId-143c099f.js +6 -0
  83. package/esm/index-a5b021bd.d.ts +70 -0
  84. package/esm/index.js +5 -1
  85. package/esm/layout.module-9932f3ea.js +4 -0
  86. package/esm/mobile/Component.mobile.d.ts +2 -0
  87. package/esm/mobile/Component.mobile.js +5 -0
  88. package/esm/mobile/index.js +4 -0
  89. package/esm/mobile/mobile.css +2 -2
  90. package/esm/transitions.css +8 -8
  91. package/esm/typings.d.ts +5 -0
  92. package/esm/useCustomWebkitScrollbar-a216f694.d.ts +2 -0
  93. package/getDataTestId-2c8d1d4f.d.ts +2 -0
  94. package/getDataTestId-2c8d1d4f.js +8 -0
  95. package/index-a5b021bd.d.ts +70 -0
  96. package/index.js +5 -1
  97. package/layout.module-61746462.js +6 -0
  98. package/mobile/Component.mobile.d.ts +2 -0
  99. package/mobile/Component.mobile.js +5 -0
  100. package/mobile/index.js +4 -0
  101. package/mobile/mobile.css +2 -2
  102. package/modern/Component.js +6 -6
  103. package/modern/Component.responsive.d.ts +3 -2
  104. package/modern/Component.responsive.js +9 -7
  105. package/modern/browser-a216f694.d.ts +6 -0
  106. package/modern/components/content/Component.js +7 -5
  107. package/modern/components/content/desktop.css +7 -7
  108. package/modern/components/content/index.css +4 -4
  109. package/modern/components/content/mobile.css +3 -3
  110. package/modern/components/controls/Component.d.ts +29 -0
  111. package/modern/components/controls/Component.js +22 -0
  112. package/modern/components/controls/index.css +4 -0
  113. package/modern/components/controls/index.d.ts +1 -0
  114. package/modern/components/controls/index.js +7 -0
  115. package/modern/components/footer/Component.js +8 -9
  116. package/modern/components/footer/desktop.css +9 -9
  117. package/modern/components/footer/index.css +9 -9
  118. package/modern/components/footer/layout.css +17 -35
  119. package/modern/components/footer/mobile.css +3 -3
  120. package/modern/components/header/Component.js +7 -5
  121. package/modern/components/header/desktop.css +16 -16
  122. package/modern/components/header/index.css +9 -9
  123. package/modern/components/header/mobile.css +4 -4
  124. package/modern/desktop/Component.desktop.d.ts +5 -3
  125. package/modern/desktop/Component.desktop.js +6 -1
  126. package/modern/desktop/desktop.css +9 -9
  127. package/modern/desktop/index.js +4 -0
  128. package/modern/getDataTestId-a8aae71a.d.ts +2 -0
  129. package/modern/getDataTestId-a8aae71a.js +6 -0
  130. package/modern/index-a5b021bd.d.ts +70 -0
  131. package/modern/index.js +5 -1
  132. package/modern/layout.module-bff97609.js +4 -0
  133. package/modern/mobile/Component.mobile.d.ts +2 -0
  134. package/modern/mobile/Component.mobile.js +5 -0
  135. package/modern/mobile/index.js +4 -0
  136. package/modern/mobile/mobile.css +2 -2
  137. package/modern/transitions.css +8 -8
  138. package/modern/typings.d.ts +5 -0
  139. package/modern/useCustomWebkitScrollbar-a216f694.d.ts +2 -0
  140. package/package.json +4 -4
  141. package/src/Component.responsive.tsx +7 -13
  142. package/src/Component.tsx +6 -2
  143. package/src/components/content/Component.tsx +4 -1
  144. package/src/components/controls/Component.tsx +75 -0
  145. package/src/components/controls/index.module.css +3 -0
  146. package/src/components/controls/index.ts +1 -0
  147. package/src/components/footer/Component.tsx +4 -2
  148. package/src/components/footer/layout.module.css +8 -34
  149. package/src/components/header/Component.tsx +3 -1
  150. package/src/desktop/Component.desktop.tsx +4 -5
  151. package/src/mobile/Component.mobile.tsx +2 -0
  152. package/src/typings.ts +6 -0
  153. package/src/vars.css +7 -7
  154. package/transitions.css +8 -8
  155. package/typings.d.ts +5 -0
  156. package/useCustomWebkitScrollbar-a216f694.d.ts +2 -0
@@ -1,13 +1,17 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import { Modal } from '../Component.js';
3
3
  import { Content } from '../components/content/Component.js';
4
+ import { Controls } from '../components/controls/Component.js';
4
5
  import { Footer } from '../components/footer/Component.js';
5
6
  import { Header } from '../components/header/Component.js';
6
7
  import 'react-merge-refs';
7
8
  import 'classnames';
8
9
  import '@alfalab/core-components-base-modal/modern';
9
10
  import '../ResponsiveContext.js';
11
+ import '../getDataTestId-a8aae71a.js';
12
+ import '@alfalab/hooks';
10
13
  import '../Context.js';
14
+ import '../layout.module-bff97609.js';
11
15
  import '@alfalab/core-components-navigation-bar/modern';
12
16
 
13
17
  const ModalMobileComponent = forwardRef((props, ref) => (React.createElement(Modal, { ...props, ref: ref, view: 'mobile' })));
@@ -15,6 +19,7 @@ const ModalMobile = Object.assign(ModalMobileComponent, {
15
19
  Content,
16
20
  Header,
17
21
  Footer,
22
+ Controls: Controls,
18
23
  });
19
24
 
20
25
  export { ModalMobile };
@@ -6,7 +6,11 @@ import 'classnames';
6
6
  import '@alfalab/core-components-base-modal/modern';
7
7
  import '../ResponsiveContext.js';
8
8
  import '../components/content/Component.js';
9
+ import '../getDataTestId-a8aae71a.js';
10
+ import '@alfalab/hooks';
9
11
  import '../Context.js';
12
+ import '../components/controls/Component.js';
13
+ import '../layout.module-bff97609.js';
10
14
  import '../components/footer/Component.js';
11
15
  import '../components/header/Component.js';
12
16
  import '@alfalab/core-components-navigation-bar/modern';
@@ -1,4 +1,4 @@
1
- /* hash: 1kjid */
1
+ /* hash: 1w9p2 */
2
2
  :root {
3
3
  } /* deprecated */ :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 */
4
4
  } :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 */
@@ -27,7 +27,7 @@
27
27
  /* mobile */
28
28
 
29
29
  /* paddings */
30
- } .modal__component_o9513 {
30
+ } .modal__component_1odq1 {
31
31
  flex: 1;
32
32
  width: 100%;
33
33
  max-width: 600px;
@@ -1,24 +1,24 @@
1
- /* hash: 1sdt2 */
2
- .modal__appear_4lmkq,
3
- .modal__enter_4lmkq {
1
+ /* hash: 1gnmd */
2
+ .modal__appear_24xq3,
3
+ .modal__enter_24xq3 {
4
4
  opacity: 0;
5
5
  transform: translateY(15px);
6
6
  }
7
7
 
8
- .modal__appearActive_4lmkq,
9
- .modal__enterActive_4lmkq {
8
+ .modal__appearActive_24xq3,
9
+ .modal__enterActive_24xq3 {
10
10
  opacity: 1;
11
11
  transform: translateY(0);
12
12
  transition: opacity 200ms ease-in, transform 200ms ease-in;
13
13
  }
14
14
 
15
- .modal__exit_4lmkq {
15
+ .modal__exit_24xq3 {
16
16
  opacity: 1;
17
17
  transform: translateY(0);
18
18
  }
19
19
 
20
- .modal__exitActive_4lmkq,
21
- .modal__exitDone_4lmkq {
20
+ .modal__exitActive_24xq3,
21
+ .modal__exitDone_24xq3 {
22
22
  opacity: 0;
23
23
  transform: translateY(15px);
24
24
  transition: opacity 200ms ease-out, transform 200ms ease-out;
@@ -29,11 +29,16 @@ type ModalResponsiveProps = ModalDesktopProps & {
29
29
  * @default 1024
30
30
  */
31
31
  breakpoint?: number;
32
+ /**
33
+ * Значение по-умолчанию для хука useMatchMedia
34
+ */
35
+ defaultMatchMediaValue?: boolean | (() => boolean);
32
36
  };
33
37
  type View = 'desktop' | 'mobile';
34
38
  type TResponsiveModalContext = {
35
39
  view: View;
36
40
  size: NonNullable<ModalDesktopProps['size']>;
41
+ dataTestId?: string;
37
42
  };
38
43
  type ContentProps = {
39
44
  /**
@@ -0,0 +1,2 @@
1
+ declare function useCustomWebkitScrollbar(): boolean;
2
+ export { useCustomWebkitScrollbar };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfalab/core-components-modal",
3
- "version": "8.1.3",
3
+ "version": "9.0.1",
4
4
  "description": "Modal component",
5
5
  "keywords": [],
6
6
  "license": "MIT",
@@ -11,9 +11,9 @@
11
11
  "directory": "dist"
12
12
  },
13
13
  "dependencies": {
14
- "@alfalab/core-components-base-modal": "^5.6.0",
15
- "@alfalab/core-components-navigation-bar": "^0.6.0",
16
- "@alfalab/hooks": "^1.13.0",
14
+ "@alfalab/core-components-base-modal": "^5.7.1",
15
+ "@alfalab/core-components-navigation-bar": "^0.8.0",
16
+ "@alfalab/core-components-mq": "^4.2.0",
17
17
  "classnames": "^2.3.1",
18
18
  "react-merge-refs": "^1.1.0",
19
19
  "tslib": "^2.4.0"
@@ -1,27 +1,20 @@
1
1
  import React, { forwardRef } from 'react';
2
2
 
3
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
- import type { BaseModalProps } from '@alfalab/core-components-base-modal';
5
- import { useMedia } from '@alfalab/hooks';
3
+ import { useMatchMedia } from '@alfalab/core-components-mq';
6
4
 
7
5
  import { Content } from './components/content/Component';
6
+ import { Controls } from './components/controls';
8
7
  import { Footer } from './components/footer/Component';
9
8
  import { Header } from './components/header/Component';
10
9
  import { Modal } from './Component';
11
- import type { ModalResponsiveProps, View } from './typings';
10
+ import type { ModalResponsiveProps } from './typings';
12
11
 
13
12
  const ModalResponsiveComponent = forwardRef<HTMLDivElement, ModalResponsiveProps>(
14
- ({ children, breakpoint = 1024, ...restProps }, ref) => {
15
- const [view] = useMedia<View>(
16
- [
17
- ['mobile', `(max-width: ${breakpoint - 1}px)`],
18
- ['desktop', `(min-width: ${breakpoint}px)`],
19
- ],
20
- 'desktop',
21
- );
13
+ ({ children, breakpoint = 1024, defaultMatchMediaValue = true, ...restProps }, ref) => {
14
+ const [isDesktop] = useMatchMedia(`(min-width: ${breakpoint}px)`, defaultMatchMediaValue);
22
15
 
23
16
  return (
24
- <Modal ref={ref} {...restProps} view={view}>
17
+ <Modal ref={ref} {...restProps} view={isDesktop ? 'desktop' : 'mobile'}>
25
18
  {children}
26
19
  </Modal>
27
20
  );
@@ -32,4 +25,5 @@ export const ModalResponsive = Object.assign(ModalResponsiveComponent, {
32
25
  Header,
33
26
  Content,
34
27
  Footer,
28
+ Controls,
35
29
  });
package/src/Component.tsx CHANGED
@@ -22,6 +22,7 @@ export const Modal = forwardRef<HTMLDivElement, ModalDesktopProps & { view: View
22
22
  wrapperClassName,
23
23
  transitionProps = {},
24
24
  view,
25
+ dataTestId,
25
26
  ...restProps
26
27
  },
27
28
  ref,
@@ -81,11 +82,14 @@ export const Modal = forwardRef<HTMLDivElement, ModalDesktopProps & { view: View
81
82
  className: cn(className, mobileStyles.component),
82
83
  };
83
84
 
84
- const contextValue = useMemo(() => ({ size: componentSize, view }), [componentSize, view]);
85
+ const contextValue = useMemo(
86
+ () => ({ size: componentSize, view, dataTestId }),
87
+ [componentSize, view, dataTestId],
88
+ );
85
89
 
86
90
  return (
87
91
  <ResponsiveContext.Provider value={contextValue}>
88
- <BaseModal {...restProps} {...baseModalProps}>
92
+ <BaseModal {...restProps} {...baseModalProps} dataTestId={dataTestId}>
89
93
  {children}
90
94
  </BaseModal>
91
95
  </ResponsiveContext.Provider>
@@ -1,6 +1,8 @@
1
1
  import React, { FC, Ref, useContext } from 'react';
2
2
  import cn from 'classnames';
3
3
 
4
+ import { getDataTestId } from '@alfalab/core-components-shared';
5
+
4
6
  import { ModalContext } from '../../Context';
5
7
  import { ResponsiveContext } from '../../ResponsiveContext';
6
8
  import { ContentProps } from '../../typings';
@@ -11,7 +13,7 @@ import mobileStyles from './mobile.module.css';
11
13
 
12
14
  export const Content: FC<ContentProps> = ({ children, flex, className }) => {
13
15
  const { contentRef, hasHeader } = useContext(ModalContext);
14
- const { size, view } = useContext(ResponsiveContext);
16
+ const { size, view, dataTestId } = useContext(ResponsiveContext);
15
17
 
16
18
  return (
17
19
  <div
@@ -22,6 +24,7 @@ export const Content: FC<ContentProps> = ({ children, flex, className }) => {
22
24
  [mobileStyles.content]: view === 'mobile',
23
25
  })}
24
26
  ref={contentRef as Ref<HTMLDivElement>}
27
+ data-test-id={getDataTestId(dataTestId, 'content')}
25
28
  >
26
29
  {children}
27
30
  </div>
@@ -0,0 +1,75 @@
1
+ import React, { ReactNode, useContext } from 'react';
2
+ import cn from 'classnames';
3
+
4
+ import { getDataTestId } from '@alfalab/core-components-shared';
5
+
6
+ import { ResponsiveContext } from '../../ResponsiveContext';
7
+
8
+ import layoutStyles from '../footer/layout.module.css';
9
+ import styles from './index.module.css';
10
+
11
+ export interface ControlsProps {
12
+ /**
13
+ * Основной слот
14
+ */
15
+ primary?: ReactNode;
16
+
17
+ /**
18
+ * Дополнительный слот
19
+ */
20
+ secondary?: ReactNode;
21
+
22
+ /**
23
+ * Выравнивание элементов футера
24
+ * @default start
25
+ */
26
+ layout?: 'start' | 'center' | 'space-between' | 'column';
27
+
28
+ /**
29
+ * Выравнивание элементов футера (мобильный view)
30
+ * @default start
31
+ */
32
+ mobileLayout?: 'start' | 'center' | 'space-between' | 'column';
33
+
34
+ /**
35
+ * Отступы между элементами футера
36
+ */
37
+ gap?: 16 | 24 | 32;
38
+ }
39
+
40
+ export const Controls: React.FC<ControlsProps> = ({
41
+ primary,
42
+ secondary,
43
+ gap = 16,
44
+ layout: layoutProp = 'start',
45
+ mobileLayout = layoutProp,
46
+ }) => {
47
+ const { view, dataTestId } = useContext(ResponsiveContext);
48
+
49
+ const layout = view === 'mobile' ? mobileLayout : layoutProp;
50
+
51
+ const shouldReverse = view === 'mobile' && layout !== 'column';
52
+
53
+ return (
54
+ <div
55
+ data-test-id={getDataTestId(dataTestId, 'controls')}
56
+ className={cn(
57
+ styles.component,
58
+ layoutStyles[layout],
59
+ gap && layoutStyles[`gap-${gap}`],
60
+ )}
61
+ >
62
+ {shouldReverse ? (
63
+ <React.Fragment>
64
+ {secondary}
65
+ {primary}
66
+ </React.Fragment>
67
+ ) : (
68
+ <React.Fragment>
69
+ {primary}
70
+ {secondary}
71
+ </React.Fragment>
72
+ )}
73
+ </div>
74
+ );
75
+ };
@@ -0,0 +1,3 @@
1
+ .component {
2
+ width: 100%;
3
+ }
@@ -0,0 +1 @@
1
+ export * from './Component';
@@ -1,6 +1,8 @@
1
1
  import React, { FC, ReactNode, useContext, useEffect } from 'react';
2
2
  import cn from 'classnames';
3
3
 
4
+ import { getDataTestId } from '@alfalab/core-components-shared';
5
+
4
6
  import { ModalContext } from '../../Context';
5
7
  import { ResponsiveContext } from '../../ResponsiveContext';
6
8
 
@@ -38,7 +40,7 @@ export type FooterProps = {
38
40
 
39
41
  export const Footer: FC<FooterProps> = ({ children, className, sticky, layout = 'start', gap }) => {
40
42
  const { footerHighlighted, setHasFooter } = useContext(ModalContext);
41
- const { size, view } = useContext(ResponsiveContext);
43
+ const { size, view, dataTestId } = useContext(ResponsiveContext);
42
44
 
43
45
  useEffect(() => {
44
46
  setHasFooter(true);
@@ -46,6 +48,7 @@ export const Footer: FC<FooterProps> = ({ children, className, sticky, layout =
46
48
 
47
49
  return (
48
50
  <div
51
+ data-test-id={getDataTestId(dataTestId, 'footer')}
49
52
  className={cn(
50
53
  styles.footer,
51
54
  className,
@@ -59,7 +62,6 @@ export const Footer: FC<FooterProps> = ({ children, className, sticky, layout =
59
62
  [desktopStyles[size]]: view === 'desktop',
60
63
  [mobileStyles.footer]: view === 'mobile',
61
64
  [mobileStyles.sticky]: view === 'mobile' && sticky,
62
- [layoutStyles[`${layout}-mobile`]]: view === 'mobile',
63
65
  },
64
66
  )}
65
67
  >
@@ -4,44 +4,23 @@
4
4
  display: flex;
5
5
  flex-direction: column;
6
6
 
7
- & > * {
7
+ & > *:not(:last-child):not(:only-child) {
8
8
  margin-bottom: var(--modal-footer-default-gap);
9
9
  }
10
10
 
11
- & > *:last-child,
12
- & > *:only-child {
13
- margin-bottom: 0;
14
- }
15
-
16
- &.gap-16 > * {
11
+ &.gap-16 > *:not(:last-child):not(:only-child) {
17
12
  margin-bottom: var(--gap-m);
18
13
  }
19
14
 
20
- &.gap-24 > * {
15
+ &.gap-24 > *:not(:last-child):not(:only-child) {
21
16
  margin-bottom: var(--gap-xl);
22
17
  }
23
18
 
24
- &.gap-32 > * {
19
+ &.gap-32 > *:not(:last-child):not(:only-child) {
25
20
  margin-bottom: var(--gap-2xl);
26
21
  }
27
22
  }
28
23
 
29
- .column-mobile {
30
- flex-direction: column-reverse;
31
-
32
- & > * {
33
- margin-bottom: 0;
34
- }
35
-
36
- & > *:last-child {
37
- margin-bottom: var(--modal-footer-default-gap);
38
- }
39
-
40
- & > *:only-child {
41
- margin-bottom: 0;
42
- }
43
- }
44
-
45
24
  .start {
46
25
  justify-content: flex-start;
47
26
  }
@@ -63,24 +42,19 @@
63
42
  .space-between {
64
43
  display: flex;
65
44
 
66
- & > * {
45
+ & > *:not(:last-child):not(:only-child) {
67
46
  margin-right: var(--modal-footer-default-gap);
68
47
  }
69
48
 
70
- & > *:last-child,
71
- & > *:only-child {
72
- margin-right: 0;
73
- }
74
-
75
- &.gap-16 > * {
49
+ &.gap-16 > *:not(:last-child):not(:only-child) {
76
50
  margin-right: var(--gap-m);
77
51
  }
78
52
 
79
- &.gap-24 > * {
53
+ &.gap-24 > *:not(:last-child):not(:only-child) {
80
54
  margin-right: var(--gap-xl);
81
55
  }
82
56
 
83
- &.gap-32 > * {
57
+ &.gap-32 > *:not(:last-child):not(:only-child) {
84
58
  margin-right: var(--gap-2xl);
85
59
  }
86
60
  }
@@ -2,6 +2,7 @@ import React, { FC, useContext, useEffect } from 'react';
2
2
  import cn from 'classnames';
3
3
 
4
4
  import { NavigationBar, NavigationBarProps } from '@alfalab/core-components-navigation-bar';
5
+ import { getDataTestId } from '@alfalab/core-components-shared';
5
6
 
6
7
  import { ModalContext } from '../../Context';
7
8
  import { ResponsiveContext } from '../../ResponsiveContext';
@@ -22,7 +23,7 @@ export const Header: FC<HeaderProps> = ({
22
23
  ...restProps
23
24
  }) => {
24
25
  const { setHasHeader, headerHighlighted, parentRef, onClose } = useContext(ModalContext);
25
- const { view, size } = useContext(ResponsiveContext);
26
+ const { view, size, dataTestId } = useContext(ResponsiveContext);
26
27
 
27
28
  useEffect(() => {
28
29
  setHasHeader(true);
@@ -33,6 +34,7 @@ export const Header: FC<HeaderProps> = ({
33
34
  return (
34
35
  <NavigationBar
35
36
  {...restProps}
37
+ dataTestId={getDataTestId(dataTestId, 'header')}
36
38
  scrollableParentRef={parentRef}
37
39
  hasCloser={hasCloser}
38
40
  sticky={sticky}
@@ -1,12 +1,10 @@
1
1
  import React, { forwardRef } from 'react';
2
2
 
3
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
- import type { BaseModalProps } from '@alfalab/core-components-base-modal';
5
-
6
3
  import { Modal } from '../Component';
7
4
  import { Content } from '../components/content/Component';
5
+ import { Controls, ControlsProps } from '../components/controls';
8
6
  import { Footer } from '../components/footer/Component';
9
- import { Header } from '../components/header/Component';
7
+ import { Header, HeaderProps } from '../components/header/Component';
10
8
  import type { ModalDesktopProps } from '../typings';
11
9
 
12
10
  const ModalDesktopComponent = forwardRef<HTMLDivElement, ModalDesktopProps>((props, ref) => (
@@ -15,6 +13,7 @@ const ModalDesktopComponent = forwardRef<HTMLDivElement, ModalDesktopProps>((pro
15
13
 
16
14
  export const ModalDesktop = Object.assign(ModalDesktopComponent, {
17
15
  Content,
18
- Header,
16
+ Header: Header as React.FC<Omit<HeaderProps, 'titleSize' | 'subtitle'>>,
19
17
  Footer,
18
+ Controls: Controls as React.FC<Omit<ControlsProps, 'mobileLayout'>>,
20
19
  });
@@ -2,6 +2,7 @@ import React, { forwardRef } from 'react';
2
2
 
3
3
  import { Modal } from '../Component';
4
4
  import { Content } from '../components/content/Component';
5
+ import { Controls, ControlsProps } from '../components/controls';
5
6
  import { Footer } from '../components/footer/Component';
6
7
  import { Header } from '../components/header/Component';
7
8
  import type { ModalMobileProps } from '../typings';
@@ -14,4 +15,5 @@ export const ModalMobile = Object.assign(ModalMobileComponent, {
14
15
  Content,
15
16
  Header,
16
17
  Footer,
18
+ Controls: Controls as React.FC<Omit<ControlsProps, 'mobileLayout'>>,
17
19
  });
package/src/typings.ts CHANGED
@@ -36,6 +36,11 @@ export type ModalResponsiveProps = ModalDesktopProps & {
36
36
  * @default 1024
37
37
  */
38
38
  breakpoint?: number;
39
+
40
+ /**
41
+ * Значение по-умолчанию для хука useMatchMedia
42
+ */
43
+ defaultMatchMediaValue?: boolean | (() => boolean);
39
44
  };
40
45
 
41
46
  export type View = 'desktop' | 'mobile';
@@ -43,6 +48,7 @@ export type View = 'desktop' | 'mobile';
43
48
  export type TResponsiveModalContext = {
44
49
  view: View;
45
50
  size: NonNullable<ModalDesktopProps['size']>;
51
+ dataTestId?: string;
46
52
  };
47
53
 
48
54
  export type ContentProps = {
package/src/vars.css CHANGED
@@ -3,8 +3,8 @@
3
3
  :root {
4
4
  --modal-border-radius: var(--border-radius-l);
5
5
  --modal-vertical-padding: var(--gap-3xl);
6
- --modal-header-background: var(--color-light-bg-primary);
7
- --modal-footer-background: var(--color-light-bg-primary);
6
+ --modal-header-background: var(--color-light-modal-bg-primary);
7
+ --modal-footer-background: var(--color-light-modal-bg-primary);
8
8
  --modal-footer-default-gap: var(--gap-m);
9
9
 
10
10
  /* sizes */
@@ -20,14 +20,14 @@
20
20
  --modal-s-footer-paddings: var(--gap-xl) var(--gap-3xl) var(--gap-3xl);
21
21
 
22
22
  /* scroll */
23
- --modal-header-highlight-background: var(--color-light-bg-primary);
24
- --modal-footer-highlight-background: var(--color-light-bg-primary);
25
- --modal-header-highlight-box-shadow: 0 1px 0 0 var(--color-light-border-secondary);
26
- --modal-footer-highlight-box-shadow: 0 -1px 0 0 var(--color-light-border-secondary);
23
+ --modal-header-highlight-background: var(--color-light-modal-bg-primary);
24
+ --modal-footer-highlight-background: var(--color-light-modal-bg-primary);
25
+ --modal-header-highlight-box-shadow: 0 1px 0 0 var(--color-light-neutral-300);
26
+ --modal-footer-highlight-box-shadow: 0 -1px 0 0 var(--color-light-neutral-300);
27
27
 
28
28
  /* desktop */
29
29
  --modal-s-header-desktop-content-paddings: var(--gap-s);
30
- --modal-s-header-desktop-font-size: 20px;
30
+ --modal-s-header-desktop-font-size: 22px;
31
31
  --modal-s-header-desktop-line-height: 26px;
32
32
  --modal-l-header-desktop-content-paddings: 6px var(--gap-s) var(--gap-m);
33
33
  --modal-l-header-desktop-font-size: 30px;
package/transitions.css CHANGED
@@ -1,24 +1,24 @@
1
- /* hash: 1sdt2 */
2
- .modal__appear_4lmkq,
3
- .modal__enter_4lmkq {
1
+ /* hash: 1gnmd */
2
+ .modal__appear_24xq3,
3
+ .modal__enter_24xq3 {
4
4
  opacity: 0;
5
5
  transform: translateY(15px);
6
6
  }
7
7
 
8
- .modal__appearActive_4lmkq,
9
- .modal__enterActive_4lmkq {
8
+ .modal__appearActive_24xq3,
9
+ .modal__enterActive_24xq3 {
10
10
  opacity: 1;
11
11
  transform: translateY(0);
12
12
  transition: opacity 200ms ease-in, transform 200ms ease-in;
13
13
  }
14
14
 
15
- .modal__exit_4lmkq {
15
+ .modal__exit_24xq3 {
16
16
  opacity: 1;
17
17
  transform: translateY(0);
18
18
  }
19
19
 
20
- .modal__exitActive_4lmkq,
21
- .modal__exitDone_4lmkq {
20
+ .modal__exitActive_24xq3,
21
+ .modal__exitDone_24xq3 {
22
22
  opacity: 0;
23
23
  transform: translateY(15px);
24
24
  transition: opacity 200ms ease-out, transform 200ms ease-out;
package/typings.d.ts CHANGED
@@ -29,11 +29,16 @@ type ModalResponsiveProps = ModalDesktopProps & {
29
29
  * @default 1024
30
30
  */
31
31
  breakpoint?: number;
32
+ /**
33
+ * Значение по-умолчанию для хука useMatchMedia
34
+ */
35
+ defaultMatchMediaValue?: boolean | (() => boolean);
32
36
  };
33
37
  type View = 'desktop' | 'mobile';
34
38
  type TResponsiveModalContext = {
35
39
  view: View;
36
40
  size: NonNullable<ModalDesktopProps['size']>;
41
+ dataTestId?: string;
37
42
  };
38
43
  type ContentProps = {
39
44
  /**
@@ -0,0 +1,2 @@
1
+ declare function useCustomWebkitScrollbar(): boolean;
2
+ export { useCustomWebkitScrollbar };