@cloud-ru/ds-uikit-product-header 2.1.2 → 2.1.3-preview-97040951.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 (37) hide show
  1. package/dist/cjs/components/MainMenu/helperComponents/Content/Content.js +1 -1
  2. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.d.ts +1 -8
  3. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.js +2 -2
  4. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +6 -2
  5. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +1 -1
  6. package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +13 -10
  7. package/dist/cjs/components/MainMenu/helperComponents/Content/styles.module.css +15 -0
  8. package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +1 -1
  9. package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/constants.js +1 -1
  10. package/dist/cjs/components/MainMenu/hooks/useMainMenuDnd.js +12 -0
  11. package/dist/cjs/components/MainMenu/styles.module.css +8 -0
  12. package/dist/cjs/style.css +36 -10
  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 +1 -8
  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 +6 -2
  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 +13 -10
  19. package/dist/esm/components/MainMenu/helperComponents/Content/styles.module.css +15 -0
  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 +10 -1
  23. package/dist/esm/components/MainMenu/styles.module.css +8 -0
  24. package/dist/esm/style.css +36 -10
  25. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  26. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  27. package/package.json +28 -28
  28. package/src/components/MainMenu/helperComponents/Content/Content.tsx +3 -1
  29. package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupDragHandle.tsx +1 -11
  30. package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.tsx +9 -4
  31. package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.scss +27 -19
  32. package/src/components/MainMenu/helperComponents/Content/styles.module.scss +22 -0
  33. package/src/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.tsx +1 -1
  34. package/src/components/MainMenu/helperComponents/MenuDesktop/constants.ts +1 -1
  35. package/src/components/MainMenu/helperComponents/MenuDesktop/styles.module.scss +6 -2
  36. package/src/components/MainMenu/hooks/useMainMenuDnd.tsx +12 -1
  37. package/src/components/MainMenu/styles.module.scss +10 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloud-ru/ds-uikit-product-header",
3
- "version": "2.1.2",
3
+ "version": "2.1.3-preview-97040951.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-adaptive": "^1.0.2",
49
- "@cloud-ru/ds-avatar": "^1.0.11",
50
- "@cloud-ru/ds-accordion": "^1.2.1",
51
- "@cloud-ru/ds-breadcrumbs": "^1.0.28",
52
- "@cloud-ru/ds-button": "^1.0.4",
53
- "@cloud-ru/ds-card": "^1.0.22",
54
- "@cloud-ru/ds-divider": "^1.0.2",
55
- "@cloud-ru/ds-drag-and-drop": "^1.1.3",
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.1",
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-segment-control": "^1.0.13",
67
- "@cloud-ru/ds-skeleton": "^1.0.2",
68
- "@cloud-ru/ds-tooltip": "^1.0.11",
69
- "@cloud-ru/ds-typography": "^1.0.1",
70
- "@cloud-ru/ds-theme": "^2.1.0",
71
- "@cloud-ru/ds-uikit-product-card-predefined": "^4.0.8",
72
- "@cloud-ru/ds-uikit-product-switch-row": "^1.0.14",
73
- "@cloud-ru/ds-uikit-product-title-clickable": "^1.0.16",
74
- "@cloud-ru/ds-utils": "^1.2.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-breadcrumbs": "1.0.28",
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-97040951.0",
56
+ "@cloud-ru/ds-divider": "1.0.2",
57
+ "@cloud-ru/ds-icons": "1.5.0",
58
+ "@cloud-ru/ds-list": "2.3.1",
59
+ "@cloud-ru/ds-info-block": "1.0.3",
60
+ "@cloud-ru/ds-locale": "1.0.0",
61
+ "@cloud-ru/ds-portal-context": "1.0.2",
62
+ "@cloud-ru/ds-modal": "2.0.0",
63
+ "@cloud-ru/ds-promo-tag": "1.0.3",
64
+ "@cloud-ru/ds-scroll": "1.0.5",
65
+ "@cloud-ru/ds-segment-control": "1.0.13",
66
+ "@cloud-ru/ds-search": "1.0.14",
67
+ "@cloud-ru/ds-skeleton": "1.0.2",
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-card-predefined": "4.0.8",
72
+ "@cloud-ru/ds-uikit-product-switch-row": "1.0.14",
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"
@@ -316,7 +316,9 @@ export function Content({
316
316
  loading={loading}
317
317
  />
318
318
 
319
- {rightTop}
319
+ <div className={styles.rightTop} data-mobile={isMobile || undefined}>
320
+ {rightTop}
321
+ </div>
320
322
  </MountAnimation>
321
323
  </>
322
324
  )}
@@ -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;
@@ -167,7 +167,7 @@ export function MenuDesktop({
167
167
  isNeedRightBlock
168
168
  ? {
169
169
  min: MENU_WIDTH_MIN,
170
- max: MENU_WIDTH_MAX,
170
+ max: 'full',
171
171
  default: Math.min(Math.max(defaultWidth, MENU_WIDTH_MIN), MENU_WIDTH_MAX),
172
172
  onResizeEnd: onWidthChangeEnd,
173
173
  draggerTooltip,
@@ -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
6
  export const MENU_WIDTH_MAX = 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
+ }