@cloud-ru/ds-uikit-product-header 2.1.3 → 2.1.4-preview-0fb5d9fa.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 (52) hide show
  1. package/README.md +2 -0
  2. package/dist/cjs/components/MainMenu/MainMenu.d.ts +1 -1
  3. package/dist/cjs/components/MainMenu/MainMenu.js +2 -2
  4. package/dist/cjs/components/MainMenu/helperComponents/Content/Content.d.ts +5 -1
  5. package/dist/cjs/components/MainMenu/helperComponents/Content/Content.js +4 -3
  6. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.d.ts +1 -8
  7. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.js +2 -2
  8. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +6 -2
  9. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +1 -1
  10. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +13 -10
  11. package/dist/cjs/components/MainMenu/helperComponents/Content/styles.module.css +15 -0
  12. package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.d.ts +1 -1
  13. package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +4 -4
  14. package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/constants.d.ts +1 -1
  15. package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/constants.js +3 -3
  16. package/dist/cjs/components/MainMenu/hooks/useMainMenuDnd.js +12 -0
  17. package/dist/cjs/components/MainMenu/styles.module.css +8 -0
  18. package/dist/cjs/components/MainMenu/types.d.ts +1 -1
  19. package/dist/cjs/style.css +36 -10
  20. package/dist/esm/components/MainMenu/MainMenu.d.ts +1 -1
  21. package/dist/esm/components/MainMenu/MainMenu.js +2 -2
  22. package/dist/esm/components/MainMenu/helperComponents/Content/Content.d.ts +5 -1
  23. package/dist/esm/components/MainMenu/helperComponents/Content/Content.js +4 -3
  24. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.d.ts +1 -8
  25. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.js +2 -2
  26. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +6 -2
  27. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +1 -1
  28. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +13 -10
  29. package/dist/esm/components/MainMenu/helperComponents/Content/styles.module.css +15 -0
  30. package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.d.ts +1 -1
  31. package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +5 -5
  32. package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/constants.d.ts +1 -1
  33. package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/constants.js +2 -2
  34. package/dist/esm/components/MainMenu/hooks/useMainMenuDnd.js +10 -1
  35. package/dist/esm/components/MainMenu/styles.module.css +8 -0
  36. package/dist/esm/components/MainMenu/types.d.ts +1 -1
  37. package/dist/esm/style.css +36 -10
  38. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  39. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  40. package/package.json +28 -28
  41. package/src/components/MainMenu/MainMenu.tsx +2 -0
  42. package/src/components/MainMenu/helperComponents/Content/Content.tsx +12 -2
  43. package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.tsx +1 -11
  44. package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.tsx +9 -4
  45. package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.scss +27 -19
  46. package/src/components/MainMenu/helperComponents/Content/styles.module.scss +22 -0
  47. package/src/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.tsx +6 -4
  48. package/src/components/MainMenu/helperComponents/MenuDesktop/constants.ts +2 -2
  49. package/src/components/MainMenu/helperComponents/MenuDesktop/styles.module.scss +6 -2
  50. package/src/components/MainMenu/hooks/useMainMenuDnd.tsx +12 -1
  51. package/src/components/MainMenu/styles.module.scss +10 -0
  52. package/src/components/MainMenu/types.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloud-ru/ds-uikit-product-header",
3
- "version": "2.1.3",
3
+ "version": "2.1.4-preview-0fb5d9fa.0",
4
4
  "description": "Продуктовая шапка консоли — HeaderLayout, MainMenu, UserMenu, Logo, PathBreadcrumbs и PlatformLogo.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -45,33 +45,33 @@
45
45
  "@dnd-kit/utilities": "^3.2.2",
46
46
  "classnames": "^2.5.1",
47
47
  "fuse.js": "^7.1.0",
48
- "@cloud-ru/ds-accordion": "^1.2.1",
49
- "@cloud-ru/ds-avatar": "^1.0.11",
50
- "@cloud-ru/ds-adaptive": "^1.0.2",
51
- "@cloud-ru/ds-button": "^1.0.4",
52
- "@cloud-ru/ds-breadcrumbs": "^1.0.29",
53
- "@cloud-ru/ds-card": "^1.0.22",
54
- "@cloud-ru/ds-drag-and-drop": "^1.1.3",
55
- "@cloud-ru/ds-divider": "^1.0.2",
56
- "@cloud-ru/ds-drawer": "^2.0.0",
57
- "@cloud-ru/ds-icons": "^1.5.0",
58
- "@cloud-ru/ds-info-block": "^1.0.3",
59
- "@cloud-ru/ds-list": "^2.3.2",
60
- "@cloud-ru/ds-locale": "^1.0.0",
61
- "@cloud-ru/ds-modal": "^2.0.0",
62
- "@cloud-ru/ds-portal-context": "^1.0.2",
63
- "@cloud-ru/ds-promo-tag": "^1.0.3",
64
- "@cloud-ru/ds-scroll": "^1.0.5",
65
- "@cloud-ru/ds-search": "^1.0.14",
66
- "@cloud-ru/ds-skeleton": "^1.0.2",
67
- "@cloud-ru/ds-segment-control": "^1.0.13",
68
- "@cloud-ru/ds-theme": "^2.1.0",
69
- "@cloud-ru/ds-tooltip": "^1.0.11",
70
- "@cloud-ru/ds-typography": "^1.0.1",
71
- "@cloud-ru/ds-uikit-product-switch-row": "^1.0.14",
72
- "@cloud-ru/ds-uikit-product-title-clickable": "^1.0.16",
73
- "@cloud-ru/ds-utils": "^1.2.0",
74
- "@cloud-ru/ds-uikit-product-card-predefined": "^4.0.9"
48
+ "@cloud-ru/ds-accordion": "1.2.1",
49
+ "@cloud-ru/ds-adaptive": "1.0.2",
50
+ "@cloud-ru/ds-breadcrumbs": "1.0.29",
51
+ "@cloud-ru/ds-avatar": "1.0.11",
52
+ "@cloud-ru/ds-button": "1.0.4",
53
+ "@cloud-ru/ds-card": "1.0.22",
54
+ "@cloud-ru/ds-drag-and-drop": "1.1.3",
55
+ "@cloud-ru/ds-drawer": "2.0.1-preview-0fb5d9fa.0",
56
+ "@cloud-ru/ds-divider": "1.0.2",
57
+ "@cloud-ru/ds-icons": "1.5.0",
58
+ "@cloud-ru/ds-info-block": "1.0.3",
59
+ "@cloud-ru/ds-list": "2.3.2",
60
+ "@cloud-ru/ds-locale": "1.0.0",
61
+ "@cloud-ru/ds-modal": "2.0.0",
62
+ "@cloud-ru/ds-portal-context": "1.0.2",
63
+ "@cloud-ru/ds-promo-tag": "1.0.3",
64
+ "@cloud-ru/ds-search": "1.0.14",
65
+ "@cloud-ru/ds-segment-control": "1.0.13",
66
+ "@cloud-ru/ds-skeleton": "1.0.2",
67
+ "@cloud-ru/ds-theme": "2.1.0",
68
+ "@cloud-ru/ds-scroll": "1.0.5",
69
+ "@cloud-ru/ds-uikit-product-card-predefined": "4.0.9",
70
+ "@cloud-ru/ds-uikit-product-switch-row": "1.0.14",
71
+ "@cloud-ru/ds-tooltip": "1.0.11",
72
+ "@cloud-ru/ds-typography": "1.0.1",
73
+ "@cloud-ru/ds-utils": "1.2.0",
74
+ "@cloud-ru/ds-uikit-product-title-clickable": "1.0.16"
75
75
  },
76
76
  "publishConfig": {
77
77
  "access": "public"
@@ -25,6 +25,7 @@ export function MainMenu({
25
25
  onActiveSegmentChange,
26
26
  onSegmentOrderChange,
27
27
  onSegmentExpandedChange,
28
+ onToggleAllGroupsExpanded,
28
29
  onSegmentServiceClick,
29
30
  favorite,
30
31
  search,
@@ -74,6 +75,7 @@ export function MainMenu({
74
75
  onSegmentOrderChange={onSegmentOrderChange}
75
76
  onSegmentExpandedChange={onSegmentExpandedChange}
76
77
  onSegmentServiceClick={onSegmentServiceClick}
78
+ onToggleAllGroupsExpanded={onToggleAllGroupsExpanded}
77
79
  platformGroups={platformGroups}
78
80
  search={search}
79
81
  logo={logo}
@@ -72,6 +72,11 @@ export type ContentProps = {
72
72
  */
73
73
  onSegmentExpandedChange?(segmentId: string, expandedGroupIds: string[]): void;
74
74
 
75
+ /**
76
+ * Колбэк смены всех групп раскрытых.
77
+ */
78
+ onToggleAllGroupsExpanded?(action: 'collapseAllGroups' | 'expandAllGroups'): void;
79
+
75
80
  /**
76
81
  * Колбэк клика по карточке сервиса в сегменте.
77
82
  */
@@ -120,6 +125,7 @@ export function Content({
120
125
  onSegmentOrderChange,
121
126
  onSegmentExpandedChange,
122
127
  onSegmentServiceClick,
128
+ onToggleAllGroupsExpanded,
123
129
  className,
124
130
  footer,
125
131
  favorite,
@@ -210,6 +216,8 @@ export function Content({
210
216
  const allGroupsExpanded = visibleGroups.length > 0 && visibleGroupIds.every(id => expandedIdsSet.has(id));
211
217
 
212
218
  const handleToggleAllGroupsExpanded = useCallback(() => {
219
+ onToggleAllGroupsExpanded?.(allGroupsExpanded ? 'collapseAllGroups' : 'expandAllGroups');
220
+
213
221
  if (allGroupsExpanded) {
214
222
  const visibleIdsSet = new Set(visibleGroupIds);
215
223
 
@@ -218,7 +226,7 @@ export function Content({
218
226
  }
219
227
 
220
228
  onExpandedChange([...new Set([...expandedIds, ...visibleGroupIds])]);
221
- }, [allGroupsExpanded, expandedIds, onExpandedChange, visibleGroupIds]);
229
+ }, [allGroupsExpanded, expandedIds, onExpandedChange, visibleGroupIds, onToggleAllGroupsExpanded]);
222
230
 
223
231
  const cardsContext = useMemo<CardsContextValue>(
224
232
  () => ({
@@ -316,7 +324,9 @@ export function Content({
316
324
  loading={loading}
317
325
  />
318
326
 
319
- {rightTop}
327
+ <div className={styles.rightTop} data-mobile={isMobile || undefined}>
328
+ {rightTop}
329
+ </div>
320
330
  </MountAnimation>
321
331
  </>
322
332
  )}
@@ -1,24 +1,14 @@
1
- import { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';
2
1
  import { DragDropSVG } from '@cloud-ru/ds-icons/interface/system';
3
2
  import { stopEventPropagation } from '@cloud-ru/ds-utils';
4
3
 
5
4
  import { headerLocale } from '../../../../../../../locale';
6
5
  import styles from '../styles.module.scss';
7
6
 
8
- export type SortableGroupDragHandleProps = {
9
- /** ARIA-атрибуты `dnd-kit` draggable-элемента. */
10
- attributes?: DraggableAttributes;
11
- /** Обработчики событий `dnd-kit` для инициации перетаскивания. */
12
- listeners?: DraggableSyntheticListeners;
13
- };
14
-
15
- export function SortableGroupDragHandle({ attributes, listeners }: SortableGroupDragHandleProps) {
7
+ export function SortableGroupDragHandle() {
16
8
  const { t } = headerLocale.useTranslations();
17
9
 
18
10
  return (
19
11
  <button
20
- {...attributes}
21
- {...listeners}
22
12
  type='button'
23
13
  className={styles.dragHandle}
24
14
  aria-label={t('dragGroup')}
@@ -1,3 +1,4 @@
1
+ import { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';
1
2
  import { Button } from '@cloud-ru/ds-button';
2
3
  import { ChevronDownSVG, ChevronUpSVG } from '@cloud-ru/ds-icons/interface/system';
3
4
  import { Typography } from '@cloud-ru/ds-typography';
@@ -7,14 +8,18 @@ import { memo, MouseEventHandler, useCallback } from 'react';
7
8
  import { LinksGroup, LinksGroupTitle } from '../../../../../types';
8
9
  import { getLinkEmblem } from '../../../../../utils';
9
10
  import styles from '../styles.module.scss';
10
- import { SortableGroupDragHandle, SortableGroupDragHandleProps } from './SortableGroupDragHandle';
11
+ import { SortableGroupDragHandle } from './SortableGroupDragHandle';
11
12
 
12
13
  export type SortableGroupHeaderProps = Pick<LinksGroup, 'icon'> & {
13
14
  label: LinksGroupTitle;
14
15
  isExpanded?: boolean;
15
16
  enableServiceDrag?: boolean;
16
17
  isMobile?: boolean;
17
- } & SortableGroupDragHandleProps;
18
+ /** ARIA-атрибуты `dnd-kit` draggable-элемента. */
19
+ attributes?: DraggableAttributes;
20
+ /** Обработчики событий `dnd-kit` для инициации перетаскивания. */
21
+ listeners?: DraggableSyntheticListeners;
22
+ };
18
23
 
19
24
  function SortableGroupHeaderBase({
20
25
  label,
@@ -35,7 +40,7 @@ function SortableGroupHeaderBase({
35
40
  );
36
41
 
37
42
  return (
38
- <div className={styles.header} data-expanded={isExpanded || undefined}>
43
+ <div className={styles.header} data-expanded={isExpanded || undefined} {...attributes} {...listeners} tabIndex={-1}>
39
44
  <Typography
40
45
  variant='title'
41
46
  size='m'
@@ -56,7 +61,7 @@ function SortableGroupHeaderBase({
56
61
 
57
62
  {(enableServiceDrag || !isMobile) && (
58
63
  <div className={styles.headerActions} data-always-visible={isMobile || undefined}>
59
- {enableServiceDrag && <SortableGroupDragHandle attributes={attributes} listeners={listeners} />}
64
+ {enableServiceDrag && <SortableGroupDragHandle />}
60
65
 
61
66
  {!isMobile && (
62
67
  <Button
@@ -17,6 +17,11 @@ $map-block-color-decor: (
17
17
  'pink': base.$sn-theme-color-pink-decor,
18
18
  );
19
19
 
20
+ @mixin header-actions-visible {
21
+ pointer-events: auto;
22
+ opacity: 1;
23
+ }
24
+
20
25
  .headerActions {
21
26
  pointer-events: none;
22
27
 
@@ -29,7 +34,7 @@ $map-block-color-decor: (
29
34
  outline: none;
30
35
 
31
36
  &[data-always-visible] {
32
- opacity: 1;
37
+ @include header-actions-visible;
33
38
  }
34
39
  }
35
40
 
@@ -47,8 +52,7 @@ $map-block-color-decor: (
47
52
  &:focus-visible,
48
53
  &:has(:focus-visible) {
49
54
  .headerActions {
50
- pointer-events: auto;
51
- opacity: 1;
55
+ @include header-actions-visible;
52
56
  }
53
57
  }
54
58
 
@@ -57,8 +61,7 @@ $map-block-color-decor: (
57
61
  background-color: base.$sn-theme-color-neutral-decorTransparent;
58
62
 
59
63
  .headerActions {
60
- pointer-events: auto;
61
- opacity: 1;
64
+ @include header-actions-visible;
62
65
  }
63
66
  }
64
67
  }
@@ -106,22 +109,31 @@ $map-block-color-decor: (
106
109
  }
107
110
 
108
111
  &[data-drag-preview] {
109
- cursor: grabbing;
110
-
111
112
  .header {
112
- cursor: grabbing;
113
113
  background-color: base.$sn-theme-color-neutral-decorTransparent;
114
114
 
115
115
  .headerActions {
116
- pointer-events: auto;
117
- opacity: 1;
116
+ @include header-actions-visible;
117
+ }
118
+ }
119
+ }
120
+
121
+ &:has(:focus-visible) {
122
+ .headerActions {
123
+ @include header-actions-visible;
124
+ }
125
+ }
126
+
127
+ @media (hover: hover) {
128
+ &:hover {
129
+ .headerActions {
130
+ @include header-actions-visible;
118
131
  }
119
132
  }
120
133
  }
121
134
  }
122
135
 
123
136
  .groupDragPreview {
124
- cursor: grabbing;
125
137
  container-type: inline-size;
126
138
  border-radius: $group-border-radius;
127
139
  }
@@ -172,7 +184,6 @@ $map-block-color-decor: (
172
184
 
173
185
  .groupBody {
174
186
  display: grid;
175
- grid-template-columns: repeat(3, minmax(auto, 1fr));
176
187
  gap: base.$sn-primitive-dimension-4;
177
188
 
178
189
  &:not([data-subcategory-body]) {
@@ -184,14 +195,11 @@ $map-block-color-decor: (
184
195
  gap: 0;
185
196
  }
186
197
 
198
+ // Drawer десктопного меню ресайзится пользователем (см. MenuDesktop.resizable), поэтому число
199
+ // колонок выводится из ширины контейнера автоматически: сколько карточек минимальной ширины влезает.
200
+ // Нет токена минимальной ширины карточки.
187
201
  &:not([data-mobile]) {
188
- // Drawer десктопного меню ресайзится пользователем (см. MenuDesktop.resizable),
189
- // поэтому колонки реагируют на реальную ширину контейнера (container query
190
- // от `.rightContent`), а не на ширину viewport.
191
- // Перестраиваться должно при ширине дровера 1024px, поэтому width тут указан с вычетом
192
- @container (width <= 728px) {
193
- grid-template-columns: repeat(2, minmax(auto, 1fr));
194
- }
202
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
195
203
  }
196
204
 
197
205
  &[data-mobile] {
@@ -27,6 +27,28 @@
27
27
  gap: inherit;
28
28
  }
29
29
 
30
+ .rightTop {
31
+ width: 100%;
32
+ min-width: 0;
33
+
34
+ &:not([data-mobile]) {
35
+ // Не больше двух колонок: минимальная ширина колонки не меньше половины контейнера (за вычетом gap),
36
+ // а при ширине меньше 2 × 286px баннеры встают в одну колонку. `auto-fit` схлопывает пустые колонки: один баннер занимает всю ширину.
37
+ display: grid;
38
+ grid-template-columns: repeat(
39
+ auto-fit,
40
+ minmax(max(286px, calc((100% - #{base.$sn-primitive-dimension-4}) / 2)), 1fr)
41
+ );
42
+ gap: base.$sn-primitive-dimension-4;
43
+ }
44
+
45
+ &[data-mobile] {
46
+ display: flex;
47
+ flex-direction: column;
48
+ gap: base.$sn-primitive-dimension-8;
49
+ }
50
+ }
51
+
30
52
  .noData {
31
53
  flex: 1 1 auto;
32
54
  place-self: center center;
@@ -14,7 +14,7 @@ import { MenuBottom } from '../MenuBottom';
14
14
  import { MenuHeaderBrand } from '../MenuHeaderBrand';
15
15
  import { MountAnimation } from '../MountAnimation';
16
16
  import { Search } from '../Search';
17
- import { MENU_WIDTH_MAX, MENU_WIDTH_MIN } from './constants';
17
+ import { MENU_WIDTH_DEFAULT, MENU_WIDTH_MIN } from './constants';
18
18
  import styles from './styles.module.scss';
19
19
 
20
20
  export function MenuDesktop({
@@ -28,6 +28,7 @@ export function MenuDesktop({
28
28
  onActiveSegmentChange,
29
29
  onSegmentOrderChange,
30
30
  onSegmentExpandedChange,
31
+ onToggleAllGroupsExpanded,
31
32
  onSegmentServiceClick,
32
33
  favorite,
33
34
  search,
@@ -36,7 +37,7 @@ export function MenuDesktop({
36
37
  rightTop,
37
38
  leftTop,
38
39
  leftBottom,
39
- defaultWidth = MENU_WIDTH_MAX,
40
+ defaultWidth = MENU_WIDTH_DEFAULT,
40
41
  onWidthChangeEnd,
41
42
  draggerTooltip,
42
43
  loading,
@@ -140,6 +141,7 @@ export function MenuDesktop({
140
141
  onSegmentOrderChange={onSegmentOrderChange}
141
142
  onSegmentExpandedChange={onSegmentExpandedChange}
142
143
  onSegmentServiceClick={onSegmentServiceClick}
144
+ onToggleAllGroupsExpanded={onToggleAllGroupsExpanded}
143
145
  preferences={preferences}
144
146
  loading={loading}
145
147
  />
@@ -167,8 +169,8 @@ export function MenuDesktop({
167
169
  isNeedRightBlock
168
170
  ? {
169
171
  min: MENU_WIDTH_MIN,
170
- max: MENU_WIDTH_MAX,
171
- default: Math.min(Math.max(defaultWidth, MENU_WIDTH_MIN), MENU_WIDTH_MAX),
172
+ max: 'full',
173
+ default: defaultWidth,
172
174
  onResizeEnd: onWidthChangeEnd,
173
175
  draggerTooltip,
174
176
  }
@@ -1,6 +1,6 @@
1
1
  export const MENU_WIDTH_STORAGE_KEY = 'cloud-ru-main-menu-user-width';
2
2
 
3
3
  // паддинг справа 24px у дровера нужно компенсировать
4
- export const MENU_WIDTH_MIN = 960 + 24;
4
+ export const MENU_WIDTH_MIN = 630 + 24;
5
5
 
6
- export const MENU_WIDTH_MAX = 1208 + 24;
6
+ export const MENU_WIDTH_DEFAULT = 1208 + 24;
@@ -2,6 +2,8 @@
2
2
  @use '@cloud-ru/ds-figma-variables/build/scss/components/divider.module' as divider;
3
3
  @use '@cloud-ru/ds-figma-variables/build/scss/components/drawer.module' as drawer;
4
4
 
5
+ $drawer-sidebar-width: 263px;
6
+
5
7
  .drawer {
6
8
  border-radius: drawer.$sn-drawer-anatomy-container-vertical-positionLeft-container-borderTopLeftRadius
7
9
  drawer.$sn-drawer-anatomy-container-vertical-positionLeft-container-borderTopRightRadius
@@ -40,7 +42,9 @@
40
42
  // по умолчанию box-sizing: content-box; и из-за этого max-width определяется некорректно
41
43
  box-sizing: border-box;
42
44
  width: 100%;
43
- max-width: calc(263px + #{drawer.$sn-drawer-anatomy-container-vertical-positionLeft-paddingRight});
45
+ max-width: calc(
46
+ #{$drawer-sidebar-width} + #{drawer.$sn-drawer-anatomy-container-vertical-positionLeft-paddingRight}
47
+ );
44
48
 
45
49
  .left {
46
50
  width: 100%;
@@ -76,7 +80,7 @@
76
80
  .menu {
77
81
  --snack-menu-header-height: #{base.$sn-primitive-dimension-40};
78
82
  // Нет токена ширины левой колонки меню.
79
- --snack-menu-left-width: 263px;
83
+ --snack-menu-left-width: #{$drawer-sidebar-width};
80
84
 
81
85
  position: relative;
82
86
  height: 100vh;
@@ -13,10 +13,11 @@ import {
13
13
  import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
14
14
  import { sortableKeyboardCoordinates } from '@dnd-kit/sortable';
15
15
  import { usePortalContext } from '@cloud-ru/ds-portal-context';
16
- import { createContext, ReactNode, useCallback, useContext, useMemo, useState } from 'react';
16
+ import { createContext, ReactNode, useCallback, useContext, useEffect, useMemo, useState } from 'react';
17
17
  import { createPortal } from 'react-dom';
18
18
 
19
19
  import { ServiceCard } from '../helperComponents/ServiceCard';
20
+ import styles from '../styles.module.scss';
20
21
  import { FavoriteProps, InnerLink } from '../types';
21
22
  import {
22
23
  favoriteListCollisionDetection,
@@ -163,6 +164,16 @@ export function MainMenuDndContext({
163
164
  overlayContextValue,
164
165
  }: Partial<MainMenuDndContextProps>) {
165
166
  const portalContextRef = usePortalContext();
167
+ const isDragging = Boolean(dragOverlay);
168
+
169
+ useEffect(() => {
170
+ if (!isDragging) return;
171
+
172
+ /* Для предотвращения случайных взаимодействий с любыми другими элементами при перетаскивании */
173
+ document.body.classList.add(styles.dragging);
174
+
175
+ return () => document.body.classList.remove(styles.dragging);
176
+ }, [isDragging]);
166
177
 
167
178
  // `DragOverlay` рендерит `position: fixed` без собственного портала. Drawer-обёртка
168
179
  // (`.snack-rc-drawer-content-wrapper`) держит `will-change: transform`, а это, как и
@@ -0,0 +1,10 @@
1
+ // Класс ставится на `body` на время drag: превью в `DragOverlay` с `pointer-events: none`,
2
+ // поэтому курсор определяется элементами под ним, и `!important` перебивает их собственные.
3
+ .dragging,
4
+ .dragging * {
5
+ cursor: grabbing !important;
6
+ }
7
+
8
+ .dragging * {
9
+ pointer-events: none !important;
10
+ }
@@ -266,6 +266,7 @@ export type MainMenuProps = Pick<
266
266
  | 'onActiveSegmentChange'
267
267
  | 'onSegmentOrderChange'
268
268
  | 'onSegmentExpandedChange'
269
+ | 'onToggleAllGroupsExpanded'
269
270
  | 'onSegmentServiceClick'
270
271
  | 'favorite'
271
272
  | 'preferences'