@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.
- package/README.md +2 -0
- package/dist/cjs/components/MainMenu/MainMenu.d.ts +1 -1
- package/dist/cjs/components/MainMenu/MainMenu.js +2 -2
- package/dist/cjs/components/MainMenu/helperComponents/Content/Content.d.ts +5 -1
- package/dist/cjs/components/MainMenu/helperComponents/Content/Content.js +4 -3
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.d.ts +1 -8
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.js +2 -2
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +6 -2
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +1 -1
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +13 -10
- package/dist/cjs/components/MainMenu/helperComponents/Content/styles.module.css +15 -0
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.d.ts +1 -1
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +4 -4
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/constants.d.ts +1 -1
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/constants.js +3 -3
- package/dist/cjs/components/MainMenu/hooks/useMainMenuDnd.js +12 -0
- package/dist/cjs/components/MainMenu/styles.module.css +8 -0
- package/dist/cjs/components/MainMenu/types.d.ts +1 -1
- package/dist/cjs/style.css +36 -10
- package/dist/esm/components/MainMenu/MainMenu.d.ts +1 -1
- package/dist/esm/components/MainMenu/MainMenu.js +2 -2
- package/dist/esm/components/MainMenu/helperComponents/Content/Content.d.ts +5 -1
- package/dist/esm/components/MainMenu/helperComponents/Content/Content.js +4 -3
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.d.ts +1 -8
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.js +2 -2
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +6 -2
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +1 -1
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +13 -10
- package/dist/esm/components/MainMenu/helperComponents/Content/styles.module.css +15 -0
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.d.ts +1 -1
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +5 -5
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/constants.d.ts +1 -1
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/constants.js +2 -2
- package/dist/esm/components/MainMenu/hooks/useMainMenuDnd.js +10 -1
- package/dist/esm/components/MainMenu/styles.module.css +8 -0
- package/dist/esm/components/MainMenu/types.d.ts +1 -1
- package/dist/esm/style.css +36 -10
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +28 -28
- package/src/components/MainMenu/MainMenu.tsx +2 -0
- package/src/components/MainMenu/helperComponents/Content/Content.tsx +12 -2
- package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.tsx +1 -11
- package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.tsx +9 -4
- package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.scss +27 -19
- package/src/components/MainMenu/helperComponents/Content/styles.module.scss +22 -0
- package/src/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.tsx +6 -4
- package/src/components/MainMenu/helperComponents/MenuDesktop/constants.ts +2 -2
- package/src/components/MainMenu/helperComponents/MenuDesktop/styles.module.scss +6 -2
- package/src/components/MainMenu/hooks/useMainMenuDnd.tsx +12 -1
- package/src/components/MainMenu/styles.module.scss +10 -0
- 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
|
+
"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": "
|
|
49
|
-
"@cloud-ru/ds-
|
|
50
|
-
"@cloud-ru/ds-
|
|
51
|
-
"@cloud-ru/ds-
|
|
52
|
-
"@cloud-ru/ds-
|
|
53
|
-
"@cloud-ru/ds-card": "
|
|
54
|
-
"@cloud-ru/ds-drag-and-drop": "
|
|
55
|
-
"@cloud-ru/ds-
|
|
56
|
-
"@cloud-ru/ds-
|
|
57
|
-
"@cloud-ru/ds-icons": "
|
|
58
|
-
"@cloud-ru/ds-info-block": "
|
|
59
|
-
"@cloud-ru/ds-list": "
|
|
60
|
-
"@cloud-ru/ds-locale": "
|
|
61
|
-
"@cloud-ru/ds-modal": "
|
|
62
|
-
"@cloud-ru/ds-portal-context": "
|
|
63
|
-
"@cloud-ru/ds-promo-tag": "
|
|
64
|
-
"@cloud-ru/ds-
|
|
65
|
-
"@cloud-ru/ds-
|
|
66
|
-
"@cloud-ru/ds-skeleton": "
|
|
67
|
-
"@cloud-ru/ds-
|
|
68
|
-
"@cloud-ru/ds-
|
|
69
|
-
"@cloud-ru/ds-
|
|
70
|
-
"@cloud-ru/ds-
|
|
71
|
-
"@cloud-ru/ds-
|
|
72
|
-
"@cloud-ru/ds-
|
|
73
|
-
"@cloud-ru/ds-utils": "
|
|
74
|
-
"@cloud-ru/ds-uikit-product-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
117
|
-
|
|
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
|
-
|
|
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 {
|
|
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 =
|
|
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:
|
|
171
|
-
default:
|
|
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 =
|
|
4
|
+
export const MENU_WIDTH_MIN = 630 + 24;
|
|
5
5
|
|
|
6
|
-
export const
|
|
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(
|
|
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:
|
|
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
|
+
}
|