@snack-uikit/notification 0.6.17-preview-e40879b4.0 → 0.6.17-preview-bd8ccc1f.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 (32) hide show
  1. package/README.md +11 -4
  2. package/dist/components/NotificationCard/NotificationCard.d.ts +6 -1
  3. package/dist/components/NotificationCard/NotificationCard.js +5 -3
  4. package/dist/components/NotificationCard/constants.d.ts +2 -0
  5. package/dist/components/NotificationCard/constants.js +2 -0
  6. package/dist/components/NotificationCard/styles.module.css +20 -14
  7. package/dist/components/NotificationPanel/NotificationPanel.d.ts +3 -0
  8. package/dist/components/NotificationPanel/NotificationPanel.js +3 -3
  9. package/dist/components/NotificationPanel/components/NotificationPanelBlank/NotificationPanelBlank.d.ts +3 -16
  10. package/dist/components/NotificationPanel/components/NotificationPanelBlank/NotificationPanelBlank.js +5 -7
  11. package/dist/components/NotificationPanel/components/NotificationPanelBlank/styles.module.css +1 -25
  12. package/dist/components/NotificationPanel/components/NotificationPanelDivider/NotificationPanelDivider.d.ts +8 -0
  13. package/dist/components/NotificationPanel/components/NotificationPanelDivider/NotificationPanelDivider.js +21 -0
  14. package/dist/components/NotificationPanel/components/NotificationPanelDivider/index.d.ts +1 -0
  15. package/dist/components/NotificationPanel/components/NotificationPanelDivider/index.js +1 -0
  16. package/dist/components/NotificationPanel/components/NotificationPanelDivider/styles.module.css +10 -0
  17. package/dist/components/NotificationPanel/constants.d.ts +0 -5
  18. package/dist/components/NotificationPanel/constants.js +0 -5
  19. package/dist/components/NotificationPanel/styles.module.css +12 -10
  20. package/dist/components/NotificationPanelPopover/styles.module.css +1 -1
  21. package/package.json +3 -3
  22. package/src/components/NotificationCard/NotificationCard.tsx +35 -1
  23. package/src/components/NotificationCard/constants.ts +2 -0
  24. package/src/components/NotificationCard/styles.module.scss +6 -0
  25. package/src/components/NotificationPanel/NotificationPanel.tsx +8 -8
  26. package/src/components/NotificationPanel/components/NotificationPanelBlank/NotificationPanelBlank.tsx +12 -46
  27. package/src/components/NotificationPanel/components/NotificationPanelBlank/styles.module.scss +1 -27
  28. package/src/components/NotificationPanel/components/NotificationPanelDivider/NotificationPanelDivider.tsx +21 -0
  29. package/src/components/NotificationPanel/components/NotificationPanelDivider/index.ts +1 -0
  30. package/src/components/NotificationPanel/components/NotificationPanelDivider/styles.module.scss +14 -0
  31. package/src/components/NotificationPanel/constants.ts +0 -5
  32. package/src/components/NotificationPanel/styles.module.scss +2 -0
package/README.md CHANGED
@@ -91,6 +91,8 @@ const cards = [
91
91
  | link | `Omit<LinkProps, "data-test-id" \| "appearance" \| "size" \| "textMode">` | - | Ссылка |
92
92
  | onClick | `MouseEventHandler<HTMLDivElement>` | - | Колбэк клика по карточке |
93
93
  | onVisible | `(cardId: string) => void` | - | Колбэк при попадании карточки в область видимости на 80% |
94
+ | primaryButton | `Omit<ButtonTonalProps, "data-test-id" \| "appearance" \| "size">` | - | Кнопка главного действия у карточки |
95
+ | secondaryButton | `Omit<ButtonSimpleProps, "data-test-id" \| "appearance" \| "size">` | - | Кнопка второстепенного действия у карточки |
94
96
  | actions | `Action[]` | - | Дополнительные действия у карточки |
95
97
  | className | `string` | - | CSS-класс |
96
98
  ## NotificationPanel
@@ -113,10 +115,15 @@ const cards = [
113
115
  ### Props
114
116
  | name | type | default value | description |
115
117
  |------|------|---------------|-------------|
116
- | title* | `ReactNode` | - | Заголовок |
117
- | description | `ReactNode` | - | Описание |
118
- | icon | `JSXElementConstructor<{ size?: number; className?: string; }>` | - | Иконка |
119
- | iconAppearance | enum Appearance: `"neutral"`, `"primary"`, `"red"`, `"orange"`, `"yellow"`, `"green"`, `"blue"`, `"violet"`, `"pink"` | - | Цвет обводки для иконки |
118
+ | title | `string` | - | Заголовок |
119
+ | className | `string` | - | CSS-класс |
120
+ | icon | `Pick<IconPredefinedProps, "appearance" \| "icon" \| "decor">` | - | Иконка |
121
+ | description | `string` | - | Подзаголовок |
122
+ ## NotificationPanel.Divider
123
+ ### Props
124
+ | name | type | default value | description |
125
+ |------|------|---------------|-------------|
126
+ | text* | `string` | - | Текст разделителя |
120
127
  | className | `string` | - | CSS-класс |
121
128
  ## NotificationPanelPopover
122
129
  Компонент-обёртка для NotificationPanel для использования как выпадающий элемент
@@ -1,4 +1,5 @@
1
1
  import { MouseEventHandler, ReactElement, ReactNode } from 'react';
2
+ import { ButtonSimpleProps, ButtonTonalProps } from '@snack-uikit/button';
2
3
  import { LinkProps } from '@snack-uikit/link';
3
4
  import { BaseItemProps } from '@snack-uikit/list';
4
5
  import { WithSupportProps } from '@snack-uikit/utils';
@@ -28,11 +29,15 @@ export type NotificationCardProps = WithSupportProps<{
28
29
  onClick?: MouseEventHandler<HTMLDivElement>;
29
30
  /** Колбэк при попадании карточки в область видимости на 80% */
30
31
  onVisible?(cardId: string): void;
32
+ /** Кнопка главного действия у карточки */
33
+ primaryButton?: Omit<ButtonTonalProps, 'size' | 'appearance' | 'data-test-id'>;
34
+ /** Кнопка второстепенного действия у карточки */
35
+ secondaryButton?: Omit<ButtonSimpleProps, 'size' | 'appearance' | 'data-test-id'>;
31
36
  /** Дополнительные действия у карточки */
32
37
  actions?: Action[];
33
38
  /** CSS-класс */
34
39
  className?: string;
35
40
  }>;
36
41
  /** Компонент карточки уведомления */
37
- export declare function NotificationCard({ id, appearance, label, unread, title, content, link, date, onClick, actions, onVisible, className, ...rest }: NotificationCardProps): import("react/jsx-runtime").JSX.Element;
42
+ export declare function NotificationCard({ id, appearance, label, unread, title, content, link, date, onClick, primaryButton, secondaryButton, actions, onVisible, className, ...rest }: NotificationCardProps): import("react/jsx-runtime").JSX.Element;
38
43
  export {};
@@ -12,6 +12,7 @@ var __rest = (this && this.__rest) || function (s, e) {
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  import cn from 'classnames';
14
14
  import { useEffect, useMemo, useRef, useState } from 'react';
15
+ import { ButtonSimple, ButtonTonal } from '@snack-uikit/button';
15
16
  import { Link } from '@snack-uikit/link';
16
17
  import { TruncateString } from '@snack-uikit/truncate-string';
17
18
  import { Typography } from '@snack-uikit/typography';
@@ -22,10 +23,11 @@ import { getIcon } from './helpers';
22
23
  import styles from './styles.module.css';
23
24
  /** Компонент карточки уведомления */
24
25
  export function NotificationCard(_a) {
25
- var { id, appearance = APPEARANCE.Neutral, label, unread, title, content, link, date, onClick, actions, onVisible, className } = _a, rest = __rest(_a, ["id", "appearance", "label", "unread", "title", "content", "link", "date", "onClick", "actions", "onVisible", "className"]);
26
- const { icon, linkOnColor } = useMemo(() => ({
26
+ var { id, appearance = APPEARANCE.Neutral, label, unread, title, content, link, date, onClick, primaryButton, secondaryButton, actions, onVisible, className } = _a, rest = __rest(_a, ["id", "appearance", "label", "unread", "title", "content", "link", "date", "onClick", "primaryButton", "secondaryButton", "actions", "onVisible", "className"]);
27
+ const { icon, linkOnColor, buttonAppearance } = useMemo(() => ({
27
28
  icon: getIcon(appearance),
28
29
  linkOnColor: appearance === APPEARANCE.ErrorCritical ? 'red' : undefined,
30
+ buttonAppearance: appearance === APPEARANCE.ErrorCritical ? 'destructive' : 'primary',
29
31
  }), [appearance]);
30
32
  const [isDroplistOpen, setDroplistOpen] = useState(false);
31
33
  const cardRef = useRef(null);
@@ -55,5 +57,5 @@ export function NotificationCard(_a) {
55
57
  e.stopPropagation();
56
58
  (_a = link === null || link === void 0 ? void 0 : link.onClick) === null || _a === void 0 ? void 0 : _a.call(link, e);
57
59
  };
58
- return (_jsxs("div", Object.assign({ ref: cardRef, role: 'button', onClick: onClick, tabIndex: 0 }, extractSupportProps(rest), { "data-appearance": appearance, "data-unread": unread || undefined, "data-clickable": Boolean(onClick) || undefined, "data-droplist-open": isDroplistOpen || undefined, className: cn(styles.notificationCard, className), children: [(actions === null || actions === void 0 ? void 0 : actions.length) && (_jsx(NotificationCardFunction, { actions: actions, open: isDroplistOpen, setDroplistOpen: setDroplistOpen })), label && (_jsx(Typography.LightLabelS, { tag: 'div', className: styles.notificationCardLabel, children: _jsx(TruncateString, { maxLines: 1, text: label, "data-test-id": TEST_IDS.label }) })), _jsxs("div", { className: styles.notificationCardTitle, children: [_jsx("div", { className: styles.notificationCardTitleIcon, children: icon }), _jsx(Typography.SansTitleS, { tag: 'div', className: styles.notificationCardTitleText, children: _jsx(TruncateString, { maxLines: 2, text: title, "data-test-id": TEST_IDS.title }) })] }), content && (_jsx(Typography.SansBodyS, { tag: 'div', className: styles.notificationCardContent, "data-test-id": TEST_IDS.content, children: content })), showFooter && (_jsxs("div", { className: styles.notificationCardFooter, children: [link && (_jsx(Link, Object.assign({}, link, { onClick: handleLinkClick, appearance: linkOnColor, textMode: 'default', size: 's', "data-test-id": TEST_IDS.link }))), date && (_jsx(Typography.LightLabelS, { className: styles.notificationCardDate, "data-test-id": TEST_IDS.date, children: date }))] }))] })));
60
+ return (_jsxs("div", Object.assign({ ref: cardRef, role: 'button', onClick: onClick, tabIndex: 0 }, extractSupportProps(rest), { "data-appearance": appearance, "data-unread": unread || undefined, "data-clickable": Boolean(onClick) || undefined, "data-droplist-open": isDroplistOpen || undefined, className: cn(styles.notificationCard, className), children: [(actions === null || actions === void 0 ? void 0 : actions.length) && (_jsx(NotificationCardFunction, { actions: actions, open: isDroplistOpen, setDroplistOpen: setDroplistOpen })), label && (_jsx(Typography.LightLabelS, { tag: 'div', className: styles.notificationCardLabel, children: _jsx(TruncateString, { maxLines: 1, text: label, "data-test-id": TEST_IDS.label }) })), _jsxs("div", { className: styles.notificationCardTitle, children: [_jsx("div", { className: styles.notificationCardTitleIcon, children: icon }), _jsx(Typography.SansTitleS, { tag: 'div', className: styles.notificationCardTitleText, children: _jsx(TruncateString, { maxLines: 2, text: title, "data-test-id": TEST_IDS.title }) })] }), content && (_jsx(Typography.SansBodyS, { tag: 'div', className: styles.notificationCardContent, "data-test-id": TEST_IDS.content, children: content })), (primaryButton || secondaryButton) && (_jsxs("div", { className: styles.notificationCardButtons, children: [secondaryButton && (_jsx(ButtonSimple, Object.assign({}, secondaryButton, { appearance: buttonAppearance, size: 's', "data-test-id": TEST_IDS.primaryButton }))), primaryButton && (_jsx(ButtonTonal, Object.assign({}, primaryButton, { appearance: buttonAppearance, size: 's', "data-test-id": TEST_IDS.secondaryButton })))] })), showFooter && (_jsxs("div", { className: styles.notificationCardFooter, children: [link && (_jsx(Link, Object.assign({}, link, { onClick: handleLinkClick, appearance: linkOnColor, textMode: 'default', size: 's', "data-test-id": TEST_IDS.link }))), date && (_jsx(Typography.LightLabelS, { className: styles.notificationCardDate, "data-test-id": TEST_IDS.date, children: date }))] }))] })));
59
61
  }
@@ -17,4 +17,6 @@ export declare const TEST_IDS: {
17
17
  droplistTrigger: string;
18
18
  droplistAction: string;
19
19
  };
20
+ primaryButton: string;
21
+ secondaryButton: string;
20
22
  };
@@ -17,4 +17,6 @@ export const TEST_IDS = {
17
17
  droplistTrigger: 'notification-card__droplist-trigger',
18
18
  droplistAction: 'notification-card__droplist-action',
19
19
  },
20
+ primaryButton: 'notification-card__primary-button',
21
+ secondaryButton: 'notification-card__secondary-button',
20
22
  };
@@ -11,7 +11,7 @@
11
11
 
12
12
  .notificationCardTitleText{
13
13
  box-sizing:border-box;
14
- color:var(--sys-neutral-text-main, #333333);
14
+ color:var(--sys-neutral-text-main, #33333b);
15
15
  }
16
16
 
17
17
  .notificationCardTitleIcon{
@@ -34,7 +34,7 @@
34
34
  display:flex;
35
35
  flex-direction:column;
36
36
  box-sizing:border-box;
37
- border-bottom-color:var(--sys-neutral-decor-default, #dedede);
37
+ border-bottom-color:var(--sys-neutral-decor-default, #dfe2ec);
38
38
  border-bottom-style:solid;
39
39
  }
40
40
  .notificationCard::before{
@@ -53,10 +53,10 @@
53
53
  outline-style:var(--border-state-focus-s-border-style, solid);
54
54
  outline-color:var(--border-state-focus-s-border-color, );
55
55
  border-bottom-color:transparent;
56
- outline-color:var(--sys-available-complementary, #131313);
56
+ outline-color:var(--sys-available-complementary, #141415);
57
57
  }
58
58
  .notificationCard[data-droplist-open]::before, .notificationCard:hover::before, .notificationCard:focus-visible::before, .notificationCard:focus-within:not(:focus)::before{
59
- background-color:var(--sys-neutral-accent-default, #757575);
59
+ background-color:var(--sys-neutral-accent-default, #6f717c);
60
60
  }
61
61
  .notificationCard[data-droplist-open] .notificationCardFunction, .notificationCard:hover .notificationCardFunction, .notificationCard:focus-visible .notificationCardFunction, .notificationCard:focus-within:not(:focus) .notificationCardFunction{
62
62
  pointer-events:auto;
@@ -67,28 +67,28 @@
67
67
  }
68
68
  .notificationCard[data-unread]::before{
69
69
  opacity:var(--opacity-a008, 0.08);
70
- background-color:var(--sys-neutral-accent-default, #757575);
70
+ background-color:var(--sys-neutral-accent-default, #6f717c);
71
71
  }
72
72
  .notificationCard[data-unread][data-droplist-open]::before, .notificationCard[data-unread]:hover::before, .notificationCard[data-unread]:focus-visible::before, .notificationCard[data-unread]:focus-within:not(:focus)::before{
73
73
  opacity:var(--opacity-a004, 0.04);
74
74
  }
75
75
  .notificationCard[data-appearance=neutral] .notificationCardTitleIcon{
76
- color:var(--sys-neutral-accent-default, #757575);
76
+ color:var(--sys-neutral-accent-default, #6f717c);
77
77
  }
78
78
  .notificationCard[data-appearance=error] .notificationCardTitleIcon, .notificationCard[data-appearance=errorCritical] .notificationCardTitleIcon{
79
- color:var(--sys-red-accent-default, #d93f2f);
79
+ color:var(--sys-red-accent-default, #cd3c3c);
80
80
  }
81
81
  .notificationCard[data-appearance=errorCritical][data-unread]::before, .notificationCard[data-appearance=errorCritical][data-droplist-open]::before, .notificationCard[data-appearance=errorCritical]:hover::before, .notificationCard[data-appearance=errorCritical]:focus-visible::before, .notificationCard[data-appearance=errorCritical]:focus-within:not(:focus)::before{
82
- background-color:var(--sys-red-accent-default, #d93f2f);
82
+ background-color:var(--sys-red-accent-default, #cd3c3c);
83
83
  }
84
84
  .notificationCard[data-appearance=errorCritical] .notificationCardTitleText{
85
- color:var(--sys-red-accent-default, #d93f2f);
85
+ color:var(--sys-red-accent-default, #cd3c3c);
86
86
  }
87
87
  .notificationCard[data-appearance=warning] .notificationCardTitleIcon{
88
- color:var(--sys-yellow-accent-default, #feb528);
88
+ color:var(--sys-yellow-accent-default, #fdca46);
89
89
  }
90
90
  .notificationCard[data-appearance=success] .notificationCardTitleIcon{
91
- color:var(--sys-green-accent-default, #0bbe8f);
91
+ color:var(--sys-green-accent-default, #57b762);
92
92
  }
93
93
  .notificationCard[data-skeleton]::before{
94
94
  display:none;
@@ -96,7 +96,7 @@
96
96
 
97
97
  .notificationCardLabel{
98
98
  display:grid;
99
- color:var(--sys-neutral-text-support, #565656);
99
+ color:var(--sys-neutral-text-support, #656771);
100
100
  }
101
101
 
102
102
  .notificationCardTitle{
@@ -109,7 +109,7 @@
109
109
 
110
110
  .notificationCardContent{
111
111
  box-sizing:border-box;
112
- color:var(--sys-neutral-text-support, #565656);
112
+ color:var(--sys-neutral-text-support, #656771);
113
113
  white-space:pre-line;
114
114
  }
115
115
 
@@ -123,6 +123,12 @@
123
123
  .notificationCardDate{
124
124
  flex:1 0 auto;
125
125
  box-sizing:border-box;
126
- color:var(--sys-neutral-text-light, #898989);
126
+ color:var(--sys-neutral-text-light, #868892);
127
127
  text-align:right;
128
+ }
129
+
130
+ .notificationCardButtons{
131
+ display:flex;
132
+ align-items:center;
133
+ justify-content:flex-end;
128
134
  }
@@ -3,6 +3,7 @@ import { ButtonFunctionProps } from '@snack-uikit/button';
3
3
  import { ChipToggleProps } from '@snack-uikit/chips';
4
4
  import { WithSupportProps } from '@snack-uikit/utils';
5
5
  import { NotificationPanelBlank, NotificationPanelBlankProps, NotificationPanelSettingsProps } from './components';
6
+ import { NotificationPanelDivider, NotificationPanelDividerProps } from './components/NotificationPanelDivider';
6
7
  export type { NotificationPanelBlankProps };
7
8
  export type NotificationPanelProps = WithSupportProps<{
8
9
  /** Заголовок панели */
@@ -37,4 +38,6 @@ export declare function NotificationPanel({ title, settings, chips, readAllButto
37
38
  export declare namespace NotificationPanel {
38
39
  const Blank: typeof NotificationPanelBlank;
39
40
  type BlankProps = NotificationPanelBlankProps;
41
+ const Divider: typeof NotificationPanelDivider;
42
+ type DividerProps = NotificationPanelDividerProps;
40
43
  }
@@ -22,16 +22,16 @@ import { Typography } from '@snack-uikit/typography';
22
22
  import { extractSupportProps } from '@snack-uikit/utils';
23
23
  import { NotificationCardSkeleton } from '../NotificationCard/components';
24
24
  import { NotificationPanelBlank, NotificationPanelSettings, } from './components';
25
+ import { NotificationPanelDivider } from './components/NotificationPanelDivider';
25
26
  import { TEST_IDS } from './constants';
26
27
  import styles from './styles.module.css';
27
28
  /** Компонент панели для уведомлений */
28
29
  export function NotificationPanel(_a) {
29
30
  var { title, settings, chips, readAllButton, footerButton, content, loading, skeletonsAmount = 2, scrollEndRef, scrollContainerRef, className } = _a, rest = __rest(_a, ["title", "settings", "chips", "readAllButton", "footerButton", "content", "loading", "skeletonsAmount", "scrollEndRef", "scrollContainerRef", "className"]);
30
31
  const skeletons = useMemo(() => Array.from({ length: skeletonsAmount }, (_, i) => i), [skeletonsAmount]);
31
- return (_jsxs("div", Object.assign({ className: cn(styles.wrapper, className) }, extractSupportProps(rest), { children: [_jsxs("div", { className: styles.notificationPanelHeader, children: [_jsxs("div", { className: styles.notificationPanelHeadline, children: [_jsx(Typography.SansHeadlineS, { className: styles.notificationPanelTitle, children: _jsx(TruncateString, { text: title, "data-test-id": TEST_IDS.title }) }), settings && _jsx(NotificationPanelSettings, Object.assign({}, settings))] }), _jsxs("div", { className: styles.notificationPanelHeaderFunctions, children: [_jsx("div", { className: styles.notificationPanelChips, children: chips === null || chips === void 0 ? void 0 : chips.map(chip => (_createElement(ChipToggle, Object.assign({}, chip, { key: chip.label, "data-test-id": `${TEST_IDS.chip}-${chip.label}`, size: 'xs', disabled: chip.disabled || loading })))) }), readAllButton && (_jsx(ButtonFunction, Object.assign({}, readAllButton, { disabled: readAllButton.disabled || loading, "data-test-id": TEST_IDS.readAll })))] })] }), _jsxs(Scroll, { size: 'm', className: styles.notificationPanelBody, ref: scrollContainerRef, children: [content, loading && (_jsx(SkeletonContextProvider, { loading: loading || false, children: skeletons.map(skeleton => (_jsx(WithSkeleton, { skeleton: _jsx(NotificationCardSkeleton, {}) }, skeleton))) })), _jsx("div", { className: styles.scrollStub, ref: scrollEndRef })] }),
32
- // !loading &&
33
- footerButton && (_jsx("button", { className: styles.notificationPanelFooterButton, "data-test-id": TEST_IDS.footerButton, children: _jsx(Typography.SansLabelS, { children: footerButton.label }) }))] })));
32
+ return (_jsxs("div", Object.assign({ className: cn(styles.wrapper, className) }, extractSupportProps(rest), { children: [_jsxs("div", { className: styles.notificationPanelHeader, children: [_jsxs("div", { className: styles.notificationPanelHeadline, children: [_jsx(Typography.SansHeadlineS, { className: styles.notificationPanelTitle, children: _jsx(TruncateString, { text: title, "data-test-id": TEST_IDS.title }) }), settings && _jsx(NotificationPanelSettings, Object.assign({}, settings))] }), _jsxs("div", { className: styles.notificationPanelHeaderFunctions, children: [_jsx("div", { className: styles.notificationPanelChips, children: chips === null || chips === void 0 ? void 0 : chips.map(chip => (_createElement(ChipToggle, Object.assign({}, chip, { key: chip.label, "data-test-id": `${TEST_IDS.chip}-${chip.label}`, size: 'xs', disabled: chip.disabled || loading })))) }), readAllButton && (_jsx(ButtonFunction, Object.assign({}, readAllButton, { disabled: readAllButton.disabled || loading, "data-test-id": TEST_IDS.readAll })))] })] }), _jsxs(Scroll, { size: 'm', className: styles.notificationPanelBody, ref: scrollContainerRef, children: [content, loading && (_jsx(SkeletonContextProvider, { loading: loading || false, children: skeletons.map(skeleton => (_jsx(WithSkeleton, { skeleton: _jsx(NotificationCardSkeleton, {}) }, skeleton))) })), _jsx("div", { className: styles.scrollStub, ref: scrollEndRef })] }), footerButton && (_jsx("button", { className: styles.notificationPanelFooterButton, "data-test-id": TEST_IDS.footerButton, children: _jsx(Typography.SansLabelS, { children: footerButton.label }) }))] })));
34
33
  }
35
34
  (function (NotificationPanel) {
36
35
  NotificationPanel.Blank = NotificationPanelBlank;
36
+ NotificationPanel.Divider = NotificationPanelDivider;
37
37
  })(NotificationPanel || (NotificationPanel = {}));
@@ -1,17 +1,4 @@
1
- import { ReactNode } from 'react';
2
- import { IconPredefinedProps } from '@snack-uikit/icon-predefined';
3
- import { WithSupportProps } from '@snack-uikit/utils';
4
- export type NotificationPanelBlankProps = WithSupportProps<{
5
- /** Заголовок */
6
- title: ReactNode;
7
- /** Описание */
8
- description?: ReactNode;
9
- /** Иконка */
10
- icon?: IconPredefinedProps['icon'];
11
- /** Цвет обводки для иконки */
12
- iconAppearance?: IconPredefinedProps['appearance'];
13
- /** CSS-класс */
14
- className?: string;
15
- }>;
1
+ import { InfoBlockProps } from '@snack-uikit/info-block';
2
+ export type NotificationPanelBlankProps = Omit<InfoBlockProps, 'footer' | 'align' | 'size'>;
16
3
  /** Компонента для "заглушки" вместо карточек в панели */
17
- export declare function NotificationPanelBlank({ icon, iconAppearance, title, description, className, ...rest }: NotificationPanelBlankProps): import("react/jsx-runtime").JSX.Element;
4
+ export declare function NotificationPanelBlank({ icon, className, ...props }: NotificationPanelBlankProps): import("react/jsx-runtime").JSX.Element;
@@ -9,15 +9,13 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
13
13
  import cn from 'classnames';
14
- import { IconPredefined } from '@snack-uikit/icon-predefined';
15
- import { Typography } from '@snack-uikit/typography';
16
- import { extractSupportProps } from '@snack-uikit/utils';
17
- import { TEST_IDS } from '../../constants';
14
+ import { InfoBlock } from '@snack-uikit/info-block';
18
15
  import styles from './styles.module.css';
19
16
  /** Компонента для "заглушки" вместо карточек в панели */
20
17
  export function NotificationPanelBlank(_a) {
21
- var { icon, iconAppearance = 'neutral', title, description, className } = _a, rest = __rest(_a, ["icon", "iconAppearance", "title", "description", "className"]);
22
- return (_jsxs("div", Object.assign({ className: cn(styles.notificationPanelBlank, className) }, extractSupportProps(rest), { children: [icon && _jsx(IconPredefined, { icon: icon, appearance: iconAppearance, size: 'l', "data-test-id": TEST_IDS.blank.icon }), _jsxs("div", { className: styles.notificationPanelBlankContent, children: [_jsx(Typography.SansTitleS, { tag: 'div', className: styles.notificationPanelBlankTitle, "data-test-id": TEST_IDS.blank.title, children: title }), _jsx(Typography.SansBodyM, { tag: 'div', className: styles.notificationPanelBlankDescription, "data-test-id": TEST_IDS.blank.description, children: description })] })] })));
18
+ var _b;
19
+ var { icon, className } = _a, props = __rest(_a, ["icon", "className"]);
20
+ return (_jsx(_Fragment, { children: _jsx(InfoBlock, Object.assign({}, props, { icon: icon ? Object.assign(Object.assign({}, icon), { appearance: (_b = icon.appearance) !== null && _b !== void 0 ? _b : 'neutral' }) : undefined, size: 'l', align: 'vertical', className: cn(styles.notificationPanelBlank, className) })) }));
23
21
  }
@@ -1,27 +1,3 @@
1
1
  .notificationPanelBlank{
2
- gap:var(--space-notification-panel-blank-gap, 16px);
3
- padding-top:var(--space-notification-panel-blank-vertical-padding, 24px);
4
- padding-bottom:var(--space-notification-panel-blank-vertical-padding, 24px);
5
- display:flex;
6
- flex-direction:column;
7
- align-items:center;
8
- box-sizing:border-box;
9
- }
10
-
11
- .notificationPanelBlankContent{
12
- gap:var(--space-notification-panel-blank-text-gap, 4px);
13
- display:flex;
14
- flex-direction:column;
15
- align-items:center;
16
- box-sizing:border-box;
17
- text-align:center;
18
- }
19
-
20
- .notificationPanelBlankTitle{
21
- color:var(--sys-neutral-text-main, #333333);
22
- }
23
-
24
- .notificationPanelBlankDescription{
25
- color:var(--sys-neutral-text-support, #565656);
26
- white-space:pre-line;
2
+ padding:var(--space-notification-panel-body-info-padding, 24px);
27
3
  }
@@ -0,0 +1,8 @@
1
+ import { WithSupportProps } from '@snack-uikit/utils';
2
+ export type NotificationPanelDividerProps = WithSupportProps<{
3
+ /** Текст разделителя */
4
+ text: string;
5
+ className?: string;
6
+ }>;
7
+ /** Разделитель для группировки или разделения карточек в списке */
8
+ export declare function NotificationPanelDivider({ text, className, ...rest }: NotificationPanelDividerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,21 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import cn from 'classnames';
14
+ import { Typography } from '@snack-uikit/typography';
15
+ import { extractSupportProps } from '@snack-uikit/utils';
16
+ import styles from './styles.module.css';
17
+ /** Разделитель для группировки или разделения карточек в списке */
18
+ export function NotificationPanelDivider(_a) {
19
+ var { text, className } = _a, rest = __rest(_a, ["text", "className"]);
20
+ return (_jsx(Typography.LightLabelS, Object.assign({ className: cn(styles.notificationPanelDivider, className) }, extractSupportProps(rest), { children: text })));
21
+ }
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelDivider';
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelDivider';
@@ -0,0 +1,10 @@
1
+ .notificationPanelDivider{
2
+ height:var(--size-notification-panel-readed-divider, 32px);
3
+ border-bottom-width:var(--border-width-notification-panel-container, 1px);
4
+ display:flex;
5
+ align-items:center;
6
+ justify-content:center;
7
+ color:var(--sys-neutral-text-light, #868892);
8
+ border-bottom-color:var(--sys-neutral-decor-default, #dfe2ec);
9
+ border-bottom-style:solid;
10
+ }
@@ -8,10 +8,5 @@ export declare const TEST_IDS: {
8
8
  };
9
9
  readAll: string;
10
10
  footerButton: string;
11
- blank: {
12
- icon: string;
13
- title: string;
14
- description: string;
15
- };
16
11
  skeleton: string;
17
12
  };
@@ -8,10 +8,5 @@ export const TEST_IDS = {
8
8
  },
9
9
  readAll: 'notification-panel__readAll',
10
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
11
  skeleton: 'notification-panel__skeleton',
17
12
  };
@@ -8,7 +8,7 @@
8
8
  position:relative;
9
9
  display:flex;
10
10
  flex-direction:column;
11
- border-bottom-color:var(--sys-neutral-decor-default, #dedede);
11
+ border-bottom-color:var(--sys-neutral-decor-default, #dfe2ec);
12
12
  border-bottom-style:solid;
13
13
  }
14
14
  .notificationPanelHeader::before{
@@ -21,7 +21,7 @@
21
21
  width:100%;
22
22
  height:calc(100% + var(--border-width-notification-panel-container, 1px));
23
23
  opacity:var(--opacity-a004, 0.04);
24
- background-color:var(--sys-neutral-accent-default, #757575);
24
+ background-color:var(--sys-neutral-accent-default, #6f717c);
25
25
  border-radius:inherit;
26
26
  }
27
27
 
@@ -41,7 +41,7 @@
41
41
  gap:var(--space-notification-panel-header-headline-gap, 16px);
42
42
  display:flex;
43
43
  align-items:center;
44
- color:var(--sys-neutral-text-main, #333333);
44
+ color:var(--sys-neutral-text-main, #33333b);
45
45
  }
46
46
 
47
47
  .notificationPanelTitle{
@@ -69,9 +69,9 @@
69
69
  width:100%;
70
70
  margin:0;
71
71
  padding:0;
72
- color:var(--sys-neutral-text-light, #898989);
72
+ color:var(--sys-neutral-text-light, #868892);
73
73
  background:none;
74
- border-color:var(--sys-neutral-decor-default, #dedede);
74
+ border-color:var(--sys-neutral-decor-default, #dfe2ec);
75
75
  border-top-style:solid;
76
76
  border-right:none;
77
77
  border-bottom:none;
@@ -80,26 +80,28 @@
80
80
  outline-offset:0;
81
81
  }
82
82
  .notificationPanelFooterButton:hover{
83
- color:var(--sys-neutral-text-support, #565656);
83
+ color:var(--sys-neutral-text-support, #656771);
84
84
  }
85
85
  .notificationPanelFooterButton:focus-visible{
86
86
  outline-width:var(--border-state-focus-s-border-width, 2px);
87
87
  outline-style:var(--border-state-focus-s-border-style, solid);
88
88
  outline-color:var(--border-state-focus-s-border-color, );
89
89
  outline-offset:calc(var(--border-state-focus-s-border-width, 2px) * -1);
90
- color:var(--sys-neutral-text-support, #565656);
90
+ color:var(--sys-neutral-text-support, #656771);
91
91
  border-color:transparent;
92
- outline-color:var(--sys-available-complementary, #131313);
92
+ outline-color:var(--sys-available-complementary, #141415);
93
93
  }
94
94
  .notificationPanelFooterButton:active{
95
- color:var(--sys-neutral-text-main, #333333);
96
- border-color:var(--sys-neutral-decor-default, #dedede);
95
+ color:var(--sys-neutral-text-main, #33333b);
96
+ border-color:var(--sys-neutral-decor-default, #dfe2ec);
97
97
  }
98
98
 
99
99
  .wrapper{
100
100
  box-sizing:border-box;
101
101
  width:100%;
102
102
  height:100%;
103
+ display:flex;
104
+ flex-direction:column;
103
105
  }
104
106
 
105
107
  .scrollStub{
@@ -15,6 +15,6 @@
15
15
  display:flex;
16
16
  flex-direction:column;
17
17
  height:100%;
18
- background-color:var(--sys-neutral-background2-level, #fdfdfd);
18
+ background-color:var(--sys-neutral-background2-level, #ffffff);
19
19
  box-shadow:var(--box-shadow-elevation-level2, 0px 0px 4px 0px rgba(0, 0, 0, 0.0392156863), 0px 4px 8px 0px rgba(0, 0, 0, 0.0392156863));
20
20
  }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "Notification",
7
- "version": "0.6.17-preview-e40879b4.0",
7
+ "version": "0.6.17-preview-bd8ccc1f.0",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -34,8 +34,8 @@
34
34
  "dependencies": {
35
35
  "@snack-uikit/button": "0.16.0",
36
36
  "@snack-uikit/chips": "0.11.6",
37
- "@snack-uikit/icon-predefined": "0.4.1",
38
37
  "@snack-uikit/icons": "0.20.1",
38
+ "@snack-uikit/info-block": "0.1.2",
39
39
  "@snack-uikit/link": "0.11.1",
40
40
  "@snack-uikit/list": "0.3.3",
41
41
  "@snack-uikit/popover-private": "0.13.0",
@@ -47,5 +47,5 @@
47
47
  "@snack-uikit/utils": "3.2.0",
48
48
  "classnames": "2.3.2"
49
49
  },
50
- "gitHead": "83c6596d673690b97e619f2ff4745be264bf6b50"
50
+ "gitHead": "2506f16d0e158f04845ab76647e92582bd556cb2"
51
51
  }
@@ -1,6 +1,7 @@
1
1
  import cn from 'classnames';
2
2
  import { MouseEventHandler, ReactElement, ReactNode, useEffect, useMemo, useRef, useState } from 'react';
3
3
 
4
+ import { ButtonSimple, ButtonSimpleProps, ButtonTonal, ButtonTonalProps } from '@snack-uikit/button';
4
5
  import { Link, LinkProps } from '@snack-uikit/link';
5
6
  import { BaseItemProps } from '@snack-uikit/list';
6
7
  import { TruncateString } from '@snack-uikit/truncate-string';
@@ -39,6 +40,10 @@ export type NotificationCardProps = WithSupportProps<{
39
40
  onClick?: MouseEventHandler<HTMLDivElement>;
40
41
  /** Колбэк при попадании карточки в область видимости на 80% */
41
42
  onVisible?(cardId: string): void;
43
+ /** Кнопка главного действия у карточки */
44
+ primaryButton?: Omit<ButtonTonalProps, 'size' | 'appearance' | 'data-test-id'>;
45
+ /** Кнопка второстепенного действия у карточки */
46
+ secondaryButton?: Omit<ButtonSimpleProps, 'size' | 'appearance' | 'data-test-id'>;
42
47
  /** Дополнительные действия у карточки */
43
48
  actions?: Action[];
44
49
  /** CSS-класс */
@@ -56,15 +61,22 @@ export function NotificationCard({
56
61
  link,
57
62
  date,
58
63
  onClick,
64
+ primaryButton,
65
+ secondaryButton,
59
66
  actions,
60
67
  onVisible,
61
68
  className,
62
69
  ...rest
63
70
  }: NotificationCardProps) {
64
- const { icon, linkOnColor } = useMemo<{ icon: ReturnType<typeof getIcon>; linkOnColor: LinkProps['appearance'] }>(
71
+ const { icon, linkOnColor, buttonAppearance } = useMemo<{
72
+ icon: ReturnType<typeof getIcon>;
73
+ linkOnColor: LinkProps['appearance'];
74
+ buttonAppearance: ButtonTonalProps['appearance'];
75
+ }>(
65
76
  () => ({
66
77
  icon: getIcon(appearance),
67
78
  linkOnColor: appearance === APPEARANCE.ErrorCritical ? 'red' : undefined,
79
+ buttonAppearance: appearance === APPEARANCE.ErrorCritical ? 'destructive' : 'primary',
68
80
  }),
69
81
  [appearance],
70
82
  );
@@ -144,6 +156,28 @@ export function NotificationCard({
144
156
  </Typography.SansBodyS>
145
157
  )}
146
158
 
159
+ {(primaryButton || secondaryButton) && (
160
+ <div className={styles.notificationCardButtons}>
161
+ {secondaryButton && (
162
+ <ButtonSimple
163
+ {...secondaryButton}
164
+ appearance={buttonAppearance}
165
+ size='s'
166
+ data-test-id={TEST_IDS.primaryButton}
167
+ />
168
+ )}
169
+
170
+ {primaryButton && (
171
+ <ButtonTonal
172
+ {...primaryButton}
173
+ appearance={buttonAppearance}
174
+ size='s'
175
+ data-test-id={TEST_IDS.secondaryButton}
176
+ />
177
+ )}
178
+ </div>
179
+ )}
180
+
147
181
  {showFooter && (
148
182
  <div className={styles.notificationCardFooter}>
149
183
  {link && (
@@ -18,4 +18,6 @@ export const TEST_IDS = {
18
18
  droplistTrigger: 'notification-card__droplist-trigger',
19
19
  droplistAction: 'notification-card__droplist-action',
20
20
  },
21
+ primaryButton: 'notification-card__primary-button',
22
+ secondaryButton: 'notification-card__secondary-button',
21
23
  };
@@ -170,3 +170,9 @@
170
170
  color: $sys-neutral-text-light;
171
171
  text-align: right;
172
172
  }
173
+
174
+ .notificationCardButtons {
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: flex-end;
178
+ }
@@ -16,6 +16,7 @@ import {
16
16
  NotificationPanelSettings,
17
17
  NotificationPanelSettingsProps,
18
18
  } from './components';
19
+ import { NotificationPanelDivider, NotificationPanelDividerProps } from './components/NotificationPanelDivider';
19
20
  import { TEST_IDS } from './constants';
20
21
  import styles from './styles.module.scss';
21
22
 
@@ -114,14 +115,11 @@ export function NotificationPanel({
114
115
  <div className={styles.scrollStub} ref={scrollEndRef} />
115
116
  </Scroll>
116
117
 
117
- {
118
- // !loading &&
119
- footerButton && (
120
- <button className={styles.notificationPanelFooterButton} data-test-id={TEST_IDS.footerButton}>
121
- <Typography.SansLabelS>{footerButton.label}</Typography.SansLabelS>
122
- </button>
123
- )
124
- }
118
+ {footerButton && (
119
+ <button className={styles.notificationPanelFooterButton} data-test-id={TEST_IDS.footerButton}>
120
+ <Typography.SansLabelS>{footerButton.label}</Typography.SansLabelS>
121
+ </button>
122
+ )}
125
123
  </div>
126
124
  );
127
125
  }
@@ -129,4 +127,6 @@ export function NotificationPanel({
129
127
  export namespace NotificationPanel {
130
128
  export const Blank: typeof NotificationPanelBlank = NotificationPanelBlank;
131
129
  export type BlankProps = NotificationPanelBlankProps;
130
+ export const Divider: typeof NotificationPanelDivider = NotificationPanelDivider;
131
+ export type DividerProps = NotificationPanelDividerProps;
132
132
  }
@@ -1,56 +1,22 @@
1
1
  import cn from 'classnames';
2
- import { ReactNode } from 'react';
3
2
 
4
- import { IconPredefined, IconPredefinedProps } from '@snack-uikit/icon-predefined';
5
- import { Typography } from '@snack-uikit/typography';
6
- import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
3
+ import { InfoBlock, InfoBlockProps } from '@snack-uikit/info-block';
7
4
 
8
- import { TEST_IDS } from '../../constants';
9
5
  import styles from './styles.module.scss';
10
6
 
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
- }>;
7
+ export type NotificationPanelBlankProps = Omit<InfoBlockProps, 'footer' | 'align' | 'size'>;
23
8
 
24
9
  /** Компонента для "заглушки" вместо карточек в панели */
25
- export function NotificationPanelBlank({
26
- icon,
27
- iconAppearance = 'neutral',
28
- title,
29
- description,
30
- className,
31
- ...rest
32
- }: NotificationPanelBlankProps) {
10
+ export function NotificationPanelBlank({ icon, className, ...props }: NotificationPanelBlankProps) {
33
11
  return (
34
- <div className={cn(styles.notificationPanelBlank, className)} {...extractSupportProps(rest)}>
35
- {icon && <IconPredefined icon={icon} appearance={iconAppearance} size='l' data-test-id={TEST_IDS.blank.icon} />}
36
-
37
- <div className={styles.notificationPanelBlankContent}>
38
- <Typography.SansTitleS
39
- tag='div'
40
- className={styles.notificationPanelBlankTitle}
41
- data-test-id={TEST_IDS.blank.title}
42
- >
43
- {title}
44
- </Typography.SansTitleS>
45
-
46
- <Typography.SansBodyM
47
- tag='div'
48
- className={styles.notificationPanelBlankDescription}
49
- data-test-id={TEST_IDS.blank.description}
50
- >
51
- {description}
52
- </Typography.SansBodyM>
53
- </div>
54
- </div>
12
+ <>
13
+ <InfoBlock
14
+ {...props}
15
+ icon={icon ? { ...icon, appearance: icon.appearance ?? 'neutral' } : undefined}
16
+ size='l'
17
+ align='vertical'
18
+ className={cn(styles.notificationPanelBlank, className)}
19
+ />
20
+ </>
55
21
  );
56
22
  }
@@ -2,31 +2,5 @@
2
2
  @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
3
3
 
4
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;
5
+ @include composite-var($notification-panel-body-info-container);
32
6
  }
@@ -0,0 +1,21 @@
1
+ import cn from 'classnames';
2
+
3
+ import { Typography } from '@snack-uikit/typography';
4
+ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
5
+
6
+ import styles from './styles.module.scss';
7
+
8
+ export type NotificationPanelDividerProps = WithSupportProps<{
9
+ /** Текст разделителя */
10
+ text: string;
11
+ className?: string;
12
+ }>;
13
+
14
+ /** Разделитель для группировки или разделения карточек в списке */
15
+ export function NotificationPanelDivider({ text, className, ...rest }: NotificationPanelDividerProps) {
16
+ return (
17
+ <Typography.LightLabelS className={cn(styles.notificationPanelDivider, className)} {...extractSupportProps(rest)}>
18
+ {text}
19
+ </Typography.LightLabelS>
20
+ );
21
+ }
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelDivider';
@@ -0,0 +1,14 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-notification-notificationPanel';
2
+
3
+ .notificationPanelDivider {
4
+ @include composite-var($notification-panel-readed-divider);
5
+
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: center;
9
+
10
+ color: $sys-neutral-text-light;
11
+
12
+ border-bottom-color: $sys-neutral-decor-default;
13
+ border-bottom-style: solid;
14
+ }
@@ -8,10 +8,5 @@ export const TEST_IDS = {
8
8
  },
9
9
  readAll: 'notification-panel__readAll',
10
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
11
  skeleton: 'notification-panel__skeleton',
17
12
  };
@@ -112,6 +112,8 @@
112
112
  box-sizing: border-box;
113
113
  width: 100%;
114
114
  height: 100%;
115
+ display: flex;
116
+ flex-direction: column;
115
117
  }
116
118
 
117
119
  .scrollStub {