@snack-uikit/drawer 0.4.6-preview-85c5f47b.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 (69) hide show
  1. package/CHANGELOG.md +256 -0
  2. package/LICENSE +201 -0
  3. package/README.md +81 -0
  4. package/dist/components/Drawer/Drawer.d.ts +28 -0
  5. package/dist/components/Drawer/Drawer.js +25 -0
  6. package/dist/components/Drawer/index.d.ts +1 -0
  7. package/dist/components/Drawer/index.js +1 -0
  8. package/dist/components/Drawer/styles.module.css +3 -0
  9. package/dist/components/DrawerCustom/DrawerCustom.d.ts +44 -0
  10. package/dist/components/DrawerCustom/DrawerCustom.js +34 -0
  11. package/dist/components/DrawerCustom/constants.d.ts +5 -0
  12. package/dist/components/DrawerCustom/constants.js +13 -0
  13. package/dist/components/DrawerCustom/index.d.ts +1 -0
  14. package/dist/components/DrawerCustom/index.js +1 -0
  15. package/dist/components/DrawerCustom/motion.css +63 -0
  16. package/dist/components/DrawerCustom/styles.module.css +53 -0
  17. package/dist/components/index.d.ts +2 -0
  18. package/dist/components/index.js +2 -0
  19. package/dist/constants.d.ts +29 -0
  20. package/dist/constants.js +32 -0
  21. package/dist/helperComponents/Body/Body.d.ts +10 -0
  22. package/dist/helperComponents/Body/Body.js +21 -0
  23. package/dist/helperComponents/Body/index.d.ts +1 -0
  24. package/dist/helperComponents/Body/index.js +1 -0
  25. package/dist/helperComponents/Body/styles.module.css +8 -0
  26. package/dist/helperComponents/ButtonClose/ButtonClose.d.ts +5 -0
  27. package/dist/helperComponents/ButtonClose/ButtonClose.js +7 -0
  28. package/dist/helperComponents/ButtonClose/index.d.ts +1 -0
  29. package/dist/helperComponents/ButtonClose/index.js +1 -0
  30. package/dist/helperComponents/ButtonClose/styles.module.css +35 -0
  31. package/dist/helperComponents/Footer/Footer.d.ts +10 -0
  32. package/dist/helperComponents/Footer/Footer.js +21 -0
  33. package/dist/helperComponents/Footer/index.d.ts +1 -0
  34. package/dist/helperComponents/Footer/index.js +1 -0
  35. package/dist/helperComponents/Footer/styles.module.css +17 -0
  36. package/dist/helperComponents/Header/Header.d.ts +20 -0
  37. package/dist/helperComponents/Header/Header.js +23 -0
  38. package/dist/helperComponents/Header/index.d.ts +1 -0
  39. package/dist/helperComponents/Header/index.js +1 -0
  40. package/dist/helperComponents/Header/styles.module.css +35 -0
  41. package/dist/helperComponents/index.d.ts +4 -0
  42. package/dist/helperComponents/index.js +4 -0
  43. package/dist/index.d.ts +1 -0
  44. package/dist/index.js +1 -0
  45. package/package.json +46 -0
  46. package/src/components/Drawer/Drawer.tsx +95 -0
  47. package/src/components/Drawer/index.ts +1 -0
  48. package/src/components/Drawer/styles.module.scss +3 -0
  49. package/src/components/DrawerCustom/DrawerCustom.tsx +117 -0
  50. package/src/components/DrawerCustom/constants.ts +18 -0
  51. package/src/components/DrawerCustom/index.ts +1 -0
  52. package/src/components/DrawerCustom/motion.css +63 -0
  53. package/src/components/DrawerCustom/styles.module.scss +64 -0
  54. package/src/components/index.ts +2 -0
  55. package/src/constants.ts +34 -0
  56. package/src/helperComponents/Body/Body.tsx +23 -0
  57. package/src/helperComponents/Body/index.ts +1 -0
  58. package/src/helperComponents/Body/styles.module.scss +10 -0
  59. package/src/helperComponents/ButtonClose/ButtonClose.tsx +21 -0
  60. package/src/helperComponents/ButtonClose/index.ts +1 -0
  61. package/src/helperComponents/ButtonClose/styles.module.scss +44 -0
  62. package/src/helperComponents/Footer/Footer.tsx +25 -0
  63. package/src/helperComponents/Footer/index.ts +1 -0
  64. package/src/helperComponents/Footer/styles.module.scss +17 -0
  65. package/src/helperComponents/Header/Header.tsx +64 -0
  66. package/src/helperComponents/Header/index.ts +1 -0
  67. package/src/helperComponents/Header/styles.module.scss +36 -0
  68. package/src/helperComponents/index.ts +4 -0
  69. package/src/index.ts +1 -0
@@ -0,0 +1,95 @@
1
+ import { ReactElement } from 'react';
2
+
3
+ import {
4
+ ButtonFilled,
5
+ ButtonFilledProps,
6
+ ButtonOutline,
7
+ ButtonOutlineProps,
8
+ ButtonSimple,
9
+ ButtonSimpleProps,
10
+ } from '@snack-uikit/button';
11
+ import { TruncateString } from '@snack-uikit/truncate-string';
12
+
13
+ import { Mode, NESTED_DRAWER_PUSH_DISTANCE, Position, Size, TEST_IDS } from '../../constants';
14
+ import { DrawerBodyProps, DrawerHeaderProps } from '../../helperComponents';
15
+ import { DrawerCustom, DrawerCustomProps } from '../DrawerCustom';
16
+
17
+ export type DrawerProps = Omit<DrawerCustomProps, 'size' | 'children' | 'nestedDrawer' | 'push'> &
18
+ Pick<DrawerHeaderProps, 'titleTooltip' | 'image'> &
19
+ Pick<DrawerBodyProps, 'content'> & {
20
+ /** Заголовок */
21
+ title: string;
22
+ /** Подзаголовок */
23
+ subtitle?: string;
24
+ /** Размер */
25
+ size?: Size;
26
+ /** Основная кнопка */
27
+ approveButton?: Omit<ButtonFilledProps, 'size' | 'data-test-id'>;
28
+ /** Кнопка отмены */
29
+ cancelButton?: Omit<ButtonOutlineProps, 'size' | 'data-test-id'>;
30
+ /** Дополнительная кнопка */
31
+ additionalButton?: Omit<ButtonSimpleProps, 'size' | 'data-test-id'>;
32
+ /** Вложенный Drawer */
33
+ nestedDrawer?: ReactElement<DrawerProps>;
34
+ };
35
+
36
+ /** Готовый компонент Drawer */
37
+ export function Drawer({
38
+ title,
39
+ titleTooltip,
40
+ subtitle,
41
+ image,
42
+ content,
43
+ approveButton,
44
+ cancelButton,
45
+ additionalButton,
46
+ nestedDrawer,
47
+ ...rest
48
+ }: DrawerProps) {
49
+ const needFooter = Boolean(approveButton) || Boolean(cancelButton) || Boolean(additionalButton);
50
+
51
+ return (
52
+ <DrawerCustom {...rest} push={Boolean(nestedDrawer) && { distance: NESTED_DRAWER_PUSH_DISTANCE }}>
53
+ <DrawerCustom.Header
54
+ title={<TruncateString text={title} />}
55
+ titleTooltip={titleTooltip}
56
+ subtitle={subtitle}
57
+ image={image}
58
+ data-test-id={TEST_IDS.header}
59
+ />
60
+
61
+ <DrawerCustom.Body content={content} data-test-id={TEST_IDS.content} />
62
+
63
+ {needFooter && (
64
+ <DrawerCustom.Footer
65
+ data-test-id={TEST_IDS.footer}
66
+ actions={
67
+ <>
68
+ {approveButton && (
69
+ <ButtonFilled {...approveButton} size={ButtonFilled.sizes.M} data-test-id={TEST_IDS.approveButton} />
70
+ )}
71
+
72
+ {cancelButton && (
73
+ <ButtonOutline {...cancelButton} size={ButtonOutline.sizes.M} data-test-id={TEST_IDS.cancelButton} />
74
+ )}
75
+
76
+ {additionalButton && (
77
+ <ButtonSimple
78
+ {...additionalButton}
79
+ size={ButtonSimple.sizes.M}
80
+ data-test-id={TEST_IDS.additionalButton}
81
+ />
82
+ )}
83
+ </>
84
+ }
85
+ />
86
+ )}
87
+
88
+ {nestedDrawer}
89
+ </DrawerCustom>
90
+ );
91
+ }
92
+
93
+ Drawer.modes = Mode;
94
+ Drawer.sizes = Size;
95
+ Drawer.positions = Position;
@@ -0,0 +1 @@
1
+ export * from './Drawer';
@@ -0,0 +1,3 @@
1
+ .drawer {
2
+ box-sizing: border-box;
3
+ }
@@ -0,0 +1,117 @@
1
+ import 'rc-drawer/assets/index.css';
2
+
3
+ import cn from 'classnames';
4
+ import RcDrawer, { DrawerProps as RcDrawerProps } from 'rc-drawer';
5
+ import { PropsWithChildren, ReactElement } from 'react';
6
+
7
+ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
8
+
9
+ import { Mode, Position, Size, SIZE_AS_VALUES } from '../../constants';
10
+ import {
11
+ ButtonClose,
12
+ DrawerBody,
13
+ DrawerBodyProps,
14
+ DrawerFooter,
15
+ DrawerFooterProps,
16
+ DrawerHeader,
17
+ DrawerHeaderProps,
18
+ } from '../../helperComponents';
19
+ import { motionProps } from './constants';
20
+ import styles from './styles.module.scss';
21
+
22
+ export type DrawerCustomProps = WithSupportProps<
23
+ PropsWithChildren<{
24
+ /** Управление состоянием показан/не показан. */
25
+ open: boolean;
26
+ /** Колбэк закрытия */
27
+ onClose(): void;
28
+ /** Режим отображения */
29
+ mode?: Mode;
30
+ /** Расположение открытого Drawer */
31
+ position?: Position;
32
+ /** CSS-класс для элемента с контентом */
33
+ className?: string;
34
+ /** CSS-класс для корневого элемента */
35
+ rootClassName?: string;
36
+ /** Размер */
37
+ size?: Size | string | number;
38
+ /** Смещение при открытии "вложенного" компонента */
39
+ push?: RcDrawerProps['push'];
40
+ /** Контейнер в котором будет рендерится Drawer. По-умолчанию - body */
41
+ container?: string | HTMLElement;
42
+ /** Вложенный Drawer */
43
+ nestedDrawer?: ReactElement<DrawerCustomProps>;
44
+ }>
45
+ >;
46
+
47
+ function DrawerCustomComponent({
48
+ open,
49
+ mode = Mode.Regular,
50
+ position = Position.Right,
51
+ onClose,
52
+ rootClassName,
53
+ className,
54
+ size = Size.S,
55
+ push,
56
+ container,
57
+ children,
58
+ nestedDrawer,
59
+ ...rest
60
+ }: DrawerCustomProps) {
61
+ const isRegular = mode === Mode.Regular;
62
+ const isPredefinedSize = typeof size === 'string' && SIZE_AS_VALUES.includes(size);
63
+
64
+ return (
65
+ <RcDrawer
66
+ mask={isRegular}
67
+ maskClosable={isRegular}
68
+ maskClassName={styles.mask}
69
+ keyboard={isRegular}
70
+ width={isPredefinedSize ? 'null' : size}
71
+ open={open}
72
+ placement={position}
73
+ destroyOnClose={true}
74
+ push={push}
75
+ onClose={onClose}
76
+ getContainer={container}
77
+ className={cn(styles.drawer, className)}
78
+ rootClassName={cn(styles.drawerRoot, rootClassName)}
79
+ {...extractSupportProps(rest)}
80
+ data-content-wrapper={true}
81
+ data-size={isPredefinedSize ? size : undefined}
82
+ data-mode={mode}
83
+ {...motionProps}
84
+ >
85
+ <div className={styles.headerElements}>
86
+ <ButtonClose onClick={onClose} />
87
+ </div>
88
+
89
+ {children}
90
+
91
+ {nestedDrawer}
92
+ </RcDrawer>
93
+ );
94
+ }
95
+
96
+ /** Компонент-конструктор */
97
+ export const DrawerCustom = DrawerCustomComponent as typeof DrawerCustomComponent & {
98
+ modes: typeof Mode;
99
+ positions: typeof Position;
100
+ sizes: typeof Size;
101
+ Header: typeof DrawerHeader;
102
+ Body: typeof DrawerBody;
103
+ Footer: typeof DrawerFooter;
104
+ };
105
+
106
+ DrawerCustom.modes = Mode;
107
+ DrawerCustom.positions = Position;
108
+ DrawerCustom.sizes = Size;
109
+ DrawerCustom.Header = DrawerHeader;
110
+ DrawerCustom.Body = DrawerBody;
111
+ DrawerCustom.Footer = DrawerFooter;
112
+
113
+ export namespace DrawerCustom {
114
+ export type HeaderProps = DrawerHeaderProps;
115
+ export type BodyProps = DrawerBodyProps;
116
+ export type FooterProps = DrawerFooterProps;
117
+ }
@@ -0,0 +1,18 @@
1
+ import './motion.css';
2
+
3
+ import type { DrawerProps } from 'rc-drawer';
4
+
5
+ export const maskMotion: DrawerProps['maskMotion'] = {
6
+ motionAppear: true,
7
+ motionName: 'maskMotion',
8
+ };
9
+
10
+ export const motion: DrawerProps['motion'] = placement => ({
11
+ motionAppear: true,
12
+ motionName: `panelMotion-${placement}`,
13
+ });
14
+
15
+ export const motionProps: Partial<DrawerProps> = {
16
+ maskMotion,
17
+ motion,
18
+ };
@@ -0,0 +1 @@
1
+ export * from './DrawerCustom';
@@ -0,0 +1,63 @@
1
+ .maskMotion {
2
+ opacity: unset;
3
+ }
4
+ .maskMotion-enter, .maskMotion-appear {
5
+ opacity: 0;
6
+ }
7
+ .maskMotion-enter-active, .maskMotion-appear-active {
8
+ opacity: 1;
9
+ transition: opacity 0.2s;
10
+ }
11
+ .maskMotion-leave {
12
+ opacity: 1;
13
+ }
14
+ .maskMotion-leave-active {
15
+ opacity: 0;
16
+ transition: opacity 0.1s;
17
+ }
18
+
19
+ .panelMotion {
20
+ transform: unset;
21
+ }
22
+ .panelMotion-left-enter-start, .panelMotion-left-appear-start, .panelMotion-left-leave-start {
23
+ transition: none !important;
24
+ }
25
+ .panelMotion-left-enter-active, .panelMotion-left-appear-active {
26
+ transition: transform 0.2s ease-in-out;
27
+ }
28
+ .panelMotion-left-leave-active {
29
+ transition: transform 0.1s ease-out;
30
+ }
31
+ .panelMotion-left-enter, .panelMotion-left-appear {
32
+ transform: translateX(-100%);
33
+ }
34
+ .panelMotion-left-enter-active, .panelMotion-left-appear-active {
35
+ transform: translateX(0);
36
+ }
37
+ .panelMotion-left-leave {
38
+ transform: translateX(0);
39
+ }
40
+ .panelMotion-left-leave-active {
41
+ transform: translateX(-100%) !important;
42
+ }
43
+ .panelMotion-right-enter-start, .panelMotion-right-appear-start, .panelMotion-right-leave-start {
44
+ transition: none !important;
45
+ }
46
+ .panelMotion-right-enter-active, .panelMotion-right-appear-active {
47
+ transition: transform 0.2s ease-in-out;
48
+ }
49
+ .panelMotion-right-leave-active {
50
+ transition: transform 0.1s ease-out;
51
+ }
52
+ .panelMotion-right-enter, .panelMotion-right-appear {
53
+ transform: translateX(100%);
54
+ }
55
+ .panelMotion-right-enter-active, .panelMotion-right-appear-active {
56
+ transform: translateX(0);
57
+ }
58
+ .panelMotion-right-leave {
59
+ transform: translateX(0);
60
+ }
61
+ .panelMotion-right-leave-active {
62
+ transform: translateX(100%) !important;
63
+ }
@@ -0,0 +1,64 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-drawer';
2
+
3
+ $sizes: ('s', 'm', 'l');
4
+ $modes: ('regular', 'soft');
5
+ $drawer-background-color: (
6
+ 'regular': $sys-neutral-background1-level,
7
+ 'soft': $sys-neutral-background2-level,
8
+ );
9
+
10
+ .drawerRoot {
11
+ z-index: auto !important; /* stylelint-disable-line declaration-no-important */
12
+ }
13
+
14
+ div[data-content-wrapper='true'] {
15
+ will-change: transform;
16
+
17
+ z-index: auto;
18
+
19
+ overflow: unset;
20
+
21
+ max-width: calc(100% - $space-drawer-outside-gap);
22
+ height: 100%;
23
+
24
+ @each $size in $sizes {
25
+ &[data-size='#{$size}'] {
26
+ @include composite-var($drawer, 'window', $size);
27
+ }
28
+ }
29
+
30
+ @each $mode in $modes {
31
+ &[data-mode='#{$mode}'] {
32
+ .drawer {
33
+ background-color: simple-var($drawer-background-color, $mode);
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ .drawer {
40
+ overflow: unset;
41
+ display: flex;
42
+ flex-direction: column;
43
+
44
+ box-sizing: border-box;
45
+
46
+ box-shadow: simple-var($box-shadow-elevation-level5);
47
+ }
48
+
49
+ .headerElements {
50
+ @include composite-var($drawer-header-elements-container);
51
+ @include composite-var($drawer-header-elements-elements-layout);
52
+
53
+ position: absolute;
54
+ top: 0;
55
+ right: 0;
56
+
57
+ display: flex;
58
+ align-items: center;
59
+ }
60
+
61
+ .mask {
62
+ z-index: auto !important; /* stylelint-disable-line declaration-no-important */
63
+ background-color: simple-var($sys-blackout);
64
+ }
@@ -0,0 +1,2 @@
1
+ export * from './DrawerCustom';
2
+ export * from './Drawer';
@@ -0,0 +1,34 @@
1
+ export enum Size {
2
+ S = 's',
3
+ M = 'm',
4
+ L = 'l',
5
+ }
6
+
7
+ export const SIZE_AS_VALUES: string[] = Object.values(Size);
8
+
9
+ export enum Mode {
10
+ Regular = 'regular',
11
+ Soft = 'soft',
12
+ }
13
+
14
+ export enum Position {
15
+ Right = 'right',
16
+ Left = 'left',
17
+ }
18
+
19
+ export const NESTED_DRAWER_PUSH_DISTANCE = 24;
20
+
21
+ export const TEST_IDS = {
22
+ closeButton: 'drawer__close-button',
23
+ header: 'drawer__header',
24
+ title: 'drawer__title',
25
+ tooltip: 'drawer__title-tooltip',
26
+ subtitle: 'drawer__subtitle',
27
+ image: 'drawer__image',
28
+ content: 'drawer__body',
29
+ footer: 'drawer__footer',
30
+ footerActions: 'drawer__footer-actions',
31
+ approveButton: 'drawer__approve-button',
32
+ cancelButton: 'drawer__cancel-button',
33
+ additionalButton: 'drawer__additional-button',
34
+ };
@@ -0,0 +1,23 @@
1
+ import cn from 'classnames';
2
+ import { ReactNode } from 'react';
3
+
4
+ import { Scroll } from '@snack-uikit/scroll';
5
+ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
6
+
7
+ import styles from './styles.module.scss';
8
+
9
+ export type DrawerBodyProps = WithSupportProps<{
10
+ /** Контент */
11
+ content: ReactNode;
12
+ /** CSS-класс */
13
+ className?: string;
14
+ }>;
15
+
16
+ /** Вспомогательный компонент для добавления "тела" в DrawerCustom */
17
+ export function DrawerBody({ content, className, ...rest }: DrawerBodyProps) {
18
+ return (
19
+ <Scroll size={Scroll.sizes.M} className={cn(styles.drawerBody, className)} {...extractSupportProps(rest)}>
20
+ {content}
21
+ </Scroll>
22
+ );
23
+ }
@@ -0,0 +1 @@
1
+ export * from './Body';
@@ -0,0 +1,10 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-drawer';
2
+
3
+ .drawerBody {
4
+ @include composite-var($drawer-body);
5
+
6
+ flex: 1 1 auto;
7
+ box-sizing: border-box;
8
+ min-height: $dimension-2m;
9
+ color: $sys-neutral-text-main;
10
+ }
@@ -0,0 +1,21 @@
1
+ import { CrossSVG } from '@snack-uikit/icons';
2
+
3
+ import { TEST_IDS } from '../../constants';
4
+ import styles from './styles.module.scss';
5
+
6
+ type ButtonCloseProps = {
7
+ onClick(): void;
8
+ };
9
+
10
+ export function ButtonClose({ onClick }: ButtonCloseProps) {
11
+ return (
12
+ <button
13
+ className={styles.buttonClose}
14
+ onClick={onClick}
15
+ aria-label='close drawer'
16
+ data-test-id={TEST_IDS.closeButton}
17
+ >
18
+ <CrossSVG />
19
+ </button>
20
+ );
21
+ }
@@ -0,0 +1 @@
1
+ export * from './ButtonClose';
@@ -0,0 +1,44 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-drawer';
2
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
3
+
4
+ .buttonClose {
5
+ @include composite-var($drawer-button-close);
6
+
7
+ cursor: pointer;
8
+
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: center;
12
+
13
+ box-sizing: border-box;
14
+ margin: 0;
15
+ padding: 0;
16
+
17
+ color: simple-var($sys-neutral-text-support);
18
+
19
+ background-color: simple-var($sys-neutral-decor-default);
20
+ border: 0 solid transparent;
21
+ outline: 0;
22
+ outline-offset: $spacing-state-focus-offset;
23
+
24
+ &:hover, &:focus-visible {
25
+ color: simple-var($sys-neutral-text-main);
26
+ background-color: simple-var($sys-neutral-decor-hovered);
27
+ }
28
+
29
+ &:focus-visible {
30
+ @include outline-var($container-focused-s);
31
+
32
+ outline-color: $sys-available-complementary;
33
+ }
34
+
35
+ &:active {
36
+ color: simple-var($sys-neutral-text-main);
37
+ background-color: simple-var($sys-neutral-decor-activated);
38
+ }
39
+
40
+ svg {
41
+ width: $icon-s !important; /* stylelint-disable-line declaration-no-important */
42
+ height: $icon-s !important; /* stylelint-disable-line declaration-no-important */
43
+ }
44
+ }
@@ -0,0 +1,25 @@
1
+ import cn from 'classnames';
2
+ import { ReactNode } from 'react';
3
+
4
+ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
5
+
6
+ import { TEST_IDS } from '../../constants';
7
+ import styles from './styles.module.scss';
8
+
9
+ export type DrawerFooterProps = WithSupportProps<{
10
+ /** Слот для добавления кнопок-действий */
11
+ actions: ReactNode;
12
+ /** CSS-класс */
13
+ className?: string;
14
+ }>;
15
+
16
+ /** Вспомогательный компонент для добавления "футера" в DrawerCustom */
17
+ export function DrawerFooter({ actions, className, ...rest }: DrawerFooterProps) {
18
+ return (
19
+ <div className={cn(styles.footer, className)} {...extractSupportProps(rest)}>
20
+ <div className={styles.footerActions} data-test-id={TEST_IDS.footerActions}>
21
+ {actions}
22
+ </div>
23
+ </div>
24
+ );
25
+ }
@@ -0,0 +1 @@
1
+ export * from './Footer';
@@ -0,0 +1,17 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-drawer';
2
+
3
+ .footer {
4
+ @include composite-var($drawer-footer);
5
+
6
+ display: flex;
7
+ flex-direction: column;
8
+ }
9
+
10
+ .footerActions {
11
+ @include composite-var($drawer-action-row);
12
+
13
+ display: flex;
14
+ flex-direction: row-reverse;
15
+ flex-wrap: wrap;
16
+ align-items: center;
17
+ }
@@ -0,0 +1,64 @@
1
+ import cn from 'classnames';
2
+ import { ReactNode } from 'react';
3
+
4
+ import { QuestionTooltip, TooltipProps } from '@snack-uikit/tooltip';
5
+ import { Typography } from '@snack-uikit/typography';
6
+ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
7
+
8
+ import { TEST_IDS } from '../../constants';
9
+ import styles from './styles.module.scss';
10
+
11
+ export type DrawerHeaderProps = WithSupportProps<{
12
+ /** Изображение */
13
+ image?: {
14
+ src: string;
15
+ alt: string;
16
+ };
17
+ /** Заголовок */
18
+ title: ReactNode;
19
+ /** Тултип для заголовка */
20
+ titleTooltip?: TooltipProps['tip'];
21
+ /** Подзаголовок */
22
+ subtitle?: ReactNode;
23
+ /** CSS-класс */
24
+ className?: string;
25
+ }>;
26
+
27
+ /** Вспомогательный компонент для добавления "шапки" в DrawerCustom */
28
+ export function DrawerHeader({ title, titleTooltip, subtitle, image, className, ...rest }: DrawerHeaderProps) {
29
+ return (
30
+ <div className={cn(styles.drawerHeader, className)} {...extractSupportProps(rest)}>
31
+ {image && <img src={image.src} alt={image.alt} className={styles.image} data-test-id={TEST_IDS.image} />}
32
+
33
+ <div className={styles.headlineLayout}>
34
+ <div className={styles.headline}>
35
+ <Typography
36
+ family={Typography.families.Sans}
37
+ role={Typography.roles.Headline}
38
+ size={Typography.sizes.S}
39
+ className={styles.title}
40
+ data-test-id={TEST_IDS.title}
41
+ >
42
+ {title}
43
+ </Typography>
44
+
45
+ {titleTooltip && (
46
+ <QuestionTooltip tip={titleTooltip} size={QuestionTooltip.sizes.S} data-test-id={TEST_IDS.tooltip} />
47
+ )}
48
+ </div>
49
+
50
+ {subtitle && (
51
+ <Typography
52
+ family={Typography.families.Sans}
53
+ role={Typography.roles.Body}
54
+ size={Typography.sizes.M}
55
+ className={styles.subtitle}
56
+ data-test-id={TEST_IDS.subtitle}
57
+ >
58
+ {subtitle}
59
+ </Typography>
60
+ )}
61
+ </div>
62
+ </div>
63
+ );
64
+ }
@@ -0,0 +1 @@
1
+ export * from './Header';
@@ -0,0 +1,36 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-drawer';
2
+
3
+ .drawerHeader {
4
+ /* stub for proper typings */
5
+ }
6
+
7
+ .image {
8
+ @include composite-var($drawer-image);
9
+
10
+ display: block;
11
+ width: 100%;
12
+ object-fit: cover;
13
+ }
14
+
15
+ .headlineLayout {
16
+ @include composite-var($drawer-headline-layout);
17
+
18
+ display: flex;
19
+ flex-direction: column;
20
+ }
21
+
22
+ .headline {
23
+ @include composite-var($drawer-headline);
24
+
25
+ display: flex;
26
+ align-items: center;
27
+ }
28
+
29
+ .title {
30
+ display: grid;
31
+ color: $sys-neutral-text-main;
32
+ }
33
+
34
+ .subtitle {
35
+ color: $sys-neutral-text-support;
36
+ }
@@ -0,0 +1,4 @@
1
+ export * from './Body';
2
+ export * from './ButtonClose';
3
+ export * from './Footer';
4
+ export * from './Header';
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './components';