@cloud-ru/ds-uikit-product-header 2.1.3-preview-97040951.0 → 2.1.3

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 (38) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/cjs/components/MainMenu/helperComponents/Content/Content.js +1 -1
  3. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.d.ts +8 -1
  4. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.js +2 -2
  5. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +2 -6
  6. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +1 -1
  7. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +10 -13
  8. package/dist/cjs/components/MainMenu/helperComponents/Content/styles.module.css +0 -15
  9. package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +1 -1
  10. package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/constants.js +1 -1
  11. package/dist/cjs/components/MainMenu/hooks/useMainMenuDnd.js +0 -12
  12. package/dist/cjs/style.css +10 -36
  13. package/dist/esm/components/MainMenu/helperComponents/Content/Content.js +1 -1
  14. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.d.ts +8 -1
  15. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.js +2 -2
  16. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +2 -6
  17. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +1 -1
  18. package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +10 -13
  19. package/dist/esm/components/MainMenu/helperComponents/Content/styles.module.css +0 -15
  20. package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +1 -1
  21. package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/constants.js +1 -1
  22. package/dist/esm/components/MainMenu/hooks/useMainMenuDnd.js +1 -10
  23. package/dist/esm/style.css +10 -36
  24. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  25. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  26. package/package.json +28 -28
  27. package/src/components/MainMenu/helperComponents/Content/Content.tsx +1 -3
  28. package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.tsx +11 -1
  29. package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.tsx +4 -9
  30. package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.scss +19 -27
  31. package/src/components/MainMenu/helperComponents/Content/styles.module.scss +0 -22
  32. package/src/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.tsx +1 -1
  33. package/src/components/MainMenu/helperComponents/MenuDesktop/constants.ts +1 -1
  34. package/src/components/MainMenu/helperComponents/MenuDesktop/styles.module.scss +2 -6
  35. package/src/components/MainMenu/hooks/useMainMenuDnd.tsx +1 -12
  36. package/dist/cjs/components/MainMenu/styles.module.css +0 -8
  37. package/dist/esm/components/MainMenu/styles.module.css +0 -8
  38. package/src/components/MainMenu/styles.module.scss +0 -10
package/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
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
+ ## 2.1.3 (2026-10-06)
7
+
8
+ **Note:** Version bump only for package @ds/uikit-product-header
9
+
6
10
  ## 2.1.2 (2026-10-05)
7
11
 
8
12
  ### Bug Fixes
@@ -116,5 +116,5 @@ function Content({ searchValue, search, rightTop, segments, searchGroups = empty
116
116
  appearance: 'neutral',
117
117
  }, content: isSearching ? t('noDataFound') : t('noData'), "data-test-id": isSearching ? constants_1.TEST_IDS.noDataFound : constants_1.TEST_IDS.noData, "data-mobile": isMobile || undefined, className: styles_module_scss_1.default.noData }));
118
118
  })();
119
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [search, (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(styles_module_scss_1.default.content, className), "data-mobile": isMobile || undefined, "data-empty": (!loading && !hasCards) || undefined, children: [!isSearching && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(MountAnimation_1.MountAnimation, { type: mountAnimationType, className: styles_module_scss_1.default.top, children: [(0, jsx_runtime_1.jsx)(ContentToolbar_1.ContentToolbar, { segment: segmentId, onSegmentChange: setSegmentId, segmentItems: segmentItems, allGroupsExpanded: allGroupsExpanded, onToggleAllGroupsExpanded: handleToggleAllGroupsExpanded, preferences: preferences, isMobile: isMobile, loading: loading }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.rightTop, "data-mobile": isMobile || undefined, children: rightTop })] }) })), cards, footer] })] }));
119
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [search, (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(styles_module_scss_1.default.content, className), "data-mobile": isMobile || undefined, "data-empty": (!loading && !hasCards) || undefined, children: [!isSearching && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)(MountAnimation_1.MountAnimation, { type: mountAnimationType, className: styles_module_scss_1.default.top, children: [(0, jsx_runtime_1.jsx)(ContentToolbar_1.ContentToolbar, { segment: segmentId, onSegmentChange: setSegmentId, segmentItems: segmentItems, allGroupsExpanded: allGroupsExpanded, onToggleAllGroupsExpanded: handleToggleAllGroupsExpanded, preferences: preferences, isMobile: isMobile, loading: loading }), rightTop] }) })), cards, footer] })] }));
120
120
  }
@@ -1 +1,8 @@
1
- export declare function SortableGroupDragHandle(): import("react/jsx-runtime").JSX.Element;
1
+ import { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';
2
+ export type SortableGroupDragHandleProps = {
3
+ /** ARIA-атрибуты `dnd-kit` draggable-элемента. */
4
+ attributes?: DraggableAttributes;
5
+ /** Обработчики событий `dnd-kit` для инициации перетаскивания. */
6
+ listeners?: DraggableSyntheticListeners;
7
+ };
8
+ export declare function SortableGroupDragHandle({ attributes, listeners }: SortableGroupDragHandleProps): import("react/jsx-runtime").JSX.Element;
@@ -9,7 +9,7 @@ const system_1 = require("@cloud-ru/ds-icons/interface/system");
9
9
  const utils_1 = require("@cloud-ru/ds-utils");
10
10
  const locale_1 = require("../../../../../../../locale");
11
11
  const styles_module_scss_1 = __importDefault(require('../styles.module.css'));
12
- function SortableGroupDragHandle() {
12
+ function SortableGroupDragHandle({ attributes, listeners }) {
13
13
  const { t } = locale_1.headerLocale.useTranslations();
14
- return ((0, jsx_runtime_1.jsx)("button", { type: 'button', className: styles_module_scss_1.default.dragHandle, "aria-label": t('dragGroup'), "data-test-id": 'header__drawer-menu__group-card-drag-handle', onClick: utils_1.stopEventPropagation, children: (0, jsx_runtime_1.jsx)(system_1.DragDropSVG, { size: 24 }) }));
14
+ return ((0, jsx_runtime_1.jsx)("button", { ...attributes, ...listeners, type: 'button', className: styles_module_scss_1.default.dragHandle, "aria-label": t('dragGroup'), "data-test-id": 'header__drawer-menu__group-card-drag-handle', onClick: utils_1.stopEventPropagation, children: (0, jsx_runtime_1.jsx)(system_1.DragDropSVG, { size: 24 }) }));
15
15
  }
@@ -1,15 +1,11 @@
1
- import { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';
2
1
  import { LinksGroup, LinksGroupTitle } from '../../../../../types';
2
+ import { SortableGroupDragHandleProps } from './SortableGroupDragHandle';
3
3
  export type SortableGroupHeaderProps = Pick<LinksGroup, 'icon'> & {
4
4
  label: LinksGroupTitle;
5
5
  isExpanded?: boolean;
6
6
  enableServiceDrag?: boolean;
7
7
  isMobile?: boolean;
8
- /** ARIA-атрибуты `dnd-kit` draggable-элемента. */
9
- attributes?: DraggableAttributes;
10
- /** Обработчики событий `dnd-kit` для инициации перетаскивания. */
11
- listeners?: DraggableSyntheticListeners;
12
- };
8
+ } & SortableGroupDragHandleProps;
13
9
  declare function SortableGroupHeaderBase({ label, icon, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }: SortableGroupHeaderProps): import("react/jsx-runtime").JSX.Element;
14
10
  export declare const SortableGroupHeader: import("react").MemoExoticComponent<typeof SortableGroupHeaderBase>;
15
11
  export {};
@@ -18,6 +18,6 @@ function SortableGroupHeaderBase({ label, icon, isExpanded, enableServiceDrag, a
18
18
  e.stopPropagation();
19
19
  label?.onClick?.(e);
20
20
  }, [label]);
21
- return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.header, "data-expanded": isExpanded || undefined, ...attributes, ...listeners, tabIndex: -1, children: [(0, jsx_runtime_1.jsx)(typography_1.Typography, { variant: 'title', size: 'm', className: styles_module_scss_1.default.headerTitle, "data-test-id": 'header__drawer-menu__group-card-title', children: label.onClick || label.href ? ((0, jsx_runtime_1.jsx)(uikit_product_title_clickable_1.TitleClickable, { ...(label.href ? { as: 'a', href: label.href } : { as: 'div' }), onClick: handleLabelClick, title: label.text, icon: (0, utils_1.getLinkEmblem)({ icon }) })) : (label.text) }), (enableServiceDrag || !isMobile) && ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.headerActions, "data-always-visible": isMobile || undefined, children: [enableServiceDrag && (0, jsx_runtime_1.jsx)(SortableGroupDragHandle_1.SortableGroupDragHandle, {}), !isMobile && ((0, jsx_runtime_1.jsx)(button_1.Button, { view: 'elevated', appearance: 'neutral', size: 's', icon: isExpanded ? (0, jsx_runtime_1.jsx)(system_1.ChevronUpSVG, {}) : (0, jsx_runtime_1.jsx)(system_1.ChevronDownSVG, {}), "data-test-id": 'header__drawer-menu__group-card-collapse' }))] }))] }));
21
+ return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.header, "data-expanded": isExpanded || undefined, children: [(0, jsx_runtime_1.jsx)(typography_1.Typography, { variant: 'title', size: 'm', className: styles_module_scss_1.default.headerTitle, "data-test-id": 'header__drawer-menu__group-card-title', children: label.onClick || label.href ? ((0, jsx_runtime_1.jsx)(uikit_product_title_clickable_1.TitleClickable, { ...(label.href ? { as: 'a', href: label.href } : { as: 'div' }), onClick: handleLabelClick, title: label.text, icon: (0, utils_1.getLinkEmblem)({ icon }) })) : (label.text) }), (enableServiceDrag || !isMobile) && ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.headerActions, "data-always-visible": isMobile || undefined, children: [enableServiceDrag && (0, jsx_runtime_1.jsx)(SortableGroupDragHandle_1.SortableGroupDragHandle, { attributes: attributes, listeners: listeners }), !isMobile && ((0, jsx_runtime_1.jsx)(button_1.Button, { view: 'elevated', appearance: 'neutral', size: 's', icon: isExpanded ? (0, jsx_runtime_1.jsx)(system_1.ChevronUpSVG, {}) : (0, jsx_runtime_1.jsx)(system_1.ChevronDownSVG, {}), "data-test-id": 'header__drawer-menu__group-card-collapse' }))] }))] }));
22
22
  }
23
23
  exports.SortableGroupHeader = (0, react_1.memo)(SortableGroupHeaderBase);
@@ -8,7 +8,6 @@
8
8
  outline:none;
9
9
  }
10
10
  .headerActions[data-always-visible]{
11
- pointer-events:auto;
12
11
  opacity:1;
13
12
  }
14
13
 
@@ -64,25 +63,20 @@
64
63
  animation:none;
65
64
  }
66
65
  }
66
+ .group[data-drag-preview]{
67
+ cursor:grabbing;
68
+ }
67
69
  .group[data-drag-preview] .header{
70
+ cursor:grabbing;
68
71
  background-color:var(--sn-theme-color-neutral-decorTransparent, var(--sn-brand-color-neutral-transparent-forLightMode, rgba(136, 146, 170, 0.0784313725)));
69
72
  }
70
73
  .group[data-drag-preview] .header .headerActions{
71
74
  pointer-events:auto;
72
75
  opacity:1;
73
76
  }
74
- .group:has(:focus-visible) .headerActions{
75
- pointer-events:auto;
76
- opacity:1;
77
- }
78
- @media (hover: hover){
79
- .group:hover .headerActions{
80
- pointer-events:auto;
81
- opacity:1;
82
- }
83
- }
84
77
 
85
78
  .groupDragPreview{
79
+ cursor:grabbing;
86
80
  container-type:inline-size;
87
81
  border-radius:var(--sn-density-radius-2xs, var(--sn-platform-comfort-radius-2xs, var(--sn-primitive-dimension-4, 4px)));
88
82
  }
@@ -125,6 +119,7 @@
125
119
 
126
120
  .groupBody{
127
121
  display:grid;
122
+ grid-template-columns:repeat(3, minmax(auto, 1fr));
128
123
  gap:var(--sn-primitive-dimension-4, 4px);
129
124
  }
130
125
  .groupBody:not([data-subcategory-body]){
@@ -133,8 +128,10 @@
133
128
  .groupBody:not([data-show-description]){
134
129
  gap:0;
135
130
  }
136
- .groupBody:not([data-mobile]){
137
- grid-template-columns:repeat(auto-fill, minmax(240px, 1fr));
131
+ @container (width <= 728px){
132
+ .groupBody:not([data-mobile]){
133
+ grid-template-columns:repeat(2, minmax(auto, 1fr));
134
+ }
138
135
  }
139
136
  .groupBody[data-mobile]{
140
137
  grid-template-columns:repeat(1, minmax(200px, 1fr));
@@ -21,21 +21,6 @@
21
21
  gap:inherit;
22
22
  }
23
23
 
24
- .rightTop{
25
- width:100%;
26
- min-width:0;
27
- }
28
- .rightTop:not([data-mobile]){
29
- display:grid;
30
- grid-template-columns:repeat(auto-fit, minmax(max(286px, (100% - var(--sn-primitive-dimension-4, 4px)) / 2), 1fr));
31
- gap:var(--sn-primitive-dimension-4, 4px);
32
- }
33
- .rightTop[data-mobile]{
34
- display:flex;
35
- flex-direction:column;
36
- gap:var(--sn-primitive-dimension-8, 8px);
37
- }
38
-
39
24
  .noData{
40
25
  flex:1 1 auto;
41
26
  place-self:center center;
@@ -60,7 +60,7 @@ function MenuDesktop({ open = false, setOpen, settingItems, platformGroups, segm
60
60
  return ((0, jsx_runtime_1.jsx)(drawer_1.DrawerCustom, { open: open, onClose: handleCloseDrawer, width: isNeedRightBlock ? 'm' : 's', position: 'left', className: styles_module_scss_1.default.drawer, rootClassName: styles_module_scss_1.default.drawerRoot, "data-test-id": constants_1.TEST_IDS.mainMenu.drawer, "data-small": !isNeedRightBlock || undefined, disableMotions: true, showButtonClosed: false, resizable: isNeedRightBlock
61
61
  ? {
62
62
  min: constants_2.MENU_WIDTH_MIN,
63
- max: 'full',
63
+ max: constants_2.MENU_WIDTH_MAX,
64
64
  default: Math.min(Math.max(defaultWidth, constants_2.MENU_WIDTH_MIN), constants_2.MENU_WIDTH_MAX),
65
65
  onResizeEnd: onWidthChangeEnd,
66
66
  draggerTooltip,
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MENU_WIDTH_MAX = exports.MENU_WIDTH_MIN = exports.MENU_WIDTH_STORAGE_KEY = void 0;
4
4
  exports.MENU_WIDTH_STORAGE_KEY = 'cloud-ru-main-menu-user-width';
5
5
  // паддинг справа 24px у дровера нужно компенсировать
6
- exports.MENU_WIDTH_MIN = 630 + 24;
6
+ exports.MENU_WIDTH_MIN = 960 + 24;
7
7
  exports.MENU_WIDTH_MAX = 1208 + 24;
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.useMainMenuDndOverlay = useMainMenuDndOverlay;
7
4
  exports.useMainMenuDnd = useMainMenuDnd;
@@ -14,7 +11,6 @@ const portal_context_1 = require("@cloud-ru/ds-portal-context");
14
11
  const react_1 = require("react");
15
12
  const react_dom_1 = require("react-dom");
16
13
  const ServiceCard_1 = require("../helperComponents/ServiceCard");
17
- const styles_module_scss_1 = __importDefault(require('../styles.module.css'));
18
14
  const utils_1 = require("../utils");
19
15
  const restrictGroupDragToVerticalAxis = args => {
20
16
  if (args.active?.id != null && (0, utils_1.isServiceSourceDragId)(args.active.id)) {
@@ -91,14 +87,6 @@ function useMainMenuDnd({ favorite, servicesById, showDescription }) {
91
87
  }
92
88
  function MainMenuDndContext({ children, sensors, modifiers, collisionDetection, onDragStart, onDragEnd, onDragCancel, dragOverlay, overlayContextValue, }) {
93
89
  const portalContextRef = (0, portal_context_1.usePortalContext)();
94
- const isDragging = Boolean(dragOverlay);
95
- (0, react_1.useEffect)(() => {
96
- if (!isDragging)
97
- return;
98
- /* Для предотвращения случайных взаимодействий с любыми другими элементами при перетаскивании */
99
- document.body.classList.add(styles_module_scss_1.default.dragging);
100
- return () => document.body.classList.remove(styles_module_scss_1.default.dragging);
101
- }, [isDragging]);
102
90
  // `DragOverlay` рендерит `position: fixed` без собственного портала. Drawer-обёртка
103
91
  // (`.snack-rc-drawer-content-wrapper`) держит `will-change: transform`, а это, как и
104
92
  // настоящий transform, создаёт containing block для fixed-потомков — оверлей резолвится
@@ -300,7 +300,6 @@
300
300
  outline:none;
301
301
  }
302
302
  .headerActions[data-always-visible]{
303
- pointer-events:auto;
304
303
  opacity:1;
305
304
  }
306
305
 
@@ -356,25 +355,20 @@
356
355
  animation:none;
357
356
  }
358
357
  }
358
+ .group[data-drag-preview]{
359
+ cursor:grabbing;
360
+ }
359
361
  .group[data-drag-preview] .header{
362
+ cursor:grabbing;
360
363
  background-color:var(--sn-theme-color-neutral-decorTransparent, var(--sn-brand-color-neutral-transparent-forLightMode, rgba(136, 146, 170, 0.0784313725)));
361
364
  }
362
365
  .group[data-drag-preview] .header .headerActions{
363
366
  pointer-events:auto;
364
367
  opacity:1;
365
368
  }
366
- .group:has(:focus-visible) .headerActions{
367
- pointer-events:auto;
368
- opacity:1;
369
- }
370
- @media (hover: hover){
371
- .group:hover .headerActions{
372
- pointer-events:auto;
373
- opacity:1;
374
- }
375
- }
376
369
 
377
370
  .groupDragPreview{
371
+ cursor:grabbing;
378
372
  container-type:inline-size;
379
373
  border-radius:var(--sn-density-radius-2xs, var(--sn-platform-comfort-radius-2xs, var(--sn-primitive-dimension-4, 4px)));
380
374
  }
@@ -417,6 +411,7 @@
417
411
 
418
412
  .groupBody{
419
413
  display:grid;
414
+ grid-template-columns:repeat(3, minmax(auto, 1fr));
420
415
  gap:var(--sn-primitive-dimension-4, 4px);
421
416
  }
422
417
  .groupBody:not([data-subcategory-body]){
@@ -425,8 +420,10 @@
425
420
  .groupBody:not([data-show-description]){
426
421
  gap:0;
427
422
  }
428
- .groupBody:not([data-mobile]){
429
- grid-template-columns:repeat(auto-fill, minmax(240px, 1fr));
423
+ @container (width <= 728px){
424
+ .groupBody:not([data-mobile]){
425
+ grid-template-columns:repeat(2, minmax(auto, 1fr));
426
+ }
430
427
  }
431
428
  .groupBody[data-mobile]{
432
429
  grid-template-columns:repeat(1, minmax(200px, 1fr));
@@ -578,21 +575,6 @@
578
575
  gap:inherit;
579
576
  }
580
577
 
581
- .rightTop{
582
- width:100%;
583
- min-width:0;
584
- }
585
- .rightTop:not([data-mobile]){
586
- display:grid;
587
- grid-template-columns:repeat(auto-fit, minmax(max(286px, (100% - var(--sn-primitive-dimension-4, 4px)) / 2), 1fr));
588
- gap:var(--sn-primitive-dimension-4, 4px);
589
- }
590
- .rightTop[data-mobile]{
591
- display:flex;
592
- flex-direction:column;
593
- gap:var(--sn-primitive-dimension-8, 8px);
594
- }
595
-
596
578
  .noData{
597
579
  flex:1 1 auto;
598
580
  place-self:center center;
@@ -957,14 +939,6 @@
957
939
  .staticCard{
958
940
  position:relative;
959
941
  }
960
- .dragging,
961
- .dragging *{
962
- cursor:grabbing !important;
963
- }
964
-
965
- .dragging *{
966
- pointer-events:none !important;
967
- }
968
942
  .container{
969
943
  display:flex;
970
944
  align-items:center;
@@ -110,5 +110,5 @@ export function Content({ searchValue, search, rightTop, segments, searchGroups
110
110
  appearance: 'neutral',
111
111
  }, content: isSearching ? t('noDataFound') : t('noData'), "data-test-id": isSearching ? TEST_IDS.noDataFound : TEST_IDS.noData, "data-mobile": isMobile || undefined, className: styles.noData }));
112
112
  })();
113
- return (_jsxs(_Fragment, { children: [search, _jsxs("div", { className: cn(styles.content, className), "data-mobile": isMobile || undefined, "data-empty": (!loading && !hasCards) || undefined, children: [!isSearching && (_jsx(_Fragment, { children: _jsxs(MountAnimation, { type: mountAnimationType, className: styles.top, children: [_jsx(ContentToolbar, { segment: segmentId, onSegmentChange: setSegmentId, segmentItems: segmentItems, allGroupsExpanded: allGroupsExpanded, onToggleAllGroupsExpanded: handleToggleAllGroupsExpanded, preferences: preferences, isMobile: isMobile, loading: loading }), _jsx("div", { className: styles.rightTop, "data-mobile": isMobile || undefined, children: rightTop })] }) })), cards, footer] })] }));
113
+ return (_jsxs(_Fragment, { children: [search, _jsxs("div", { className: cn(styles.content, className), "data-mobile": isMobile || undefined, "data-empty": (!loading && !hasCards) || undefined, children: [!isSearching && (_jsx(_Fragment, { children: _jsxs(MountAnimation, { type: mountAnimationType, className: styles.top, children: [_jsx(ContentToolbar, { segment: segmentId, onSegmentChange: setSegmentId, segmentItems: segmentItems, allGroupsExpanded: allGroupsExpanded, onToggleAllGroupsExpanded: handleToggleAllGroupsExpanded, preferences: preferences, isMobile: isMobile, loading: loading }), rightTop] }) })), cards, footer] })] }));
114
114
  }
@@ -1 +1,8 @@
1
- export declare function SortableGroupDragHandle(): import("react/jsx-runtime").JSX.Element;
1
+ import { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';
2
+ export type SortableGroupDragHandleProps = {
3
+ /** ARIA-атрибуты `dnd-kit` draggable-элемента. */
4
+ attributes?: DraggableAttributes;
5
+ /** Обработчики событий `dnd-kit` для инициации перетаскивания. */
6
+ listeners?: DraggableSyntheticListeners;
7
+ };
8
+ export declare function SortableGroupDragHandle({ attributes, listeners }: SortableGroupDragHandleProps): import("react/jsx-runtime").JSX.Element;
@@ -3,7 +3,7 @@ import { DragDropSVG } from '@cloud-ru/ds-icons/interface/system';
3
3
  import { stopEventPropagation } from '@cloud-ru/ds-utils';
4
4
  import { headerLocale } from '../../../../../../../locale/index.js';
5
5
  import styles from '../styles.module.css';
6
- export function SortableGroupDragHandle() {
6
+ export function SortableGroupDragHandle({ attributes, listeners }) {
7
7
  const { t } = headerLocale.useTranslations();
8
- return (_jsx("button", { type: 'button', className: styles.dragHandle, "aria-label": t('dragGroup'), "data-test-id": 'header__drawer-menu__group-card-drag-handle', onClick: stopEventPropagation, children: _jsx(DragDropSVG, { size: 24 }) }));
8
+ return (_jsx("button", { ...attributes, ...listeners, type: 'button', className: styles.dragHandle, "aria-label": t('dragGroup'), "data-test-id": 'header__drawer-menu__group-card-drag-handle', onClick: stopEventPropagation, children: _jsx(DragDropSVG, { size: 24 }) }));
9
9
  }
@@ -1,15 +1,11 @@
1
- import { DraggableAttributes, DraggableSyntheticListeners } from '@dnd-kit/core';
2
1
  import { LinksGroup, LinksGroupTitle } from '../../../../../types.js';
2
+ import { SortableGroupDragHandleProps } from './SortableGroupDragHandle.js';
3
3
  export type SortableGroupHeaderProps = Pick<LinksGroup, 'icon'> & {
4
4
  label: LinksGroupTitle;
5
5
  isExpanded?: boolean;
6
6
  enableServiceDrag?: boolean;
7
7
  isMobile?: boolean;
8
- /** ARIA-атрибуты `dnd-kit` draggable-элемента. */
9
- attributes?: DraggableAttributes;
10
- /** Обработчики событий `dnd-kit` для инициации перетаскивания. */
11
- listeners?: DraggableSyntheticListeners;
12
- };
8
+ } & SortableGroupDragHandleProps;
13
9
  declare function SortableGroupHeaderBase({ label, icon, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }: SortableGroupHeaderProps): import("react/jsx-runtime").JSX.Element;
14
10
  export declare const SortableGroupHeader: import("react").MemoExoticComponent<typeof SortableGroupHeaderBase>;
15
11
  export {};
@@ -12,6 +12,6 @@ function SortableGroupHeaderBase({ label, icon, isExpanded, enableServiceDrag, a
12
12
  e.stopPropagation();
13
13
  label?.onClick?.(e);
14
14
  }, [label]);
15
- return (_jsxs("div", { className: styles.header, "data-expanded": isExpanded || undefined, ...attributes, ...listeners, tabIndex: -1, children: [_jsx(Typography, { variant: 'title', size: 'm', className: styles.headerTitle, "data-test-id": 'header__drawer-menu__group-card-title', children: label.onClick || label.href ? (_jsx(TitleClickable, { ...(label.href ? { as: 'a', href: label.href } : { as: 'div' }), onClick: handleLabelClick, title: label.text, icon: getLinkEmblem({ icon }) })) : (label.text) }), (enableServiceDrag || !isMobile) && (_jsxs("div", { className: styles.headerActions, "data-always-visible": isMobile || undefined, children: [enableServiceDrag && _jsx(SortableGroupDragHandle, {}), !isMobile && (_jsx(Button, { view: 'elevated', appearance: 'neutral', size: 's', icon: isExpanded ? _jsx(ChevronUpSVG, {}) : _jsx(ChevronDownSVG, {}), "data-test-id": 'header__drawer-menu__group-card-collapse' }))] }))] }));
15
+ return (_jsxs("div", { className: styles.header, "data-expanded": isExpanded || undefined, children: [_jsx(Typography, { variant: 'title', size: 'm', className: styles.headerTitle, "data-test-id": 'header__drawer-menu__group-card-title', children: label.onClick || label.href ? (_jsx(TitleClickable, { ...(label.href ? { as: 'a', href: label.href } : { as: 'div' }), onClick: handleLabelClick, title: label.text, icon: getLinkEmblem({ icon }) })) : (label.text) }), (enableServiceDrag || !isMobile) && (_jsxs("div", { className: styles.headerActions, "data-always-visible": isMobile || undefined, children: [enableServiceDrag && _jsx(SortableGroupDragHandle, { attributes: attributes, listeners: listeners }), !isMobile && (_jsx(Button, { view: 'elevated', appearance: 'neutral', size: 's', icon: isExpanded ? _jsx(ChevronUpSVG, {}) : _jsx(ChevronDownSVG, {}), "data-test-id": 'header__drawer-menu__group-card-collapse' }))] }))] }));
16
16
  }
17
17
  export const SortableGroupHeader = memo(SortableGroupHeaderBase);
@@ -8,7 +8,6 @@
8
8
  outline:none;
9
9
  }
10
10
  .headerActions[data-always-visible]{
11
- pointer-events:auto;
12
11
  opacity:1;
13
12
  }
14
13
 
@@ -64,25 +63,20 @@
64
63
  animation:none;
65
64
  }
66
65
  }
66
+ .group[data-drag-preview]{
67
+ cursor:grabbing;
68
+ }
67
69
  .group[data-drag-preview] .header{
70
+ cursor:grabbing;
68
71
  background-color:var(--sn-theme-color-neutral-decorTransparent, var(--sn-brand-color-neutral-transparent-forLightMode, rgba(136, 146, 170, 0.0784313725)));
69
72
  }
70
73
  .group[data-drag-preview] .header .headerActions{
71
74
  pointer-events:auto;
72
75
  opacity:1;
73
76
  }
74
- .group:has(:focus-visible) .headerActions{
75
- pointer-events:auto;
76
- opacity:1;
77
- }
78
- @media (hover: hover){
79
- .group:hover .headerActions{
80
- pointer-events:auto;
81
- opacity:1;
82
- }
83
- }
84
77
 
85
78
  .groupDragPreview{
79
+ cursor:grabbing;
86
80
  container-type:inline-size;
87
81
  border-radius:var(--sn-density-radius-2xs, var(--sn-platform-comfort-radius-2xs, var(--sn-primitive-dimension-4, 4px)));
88
82
  }
@@ -125,6 +119,7 @@
125
119
 
126
120
  .groupBody{
127
121
  display:grid;
122
+ grid-template-columns:repeat(3, minmax(auto, 1fr));
128
123
  gap:var(--sn-primitive-dimension-4, 4px);
129
124
  }
130
125
  .groupBody:not([data-subcategory-body]){
@@ -133,8 +128,10 @@
133
128
  .groupBody:not([data-show-description]){
134
129
  gap:0;
135
130
  }
136
- .groupBody:not([data-mobile]){
137
- grid-template-columns:repeat(auto-fill, minmax(240px, 1fr));
131
+ @container (width <= 728px){
132
+ .groupBody:not([data-mobile]){
133
+ grid-template-columns:repeat(2, minmax(auto, 1fr));
134
+ }
138
135
  }
139
136
  .groupBody[data-mobile]{
140
137
  grid-template-columns:repeat(1, minmax(200px, 1fr));
@@ -21,21 +21,6 @@
21
21
  gap:inherit;
22
22
  }
23
23
 
24
- .rightTop{
25
- width:100%;
26
- min-width:0;
27
- }
28
- .rightTop:not([data-mobile]){
29
- display:grid;
30
- grid-template-columns:repeat(auto-fit, minmax(max(286px, (100% - var(--sn-primitive-dimension-4, 4px)) / 2), 1fr));
31
- gap:var(--sn-primitive-dimension-4, 4px);
32
- }
33
- .rightTop[data-mobile]{
34
- display:flex;
35
- flex-direction:column;
36
- gap:var(--sn-primitive-dimension-8, 8px);
37
- }
38
-
39
24
  .noData{
40
25
  flex:1 1 auto;
41
26
  place-self:center center;
@@ -54,7 +54,7 @@ export function MenuDesktop({ open = false, setOpen, settingItems, platformGroup
54
54
  return (_jsx(DrawerCustom, { open: open, onClose: handleCloseDrawer, width: isNeedRightBlock ? 'm' : 's', position: 'left', className: styles.drawer, rootClassName: styles.drawerRoot, "data-test-id": TEST_IDS.mainMenu.drawer, "data-small": !isNeedRightBlock || undefined, disableMotions: true, showButtonClosed: false, resizable: isNeedRightBlock
55
55
  ? {
56
56
  min: MENU_WIDTH_MIN,
57
- max: 'full',
57
+ max: MENU_WIDTH_MAX,
58
58
  default: Math.min(Math.max(defaultWidth, MENU_WIDTH_MIN), MENU_WIDTH_MAX),
59
59
  onResizeEnd: onWidthChangeEnd,
60
60
  draggerTooltip,
@@ -1,4 +1,4 @@
1
1
  export const MENU_WIDTH_STORAGE_KEY = 'cloud-ru-main-menu-user-width';
2
2
  // паддинг справа 24px у дровера нужно компенсировать
3
- export const MENU_WIDTH_MIN = 630 + 24;
3
+ export const MENU_WIDTH_MIN = 960 + 24;
4
4
  export const MENU_WIDTH_MAX = 1208 + 24;
@@ -3,10 +3,9 @@ import { DndContext, DragOverlay, KeyboardSensor, PointerSensor, useSensor, useS
3
3
  import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
4
4
  import { sortableKeyboardCoordinates } from '@dnd-kit/sortable';
5
5
  import { usePortalContext } from '@cloud-ru/ds-portal-context';
6
- import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
6
+ import { createContext, useCallback, useContext, useMemo, useState } from 'react';
7
7
  import { createPortal } from 'react-dom';
8
8
  import { ServiceCard } from '../helperComponents/ServiceCard/index.js';
9
- import styles from '../styles.module.css';
10
9
  import { favoriteListCollisionDetection, getDragReferenceY, isServiceDragId, isServiceSourceDragId, parseServiceDragId, resolveFavoriteOrderOnDragEnd, } from '../utils/index.js';
11
10
  const restrictGroupDragToVerticalAxis = args => {
12
11
  if (args.active?.id != null && isServiceSourceDragId(args.active.id)) {
@@ -83,14 +82,6 @@ export function useMainMenuDnd({ favorite, servicesById, showDescription }) {
83
82
  }
84
83
  export function MainMenuDndContext({ children, sensors, modifiers, collisionDetection, onDragStart, onDragEnd, onDragCancel, dragOverlay, overlayContextValue, }) {
85
84
  const portalContextRef = usePortalContext();
86
- const isDragging = Boolean(dragOverlay);
87
- useEffect(() => {
88
- if (!isDragging)
89
- return;
90
- /* Для предотвращения случайных взаимодействий с любыми другими элементами при перетаскивании */
91
- document.body.classList.add(styles.dragging);
92
- return () => document.body.classList.remove(styles.dragging);
93
- }, [isDragging]);
94
85
  // `DragOverlay` рендерит `position: fixed` без собственного портала. Drawer-обёртка
95
86
  // (`.snack-rc-drawer-content-wrapper`) держит `will-change: transform`, а это, как и
96
87
  // настоящий transform, создаёт containing block для fixed-потомков — оверлей резолвится
@@ -300,7 +300,6 @@
300
300
  outline:none;
301
301
  }
302
302
  .headerActions[data-always-visible]{
303
- pointer-events:auto;
304
303
  opacity:1;
305
304
  }
306
305
 
@@ -356,25 +355,20 @@
356
355
  animation:none;
357
356
  }
358
357
  }
358
+ .group[data-drag-preview]{
359
+ cursor:grabbing;
360
+ }
359
361
  .group[data-drag-preview] .header{
362
+ cursor:grabbing;
360
363
  background-color:var(--sn-theme-color-neutral-decorTransparent, var(--sn-brand-color-neutral-transparent-forLightMode, rgba(136, 146, 170, 0.0784313725)));
361
364
  }
362
365
  .group[data-drag-preview] .header .headerActions{
363
366
  pointer-events:auto;
364
367
  opacity:1;
365
368
  }
366
- .group:has(:focus-visible) .headerActions{
367
- pointer-events:auto;
368
- opacity:1;
369
- }
370
- @media (hover: hover){
371
- .group:hover .headerActions{
372
- pointer-events:auto;
373
- opacity:1;
374
- }
375
- }
376
369
 
377
370
  .groupDragPreview{
371
+ cursor:grabbing;
378
372
  container-type:inline-size;
379
373
  border-radius:var(--sn-density-radius-2xs, var(--sn-platform-comfort-radius-2xs, var(--sn-primitive-dimension-4, 4px)));
380
374
  }
@@ -417,6 +411,7 @@
417
411
 
418
412
  .groupBody{
419
413
  display:grid;
414
+ grid-template-columns:repeat(3, minmax(auto, 1fr));
420
415
  gap:var(--sn-primitive-dimension-4, 4px);
421
416
  }
422
417
  .groupBody:not([data-subcategory-body]){
@@ -425,8 +420,10 @@
425
420
  .groupBody:not([data-show-description]){
426
421
  gap:0;
427
422
  }
428
- .groupBody:not([data-mobile]){
429
- grid-template-columns:repeat(auto-fill, minmax(240px, 1fr));
423
+ @container (width <= 728px){
424
+ .groupBody:not([data-mobile]){
425
+ grid-template-columns:repeat(2, minmax(auto, 1fr));
426
+ }
430
427
  }
431
428
  .groupBody[data-mobile]{
432
429
  grid-template-columns:repeat(1, minmax(200px, 1fr));
@@ -578,21 +575,6 @@
578
575
  gap:inherit;
579
576
  }
580
577
 
581
- .rightTop{
582
- width:100%;
583
- min-width:0;
584
- }
585
- .rightTop:not([data-mobile]){
586
- display:grid;
587
- grid-template-columns:repeat(auto-fit, minmax(max(286px, (100% - var(--sn-primitive-dimension-4, 4px)) / 2), 1fr));
588
- gap:var(--sn-primitive-dimension-4, 4px);
589
- }
590
- .rightTop[data-mobile]{
591
- display:flex;
592
- flex-direction:column;
593
- gap:var(--sn-primitive-dimension-8, 8px);
594
- }
595
-
596
578
  .noData{
597
579
  flex:1 1 auto;
598
580
  place-self:center center;
@@ -957,14 +939,6 @@
957
939
  .staticCard{
958
940
  position:relative;
959
941
  }
960
- .dragging,
961
- .dragging *{
962
- cursor:grabbing !important;
963
- }
964
-
965
- .dragging *{
966
- pointer-events:none !important;
967
- }
968
942
  .container{
969
943
  display:flex;
970
944
  align-items:center;