@snack-uikit/notification 0.3.17-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 (75) hide show
  1. package/CHANGELOG.md +333 -0
  2. package/LICENSE +201 -0
  3. package/README.md +134 -0
  4. package/dist/components/NotificationCard/NotificationCard.d.ts +36 -0
  5. package/dist/components/NotificationCard/NotificationCard.js +60 -0
  6. package/dist/components/NotificationCard/components/NotificationCardFunction.d.ts +7 -0
  7. package/dist/components/NotificationCard/components/NotificationCardFunction.js +13 -0
  8. package/dist/components/NotificationCard/components/NotificationCardSkeleton.d.ts +1 -0
  9. package/dist/components/NotificationCard/components/NotificationCardSkeleton.js +8 -0
  10. package/dist/components/NotificationCard/components/index.d.ts +2 -0
  11. package/dist/components/NotificationCard/components/index.js +2 -0
  12. package/dist/components/NotificationCard/constants.d.ts +20 -0
  13. package/dist/components/NotificationCard/constants.js +21 -0
  14. package/dist/components/NotificationCard/helpers.d.ts +2 -0
  15. package/dist/components/NotificationCard/helpers.js +18 -0
  16. package/dist/components/NotificationCard/index.d.ts +1 -0
  17. package/dist/components/NotificationCard/index.js +1 -0
  18. package/dist/components/NotificationCard/styles.module.css +128 -0
  19. package/dist/components/NotificationPanel/NotificationPanel.d.ts +42 -0
  20. package/dist/components/NotificationPanel/NotificationPanel.js +38 -0
  21. package/dist/components/NotificationPanel/components/NotificationPanelBlank/NotificationPanelBlank.d.ts +20 -0
  22. package/dist/components/NotificationPanel/components/NotificationPanelBlank/NotificationPanelBlank.js +24 -0
  23. package/dist/components/NotificationPanel/components/NotificationPanelBlank/index.d.ts +1 -0
  24. package/dist/components/NotificationPanel/components/NotificationPanelBlank/index.js +1 -0
  25. package/dist/components/NotificationPanel/components/NotificationPanelBlank/styles.module.css +27 -0
  26. package/dist/components/NotificationPanel/components/NotificationPanelSettings/NotificationPanelSettings.d.ts +9 -0
  27. package/dist/components/NotificationPanel/components/NotificationPanelSettings/NotificationPanelSettings.js +12 -0
  28. package/dist/components/NotificationPanel/components/NotificationPanelSettings/NotificationPanelSettingsDroplist.d.ts +8 -0
  29. package/dist/components/NotificationPanel/components/NotificationPanelSettings/NotificationPanelSettingsDroplist.js +13 -0
  30. package/dist/components/NotificationPanel/components/NotificationPanelSettings/index.d.ts +1 -0
  31. package/dist/components/NotificationPanel/components/NotificationPanelSettings/index.js +1 -0
  32. package/dist/components/NotificationPanel/components/index.d.ts +2 -0
  33. package/dist/components/NotificationPanel/components/index.js +2 -0
  34. package/dist/components/NotificationPanel/constants.d.ts +17 -0
  35. package/dist/components/NotificationPanel/constants.js +17 -0
  36. package/dist/components/NotificationPanel/index.d.ts +1 -0
  37. package/dist/components/NotificationPanel/index.js +1 -0
  38. package/dist/components/NotificationPanel/styles.module.css +97 -0
  39. package/dist/components/index.d.ts +2 -0
  40. package/dist/components/index.js +2 -0
  41. package/dist/helperComponents/NotificationPanelPopover/NotificationPanelPopover.d.ts +9 -0
  42. package/dist/helperComponents/NotificationPanelPopover/NotificationPanelPopover.js +22 -0
  43. package/dist/helperComponents/NotificationPanelPopover/index.d.ts +1 -0
  44. package/dist/helperComponents/NotificationPanelPopover/index.js +1 -0
  45. package/dist/helperComponents/NotificationPanelPopover/styles.module.css +20 -0
  46. package/dist/helperComponents/index.d.ts +1 -0
  47. package/dist/helperComponents/index.js +1 -0
  48. package/dist/index.d.ts +1 -0
  49. package/dist/index.js +1 -0
  50. package/package.json +50 -0
  51. package/src/components/NotificationCard/NotificationCard.tsx +172 -0
  52. package/src/components/NotificationCard/components/NotificationCardFunction.tsx +60 -0
  53. package/src/components/NotificationCard/components/NotificationCardSkeleton.tsx +30 -0
  54. package/src/components/NotificationCard/components/index.ts +2 -0
  55. package/src/components/NotificationCard/constants.ts +21 -0
  56. package/src/components/NotificationCard/helpers.tsx +19 -0
  57. package/src/components/NotificationCard/index.ts +1 -0
  58. package/src/components/NotificationCard/styles.module.scss +172 -0
  59. package/src/components/NotificationPanel/NotificationPanel.tsx +134 -0
  60. package/src/components/NotificationPanel/components/NotificationPanelBlank/NotificationPanelBlank.tsx +65 -0
  61. package/src/components/NotificationPanel/components/NotificationPanelBlank/index.ts +1 -0
  62. package/src/components/NotificationPanel/components/NotificationPanelBlank/styles.module.scss +32 -0
  63. package/src/components/NotificationPanel/components/NotificationPanelSettings/NotificationPanelSettings.tsx +31 -0
  64. package/src/components/NotificationPanel/components/NotificationPanelSettings/NotificationPanelSettingsDroplist.tsx +50 -0
  65. package/src/components/NotificationPanel/components/NotificationPanelSettings/index.ts +1 -0
  66. package/src/components/NotificationPanel/components/index.ts +2 -0
  67. package/src/components/NotificationPanel/constants.ts +17 -0
  68. package/src/components/NotificationPanel/index.ts +1 -0
  69. package/src/components/NotificationPanel/styles.module.scss +109 -0
  70. package/src/components/index.ts +2 -0
  71. package/src/helperComponents/NotificationPanelPopover/NotificationPanelPopover.tsx +60 -0
  72. package/src/helperComponents/NotificationPanelPopover/index.ts +1 -0
  73. package/src/helperComponents/NotificationPanelPopover/styles.module.scss +23 -0
  74. package/src/helperComponents/index.ts +1 -0
  75. package/src/index.ts +1 -0
@@ -0,0 +1,172 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-notification-notificationCard';
2
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
3
+
4
+ .notificationCardFunction {
5
+ @include composite-var($notification-card-function-badge);
6
+
7
+ pointer-events: none;
8
+
9
+ position: absolute;
10
+ top: 0;
11
+ right: 0;
12
+
13
+ display: flex;
14
+
15
+ opacity: 0;
16
+ }
17
+
18
+ .notificationCardTitleText {
19
+ box-sizing: border-box;
20
+ color: $sys-neutral-text-main;
21
+ }
22
+
23
+ .notificationCardTitleIcon {
24
+ @include composite-var($notification-card-icon-type);
25
+
26
+ display: flex;
27
+ align-items: center;
28
+ justify-content: center;
29
+ box-sizing: border-box;
30
+ }
31
+
32
+ .notificationCard {
33
+ @include composite-var($notification-card-container);
34
+
35
+ position: relative;
36
+
37
+ display: flex;
38
+ flex-direction: column;
39
+
40
+ box-sizing: border-box;
41
+
42
+ border-bottom-color: $sys-neutral-decor-default;
43
+ border-bottom-style: solid;
44
+
45
+ &::before {
46
+ pointer-events: none;
47
+ content: '';
48
+
49
+ position: absolute;
50
+ top: 0;
51
+ left: 0;
52
+
53
+ box-sizing: border-box;
54
+ width: 100%;
55
+ height: calc(100% + $border-width-notification-panel-card);
56
+
57
+ opacity: $opacity-a004;
58
+ }
59
+
60
+ &:focus-visible {
61
+ @include outline-var($container-focused-s);
62
+
63
+ border-bottom-color: transparent;
64
+ outline-color: $sys-available-complementary;
65
+ }
66
+
67
+ &[data-droplist-open], &:hover, &:focus-visible, &:focus-within:not(:focus) {
68
+ &::before {
69
+ background-color: $sys-neutral-accent-default;
70
+ }
71
+
72
+ .notificationCardFunction {
73
+ pointer-events: auto;
74
+ opacity: 1;
75
+ }
76
+ }
77
+
78
+ &[data-clickable] {
79
+ cursor: pointer;
80
+ }
81
+
82
+ &[data-unread] {
83
+ &::before {
84
+ opacity: $opacity-a008;
85
+ background-color: $sys-neutral-accent-default;
86
+ }
87
+
88
+ &[data-droplist-open], &:hover, &:focus-visible, &:focus-within:not(:focus) {
89
+ &::before {
90
+ opacity: $opacity-a004;
91
+ }
92
+ }
93
+ }
94
+
95
+ &[data-appearance='neutral'] {
96
+ .notificationCardTitleIcon {
97
+ color: $sys-neutral-accent-default;
98
+ }
99
+ }
100
+
101
+ &[data-appearance='error'],
102
+ &[data-appearance='errorCritical'] {
103
+ .notificationCardTitleIcon {
104
+ color: $sys-red-accent-default;
105
+ }
106
+ }
107
+
108
+ &[data-appearance='errorCritical'] {
109
+ &[data-unread], &[data-droplist-open], &:hover, &:focus-visible, &:focus-within:not(:focus) {
110
+ &::before {
111
+ background-color: $sys-red-accent-default;
112
+ }
113
+ }
114
+
115
+ .notificationCardTitleText {
116
+ color: $sys-red-accent-default;
117
+ }
118
+ }
119
+
120
+ &[data-appearance='warning'] {
121
+ .notificationCardTitleIcon {
122
+ color: $sys-yellow-accent-default;
123
+ }
124
+ }
125
+
126
+ &[data-appearance='success'] {
127
+ .notificationCardTitleIcon {
128
+ color: $sys-green-accent-default;
129
+ }
130
+ }
131
+
132
+ &[data-skeleton] {
133
+ &::before {
134
+ display: none;
135
+ }
136
+ }
137
+ }
138
+
139
+ .notificationCardLabel {
140
+ display: grid;
141
+ color: $sys-neutral-text-support;
142
+ }
143
+
144
+ .notificationCardTitle {
145
+ @include composite-var($notification-card-title-layout);
146
+
147
+ display: flex;
148
+
149
+ &[data-center] {
150
+ align-items: center;
151
+ }
152
+ }
153
+
154
+ .notificationCardContent {
155
+ box-sizing: border-box;
156
+ color: $sys-neutral-text-support;
157
+ white-space: pre-line;
158
+ }
159
+
160
+ .notificationCardFooter {
161
+ display: flex;
162
+ align-items: flex-end;
163
+ justify-content: space-between;
164
+ box-sizing: border-box;
165
+ }
166
+
167
+ .notificationCardDate {
168
+ flex: 1 0 auto;
169
+ box-sizing: border-box;
170
+ color: $sys-neutral-text-light;
171
+ text-align: right;
172
+ }
@@ -0,0 +1,134 @@
1
+ import { MouseEventHandler, ReactNode, useMemo } from 'react';
2
+
3
+ import { ButtonFunction, ButtonFunctionProps } from '@snack-uikit/button';
4
+ import { ChipToggle, ChipToggleProps } from '@snack-uikit/chips';
5
+ import { PopoverPrivate } from '@snack-uikit/popover-private';
6
+ import { Scroll } from '@snack-uikit/scroll';
7
+ import { SkeletonContextProvider, WithSkeleton } from '@snack-uikit/skeleton';
8
+ import { TruncateString } from '@snack-uikit/truncate-string';
9
+ import { Typography } from '@snack-uikit/typography';
10
+
11
+ import { NotificationPanelPopover, NotificationPanelPopoverProps } from '../../helperComponents';
12
+ import { NotificationCardSkeleton } from '../NotificationCard/components';
13
+ import {
14
+ NotificationPanelBlank,
15
+ NotificationPanelBlankProps,
16
+ NotificationPanelSettings,
17
+ NotificationPanelSettingsProps,
18
+ } from './components';
19
+ import { TEST_IDS } from './constants';
20
+ import styles from './styles.module.scss';
21
+
22
+ export type { NotificationPanelBlankProps };
23
+
24
+ export type NotificationPanelProps = {
25
+ /** Заголовок панели */
26
+ title: string;
27
+ /** Кнопка настроек и выпадающий список */
28
+ settings?: NotificationPanelSettingsProps;
29
+ /** Чипы для фильтрации */
30
+ chips?: Omit<ChipToggleProps, 'size' | 'data-test-id'>[];
31
+ /** Кнопка в "шапке" панели */
32
+ readAllButton?: Omit<ButtonFunctionProps, 'data-test-id'> & {
33
+ onClick: ButtonFunctionProps['onClick'];
34
+ };
35
+ /** Элемент для открытия панели */
36
+ triggerElement: NotificationPanelPopoverProps['children'];
37
+ /** Кнопка внизу панели */
38
+ footerButton?: {
39
+ label: string;
40
+ onClick: MouseEventHandler<HTMLButtonElement>;
41
+ };
42
+ /** Состояние загрузки */
43
+ loading?: boolean;
44
+ /** Контент для отрисовки (e.g NotificationCard | NotificationPanel.Blank) */
45
+ content?: ReactNode;
46
+ /** Количество скелетонов карточек для отображения при загрузке */
47
+ skeletonsAmount?: number;
48
+ } & Omit<NotificationPanelPopoverProps, 'children' | 'content'>;
49
+
50
+ /** Компонент панели для уведомлений */
51
+ export function NotificationPanel({
52
+ title,
53
+ triggerElement,
54
+ settings,
55
+ chips,
56
+ readAllButton,
57
+ footerButton,
58
+ content,
59
+ loading,
60
+ skeletonsAmount = 2,
61
+ ...rest
62
+ }: NotificationPanelProps) {
63
+ const skeletons = useMemo(() => Array.from({ length: skeletonsAmount }, (_, i) => i), [skeletonsAmount]);
64
+
65
+ return (
66
+ <NotificationPanelPopover
67
+ {...rest}
68
+ content={
69
+ <>
70
+ <div className={styles.notificationPanelHeader}>
71
+ <div className={styles.notificationPanelHeadline}>
72
+ <Typography.SansHeadlineS className={styles.notificationPanelTitle}>
73
+ <TruncateString text={title} data-test-id={TEST_IDS.title} />
74
+ </Typography.SansHeadlineS>
75
+
76
+ {settings && <NotificationPanelSettings {...settings} />}
77
+ </div>
78
+
79
+ <div className={styles.notificationPanelHeaderFunctions}>
80
+ <div className={styles.notificationPanelChips}>
81
+ {chips?.map(chip => (
82
+ <ChipToggle
83
+ {...chip}
84
+ key={chip.label}
85
+ data-test-id={`${TEST_IDS.chip}-${chip.label}`}
86
+ size={ChipToggle.sizes.Xs}
87
+ disabled={chip.disabled || loading}
88
+ />
89
+ ))}
90
+ </div>
91
+
92
+ {readAllButton && (
93
+ <ButtonFunction
94
+ {...readAllButton}
95
+ disabled={readAllButton.disabled || loading}
96
+ data-test-id={TEST_IDS.readAll}
97
+ />
98
+ )}
99
+ </div>
100
+ </div>
101
+
102
+ <Scroll size={Scroll.sizes.M} className={styles.notificationPanelBody}>
103
+ {loading ? (
104
+ <SkeletonContextProvider loading={loading || false}>
105
+ {skeletons.map(skeleton => (
106
+ <WithSkeleton key={skeleton} skeleton={<NotificationCardSkeleton />} />
107
+ ))}
108
+ </SkeletonContextProvider>
109
+ ) : (
110
+ content
111
+ )}
112
+ </Scroll>
113
+
114
+ {!loading && footerButton && (
115
+ <button className={styles.notificationPanelFooterButton} data-test-id={TEST_IDS.footerButton}>
116
+ <Typography.SansLabelS>{footerButton.label}</Typography.SansLabelS>
117
+ </button>
118
+ )}
119
+ </>
120
+ }
121
+ >
122
+ {triggerElement}
123
+ </NotificationPanelPopover>
124
+ );
125
+ }
126
+
127
+ NotificationPanel.placements = PopoverPrivate.placements;
128
+ NotificationPanel.triggers = PopoverPrivate.triggers;
129
+ NotificationPanel.widthStrategies = PopoverPrivate.widthStrategies;
130
+
131
+ export namespace NotificationPanel {
132
+ export const Blank: typeof NotificationPanelBlank = NotificationPanelBlank;
133
+ export type BlankProps = NotificationPanelBlankProps;
134
+ }
@@ -0,0 +1,65 @@
1
+ import cn from 'classnames';
2
+ import { ReactNode } from 'react';
3
+
4
+ import { IconPredefined, IconPredefinedProps } from '@snack-uikit/icon-predefined';
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 NotificationPanelBlankProps = WithSupportProps<{
12
+ /** Заголовок */
13
+ title: ReactNode;
14
+ /** Описание */
15
+ description?: ReactNode;
16
+ /** Иконка */
17
+ icon?: IconPredefinedProps['icon'];
18
+ /** Цвет обводки для иконки */
19
+ iconAppearance?: IconPredefinedProps['appearance'];
20
+ /** CSS-класс */
21
+ className?: string;
22
+ }>;
23
+
24
+ /** Компонента для "заглушки" вместо карточек в панели */
25
+ export function NotificationPanelBlank({
26
+ icon,
27
+ iconAppearance = IconPredefined.appearances.Neutral,
28
+ title,
29
+ description,
30
+ className,
31
+ ...rest
32
+ }: NotificationPanelBlankProps) {
33
+ return (
34
+ <div className={cn(styles.notificationPanelBlank, className)} {...extractSupportProps(rest)}>
35
+ {icon && (
36
+ <IconPredefined
37
+ icon={icon}
38
+ appearance={iconAppearance}
39
+ size={IconPredefined.sizes.L}
40
+ data-test-id={TEST_IDS.blank.icon}
41
+ />
42
+ )}
43
+
44
+ <div className={styles.notificationPanelBlankContent}>
45
+ <Typography.SansTitleS
46
+ tag={Typography.tags.div}
47
+ className={styles.notificationPanelBlankTitle}
48
+ data-test-id={TEST_IDS.blank.title}
49
+ >
50
+ {title}
51
+ </Typography.SansTitleS>
52
+
53
+ <Typography.SansBodyM
54
+ tag={Typography.tags.div}
55
+ className={styles.notificationPanelBlankDescription}
56
+ data-test-id={TEST_IDS.blank.description}
57
+ >
58
+ {description}
59
+ </Typography.SansBodyM>
60
+ </div>
61
+ </div>
62
+ );
63
+ }
64
+
65
+ NotificationPanelBlank.iconAppearances = IconPredefined.appearances;
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelBlank';
@@ -0,0 +1,32 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-notification-notificationPanel';
2
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
3
+
4
+ .notificationPanelBlank {
5
+ @include composite-var($notification-panel-blank-container);
6
+
7
+ display: flex;
8
+ flex-direction: column;
9
+ align-items: center;
10
+ box-sizing: border-box;
11
+ }
12
+
13
+ .notificationPanelBlankContent {
14
+ @include composite-var($notification-panel-blank-text);
15
+
16
+ display: flex;
17
+ flex-direction: column;
18
+ align-items: center;
19
+
20
+ box-sizing: border-box;
21
+
22
+ text-align: center;
23
+ }
24
+
25
+ .notificationPanelBlankTitle {
26
+ color: $sys-neutral-text-main;
27
+ }
28
+
29
+ .notificationPanelBlankDescription {
30
+ color: $sys-neutral-text-support;
31
+ white-space: pre-line;
32
+ }
@@ -0,0 +1,31 @@
1
+ import { ButtonSimple, ButtonSimpleProps } from '@snack-uikit/button';
2
+ import { ItemSingleProps } from '@snack-uikit/droplist';
3
+ import { KebabSVG } from '@snack-uikit/icons';
4
+
5
+ import { TEST_IDS } from '../../constants';
6
+ import { NotificationPanelSettingsDroplist } from './NotificationPanelSettingsDroplist';
7
+
8
+ export type NotificationPanelSettingsProps = {
9
+ /** Дополнительные действия панели */
10
+ actions?: Pick<
11
+ ItemSingleProps,
12
+ 'option' | 'onClick' | 'disabled' | 'icon' | 'description' | 'caption' | 'tagLabel'
13
+ >[];
14
+ /** Кнопка дополнительного действия панели */
15
+ button: Omit<ButtonSimpleProps, 'label' | 'type' | 'size' | 'data-test-id'>;
16
+ };
17
+
18
+ export function NotificationPanelSettings({ actions, button }: NotificationPanelSettingsProps) {
19
+ const buttonProps: ButtonSimpleProps = {
20
+ ...button,
21
+ size: ButtonSimple.sizes.S,
22
+ icon: button.icon || <KebabSVG />,
23
+ 'data-test-id': TEST_IDS.settings.droplistTrigger,
24
+ };
25
+
26
+ if (!actions?.length) {
27
+ return <ButtonSimple {...buttonProps} />;
28
+ }
29
+
30
+ return <NotificationPanelSettingsDroplist actions={actions} button={buttonProps} />;
31
+ }
@@ -0,0 +1,50 @@
1
+ import { useState } from 'react';
2
+
3
+ import { ButtonSimple, ButtonSimpleProps } from '@snack-uikit/button';
4
+ import { Droplist, ItemSingleProps } from '@snack-uikit/droplist';
5
+
6
+ import { TEST_IDS } from '../../constants';
7
+
8
+ type NotificationPanelSettingsDroplistProps = {
9
+ actions: ItemSingleProps[];
10
+ button: ButtonSimpleProps;
11
+ };
12
+
13
+ export function NotificationPanelSettingsDroplist({ actions, button }: NotificationPanelSettingsDroplistProps) {
14
+ const [isDroplistOpen, setDroplistOpen] = useState(false);
15
+
16
+ const {
17
+ firstElementRefCallback,
18
+ triggerElementRef,
19
+ handleDroplistFocusLeave,
20
+ handleTriggerKeyDown,
21
+ handleDroplistItemKeyDown,
22
+ handleDroplistItemClick,
23
+ } = Droplist.useKeyboardNavigation<HTMLButtonElement>({
24
+ setDroplistOpen,
25
+ });
26
+
27
+ return (
28
+ <Droplist
29
+ open={isDroplistOpen}
30
+ onOpenChange={setDroplistOpen}
31
+ firstElementRefCallback={firstElementRefCallback}
32
+ onFocusLeave={handleDroplistFocusLeave}
33
+ useScroll
34
+ triggerRef={triggerElementRef}
35
+ triggerElement={<ButtonSimple {...button} onKeyDown={handleTriggerKeyDown} />}
36
+ placement={Droplist.placements.BottomEnd}
37
+ data-test-id={TEST_IDS.settings.droplist}
38
+ >
39
+ {actions.map(action => (
40
+ <Droplist.ItemSingle
41
+ {...action}
42
+ key={action.option}
43
+ onClick={e => handleDroplistItemClick(e, action.onClick)}
44
+ onKeyDown={handleDroplistItemKeyDown}
45
+ data-test-id={TEST_IDS.settings.droplistAction}
46
+ />
47
+ ))}
48
+ </Droplist>
49
+ );
50
+ }
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelSettings';
@@ -0,0 +1,2 @@
1
+ export * from './NotificationPanelSettings';
2
+ export * from './NotificationPanelBlank';
@@ -0,0 +1,17 @@
1
+ export const TEST_IDS = {
2
+ title: 'notification-panel__title',
3
+ chip: 'notification-panel__chip',
4
+ settings: {
5
+ droplist: 'notification-panel__settings__droplist',
6
+ droplistTrigger: 'notification-panel__settings__droplist-trigger',
7
+ droplistAction: 'notification-panel__settings__droplist-action',
8
+ },
9
+ readAll: 'notification-panel__readAll',
10
+ footerButton: 'notification-panel__footerButton',
11
+ blank: {
12
+ icon: 'notification-panel__blank__icon',
13
+ title: 'notification-panel__blank__title',
14
+ description: 'notification-panel__blank__description',
15
+ },
16
+ skeleton: 'notification-panel__skeleton',
17
+ };
@@ -0,0 +1 @@
1
+ export * from './NotificationPanel';
@@ -0,0 +1,109 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-notification-notificationPanel';
2
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
3
+
4
+ .notificationPanelHeader {
5
+ @include composite-var($notification-panel-header-container);
6
+
7
+ position: relative;
8
+
9
+ display: flex;
10
+ flex-direction: column;
11
+
12
+ border-bottom-color: $sys-neutral-decor-default;
13
+ border-bottom-style: solid;
14
+
15
+ &::before {
16
+ pointer-events: none;
17
+ content: '';
18
+
19
+ position: absolute;
20
+ top: 0;
21
+ left: 0;
22
+
23
+ box-sizing: border-box;
24
+ width: 100%;
25
+ height: calc(100% + $border-width-notification-panel-container);
26
+
27
+ opacity: $opacity-a004;
28
+ background-color: $sys-neutral-accent-default;
29
+ border-radius: inherit;
30
+ }
31
+ }
32
+
33
+ .notificationPanelHeaderFunctions {
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: space-between;
37
+ }
38
+
39
+ .notificationPanelChips {
40
+ @include composite-var($notification-panel-header-chips);
41
+
42
+ display: flex;
43
+ align-items: center;
44
+ }
45
+
46
+ .notificationPanelHeadline {
47
+ @include composite-var($notification-panel-header-headline);
48
+
49
+ display: flex;
50
+ align-items: center;
51
+ color: $sys-neutral-text-main;
52
+ }
53
+
54
+ .notificationPanelTitle {
55
+ flex: 1 1 auto;
56
+ min-width: 0;
57
+ }
58
+
59
+ .notificationPanelBody {
60
+ flex: 1 1 auto;
61
+ min-height: 0;
62
+ }
63
+
64
+ .notificationPanelCard {
65
+ &:last-of-type {
66
+ border-bottom: none;
67
+ }
68
+ }
69
+
70
+ .notificationPanelFooterButton {
71
+ @include composite-var($notification-panel-button-container);
72
+
73
+ cursor: pointer;
74
+
75
+ flex-shrink: 0;
76
+
77
+ box-sizing: border-box;
78
+ width: 100%;
79
+ margin: 0;
80
+ padding: 0;
81
+
82
+ color: $sys-neutral-text-light;
83
+
84
+ background: none;
85
+ border-color: $sys-neutral-decor-default;
86
+ border-top-style: solid;
87
+ border-right: none;
88
+ border-bottom: none;
89
+ border-left: none;
90
+ outline: 0;
91
+ outline-offset: 0;
92
+
93
+ &:hover {
94
+ color: $sys-neutral-text-support;
95
+ }
96
+
97
+ &:focus-visible {
98
+ @include outline-inside-var($container-focused-s);
99
+
100
+ color: $sys-neutral-text-support;
101
+ border-color: transparent;
102
+ outline-color: $sys-available-complementary;
103
+ }
104
+
105
+ &:active {
106
+ color: $sys-neutral-text-main;
107
+ border-color: $sys-neutral-decor-default;
108
+ }
109
+ }
@@ -0,0 +1,2 @@
1
+ export * from './NotificationCard';
2
+ export * from './NotificationPanel';
@@ -0,0 +1,60 @@
1
+ import cn from 'classnames';
2
+ import { ReactNode } from 'react';
3
+
4
+ import { PopoverPrivate, PopoverPrivateProps } from '@snack-uikit/popover-private';
5
+ import { WithSupportProps } from '@snack-uikit/utils';
6
+
7
+ import styles from './styles.module.scss';
8
+
9
+ export type NotificationPanelPopoverProps = WithSupportProps<
10
+ {
11
+ content: ReactNode;
12
+ /** CSS-класс для элемента содержащего контент */
13
+ contentClassName?: string;
14
+ } & Pick<
15
+ PopoverPrivateProps,
16
+ | 'className'
17
+ | 'triggerClassName'
18
+ | 'open'
19
+ | 'onOpenChange'
20
+ | 'hoverDelayOpen'
21
+ | 'hoverDelayClose'
22
+ | 'offset'
23
+ | 'children'
24
+ | 'closeOnEscapeKey'
25
+ | 'triggerClickByKeys'
26
+ | 'triggerRef'
27
+ > &
28
+ Partial<Pick<PopoverPrivateProps, 'trigger' | 'placement'>>
29
+ >;
30
+
31
+ export function NotificationPanelPopover({
32
+ content,
33
+ trigger = PopoverPrivate.triggers.Click,
34
+ placement = PopoverPrivate.placements.BottomEnd,
35
+ children,
36
+ contentClassName,
37
+ ...otherProps
38
+ }: NotificationPanelPopoverProps) {
39
+ if (!children) {
40
+ return null;
41
+ }
42
+
43
+ return (
44
+ <PopoverPrivate
45
+ fallbackPlacements={[]}
46
+ placement={placement}
47
+ popoverContent={
48
+ <div className={styles.notificationPanelPopoverWrap}>
49
+ <div className={cn(styles.notificationPanelPopover, contentClassName)}>{content}</div>
50
+ </div>
51
+ }
52
+ trigger={trigger}
53
+ hasArrow={false}
54
+ heightStrategy={PopoverPrivate.heightStrategies.Lte}
55
+ {...otherProps}
56
+ >
57
+ {children}
58
+ </PopoverPrivate>
59
+ );
60
+ }
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelPopover';