@cloud-ru/ds-uikit-product-header 2.0.8-preview-5c9b8135.0 → 2.1.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/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
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.0 (2026-10-05)
7
+
8
+ ### Features
9
+
10
+ - **FF-9204:** add disableSpanWrapper prop ([2f4bc67](https://github.com/cloud-ru-tech/snack-v2/commit/2f4bc675bb984f18c788913dd8f5136cd4be3ed9))
11
+
6
12
  ## 2.0.7 (2026-10-02)
7
13
 
8
14
  **Note:** Version bump only for package @ds/uikit-product-header
package/README.md CHANGED
@@ -339,7 +339,7 @@ function LocalMainMenu() {
339
339
  | Prop | Type | Default | Description |
340
340
  |------|------|---------|-------------|
341
341
  | `aliases` | `string[]` | — | Синонимы для fuzzy-поиска. |
342
- | `badge` | `CardPromoTagProps` \| `PromoTagPredefinedBaseProps` | — | Промо-тег карточки. |
342
+ | `badge` | `CardServiceLightProps` \| `PromoTagPredefinedBaseProps` | — | Промо-тег карточки. |
343
343
  | `description` | `string \| undefined` | — | Краткое описание сервиса — отображается при включённом переключателе «Описание». |
344
344
  | `disabled` | `boolean \| undefined` | — | Карточка недоступна для клика/drag и визуально приглушена. |
345
345
  | `favoritesEnabled` | `boolean \| undefined` | — | Разрешено ли добавление карточки в избранное. default=true - разрешено |
@@ -513,7 +513,7 @@ import { MainMenu, MenuMobile } from '@cloud-ru/ds-uikit-product-header';
513
513
  | Prop | Type | Default | Description |
514
514
  |------|------|---------|-------------|
515
515
  | `aliases` | `string[]` | — | Синонимы для fuzzy-поиска. |
516
- | `badge` | `CardPromoTagProps` \| `PromoTagPredefinedBaseProps` | — | Промо-тег карточки. |
516
+ | `badge` | `CardServiceLightProps` \| `PromoTagPredefinedBaseProps` | — | Промо-тег карточки. |
517
517
  | `description` | `string \| undefined` | — | Краткое описание сервиса — отображается при включённом переключателе «Описание». |
518
518
  | `disabled` | `boolean \| undefined` | — | Карточка недоступна для клика/drag и визуально приглушена. |
519
519
  | `favoritesEnabled` | `boolean \| undefined` | — | Разрешено ли добавление карточки в избранное. default=true - разрешено |
@@ -693,16 +693,16 @@ export function ControlledTheme() {
693
693
 
694
694
  | Prop | Type | Default | Description |
695
695
  |------|------|---------|-------------|
696
- | `bottomItems` | `BaseItemWithoutNonGroup` \| `CommonGroupItem` \| `Item` \| `ScrollProps` | — | Пункты перед «Выйти из аккаунта». На desktop закреплены снизу |
696
+ | `bottomItems` | `BaseItemWithoutNonGroup` \| `CommonGroupItem` \| `DroplistProps` \| `ScrollProps` | — | Пункты перед «Выйти из аккаунта». На desktop закреплены снизу |
697
697
  | `onClick` | `(() => void)` | — | Колбэк клика по кнопке-триггеру. |
698
698
  | `onLogout` | `(() => void)` | — | Колбэк клика по пункту «Выйти». |
699
699
  | `open` | `boolean` | — | Открыто ли меню. <br/> Не передано — состояние открытия неуправляемое (меню само переключает себя по клику на кнопку). |
700
- | `organizationItems` | `BaseItemWithoutNonGroup` \| `CommonGroupItem` \| `Item` \| `ScrollProps` | — | Список организаций. На desktop — единственная прокручиваемая часть меню. <br/> Не передан или пуст — меню отображается единым списком без закреплённых частей. |
700
+ | `organizationItems` | `BaseItemWithoutNonGroup` \| `CommonGroupItem` \| `DroplistProps` \| `ScrollProps` | — | Список организаций. На desktop — единственная прокручиваемая часть меню |
701
701
  | `profile` | `UserProfileProps` | `{}` | Профиль пользователя (имя, email, счётчик приглашений). |
702
702
  | `setOpen` | `((open: boolean) => void)` | — | Колбэк открытия/закрытия меню. |
703
703
  | `settingItems` | `BaseItemProps` | — | Пункты настроек в нижней части меню. |
704
704
  | `theme` | `ThemeProps` | — | Переключатель темы в меню. Без пропа не отображается. |
705
- | `topItems` | `BaseItemWithoutNonGroup` \| `CommonGroupItem` \| `Item` \| `ScrollProps` | — | Пункты после темы. На desktop закреплены сверху вместе с профилем и темой |
705
+ | `topItems` | `BaseItemWithoutNonGroup` \| `CommonGroupItem` \| `DroplistProps` \| `ScrollProps` | — | Пункты после темы. На desktop закреплены сверху вместе с профилем и темой |
706
706
  | `triggerTooltip` | `string` | — | Текст подсказки для кнопки-триггера. |
707
707
 
708
708
  ##### Related types
@@ -823,4 +823,4 @@ export function Basic() {
823
823
 
824
824
  | Prop | Type | Default | Description |
825
825
  |------|------|---------|-------------|
826
- | `items` | `Item` | — | Пункты хлебных крошек. |
826
+ | `items` | `BreadcrumbsProps` \| `Item` | — | Пункты хлебных крошек. |
@@ -8,7 +8,6 @@
8
8
  }
9
9
 
10
10
  .breadcrums{
11
- min-width:0;
12
11
  padding:0 var(--sn-primitive-dimension-8, 8px);
13
12
  }
14
13
 
@@ -12,17 +12,15 @@ const promo_tag_1 = require("@cloud-ru/ds-promo-tag");
12
12
  const typography_1 = require("@cloud-ru/ds-typography");
13
13
  const classnames_1 = __importDefault(require("classnames"));
14
14
  const react_1 = require("react");
15
- const useMobileLayout_1 = require("../../../../hooks/useMobileLayout");
16
15
  const locale_1 = require("../../../../locale");
17
16
  const constants_1 = require("./constants");
18
17
  const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
19
18
  function MenuBanner({ title, promoTag, afterTitle, onClose, className, href = '#', 'data-test-id': dataTestId, ...rest }) {
20
19
  const { t } = locale_1.headerLocale.useTranslations();
21
- const isMobile = (0, useMobileLayout_1.useMobileLayout)();
22
20
  const handleClose = (0, react_1.useCallback)(e => {
23
21
  e.preventDefault();
24
22
  e.stopPropagation();
25
23
  onClose?.(e);
26
24
  }, [onClose]);
27
- return ((0, jsx_runtime_1.jsx)(card_1.Card, { as: 'a', href: href, radius: 'l', view: 'simple', className: (0, classnames_1.default)(styles_module_scss_1.default.root, className), "data-mobile": isMobile || undefined, "data-test-id": dataTestId ?? constants_1.MENU_BANNER_TEST_IDS.root, ...rest, children: (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.contentRow, "data-closable": Boolean(onClose) || undefined, children: [(0, jsx_runtime_1.jsxs)("span", { className: styles_module_scss_1.default.titleWrapper, children: [(0, jsx_runtime_1.jsx)(typography_1.Typography, { as: 'span', variant: 'body', size: 'm', className: styles_module_scss_1.default.title, "data-test-id": constants_1.MENU_BANNER_TEST_IDS.title, children: title }), promoTag && ((0, jsx_runtime_1.jsx)(promo_tag_1.PromoTag, { ...promoTag, className: styles_module_scss_1.default.promoTag, roleAppearance: promo_tag_1.ROLE_APPEARANCE.Decor, size: promo_tag_1.SIZE.Xs, "data-test-id": constants_1.MENU_BANNER_TEST_IDS.promoTag }))] }), afterTitle && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.afterTitle, "data-test-id": constants_1.MENU_BANNER_TEST_IDS.afterTitle, children: afterTitle })), onClose && ((0, jsx_runtime_1.jsx)(button_1.Button, { className: styles_module_scss_1.default.closeButton, view: 'elevated', appearance: 'neutral', size: 's', icon: (0, jsx_runtime_1.jsx)(system_1.CrossSVG, {}), onClick: handleClose, "aria-label": t('close'), "data-test-id": constants_1.MENU_BANNER_TEST_IDS.close }))] }) }));
25
+ return ((0, jsx_runtime_1.jsx)(card_1.Card, { as: 'a', href: href, radius: 'l', view: 'simple', className: (0, classnames_1.default)(styles_module_scss_1.default.root, className), "data-test-id": dataTestId ?? constants_1.MENU_BANNER_TEST_IDS.root, ...rest, children: (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.contentRow, children: [(0, jsx_runtime_1.jsxs)("span", { className: styles_module_scss_1.default.titleWrapper, children: [(0, jsx_runtime_1.jsx)(typography_1.Typography, { as: 'span', variant: 'body', size: 'm', className: styles_module_scss_1.default.title, "data-test-id": constants_1.MENU_BANNER_TEST_IDS.title, children: title }), promoTag && ((0, jsx_runtime_1.jsx)(promo_tag_1.PromoTag, { ...promoTag, className: styles_module_scss_1.default.promoTag, roleAppearance: promo_tag_1.ROLE_APPEARANCE.Decor, size: promo_tag_1.SIZE.Xs, "data-test-id": constants_1.MENU_BANNER_TEST_IDS.promoTag }))] }), afterTitle && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.afterTitle, "data-test-id": constants_1.MENU_BANNER_TEST_IDS.afterTitle, children: afterTitle })), onClose && ((0, jsx_runtime_1.jsx)(button_1.Button, { className: styles_module_scss_1.default.closeButton, view: 'elevated', appearance: 'neutral', size: 's', icon: (0, jsx_runtime_1.jsx)(system_1.CrossSVG, {}), onClick: handleClose, "aria-label": t('close'), "data-test-id": constants_1.MENU_BANNER_TEST_IDS.close }))] }) }));
28
26
  }
@@ -18,16 +18,6 @@
18
18
  .root:hover .closeButton, .root:focus-visible .closeButton, .root:has(*:focus-visible) .closeButton{
19
19
  visibility:visible;
20
20
  }
21
- .root[data-mobile] .closeButton{
22
- position:relative;
23
- top:auto;
24
- right:auto;
25
- flex-shrink:0;
26
- visibility:visible;
27
- }
28
- .root[data-mobile] .contentRow[data-closable]{
29
- padding-right:var(--sn-primitive-dimension-4, 4px);
30
- }
31
21
 
32
22
  .contentRow{
33
23
  position:relative;
@@ -7,11 +7,7 @@ export type UserMenuProps = {
7
7
  theme?: ThemeProps;
8
8
  /** Пункты после темы. На desktop закреплены сверху вместе с профилем и темой */
9
9
  topItems?: DroplistProps['items'];
10
- /**
11
- * Список организаций. На desktop — единственная прокручиваемая часть меню.
12
- *
13
- * Не передан или пуст — меню отображается единым списком без закреплённых частей.
14
- */
10
+ /** Список организаций. На desktop — единственная прокручиваемая часть меню */
15
11
  organizationItems?: DroplistProps['items'];
16
12
  /** Пункты перед «Выйти из аккаунта». На desktop закреплены снизу */
17
13
  bottomItems?: DroplistProps['items'];
@@ -49,10 +49,6 @@ function useUserMenuItems({ profile, theme, onLogout, topItems = emptyArray_1.EM
49
49
  pinBottom: [],
50
50
  };
51
51
  }
52
- // Без организаций прокручивать нечего: пустой `items` показал бы заглушку «Нет данных»
53
- if (!organizationItems.length) {
54
- return { pinTop: [], items: withClose([...pinTop, DIVIDER_ITEM, ...pinBottom]), pinBottom: [] };
55
- }
56
52
  return { pinTop: withClose(pinTop), items: withClose(organizationItems), pinBottom: withClose(pinBottom) };
57
53
  }, [bottomItems, isMobile, logoutItem, onClose, organizationItems, profileItem, settingItems, themeItem, topItems]);
58
54
  }
@@ -11,7 +11,6 @@
11
11
  }
12
12
 
13
13
  .breadcrums{
14
- min-width:0;
15
14
  padding:0 var(--sn-primitive-dimension-8, 8px);
16
15
  }
17
16
 
@@ -117,16 +116,6 @@
117
116
  .root:hover .closeButton, .root:focus-visible .closeButton, .root:has(*:focus-visible) .closeButton{
118
117
  visibility:visible;
119
118
  }
120
- .root[data-mobile] .closeButton{
121
- position:relative;
122
- top:auto;
123
- right:auto;
124
- flex-shrink:0;
125
- visibility:visible;
126
- }
127
- .root[data-mobile] .contentRow[data-closable]{
128
- padding-right:var(--sn-primitive-dimension-4, 4px);
129
- }
130
119
 
131
120
  .contentRow{
132
121
  position:relative;
@@ -8,7 +8,6 @@
8
8
  }
9
9
 
10
10
  .breadcrums{
11
- min-width:0;
12
11
  padding:0 var(--sn-primitive-dimension-8, 8px);
13
12
  }
14
13
 
@@ -6,17 +6,15 @@ import { PromoTag, ROLE_APPEARANCE, SIZE } from '@cloud-ru/ds-promo-tag';
6
6
  import { Typography } from '@cloud-ru/ds-typography';
7
7
  import cn from 'classnames';
8
8
  import { useCallback } from 'react';
9
- import { useMobileLayout } from '../../../../hooks/useMobileLayout.js';
10
9
  import { headerLocale } from '../../../../locale/index.js';
11
10
  import { MENU_BANNER_TEST_IDS } from './constants.js';
12
11
  import styles from './styles.module.css';
13
12
  export function MenuBanner({ title, promoTag, afterTitle, onClose, className, href = '#', 'data-test-id': dataTestId, ...rest }) {
14
13
  const { t } = headerLocale.useTranslations();
15
- const isMobile = useMobileLayout();
16
14
  const handleClose = useCallback(e => {
17
15
  e.preventDefault();
18
16
  e.stopPropagation();
19
17
  onClose?.(e);
20
18
  }, [onClose]);
21
- return (_jsx(Card, { as: 'a', href: href, radius: 'l', view: 'simple', className: cn(styles.root, className), "data-mobile": isMobile || undefined, "data-test-id": dataTestId ?? MENU_BANNER_TEST_IDS.root, ...rest, children: _jsxs("div", { className: styles.contentRow, "data-closable": Boolean(onClose) || undefined, children: [_jsxs("span", { className: styles.titleWrapper, children: [_jsx(Typography, { as: 'span', variant: 'body', size: 'm', className: styles.title, "data-test-id": MENU_BANNER_TEST_IDS.title, children: title }), promoTag && (_jsx(PromoTag, { ...promoTag, className: styles.promoTag, roleAppearance: ROLE_APPEARANCE.Decor, size: SIZE.Xs, "data-test-id": MENU_BANNER_TEST_IDS.promoTag }))] }), afterTitle && (_jsx("div", { className: styles.afterTitle, "data-test-id": MENU_BANNER_TEST_IDS.afterTitle, children: afterTitle })), onClose && (_jsx(Button, { className: styles.closeButton, view: 'elevated', appearance: 'neutral', size: 's', icon: _jsx(CrossSVG, {}), onClick: handleClose, "aria-label": t('close'), "data-test-id": MENU_BANNER_TEST_IDS.close }))] }) }));
19
+ return (_jsx(Card, { as: 'a', href: href, radius: 'l', view: 'simple', className: cn(styles.root, className), "data-test-id": dataTestId ?? MENU_BANNER_TEST_IDS.root, ...rest, children: _jsxs("div", { className: styles.contentRow, children: [_jsxs("span", { className: styles.titleWrapper, children: [_jsx(Typography, { as: 'span', variant: 'body', size: 'm', className: styles.title, "data-test-id": MENU_BANNER_TEST_IDS.title, children: title }), promoTag && (_jsx(PromoTag, { ...promoTag, className: styles.promoTag, roleAppearance: ROLE_APPEARANCE.Decor, size: SIZE.Xs, "data-test-id": MENU_BANNER_TEST_IDS.promoTag }))] }), afterTitle && (_jsx("div", { className: styles.afterTitle, "data-test-id": MENU_BANNER_TEST_IDS.afterTitle, children: afterTitle })), onClose && (_jsx(Button, { className: styles.closeButton, view: 'elevated', appearance: 'neutral', size: 's', icon: _jsx(CrossSVG, {}), onClick: handleClose, "aria-label": t('close'), "data-test-id": MENU_BANNER_TEST_IDS.close }))] }) }));
22
20
  }
@@ -18,16 +18,6 @@
18
18
  .root:hover .closeButton, .root:focus-visible .closeButton, .root:has(*:focus-visible) .closeButton{
19
19
  visibility:visible;
20
20
  }
21
- .root[data-mobile] .closeButton{
22
- position:relative;
23
- top:auto;
24
- right:auto;
25
- flex-shrink:0;
26
- visibility:visible;
27
- }
28
- .root[data-mobile] .contentRow[data-closable]{
29
- padding-right:var(--sn-primitive-dimension-4, 4px);
30
- }
31
21
 
32
22
  .contentRow{
33
23
  position:relative;
@@ -7,11 +7,7 @@ export type UserMenuProps = {
7
7
  theme?: ThemeProps;
8
8
  /** Пункты после темы. На desktop закреплены сверху вместе с профилем и темой */
9
9
  topItems?: DroplistProps['items'];
10
- /**
11
- * Список организаций. На desktop — единственная прокручиваемая часть меню.
12
- *
13
- * Не передан или пуст — меню отображается единым списком без закреплённых частей.
14
- */
10
+ /** Список организаций. На desktop — единственная прокручиваемая часть меню */
15
11
  organizationItems?: DroplistProps['items'];
16
12
  /** Пункты перед «Выйти из аккаунта». На desktop закреплены снизу */
17
13
  bottomItems?: DroplistProps['items'];
@@ -46,10 +46,6 @@ export function useUserMenuItems({ profile, theme, onLogout, topItems = EMPTY_AR
46
46
  pinBottom: [],
47
47
  };
48
48
  }
49
- // Без организаций прокручивать нечего: пустой `items` показал бы заглушку «Нет данных»
50
- if (!organizationItems.length) {
51
- return { pinTop: [], items: withClose([...pinTop, DIVIDER_ITEM, ...pinBottom]), pinBottom: [] };
52
- }
53
49
  return { pinTop: withClose(pinTop), items: withClose(organizationItems), pinBottom: withClose(pinBottom) };
54
50
  }, [bottomItems, isMobile, logoutItem, onClose, organizationItems, profileItem, settingItems, themeItem, topItems]);
55
51
  }
@@ -11,7 +11,6 @@
11
11
  }
12
12
 
13
13
  .breadcrums{
14
- min-width:0;
15
14
  padding:0 var(--sn-primitive-dimension-8, 8px);
16
15
  }
17
16
 
@@ -117,16 +116,6 @@
117
116
  .root:hover .closeButton, .root:focus-visible .closeButton, .root:has(*:focus-visible) .closeButton{
118
117
  visibility:visible;
119
118
  }
120
- .root[data-mobile] .closeButton{
121
- position:relative;
122
- top:auto;
123
- right:auto;
124
- flex-shrink:0;
125
- visibility:visible;
126
- }
127
- .root[data-mobile] .contentRow[data-closable]{
128
- padding-right:var(--sn-primitive-dimension-4, 4px);
129
- }
130
119
 
131
120
  .contentRow{
132
121
  position:relative;