@cloud-ru/ds-uikit-product-header 1.1.1 → 1.1.2-preview-d405de03.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -4
- package/dist/cjs/components/MainMenu/helperComponents/Content/Content.js +7 -8
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/ContentToolbar/styles.module.css +1 -0
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.d.ts +3 -3
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.js +2 -2
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +3 -3
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +8 -2
- package/dist/cjs/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +1 -0
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.d.ts +1 -1
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +10 -7
- package/dist/cjs/components/MainMenu/helperComponents/MenuDesktop/styles.module.css +13 -3
- package/dist/cjs/components/MainMenu/types.d.ts +14 -9
- package/dist/cjs/components/MainMenu/utils/getLinkEmblem.d.ts +1 -1
- package/dist/cjs/components/MainMenu/utils/getLinkEmblem.js +1 -9
- package/dist/cjs/components/MainMenu/utils/index.d.ts +0 -1
- package/dist/cjs/components/MainMenu/utils/index.js +0 -1
- package/dist/cjs/components/PathBreadcrumbs/styles.module.css +3 -0
- package/dist/cjs/constants.d.ts +2 -0
- package/dist/cjs/constants.js +2 -0
- package/dist/cjs/style.css +18 -3
- package/dist/esm/components/MainMenu/helperComponents/Content/Content.js +7 -8
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/ContentToolbar/styles.module.css +1 -0
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.d.ts +3 -3
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.js +2 -2
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.d.ts +3 -3
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.js +8 -2
- package/dist/esm/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.css +1 -0
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.d.ts +1 -1
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.js +6 -3
- package/dist/esm/components/MainMenu/helperComponents/MenuDesktop/styles.module.css +13 -3
- package/dist/esm/components/MainMenu/types.d.ts +14 -9
- package/dist/esm/components/MainMenu/utils/getLinkEmblem.d.ts +1 -1
- package/dist/esm/components/MainMenu/utils/getLinkEmblem.js +1 -9
- package/dist/esm/components/MainMenu/utils/index.d.ts +0 -1
- package/dist/esm/components/MainMenu/utils/index.js +0 -1
- package/dist/esm/components/PathBreadcrumbs/styles.module.css +3 -0
- package/dist/esm/constants.d.ts +2 -0
- package/dist/esm/constants.js +2 -0
- package/dist/esm/style.css +18 -3
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +26 -26
- package/src/components/MainMenu/helperComponents/Content/Content.tsx +8 -12
- package/src/components/MainMenu/helperComponents/Content/helperComponents/ContentToolbar/styles.module.scss +1 -0
- package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/SortableGroup.tsx +11 -8
- package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/components/SortableGroupHeader.tsx +28 -4
- package/src/components/MainMenu/helperComponents/Content/helperComponents/SortableGroup/styles.module.scss +14 -7
- package/src/components/MainMenu/helperComponents/MenuDesktop/MenuDesktop.tsx +26 -4
- package/src/components/MainMenu/helperComponents/MenuDesktop/styles.module.scss +13 -3
- package/src/components/MainMenu/types.ts +15 -9
- package/src/components/MainMenu/utils/getLinkEmblem.tsx +3 -18
- package/src/components/MainMenu/utils/index.ts +0 -1
- package/src/components/PathBreadcrumbs/styles.module.scss +4 -0
- package/src/constants.ts +2 -0
- package/dist/cjs/components/MainMenu/utils/getAvatarNameFromLabel.d.ts +0 -14
- package/dist/cjs/components/MainMenu/utils/getAvatarNameFromLabel.js +0 -24
- package/dist/esm/components/MainMenu/utils/getAvatarNameFromLabel.d.ts +0 -14
- package/dist/esm/components/MainMenu/utils/getAvatarNameFromLabel.js +0 -21
- package/src/components/MainMenu/utils/getAvatarNameFromLabel.ts +0 -24
package/README.md
CHANGED
|
@@ -206,6 +206,7 @@ export function WithFavorites() {
|
|
|
206
206
|
| `disabled` | `boolean` | — | |
|
|
207
207
|
| `draggerTooltip` | `string` | — | Текст подсказки для драггера (desktop only) |
|
|
208
208
|
| `favorite` | `FavoriteProps` | — | |
|
|
209
|
+
| `leftBottom` | `ReactNode` | — | |
|
|
209
210
|
| `leftTop` | `ReactNode` | — | |
|
|
210
211
|
| `loading` | `boolean` | — | Флаг загрузки данных |
|
|
211
212
|
| `logo` | `ReactNode` | — | |
|
|
@@ -221,16 +222,42 @@ export function WithFavorites() {
|
|
|
221
222
|
| `segmentPrefs` | `MainMenuSegmentPrefs` | — | Пользовательские prefs сегментов (порядок / раскрытие групп). <br/> Нет записи для сегмента или omit `order` / `expanded` → uncontrolled для этого поля. |
|
|
222
223
|
| `segments` | `MainMenuSegment` | — | Сегменты правой панели (сетка карточек) — только каталог. <br/> При поиске: совпадения из сегментов без `pinBottomOnSearch` → `platformGroups` → сегменты с `pinBottomOnSearch`. <br/> Если один и тот же {@link InnerLink.id} совпал сразу в нескольких сегментах — остаётся только <br/> первое по этому приоритету вхождение, остальные (и опустевшие после этого группы) не показываются. <br/> При `segments.length > 1` показывается SegmentControl (скрывается во время поиска). <br/> Порядок и раскрытие групп — через `segmentPrefs` и колбэки ниже. |
|
|
223
224
|
| `setOpen` | `((open: boolean) => void)` | — | |
|
|
224
|
-
| `settingItems` | `
|
|
225
|
+
| `settingItems` | `InnerLink` \| `MainMenuSettingsItem` | — | Пункты левой колонки (desktop) / нижней части списка (mobile). <br/> Плоский список (`dividerBefore` для разделителей). <br/> Не связан с сегментами правой панели и не меняется при сортировке групп в сегментах. |
|
|
225
226
|
|
|
226
227
|
##### Related types
|
|
227
228
|
|
|
228
|
-
**
|
|
229
|
+
**FavoriteProps**
|
|
229
230
|
|
|
230
231
|
| Prop | Type | Default | Description |
|
|
231
232
|
|------|------|---------|-------------|
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
233
|
+
| `actions` | `BaseItemProps` | — | Действия для списка сервисов |
|
|
234
|
+
| `loading` | `boolean \| undefined` | — | Флаг загрузки данных |
|
|
235
|
+
| `onChange` | `(productId: string) => (addingValue: boolean, position?: number) => void` | — | Колбэк переключения избранного для карточки сервиса. <br/> `position` передаётся при добавлении через drag из сетки сервисов — индекс, <br/> на который должна встать карточка среди избранного (см. <br/> {@link <br/> FavoriteProps.onOrderChange <br/> } <br/> ). <br/> При переключении избранного кликом не передаётся. |
|
|
236
|
+
| `onFavoriteServiceClick` | `((serviceId: string, event?: MouseEvent<HTMLElement>) => void) \| undefined` | — | Колбэк клика по карточке сервиса в сегменте «Избранное» |
|
|
237
|
+
| `onOrderChange` | `((orderedIds: string[]) => void) \| undefined` | — | Колбэк вызывается после перетаскивания карточек внутри избранного с новым порядком id. <br/> Добавление новой карточки через drag из сетки сервисов идёт через <br/> {@link <br/> FavoriteProps.onChange <br/> } <br/> с `position` — этот колбэк для такого добавления не вызывается. |
|
|
238
|
+
| `onRecentServiceClick` | `((serviceId: string, event?: MouseEvent<HTMLElement>) => void) \| undefined` | — | Колбэк клика по карточке сервиса в сегменте «Недавнее» |
|
|
239
|
+
| `onSegmentChange` | `((segment: FavoritesSegment) => void) \| undefined` | — | Колбэк смены сегмента панели избранного. |
|
|
240
|
+
| `recentServices` | `string[] \| undefined` | — | Список id недавно открытых сервисов |
|
|
241
|
+
| `segment` | `"favorites"` \| `"recent"` | — | Активный сегмент («Избранное» / «Недавнее») в панели избранного. <br/> Не передано — неуправляемое состояние (дефолт `'favorites'`). |
|
|
242
|
+
| `value` | `string[]` | — | Список id избранных сервисов |
|
|
243
|
+
|
|
244
|
+
- `FavoritesSegment` = `"favorites"` \| `"recent"`
|
|
245
|
+
|
|
246
|
+
**InnerLink**
|
|
247
|
+
|
|
248
|
+
| Prop | Type | Default | Description |
|
|
249
|
+
|------|------|---------|-------------|
|
|
250
|
+
| `aliases` | `string[]` | — | Синонимы для fuzzy-поиска. |
|
|
251
|
+
| `badge` | `CardServiceLightProps` \| `PromoTagPredefinedBaseProps` | — | |
|
|
252
|
+
| `description` | `string \| undefined` | — | Краткое описание сервиса — отображается при включённом переключателе «Описание». |
|
|
253
|
+
| `disabled` | `boolean \| undefined` | — | |
|
|
254
|
+
| `hidden` | `boolean \| undefined` | — | |
|
|
255
|
+
| `href` | `string \| undefined` | — | |
|
|
256
|
+
| `icon` | `JSXElementConstructor<{ size?: number; className?: string; }> \| undefined` | — | Иконка карточки. |
|
|
257
|
+
| `id` | `string` | — | Уникальный идентификатор карточки (также используется в избранном и при поиске). <br/> Один и тот же сервис может быть представлен в разных сегментах с разной <br/> детализацией (простая карточка в общем каталоге и раскрытая с вложенными <br/> сервисами версия в другом сегменте) — в этом случае обеим версиям задаётся <br/> общий `id`. При поиске из совпадений с одинаковым `id` в разных сегментах <br/> остаётся только первое по приоритету сегментов (см. <br/> {@link <br/> MainMenuProps.segments <br/> } <br/> ). |
|
|
258
|
+
| `items` | `InnerLink` | — | Вложенные сервисы подкатегории. <br/> При наличии карточка раскрывается аккордеоном: в свёрнутом виде — обычная карточка <br/> с кнопкой раскрытия, в развёрнутом — заголовок <br/> {@link <br/> TitleClickable <br/> } <br/> и сетка вложенных сервисов. |
|
|
259
|
+
| `label` | `string` | — | Заголовок карточки. |
|
|
260
|
+
| `onClick` | `(e?: MouseEvent<HTMLElement>) => void` | — | |
|
|
234
261
|
|
|
235
262
|
**LinksGroup**
|
|
236
263
|
|
|
@@ -241,11 +268,21 @@ export function WithFavorites() {
|
|
|
241
268
|
| `favoritesEnabled` | `boolean \| undefined` | — | Разрешено ли добавление карточек группы в избранное. |
|
|
242
269
|
| `hidden` | `boolean \| undefined` | — | |
|
|
243
270
|
| `highlight` | `boolean \| undefined` | — | Визуальное выделение группы |
|
|
271
|
+
| `icon` | `JSXElementConstructor<{ size?: number; className?: string; }> \| undefined` | — | |
|
|
244
272
|
| `id` | `string` | — | Уникальный идентификатор группы (якорь скролла, поиск по id). |
|
|
245
273
|
| `items` | `InnerLink` | — | Карточки сервисов или ссылок внутри группы. |
|
|
246
274
|
| `label` | `LinksGroupTitle` \| `TitleClickable` \| `TitleStatic` | — | Заголовок группы в сетке карточек и в боковой навигации. |
|
|
247
275
|
| `onClick` | `((e?: MouseEvent<HTMLElement>) => void) \| undefined` | — | |
|
|
248
276
|
|
|
277
|
+
**MainMenuPreferencesProps**
|
|
278
|
+
|
|
279
|
+
| Prop | Type | Default | Description |
|
|
280
|
+
|------|------|---------|-------------|
|
|
281
|
+
| `onOpenChange` | `((open: boolean) => void) \| undefined` | — | Колбэк открытия/закрытия модалки. |
|
|
282
|
+
| `open` | `boolean \| undefined` | — | Открыта ли модалка настроек. <br/> Не передано — состояние открытия неуправляемое (модалка сама переключает себя по клику на кнопку). |
|
|
283
|
+
| `showDescription` | `MainMenuToggleProps` | — | Показывать описания сервисов в карточках. |
|
|
284
|
+
| `showGroupsColors` | `MainMenuToggleProps` | — | Отображать цвета блоков групп ( <br/> {@link <br/> LinksGroup.blockColor <br/> } <br/> ). <br/> `value: false` скрывает цвета всех групп независимо от заданного `blockColor`. |
|
|
285
|
+
|
|
249
286
|
**MainMenuSegment**
|
|
250
287
|
|
|
251
288
|
| Prop | Type | Default | Description |
|
|
@@ -264,6 +301,35 @@ export function WithFavorites() {
|
|
|
264
301
|
| `id` | `string` | — | Id сегмента из <br/> {@link <br/> MainMenuSegment.id <br/> } <br/> . |
|
|
265
302
|
| `order` | `string[] \| undefined` | — | Порядок id групп. Если не передан — uncontrolled для этого сегмента <br/> (дефолт = порядок `items`; новые группы добавляются в конец). |
|
|
266
303
|
|
|
304
|
+
**MainMenuSettingsItem**
|
|
305
|
+
|
|
306
|
+
| Prop | Type | Default | Description |
|
|
307
|
+
|------|------|---------|-------------|
|
|
308
|
+
| `dividerBefore` | `boolean \| undefined` | — | |
|
|
309
|
+
| `hidden` | `boolean \| undefined` | — | |
|
|
310
|
+
| `href` | `string \| undefined` | — | |
|
|
311
|
+
| `icon` | `JSXElementConstructor<{ size?: number; className?: string; }> \| undefined` | — | Иконка карточки. |
|
|
312
|
+
| `id` | `string` | — | Уникальный идентификатор карточки (также используется в избранном и при поиске). <br/> Один и тот же сервис может быть представлен в разных сегментах с разной <br/> детализацией (простая карточка в общем каталоге и раскрытая с вложенными <br/> сервисами версия в другом сегменте) — в этом случае обеим версиям задаётся <br/> общий `id`. При поиске из совпадений с одинаковым `id` в разных сегментах <br/> остаётся только первое по приоритету сегментов (см. <br/> {@link <br/> MainMenuProps.segments <br/> } <br/> ). |
|
|
313
|
+
| `label` | `string` | — | Заголовок карточки. |
|
|
314
|
+
| `onClick` | `(e?: MouseEvent<HTMLElement>) => void` | — | |
|
|
315
|
+
|
|
316
|
+
**MainMenuToggleProps**
|
|
317
|
+
|
|
318
|
+
| Prop | Type | Default | Description |
|
|
319
|
+
|------|------|---------|-------------|
|
|
320
|
+
| `onChange` | `(value: boolean) => void` | — | |
|
|
321
|
+
| `value` | `boolean` | — | |
|
|
322
|
+
|
|
323
|
+
**SearchProps**
|
|
324
|
+
|
|
325
|
+
| Prop | Type | Default | Description |
|
|
326
|
+
|------|------|---------|-------------|
|
|
327
|
+
| `onBlur` | `FocusEventHandler<HTMLInputElement> \| undefined` | — | Колбек обработки потери фокуса |
|
|
328
|
+
| `onChange` | `(value: string) => void` | — | |
|
|
329
|
+
| `onFocus` | `FocusEventHandler<HTMLInputElement> \| undefined` | — | Колбек обработки получения фокуса |
|
|
330
|
+
| `onSearchNoResult` | `((value: string) => void) \| undefined` | — | |
|
|
331
|
+
| `value` | `string` | — | |
|
|
332
|
+
|
|
267
333
|
## UserMenu
|
|
268
334
|
|
|
269
335
|
Меню пользователя — профиль, переключатель темы, пункты настроек и выход.
|
|
@@ -25,8 +25,7 @@ function Content({ searchValue, search, rightTop, segments, searchGroups = [], s
|
|
|
25
25
|
const { t } = locale_1.headerLocale.useTranslations();
|
|
26
26
|
const showDescription = (0, react_1.useDeferredValue)(preferences?.showDescription.value ?? false);
|
|
27
27
|
const segmentPrefsById = (0, react_1.useMemo)(() => new Map((segmentPrefs ?? []).map(prefs => [prefs.id, prefs])), [segmentPrefs]);
|
|
28
|
-
const
|
|
29
|
-
const defaultSegmentId = visibleSegments[0]?.id ?? segments[0]?.id ?? '';
|
|
28
|
+
const defaultSegmentId = activeSegmentId ?? segments[0]?.id ?? '';
|
|
30
29
|
const [segmentId = defaultSegmentId, setSegmentId] = (0, utils_1.useValueControl)({
|
|
31
30
|
value: activeSegmentId,
|
|
32
31
|
defaultValue: defaultSegmentId,
|
|
@@ -35,10 +34,10 @@ function Content({ searchValue, search, rightTop, segments, searchGroups = [], s
|
|
|
35
34
|
const isSearching = Boolean(searchValue);
|
|
36
35
|
const enableServiceDrag = Boolean(favorite) && !isMobile && !isSearching;
|
|
37
36
|
(0, react_1.useEffect)(() => {
|
|
38
|
-
if (!
|
|
37
|
+
if (!segments.some(segment => segment.id === segmentId) && defaultSegmentId) {
|
|
39
38
|
setSegmentId(defaultSegmentId);
|
|
40
39
|
}
|
|
41
|
-
}, [defaultSegmentId, segmentId, setSegmentId,
|
|
40
|
+
}, [defaultSegmentId, segmentId, setSegmentId, segments]);
|
|
42
41
|
const handleLinkClick = (0, react_1.useCallback)(({ disabled, onClick }, e) => {
|
|
43
42
|
if (disabled) {
|
|
44
43
|
e?.preventDefault();
|
|
@@ -79,23 +78,23 @@ function Content({ searchValue, search, rightTop, segments, searchGroups = [], s
|
|
|
79
78
|
}
|
|
80
79
|
onExpandedChange([...new Set([...expandedIds, ...visibleIds])]);
|
|
81
80
|
}, [allGroupsExpanded, expandedIds, onExpandedChange, visibleGroups]);
|
|
82
|
-
const segmentItems = (0, react_1.useMemo)(() =>
|
|
81
|
+
const segmentItems = (0, react_1.useMemo)(() => segments.map(segment => ({
|
|
83
82
|
value: segment.id,
|
|
84
83
|
label: segment.label,
|
|
85
84
|
icon: segment.icon,
|
|
86
|
-
})), [
|
|
85
|
+
})), [segments]);
|
|
87
86
|
const hasCards = visibleGroups.length > 0;
|
|
88
87
|
const cards = (() => {
|
|
89
88
|
if (loading) {
|
|
90
89
|
return Array.from({ length: 5 }).map((_, index) => (0, jsx_runtime_1.jsx)(SortableGroup_1.SortableGroupSkeleton, { isMobile: isMobile }, index));
|
|
91
90
|
}
|
|
92
91
|
if (hasCards) {
|
|
93
|
-
return ((0, jsx_runtime_1.jsx)(sortable_1.SortableContext, { items: visibleGroups.map(({ id }) => id), strategy: sortable_1.verticalListSortingStrategy, children: (0, jsx_runtime_1.jsx)(accordion_1.Accordion, { selectionMode: 'multiple', expanded: expandedIds, onExpandedChange: onExpandedChange, children: visibleGroups.map(({ id, label, items, favoritesEnabled = true, blockColor, highlight }) => ((0, jsx_runtime_1.jsx)(SortableGroup_1.SortableGroup, { id: id, label: label, items: items, isExpanded: expandedIds.includes(id), blockColor: (0, utils_2.resolveGroupBlockColor)(blockColor, preferences?.showGroupsColors?.value), showDescription: showDescription, isMobile: isMobile, enableServiceDrag: enableServiceDrag, favorite: favoritesEnabled ? favorite : undefined, onServiceClick: handleLinkClick, highlight: highlight }, id))) }) }));
|
|
92
|
+
return ((0, jsx_runtime_1.jsx)(sortable_1.SortableContext, { items: visibleGroups.map(({ id }) => id), strategy: sortable_1.verticalListSortingStrategy, children: (0, jsx_runtime_1.jsx)(accordion_1.Accordion, { selectionMode: 'multiple', expanded: expandedIds, onExpandedChange: onExpandedChange, children: visibleGroups.map(({ id, label, icon, items, favoritesEnabled = true, blockColor, highlight }) => ((0, jsx_runtime_1.jsx)(SortableGroup_1.SortableGroup, { id: id, icon: icon, label: label, items: items, isExpanded: expandedIds.includes(id), blockColor: (0, utils_2.resolveGroupBlockColor)(blockColor, preferences?.showGroupsColors?.value), showDescription: showDescription, isMobile: isMobile, enableServiceDrag: enableServiceDrag, favorite: favoritesEnabled ? favorite : undefined, onServiceClick: handleLinkClick, highlight: highlight }, id))) }) }));
|
|
94
93
|
}
|
|
95
94
|
return ((0, jsx_runtime_1.jsx)(info_block_1.InfoBlock, { size: 'm', icon: {
|
|
96
95
|
icon: system_1.SearchSVG,
|
|
97
96
|
appearance: 'neutral',
|
|
98
97
|
}, content: isSearching ? t('noDataFound') : t('noData'), "data-test-id": isSearching ? constants_1.TEST_IDS.noDataFound : constants_1.TEST_IDS.noData }));
|
|
99
98
|
})();
|
|
100
|
-
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": !hasCards || undefined, children: [!isSearching && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isMobile && rightTop, (0, jsx_runtime_1.jsx)(ContentToolbar_1.ContentToolbar, { segment: segmentId, onSegmentChange: setSegmentId, segmentItems: segmentItems, allGroupsExpanded: allGroupsExpanded, onToggleAllGroupsExpanded: handleToggleAllGroupsExpanded, preferences: preferences, isMobile: isMobile }), !isMobile && rightTop] })), cards, footer] })] }));
|
|
99
|
+
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.jsxs)(jsx_runtime_1.Fragment, { children: [isMobile && rightTop, (0, jsx_runtime_1.jsx)(ContentToolbar_1.ContentToolbar, { segment: segmentId, onSegmentChange: setSegmentId, segmentItems: segmentItems, allGroupsExpanded: allGroupsExpanded, onToggleAllGroupsExpanded: handleToggleAllGroupsExpanded, preferences: preferences, isMobile: isMobile }), !isMobile && rightTop] })), cards, footer] })] }));
|
|
101
100
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { LinksGroupBlockColor, LinksGroupTitle } from '../../../../types';
|
|
1
|
+
import { LinksGroup, LinksGroupBlockColor, LinksGroupTitle } from '../../../../types';
|
|
2
2
|
import { SortableGroupCardsProps } from './components';
|
|
3
|
-
export type SortableGroupProps = Omit<SortableGroupCardsProps, 'groupId'> & {
|
|
3
|
+
export type SortableGroupProps = Omit<SortableGroupCardsProps, 'groupId'> & Pick<LinksGroup, 'icon'> & {
|
|
4
4
|
id: string;
|
|
5
5
|
label: LinksGroupTitle;
|
|
6
6
|
isExpanded?: boolean;
|
|
7
7
|
blockColor?: LinksGroupBlockColor;
|
|
8
8
|
highlight?: boolean;
|
|
9
9
|
};
|
|
10
|
-
export declare function SortableGroup({ id, label, items, isExpanded, showDescription, isMobile, enableServiceDrag, favorite, onServiceClick, blockColor, highlight, }: SortableGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function SortableGroup({ id, icon, label, items, isExpanded, showDescription, isMobile, enableServiceDrag, favorite, onServiceClick, blockColor, highlight, }: SortableGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
11
11
|
export declare function SortableGroupDragPreview({ id, label, items, isExpanded, showDescription, isMobile, favorite, blockColor, highlight, }: Omit<SortableGroupProps, 'enableServiceDrag'>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -14,7 +14,7 @@ const theme_1 = require("@cloud-ru/ds-theme");
|
|
|
14
14
|
const constants_1 = require("../../constants");
|
|
15
15
|
const components_1 = require("./components");
|
|
16
16
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
17
|
-
function SortableGroup({ id, label, items, isExpanded, showDescription, isMobile, enableServiceDrag, favorite, onServiceClick, blockColor, highlight, }) {
|
|
17
|
+
function SortableGroup({ id, icon, label, items, isExpanded, showDescription, isMobile, enableServiceDrag, favorite, onServiceClick, blockColor, highlight, }) {
|
|
18
18
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = (0, sortable_1.useSortable)({
|
|
19
19
|
id,
|
|
20
20
|
disabled: !enableServiceDrag,
|
|
@@ -28,7 +28,7 @@ function SortableGroup({ id, label, items, isExpanded, showDescription, isMobile
|
|
|
28
28
|
transition,
|
|
29
29
|
};
|
|
30
30
|
const { colorScheme } = (0, theme_1.useThemeAppearance)().appearance;
|
|
31
|
-
return ((0, jsx_runtime_1.jsxs)(drag_and_drop_1.DragGhost, { innerRef: setNodeRef, id: id, style: style, className: styles_module_scss_1.default.group, dragging: isDragging, mode: drag_and_drop_1.DRAG_MODE.Dynamic, "data-test-id": `${constants_1.TEST_IDS.groupCard}-${id}`, children: [(0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.decoration, "data-color-scheme": colorScheme, "data-is-highlighted": highlight || undefined, children: (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.decorationBackground, children: (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.colorMarker, "data-block-color": blockColor }) }) }), (0, jsx_runtime_1.jsx)(accordion_1.Accordion.CollapseBlockTertiary, { id: id, showChevron: false, afterTitle: (0, jsx_runtime_1.jsx)(components_1.SortableGroupHeader, { label: label, isExpanded: isExpanded, enableServiceDrag: enableServiceDrag, attributes: attributes, listeners: listeners, isMobile: isMobile }), children: (0, jsx_runtime_1.jsx)(components_1.SortableGroupCards, { groupId: id, items: items, showDescription: showDescription, isMobile: isMobile, enableServiceDrag: enableServiceDrag, favorite: favorite, onServiceClick: onServiceClick }) })] }));
|
|
31
|
+
return ((0, jsx_runtime_1.jsxs)(drag_and_drop_1.DragGhost, { innerRef: setNodeRef, id: id, style: style, className: styles_module_scss_1.default.group, dragging: isDragging, mode: drag_and_drop_1.DRAG_MODE.Dynamic, "data-test-id": `${constants_1.TEST_IDS.groupCard}-${id}`, children: [(0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.decoration, "data-color-scheme": colorScheme, "data-is-highlighted": highlight || undefined, children: (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.decorationBackground, children: (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.colorMarker, "data-block-color": blockColor }) }) }), (0, jsx_runtime_1.jsx)(accordion_1.Accordion.CollapseBlockTertiary, { id: id, showChevron: false, afterTitle: (0, jsx_runtime_1.jsx)(components_1.SortableGroupHeader, { label: label, icon: icon, isExpanded: isExpanded, enableServiceDrag: enableServiceDrag, attributes: attributes, listeners: listeners, isMobile: isMobile }), children: (0, jsx_runtime_1.jsx)(components_1.SortableGroupCards, { groupId: id, items: items, showDescription: showDescription, isMobile: isMobile, enableServiceDrag: enableServiceDrag, favorite: favorite, onServiceClick: onServiceClick }) })] }));
|
|
32
32
|
}
|
|
33
33
|
function SortableGroupDragPreview({ id, label, items, isExpanded, showDescription, isMobile, favorite, blockColor, highlight, }) {
|
|
34
34
|
const { colorScheme } = (0, theme_1.useThemeAppearance)().appearance;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { LinksGroupTitle } from '../../../../../types';
|
|
1
|
+
import { LinksGroup, LinksGroupTitle } from '../../../../../types';
|
|
2
2
|
import { SortableGroupDragHandleProps } from './SortableGroupDragHandle';
|
|
3
|
-
export type SortableGroupHeaderProps = {
|
|
3
|
+
export type SortableGroupHeaderProps = Pick<LinksGroup, 'icon'> & {
|
|
4
4
|
label: LinksGroupTitle;
|
|
5
5
|
isExpanded?: boolean;
|
|
6
6
|
enableServiceDrag?: boolean;
|
|
7
7
|
isMobile?: boolean;
|
|
8
8
|
} & SortableGroupDragHandleProps;
|
|
9
|
-
export declare function SortableGroupHeader({ label, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }: SortableGroupHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function SortableGroupHeader({ label, icon, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }: SortableGroupHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -8,8 +8,14 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
8
8
|
const button_1 = require("@cloud-ru/ds-button");
|
|
9
9
|
const system_1 = require("@cloud-ru/ds-icons/interface/system");
|
|
10
10
|
const typography_1 = require("@cloud-ru/ds-typography");
|
|
11
|
+
const uikit_product_title_clickable_1 = require("@cloud-ru/ds-uikit-product-title-clickable");
|
|
12
|
+
const utils_1 = require("../../../../../utils");
|
|
11
13
|
const styles_module_scss_1 = __importDefault(require('../styles.module.css'));
|
|
12
14
|
const SortableGroupDragHandle_1 = require("./SortableGroupDragHandle");
|
|
13
|
-
function SortableGroupHeader({ label, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }) {
|
|
14
|
-
|
|
15
|
+
function SortableGroupHeader({ label, icon, isExpanded, enableServiceDrag, attributes, listeners, isMobile, }) {
|
|
16
|
+
const handleLabelClick = e => {
|
|
17
|
+
e.stopPropagation();
|
|
18
|
+
label?.onClick?.(e);
|
|
19
|
+
};
|
|
20
|
+
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, before: (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' }))] }))] }));
|
|
15
21
|
}
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
overflow-x:clip;
|
|
51
51
|
display:flex;
|
|
52
52
|
flex-direction:column;
|
|
53
|
+
width:100%;
|
|
53
54
|
min-width:0;
|
|
54
55
|
padding:var(--sn-primitive-dimension-4, 4px) var(--sn-primitive-dimension-8, 8px) var(--sn-primitive-dimension-8, 8px) var(--sn-primitive-dimension-12, 12px);
|
|
55
56
|
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { MainMenuProps } from '../../types';
|
|
2
|
-
export declare function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platformGroups, segments, segmentPrefs, activeSegmentId, onActiveSegmentChange, onSegmentOrderChange, onSegmentExpandedChange, favorite, search, preferences, logo, rightTop, leftTop, defaultWidth, onWidthChangeEnd, draggerTooltip, loading, }: MainMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platformGroups, segments, segmentPrefs, activeSegmentId, onActiveSegmentChange, onSegmentOrderChange, onSegmentExpandedChange, favorite, search, preferences, logo, rightTop, leftTop, leftBottom, defaultWidth, onWidthChangeEnd, draggerTooltip, loading, }: MainMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,16 +4,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.MenuDesktop = MenuDesktop;
|
|
7
|
+
const react_1 = require("react");
|
|
7
8
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
9
|
const divider_1 = require("@cloud-ru/ds-divider");
|
|
9
10
|
const drawer_1 = require("@cloud-ru/ds-drawer");
|
|
10
|
-
const list_1 = require("@cloud-ru/ds-list");
|
|
11
11
|
const scroll_1 = require("@cloud-ru/ds-scroll");
|
|
12
|
+
const uikit_product_card_predefined_1 = require("@cloud-ru/ds-uikit-product-card-predefined");
|
|
12
13
|
const utils_1 = require("@cloud-ru/ds-utils");
|
|
13
|
-
const
|
|
14
|
+
const react_2 = require("react");
|
|
14
15
|
const constants_1 = require("../../../../constants");
|
|
15
16
|
const useMainMenuDnd_1 = require("../../hooks/useMainMenuDnd");
|
|
16
17
|
const useMenuItems_1 = require("../../hooks/useMenuItems");
|
|
18
|
+
const utils_2 = require("../../utils");
|
|
17
19
|
const Content_1 = require("../Content");
|
|
18
20
|
const Favorites_1 = require("../Favorites");
|
|
19
21
|
const MenuHeaderBrand_1 = require("../MenuHeaderBrand");
|
|
@@ -21,7 +23,7 @@ const MountAnimation_1 = require("../MountAnimation");
|
|
|
21
23
|
const Search_1 = require("../Search");
|
|
22
24
|
const constants_2 = require("./constants");
|
|
23
25
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
24
|
-
function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platformGroups, segments, segmentPrefs, activeSegmentId, onActiveSegmentChange, onSegmentOrderChange, onSegmentExpandedChange, favorite, search, preferences, logo, rightTop, leftTop, defaultWidth = constants_2.MENU_WIDTH_MAX, onWidthChangeEnd, draggerTooltip, loading, }) {
|
|
26
|
+
function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platformGroups, segments, segmentPrefs, activeSegmentId, onActiveSegmentChange, onSegmentOrderChange, onSegmentExpandedChange, favorite, search, preferences, logo, rightTop, leftTop, leftBottom, defaultWidth = constants_2.MENU_WIDTH_MAX, onWidthChangeEnd, draggerTooltip, loading, }) {
|
|
25
27
|
const [open = false, setOpen] = (0, utils_1.useValueControl)({ value: openProp, onChange: setOpenProp });
|
|
26
28
|
const { scrollRef, searchRef, resultItems } = (0, useMenuItems_1.useMenuItems)({
|
|
27
29
|
segments,
|
|
@@ -29,7 +31,7 @@ function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platf
|
|
|
29
31
|
platformGroups,
|
|
30
32
|
});
|
|
31
33
|
const hasSearch = Boolean(search);
|
|
32
|
-
(0,
|
|
34
|
+
(0, react_2.useEffect)(() => {
|
|
33
35
|
if (!open || !hasSearch) {
|
|
34
36
|
return;
|
|
35
37
|
}
|
|
@@ -41,16 +43,17 @@ function MenuDesktop({ open: openProp, setOpen: setOpenProp, settingItems, platf
|
|
|
41
43
|
return () => cancelAnimationFrame(frameId);
|
|
42
44
|
}, [open, hasSearch, searchRef]);
|
|
43
45
|
const isNeedRightBlock = segments && segments.some(segment => segment.items.length > 0);
|
|
44
|
-
const
|
|
46
|
+
const hasBottomItems = Boolean(settingItems?.length) || Boolean(leftBottom);
|
|
47
|
+
const allServiceGroups = (0, react_2.useMemo)(() => segments?.flatMap(segment => segment.items) ?? [], [segments]);
|
|
45
48
|
const mainMenuDnd = (0, useMainMenuDnd_1.useMainMenuDnd)({
|
|
46
49
|
favorite,
|
|
47
50
|
groups: allServiceGroups,
|
|
48
51
|
showDescription: preferences?.showDescription.value ?? false,
|
|
49
52
|
});
|
|
50
|
-
const handleCloseDrawer = (0,
|
|
53
|
+
const handleCloseDrawer = (0, react_2.useCallback)(() => {
|
|
51
54
|
setOpen(false);
|
|
52
55
|
}, [setOpen]);
|
|
53
|
-
const menu = ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.menu, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.menuHeader, children: [(0, jsx_runtime_1.jsx)(MenuHeaderBrand_1.MenuHeaderBrand, { logo: logo, onClose: handleCloseDrawer, className: styles_module_scss_1.default.menuHeaderBrand }), isNeedRightBlock && search && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' }), (0, jsx_runtime_1.jsx)(Search_1.Search, { ...search, ref: searchRef })] }))] }), (0, jsx_runtime_1.jsx)(divider_1.Divider, {}), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.menuBody, children: [(0, jsx_runtime_1.jsxs)(MountAnimation_1.MountAnimation, { className: styles_module_scss_1.default.left, "data-test-id": constants_1.TEST_IDS.mainMenu.left, type: 'slide-right', children: [leftTop && (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.leftTop, children: leftTop }), isNeedRightBlock && favorite && (0, jsx_runtime_1.jsx)(Favorites_1.Favorites, { favorite: favorite, allServiceGroups: allServiceGroups }),
|
|
56
|
+
const menu = ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.menu, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.menuHeader, children: [(0, jsx_runtime_1.jsx)(MenuHeaderBrand_1.MenuHeaderBrand, { logo: logo, onClose: handleCloseDrawer, className: styles_module_scss_1.default.menuHeaderBrand }), isNeedRightBlock && search && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' }), (0, jsx_runtime_1.jsx)(Search_1.Search, { ...search, ref: searchRef })] }))] }), (0, jsx_runtime_1.jsx)(divider_1.Divider, {}), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.menuBody, children: [(0, jsx_runtime_1.jsxs)(MountAnimation_1.MountAnimation, { className: styles_module_scss_1.default.left, "data-test-id": constants_1.TEST_IDS.mainMenu.left, type: 'slide-right', children: [leftTop && (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.leftTop, children: leftTop }), isNeedRightBlock && favorite && (0, jsx_runtime_1.jsx)(Favorites_1.Favorites, { favorite: favorite, allServiceGroups: allServiceGroups }), hasBottomItems ? ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.leftBottom, "data-test-id": constants_1.TEST_IDS.mainMenu.leftBottom, children: [(0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.leftBottomItems, "data-test-id": constants_1.TEST_IDS.mainMenu.leftBottomItems, children: settingItems?.map(item => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [item.dividerBefore && (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'horizontal', className: styles_module_scss_1.default.leftBottomDivider }), (0, react_1.createElement)(uikit_product_card_predefined_1.CardServiceLight, { ...(item.href ? { href: item.href, as: 'a' } : { as: 'button', type: 'button' }), key: item.id, title: item.label, icon: (0, utils_2.getLinkEmblem)(item), onClick: item.onClick, "data-test-id": `header__drawer-menu__setting-${item.id}` })] }))) }), leftBottom] })) : null] }), isNeedRightBlock && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(MountAnimation_1.MountAnimation, { type: 'fade-in', children: (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' }) }), (0, jsx_runtime_1.jsx)(MountAnimation_1.MountAnimation, { type: 'fade-slide-up-right', className: styles_module_scss_1.default.right, "data-test-id": constants_1.TEST_IDS.mainMenu.right, children: (0, jsx_runtime_1.jsx)(scroll_1.Scroll, { paddingAbsolute: true, className: styles_module_scss_1.default.scroll, ref: scrollRef, barHideStrategy: 'never', overflow: { x: 'hidden' }, children: (0, jsx_runtime_1.jsx)(Content_1.Content, { onClose: handleCloseDrawer, className: styles_module_scss_1.default.rightContent, searchValue: search?.value, rightTop: rightTop, favorite: favorite, segments: segments, searchGroups: resultItems, segmentPrefs: segmentPrefs, activeSegmentId: activeSegmentId, onActiveSegmentChange: onActiveSegmentChange, onSegmentOrderChange: onSegmentOrderChange, onSegmentExpandedChange: onSegmentExpandedChange, preferences: preferences, loading: loading }) }) })] }))] })] }));
|
|
54
57
|
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
|
|
55
58
|
? {
|
|
56
59
|
min: constants_2.MENU_WIDTH_MIN,
|
|
@@ -43,9 +43,18 @@
|
|
|
43
43
|
min-height:0;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
.
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
.leftBottomItems{
|
|
47
|
+
width:100%;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.leftBottom{
|
|
51
|
+
display:flex;
|
|
52
|
+
flex-direction:column;
|
|
53
|
+
gap:var(--sn-primitive-dimension-8, 8px);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.leftBottomDivider{
|
|
57
|
+
margin:var(--sn-primitive-dimension-2, 2px) 0;
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
.right{
|
|
@@ -63,6 +72,7 @@
|
|
|
63
72
|
display:flex;
|
|
64
73
|
flex-direction:column;
|
|
65
74
|
gap:var(--sn-primitive-dimension-4, 4px);
|
|
75
|
+
width:100%;
|
|
66
76
|
min-width:0;
|
|
67
77
|
padding:var(--sn-primitive-dimension-16, 16px);
|
|
68
78
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseItemProps
|
|
1
|
+
import { BaseItemProps } from '@cloud-ru/ds-list';
|
|
2
2
|
import { SearchProps as SearchPropsSnack } from '@cloud-ru/ds-search';
|
|
3
3
|
import { CardServiceLightProps } from '@cloud-ru/ds-uikit-product-card-predefined';
|
|
4
4
|
import { JSXElementConstructor, MouseEvent, ReactNode } from 'react';
|
|
@@ -19,12 +19,7 @@ export type InnerLink = {
|
|
|
19
19
|
* остаётся только первое по приоритету сегментов (см. {@link MainMenuProps.segments}).
|
|
20
20
|
*/
|
|
21
21
|
id: string;
|
|
22
|
-
/**
|
|
23
|
-
* Иконка карточки.
|
|
24
|
-
*
|
|
25
|
-
* Если не задана, вместо иконки рендерится `Avatar` с двухбуквенным текстом по `label`
|
|
26
|
-
* (см. `getAvatarNameFromLabel`).
|
|
27
|
-
*/
|
|
22
|
+
/** Иконка карточки. */
|
|
28
23
|
icon?: JSXElementConstructor<{
|
|
29
24
|
size?: number;
|
|
30
25
|
className?: string;
|
|
@@ -53,9 +48,11 @@ export type InnerLink = {
|
|
|
53
48
|
type TitleStatic = {
|
|
54
49
|
text: string;
|
|
55
50
|
onClick?: never;
|
|
51
|
+
href?: never;
|
|
56
52
|
};
|
|
57
53
|
type TitleClickable = {
|
|
58
54
|
text: string;
|
|
55
|
+
href?: string;
|
|
59
56
|
onClick?(e?: MouseEvent<HTMLElement>): void;
|
|
60
57
|
};
|
|
61
58
|
export type LinksGroupTitle = TitleStatic | TitleClickable;
|
|
@@ -71,6 +68,10 @@ export type LinksGroup = {
|
|
|
71
68
|
id: string;
|
|
72
69
|
/** Заголовок группы в сетке карточек и в боковой навигации. */
|
|
73
70
|
label: LinksGroupTitle;
|
|
71
|
+
icon?: JSXElementConstructor<{
|
|
72
|
+
size?: number;
|
|
73
|
+
className?: string;
|
|
74
|
+
}>;
|
|
74
75
|
/**
|
|
75
76
|
* Синонимы заголовка группы для fuzzy-поиска.
|
|
76
77
|
*/
|
|
@@ -202,12 +203,16 @@ export type MainMenuPreferencesProps = {
|
|
|
202
203
|
*/
|
|
203
204
|
showGroupsColors?: MainMenuToggleProps;
|
|
204
205
|
};
|
|
206
|
+
export type MainMenuSettingsItem = Pick<InnerLink, 'id' | 'label' | 'icon' | 'onClick' | 'href' | 'hidden'> & {
|
|
207
|
+
dividerBefore?: boolean;
|
|
208
|
+
};
|
|
205
209
|
export type MainMenuProps = {
|
|
206
210
|
disabled?: boolean;
|
|
207
211
|
open?: boolean;
|
|
208
212
|
setOpen?(open: boolean): void;
|
|
209
213
|
logo?: ReactNode;
|
|
210
214
|
leftTop?: ReactNode;
|
|
215
|
+
leftBottom?: ReactNode;
|
|
211
216
|
rightTop?: ReactNode;
|
|
212
217
|
/**
|
|
213
218
|
* Сегменты правой панели (сетка карточек) — только каталог.
|
|
@@ -245,10 +250,10 @@ export type MainMenuProps = {
|
|
|
245
250
|
/**
|
|
246
251
|
* Пункты левой колонки (desktop) / нижней части списка (mobile).
|
|
247
252
|
*
|
|
248
|
-
* Плоский список
|
|
253
|
+
* Плоский список (`dividerBefore` для разделителей).
|
|
249
254
|
* Не связан с сегментами правой панели и не меняется при сортировке групп в сегментах.
|
|
250
255
|
*/
|
|
251
|
-
settingItems?:
|
|
256
|
+
settingItems?: MainMenuSettingsItem[];
|
|
252
257
|
/**
|
|
253
258
|
* Платформенные группы (например «Облачные продукты», «Другие продукты»).
|
|
254
259
|
*
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { CardServiceLightProps } from '@cloud-ru/ds-uikit-product-card-predefined';
|
|
2
2
|
import { InnerLink } from '../types';
|
|
3
|
-
export declare function getLinkEmblem(link: InnerLink): CardServiceLightProps['icon'];
|
|
3
|
+
export declare function getLinkEmblem(link: Pick<InnerLink, 'icon'>): CardServiceLightProps['icon'];
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getLinkEmblem = getLinkEmblem;
|
|
4
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const avatar_1 = require("@cloud-ru/ds-avatar");
|
|
6
4
|
const react_1 = require("react");
|
|
7
|
-
const getAvatarNameFromLabel_1 = require("./getAvatarNameFromLabel");
|
|
8
|
-
function createAvatarIcon(displayName) {
|
|
9
|
-
return function LinkAvatarIcon({ className }) {
|
|
10
|
-
return ((0, jsx_runtime_1.jsx)(avatar_1.Avatar, { name: displayName, showTwoSymbols: true, shape: 'squared', appearance: 'neutral', size: 's', className: className }));
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
5
|
function getLinkEmblem(link) {
|
|
14
6
|
if (!link.icon) {
|
|
15
|
-
return
|
|
7
|
+
return undefined;
|
|
16
8
|
}
|
|
17
9
|
return (0, react_1.createElement)(link.icon);
|
|
18
10
|
}
|
|
@@ -15,7 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./innerLink"), exports);
|
|
18
|
-
__exportStar(require("./getAvatarNameFromLabel"), exports);
|
|
19
18
|
__exportStar(require("./flatLinksGroups"), exports);
|
|
20
19
|
__exportStar(require("./getLinkEmblem"), exports);
|
|
21
20
|
__exportStar(require("./mapInnerLinksToListItems"), exports);
|
package/dist/cjs/constants.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export declare const TEST_IDS: {
|
|
|
10
10
|
readonly search: "header__drawer-menu__search";
|
|
11
11
|
readonly left: "header__drawer-menu__left";
|
|
12
12
|
readonly right: "header__drawer-menu__right";
|
|
13
|
+
readonly leftBottom: "header__drawer-menu__left-bottom";
|
|
14
|
+
readonly leftBottomItems: "header__drawer-menu__left-bottom-items";
|
|
13
15
|
};
|
|
14
16
|
readonly userMenu: {
|
|
15
17
|
readonly root: "header__user-menu";
|
package/dist/cjs/constants.js
CHANGED
|
@@ -13,6 +13,8 @@ exports.TEST_IDS = {
|
|
|
13
13
|
search: 'header__drawer-menu__search',
|
|
14
14
|
left: 'header__drawer-menu__left',
|
|
15
15
|
right: 'header__drawer-menu__right',
|
|
16
|
+
leftBottom: 'header__drawer-menu__left-bottom',
|
|
17
|
+
leftBottomItems: 'header__drawer-menu__left-bottom-items',
|
|
16
18
|
},
|
|
17
19
|
userMenu: {
|
|
18
20
|
root: 'header__user-menu',
|
package/dist/cjs/style.css
CHANGED
|
@@ -157,6 +157,7 @@
|
|
|
157
157
|
gap:var(--sn-primitive-dimension-8, 8px);
|
|
158
158
|
align-items:center;
|
|
159
159
|
justify-content:space-between;
|
|
160
|
+
width:100%;
|
|
160
161
|
min-width:0;
|
|
161
162
|
min-height:var(--sn-primitive-dimension-32, 32px);
|
|
162
163
|
}
|
|
@@ -297,6 +298,7 @@
|
|
|
297
298
|
overflow-x:clip;
|
|
298
299
|
display:flex;
|
|
299
300
|
flex-direction:column;
|
|
301
|
+
width:100%;
|
|
300
302
|
min-width:0;
|
|
301
303
|
padding:var(--sn-primitive-dimension-4, 4px) var(--sn-primitive-dimension-8, 8px) var(--sn-primitive-dimension-8, 8px) var(--sn-primitive-dimension-12, 12px);
|
|
302
304
|
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
@@ -646,9 +648,18 @@
|
|
|
646
648
|
min-height:0;
|
|
647
649
|
}
|
|
648
650
|
|
|
649
|
-
.
|
|
650
|
-
|
|
651
|
-
|
|
651
|
+
.leftBottomItems{
|
|
652
|
+
width:100%;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.leftBottom{
|
|
656
|
+
display:flex;
|
|
657
|
+
flex-direction:column;
|
|
658
|
+
gap:var(--sn-primitive-dimension-8, 8px);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
.leftBottomDivider{
|
|
662
|
+
margin:var(--sn-primitive-dimension-2, 2px) 0;
|
|
652
663
|
}
|
|
653
664
|
|
|
654
665
|
.right{
|
|
@@ -666,6 +677,7 @@
|
|
|
666
677
|
display:flex;
|
|
667
678
|
flex-direction:column;
|
|
668
679
|
gap:var(--sn-primitive-dimension-4, 4px);
|
|
680
|
+
width:100%;
|
|
669
681
|
min-width:0;
|
|
670
682
|
padding:var(--sn-primitive-dimension-16, 16px);
|
|
671
683
|
}
|
|
@@ -827,7 +839,10 @@
|
|
|
827
839
|
min-width:0;
|
|
828
840
|
}
|
|
829
841
|
.breadcrumbs{
|
|
842
|
+
display:flex;
|
|
843
|
+
align-items:center;
|
|
830
844
|
min-width:0;
|
|
845
|
+
height:100%;
|
|
831
846
|
padding:0 var(--sn-primitive-dimension-8, 8px) !important;
|
|
832
847
|
}
|
|
833
848
|
.container{
|