@astral/ui 4.40.0 → 4.42.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 (71) hide show
  1. package/components/Notification/Notification.js +1 -0
  2. package/components/Notification/NotificationContainer/styles.js +16 -5
  3. package/components/Notification/NotificationStackContainer/NotificationStackContainer.js +3 -3
  4. package/components/Notification/NotificationStackContainer/styles.js +261 -23
  5. package/components/Notification/NotificationStackContainer/useLogic/hooks/index.d.ts +1 -0
  6. package/components/Notification/NotificationStackContainer/useLogic/hooks/index.js +1 -0
  7. package/components/Notification/NotificationStackContainer/useLogic/hooks/useHover/useHover.d.ts +5 -1
  8. package/components/Notification/NotificationStackContainer/useLogic/hooks/useHover/useHover.js +6 -2
  9. package/components/Notification/NotificationStackContainer/useLogic/hooks/useTouchStackExpand/index.d.ts +1 -0
  10. package/components/Notification/NotificationStackContainer/useLogic/hooks/useTouchStackExpand/index.js +1 -0
  11. package/components/Notification/NotificationStackContainer/useLogic/hooks/useTouchStackExpand/useTouchStackExpand.d.ts +10 -0
  12. package/components/Notification/NotificationStackContainer/useLogic/hooks/useTouchStackExpand/useTouchStackExpand.js +54 -0
  13. package/components/Notification/NotificationStackContainer/useLogic/useLogic.d.ts +1 -1
  14. package/components/Notification/NotificationStackContainer/useLogic/useLogic.js +19 -9
  15. package/components/Notification/NotificationTemplate/styles.js +20 -0
  16. package/components/Notification/constants.d.ts +4 -0
  17. package/components/Notification/constants.js +4 -0
  18. package/components/PageLayoutSection/PageLayoutSection.d.ts +21 -0
  19. package/components/PageLayoutSection/PageLayoutSection.js +19 -0
  20. package/components/PageLayoutSection/PageLayoutSectionContainer/PageLayoutSectionContainer.d.ts +25 -0
  21. package/components/PageLayoutSection/PageLayoutSectionContainer/PageLayoutSectionContainer.js +28 -0
  22. package/components/PageLayoutSection/PageLayoutSectionContainer/constants.d.ts +4 -0
  23. package/components/PageLayoutSection/PageLayoutSectionContainer/constants.js +4 -0
  24. package/components/PageLayoutSection/PageLayoutSectionContainer/index.d.ts +1 -0
  25. package/components/PageLayoutSection/PageLayoutSectionContainer/index.js +1 -0
  26. package/components/PageLayoutSection/PageLayoutSectionContainer/styles.d.ts +5 -0
  27. package/components/PageLayoutSection/PageLayoutSectionContainer/styles.js +51 -0
  28. package/components/PageLayoutSection/index.d.ts +2 -0
  29. package/components/PageLayoutSection/index.js +2 -0
  30. package/components/PageLayoutSection/public.d.ts +2 -0
  31. package/components/PageLayoutSection/public.js +2 -0
  32. package/components/PageLayoutSection/styles.d.ts +9 -0
  33. package/components/PageLayoutSection/styles.js +21 -0
  34. package/components/index.d.ts +1 -0
  35. package/components/index.js +1 -0
  36. package/node/components/Notification/Notification.js +1 -0
  37. package/node/components/Notification/NotificationContainer/styles.js +15 -4
  38. package/node/components/Notification/NotificationStackContainer/NotificationStackContainer.js +3 -3
  39. package/node/components/Notification/NotificationStackContainer/styles.js +260 -22
  40. package/node/components/Notification/NotificationStackContainer/useLogic/hooks/index.d.ts +1 -0
  41. package/node/components/Notification/NotificationStackContainer/useLogic/hooks/index.js +1 -0
  42. package/node/components/Notification/NotificationStackContainer/useLogic/hooks/useHover/useHover.d.ts +5 -1
  43. package/node/components/Notification/NotificationStackContainer/useLogic/hooks/useHover/useHover.js +6 -2
  44. package/node/components/Notification/NotificationStackContainer/useLogic/hooks/useTouchStackExpand/index.d.ts +1 -0
  45. package/node/components/Notification/NotificationStackContainer/useLogic/hooks/useTouchStackExpand/index.js +17 -0
  46. package/node/components/Notification/NotificationStackContainer/useLogic/hooks/useTouchStackExpand/useTouchStackExpand.d.ts +10 -0
  47. package/node/components/Notification/NotificationStackContainer/useLogic/hooks/useTouchStackExpand/useTouchStackExpand.js +58 -0
  48. package/node/components/Notification/NotificationStackContainer/useLogic/useLogic.d.ts +1 -1
  49. package/node/components/Notification/NotificationStackContainer/useLogic/useLogic.js +18 -8
  50. package/node/components/Notification/NotificationTemplate/styles.js +20 -0
  51. package/node/components/Notification/constants.d.ts +4 -0
  52. package/node/components/Notification/constants.js +5 -1
  53. package/node/components/PageLayoutSection/PageLayoutSection.d.ts +21 -0
  54. package/node/components/PageLayoutSection/PageLayoutSection.js +22 -0
  55. package/node/components/PageLayoutSection/PageLayoutSectionContainer/PageLayoutSectionContainer.d.ts +25 -0
  56. package/node/components/PageLayoutSection/PageLayoutSectionContainer/PageLayoutSectionContainer.js +32 -0
  57. package/node/components/PageLayoutSection/PageLayoutSectionContainer/constants.d.ts +4 -0
  58. package/node/components/PageLayoutSection/PageLayoutSectionContainer/constants.js +7 -0
  59. package/node/components/PageLayoutSection/PageLayoutSectionContainer/index.d.ts +1 -0
  60. package/node/components/PageLayoutSection/PageLayoutSectionContainer/index.js +5 -0
  61. package/node/components/PageLayoutSection/PageLayoutSectionContainer/styles.d.ts +5 -0
  62. package/node/components/PageLayoutSection/PageLayoutSectionContainer/styles.js +54 -0
  63. package/node/components/PageLayoutSection/index.d.ts +2 -0
  64. package/node/components/PageLayoutSection/index.js +7 -0
  65. package/node/components/PageLayoutSection/public.d.ts +2 -0
  66. package/node/components/PageLayoutSection/public.js +7 -0
  67. package/node/components/PageLayoutSection/styles.d.ts +9 -0
  68. package/node/components/PageLayoutSection/styles.js +24 -0
  69. package/node/components/index.d.ts +1 -0
  70. package/node/components/index.js +5 -2
  71. package/package.json +1 -1
@@ -33,6 +33,16 @@ const leaveOut = (0, styled_1.keyframes) `
33
33
  visibility: hidden;
34
34
  }
35
35
  `;
36
+ /** Сохраняем scale stacked (--s), иначе при старте exit transform из keyframes затирает scale и карточка визуально «прыгает» вправо */
37
+ const leaveOutMobileStacked = (0, styled_1.keyframes) `
38
+ from {
39
+ transform: translateX(0) scale(var(--s, 1));
40
+ }
41
+ to {
42
+ transform: translateX(100%) scale(var(--s, 1));
43
+ visibility: hidden;
44
+ }
45
+ `;
36
46
  // используем дополнительный враппер,
37
47
  // потому что styled для ToastContainer не умеет работать с theme внутри
38
48
  // использовать бэм классы для стилизации пришлось,
@@ -48,7 +58,15 @@ exports.Wrapper = styled_1.styled.div `
48
58
  width: 432px;
49
59
 
50
60
  ${({ theme }) => theme.breakpoints.down('sm')} {
51
- right: -20px;
61
+ inset: 0 0 auto;
62
+
63
+ width: 100%;
64
+ max-width: 100vw;
65
+ padding: ${({ theme }) => theme.spacing(2, 2, 2, 2)};
66
+ padding-top: max(
67
+ ${({ theme }) => theme.spacing(2)},
68
+ env(safe-area-inset-top, 0px)
69
+ );
52
70
  }
53
71
 
54
72
  &.${constants_1.notifyClassnames.container} {
@@ -65,18 +83,86 @@ exports.Wrapper = styled_1.styled.div `
65
83
  }
66
84
  /* stylelint-enable plugin/no-unsupported-browser-features */
67
85
 
68
- .Toastify:not(:last-child) {
69
- overflow: hidden;
86
+ ${({ theme }) => theme.breakpoints.up('sm')} {
87
+ .${constants_1.notifyClassnames.stackHost} .Toastify {
88
+ overflow: hidden;
89
+ }
90
+ }
91
+
92
+ ${({ theme }) => theme.breakpoints.down('sm')} {
93
+ justify-content: flex-start;
94
+
95
+ height: auto;
96
+
97
+ .${constants_1.notifyClassnames.stackHost} .Toastify {
98
+ overflow: visible;
99
+ }
100
+
101
+ .${constants_1.notifyClassnames.stack} {
102
+ overflow: hidden auto;
103
+ display: flex;
104
+ flex-direction: column;
105
+ gap: ${({ theme }) => theme.spacing(2)};
106
+ align-items: stretch;
107
+
108
+ width: 100%;
109
+ max-width: 100%;
110
+ padding-top: ${({ theme }) => theme.microSpacing(1)};
111
+ padding-bottom: 8px !important;
112
+ padding-bottom: ${({ theme }) => theme.spacing(1)};
113
+ -webkit-overflow-scrolling: touch;
114
+ }
115
+
116
+ .${constants_1.notifyClassnames.stack} .${constants_1.notifyClassnames.root} {
117
+ pointer-events: auto !important;
118
+
119
+ position: relative !important;
120
+ transform: none !important;
121
+
122
+ flex-shrink: 0;
123
+
124
+ width: 100% !important;
125
+ max-width: 100%;
126
+ height: auto !important;
127
+ min-height: ${constants_1.NOTIFY_HEIGHT_MOBILE};
128
+ max-height: fit-content !important;
129
+ margin-top: 0 !important;
130
+ margin-right: 0 !important;
131
+ margin-bottom: 0 !important;
132
+
133
+ opacity: 1 !important;
134
+ }
135
+
136
+ /*
137
+ На мобильных контейнер не получает mouseEnter — toastify оставляет data-collapsed=true
138
+ и скрывает direct children не‑последних тостов (.Toastify__toast--stacked[data-collapsed=true]:not(:last-child)>*{opacity:0})
139
+ */
140
+ .${constants_1.notifyClassnames.stack} .Toastify__toast--stacked > * {
141
+ opacity: 1 !important;
142
+ }
143
+
144
+ .${constants_1.notifyClassnames.stack} .${constants_1.notifyClassnames.root}__content {
145
+ max-height: 400px;
146
+ margin: ${({ theme }) => theme.spacing(2, 0, 0, 8)};
147
+ }
148
+
149
+ .${constants_1.notifyClassnames.stack} .${constants_1.notifyClassnames.root}__footer {
150
+ margin-bottom: 0;
151
+ }
152
+
153
+ .${constants_1.notifyClassnames.stack} .Toastify__toast--stacked::before {
154
+ display: none;
155
+ }
70
156
  }
71
157
  }
72
158
 
73
159
  .${constants_1.notifyClassnames.animationIn} {
74
- animation: ${leaveIn} ease-in-out 0.34s;
160
+ animation: ${leaveIn} ease-in-out ${({ theme }) => theme.transitions.duration.standard}ms;
75
161
  animation-fill-mode: both;
76
162
  }
77
163
 
78
164
  .${constants_1.notifyClassnames.animationOut} {
79
- animation: ${leaveOut} ease-in-out 0.34s;
165
+ animation: ${leaveOut} ease-in-out;
80
166
  animation-fill-mode: both;
81
167
  }
82
168
 
@@ -85,7 +171,6 @@ exports.Wrapper = styled_1.styled.div `
85
171
 
86
172
  width: 400px;
87
173
  height: ${constants_1.NOTIFY_HEIGHT};
88
- min-height: ${constants_1.NOTIFY_HEIGHT};
89
174
  padding: 0;
90
175
 
91
176
  box-shadow: ${({ theme }) => theme.elevation[300]};
@@ -107,6 +192,12 @@ exports.Wrapper = styled_1.styled.div `
107
192
  width: 100%;
108
193
  height: 3px;
109
194
  }
195
+ ${({ theme }) => theme.breakpoints.up('sm')} {
196
+ min-height: ${constants_1.NOTIFY_HEIGHT};
197
+ }
198
+ ${({ theme }) => theme.breakpoints.down('sm')} {
199
+ min-height: ${constants_1.NOTIFY_HEIGHT_MOBILE};
200
+ }
110
201
 
111
202
  .Toastify__progress-bar--wrp {
112
203
  top: 0;
@@ -154,8 +245,8 @@ exports.Wrapper = styled_1.styled.div `
154
245
  }
155
246
 
156
247
  /* Стили для уведомлений в стеке */
157
- .Toastify:not(:last-child) {
158
- .${constants_1.notifyClassnames.root} {
248
+ ${({ theme }) => theme.breakpoints.up('sm')} {
249
+ .${constants_1.notifyClassnames.stack} .${constants_1.notifyClassnames.root} {
159
250
  position: relative;
160
251
  transform: scale(var(--s));
161
252
 
@@ -188,6 +279,119 @@ exports.Wrapper = styled_1.styled.div `
188
279
  }
189
280
  }
190
281
  }
282
+
283
+ /* Мобильный стек в свёрнутом виде: последний в DOM (самый новый) — сверху; остальные без участия в раскладке */
284
+ ${({ theme }) => theme.breakpoints.down('sm')} {
285
+ &:not(.${constants_1.notifyClassnames.container}) {
286
+ .${constants_1.notifyClassnames.stack} {
287
+ position: relative;
288
+
289
+ overflow: visible;
290
+ display: flex;
291
+ flex-direction: column-reverse;
292
+ gap: 0;
293
+ align-items: stretch;
294
+ justify-content: flex-end;
295
+
296
+ max-height: none;
297
+ margin-bottom: ${({ theme }) => theme.spacing(2)};
298
+ -webkit-overflow-scrolling: auto;
299
+
300
+ /* Два фейковых слоя — только пока в стеке ≥2 активных тоста (без анимации закрытия) */
301
+
302
+ /* Причина игнора: Не критично для отображения */
303
+ /* stylelint-disable-next-line plugin/no-unsupported-browser-features */
304
+ &:has(.${constants_1.notifyClassnames.root}:not(.${constants_1.notifyClassnames.animationOut}) ~ .${constants_1.notifyClassnames.root}:not(.${constants_1.notifyClassnames.animationOut})) {
305
+ padding-top: ${({ theme }) => theme.spacing(4)};
306
+
307
+ &::before,
308
+ &::after {
309
+ pointer-events: none;
310
+ content: '';
311
+
312
+ position: absolute;
313
+ z-index: 0;
314
+ right: ${({ theme }) => theme.spacing(2)};
315
+ left: ${({ theme }) => theme.spacing(2)};
316
+
317
+ height: ${constants_1.NOTIFY_HEIGHT_MOBILE};
318
+
319
+ background: ${({ theme }) => theme.palette.background.paper};
320
+ border-radius: ${({ theme }) => theme.shape.medium};
321
+ box-shadow: ${({ theme }) => theme.elevation[200]};
322
+ }
323
+
324
+ &::before {
325
+ top: 0;
326
+ transform: scaleX(0.92);
327
+ }
328
+
329
+ &::after {
330
+ top: ${({ theme }) => theme.spacing(2)};
331
+ transform: scaleX(0.96);
332
+ }
333
+ }
334
+ }
335
+
336
+ .${constants_1.notifyClassnames.stack} .${constants_1.notifyClassnames.root}:not(:last-of-type) {
337
+ pointer-events: none;
338
+
339
+ position: absolute;
340
+
341
+ overflow: hidden;
342
+
343
+ width: 1px;
344
+ height: 1px;
345
+ margin: -1px;
346
+ padding: 0;
347
+
348
+ white-space: nowrap;
349
+
350
+ opacity: 0;
351
+ clip: rect(0, 0, 0, 0);
352
+ clip-path: inset(50%);
353
+ border: 0;
354
+
355
+ .${constants_1.notifyClassnames.root}__content {
356
+ max-height: 0 !important;
357
+ margin: 0 !important;
358
+ }
359
+ }
360
+
361
+ .${constants_1.notifyClassnames.stack} .${constants_1.notifyClassnames.root}:last-of-type {
362
+ position: relative;
363
+ z-index: 1;
364
+ transform: scale(var(--s, 1));
365
+
366
+ flex: 0 0 auto;
367
+ align-self: stretch;
368
+
369
+ width: 100% !important;
370
+ min-width: 0 !important;
371
+ max-width: 100% !important;
372
+ min-height: ${constants_1.NOTIFY_HEIGHT_MOBILE};
373
+ margin-bottom: 0 !important;
374
+
375
+ opacity: 1;
376
+ border-radius: ${({ theme }) => theme.shape.medium};
377
+
378
+ .${constants_1.notifyClassnames.root}__content {
379
+ max-height: 400px;
380
+ margin: ${({ theme }) => theme.spacing(2, 0, 0, 8)};
381
+ }
382
+ }
383
+
384
+ .${constants_1.notifyClassnames.stackHost} .Toastify,
385
+ .${constants_1.notifyClassnames.stackHost} .${constants_1.notifyClassnames.stack} {
386
+ overflow: visible !important;
387
+ }
388
+
389
+ .${constants_1.notifyClassnames.animationOut} {
390
+ animation: ${leaveOutMobileStacked} ease-in-out ${({ theme }) => theme.transitions.duration.standard}ms;
391
+ animation-fill-mode: both;
392
+ }
393
+ }
394
+ }
191
395
  `;
192
396
  exports.Inner = (0, styled_1.styled)(react_toastify_next_1.ToastContainer) `
193
397
  position: relative !important;
@@ -208,20 +412,53 @@ exports.Inner = (0, styled_1.styled)(react_toastify_next_1.ToastContainer) `
208
412
  }
209
413
  }
210
414
 
211
- &:hover {
212
- overflow: hidden auto;
415
+ /* Только устройства с реальным hover и ≥sm — иначе на touch :hover залипает и ломает мобильный стек */
416
+ ${({ theme }) => theme.breakpoints.up('sm')} {
417
+ @media (hover: hover) and (pointer: fine) {
418
+ &:hover {
419
+ overflow: hidden auto;
213
420
 
214
- height: 100%;
421
+ height: 100%;
215
422
 
216
- .${constants_1.notifyClassnames.root} {
217
- position: relative;
218
- transform: unset;
423
+ .${constants_1.notifyClassnames.root} {
424
+ position: relative;
425
+ transform: unset;
219
426
 
220
- height: auto;
221
- min-height: ${constants_1.NOTIFY_HEIGHT};
222
- margin-bottom: ${({ theme }) => theme.spacing(1)} !important;
427
+ height: auto;
428
+ min-height: ${constants_1.NOTIFY_HEIGHT};
429
+ margin-bottom: ${({ theme }) => theme.spacing(1)} !important;
223
430
 
224
- opacity: 1 !important;
431
+ opacity: 1 !important;
432
+ }
433
+
434
+ .${constants_1.notifyClassnames.root}__content {
435
+ max-height: 400px;
436
+ margin: ${({ theme }) => theme.spacing(2, 0, 0, 8)};
437
+ }
438
+
439
+ .${constants_1.notifyClassnames.root}__footer {
440
+ margin-bottom: 0;
441
+ }
442
+
443
+ .Toastify__toast--stacked::before {
444
+ display: none;
445
+ }
446
+ }
447
+ }
448
+ }
449
+
450
+ ${({ theme }) => theme.breakpoints.down('sm')} {
451
+ min-width: unset;
452
+ max-width: 100%;
453
+ padding-right: ${({ theme }) => theme.spacing(2)} !important;
454
+ padding-left: ${({ theme }) => theme.spacing(2)} !important;
455
+
456
+ .${constants_1.notifyClassnames.root} {
457
+ width: 100% !important;
458
+ max-width: 100%;
459
+ height: auto !important;
460
+ min-height: ${constants_1.NOTIFY_HEIGHT_MOBILE};
461
+ margin-bottom: ${({ theme }) => theme.spacing(2)} !important;
225
462
  }
226
463
 
227
464
  .${constants_1.notifyClassnames.root}__content {
@@ -232,10 +469,6 @@ exports.Inner = (0, styled_1.styled)(react_toastify_next_1.ToastContainer) `
232
469
  .${constants_1.notifyClassnames.root}__footer {
233
470
  margin-bottom: 0;
234
471
  }
235
-
236
- .Toastify__toast--stacked::before {
237
- display: none;
238
- }
239
472
  }
240
473
  `;
241
474
  exports.StaticInner = (0, styled_1.styled)(exports.Inner) `
@@ -262,4 +495,9 @@ exports.CloseButton = (0, styled_1.styled)(Button_1.Button) `
262
495
  &.${constants_1.notifyClassnames.closeButtonAnimationOut} {
263
496
  opacity: 0;
264
497
  }
498
+
499
+ ${({ theme }) => theme.breakpoints.down('sm')} {
500
+ width: calc(100% - ${({ theme }) => theme.spacing(4)});
501
+ margin: ${({ theme }) => theme.spacing(0, 5, 2, 5)};
502
+ }
265
503
  `;
@@ -1 +1,2 @@
1
1
  export * from './useHover';
2
+ export * from './useTouchStackExpand';
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./useHover"), exports);
18
+ __exportStar(require("./useTouchStackExpand"), exports);
@@ -1,3 +1,7 @@
1
- export declare const useHover: (element?: Element) => {
1
+ type UseHoverParams = {
2
+ enabled?: boolean;
3
+ };
4
+ export declare const useHover: (element: Element | undefined, { enabled }?: UseHoverParams) => {
2
5
  isHovered: boolean;
3
6
  };
7
+ export {};
@@ -2,11 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useHover = void 0;
4
4
  const react_1 = require("react");
5
- const useHover = (element) => {
5
+ const useHover = (element, { enabled = true } = {}) => {
6
6
  const [isHovered, setHover] = (0, react_1.useState)(false);
7
7
  const handleMouseEnter = () => setHover(true);
8
8
  const handleMouseLeave = () => setHover(false);
9
9
  (0, react_1.useEffect)(() => {
10
+ if (!enabled) {
11
+ setHover(false);
12
+ return undefined;
13
+ }
10
14
  if (!element) {
11
15
  return undefined;
12
16
  }
@@ -16,7 +20,7 @@ const useHover = (element) => {
16
20
  element.removeEventListener('mouseenter', handleMouseEnter);
17
21
  element.removeEventListener('mouseleave', handleMouseLeave);
18
22
  };
19
- }, [element]);
23
+ }, [element, enabled]);
20
24
  return { isHovered };
21
25
  };
22
26
  exports.useHover = useHover;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./useTouchStackExpand"), exports);
@@ -0,0 +1,10 @@
1
+ type UseTouchStackExpandParams = {
2
+ stackContainerElement: Element | null;
3
+ enabled: boolean;
4
+ hasOpenNotify: boolean;
5
+ };
6
+ /**
7
+ * Определяет, является ли стек уведомлений раскрытым на мобильном устройстве.
8
+ */
9
+ export declare const useTouchStackExpand: ({ stackContainerElement, enabled, hasOpenNotify, }: UseTouchStackExpandParams) => boolean;
10
+ export {};
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useTouchStackExpand = void 0;
4
+ const react_1 = require("react");
5
+ const constants_1 = require("../../../../constants");
6
+ const isInteractiveTarget = (element) => Boolean(element.closest('button, a[href], [role="button"], input, textarea, select'));
7
+ /**
8
+ * Определяет, является ли стек уведомлений раскрытым на мобильном устройстве.
9
+ */
10
+ const useTouchStackExpand = ({ stackContainerElement, enabled, hasOpenNotify, }) => {
11
+ const [isTouchExpanded, setTouchExpanded] = (0, react_1.useState)(false);
12
+ (0, react_1.useEffect)(() => {
13
+ if (!enabled || !hasOpenNotify) {
14
+ setTouchExpanded(false);
15
+ }
16
+ }, [enabled, hasOpenNotify]);
17
+ (0, react_1.useEffect)(() => {
18
+ if (!enabled || !hasOpenNotify || !stackContainerElement) {
19
+ return undefined;
20
+ }
21
+ const toggleStack = (event) => {
22
+ const { target } = event;
23
+ if (!(target instanceof Element) || isInteractiveTarget(target)) {
24
+ return;
25
+ }
26
+ setTouchExpanded((prev) => !prev);
27
+ };
28
+ stackContainerElement.addEventListener('pointerdown', toggleStack);
29
+ return () => {
30
+ stackContainerElement.removeEventListener('pointerdown', toggleStack);
31
+ };
32
+ }, [enabled, hasOpenNotify, stackContainerElement]);
33
+ (0, react_1.useEffect)(() => {
34
+ const collapseIfOutside = (event) => {
35
+ const { target } = event;
36
+ if (!(target instanceof Node) || !stackContainerElement) {
37
+ return;
38
+ }
39
+ const stackHost = stackContainerElement.closest(`.${constants_1.notifyClassnames.stackHost}`);
40
+ const insideUi = stackHost?.parentElement ?? stackContainerElement;
41
+ if (!insideUi.contains(target)) {
42
+ setTouchExpanded(false);
43
+ }
44
+ };
45
+ document.addEventListener('pointerdown', collapseIfOutside, true);
46
+ if (!enabled ||
47
+ !hasOpenNotify ||
48
+ !isTouchExpanded ||
49
+ !stackContainerElement) {
50
+ document.removeEventListener('pointerdown', collapseIfOutside, true);
51
+ }
52
+ return () => {
53
+ document.removeEventListener('pointerdown', collapseIfOutside, true);
54
+ };
55
+ }, [enabled, hasOpenNotify, isTouchExpanded, stackContainerElement]);
56
+ return isTouchExpanded;
57
+ };
58
+ exports.useTouchStackExpand = useTouchStackExpand;
@@ -4,7 +4,7 @@ type UseLogicParams = {
4
4
  };
5
5
  export declare const useLogic: ({ containerId: externalContainerId, }: UseLogicParams) => {
6
6
  isVisibleCloseButton: boolean;
7
- isHoveredContainer: boolean;
7
+ isStackExpanded: boolean;
8
8
  isStartedClosingNotify: boolean;
9
9
  closeAll: () => void;
10
10
  };
@@ -3,10 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useLogic = void 0;
4
4
  const react_1 = require("react");
5
5
  const react_toastify_next_1 = require("react-toastify-next");
6
+ const useViewportType_1 = require("../../../useViewportType");
6
7
  const constants_1 = require("../../constants");
7
8
  const sleep_1 = require("../../utils/sleep");
8
9
  const hooks_1 = require("./hooks");
9
10
  const useLogic = ({ containerId: externalContainerId, }) => {
11
+ const { isMobile } = (0, useViewportType_1.useViewportType)();
10
12
  const [toasts, setToasts] = (0, react_1.useState)([]);
11
13
  const [container, setContainer] = (0, react_1.useState)();
12
14
  const [isStartedClosingNotify, setStartedClosingNotify] = (0, react_1.useState)(false);
@@ -32,7 +34,16 @@ const useLogic = ({ containerId: externalContainerId, }) => {
32
34
  setStartedClosingNotify(false);
33
35
  }
34
36
  }, [toasts]);
35
- const { isHovered: isHoveredContainer } = (0, hooks_1.useHover)(container);
37
+ const hasOpenNotify = Boolean(toasts.length);
38
+ const { isHovered } = (0, hooks_1.useHover)(container, {
39
+ enabled: !isMobile,
40
+ });
41
+ const isTouchExpanded = (0, hooks_1.useTouchStackExpand)({
42
+ stackContainerElement: container ?? null,
43
+ enabled: isMobile,
44
+ hasOpenNotify,
45
+ });
46
+ const isStackExpanded = isMobile ? isTouchExpanded : isHovered;
36
47
  const handleAddToast = ({ id, containerId }) => {
37
48
  if (Object.is(containerId, externalContainerId)) {
38
49
  setToasts((currentToasts) => [...currentToasts, id]);
@@ -61,29 +72,28 @@ const useLogic = ({ containerId: externalContainerId, }) => {
61
72
  return unsubscribe;
62
73
  }, []);
63
74
  (0, react_1.useEffect)(() => {
64
- if (!isHoveredContainer || !container) {
75
+ if (!isStackExpanded || !container) {
65
76
  return;
66
77
  }
67
78
  (async () => {
68
79
  // Ожидаем пока отработает анимация и стек с уведомлениями раскроется
69
80
  await (0, sleep_1.sleep)(300);
70
- const hasScroll = container?.scrollHeight > container?.clientHeight;
71
- if (hasScroll) {
81
+ const hasVerticalScroll = container.scrollHeight > container.clientHeight;
82
+ if (hasVerticalScroll) {
72
83
  container.scrollTo({
73
84
  top: container.scrollHeight,
74
85
  behavior: 'smooth',
75
86
  });
76
87
  }
77
88
  })();
78
- }, [container, isHoveredContainer]);
89
+ }, [container, isStackExpanded]);
79
90
  const closeAll = () => {
80
91
  setStartedClosingNotify(true);
81
92
  react_toastify_next_1.toast.dismiss({ containerId: externalContainerId });
82
93
  };
83
- const hasOpenNotify = Boolean(toasts.length);
84
94
  return {
85
- isVisibleCloseButton: hasOpenNotify,
86
- isHoveredContainer: isHoveredContainer && hasOpenNotify,
95
+ isVisibleCloseButton: hasOpenNotify && (isMobile ? isStackExpanded : true),
96
+ isStackExpanded,
87
97
  isStartedClosingNotify,
88
98
  closeAll,
89
99
  };
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Title = exports.CloseButton = exports.IconWrapper = exports.Footer = exports.Content = exports.Header = exports.Wrapper = void 0;
4
+ const constants_1 = require("../../Button/constants");
4
5
  const IconButton_1 = require("../../IconButton");
6
+ const constants_2 = require("../../SvgIcon/constants");
5
7
  const styled_1 = require("../../styled");
6
8
  const Typography_1 = require("../../Typography");
7
9
  const utils_1 = require("./utils");
@@ -18,6 +20,10 @@ exports.Wrapper = styled_1.styled.article `
18
20
  color: ${({ theme }) => theme.palette.grey[900]};
19
21
 
20
22
  background: ${({ theme }) => theme.palette.background.default};
23
+
24
+ ${({ theme }) => theme.breakpoints.down('sm')} {
25
+ padding: ${({ theme }) => theme.spacing(2, 3)};
26
+ }
21
27
  `;
22
28
  exports.Header = styled_1.styled.header `
23
29
  display: flex;
@@ -25,6 +31,13 @@ exports.Header = styled_1.styled.header `
25
31
 
26
32
  width: 100%;
27
33
  min-height: 24px;
34
+
35
+ ${({ theme }) => theme.breakpoints.down('sm')} {
36
+ .${constants_1.buttonClassnames.root} {
37
+ width: 24px;
38
+ height: 24px;
39
+ }
40
+ }
28
41
  `;
29
42
  exports.Content = (0, styled_1.styled)(Typography_1.Typography) `
30
43
  margin-top: ${({ theme }) => theme.spacing(2)};
@@ -41,6 +54,13 @@ exports.IconWrapper = styled_1.styled.div `
41
54
  display: flex;
42
55
 
43
56
  margin-right: ${({ theme }) => theme.spacing(2)};
57
+
58
+ ${({ theme }) => theme.breakpoints.down('sm')} {
59
+ .${constants_2.svgIconClassnames.root} {
60
+ width: 24px;
61
+ height: 24px;
62
+ }
63
+ }
44
64
  `;
45
65
  exports.CloseButton = (0, styled_1.styled)(IconButton_1.IconButton) `
46
66
  align-self: center;
@@ -18,9 +18,13 @@ export declare const NOTIFY_STATIC_CONTAINER_ID = "static-notify-container";
18
18
  export declare const BANNER_CONTAINER_ID = "banner-container-id";
19
19
  export declare const NOTIFY_NO_TRANSITION_ATTR = "data-no-transition";
20
20
  export declare const NOTIFY_HEIGHT = "56px";
21
+ export declare const NOTIFY_HEIGHT_MOBILE = "40px";
21
22
  export declare const notifyClassnames: {
22
23
  root: string;
23
24
  body: string;
25
+ stack: string;
26
+ /** Обёртка только над stacked ToastContainer — без :has() отделяем внешний .Toastify от статичного */
27
+ stackHost: string;
24
28
  container: string;
25
29
  animationIn: string;
26
30
  animationOut: string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.notifyClassnames = exports.NOTIFY_HEIGHT = exports.NOTIFY_NO_TRANSITION_ATTR = exports.BANNER_CONTAINER_ID = exports.NOTIFY_STATIC_CONTAINER_ID = exports.NOTIFY_CONTAINER_ID = exports.NOTIFY_POSITIONS = exports.NotificationVariantTypes = void 0;
3
+ exports.notifyClassnames = exports.NOTIFY_HEIGHT_MOBILE = exports.NOTIFY_HEIGHT = exports.NOTIFY_NO_TRANSITION_ATTR = exports.BANNER_CONTAINER_ID = exports.NOTIFY_STATIC_CONTAINER_ID = exports.NOTIFY_CONTAINER_ID = exports.NOTIFY_POSITIONS = exports.NotificationVariantTypes = void 0;
4
4
  const createUIKitClassname_1 = require("../utils/createUIKitClassname");
5
5
  var NotificationVariantTypes;
6
6
  (function (NotificationVariantTypes) {
@@ -23,9 +23,13 @@ exports.NOTIFY_STATIC_CONTAINER_ID = 'static-notify-container';
23
23
  exports.BANNER_CONTAINER_ID = 'banner-container-id';
24
24
  exports.NOTIFY_NO_TRANSITION_ATTR = 'data-no-transition';
25
25
  exports.NOTIFY_HEIGHT = '56px';
26
+ exports.NOTIFY_HEIGHT_MOBILE = '40px';
26
27
  exports.notifyClassnames = {
27
28
  root: (0, createUIKitClassname_1.createUIKitClassname)('notify'),
28
29
  body: (0, createUIKitClassname_1.createUIKitClassname)('notify__body'),
30
+ stack: (0, createUIKitClassname_1.createUIKitClassname)('notify__stack'),
31
+ /** Обёртка только над stacked ToastContainer — без :has() отделяем внешний .Toastify от статичного */
32
+ stackHost: (0, createUIKitClassname_1.createUIKitClassname)('notify__stack-host'),
29
33
  container: (0, createUIKitClassname_1.createUIKitClassname)('notify__container'),
30
34
  animationIn: (0, createUIKitClassname_1.createUIKitClassname)('notify_animation-in'),
31
35
  animationOut: (0, createUIKitClassname_1.createUIKitClassname)('notify_animation-out'),