@snack-uikit/alert 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 0.8.0 (2023-12-28)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **FF-3960:** support link props renaming ([990b35e](https://github.com/cloud-ru-tech/snack-uikit/commit/990b35e6f0ea091c499b337e721add2f1606a251))
12
+
13
+
14
+ ### Features
15
+
16
+ * **FF-3960:** update inner structure, add action buttons ([0de436c](https://github.com/cloud-ru-tech/snack-uikit/commit/0de436c7128a9d6753645ed80c8c45201586d952))
17
+
18
+
19
+
20
+
21
+
6
22
  ## 0.7.3 (2023-12-25)
7
23
 
8
24
  ### Only dependencies have been changed
package/README.md CHANGED
@@ -58,6 +58,7 @@ import { InfoFilledSVG } from '@snack-uikit/icons';
58
58
  | onClose | `() => void` | - | Колбек закрытия |
59
59
  | appearance | enum Appearance: `"neutral"`, `"primary"`, `"error"`, `"warning"`, `"success"` | neutral | Внешний вид |
60
60
  | className | `string` | - | CSS-класс |
61
+ | action | `Pick<AlertButtonProps, "icon" \| "label" \| "onClick">[]` | - | Свойства, описывающие кнопки в футере алерта |
61
62
  ## AlertTop
62
63
  Компонент для отображения уведомления вверху экрана.
63
64
  ### Props
@@ -1,4 +1,5 @@
1
1
  import { WithSupportProps } from '@snack-uikit/utils';
2
+ import { AlertButtonProps } from '../../helperComponents';
2
3
  import { Appearance } from '../../types';
3
4
  export type AlertProps = WithSupportProps<{
4
5
  /** Отображать иконку */
@@ -17,8 +18,10 @@ export type AlertProps = WithSupportProps<{
17
18
  appearance?: Appearance;
18
19
  /** CSS-класс */
19
20
  className?: string;
21
+ /** Свойства, описывающие кнопки в футере алерта */
22
+ action?: Pick<AlertButtonProps, 'label' | 'onClick' | 'icon'>[];
20
23
  }>;
21
24
  /**
22
25
  * Компонент для отображения уведомления.
23
26
  */
24
- export declare function Alert({ icon, title, href, link, description, onClose, appearance, className, ...rest }: AlertProps): import("react/jsx-runtime").JSX.Element;
27
+ export declare function Alert({ icon, title, href, link, description, onClose, appearance, className, action, ...rest }: AlertProps): import("react/jsx-runtime").JSX.Element;
@@ -16,12 +16,13 @@ import { Link } from '@snack-uikit/link';
16
16
  import { TruncateString } from '@snack-uikit/truncate-string';
17
17
  import { extractSupportProps } from '@snack-uikit/utils';
18
18
  import { APPEARANCE, APPEARANCE_TO_COLOR_MAP } from '../../constants';
19
+ import { AlertButton } from '../../helperComponents';
19
20
  import { getIcon } from '../../utils';
20
21
  import styles from './styles.module.css';
21
22
  /**
22
23
  * Компонент для отображения уведомления.
23
24
  */
24
25
  export function Alert(_a) {
25
- var { icon = true, title, href, link, description, onClose, appearance = APPEARANCE.Neutral, className } = _a, rest = __rest(_a, ["icon", "title", "href", "link", "description", "onClose", "appearance", "className"]);
26
- return (_jsxs("div", Object.assign({ className: cn(styles.alert, className) }, extractSupportProps(rest), { "data-color": APPEARANCE_TO_COLOR_MAP[appearance], children: [icon && (_jsx("div", { className: styles.icon, "data-color": APPEARANCE_TO_COLOR_MAP[appearance], "data-test-id": 'alert__icon', children: getIcon(appearance) })), _jsxs("div", { className: styles.content, children: [_jsxs("div", { className: styles.textlayout, children: [title && _jsx(TruncateString, { text: title, maxLines: 1, className: styles.title, "data-test-id": 'alert__title' }), _jsx("span", { "data-test-id": 'alert__description', className: styles.description, children: description })] }), link && (_jsx("span", { children: _jsx(Link, { href: href, text: link, onSurface: 'decor', external: true, onColor: APPEARANCE_TO_COLOR_MAP[appearance], size: 'm', "data-test-id": 'alert__link' }) }))] }), onClose && (_jsx("button", { onClick: onClose, className: styles.closeButton, "data-color": APPEARANCE_TO_COLOR_MAP[appearance], "data-test-id": 'alert__close-button', children: _jsx(CrossSVG, {}) }))] })));
26
+ var { icon = true, title, href, link, description, onClose, appearance = APPEARANCE.Neutral, className, action } = _a, rest = __rest(_a, ["icon", "title", "href", "link", "description", "onClose", "appearance", "className", "action"]);
27
+ return (_jsxs("div", Object.assign({ className: cn(styles.alert, className) }, extractSupportProps(rest), { "data-color": APPEARANCE_TO_COLOR_MAP[appearance], children: [_jsxs("div", { className: styles.body, children: [icon && (_jsx("div", { className: styles.icon, "data-color": APPEARANCE_TO_COLOR_MAP[appearance], "data-test-id": 'alert__icon', children: getIcon(appearance) })), _jsxs("div", { className: styles.contentLayout, children: [title && _jsx(TruncateString, { text: title, maxLines: 1, className: styles.title, "data-test-id": 'alert__title' }), _jsx("span", { "data-test-id": 'alert__description', className: styles.description, children: description }), link && (_jsx("span", { children: _jsx(Link, { href: href, text: link, textMode: 'default', external: true, appearance: APPEARANCE_TO_COLOR_MAP[appearance], size: 'm', "data-test-id": 'alert__link' }) }))] }), onClose && (_jsx("button", { onClick: onClose, className: styles.closeButton, "data-color": APPEARANCE_TO_COLOR_MAP[appearance], "data-test-id": 'alert__close-button', children: _jsx(CrossSVG, {}) }))] }), Array.isArray(action) && action.length > 0 && (_jsx("div", { className: styles.footer, children: action.map(buttonProps => (_jsx(AlertButton, Object.assign({}, buttonProps, { appearance: appearance }), buttonProps.label))) }))] })));
27
28
  }
@@ -3,10 +3,11 @@
3
3
  padding-bottom:var(--space-alert-container-vertical-padding, 14px);
4
4
  padding-left:var(--space-alert-container-horizontal-padding, 14px);
5
5
  padding-right:var(--space-alert-container-horizontal-padding, 14px);
6
- gap:var(--space-alert-container-gap, 8px);
6
+ gap:var(--space-alert-container-gap, 14px);
7
7
  border-radius:var(--radius-alert-container, 8px);
8
8
  border-width:var(--border-width-general-xs, 1px);
9
9
  display:flex;
10
+ flex-direction:column;
10
11
  box-sizing:border-box;
11
12
  min-width:256px;
12
13
  border-style:solid;
@@ -32,38 +33,11 @@
32
33
  border-color:var(--sys-green-decor-default, #cdebe3);
33
34
  }
34
35
 
35
- .title{
36
- font-family:var(--sans-title-s-font-family, SB Sans Interface);
37
- font-weight:var(--sans-title-s-font-weight, Semibold);
38
- line-height:var(--sans-title-s-line-height, 20px);
39
- font-size:var(--sans-title-s-font-size, 14px);
40
- letter-spacing:var(--sans-title-s-letter-spacing, 0.15px);
41
- paragraph-spacing:var(--sans-title-s-paragraph-spacing, 7.7px);
42
- color:var(--sys-neutral-text-main, #333333);
43
- }
44
-
45
- .textlayout{
46
- padding-top:var(--space-alert-container-content-layout-text-layout-padding-top, 2px);
47
- overflow:hidden;
48
- }
49
-
50
- .description{
51
- font-family:var(--sans-body-m-font-family, SB Sans Interface);
52
- font-weight:var(--sans-body-m-font-weight, Regular);
53
- line-height:var(--sans-body-m-line-height, 20px);
54
- font-size:var(--sans-body-m-font-size, 14px);
55
- letter-spacing:var(--sans-body-m-letter-spacing, 0.1px);
56
- paragraph-spacing:var(--sans-body-m-paragraph-spacing, 7.7px);
57
- color:var(--sys-neutral-text-support, #565656);
58
- word-wrap:break-word;
59
- }
60
-
61
- .content{
62
- gap:var(--space-alert-container-content-layout-gap, 8px);
36
+ .body{
37
+ gap:var(--space-alert-container-body-gap, 8px);
63
38
  display:flex;
64
- flex:1;
65
- flex-direction:column;
66
- min-width:0;
39
+ box-sizing:border-box;
40
+ width:100%;
67
41
  }
68
42
 
69
43
  .icon[data-color=neutral]{
@@ -86,10 +60,39 @@
86
60
  height:var(--dimension-3m, 24px) !important;
87
61
  }
88
62
 
63
+ .contentLayout{
64
+ padding-top:var(--space-alert-container-content-layout-padding-top, 2px);
65
+ display:flex;
66
+ flex:1;
67
+ flex-direction:column;
68
+ min-width:0;
69
+ }
70
+
71
+ .title{
72
+ font-family:var(--sans-title-s-font-family, SB Sans Interface);
73
+ font-weight:var(--sans-title-s-font-weight, Semibold);
74
+ line-height:var(--sans-title-s-line-height, 20px);
75
+ font-size:var(--sans-title-s-font-size, 14px);
76
+ letter-spacing:var(--sans-title-s-letter-spacing, 0.15px);
77
+ paragraph-spacing:var(--sans-title-s-paragraph-spacing, 7.7px);
78
+ color:var(--sys-neutral-text-main, #333333);
79
+ }
80
+
81
+ .description{
82
+ font-family:var(--sans-body-m-font-family, SB Sans Interface);
83
+ font-weight:var(--sans-body-m-font-weight, Regular);
84
+ line-height:var(--sans-body-m-line-height, 20px);
85
+ font-size:var(--sans-body-m-font-size, 14px);
86
+ letter-spacing:var(--sans-body-m-letter-spacing, 0.1px);
87
+ paragraph-spacing:var(--sans-body-m-paragraph-spacing, 7.7px);
88
+ color:var(--sys-neutral-text-support, #565656);
89
+ word-wrap:break-word;
90
+ }
91
+
89
92
  .closeButton{
90
- height:var(--size-alert-button-close, 24px);
91
- width:var(--size-alert-button-close, 24px);
92
- border-radius:var(--radius-alert-button-close, 8px);
93
+ height:var(--size-alert-button, 24px);
94
+ width:var(--size-alert-button, 24px);
95
+ border-radius:var(--radius-alert-button, 8px);
93
96
  cursor:pointer;
94
97
  display:flex;
95
98
  align-items:center;
@@ -106,82 +109,91 @@
106
109
  height:var(--dimension-3m, 24px) !important;
107
110
  }
108
111
  .closeButton[data-color=neutral]{
109
- color:var(--sys-neutral-text-light, #898989);
112
+ color:var(--sys-neutral-text-support, #565656);
110
113
  }
111
114
  .closeButton[data-color=neutral]:hover{
112
- color:var(--sys-neutral-text-support, #565656);
115
+ color:var(--sys-neutral-text-light, #898989);
113
116
  }
114
117
  .closeButton[data-color=neutral]:focus-visible{
115
118
  outline-width:var(--border-state-focus-s-border-width, 2px);
116
119
  outline-style:var(--border-state-focus-s-border-style, solid);
117
120
  outline-color:var(--border-state-focus-s-border-color, );
118
- color:var(--sys-neutral-text-support, #565656);
121
+ color:var(--sys-neutral-text-light, #898989);
119
122
  outline-color:var(--sys-available-complementary, #131313);
120
123
  }
121
124
  .closeButton[data-color=neutral]:active{
122
125
  color:var(--sys-neutral-text-main, #333333);
123
126
  }
124
127
  .closeButton[data-color=primary]{
125
- color:var(--sys-primary-text-light, #997adc);
128
+ color:var(--sys-primary-text-support, #5b4796);
126
129
  }
127
130
  .closeButton[data-color=primary]:hover{
128
- color:var(--sys-primary-text-support, #5b4796);
131
+ color:var(--sys-primary-text-light, #997adc);
129
132
  }
130
133
  .closeButton[data-color=primary]:focus-visible{
131
134
  outline-width:var(--border-state-focus-s-border-width, 2px);
132
135
  outline-style:var(--border-state-focus-s-border-style, solid);
133
136
  outline-color:var(--border-state-focus-s-border-color, );
134
- color:var(--sys-primary-text-support, #5b4796);
137
+ color:var(--sys-primary-text-light, #997adc);
135
138
  outline-color:var(--sys-available-complementary, #131313);
136
139
  }
137
140
  .closeButton[data-color=primary]:active{
138
141
  color:var(--sys-primary-text-main, #382a62);
139
142
  }
140
143
  .closeButton[data-color=red]{
141
- color:var(--sys-red-text-light, #ec7465);
144
+ color:var(--sys-red-text-support, #a93936);
142
145
  }
143
146
  .closeButton[data-color=red]:hover{
144
- color:var(--sys-red-text-support, #a93936);
147
+ color:var(--sys-red-text-light, #ec7465);
145
148
  }
146
149
  .closeButton[data-color=red]:focus-visible{
147
150
  outline-width:var(--border-state-focus-s-border-width, 2px);
148
151
  outline-style:var(--border-state-focus-s-border-style, solid);
149
152
  outline-color:var(--border-state-focus-s-border-color, );
150
- color:var(--sys-red-text-support, #a93936);
153
+ color:var(--sys-red-text-light, #ec7465);
151
154
  outline-color:var(--sys-available-complementary, #131313);
152
155
  }
153
156
  .closeButton[data-color=red]:active{
154
157
  color:var(--sys-red-text-main, #621c1e);
155
158
  }
156
159
  .closeButton[data-color=yellow]{
157
- color:var(--sys-yellow-text-light, #be7d3c);
160
+ color:var(--sys-yellow-text-support, #80461b);
158
161
  }
159
162
  .closeButton[data-color=yellow]:hover{
160
- color:var(--sys-yellow-text-support, #80461b);
163
+ color:var(--sys-yellow-text-light, #be7d3c);
161
164
  }
162
165
  .closeButton[data-color=yellow]:focus-visible{
163
166
  outline-width:var(--border-state-focus-s-border-width, 2px);
164
167
  outline-style:var(--border-state-focus-s-border-style, solid);
165
168
  outline-color:var(--border-state-focus-s-border-color, );
166
- color:var(--sys-yellow-text-support, #80461b);
169
+ color:var(--sys-yellow-text-light, #be7d3c);
167
170
  outline-color:var(--sys-available-complementary, #131313);
168
171
  }
169
172
  .closeButton[data-color=yellow]:active{
170
173
  color:var(--sys-yellow-text-main, #54290f);
171
174
  }
172
175
  .closeButton[data-color=green]{
173
- color:var(--sys-green-text-light, #4d9e80);
176
+ color:var(--sys-green-text-support, #335747);
174
177
  }
175
178
  .closeButton[data-color=green]:hover{
176
- color:var(--sys-green-text-support, #335747);
179
+ color:var(--sys-green-text-light, #4d9e80);
177
180
  }
178
181
  .closeButton[data-color=green]:focus-visible{
179
182
  outline-width:var(--border-state-focus-s-border-width, 2px);
180
183
  outline-style:var(--border-state-focus-s-border-style, solid);
181
184
  outline-color:var(--border-state-focus-s-border-color, );
182
- color:var(--sys-green-text-support, #335747);
185
+ color:var(--sys-green-text-light, #4d9e80);
183
186
  outline-color:var(--sys-available-complementary, #131313);
184
187
  }
185
188
  .closeButton[data-color=green]:active{
186
189
  color:var(--sys-green-text-main, #1f392a);
190
+ }
191
+
192
+ .footer{
193
+ gap:var(--space-alert-container-footer-gap, 16px);
194
+ position:relative;
195
+ display:flex;
196
+ flex-direction:row-reverse;
197
+ align-items:center;
198
+ width:100%;
187
199
  }
@@ -25,5 +25,5 @@ import styles from './styles.module.css';
25
25
  */
26
26
  export function AlertTop(_a) {
27
27
  var { icon = true, title, description, link, href, onClose, appearance = APPEARANCE.Neutral, buttonText, buttonOnClick, buttonIcon, className } = _a, rest = __rest(_a, ["icon", "title", "description", "link", "href", "onClose", "appearance", "buttonText", "buttonOnClick", "buttonIcon", "className"]);
28
- return (_jsxs("div", Object.assign({ className: cn(styles.alertTop, className) }, extractSupportProps(rest), { "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], children: [_jsxs("div", { className: styles.contentWrapper, children: [icon && (_jsx("div", { className: styles.icon, "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], "data-test-id": 'alert-top__icon', children: getIcon(appearance) })), _jsxs("div", { className: styles.contentLayout, children: [_jsxs("div", { className: styles.textLayout, children: [title && (_jsx("div", { className: styles.title, "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], "data-test-id": 'alert-top__title', children: _jsx(TruncateString, { text: title, maxLines: 1 }) })), _jsx("span", { className: styles.description, "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], "data-test-id": 'alert-top__description', children: description })] }), link && (_jsx("span", { children: _jsx(Link, { onSurface: 'accent', href: href, text: link, external: true, onColor: APPEARANCE_TO_COLOR_MAP[appearance], size: 'm', "data-test-id": 'alert-top__link' }) }))] })] }), _jsxs("div", { className: styles.actions, children: [buttonText && (_jsx(AlertTopButton, { buttonIcon: buttonIcon, buttonOnClick: buttonOnClick, buttonText: buttonText, appearance: appearance })), onClose && (_jsx("button", { onClick: onClose, className: styles.closeButton, "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], "data-test-id": 'alert-top__close-button', children: _jsx(CrossSVG, {}) }))] })] })));
28
+ return (_jsxs("div", Object.assign({ className: cn(styles.alertTop, className) }, extractSupportProps(rest), { "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], children: [_jsxs("div", { className: styles.contentWrapper, children: [icon && (_jsx("div", { className: styles.icon, "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], "data-test-id": 'alert-top__icon', children: getIcon(appearance) })), _jsxs("div", { className: styles.contentLayout, children: [_jsxs("div", { className: styles.textLayout, children: [title && (_jsx("div", { className: styles.title, "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], "data-test-id": 'alert-top__title', children: _jsx(TruncateString, { text: title, maxLines: 1 }) })), _jsx("span", { className: styles.description, "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], "data-test-id": 'alert-top__description', children: description })] }), link && (_jsx("span", { children: _jsx(Link, { textMode: 'on-accent', href: href, text: link, external: true, appearance: APPEARANCE_TO_COLOR_MAP[appearance], size: 'm', "data-test-id": 'alert-top__link' }) }))] })] }), _jsxs("div", { className: styles.actions, children: [buttonText && (_jsx(AlertTopButton, { buttonIcon: buttonIcon, buttonOnClick: buttonOnClick, buttonText: buttonText, appearance: appearance })), onClose && (_jsx("button", { onClick: onClose, className: styles.closeButton, "data-color": APPEARANCE_TO_COLOR_MAP_INVERT[appearance], "data-test-id": 'alert-top__close-button', children: _jsx(CrossSVG, {}) }))] })] })));
29
29
  }
@@ -24,6 +24,11 @@
24
24
  background-color:var(--sys-green-accent-default, #0bbe8f);
25
25
  }
26
26
 
27
+ .icon{
28
+ display:flex;
29
+ align-items:center;
30
+ justify-content:center;
31
+ }
27
32
  .icon[data-color=invert-neutral]{
28
33
  color:var(--sys-invert-neutral-text-main, #e7e7e7);
29
34
  }
@@ -131,7 +136,7 @@
131
136
  }
132
137
  .closeButton[data-color=invert-neutral]{
133
138
  color:var(--sys-invert-neutral-text-main, #e7e7e7);
134
- opacity:var(--opacity-a080, 0.8);
139
+ background-color:inherit;
135
140
  }
136
141
  .closeButton[data-color=invert-neutral]:hover{
137
142
  opacity:unset;
@@ -146,12 +151,11 @@
146
151
  outline-color:var(--sys-available-on-complementary, #fdfdfd);
147
152
  }
148
153
  .closeButton[data-color=invert-neutral]:active{
149
- opacity:var(--opacity-a080, 0.8);
150
154
  background-color:var(--sys-opacity-activated, rgba(253, 253, 253, 0.3215686275));
151
155
  }
152
156
  .closeButton[data-color=primary]{
153
157
  color:var(--sys-primary-on-accent, #fdfbff);
154
- opacity:var(--opacity-a080, 0.8);
158
+ background-color:inherit;
155
159
  }
156
160
  .closeButton[data-color=primary]:hover{
157
161
  opacity:unset;
@@ -166,12 +170,11 @@
166
170
  outline-color:var(--sys-available-on-complementary, #fdfdfd);
167
171
  }
168
172
  .closeButton[data-color=primary]:active{
169
- opacity:var(--opacity-a080, 0.8);
170
173
  background-color:var(--sys-opacity-activated, rgba(253, 253, 253, 0.3215686275));
171
174
  }
172
175
  .closeButton[data-color=red]{
173
176
  color:var(--sys-red-on-accent, #fffbfa);
174
- opacity:var(--opacity-a080, 0.8);
177
+ background-color:inherit;
175
178
  }
176
179
  .closeButton[data-color=red]:hover{
177
180
  opacity:unset;
@@ -186,12 +189,11 @@
186
189
  outline-color:var(--sys-available-on-complementary, #fdfdfd);
187
190
  }
188
191
  .closeButton[data-color=red]:active{
189
- opacity:var(--opacity-a080, 0.8);
190
192
  background-color:var(--sys-opacity-activated, rgba(253, 253, 253, 0.3215686275));
191
193
  }
192
194
  .closeButton[data-color=yellow]{
193
195
  color:var(--sys-yellow-on-accent, #54290f);
194
- opacity:var(--opacity-a080, 0.8);
196
+ background-color:inherit;
195
197
  }
196
198
  .closeButton[data-color=yellow]:hover{
197
199
  opacity:unset;
@@ -206,12 +208,11 @@
206
208
  outline-color:var(--sys-available-on-complementary, #fdfdfd);
207
209
  }
208
210
  .closeButton[data-color=yellow]:active{
209
- opacity:var(--opacity-a080, 0.8);
210
211
  background-color:var(--sys-opacity-activated, rgba(253, 253, 253, 0.3215686275));
211
212
  }
212
213
  .closeButton[data-color=green]{
213
214
  color:var(--sys-green-on-accent, #1f392a);
214
- opacity:var(--opacity-a080, 0.8);
215
+ background-color:inherit;
215
216
  }
216
217
  .closeButton[data-color=green]:hover{
217
218
  opacity:unset;
@@ -226,7 +227,6 @@
226
227
  outline-color:var(--sys-available-on-complementary, #fdfdfd);
227
228
  }
228
229
  .closeButton[data-color=green]:active{
229
- opacity:var(--opacity-a080, 0.8);
230
230
  background-color:var(--sys-opacity-activated, rgba(253, 253, 253, 0.3215686275));
231
231
  }
232
232
 
@@ -1,3 +1,5 @@
1
+ import { LinkProps } from '@snack-uikit/link';
2
+ import { ValueOf } from '@snack-uikit/utils';
1
3
  export declare const APPEARANCE: {
2
4
  readonly Neutral: "neutral";
3
5
  readonly Primary: "primary";
@@ -5,10 +7,4 @@ export declare const APPEARANCE: {
5
7
  readonly Warning: "warning";
6
8
  readonly Success: "success";
7
9
  };
8
- export declare const APPEARANCE_TO_COLOR_MAP: {
9
- readonly neutral: "neutral";
10
- readonly primary: "primary";
11
- readonly error: "red";
12
- readonly warning: "yellow";
13
- readonly success: "green";
14
- };
10
+ export declare const APPEARANCE_TO_COLOR_MAP: Record<ValueOf<typeof APPEARANCE>, LinkProps['appearance']>;
package/dist/constants.js CHANGED
@@ -1,4 +1,3 @@
1
- import { ON_COLOR } from '@snack-uikit/link';
2
1
  export const APPEARANCE = {
3
2
  Neutral: 'neutral',
4
3
  Primary: 'primary',
@@ -7,9 +6,9 @@ export const APPEARANCE = {
7
6
  Success: 'success',
8
7
  };
9
8
  export const APPEARANCE_TO_COLOR_MAP = {
10
- [APPEARANCE.Neutral]: ON_COLOR.Neutral,
11
- [APPEARANCE.Primary]: ON_COLOR.Primary,
12
- [APPEARANCE.Error]: ON_COLOR.Red,
13
- [APPEARANCE.Warning]: ON_COLOR.Yellow,
14
- [APPEARANCE.Success]: ON_COLOR.Green,
9
+ [APPEARANCE.Neutral]: 'neutral',
10
+ [APPEARANCE.Primary]: 'primary',
11
+ [APPEARANCE.Error]: 'red',
12
+ [APPEARANCE.Warning]: 'yellow',
13
+ [APPEARANCE.Success]: 'green',
15
14
  };
@@ -0,0 +1,9 @@
1
+ import { MouseEvent, ReactElement } from 'react';
2
+ import { Appearance } from '../../types';
3
+ export type AlertButtonProps = {
4
+ appearance: Appearance;
5
+ label: string;
6
+ icon?: ReactElement;
7
+ onClick(e: MouseEvent<HTMLButtonElement>): void;
8
+ };
9
+ export declare function AlertButton({ appearance, label, icon, onClick }: AlertButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { APPEARANCE_TO_COLOR_MAP } from '../../constants';
3
+ import styles from './styles.module.css';
4
+ export function AlertButton({ appearance, label, icon, onClick }) {
5
+ return (_jsxs("button", { onClick: onClick, className: styles.alertButton, "data-color": APPEARANCE_TO_COLOR_MAP[appearance], "data-test-id": 'alert__action-button', children: [_jsx("span", { children: label }), icon] }));
6
+ }
@@ -0,0 +1 @@
1
+ export * from './AlertButton';
@@ -0,0 +1 @@
1
+ export * from './AlertButton';
@@ -0,0 +1,75 @@
1
+ .alertButton{
2
+ height:var(--size-alert-button, 24px);
3
+ gap:var(--space-alert-button-gap, 4px);
4
+ border-radius:var(--radius-alert-button, 8px);
5
+ font-family:var(--sans-label-l-font-family, SB Sans Interface);
6
+ font-weight:var(--sans-label-l-font-weight, Semibold);
7
+ line-height:var(--sans-label-l-line-height, 20px);
8
+ font-size:var(--sans-label-l-font-size, 14px);
9
+ letter-spacing:var(--sans-label-l-letter-spacing, -0.1px);
10
+ paragraph-spacing:var(--sans-label-l-paragraph-spacing, 7.7px);
11
+ cursor:pointer;
12
+ display:flex;
13
+ align-items:center;
14
+ box-sizing:border-box;
15
+ margin:0;
16
+ white-space:nowrap;
17
+ background:none;
18
+ border:0;
19
+ }
20
+ .alertButton svg{
21
+ width:var(--dimension-3m, 24px) !important;
22
+ height:var(--dimension-3m, 24px) !important;
23
+ }
24
+ .alertButton:focus-visible{
25
+ outline-width:var(--border-state-focus-s-border-width, 2px);
26
+ outline-style:var(--border-state-focus-s-border-style, solid);
27
+ outline-color:var(--border-state-focus-s-border-color, );
28
+ outline-color:var(--sys-available-complementary, #131313);
29
+ outline-offset:var(--spacing-state-focus-offset, 2px);
30
+ }
31
+ .alertButton[data-color=neutral]{
32
+ color:var(--sys-neutral-text-support, #565656);
33
+ }
34
+ .alertButton[data-color=neutral]:hover, .alertButton[data-color=neutral]:focus-visible{
35
+ color:var(--sys-neutral-text-light, #898989);
36
+ }
37
+ .alertButton[data-color=neutral]:active{
38
+ color:var(--sys-neutral-text-main, #333333);
39
+ }
40
+ .alertButton[data-color=primary]{
41
+ color:var(--sys-primary-text-support, #5b4796);
42
+ }
43
+ .alertButton[data-color=primary]:hover, .alertButton[data-color=primary]:focus-visible{
44
+ color:var(--sys-primary-text-light, #997adc);
45
+ }
46
+ .alertButton[data-color=primary]:active{
47
+ color:var(--sys-primary-text-main, #382a62);
48
+ }
49
+ .alertButton[data-color=red]{
50
+ color:var(--sys-red-text-support, #a93936);
51
+ }
52
+ .alertButton[data-color=red]:hover, .alertButton[data-color=red]:focus-visible{
53
+ color:var(--sys-red-text-light, #ec7465);
54
+ }
55
+ .alertButton[data-color=red]:active{
56
+ color:var(--sys-red-text-main, #621c1e);
57
+ }
58
+ .alertButton[data-color=yellow]{
59
+ color:var(--sys-yellow-text-support, #80461b);
60
+ }
61
+ .alertButton[data-color=yellow]:hover, .alertButton[data-color=yellow]:focus-visible{
62
+ color:var(--sys-yellow-text-light, #be7d3c);
63
+ }
64
+ .alertButton[data-color=yellow]:active{
65
+ color:var(--sys-yellow-text-main, #54290f);
66
+ }
67
+ .alertButton[data-color=green]{
68
+ color:var(--sys-green-text-support, #335747);
69
+ }
70
+ .alertButton[data-color=green]:hover, .alertButton[data-color=green]:focus-visible{
71
+ color:var(--sys-green-text-light, #4d9e80);
72
+ }
73
+ .alertButton[data-color=green]:active{
74
+ color:var(--sys-green-text-main, #1f392a);
75
+ }
@@ -17,8 +17,7 @@
17
17
  margin:0;
18
18
  margin-left:auto;
19
19
  white-space:nowrap;
20
- opacity:var(--opacity-a080, 0.8);
21
- background:none;
20
+ background:var(--sys-opacity-enabled, rgba(253, 253, 253, 0.1607843137));
22
21
  border:0;
23
22
  }
24
23
  .alertTopButton svg{
@@ -33,12 +32,10 @@
33
32
  outline-width:var(--border-state-focus-s-border-width, 2px);
34
33
  outline-style:var(--border-state-focus-s-border-style, solid);
35
34
  outline-color:var(--border-state-focus-s-border-color, );
36
- opacity:unset;
37
35
  background-color:var(--sys-opacity-hovered, rgba(253, 253, 253, 0.2392156863));
38
36
  outline-color:var(--sys-available-on-complementary, #fdfdfd);
39
37
  }
40
38
  .alertTopButton:active{
41
- opacity:var(--opacity-a080, 0.8);
42
39
  background-color:var(--sys-opacity-activated, rgba(253, 253, 253, 0.3215686275));
43
40
  }
44
41
  .alertTopButton[data-color=invert-neutral]{
@@ -1 +1,2 @@
1
+ export * from './AlertButton';
1
2
  export * from './AlertTopButton';
@@ -1 +1,2 @@
1
+ export * from './AlertButton';
1
2
  export * from './AlertTopButton';
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "title": "Alert",
7
- "version": "0.7.3",
7
+ "version": "0.8.0",
8
8
  "sideEffects": [
9
9
  "*.css",
10
10
  "*.woff",
@@ -33,10 +33,10 @@
33
33
  "scripts": {},
34
34
  "dependencies": {
35
35
  "@snack-uikit/icons": "0.19.2",
36
- "@snack-uikit/link": "0.9.3",
37
- "@snack-uikit/truncate-string": "0.4.3",
36
+ "@snack-uikit/link": "0.10.0",
37
+ "@snack-uikit/truncate-string": "0.4.4",
38
38
  "@snack-uikit/utils": "3.2.0",
39
39
  "classnames": "2.3.2"
40
40
  },
41
- "gitHead": "420ccb07e016ae79a8b783e88c24f2045fadc026"
41
+ "gitHead": "57c597a3eebaf6528c0c61b6b27dd244753de1cf"
42
42
  }
@@ -6,6 +6,7 @@ import { TruncateString } from '@snack-uikit/truncate-string';
6
6
  import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
7
7
 
8
8
  import { APPEARANCE, APPEARANCE_TO_COLOR_MAP } from '../../constants';
9
+ import { AlertButton, AlertButtonProps } from '../../helperComponents';
9
10
  import { Appearance } from '../../types';
10
11
  import { getIcon } from '../../utils';
11
12
  import styles from './styles.module.scss';
@@ -27,6 +28,8 @@ export type AlertProps = WithSupportProps<{
27
28
  appearance?: Appearance;
28
29
  /** CSS-класс */
29
30
  className?: string;
31
+ /** Свойства, описывающие кнопки в футере алерта */
32
+ action?: Pick<AlertButtonProps, 'label' | 'onClick' | 'icon'>[];
30
33
  }>;
31
34
 
32
35
  /**
@@ -41,6 +44,7 @@ export function Alert({
41
44
  onClose,
42
45
  appearance = APPEARANCE.Neutral,
43
46
  className,
47
+ action,
44
48
  ...rest
45
49
  }: AlertProps) {
46
50
  return (
@@ -49,42 +53,52 @@ export function Alert({
49
53
  {...extractSupportProps(rest)}
50
54
  data-color={APPEARANCE_TO_COLOR_MAP[appearance]}
51
55
  >
52
- {icon && (
53
- <div className={styles.icon} data-color={APPEARANCE_TO_COLOR_MAP[appearance]} data-test-id='alert__icon'>
54
- {getIcon(appearance)}
55
- </div>
56
- )}
57
- <div className={styles.content}>
58
- <div className={styles.textlayout}>
56
+ <div className={styles.body}>
57
+ {icon && (
58
+ <div className={styles.icon} data-color={APPEARANCE_TO_COLOR_MAP[appearance]} data-test-id='alert__icon'>
59
+ {getIcon(appearance)}
60
+ </div>
61
+ )}
62
+
63
+ <div className={styles.contentLayout}>
59
64
  {title && <TruncateString text={title} maxLines={1} className={styles.title} data-test-id='alert__title' />}
60
65
  <span data-test-id='alert__description' className={styles.description}>
61
66
  {description}
62
67
  </span>
68
+
69
+ {link && (
70
+ <span>
71
+ <Link
72
+ href={href}
73
+ text={link}
74
+ textMode='default'
75
+ external
76
+ appearance={APPEARANCE_TO_COLOR_MAP[appearance]}
77
+ size='m'
78
+ data-test-id='alert__link'
79
+ />
80
+ </span>
81
+ )}
63
82
  </div>
64
83
 
65
- {link && (
66
- <span>
67
- <Link
68
- href={href}
69
- text={link}
70
- onSurface='decor'
71
- external
72
- onColor={APPEARANCE_TO_COLOR_MAP[appearance]}
73
- size='m'
74
- data-test-id='alert__link'
75
- />
76
- </span>
84
+ {onClose && (
85
+ <button
86
+ onClick={onClose}
87
+ className={styles.closeButton}
88
+ data-color={APPEARANCE_TO_COLOR_MAP[appearance]}
89
+ data-test-id='alert__close-button'
90
+ >
91
+ <CrossSVG />
92
+ </button>
77
93
  )}
78
94
  </div>
79
- {onClose && (
80
- <button
81
- onClick={onClose}
82
- className={styles.closeButton}
83
- data-color={APPEARANCE_TO_COLOR_MAP[appearance]}
84
- data-test-id='alert__close-button'
85
- >
86
- <CrossSVG />
87
- </button>
95
+
96
+ {Array.isArray(action) && action.length > 0 && (
97
+ <div className={styles.footer}>
98
+ {action.map(buttonProps => (
99
+ <AlertButton key={buttonProps.label} {...buttonProps} appearance={appearance} />
100
+ ))}
101
+ </div>
88
102
  )}
89
103
  </div>
90
104
  );
@@ -3,13 +3,15 @@
3
3
 
4
4
  $colors: 'neutral', 'primary', 'red', 'yellow', 'green';
5
5
 
6
-
7
6
  .alert {
8
7
  @include composite-var($alert-container-container);
9
8
 
10
9
  display: flex;
10
+ flex-direction: column;
11
+
11
12
  box-sizing: border-box;
12
13
  min-width: 256px;
14
+
13
15
  border-style: solid;
14
16
 
15
17
  @each $color in $colors {
@@ -20,26 +22,28 @@ $colors: 'neutral', 'primary', 'red', 'yellow', 'green';
20
22
  }
21
23
  }
22
24
 
23
- .title {
24
- @include composite-var($sans-title-s);
25
+ .body {
26
+ @include composite-var($alert-container-body);
25
27
 
26
- color: $sys-neutral-text-main;
27
- }
28
-
29
- .textlayout {
30
- @include composite-var($alert-container-text-layout);
31
-
32
- overflow: hidden;
28
+ display: flex;
29
+ box-sizing: border-box;
30
+ width: 100%
33
31
  }
34
32
 
35
- .description {
36
- @include composite-var($sans-body-m);
33
+ .icon {
34
+ @each $color in $colors {
35
+ &[data-color='#{$color}'] {
36
+ color: simple-var($theme-variables, 'sys', $color, 'accent-default');
37
+ }
38
+ }
37
39
 
38
- color: $sys-neutral-text-support;
39
- word-wrap: break-word;
40
+ svg {
41
+ width: $icon-s !important; /* stylelint-disable-line declaration-no-important */
42
+ height: $icon-s !important; /* stylelint-disable-line declaration-no-important */
43
+ }
40
44
  }
41
45
 
42
- .content {
46
+ .contentLayout {
43
47
  @include composite-var($alert-container-content-layout);
44
48
 
45
49
  display: flex;
@@ -48,17 +52,17 @@ $colors: 'neutral', 'primary', 'red', 'yellow', 'green';
48
52
  min-width: 0;
49
53
  }
50
54
 
51
- .icon {
52
- @each $color in $colors {
53
- &[data-color='#{$color}'] {
54
- color: simple-var($theme-variables, 'sys', $color, 'accent-default');
55
- }
56
- }
55
+ .title {
56
+ @include composite-var($sans-title-s);
57
57
 
58
- svg {
59
- width: $icon-s !important; /* stylelint-disable-line declaration-no-important */
60
- height: $icon-s !important; /* stylelint-disable-line declaration-no-important */
61
- }
58
+ color: $sys-neutral-text-main;
59
+ }
60
+
61
+ .description {
62
+ @include composite-var($sans-body-m);
63
+
64
+ color: $sys-neutral-text-support;
65
+ word-wrap: break-word;
62
66
  }
63
67
 
64
68
  .closeButton {
@@ -83,24 +87,36 @@ $colors: 'neutral', 'primary', 'red', 'yellow', 'green';
83
87
  height: $icon-s !important; /* stylelint-disable-line declaration-no-important */
84
88
  }
85
89
 
86
- @each $color in $colors {
90
+ @each $color in $colors {
87
91
  &[data-color='#{$color}'] {
88
- color: simple-var($theme-variables, 'sys', $color, 'text-light');
89
-
92
+ color: simple-var($theme-variables, 'sys', $color, 'text-support');
93
+
90
94
  &:hover {
91
- color: simple-var($theme-variables, 'sys', $color, 'text-support');
95
+ color: simple-var($theme-variables, 'sys', $color, 'text-light');
92
96
  }
93
-
97
+
94
98
  &:focus-visible {
95
99
  @include outline-var($container-focused-s);
96
100
 
97
- color: simple-var($theme-variables, 'sys', $color, 'text-support');
101
+ color: simple-var($theme-variables, 'sys', $color, 'text-light');
98
102
  outline-color: $sys-available-complementary;
99
103
  }
100
-
104
+
101
105
  &:active {
102
106
  color: simple-var($theme-variables, 'sys', $color, 'text-main');
103
107
  }
104
108
  }
105
- }
106
- }
109
+ }
110
+ }
111
+
112
+ .footer {
113
+ @include composite-var($alert-container-footer);
114
+
115
+ position: relative;
116
+
117
+ display: flex;
118
+ flex-direction: row-reverse;
119
+ align-items: center;
120
+
121
+ width: 100%;
122
+ }
@@ -95,11 +95,11 @@ export function AlertTop({
95
95
  {link && (
96
96
  <span>
97
97
  <Link
98
- onSurface='accent'
98
+ textMode='on-accent'
99
99
  href={href}
100
100
  text={link}
101
101
  external
102
- onColor={APPEARANCE_TO_COLOR_MAP[appearance]}
102
+ appearance={APPEARANCE_TO_COLOR_MAP[appearance]}
103
103
  size='m'
104
104
  data-test-id='alert-top__link'
105
105
  />
@@ -24,6 +24,10 @@ $colors: 'invert-neutral', 'primary', 'red', 'yellow', 'green';
24
24
  }
25
25
 
26
26
  .icon {
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: center;
30
+
27
31
  @each $color in $colors {
28
32
  &[data-color='#{$color}'] {
29
33
  @if $color == 'invert-neutral'{
@@ -127,7 +131,7 @@ $colors: 'invert-neutral', 'primary', 'red', 'yellow', 'green';
127
131
  color: simple-var($theme-variables, 'sys', $color, 'on-accent');
128
132
  }
129
133
 
130
- opacity: $opacity-a080;
134
+ background-color: inherit;
131
135
 
132
136
  &:hover {
133
137
  opacity: unset;
@@ -143,7 +147,6 @@ $colors: 'invert-neutral', 'primary', 'red', 'yellow', 'green';
143
147
  }
144
148
 
145
149
  &:active {
146
- opacity: $opacity-a080;
147
150
  background-color: $sys-opacity-activated;
148
151
  }
149
152
  }
package/src/constants.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { ON_COLOR } from '@snack-uikit/link';
1
+ import { LinkProps } from '@snack-uikit/link';
2
+ import { ValueOf } from '@snack-uikit/utils';
2
3
 
3
4
  export const APPEARANCE = {
4
5
  Neutral: 'neutral',
@@ -8,10 +9,10 @@ export const APPEARANCE = {
8
9
  Success: 'success',
9
10
  } as const;
10
11
 
11
- export const APPEARANCE_TO_COLOR_MAP = {
12
- [APPEARANCE.Neutral]: ON_COLOR.Neutral,
13
- [APPEARANCE.Primary]: ON_COLOR.Primary,
14
- [APPEARANCE.Error]: ON_COLOR.Red,
15
- [APPEARANCE.Warning]: ON_COLOR.Yellow,
16
- [APPEARANCE.Success]: ON_COLOR.Green,
12
+ export const APPEARANCE_TO_COLOR_MAP: Record<ValueOf<typeof APPEARANCE>, LinkProps['appearance']> = {
13
+ [APPEARANCE.Neutral]: 'neutral',
14
+ [APPEARANCE.Primary]: 'primary',
15
+ [APPEARANCE.Error]: 'red',
16
+ [APPEARANCE.Warning]: 'yellow',
17
+ [APPEARANCE.Success]: 'green',
17
18
  } as const;
@@ -0,0 +1,26 @@
1
+ import { MouseEvent, ReactElement } from 'react';
2
+
3
+ import { APPEARANCE_TO_COLOR_MAP } from '../../constants';
4
+ import { Appearance } from '../../types';
5
+ import styles from './styles.module.scss';
6
+
7
+ export type AlertButtonProps = {
8
+ appearance: Appearance;
9
+ label: string;
10
+ icon?: ReactElement;
11
+ onClick(e: MouseEvent<HTMLButtonElement>): void;
12
+ };
13
+
14
+ export function AlertButton({ appearance, label, icon, onClick }: AlertButtonProps) {
15
+ return (
16
+ <button
17
+ onClick={onClick}
18
+ className={styles.alertButton}
19
+ data-color={APPEARANCE_TO_COLOR_MAP[appearance]}
20
+ data-test-id='alert__action-button'
21
+ >
22
+ <span>{label}</span>
23
+ {icon}
24
+ </button>
25
+ );
26
+ }
@@ -0,0 +1 @@
1
+ export * from './AlertButton';
@@ -0,0 +1,49 @@
1
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-alert';
2
+ @import '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
3
+
4
+ $colors: 'neutral', 'primary', 'red', 'yellow', 'green';
5
+
6
+ .alertButton {
7
+ @include composite-var($alert-button-button-action);
8
+ @include composite-var($sans-label-l);
9
+
10
+ cursor: pointer;
11
+
12
+ display: flex;
13
+ align-items: center;
14
+
15
+ box-sizing: border-box;
16
+ margin: 0;
17
+
18
+ white-space: nowrap;
19
+
20
+ background: none;
21
+ border: 0;
22
+
23
+ svg {
24
+ width: $icon-s !important; /* stylelint-disable-line declaration-no-important */
25
+ height: $icon-s !important; /* stylelint-disable-line declaration-no-important */
26
+ }
27
+
28
+ &:focus-visible {
29
+ @include outline-var($container-focused-s);
30
+
31
+ outline-color: $sys-available-complementary;
32
+ outline-offset: $spacing-state-focus-offset;
33
+ }
34
+
35
+ @each $color in $colors {
36
+ &[data-color='#{$color}'] {
37
+ color: simple-var($theme-variables, 'sys', $color, 'text-support');
38
+
39
+ &:hover,
40
+ &:focus-visible {
41
+ color: simple-var($theme-variables, 'sys', $color, 'text-light');
42
+ }
43
+
44
+ &:active {
45
+ color: simple-var($theme-variables, 'sys', $color, 'text-main');
46
+ }
47
+ }
48
+ }
49
+ }
@@ -18,8 +18,7 @@ $colors: 'invert-neutral', 'primary', 'red', 'yellow', 'green';
18
18
 
19
19
  white-space: nowrap;
20
20
 
21
- opacity: $opacity-a080;
22
- background: none;
21
+ background: $sys-opacity-enabled;
23
22
  border: 0;
24
23
 
25
24
  svg {
@@ -34,12 +33,10 @@ $colors: 'invert-neutral', 'primary', 'red', 'yellow', 'green';
34
33
  &:focus-visible {
35
34
  @include outline-var($container-focused-s);
36
35
 
37
- opacity: unset;
38
36
  background-color: $sys-opacity-hovered;
39
37
  outline-color: $sys-available-on-complementary;
40
38
  }
41
39
  &:active {
42
- opacity: $opacity-a080;
43
40
  background-color: $sys-opacity-activated;
44
41
  }
45
42
 
@@ -1 +1,2 @@
1
+ export * from './AlertButton';
1
2
  export * from './AlertTopButton';