# @cloud-ru/ds-uikit-product-header > Продуктовая шапка консоли — HeaderLayout, MainMenu, UserMenu, Logo, PathBreadcrumbs и PlatformLogo. Docs: /snack-v2/components/uikit-product-header/ ## Установка ```sh pnpm add @cloud-ru/ds-uikit-product-header ``` ## Когда использовать - Новая навигация консоли с сегментами сервисов, избранным и настройками отображения карточек. - Полная замена header на Snack V2 без legacy-контрактов Figma `headerOld` / `navigationOldDrawer`. - Поэтапная миграция: `MenuMobile` (bottom sheet) подключается к legacy [`MainMenu`](/components/uikit-product-header-legacy/main-menu) через `customMobileMenu`. Когда **не** нужен: - Обратная совместимость со старым drawer и API `serviceGroups` / `LinksGroup`: - используйте [`@cloud-ru/ds-uikit-product-header-legacy`](/components/uikit-product-header-legacy). ## API ### Container | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | | | `data-test-id` | `string` | — | no | | ### Content | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `activeSegmentId` | `string` | — | no | Активный сегмент правой панели (значение SegmentControl, см. {@link MainMenuSegment.id}). Не передано — неуправляемое состояние (дефолт — первый сегмент с видимыми карточками). | | `className` | `string` | — | no | CSS-класс корневого элемента. | | `favorite` | `FavoriteProps` | — | no | Избранное. Без пропа группа-предок карточек драга из избранного не активируется. | | `footer` | `ReactNode` | — | no | Слот под сеткой карточек. | | `isMobile` | `boolean` | — | no | Мобильная раскладка. | | `loading` | `boolean` | — | no | Флаг загрузки данных | | `onActiveSegmentChange` | `((segmentId: string) => void)` | — | no | Колбэк смены активного сегмента правой панели. | | `onSegmentExpandedChange` | `((segmentId: string, expandedGroupIds: string[]) => void)` | — | no | Колбэк при изменении набора раскрытых групп сегмента (без id синтетической группы избранного). | | `onSegmentOrderChange` | `((segmentId: string, orderedGroupIds: string[]) => void)` | — | no | Колбэк после DnD групп в сегменте (без id синтетической группы избранного). | | `onSegmentServiceClick` | `((service: InnerLink, e?: MouseEvent) => void)` | — | no | Колбэк клика по карточке сервиса в сегменте. | | `preferences` | `MainMenuPreferencesProps` | — | no | Настройки меню (модалка по кнопке в тулбаре): описания карточек, цвета групп. Не передано — кнопка настроек в тулбаре не отображается. | | `rightTop` | `ReactNode` | — | no | Слот над тулбаром правой колонки (например, баннеры) | | `search` | `ReactNode` | — | no | Слот поисковой строки — рендерится над контентом. | | `searchGroups` | `LinksGroup[]` | `[]` | no | Результаты поиска (уже смерженные); в обычном режиме не используются. | | `searchValue` | `string` | — | no | Текущее значение поисковой строки — переключает контент между каталогом и результатами поиска. | | `segmentPrefs` | `MainMenuSegmentPrefs[]` | — | no | Пользовательские prefs сегментов (порядок / раскрытие групп). Нет записи для сегмента или omit `order` / `expanded` → uncontrolled для этого поля. | | `segments` | `MainMenuSegment[]` | — | no | Сегменты правой панели (сетка карточек) — только каталог. При поиске: совпадения из сегментов без `pinBottomOnSearch` → `platformGroups` → сегменты с `pinBottomOnSearch`. Если один и тот же {@link InnerLink.id} совпал сразу в нескольких сегментах — остаётся только первое по этому приоритету вхождение, остальные (и опустевшие после этого группы) не показываются. При `segments.length > 1` показывается SegmentControl (скрывается во время поиска). Порядок и раскрытие групп — через `segmentPrefs` и колбэки ниже. | ### ContentToolbar | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `allGroupsExpanded` | `boolean` | — | yes | Все группы сегмента раскрыты — определяет иконку кнопки свернуть/развернуть все. | | `isMobile` | `boolean` | — | no | Мобильная раскладка — кнопка свернуть/развернуть все скрывается. | | `loading` | `boolean` | — | no | Флаг загрузки данных — сегменты подгружаются с бэка, поэтому SegmentControl тоже уходит в скелетон. | | `onSegmentChange` | `(segment: string) => void` | — | yes | Колбэк смены активного сегмента. | | `onToggleAllGroupsExpanded` | `() => void` | — | yes | Колбэк клика по кнопке свернуть/развернуть все группы. | | `preferences` | `MainMenuPreferencesProps` | — | no | Настройки меню (модалка по кнопке). Не передано — кнопка настроек не отображается. | | `segment` | `string` | — | yes | Значение активного сегмента SegmentControl. | | `segmentItems` | `ContentToolbarSegmentItem[]` | — | no | Пункты SegmentControl. Без пунктов (или с одним) SegmentControl не отображается. | ### DraggableServiceCard | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | CSS-класс корневого элемента. | | `dragPreview` | `boolean` | — | no | Карточка рендерится как превью в `DragOverlay` (без тултипа и описания). | | `expandable` | `{ value: boolean; onClick(): void; }` | — | no | Настройки кнопки раскрытия | | `favoriteChecked` | `boolean` | — | no | В избранном ли сервис. Учитывается только вместе с `onFavoriteChange`. | | `groupId` | `string` | — | yes | | | `isMobile` | `boolean` | — | no | Мобильная раскладка. | | `onFavoriteChange` | `((productId: string) => (addingValue: boolean, position?: number) => void)` | — | no | Переключение избранного (стабильная по ссылке функция). Не передано — кнопка избранного не показывается. | | `onServiceClick` | `((service: InnerLink, event: MouseEvent) => void)` | — | no | Колбэк клика по карточке. | | `service` | `InnerLink` | — | yes | Карточка сервиса. | | `showDescription` | `boolean` | — | yes | Показывать описание сервиса вместо тултипа. | | `tabIndex` | `number` | — | no | `tabIndex` корневого элемента. | ### EmptyFavoriteSVG | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | | ### EmptyRecentSVG | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | | ### EmptyState | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `isFavoritesSegment` | `boolean` | — | yes | Пустое состояние сегмента «Избранное» (иначе — «Недавнее»). | | `isMobile` | `boolean` | — | no | Мобильная раскладка. | ### Favorites | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `favorite` | `FavoriteProps` | — | yes | Список избранных сервисов | | `headerClassName` | `string` | — | no | CSS-класс строки заголовка (segment + кнопка настроек) | | `isMobile` | `boolean` | — | no | Флаг мобильной раскладки | | `servicesById` | `ReadonlyMap` | — | yes | Сервисы каталога по id для разрешения id в карточки | #### Related types - `BaseItemProps` (interface) - `CardServiceLightProps` (interface) - `FavoriteProps` (interface) - `FavoritesSegment` = `favorites | recent` - `InnerLink` (interface) - `InnerLinkViewMode` = `expandable | expanded | flat-link | group-title-only` - `PromoTagPredefinedBaseProps` (alias) ### FavoritesList | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `items` | `InnerLink[]` | — | yes | Карточки избранных сервисов. | | `onFavoriteChange` | `(productId: string) => (addingValue: boolean, position?: number \| undefined) => void` | — | yes | Колбэк переключения избранного (`FavoriteProps['onChange']`). | | `onServiceClick` | `(service: InnerLink) => (event: MouseEvent) => void` | — | yes | Колбэк клика по карточке. | ### FavoritesReorderList | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `favoriteIds` | `string[]` | — | yes | Id избранных сервисов (`FavoriteProps['value']`). | | `items` | `InnerLink[]` | — | yes | Карточки избранных сервисов. | | `onFavoriteChange` | `(productId: string) => (addingValue: boolean, position?: number \| undefined) => void` | — | yes | Колбэк переключения избранного (`FavoriteProps['onChange']`). | | `onServiceClick` | `(service: InnerLink) => (event: MouseEvent) => void` | — | yes | Колбэк клика по карточке. | ### GridServiceCard | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | CSS-класс корневого элемента. | | `dragEnabled` | `boolean` | — | no | Карточку можно перетаскивать. Иначе рендерится без `useDraggable`: на mobile, при поиске и без избранного сотни карточек не регистрируются в `DndContext` впустую. | | `dragPreview` | `boolean` | — | no | Карточка рендерится как превью в `DragOverlay` (без тултипа и описания). | | `expandable` | `{ value: boolean; onClick(): void; }` | — | no | Настройки кнопки раскрытия | | `favoriteChecked` | `boolean` | — | no | В избранном ли сервис. Учитывается только вместе с `onFavoriteChange`. | | `groupId` | `string` | — | yes | | | `isMobile` | `boolean` | — | no | Мобильная раскладка. | | `onFavoriteChange` | `((productId: string) => (addingValue: boolean, position?: number) => void)` | — | no | Переключение избранного (стабильная по ссылке функция). Не передано — кнопка избранного не показывается. | | `onServiceClick` | `((service: InnerLink, event: MouseEvent) => void)` | — | no | Колбэк клика по карточке. | | `service` | `InnerLink` | — | yes | Карточка сервиса. | | `showDescription` | `boolean` | — | yes | Показывать описание сервиса вместо тултипа. | | `tabIndex` | `number` | — | no | `tabIndex` корневого элемента. | ### HeaderButton | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `as` | `any` | — | no | Элемент или компонент для рендера: 'button' \| 'a' \| ComponentType (например Link из react-router-dom) | | `className` | `any` | — | no | Дополнительный класс | | `counter` | `any` | — | no | Пропсы для counter. `appearance` можно задать явно (по умолчанию наследуется от appearance кнопки). | | `data-test-id` | `any` | — | no | | | `disabled` | `any` | — | no | Отключена | | `fullWidth` | `any` | — | no | На всю ширину | | `icon` | `any` | — | no | Иконка | | `iconPosition` | `any` | — | no | Позиция иконки относительно текста | | `innerRef` | `any` | — | no | Ref на реальный DOM-элемент/инстанс, который рендерится через `as`. Используем явный проп, чтобы не зависеть от `forwardRef` и не тащить type-assertions на экспорт. | | `isMobile` | `boolean` | — | no | Мобильная раскладка — тултип не показывается (на mobile нет hover). | | `label` | `any` | — | no | Текст кнопки | | `loading` | `any` | — | no | Состояние загрузки | | `minWidth` | `any` | — | no | Минимальная ширина контейнера (`min-width` из токена размера). По умолчанию `true`. `false` — кнопка сжимается по контенту вместо фиксированного минимума. | | `tooltip` | `Omit` | — | no | Настройки тултипа. `placement` и `disableSpanWrapper` зафиксированы под анатомию хедера | #### Related types - `Appearance` = `blue | green | neutral | orange | pink | primary | red | violet | yellow` - `ChildrenFunction` (alias) - `CounterProps` (interface) - `IconPosition` = `after | before` - `Placement` = `bottom | bottom-end | bottom-start | left | left-end | left-start | right | right-end | right-start | top | top-end | top-start` - `PolymorphicRef` (alias) - `RoleAppearance` = `accent | decor` - `Size` = `s | xs` - `TooltipProps` (interface) - `Trigger` = `click | clickAndFocusVisible | focus | focusVisible | hover | hoverAndFocus | hoverAndFocusVisible` - `Variant` = `count | count-k | count-plus` ### HeaderLayout | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `breadcrumbs` | `ReactNode` | — | no | Слот хлебных крошек. На mobile переносится под основную строку хедера. | | `className` | `string` | — | no | CSS-класс корневого элемента. | | `data-test-id` | `string` | — | no | | | `logo` | `ReactNode` | — | no | Слот логотипа (крайний левый). | | `menu` | `ReactNode` | — | no | Слот главного меню (слева, после логотипа). | | `select` | `ReactNode` | — | no | Слот селектора (например, выбор облака/организации), после меню. | | `toolbar` | `ReactNode` | — | no | Слот тулбара — правая часть хедера. | ### Logo | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | CSS-класс корневого элемента. | | `data-test-id` | `string` | — | no | | | `href` | `string` | — | yes | Ссылка логотипа. | | `loading` | `boolean` | — | no | Флаг загрузки — логотип показывается в состоянии загрузки кнопки. | | `mode` | `develop \| hybrid \| prod \| stage` | — | no | Режим окружения — отображается промо-тегом рядом с дефолтной иконкой (не для `'prod'`). | | `onClick` | `MouseEventHandler` | — | no | Колбэк клика по логотипу. | | `path` | `string` | — | no | Путь до кастомного изображения логотипа. Без пропа (или при ошибке загрузки) — дефолтная иконка. | | `tooltip` | `TooltipProps` | — | no | Настройки тултипа логотипа. | #### Related types - `ChildrenFunction` (alias) - `HeaderLogoMode` = `develop | hybrid | prod | stage` - `Placement` = `bottom | bottom-end | bottom-start | left | left-end | left-start | right | right-end | right-start | top | top-end | top-start` - `TooltipProps` (interface) - `Trigger` = `click | clickAndFocusVisible | focus | focusVisible | hover | hoverAndFocus | hoverAndFocusVisible` ### MainMenu | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `activeSegmentId` | `string` | — | no | Активный сегмент правой панели (значение SegmentControl, см. {@link MainMenuSegment.id}). Не передано — неуправляемое состояние (дефолт — первый сегмент с видимыми карточками). | | `defaultWidth` | `number` | — | no | Ширина дровера, с которой открывается меню (desktop only) | | `disabled` | `boolean` | — | no | Кнопка открытия меню недоступна для клика. | | `draggerTooltip` | `string` | — | no | Текст подсказки для драггера (desktop only) | | `favorite` | `FavoriteProps` | — | no | Избранное. Без пропа группа-предок карточек драга из избранного не активируется. Избранное. Без пропа секция «Избранное» не отображается. | | `leftBottom` | `ReactNode` | — | no | Слот под пунктами настроек в левой колонке (desktop) / в конце списка (mobile). | | `leftTop` | `ReactNode` | — | no | Слот над поиском в левой колонке (desktop) / над поиском в списке (mobile). | | `loading` | `boolean` | — | no | Флаг загрузки данных | | `logo` | `ReactNode` | — | no | Логотип в шапке меню. | | `onActiveSegmentChange` | `((segmentId: string) => void)` | — | no | Колбэк смены активного сегмента правой панели. | | `onSegmentExpandedChange` | `((segmentId: string, expandedGroupIds: string[]) => void)` | — | no | Колбэк при изменении набора раскрытых групп сегмента (без id синтетической группы избранного). | | `onSegmentOrderChange` | `((segmentId: string, orderedGroupIds: string[]) => void)` | — | no | Колбэк после DnD групп в сегменте (без id синтетической группы избранного). | | `onSegmentServiceClick` | `((service: InnerLink, e?: MouseEvent) => void)` | — | no | Колбэк клика по карточке сервиса в сегменте. | | `onWidthChangeEnd` | `((width: number) => void)` | — | no | Вызывается при окончании изменения ширины дровера (desktop only) | | `open` | `boolean` | — | no | Открыто ли меню. Не передано — состояние открытия неуправляемое (меню само переключает себя по клику на кнопку). | | `platformGroups` | `LinksGroup[]` | — | no | Платформенные группы (например «Облачные продукты», «Другие продукты»). Без поиска в сетке карточек **не отображаются**. С поиском: попадают в результаты при совпадении; порядок — после совпадений из сегментов без `pinBottomOnSearch`, перед сегментами с `pinBottomOnSearch`. Обычно `favoritesEnabled: false`; карточки могут быть без `icon` (Avatar по `label`). | | `preferences` | `MainMenuPreferencesProps` | — | no | Настройки меню (модалка по кнопке в тулбаре): описания карточек, цвета групп. Не передано — кнопка настроек в тулбаре не отображается. | | `rightTop` | `ReactNode` | — | no | Слот над тулбаром правой колонки (например, баннеры) | | `search` | `SearchProps` | — | no | Поиск по сервисам. Без пропа поисковая строка не отображается. | | `searchGroups` | `LinksGroup[]` | — | no | Результаты поиска (уже смерженные); в обычном режиме не используются. | | `segmentPrefs` | `MainMenuSegmentPrefs[]` | — | no | Пользовательские prefs сегментов (порядок / раскрытие групп). Нет записи для сегмента или omit `order` / `expanded` → uncontrolled для этого поля. | | `segments` | `MainMenuSegment[]` | — | no | Сегменты правой панели (сетка карточек) — только каталог. При поиске: совпадения из сегментов без `pinBottomOnSearch` → `platformGroups` → сегменты с `pinBottomOnSearch`. Если один и тот же {@link InnerLink.id} совпал сразу в нескольких сегментах — остаётся только первое по этому приоритету вхождение, остальные (и опустевшие после этого группы) не показываются. При `segments.length > 1` показывается SegmentControl (скрывается во время поиска). Порядок и раскрытие групп — через `segmentPrefs` и колбэки ниже. | | `setOpen` | `((open: boolean) => void)` | — | no | Колбэк открытия/закрытия меню. | | `settingItems` | `MainMenuSettingsItem[]` | — | no | Пункты левой колонки (desktop) / нижней части списка (mobile). Плоский список (`dividerBefore` для разделителей). Не связан с сегментами правой панели и не меняется при сортировке групп в сегментах. | #### Related types - `BaseItemProps` (interface) - `CardServiceLightProps` (interface) - `FavoriteProps` (interface) - `FavoritesSegment` = `favorites | recent` - `InnerLink` (interface) - `InnerLinkViewMode` = `expandable | expanded | flat-link | group-title-only` - `LinksGroup` (interface) - `LinksGroupBlockColor` = `blue | green | neutral | orange | pink | primary | red | violet | yellow` - `LinksGroupTitle` (alias) - `MainMenuPreferencesProps` (interface) - `MainMenuSegment` (interface) - `MainMenuSegmentPrefs` (interface) - `MainMenuSettingsItem` (interface) - `MainMenuToggleProps` (interface) - `PromoTagPredefinedBaseProps` (alias) - `SearchProps` (interface) - `TitleClickable` (interface) - `TitleStatic` (interface) ### MainMenuDndContext | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `collisionDetection` | `CollisionDetection` | — | no | | | `dragOverlay` | `string \| number \| boolean \| Iterable \| Element \| null` | — | no | | | `modifiers` | `Modifier[]` | — | no | | | `onDragCancel` | `(({ active }: DragCancelEvent) => void)` | — | no | | | `onDragEnd` | `(({ active, over, delta, activatorEvent }: DragEndEvent) => void)` | — | no | | | `onDragStart` | `(({ active }: DragStartEvent) => void)` | — | no | | | `overlayContextValue` | `{ setGroupDragOverlay: Dispatch>; }` | — | no | | | `sensors` | `SensorDescriptor[]` | — | no | | ### MenuBanner | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `afterTitle` | `ReactNode` | — | no | Слот справа от заголовка и промо-тега | | `className` | `string` | — | no | CSS-класс корневого элемента | | `data-test-id` | `string` | — | no | | | `onClose` | `MouseEventHandler` | — | no | Колбэк закрытия. При наличии отображается кнопка «Закрыть» на hover | | `promoTag` | `Omit` | — | no | Текст промо-тега рядом с заголовком | | `title` | `string` | — | yes | Заголовок баннера | #### Related types - `Appearance` = `blue | green | neutral | orange | pink | primary | red | violet | yellow` - `PolymorphicRef` (alias) - `PromoTagOwnProps` (interface) - `PromoTagProps` (interface) - `RoleAppearance` = `accent | decor` - `Size` = `m | s | xs` ### MenuBottom | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `leftBottom` | `ReactNode` | — | yes | Слот под пунктами настроек. | | `settingItems` | `MainMenuSettingsItem[]` | — | no | Пункты настроек, отображаемые в нижней части меню. | ### MenuDesktop | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `activeSegmentId` | `string` | — | no | Активный сегмент правой панели (значение SegmentControl, см. {@link MainMenuSegment.id}). Не передано — неуправляемое состояние (дефолт — первый сегмент с видимыми карточками). | | `defaultWidth` | `number` | `1208 + 24` | no | Ширина дровера, с которой открывается меню (desktop only) | | `disabled` | `boolean` | — | no | Кнопка открытия меню недоступна для клика. | | `draggerTooltip` | `string` | — | no | Текст подсказки для драггера (desktop only) | | `favorite` | `FavoriteProps` | — | no | Избранное. Без пропа группа-предок карточек драга из избранного не активируется. Избранное. Без пропа секция «Избранное» не отображается. | | `leftBottom` | `ReactNode` | — | no | Слот под пунктами настроек в левой колонке (desktop) / в конце списка (mobile). | | `leftTop` | `ReactNode` | — | no | Слот над поиском в левой колонке (desktop) / над поиском в списке (mobile). | | `loading` | `boolean` | — | no | Флаг загрузки данных | | `logo` | `ReactNode` | — | no | Логотип в шапке меню. | | `onActiveSegmentChange` | `((segmentId: string) => void)` | — | no | Колбэк смены активного сегмента правой панели. | | `onSegmentExpandedChange` | `((segmentId: string, expandedGroupIds: string[]) => void)` | — | no | Колбэк при изменении набора раскрытых групп сегмента (без id синтетической группы избранного). | | `onSegmentOrderChange` | `((segmentId: string, orderedGroupIds: string[]) => void)` | — | no | Колбэк после DnD групп в сегменте (без id синтетической группы избранного). | | `onSegmentServiceClick` | `((service: InnerLink, e?: MouseEvent) => void)` | — | no | Колбэк клика по карточке сервиса в сегменте. | | `onWidthChangeEnd` | `((width: number) => void)` | — | no | Вызывается при окончании изменения ширины дровера (desktop only) | | `open` | `boolean` | `false` | no | Открыто ли меню. Не передано — состояние открытия неуправляемое (меню само переключает себя по клику на кнопку). | | `platformGroups` | `LinksGroup[]` | — | no | Платформенные группы (например «Облачные продукты», «Другие продукты»). Без поиска в сетке карточек **не отображаются**. С поиском: попадают в результаты при совпадении; порядок — после совпадений из сегментов без `pinBottomOnSearch`, перед сегментами с `pinBottomOnSearch`. Обычно `favoritesEnabled: false`; карточки могут быть без `icon` (Avatar по `label`). | | `preferences` | `MainMenuPreferencesProps` | — | no | Настройки меню (модалка по кнопке в тулбаре): описания карточек, цвета групп. Не передано — кнопка настроек в тулбаре не отображается. | | `rightTop` | `ReactNode` | — | no | Слот над тулбаром правой колонки (например, баннеры) | | `search` | `SearchProps` | — | no | Поиск по сервисам. Без пропа поисковая строка не отображается. | | `searchGroups` | `LinksGroup[]` | — | no | Результаты поиска (уже смерженные); в обычном режиме не используются. | | `segmentPrefs` | `MainMenuSegmentPrefs[]` | — | no | Пользовательские prefs сегментов (порядок / раскрытие групп). Нет записи для сегмента или omit `order` / `expanded` → uncontrolled для этого поля. | | `segments` | `MainMenuSegment[]` | — | no | Сегменты правой панели (сетка карточек) — только каталог. При поиске: совпадения из сегментов без `pinBottomOnSearch` → `platformGroups` → сегменты с `pinBottomOnSearch`. Если один и тот же {@link InnerLink.id} совпал сразу в нескольких сегментах — остаётся только первое по этому приоритету вхождение, остальные (и опустевшие после этого группы) не показываются. При `segments.length > 1` показывается SegmentControl (скрывается во время поиска). Порядок и раскрытие групп — через `segmentPrefs` и колбэки ниже. | | `setOpen` | `((open: boolean) => void)` | — | no | Колбэк открытия/закрытия меню. | | `settingItems` | `MainMenuSettingsItem[]` | — | no | Пункты левой колонки (desktop) / нижней части списка (mobile). Плоский список (`dividerBefore` для разделителей). Не связан с сегментами правой панели и не меняется при сортировке групп в сегментах. | ### MenuHeaderBrand | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | CSS-класс корневого элемента. | | `isMobile` | `boolean` | — | no | | | `logo` | `ReactNode` | — | no | Логотип в шапке меню. | | `onClose` | `() => void` | — | yes | Колбэк клика по кнопке закрытия меню. | ### MenuMobile | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `activeSegmentId` | `string` | — | no | Активный сегмент правой панели (значение SegmentControl, см. {@link MainMenuSegment.id}). Не передано — неуправляемое состояние (дефолт — первый сегмент с видимыми карточками). | | `defaultWidth` | `number` | — | no | Ширина дровера, с которой открывается меню (desktop only) | | `disabled` | `boolean` | — | no | Кнопка открытия меню недоступна для клика. | | `draggerTooltip` | `string` | — | no | Текст подсказки для драггера (desktop only) | | `favorite` | `FavoriteProps` | — | no | Избранное. Без пропа группа-предок карточек драга из избранного не активируется. Избранное. Без пропа секция «Избранное» не отображается. | | `leftBottom` | `ReactNode` | — | no | Слот под пунктами настроек в левой колонке (desktop) / в конце списка (mobile). | | `leftTop` | `ReactNode` | — | no | Слот над поиском в левой колонке (desktop) / над поиском в списке (mobile). | | `loading` | `boolean` | — | no | Флаг загрузки данных | | `logo` | `ReactNode` | — | no | Логотип в шапке меню. | | `onActiveSegmentChange` | `((segmentId: string) => void)` | — | no | Колбэк смены активного сегмента правой панели. | | `onSegmentExpandedChange` | `((segmentId: string, expandedGroupIds: string[]) => void)` | — | no | Колбэк при изменении набора раскрытых групп сегмента (без id синтетической группы избранного). | | `onSegmentOrderChange` | `((segmentId: string, orderedGroupIds: string[]) => void)` | — | no | Колбэк после DnD групп в сегменте (без id синтетической группы избранного). | | `onSegmentServiceClick` | `((service: InnerLink, e?: MouseEvent) => void)` | — | no | Колбэк клика по карточке сервиса в сегменте. | | `onWidthChangeEnd` | `((width: number) => void)` | — | no | Вызывается при окончании изменения ширины дровера (desktop only) | | `open` | `boolean` | `false` | no | Открыто ли меню. Не передано — состояние открытия неуправляемое (меню само переключает себя по клику на кнопку). | | `platformGroups` | `LinksGroup[]` | — | no | Платформенные группы (например «Облачные продукты», «Другие продукты»). Без поиска в сетке карточек **не отображаются**. С поиском: попадают в результаты при совпадении; порядок — после совпадений из сегментов без `pinBottomOnSearch`, перед сегментами с `pinBottomOnSearch`. Обычно `favoritesEnabled: false`; карточки могут быть без `icon` (Avatar по `label`). | | `preferences` | `MainMenuPreferencesProps` | — | no | Настройки меню (модалка по кнопке в тулбаре): описания карточек, цвета групп. Не передано — кнопка настроек в тулбаре не отображается. | | `rightTop` | `ReactNode` | — | no | Слот над тулбаром правой колонки (например, баннеры) | | `search` | `SearchProps` | — | no | Поиск по сервисам. Без пропа поисковая строка не отображается. | | `searchGroups` | `LinksGroup[]` | — | no | Результаты поиска (уже смерженные); в обычном режиме не используются. | | `segmentPrefs` | `MainMenuSegmentPrefs[]` | — | no | Пользовательские prefs сегментов (порядок / раскрытие групп). Нет записи для сегмента или omit `order` / `expanded` → uncontrolled для этого поля. | | `segments` | `MainMenuSegment[]` | — | no | Сегменты правой панели (сетка карточек) — только каталог. При поиске: совпадения из сегментов без `pinBottomOnSearch` → `platformGroups` → сегменты с `pinBottomOnSearch`. Если один и тот же {@link InnerLink.id} совпал сразу в нескольких сегментах — остаётся только первое по этому приоритету вхождение, остальные (и опустевшие после этого группы) не показываются. При `segments.length > 1` показывается SegmentControl (скрывается во время поиска). Порядок и раскрытие групп — через `segmentPrefs` и колбэки ниже. | | `setOpen` | `((open: boolean) => void)` | — | no | Колбэк открытия/закрытия меню. | | `settingItems` | `MainMenuSettingsItem[]` | — | no | Пункты левой колонки (desktop) / нижней части списка (mobile). Плоский список (`dividerBefore` для разделителей). Не связан с сегментами правой панели и не меняется при сортировке групп в сегментах. | #### Related types - `BaseItemProps` (interface) - `CardServiceLightProps` (interface) - `FavoriteProps` (interface) - `FavoritesSegment` = `favorites | recent` - `InnerLink` (interface) - `InnerLinkViewMode` = `expandable | expanded | flat-link | group-title-only` - `LinksGroup` (interface) - `LinksGroupBlockColor` = `blue | green | neutral | orange | pink | primary | red | violet | yellow` - `LinksGroupTitle` (alias) - `MainMenuPreferencesProps` (interface) - `MainMenuSegment` (interface) - `MainMenuSegmentPrefs` (interface) - `MainMenuSettingsItem` (interface) - `MainMenuToggleProps` (interface) - `PromoTagPredefinedBaseProps` (alias) - `SearchProps` (interface) - `TitleClickable` (interface) - `TitleStatic` (interface) ### MountAnimation | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | | | `data-test-id` | `string` | — | no | | | `type` | `fade-in \| fade-slide-up \| fade-slide-up-right \| slide-right` | — | no | | ### PathBreadcrumbs | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `items` | `Item[]` | — | yes | Пункты хлебных крошек. | #### Related types - `BreadcrumbsProps` (interface) - `Item` (interface) - `Size` = `s | xs` ### RecentList | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `favoriteIds` | `string[]` | — | yes | Id избранных сервисов — для звёздочки «в избранном» на карточках недавнего (`FavoriteProps['value']`). | | `isMobile` | `boolean` | — | no | Мобильная раскладка. | | `items` | `InnerLink[]` | — | yes | Карточки сегмента «Недавнее». | | `onFavoriteChange` | `(productId: string) => (addingValue: boolean, position?: number \| undefined) => void` | — | yes | Колбэк переключения избранного (`FavoriteProps['onChange']`). | | `onServiceClick` | `(service: InnerLink) => (event: MouseEvent) => void` | — | yes | Колбэк клика по карточке. | ### ScrollWithAnimatedStickyPanel | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `panel` | `ReactNode` | — | yes | | ### Search | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `isMobile` | `boolean` | `false` | no | | | `onBlur` | `FocusEventHandler` | — | no | Колбек обработки потери фокуса | | `onChange` | `(value: string) => void` | — | yes | Колбэк изменения значения поисковой строки. | | `onFocus` | `FocusEventHandler` | — | no | Колбек обработки получения фокуса | | `onSearchNoResult` | `((value: string) => void)` | — | no | Колбэк вызывается, когда поиск по текущему значению не дал результатов. | | `value` | `string` | — | yes | Текущее значение поисковой строки. | ### ServiceCard | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | CSS-класс корневого элемента. | | `dragPreview` | `boolean` | — | no | Карточка рендерится как превью в `DragOverlay` (без тултипа и описания). | | `expandable` | `{ value: boolean; onClick(): void; }` | — | no | Настройки кнопки раскрытия | | `favoriteChecked` | `boolean` | — | no | В избранном ли сервис. Учитывается только вместе с `onFavoriteChange`. | | `isMobile` | `boolean` | — | no | Мобильная раскладка. | | `onFavoriteChange` | `((productId: string) => (addingValue: boolean, position?: number) => void)` | — | no | Переключение избранного (стабильная по ссылке функция). Не передано — кнопка избранного не показывается. | | `onServiceClick` | `((service: InnerLink, event: MouseEvent) => void)` | — | no | Колбэк клика по карточке. | | `service` | `InnerLink` | — | yes | Карточка сервиса. | | `showDescription` | `boolean` | — | yes | Показывать описание сервиса вместо тултипа. | | `tabIndex` | `number` | — | no | `tabIndex` корневого элемента. | ### SortableFavoriteCard | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `className` | `string` | — | no | CSS-класс корневого элемента | | `data-test-id` | `string` | — | no | Support prop для тестов | | `expandable` | `{ value: boolean; onClick(): void; }` | — | no | Настройки кнопки раскрытия | | `favorite` | `FavoriteProps` | — | no | Настройки кнопки «Избранное». Keyboard: ArrowRight на карточке → promo tag → tooltip (если есть) → Favorite → expand; ArrowLeft — в обратном порядке. | | `icon` | `ReactElement>` | — | no | Иконка сервиса | | `isFirst` | `boolean` | — | no | Карточка первая в списке — влияет на позиционирование индикатора вставки. | | `promoTag` | `CardPromoTagProps` | — | no | Настройки promo tag. При отсутствии не отображается | | `serviceId` | `string` | — | yes | Id сервиса (используется для drag-идентификатора карточки). | | `showInsertIndicatorAfter` | `boolean` | — | no | Показывать индикатор вставки после карточки (drag поверх избранного). | | `showInsertIndicatorBefore` | `boolean` | — | no | Показывать индикатор вставки перед карточкой (drag поверх избранного). | | `title` | `string` | — | yes | Заголовок карточки | | `tooltip` | `Omit` | — | no | Подсказка с иконкой «?» рядом с заголовком. Показывается только в компактном виде | ### SortableGroup | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `appear` | `boolean` | — | no | Группа появляется с fade-in при монтировании (на desktop; на mobile анимирует контейнер). | | `blockColor` | `blue \| green \| neutral \| orange \| pink \| primary \| red \| violet \| yellow` | — | no | Цвет блока группы. | | `enableServiceDrag` | `boolean` | — | no | Группу можно перетаскивать (иначе рендерится без `useSortable`). | | `groupFavoritesEnabled` | `boolean` | — | no | Разрешено ли добавление карточек группы в избранное. | | `highlight` | `boolean` | — | no | Визуальное выделение группы. | | `icon` | `JSXElementConstructor<{ size?: number; className?: string; }> \| undefined` | — | no | Иконка группы. | | `id` | `string` | — | yes | Id группы. | | `isExpanded` | `boolean` | — | no | Раскрыта ли группа. | | `isMobile` | `boolean` | — | no | Мобильная раскладка. | | `items` | `InnerLink[]` | — | yes | Карточки сервисов или ссылок внутри группы. | | `label` | `LinksGroupTitle` | — | yes | Заголовок группы. | ### SortableGroupCards | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `groupFavoritesEnabled` | `boolean` | — | no | Разрешено ли добавление карточек группы в избранное. | | `groupId` | `string` | — | yes | Id группы-предка. | | `items` | `InnerLink[]` | — | yes | Карточки сервисов группы. | ### SortableGroupDragHandle | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `attributes` | `DraggableAttributes` | — | no | ARIA-атрибуты `dnd-kit` draggable-элемента. | | `listeners` | `DraggableSyntheticListeners` | — | no | Обработчики событий `dnd-kit` для инициации перетаскивания. | ### SortableGroupDragPreview | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `appear` | `boolean` | — | no | Группа появляется с fade-in при монтировании (на desktop; на mobile анимирует контейнер). | | `blockColor` | `blue \| green \| neutral \| orange \| pink \| primary \| red \| violet \| yellow` | — | no | Цвет блока группы. | | `favoriteIds` | `ReadonlySet` | — | no | Id избранных сервисов. Не передано — избранное для карточек недоступно. | | `groupFavoritesEnabled` | `boolean` | — | no | Разрешено ли добавление карточек группы в избранное. | | `highlight` | `boolean` | — | no | Визуальное выделение группы. | | `icon` | `JSXElementConstructor<{ size?: number; className?: string; }> \| undefined` | — | no | Иконка группы. | | `id` | `string` | — | yes | Id группы. | | `isExpanded` | `boolean` | — | no | Раскрыта ли группа. | | `isMobile` | `boolean` | — | no | Мобильная раскладка. | | `items` | `InnerLink[]` | — | yes | Карточки сервисов или ссылок внутри группы. | | `label` | `LinksGroupTitle` | — | yes | Заголовок группы. | | `onFavoriteChange` | `((productId: string) => (addingValue: boolean, position?: number) => void)` | — | no | Стабильная по ссылке обёртка над `favorite.onChange`. | | `showDescription` | `boolean` | — | yes | | ### SortableGroupHeader | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `attributes` | `DraggableAttributes` | — | no | ARIA-атрибуты `dnd-kit` draggable-элемента. | | `enableServiceDrag` | `boolean` | — | no | | | `icon` | `JSXElementConstructor<{ size?: number; className?: string; }> \| undefined` | — | no | Иконка группы. | | `isExpanded` | `boolean` | — | no | | | `isMobile` | `boolean` | — | no | | | `label` | `LinksGroupTitle` | — | yes | | | `listeners` | `DraggableSyntheticListeners` | — | no | Обработчики событий `dnd-kit` для инициации перетаскивания. | ### SortableGroupSkeleton | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `isMobile` | `boolean` | — | no | Мобильная раскладка. | ### SubCategory | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `groupFavoritesEnabled` | `boolean` | — | no | Разрешено ли добавление карточек группы в избранное. | | `groupId` | `string` | — | yes | Id группы-предка. | | `service` | `InnerLink` | — | yes | Карточка подкатегории (с непустым {@link InnerLink.items}). | ### SubCategoryTitle | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `expandable` | `{ value: boolean; onClick(): void; }` | — | no | Настройки кнопки раскрытия | | `groupFavoritesEnabled` | `boolean` | — | no | Кнопка избранного показывается только если для группы избранное включено. | | `groupId` | `string` | — | yes | Id группы-предка. | | `service` | `InnerLink` | — | yes | Карточка сервиса. | ### UserMenu | Prop | Type | Default | Required | Description | |------|------|---------|----------|-------------| | `bottomItems` | `Item[]` | — | no | Пункты перед «Выйти из аккаунта». На desktop закреплены снизу | | `onClick` | `(() => void)` | — | no | Колбэк клика по кнопке-триггеру. | | `onLogout` | `(() => void)` | — | no | Колбэк клика по пункту «Выйти». | | `open` | `boolean` | — | no | Открыто ли меню. Не передано — состояние открытия неуправляемое (меню само переключает себя по клику на кнопку). | | `organizationItems` | `Item[]` | — | no | Список организаций. На desktop — единственная прокручиваемая часть меню | | `profile` | `UserProfileProps` | `{}` | no | Профиль пользователя (имя, email, счётчик приглашений). | | `setOpen` | `((open: boolean) => void)` | — | no | Колбэк открытия/закрытия меню. | | `settingItems` | `BaseItem[]` | — | no | Пункты настроек в нижней части меню. | | `theme` | `ThemeProps` | — | no | Переключатель темы в меню. Без пропа не отображается. | | `topItems` | `Item[]` | — | no | Пункты после темы. На desktop закреплены сверху вместе с профилем и темой | | `triggerTooltip` | `string` | — | no | Текст подсказки для кнопки-триггера. | #### Related types - `BaseItemProps` (interface) - `BaseItemWithoutNonGroup` (interface) - `CollapseState` (interface) - `CommonGroupItem` (interface) - `DroplistProps` (interface) - `Item` (alias) - `ItemContent` (interface) - `ItemId` (alias) - `OriginalScrollProps` (interface) - `Placement` = `bottom | bottom-end | bottom-start | left | left-end | left-start | right | right-end | right-start | top | top-end | top-start` - `PopoverWidthStrategy` = `auto | eq | gte` - `ScrollProps` (interface) - `SearchState` (interface) - `SelectionMultipleState` (interface) - `Size` = `l | m | s` - `ThemeMode` = `dark | light | system` - `ThemeProps` (interface) - `Trigger` = `click | clickAndFocusVisible | focus | focusVisible | hover | hoverAndFocus | hoverAndFocusVisible` - `TruncateStringProps` (alias) - `UserProfileProps` (interface)