@alfalab/core-components-modal 7.0.15 → 8.0.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.
- package/Component.desktop.d.ts +0 -1
- package/Component.desktop.js +1 -2
- package/Component.js +3 -3
- package/Component.mobile.d.ts +0 -1
- package/Component.mobile.js +1 -2
- package/Component.responsive.d.ts +0 -1
- package/Component.responsive.js +1 -2
- package/components/content/Component.js +3 -3
- package/components/content/desktop.css +7 -7
- package/components/content/index.css +4 -4
- package/components/content/mobile.css +3 -3
- package/components/footer/Component.js +4 -4
- package/components/footer/desktop.css +9 -9
- package/components/footer/index.css +4 -4
- package/components/footer/layout.css +29 -29
- package/components/footer/mobile.css +3 -3
- package/components/header/Component.js +3 -3
- package/components/header/desktop.css +15 -15
- package/components/header/index.css +4 -4
- package/components/header/mobile.css +4 -4
- package/cssm/Component.desktop.d.ts +0 -1
- package/cssm/Component.desktop.js +1 -2
- package/cssm/Component.mobile.d.ts +0 -1
- package/cssm/Component.mobile.js +1 -2
- package/cssm/Component.responsive.d.ts +0 -1
- package/cssm/Component.responsive.js +1 -2
- package/cssm/desktop.d.ts +1 -1
- package/cssm/desktop.js +1 -1
- package/cssm/index.d.ts +2 -3
- package/cssm/index.js +4 -5
- package/cssm/mobile.d.ts +1 -1
- package/cssm/mobile.js +1 -1
- package/cssm/shared.d.ts +1 -0
- package/cssm/shared.js +10 -0
- package/desktop.css +9 -9
- package/desktop.d.ts +1 -1
- package/desktop.js +1 -1
- package/esm/Component.desktop.d.ts +0 -1
- package/esm/Component.desktop.js +1 -2
- package/esm/Component.js +3 -3
- package/esm/Component.mobile.d.ts +0 -1
- package/esm/Component.mobile.js +1 -2
- package/esm/Component.responsive.d.ts +0 -1
- package/esm/Component.responsive.js +1 -2
- package/esm/components/content/Component.js +3 -3
- package/esm/components/content/desktop.css +7 -7
- package/esm/components/content/index.css +4 -4
- package/esm/components/content/mobile.css +3 -3
- package/esm/components/footer/Component.js +4 -4
- package/esm/components/footer/desktop.css +9 -9
- package/esm/components/footer/index.css +4 -4
- package/esm/components/footer/layout.css +29 -29
- package/esm/components/footer/mobile.css +3 -3
- package/esm/components/header/Component.js +3 -3
- package/esm/components/header/desktop.css +15 -15
- package/esm/components/header/index.css +4 -4
- package/esm/components/header/mobile.css +4 -4
- package/esm/desktop.css +9 -9
- package/esm/desktop.d.ts +1 -1
- package/esm/desktop.js +1 -1
- package/esm/index.d.ts +2 -3
- package/esm/index.js +4 -4
- package/esm/mobile.css +2 -2
- package/esm/mobile.d.ts +1 -1
- package/esm/mobile.js +1 -1
- package/esm/shared.d.ts +1 -0
- package/esm/shared.js +2 -0
- package/esm/transitions.css +8 -8
- package/index.d.ts +2 -3
- package/index.js +4 -5
- package/mobile.css +2 -2
- package/mobile.d.ts +1 -1
- package/mobile.js +1 -1
- package/modern/Component.desktop.d.ts +0 -1
- package/modern/Component.desktop.js +1 -2
- package/modern/Component.js +3 -3
- package/modern/Component.mobile.d.ts +0 -1
- package/modern/Component.mobile.js +1 -2
- package/modern/Component.responsive.d.ts +0 -1
- package/modern/Component.responsive.js +1 -2
- package/modern/components/content/Component.js +3 -3
- package/modern/components/content/desktop.css +7 -7
- package/modern/components/content/index.css +4 -4
- package/modern/components/content/mobile.css +3 -3
- package/modern/components/footer/Component.js +4 -4
- package/modern/components/footer/desktop.css +9 -9
- package/modern/components/footer/index.css +4 -4
- package/modern/components/footer/layout.css +29 -29
- package/modern/components/footer/mobile.css +3 -3
- package/modern/components/header/Component.js +3 -3
- package/modern/components/header/desktop.css +15 -15
- package/modern/components/header/index.css +4 -4
- package/modern/components/header/mobile.css +4 -4
- package/modern/desktop.css +9 -9
- package/modern/desktop.d.ts +1 -1
- package/modern/desktop.js +1 -1
- package/modern/index.d.ts +2 -3
- package/modern/index.js +4 -4
- package/modern/mobile.css +2 -2
- package/modern/mobile.d.ts +1 -1
- package/modern/mobile.js +1 -1
- package/modern/shared.d.ts +1 -0
- package/modern/shared.js +2 -0
- package/modern/transitions.css +8 -8
- package/package.json +27 -3
- package/shared.d.ts +1 -0
- package/shared.js +10 -0
- package/src/Component.desktop.tsx +20 -0
- package/src/Component.mobile.tsx +17 -0
- package/src/Component.responsive.tsx +35 -0
- package/src/Component.tsx +93 -0
- package/src/Context.tsx +3 -0
- package/src/ResponsiveContext.tsx +8 -0
- package/src/components/content/Component.tsx +29 -0
- package/src/components/content/desktop.module.css +13 -0
- package/src/components/content/index.module.css +16 -0
- package/src/components/content/mobile.module.css +9 -0
- package/src/components/footer/Component.tsx +69 -0
- package/src/components/footer/desktop.module.css +22 -0
- package/src/components/footer/index.module.css +17 -0
- package/src/components/footer/layout.module.css +86 -0
- package/src/components/footer/mobile.module.css +9 -0
- package/src/components/header/Component.tsx +60 -0
- package/src/components/header/desktop.module.css +42 -0
- package/src/components/header/index.module.css +15 -0
- package/src/components/header/mobile.module.css +18 -0
- package/src/desktop.module.css +38 -0
- package/src/desktop.ts +2 -0
- package/src/index.ts +2 -0
- package/src/mobile.module.css +7 -0
- package/src/mobile.ts +2 -0
- package/src/shared.ts +1 -0
- package/src/transitions.module.css +24 -0
- package/src/typings.ts +63 -0
- package/src/utils.ts +90 -0
- package/src/vars.css +47 -0
- package/transitions.css +8 -8
- package/cssm/responsive.d.ts +0 -2
- package/cssm/responsive.js +0 -35
- package/esm/responsive.d.ts +0 -2
- package/esm/responsive.js +0 -14
- package/modern/responsive.d.ts +0 -2
- package/modern/responsive.js +0 -13
- package/responsive.d.ts +0 -2
- package/responsive.js +0 -22
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React, { forwardRef, useMemo, useRef } from 'react';
|
|
2
|
+
import mergeRefs from 'react-merge-refs';
|
|
3
|
+
import cn from 'classnames';
|
|
4
|
+
|
|
5
|
+
import { BaseModal } from '@alfalab/core-components-base-modal';
|
|
6
|
+
|
|
7
|
+
import { ResponsiveContext } from './ResponsiveContext';
|
|
8
|
+
import { ModalDesktopProps, View } from './typings';
|
|
9
|
+
|
|
10
|
+
import desktopStyles from './desktop.module.css';
|
|
11
|
+
import mobileStyles from './mobile.module.css';
|
|
12
|
+
import transitions from './transitions.module.css';
|
|
13
|
+
|
|
14
|
+
export const Modal = forwardRef<HTMLDivElement, ModalDesktopProps & { view: View }>(
|
|
15
|
+
(
|
|
16
|
+
{
|
|
17
|
+
size = 's',
|
|
18
|
+
fixedPosition,
|
|
19
|
+
fullscreen,
|
|
20
|
+
children,
|
|
21
|
+
className,
|
|
22
|
+
wrapperClassName,
|
|
23
|
+
transitionProps = {},
|
|
24
|
+
view,
|
|
25
|
+
...restProps
|
|
26
|
+
},
|
|
27
|
+
ref,
|
|
28
|
+
) => {
|
|
29
|
+
// TODO: удалить, после удаления пропсы fullscreen
|
|
30
|
+
const componentSize = fullscreen ? 'fullscreen' : size;
|
|
31
|
+
|
|
32
|
+
const modalRef = useRef<HTMLElement>(null);
|
|
33
|
+
|
|
34
|
+
const handleEntered = (node: HTMLElement, isAppearing: boolean) => {
|
|
35
|
+
if (fixedPosition && modalRef.current) {
|
|
36
|
+
const content = modalRef.current.querySelector<HTMLElement>(
|
|
37
|
+
`.${desktopStyles.component}`,
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (content) {
|
|
41
|
+
const { marginTop } = window.getComputedStyle(content);
|
|
42
|
+
|
|
43
|
+
content.style.marginTop = marginTop;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (transitionProps.onEntered) {
|
|
48
|
+
transitionProps.onEntered(node, isAppearing);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const baseModalProps =
|
|
53
|
+
view === 'desktop'
|
|
54
|
+
? {
|
|
55
|
+
ref: mergeRefs([ref, modalRef]),
|
|
56
|
+
wrapperClassName: cn(desktopStyles.wrapper, wrapperClassName, {
|
|
57
|
+
[desktopStyles.fullscreen]: componentSize === 'fullscreen',
|
|
58
|
+
}),
|
|
59
|
+
className: cn(
|
|
60
|
+
desktopStyles.component,
|
|
61
|
+
className,
|
|
62
|
+
desktopStyles[componentSize],
|
|
63
|
+
),
|
|
64
|
+
backdropProps: {
|
|
65
|
+
invisible: componentSize === 'fullscreen',
|
|
66
|
+
...restProps.backdropProps,
|
|
67
|
+
},
|
|
68
|
+
transitionProps: {
|
|
69
|
+
classNames: transitions,
|
|
70
|
+
...transitionProps,
|
|
71
|
+
onEntered: handleEntered,
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
: {
|
|
75
|
+
ref,
|
|
76
|
+
transitionProps: {
|
|
77
|
+
classNames: transitions,
|
|
78
|
+
...transitionProps,
|
|
79
|
+
},
|
|
80
|
+
className: cn(className, mobileStyles.component),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const contextValue = useMemo(() => ({ size: componentSize, view }), [componentSize, view]);
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<ResponsiveContext.Provider value={contextValue}>
|
|
87
|
+
<BaseModal {...restProps} {...baseModalProps}>
|
|
88
|
+
{children}
|
|
89
|
+
</BaseModal>
|
|
90
|
+
</ResponsiveContext.Provider>
|
|
91
|
+
);
|
|
92
|
+
},
|
|
93
|
+
);
|
package/src/Context.tsx
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { FC, Ref, useContext } from 'react';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
|
|
4
|
+
import { ModalContext } from '../../Context';
|
|
5
|
+
import { ResponsiveContext } from '../../ResponsiveContext';
|
|
6
|
+
import { ContentProps } from '../../typings';
|
|
7
|
+
|
|
8
|
+
import desktopStyles from './desktop.module.css';
|
|
9
|
+
import styles from './index.module.css';
|
|
10
|
+
import mobileStyles from './mobile.module.css';
|
|
11
|
+
|
|
12
|
+
export const Content: FC<ContentProps> = ({ children, flex, className }) => {
|
|
13
|
+
const { contentRef, hasHeader } = useContext(ModalContext);
|
|
14
|
+
const { size, view } = useContext(ResponsiveContext);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
className={cn(styles.content, className, {
|
|
19
|
+
[styles.flex]: flex,
|
|
20
|
+
[styles.withHeader]: hasHeader,
|
|
21
|
+
[desktopStyles[size]]: view === 'desktop' && size,
|
|
22
|
+
[mobileStyles.content]: view === 'mobile',
|
|
23
|
+
})}
|
|
24
|
+
ref={contentRef as Ref<HTMLDivElement>}
|
|
25
|
+
>
|
|
26
|
+
{children}
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React, { FC, ReactNode, useContext, useEffect } from 'react';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
|
|
4
|
+
import { ModalContext } from '../../Context';
|
|
5
|
+
import { ResponsiveContext } from '../../ResponsiveContext';
|
|
6
|
+
|
|
7
|
+
import desktopStyles from './desktop.module.css';
|
|
8
|
+
import styles from './index.module.css';
|
|
9
|
+
import layoutStyles from './layout.module.css';
|
|
10
|
+
import mobileStyles from './mobile.module.css';
|
|
11
|
+
|
|
12
|
+
export type FooterProps = {
|
|
13
|
+
/**
|
|
14
|
+
* Контент футера
|
|
15
|
+
*/
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Дополнительный класс
|
|
20
|
+
*/
|
|
21
|
+
className?: string;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Фиксирует футер
|
|
25
|
+
*/
|
|
26
|
+
sticky?: boolean;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Выравнивание элементов футера
|
|
30
|
+
*/
|
|
31
|
+
layout?: 'start' | 'center' | 'space-between' | 'column';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Отступы между элементами футера
|
|
35
|
+
*/
|
|
36
|
+
gap?: 16 | 24 | 32;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const Footer: FC<FooterProps> = ({ children, className, sticky, layout = 'start', gap }) => {
|
|
40
|
+
const { footerHighlighted, setHasFooter } = useContext(ModalContext);
|
|
41
|
+
const { size, view } = useContext(ResponsiveContext);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
setHasFooter(true);
|
|
45
|
+
}, [setHasFooter]);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div
|
|
49
|
+
className={cn(
|
|
50
|
+
styles.footer,
|
|
51
|
+
className,
|
|
52
|
+
layoutStyles[layout],
|
|
53
|
+
gap && layoutStyles[`gap-${gap}`],
|
|
54
|
+
{
|
|
55
|
+
[styles.highlighted]: sticky && footerHighlighted,
|
|
56
|
+
[styles.sticky]: sticky,
|
|
57
|
+
[desktopStyles.footer]: view === 'desktop',
|
|
58
|
+
[desktopStyles.sticky]: view === 'desktop' && sticky,
|
|
59
|
+
[desktopStyles[size]]: view === 'desktop',
|
|
60
|
+
[mobileStyles.footer]: view === 'mobile',
|
|
61
|
+
[mobileStyles.sticky]: view === 'mobile' && sticky,
|
|
62
|
+
[layoutStyles[`${layout}-mobile`]]: view === 'mobile',
|
|
63
|
+
},
|
|
64
|
+
)}
|
|
65
|
+
>
|
|
66
|
+
{children}
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@import '../../vars.css';
|
|
2
|
+
|
|
3
|
+
.footer {
|
|
4
|
+
border-bottom-left-radius: var(--modal-border-radius);
|
|
5
|
+
border-bottom-right-radius: var(--modal-border-radius);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.sticky {
|
|
9
|
+
bottom: calc(var(--modal-vertical-padding) * -1);
|
|
10
|
+
|
|
11
|
+
&.fullscreen {
|
|
12
|
+
bottom: 0;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.s,
|
|
17
|
+
.m,
|
|
18
|
+
.l,
|
|
19
|
+
.xl,
|
|
20
|
+
.fullscreen {
|
|
21
|
+
padding: var(--modal-s-footer-paddings);
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
@import '../../vars.css';
|
|
2
|
+
|
|
3
|
+
.footer {
|
|
4
|
+
width: 100%;
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
transition: box-shadow 0.2s ease, background 0.2s ease;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.sticky {
|
|
10
|
+
background: var(--modal-footer-background);
|
|
11
|
+
position: sticky;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.highlighted {
|
|
15
|
+
background: var(--modal-footer-highlight-background);
|
|
16
|
+
box-shadow: var(--modal-footer-highlight-box-shadow);
|
|
17
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
@import '../../vars.css';
|
|
2
|
+
|
|
3
|
+
.column {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
|
|
7
|
+
& > * {
|
|
8
|
+
margin-bottom: var(--modal-footer-default-gap);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
& > *:last-child,
|
|
12
|
+
& > *:only-child {
|
|
13
|
+
margin-bottom: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&.gap-16 > * {
|
|
17
|
+
margin-bottom: var(--gap-m);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&.gap-24 > * {
|
|
21
|
+
margin-bottom: var(--gap-xl);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&.gap-32 > * {
|
|
25
|
+
margin-bottom: var(--gap-2xl);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
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
|
+
.start {
|
|
46
|
+
justify-content: flex-start;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.center {
|
|
50
|
+
justify-content: center;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.space-between {
|
|
54
|
+
justify-content: space-between;
|
|
55
|
+
|
|
56
|
+
& > * {
|
|
57
|
+
flex: 1;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.start,
|
|
62
|
+
.center,
|
|
63
|
+
.space-between {
|
|
64
|
+
display: flex;
|
|
65
|
+
|
|
66
|
+
& > * {
|
|
67
|
+
margin-right: var(--modal-footer-default-gap);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
& > *:last-child,
|
|
71
|
+
& > *:only-child {
|
|
72
|
+
margin-right: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&.gap-16 > * {
|
|
76
|
+
margin-right: var(--gap-m);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&.gap-24 > * {
|
|
80
|
+
margin-right: var(--gap-xl);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
&.gap-32 > * {
|
|
84
|
+
margin-right: var(--gap-2xl);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React, { FC, useContext, useEffect } from 'react';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
|
|
4
|
+
import { NavigationBar, NavigationBarProps } from '@alfalab/core-components-navigation-bar';
|
|
5
|
+
|
|
6
|
+
import { ModalContext } from '../../Context';
|
|
7
|
+
import { ResponsiveContext } from '../../ResponsiveContext';
|
|
8
|
+
|
|
9
|
+
import desktopStyles from './desktop.module.css';
|
|
10
|
+
import styles from './index.module.css';
|
|
11
|
+
import mobileStyles from './mobile.module.css';
|
|
12
|
+
|
|
13
|
+
export type HeaderProps = Omit<NavigationBarProps, 'size' | 'view' | 'parentRef'>;
|
|
14
|
+
|
|
15
|
+
export const Header: FC<HeaderProps> = ({
|
|
16
|
+
className,
|
|
17
|
+
sticky,
|
|
18
|
+
title,
|
|
19
|
+
children,
|
|
20
|
+
contentClassName,
|
|
21
|
+
hasCloser = true,
|
|
22
|
+
...restProps
|
|
23
|
+
}) => {
|
|
24
|
+
const { setHasHeader, headerHighlighted, parentRef, onClose } = useContext(ModalContext);
|
|
25
|
+
const { view, size } = useContext(ResponsiveContext);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setHasHeader(true);
|
|
29
|
+
}, [setHasHeader]);
|
|
30
|
+
|
|
31
|
+
const hasContent = Boolean(title || children);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<NavigationBar
|
|
35
|
+
{...restProps}
|
|
36
|
+
scrollableParentRef={parentRef}
|
|
37
|
+
hasCloser={hasCloser}
|
|
38
|
+
sticky={sticky}
|
|
39
|
+
view={view}
|
|
40
|
+
title={title}
|
|
41
|
+
onClose={onClose}
|
|
42
|
+
className={cn(className, {
|
|
43
|
+
[styles.highlighted]: hasContent && sticky && headerHighlighted,
|
|
44
|
+
[styles.sticky]: sticky,
|
|
45
|
+
[styles.hasContent]: hasContent,
|
|
46
|
+
[desktopStyles.header]: view === 'desktop',
|
|
47
|
+
[desktopStyles.sticky]: view === 'desktop' && sticky,
|
|
48
|
+
[desktopStyles[size]]: view === 'desktop',
|
|
49
|
+
[mobileStyles.header]: view === 'mobile',
|
|
50
|
+
[mobileStyles.sticky]: view === 'mobile' && sticky,
|
|
51
|
+
})}
|
|
52
|
+
contentClassName={cn(contentClassName, {
|
|
53
|
+
[desktopStyles.content]: view === 'desktop',
|
|
54
|
+
[mobileStyles.content]: view === 'mobile',
|
|
55
|
+
})}
|
|
56
|
+
>
|
|
57
|
+
{children}
|
|
58
|
+
</NavigationBar>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@import '../../vars.css';
|
|
2
|
+
|
|
3
|
+
.header {
|
|
4
|
+
border-top-left-radius: var(--modal-border-radius);
|
|
5
|
+
border-top-right-radius: var(--modal-border-radius);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.content {
|
|
9
|
+
font-weight: var(--modal-header-desktop-font-weight);
|
|
10
|
+
font-family: var(--modal-header-desktop-font-family);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.s .content,
|
|
14
|
+
.m .content {
|
|
15
|
+
padding: var(--modal-s-header-desktop-content-paddings);
|
|
16
|
+
font-size: var(--modal-s-header-desktop-font-size);
|
|
17
|
+
line-height: var(--modal-s-header-desktop-line-height);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.l .content,
|
|
21
|
+
.xl .content,
|
|
22
|
+
.fullscreen .content {
|
|
23
|
+
padding: var(--modal-l-header-desktop-content-paddings);
|
|
24
|
+
font-size: var(--modal-l-header-desktop-font-size);
|
|
25
|
+
line-height: var(--modal-l-header-desktop-line-height);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.s,
|
|
29
|
+
.m,
|
|
30
|
+
.l,
|
|
31
|
+
.xl,
|
|
32
|
+
.fullscreen {
|
|
33
|
+
padding: var(--modal-s-header-paddings);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.sticky {
|
|
37
|
+
top: calc(var(--modal-vertical-padding) * -1);
|
|
38
|
+
|
|
39
|
+
&.fullscreen {
|
|
40
|
+
top: 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@import '../../vars.css';
|
|
2
|
+
|
|
3
|
+
.highlighted {
|
|
4
|
+
background: var(--modal-header-highlight-background);
|
|
5
|
+
box-shadow: var(--modal-header-highlight-box-shadow);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.sticky {
|
|
9
|
+
position: sticky;
|
|
10
|
+
z-index: 1;
|
|
11
|
+
|
|
12
|
+
&.hasContent {
|
|
13
|
+
background: var(--modal-header-background);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
@import '../../vars.css';
|
|
2
|
+
|
|
3
|
+
.header {
|
|
4
|
+
padding: var(--modal-header-mobile-paddings);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.sticky {
|
|
8
|
+
top: 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.content {
|
|
12
|
+
font-size: var(--modal-header-mobile-font-size);
|
|
13
|
+
line-height: var(--modal-header-mobile-line-height);
|
|
14
|
+
font-family: var(--modal-header-mobile-font-family);
|
|
15
|
+
font-weight: var(--modal-header-mobile-font-weight);
|
|
16
|
+
|
|
17
|
+
padding: var(--modal-header-mobile-content-paddings);
|
|
18
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
@import './vars.css';
|
|
2
|
+
|
|
3
|
+
.wrapper {
|
|
4
|
+
padding-top: var(--modal-vertical-padding);
|
|
5
|
+
padding-bottom: var(--modal-vertical-padding);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.component {
|
|
9
|
+
width: 100%;
|
|
10
|
+
max-width: 100%;
|
|
11
|
+
border-radius: var(--modal-border-radius);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.fullscreen {
|
|
15
|
+
padding-top: 0;
|
|
16
|
+
padding-bottom: 0;
|
|
17
|
+
|
|
18
|
+
& .component {
|
|
19
|
+
flex: 1;
|
|
20
|
+
border-radius: 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.s {
|
|
25
|
+
width: var(--modal-s-width);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.m {
|
|
29
|
+
width: var(--modal-m-width);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.l {
|
|
33
|
+
width: var(--modal-l-width);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.xl {
|
|
37
|
+
width: var(--modal-xl-width);
|
|
38
|
+
}
|
package/src/desktop.ts
ADDED
package/src/index.ts
ADDED
package/src/mobile.ts
ADDED
package/src/shared.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ModalContext } from './Context';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
.appear,
|
|
2
|
+
.enter {
|
|
3
|
+
opacity: 0;
|
|
4
|
+
transform: translateY(15px);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.appearActive,
|
|
8
|
+
.enterActive {
|
|
9
|
+
opacity: 1;
|
|
10
|
+
transform: translateY(0);
|
|
11
|
+
transition: opacity 200ms ease-in, transform 200ms ease-in;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.exit {
|
|
15
|
+
opacity: 1;
|
|
16
|
+
transform: translateY(0);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.exitActive,
|
|
20
|
+
.exitDone {
|
|
21
|
+
opacity: 0;
|
|
22
|
+
transform: translateY(15px);
|
|
23
|
+
transition: opacity 200ms ease-out, transform 200ms ease-out;
|
|
24
|
+
}
|
package/src/typings.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { BaseModalProps } from '@alfalab/core-components-base-modal';
|
|
4
|
+
|
|
5
|
+
export type ModalDesktopProps = BaseModalProps & {
|
|
6
|
+
/**
|
|
7
|
+
* Ширина модального окна
|
|
8
|
+
* @default "m"
|
|
9
|
+
*/
|
|
10
|
+
size?: 's' | 'm' | 'l' | 'xl' | 'fullscreen';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Растягивает модальное окно на весь экран
|
|
14
|
+
* @deprecated Используйте размер fullscreen
|
|
15
|
+
*/
|
|
16
|
+
fullscreen?: boolean;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Фиксирует позицию модального окна после открытия,
|
|
20
|
+
* предотвращая скачки, если контент внутри будет меняться
|
|
21
|
+
*/
|
|
22
|
+
fixedPosition?: boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Управление наличием закрывающего крестика
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
hasCloser?: boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type ModalMobileProps = Omit<ModalDesktopProps, 'size' | 'fixedPosition' | 'fullscreen'>;
|
|
32
|
+
|
|
33
|
+
export type ModalResponsiveProps = ModalDesktopProps & {
|
|
34
|
+
/**
|
|
35
|
+
* Контрольная точка, с нее начинается desktop версия
|
|
36
|
+
* @default 1024
|
|
37
|
+
*/
|
|
38
|
+
breakpoint?: number;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type View = 'desktop' | 'mobile';
|
|
42
|
+
|
|
43
|
+
export type TResponsiveModalContext = {
|
|
44
|
+
view: View;
|
|
45
|
+
size: NonNullable<ModalDesktopProps['size']>;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type ContentProps = {
|
|
49
|
+
/**
|
|
50
|
+
* Контент
|
|
51
|
+
*/
|
|
52
|
+
children?: ReactNode;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Дополнительный класс
|
|
56
|
+
*/
|
|
57
|
+
className?: string;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Растягивает контент на всю высоту
|
|
61
|
+
*/
|
|
62
|
+
flex?: boolean;
|
|
63
|
+
};
|