@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,97 @@
1
+ .notificationPanelHeader{
2
+ padding-left:var(--space-notification-panel-header-horizontal-padding, 24px);
3
+ padding-right:var(--space-notification-panel-header-horizontal-padding, 24px);
4
+ padding-top:var(--space-notification-panel-header-padding-top, 24px);
5
+ padding-bottom:var(--space-notification-panel-header-padding-bottom, 16px);
6
+ gap:var(--space-notification-panel-header-gap, 16px);
7
+ border-bottom-width:var(--border-width-notification-panel-container, 1px);
8
+ position:relative;
9
+ display:flex;
10
+ flex-direction:column;
11
+ border-bottom-color:var(--sys-neutral-decor-default, #dedede);
12
+ border-bottom-style:solid;
13
+ }
14
+ .notificationPanelHeader::before{
15
+ pointer-events:none;
16
+ content:"";
17
+ position:absolute;
18
+ top:0;
19
+ left:0;
20
+ box-sizing:border-box;
21
+ width:100%;
22
+ height:calc(100% + var(--border-width-notification-panel-container, 1px));
23
+ opacity:var(--opacity-a004, 0.04);
24
+ background-color:var(--sys-neutral-accent-default, #757575);
25
+ border-radius:inherit;
26
+ }
27
+
28
+ .notificationPanelHeaderFunctions{
29
+ display:flex;
30
+ align-items:center;
31
+ justify-content:space-between;
32
+ }
33
+
34
+ .notificationPanelChips{
35
+ gap:var(--space-notification-panel-header-chips-gap, 8px);
36
+ display:flex;
37
+ align-items:center;
38
+ }
39
+
40
+ .notificationPanelHeadline{
41
+ gap:var(--space-notification-panel-header-headline-gap, 16px);
42
+ display:flex;
43
+ align-items:center;
44
+ color:var(--sys-neutral-text-main, #333333);
45
+ }
46
+
47
+ .notificationPanelTitle{
48
+ flex:1 1 auto;
49
+ min-width:0;
50
+ }
51
+
52
+ .notificationPanelBody{
53
+ flex:1 1 auto;
54
+ min-height:0;
55
+ }
56
+
57
+ .notificationPanelCard:last-of-type{
58
+ border-bottom:none;
59
+ }
60
+
61
+ .notificationPanelFooterButton{
62
+ border-top-width:var(--border-width-notification-panel-container, 1px);
63
+ border-bottom-right-radius:var(--radius-notification-panel-footer-radius-bottom, 16px);
64
+ border-bottom-left-radius:var(--radius-notification-panel-footer-radius-bottom, 16px);
65
+ height:var(--size-notification-panel-button, 32px);
66
+ cursor:pointer;
67
+ flex-shrink:0;
68
+ box-sizing:border-box;
69
+ width:100%;
70
+ margin:0;
71
+ padding:0;
72
+ color:var(--sys-neutral-text-light, #898989);
73
+ background:none;
74
+ border-color:var(--sys-neutral-decor-default, #dedede);
75
+ border-top-style:solid;
76
+ border-right:none;
77
+ border-bottom:none;
78
+ border-left:none;
79
+ outline:0;
80
+ outline-offset:0;
81
+ }
82
+ .notificationPanelFooterButton:hover{
83
+ color:var(--sys-neutral-text-support, #565656);
84
+ }
85
+ .notificationPanelFooterButton:focus-visible{
86
+ outline-width:var(--border-state-focus-s-border-width, 2px);
87
+ outline-style:var(--border-state-focus-s-border-style, solid);
88
+ outline-color:var(--border-state-focus-s-border-color, );
89
+ outline-offset:calc(var(--border-state-focus-s-border-width, 2px) * -1);
90
+ color:var(--sys-neutral-text-support, #565656);
91
+ border-color:transparent;
92
+ outline-color:var(--sys-available-complementary, #131313);
93
+ }
94
+ .notificationPanelFooterButton:active{
95
+ color:var(--sys-neutral-text-main, #333333);
96
+ border-color:var(--sys-neutral-decor-default, #dedede);
97
+ }
@@ -0,0 +1,2 @@
1
+ export * from './NotificationCard';
2
+ export * from './NotificationPanel';
@@ -0,0 +1,2 @@
1
+ export * from './NotificationCard';
2
+ export * from './NotificationPanel';
@@ -0,0 +1,9 @@
1
+ import { ReactNode } from 'react';
2
+ import { PopoverPrivateProps } from '@snack-uikit/popover-private';
3
+ import { WithSupportProps } from '@snack-uikit/utils';
4
+ export type NotificationPanelPopoverProps = WithSupportProps<{
5
+ content: ReactNode;
6
+ /** CSS-класс для элемента содержащего контент */
7
+ contentClassName?: string;
8
+ } & Pick<PopoverPrivateProps, 'className' | 'triggerClassName' | 'open' | 'onOpenChange' | 'hoverDelayOpen' | 'hoverDelayClose' | 'offset' | 'children' | 'closeOnEscapeKey' | 'triggerClickByKeys' | 'triggerRef'> & Partial<Pick<PopoverPrivateProps, 'trigger' | 'placement'>>>;
9
+ export declare function NotificationPanelPopover({ content, trigger, placement, children, contentClassName, ...otherProps }: NotificationPanelPopoverProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,22 @@
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 { PopoverPrivate } from '@snack-uikit/popover-private';
15
+ import styles from './styles.module.css';
16
+ export function NotificationPanelPopover(_a) {
17
+ var { content, trigger = PopoverPrivate.triggers.Click, placement = PopoverPrivate.placements.BottomEnd, children, contentClassName } = _a, otherProps = __rest(_a, ["content", "trigger", "placement", "children", "contentClassName"]);
18
+ if (!children) {
19
+ return null;
20
+ }
21
+ return (_jsx(PopoverPrivate, Object.assign({ fallbackPlacements: [], placement: placement, popoverContent: _jsx("div", Object.assign({ className: styles.notificationPanelPopoverWrap }, { children: _jsx("div", Object.assign({ className: cn(styles.notificationPanelPopover, contentClassName) }, { children: content })) })), trigger: trigger, hasArrow: false, heightStrategy: PopoverPrivate.heightStrategies.Lte }, otherProps, { children: children })));
22
+ }
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelPopover';
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelPopover';
@@ -0,0 +1,20 @@
1
+ .notificationPanelPopoverWrap{
2
+ padding-top:var(--space-notification-panel-container-padding-top, 4px);
3
+ padding-bottom:var(--space-notification-panel-container-padding-bottom, 24px);
4
+ min-height:var(--size-notification-panel-container, 388px);
5
+ display:flex;
6
+ flex-direction:column;
7
+ box-sizing:border-box;
8
+ height:100%;
9
+ }
10
+
11
+ .notificationPanelPopover{
12
+ border-radius:var(--radius-notification-panel-panel, 16px);
13
+ width:var(--size-notification-panel-panel, 464px);
14
+ overflow:hidden;
15
+ display:flex;
16
+ flex-direction:column;
17
+ height:100%;
18
+ background-color:var(--sys-neutral-background2-level, #fdfdfd);
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
+ }
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelPopover';
@@ -0,0 +1 @@
1
+ export * from './NotificationPanelPopover';
@@ -0,0 +1 @@
1
+ export * from './components';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './components';
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@snack-uikit/notification",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "title": "Notification",
7
+ "version": "0.3.17-preview-85c5f47b.0",
8
+ "sideEffects": [
9
+ "*.css",
10
+ "*.woff",
11
+ "*.woff2"
12
+ ],
13
+ "description": "",
14
+ "main": "./dist/index.js",
15
+ "module": "./dist/index.js",
16
+ "homepage": "https://github.com/cloud-ru-tech/snack-uikit/tree/master/packages/notification",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/cloud-ru-tech/snack-uikit.git",
20
+ "directory": "packages/notification"
21
+ },
22
+ "author": "Белов Алексей <anbelov@cloud.ru>",
23
+ "contributors": [
24
+ "Белов Алексей <anbelov@cloud.ru>"
25
+ ],
26
+ "files": [
27
+ "dist",
28
+ "src",
29
+ "./CHANGELOG.md",
30
+ "./LICENSE"
31
+ ],
32
+ "license": "Apache-2.0",
33
+ "scripts": {},
34
+ "dependencies": {
35
+ "@snack-uikit/button": "0.13.7-preview-85c5f47b.0",
36
+ "@snack-uikit/chips": "0.8.5-preview-85c5f47b.0",
37
+ "@snack-uikit/droplist": "0.10.13-preview-85c5f47b.0",
38
+ "@snack-uikit/icon-predefined": "0.2.6-preview-85c5f47b.0",
39
+ "@snack-uikit/icons": "0.18.2-preview-85c5f47b.0",
40
+ "@snack-uikit/link": "0.7.1-preview-85c5f47b.0",
41
+ "@snack-uikit/popover-private": "0.10.1-preview-85c5f47b.0",
42
+ "@snack-uikit/scroll": "0.3.5-preview-85c5f47b.0",
43
+ "@snack-uikit/skeleton": "0.2.5-preview-85c5f47b.0",
44
+ "@snack-uikit/truncate-string": "0.2.17-preview-85c5f47b.0",
45
+ "@snack-uikit/typography": "0.4.5-preview-85c5f47b.0",
46
+ "@snack-uikit/utils": "2.0.2-preview-85c5f47b.0",
47
+ "classnames": "2.3.2"
48
+ },
49
+ "gitHead": "6a7eef41d780d945f64f791448eaa72b9e0ae72d"
50
+ }
@@ -0,0 +1,172 @@
1
+ import cn from 'classnames';
2
+ import { MouseEventHandler, ReactNode, useEffect, useMemo, useRef, useState } from 'react';
3
+
4
+ import { ItemSingleProps } from '@snack-uikit/droplist';
5
+ import { Link, LinkProps } from '@snack-uikit/link';
6
+ import { TruncateString } from '@snack-uikit/truncate-string';
7
+ import { Typography } from '@snack-uikit/typography';
8
+ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
9
+
10
+ import { NotificationCardFunction } from './components';
11
+ import { Appearance, TEST_IDS } from './constants';
12
+ import { getIcon } from './helpers';
13
+ import styles from './styles.module.scss';
14
+
15
+ export type NotificationCardProps = WithSupportProps<{
16
+ /** Идентификатор уведомления */
17
+ id: string;
18
+ /** Тип уведомления */
19
+ appearance?: Appearance;
20
+ /** Лейбл перед заголовком */
21
+ label?: string;
22
+ /** Управление состоянием прочитано/не прочитано */
23
+ unread?: boolean;
24
+ /** Заголовок уведомления */
25
+ title: string;
26
+ /** Контент уведомления */
27
+ content: ReactNode;
28
+ /** Ссылка */
29
+ link?: Omit<LinkProps, 'size' | 'onColor' | 'onSurface' | 'data-test-id'>;
30
+ /** Дата уведомления */
31
+ date: string;
32
+ /** Колбэк клика по карточке */
33
+ onClick?: MouseEventHandler<HTMLDivElement>;
34
+ /** Колбэк при попадании карточки в область видимости на 80% */
35
+ onVisible?(cardId: string): void;
36
+ /** Дополнительные действия у карточки */
37
+ actions?: Pick<
38
+ ItemSingleProps,
39
+ 'option' | 'onClick' | 'disabled' | 'icon' | 'description' | 'caption' | 'tagLabel'
40
+ >[];
41
+ /** CSS-класс */
42
+ className?: string;
43
+ }>;
44
+
45
+ /** Компонент карточки уведомления */
46
+ export function NotificationCard({
47
+ id,
48
+ appearance = Appearance.Neutral,
49
+ label,
50
+ unread,
51
+ title,
52
+ content,
53
+ link,
54
+ date,
55
+ onClick,
56
+ actions,
57
+ onVisible,
58
+ className,
59
+ ...rest
60
+ }: NotificationCardProps) {
61
+ const { icon, linkOnColor } = useMemo(
62
+ () => ({
63
+ icon: getIcon(appearance),
64
+ linkOnColor: appearance === Appearance.ErrorCritical ? Link.onColors.Red : undefined,
65
+ }),
66
+ [appearance],
67
+ );
68
+
69
+ const [isDroplistOpen, setDroplistOpen] = useState(false);
70
+
71
+ const cardRef = useRef<HTMLDivElement>(null);
72
+
73
+ useEffect(() => {
74
+ if (!unread || !onVisible) {
75
+ return;
76
+ }
77
+
78
+ const handleIntersection = (entries: IntersectionObserverEntry[]) => {
79
+ const [entry] = entries;
80
+
81
+ if (entry.isIntersecting) {
82
+ onVisible(id);
83
+ }
84
+ };
85
+
86
+ const observer = new IntersectionObserver(handleIntersection, {
87
+ root: null,
88
+ threshold: 0.8,
89
+ rootMargin: '0px',
90
+ });
91
+
92
+ observer.observe(cardRef.current as HTMLElement);
93
+
94
+ return () => {
95
+ observer.disconnect();
96
+ };
97
+ }, [id, onVisible, unread]);
98
+
99
+ const showFooter = Boolean(link || date);
100
+
101
+ const handleLinkClick: MouseEventHandler<HTMLAnchorElement> = e => {
102
+ e.stopPropagation();
103
+
104
+ link?.onClick?.(e);
105
+ };
106
+
107
+ return (
108
+ <div
109
+ ref={cardRef}
110
+ role='button'
111
+ onClick={onClick}
112
+ tabIndex={0}
113
+ {...extractSupportProps(rest)}
114
+ data-appearance={appearance}
115
+ data-unread={unread || undefined}
116
+ data-clickable={Boolean(onClick) || undefined}
117
+ data-droplist-open={isDroplistOpen || undefined}
118
+ className={cn(styles.notificationCard, className)}
119
+ >
120
+ {actions?.length && (
121
+ <NotificationCardFunction actions={actions} open={isDroplistOpen} setDroplistOpen={setDroplistOpen} />
122
+ )}
123
+
124
+ {label && (
125
+ <Typography.LightLabelS tag={Typography.tags.div} className={styles.notificationCardLabel}>
126
+ <TruncateString maxLines={1} text={label} data-test-id={TEST_IDS.label} />
127
+ </Typography.LightLabelS>
128
+ )}
129
+
130
+ <div className={styles.notificationCardTitle}>
131
+ <div className={styles.notificationCardTitleIcon}>{icon}</div>
132
+
133
+ <Typography.SansTitleS tag={Typography.tags.div} className={styles.notificationCardTitleText}>
134
+ <TruncateString maxLines={2} text={title} data-test-id={TEST_IDS.title} />
135
+ </Typography.SansTitleS>
136
+ </div>
137
+
138
+ {content && (
139
+ <Typography.SansBodyS
140
+ tag={Typography.tags.div}
141
+ className={styles.notificationCardContent}
142
+ data-test-id={TEST_IDS.content}
143
+ >
144
+ {content}
145
+ </Typography.SansBodyS>
146
+ )}
147
+
148
+ {showFooter && (
149
+ <div className={styles.notificationCardFooter}>
150
+ {link && (
151
+ <Link
152
+ {...link}
153
+ onClick={handleLinkClick}
154
+ onColor={linkOnColor}
155
+ onSurface={Link.onSurfaces.Decor}
156
+ size={Link.sizes.S}
157
+ data-test-id={TEST_IDS.link}
158
+ />
159
+ )}
160
+
161
+ {date && (
162
+ <Typography.LightLabelS className={styles.notificationCardDate} data-test-id={TEST_IDS.date}>
163
+ {date}
164
+ </Typography.LightLabelS>
165
+ )}
166
+ </div>
167
+ )}
168
+ </div>
169
+ );
170
+ }
171
+
172
+ NotificationCard.appearances = Appearance;
@@ -0,0 +1,60 @@
1
+ import { Dispatch, SetStateAction } from 'react';
2
+
3
+ import { ButtonFunction } from '@snack-uikit/button';
4
+ import { Droplist, DroplistProps } from '@snack-uikit/droplist';
5
+ import { KebabSVG } from '@snack-uikit/icons';
6
+
7
+ import { TEST_IDS } from '../constants';
8
+ import { NotificationCardProps } from '../NotificationCard';
9
+ import styles from '../styles.module.scss';
10
+
11
+ export type NotificationCardFunctionProps = Required<Pick<NotificationCardProps, 'actions'>> &
12
+ Required<Pick<DroplistProps, 'open'>> & {
13
+ setDroplistOpen: Dispatch<SetStateAction<boolean>>;
14
+ };
15
+
16
+ export function NotificationCardFunction({ actions, open, setDroplistOpen }: NotificationCardFunctionProps) {
17
+ const {
18
+ firstElementRefCallback,
19
+ triggerElementRef,
20
+ handleDroplistFocusLeave,
21
+ handleTriggerKeyDown,
22
+ handleDroplistItemKeyDown,
23
+ handleDroplistItemClick,
24
+ } = Droplist.useKeyboardNavigation<HTMLButtonElement>({
25
+ setDroplistOpen,
26
+ });
27
+
28
+ return (
29
+ <div className={styles.notificationCardFunction} data-test-id={TEST_IDS.actions.wrapper}>
30
+ <Droplist
31
+ open={open}
32
+ onOpenChange={setDroplistOpen}
33
+ placement={Droplist.placements.BottomEnd}
34
+ firstElementRefCallback={firstElementRefCallback}
35
+ onFocusLeave={handleDroplistFocusLeave}
36
+ triggerRef={triggerElementRef}
37
+ useScroll
38
+ triggerElement={
39
+ <ButtonFunction
40
+ size={ButtonFunction.sizes.S}
41
+ icon={<KebabSVG />}
42
+ onKeyDown={handleTriggerKeyDown}
43
+ data-test-id={TEST_IDS.actions.droplistTrigger}
44
+ />
45
+ }
46
+ data-test-id={TEST_IDS.actions.droplist}
47
+ >
48
+ {actions.map(action => (
49
+ <Droplist.ItemSingle
50
+ {...action}
51
+ key={action.option}
52
+ onClick={e => handleDroplistItemClick(e, action.onClick)}
53
+ data-test-id={TEST_IDS.actions.droplistAction}
54
+ onKeyDown={handleDroplistItemKeyDown}
55
+ />
56
+ ))}
57
+ </Droplist>
58
+ </div>
59
+ );
60
+ }
@@ -0,0 +1,30 @@
1
+ import { Skeleton, SkeletonText } from '@snack-uikit/skeleton';
2
+
3
+ import { TEST_IDS } from '../../NotificationPanel/constants';
4
+ import styles from '../styles.module.scss';
5
+
6
+ const BORDER_RADIUS = 24;
7
+
8
+ export function NotificationCardSkeleton() {
9
+ return (
10
+ <div className={styles.notificationCard} data-test-id={TEST_IDS.skeleton} data-skeleton={true}>
11
+ <Skeleton width={140} height={11} borderRadius={BORDER_RADIUS} />
12
+
13
+ <div className={styles.notificationCardTitle} data-center={true}>
14
+ <div className={styles.notificationCardTitleIcon}>
15
+ <Skeleton width={16} height={16} borderRadius={BORDER_RADIUS} />
16
+ </div>
17
+ <Skeleton width={140} height={14} borderRadius={BORDER_RADIUS} />
18
+ </div>
19
+
20
+ <div className={styles.notificationCardContent}>
21
+ <SkeletonText lines={3} borderRadius={BORDER_RADIUS} />
22
+ </div>
23
+
24
+ <div className={styles.notificationCardFooter}>
25
+ <Skeleton width={140} borderRadius={BORDER_RADIUS} height={12} />
26
+ <Skeleton width={140} borderRadius={BORDER_RADIUS} height={11} />
27
+ </div>
28
+ </div>
29
+ );
30
+ }
@@ -0,0 +1,2 @@
1
+ export * from './NotificationCardFunction';
2
+ export * from './NotificationCardSkeleton';
@@ -0,0 +1,21 @@
1
+ export enum Appearance {
2
+ Neutral = 'neutral',
3
+ Error = 'error',
4
+ ErrorCritical = 'errorCritical',
5
+ Warning = 'warning',
6
+ Success = 'success',
7
+ }
8
+
9
+ export const TEST_IDS = {
10
+ label: 'notification-card__label',
11
+ title: 'notification-card__title',
12
+ content: 'notification-card__content',
13
+ link: 'notification-card__link',
14
+ date: 'notification-card__date',
15
+ actions: {
16
+ wrapper: 'notification-card__actions',
17
+ droplist: 'notification-card__droplist',
18
+ droplistTrigger: 'notification-card__droplist-trigger',
19
+ droplistAction: 'notification-card__droplist-action',
20
+ },
21
+ };
@@ -0,0 +1,19 @@
1
+ import { AlarmFilledSVG, CheckFilledSVG, CrossFilledSVG, InfoFilledSVG } from '@snack-uikit/icons';
2
+
3
+ import { Appearance } from './constants';
4
+
5
+ export function getIcon(appearance: Appearance) {
6
+ switch (appearance) {
7
+ case Appearance.Success:
8
+ return <CheckFilledSVG size={16} />;
9
+ case Appearance.Error:
10
+ case Appearance.ErrorCritical:
11
+ return <CrossFilledSVG size={16} />;
12
+ case Appearance.Warning:
13
+ return <AlarmFilledSVG size={16} />;
14
+ case Appearance.Neutral:
15
+ return <InfoFilledSVG size={16} />;
16
+ default:
17
+ return null;
18
+ }
19
+ }
@@ -0,0 +1 @@
1
+ export * from './NotificationCard';